@rubytech/create-realagent 1.0.622 → 1.0.623

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.
@@ -2896,8 +2896,8 @@ var serveStatic = (options = { root: "" }) => {
2896
2896
  };
2897
2897
 
2898
2898
  // server/index.ts
2899
- import { readFileSync as readFileSync26, existsSync as existsSync26, watchFile } from "fs";
2900
- import { resolve as resolve27, join as join13, basename as basename6 } from "path";
2899
+ import { readFileSync as readFileSync27, existsSync as existsSync27, watchFile } from "fs";
2900
+ import { resolve as resolve27, join as join14, basename as basename6 } from "path";
2901
2901
  import { homedir as homedir4 } from "os";
2902
2902
 
2903
2903
  // app/lib/vnc-logger.ts
@@ -3829,7 +3829,7 @@ Content-Length: 0\r
3829
3829
  }
3830
3830
 
3831
3831
  // app/api/health/route.ts
3832
- import { existsSync as existsSync11, readFileSync as readFileSync12 } from "fs";
3832
+ import { existsSync as existsSync12, readFileSync as readFileSync13 } from "fs";
3833
3833
  import { createConnection as createConnection3 } from "net";
3834
3834
 
3835
3835
  // app/lib/claude-auth.ts
@@ -4164,9 +4164,9 @@ function keyFilePath() {
4164
4164
  import Anthropic2 from "@anthropic-ai/sdk";
4165
4165
  import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
4166
4166
  import { randomUUID as randomUUID2 } from "crypto";
4167
- import { resolve as resolve6, join as join4 } from "path";
4167
+ import { resolve as resolve6, join as join5 } from "path";
4168
4168
  import { platform as osPlatform } from "os";
4169
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, readdirSync as readdirSync2, existsSync as existsSync6, mkdirSync as mkdirSync4, createWriteStream, statSync as statSync3, unlinkSync, cpSync, rmSync } from "fs";
4169
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, readdirSync as readdirSync2, existsSync as existsSync7, mkdirSync as mkdirSync4, createWriteStream, statSync as statSync3, unlinkSync, cpSync, rmSync } from "fs";
4170
4170
  import { lookup as dnsLookup } from "dns/promises";
4171
4171
  import { createConnection as netConnect } from "net";
4172
4172
  import { StringDecoder } from "string_decoder";
@@ -6037,6 +6037,73 @@ ${items}
6037
6037
  </commitment-detected>`;
6038
6038
  }
6039
6039
 
6040
+ // app/lib/tool-surface-filter.ts
6041
+ import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
6042
+ import { join as join4 } from "path";
6043
+ var ALLOWED_CLOUDFLARE_DURING_SETUP = /* @__PURE__ */ new Set([
6044
+ "mcp__cloudflare__cloudflare-setup-run",
6045
+ "mcp__cloudflare__cloudflare-setup-status"
6046
+ ]);
6047
+ function shouldRemoveDuringCloudflareSetup(toolName) {
6048
+ if (toolName.startsWith("mcp__plugin_playwright_playwright__")) return true;
6049
+ if (toolName.startsWith("mcp__plugin_chrome-devtools-mcp_chrome-devtools__")) return true;
6050
+ if (toolName.startsWith("mcp__cloudflare__")) {
6051
+ return !ALLOWED_CLOUDFLARE_DURING_SETUP.has(toolName);
6052
+ }
6053
+ if (toolName === "Bash") return true;
6054
+ if (toolName === "Write") return true;
6055
+ if (toolName === "Edit") return true;
6056
+ if (toolName === "NotebookEdit") return true;
6057
+ return false;
6058
+ }
6059
+ function readCloudflareSetupState() {
6060
+ const path2 = join4(MAXY_DIR, "cloudflared", "setup.state.json");
6061
+ if (!existsSync6(path2)) return null;
6062
+ try {
6063
+ const raw2 = readFileSync7(path2, "utf-8");
6064
+ const parsed = JSON.parse(raw2);
6065
+ if (typeof parsed?.phase !== "string") return null;
6066
+ const phase = parsed.phase;
6067
+ const setupActive = phase !== "idle" && phase !== "healthy" && phase !== "unhealthy";
6068
+ return { phase, domain: parsed.domain ?? null, setupActive };
6069
+ } catch {
6070
+ return null;
6071
+ }
6072
+ }
6073
+ function applyToolSurfaceFilters(tools) {
6074
+ const cf = readCloudflareSetupState();
6075
+ if (cf && cf.setupActive) {
6076
+ const kept = [];
6077
+ const removed = [];
6078
+ for (const t of tools) {
6079
+ if (shouldRemoveDuringCloudflareSetup(t)) {
6080
+ removed.push(t);
6081
+ } else {
6082
+ kept.push(t);
6083
+ }
6084
+ }
6085
+ return {
6086
+ tools: kept,
6087
+ filtered: "cloudflare-setup",
6088
+ phase: cf.phase,
6089
+ removed: removed.length,
6090
+ removedList: [...removed].sort().join(",")
6091
+ };
6092
+ }
6093
+ return {
6094
+ tools,
6095
+ filtered: "none",
6096
+ phase: cf?.phase ?? "idle",
6097
+ removed: 0,
6098
+ removedList: ""
6099
+ };
6100
+ }
6101
+ function logToolSurfaceFilter(result) {
6102
+ console.error(
6103
+ `[chat-driver:tool-surface] filtered=${result.filtered} phase=${result.phase} removed=${result.removed} removed-list=${result.removedList}`
6104
+ );
6105
+ }
6106
+
6040
6107
  // app/lib/claude-agent.ts
6041
6108
  var LOG_RETENTION_DAYS = 7;
6042
6109
  var BROWSER_TOOL_PREFIXES = [
@@ -6270,7 +6337,7 @@ function sampleProcState(pid) {
6270
6337
  let sockets2 = 0;
6271
6338
  for (const tcpFile of ["/proc/" + pid + "/net/tcp", "/proc/" + pid + "/net/tcp6"]) {
6272
6339
  try {
6273
- const raw2 = readFileSync7(tcpFile, "utf-8");
6340
+ const raw2 = readFileSync8(tcpFile, "utf-8");
6274
6341
  const lines2 = raw2.split("\n");
6275
6342
  for (let i = 1; i < lines2.length; i++) {
6276
6343
  const line = lines2[i].trim();
@@ -6286,7 +6353,7 @@ function sampleProcState(pid) {
6286
6353
  }
6287
6354
  let rssMb = 0;
6288
6355
  try {
6289
- const statm = readFileSync7(`/proc/${pid}/statm`, "utf-8").trim().split(/\s+/);
6356
+ const statm = readFileSync8(`/proc/${pid}/statm`, "utf-8").trim().split(/\s+/);
6290
6357
  const rssPages = parseInt(statm[1] ?? "0", 10);
6291
6358
  if (Number.isFinite(rssPages)) rssMb = Math.round(rssPages * 4096 / (1024 * 1024));
6292
6359
  } catch {
@@ -6321,19 +6388,19 @@ function sampleProcState(pid) {
6321
6388
  }
6322
6389
  var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "..");
6323
6390
  var ACCOUNTS_DIR = resolve6(PLATFORM_ROOT4, "..", "data/accounts");
6324
- if (!existsSync6(PLATFORM_ROOT4)) {
6391
+ if (!existsSync7(PLATFORM_ROOT4)) {
6325
6392
  throw new Error(
6326
6393
  `PLATFORM_ROOT does not exist: ${PLATFORM_ROOT4}
6327
6394
  Set the MAXY_PLATFORM_ROOT environment variable to the absolute path of the platform directory.`
6328
6395
  );
6329
6396
  }
6330
6397
  function resolveAccount() {
6331
- if (!existsSync6(ACCOUNTS_DIR)) return null;
6398
+ if (!existsSync7(ACCOUNTS_DIR)) return null;
6332
6399
  const usersFilePath = resolve6(PLATFORM_ROOT4, "config", "users.json");
6333
6400
  let usersJsonUserId = null;
6334
- if (existsSync6(usersFilePath)) {
6401
+ if (existsSync7(usersFilePath)) {
6335
6402
  try {
6336
- const raw2 = readFileSync7(usersFilePath, "utf-8").trim();
6403
+ const raw2 = readFileSync8(usersFilePath, "utf-8").trim();
6337
6404
  if (raw2) {
6338
6405
  const users = JSON.parse(raw2);
6339
6406
  if (users.length > 0) {
@@ -6348,8 +6415,8 @@ function resolveAccount() {
6348
6415
  for (const entry of entries) {
6349
6416
  if (!entry.isDirectory()) continue;
6350
6417
  const configPath2 = resolve6(ACCOUNTS_DIR, entry.name, "account.json");
6351
- if (!existsSync6(configPath2)) continue;
6352
- const raw2 = readFileSync7(configPath2, "utf-8");
6418
+ if (!existsSync7(configPath2)) continue;
6419
+ const raw2 = readFileSync8(configPath2, "utf-8");
6353
6420
  let config2;
6354
6421
  try {
6355
6422
  config2 = JSON.parse(raw2);
@@ -6383,8 +6450,8 @@ function resolveAccount() {
6383
6450
  }
6384
6451
  function readAgentFile(accountDir, agentName, filename) {
6385
6452
  const filePath = resolve6(accountDir, "agents", agentName, filename);
6386
- if (!existsSync6(filePath)) return null;
6387
- return readFileSync7(filePath, "utf-8");
6453
+ if (!existsSync7(filePath)) return null;
6454
+ return readFileSync8(filePath, "utf-8");
6388
6455
  }
6389
6456
  function readIdentity(accountDir, agentName) {
6390
6457
  return readAgentFile(accountDir, agentName, "IDENTITY.md");
@@ -6401,13 +6468,13 @@ function validateAgentSlug(slug) {
6401
6468
  }
6402
6469
  function resolveDefaultAgentSlug(accountDir) {
6403
6470
  const configPath2 = resolve6(accountDir, "account.json");
6404
- if (!existsSync6(configPath2)) {
6471
+ if (!existsSync7(configPath2)) {
6405
6472
  console.error("[agent-resolve] account.json not found \u2014 cannot resolve defaultAgent");
6406
6473
  return null;
6407
6474
  }
6408
6475
  let config2;
6409
6476
  try {
6410
- config2 = JSON.parse(readFileSync7(configPath2, "utf-8"));
6477
+ config2 = JSON.parse(readFileSync8(configPath2, "utf-8"));
6411
6478
  } catch (err) {
6412
6479
  console.error("[agent-resolve] failed to read account.json:", err);
6413
6480
  return null;
@@ -6417,7 +6484,7 @@ function resolveDefaultAgentSlug(accountDir) {
6417
6484
  return null;
6418
6485
  }
6419
6486
  const agentConfigPath = resolve6(accountDir, "agents", config2.defaultAgent, "config.json");
6420
- if (!existsSync6(agentConfigPath)) {
6487
+ if (!existsSync7(agentConfigPath)) {
6421
6488
  console.error(`[agent-resolve] defaultAgent="${config2.defaultAgent}" has no config.json at ${agentConfigPath}`);
6422
6489
  return null;
6423
6490
  }
@@ -6492,20 +6559,20 @@ function resolveAgentConfig(accountDir, agentName) {
6492
6559
  const agentDir = resolve6(accountDir, "agents", agentName);
6493
6560
  const knowledgePath = resolve6(agentDir, "KNOWLEDGE.md");
6494
6561
  const summaryPath = resolve6(agentDir, "KNOWLEDGE-SUMMARY.md");
6495
- const hasKnowledge = existsSync6(knowledgePath);
6496
- const hasSummary = existsSync6(summaryPath);
6562
+ const hasKnowledge = existsSync7(knowledgePath);
6563
+ const hasSummary = existsSync7(summaryPath);
6497
6564
  if (hasKnowledge && hasSummary) {
6498
6565
  const knowledgeMtime = statSync3(knowledgePath).mtimeMs;
6499
6566
  const summaryMtime = statSync3(summaryPath).mtimeMs;
6500
6567
  if (summaryMtime >= knowledgeMtime) {
6501
- knowledge = readFileSync7(summaryPath, "utf-8");
6568
+ knowledge = readFileSync8(summaryPath, "utf-8");
6502
6569
  } else {
6503
6570
  console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
6504
- knowledge = readFileSync7(knowledgePath, "utf-8");
6571
+ knowledge = readFileSync8(knowledgePath, "utf-8");
6505
6572
  }
6506
6573
  knowledgeBaked = true;
6507
6574
  } else if (hasKnowledge) {
6508
- knowledge = readFileSync7(knowledgePath, "utf-8");
6575
+ knowledge = readFileSync8(knowledgePath, "utf-8");
6509
6576
  knowledgeBaked = true;
6510
6577
  }
6511
6578
  let budget = null;
@@ -6528,10 +6595,10 @@ function resolveAgentConfig(accountDir, agentName) {
6528
6595
  }
6529
6596
  function parsePluginFrontmatter(pluginDir) {
6530
6597
  const pluginPath = resolve6(PLATFORM_ROOT4, "plugins", pluginDir, "PLUGIN.md");
6531
- if (!existsSync6(pluginPath)) return null;
6598
+ if (!existsSync7(pluginPath)) return null;
6532
6599
  let raw2;
6533
6600
  try {
6534
- raw2 = readFileSync7(pluginPath, "utf-8");
6601
+ raw2 = readFileSync8(pluginPath, "utf-8");
6535
6602
  } catch {
6536
6603
  console.warn(`[plugins] cannot read ${pluginPath}`);
6537
6604
  return null;
@@ -6592,22 +6659,22 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
6592
6659
  const TAG18 = "[premium-auto-deliver]";
6593
6660
  const stagingRoot = resolve6(PLATFORM_ROOT4, "../premium-plugins");
6594
6661
  const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
6595
- if (!existsSync6(stagingRoot)) {
6662
+ if (!existsSync7(stagingRoot)) {
6596
6663
  console.log(`${TAG18} no staging directory \u2014 skipping`);
6597
6664
  return;
6598
6665
  }
6599
6666
  for (const pluginName of purchasedPlugins) {
6600
6667
  const stagingDir = resolve6(stagingRoot, pluginName);
6601
- if (!existsSync6(stagingDir)) {
6668
+ if (!existsSync7(stagingDir)) {
6602
6669
  console.log(`${TAG18} ${pluginName}: not in staging \u2014 skipping`);
6603
6670
  continue;
6604
6671
  }
6605
- const bundlePath = join4(stagingDir, "BUNDLE.md");
6606
- const isBundle = existsSync6(bundlePath);
6672
+ const bundlePath = join5(stagingDir, "BUNDLE.md");
6673
+ const isBundle = existsSync7(bundlePath);
6607
6674
  if (isBundle) {
6608
6675
  let bundleRaw;
6609
6676
  try {
6610
- bundleRaw = readFileSync7(bundlePath, "utf-8");
6677
+ bundleRaw = readFileSync8(bundlePath, "utf-8");
6611
6678
  } catch (err) {
6612
6679
  console.log(`${TAG18} ${pluginName}: cannot read BUNDLE.md \u2014 ${err instanceof Error ? err.message : String(err)}`);
6613
6680
  continue;
@@ -6639,12 +6706,12 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
6639
6706
  let skipped = 0;
6640
6707
  for (const sub of subPlugins) {
6641
6708
  const target = resolve6(pluginsDir, sub);
6642
- if (existsSync6(resolve6(target, "PLUGIN.md"))) {
6709
+ if (existsSync7(resolve6(target, "PLUGIN.md"))) {
6643
6710
  skipped++;
6644
6711
  continue;
6645
6712
  }
6646
6713
  const source = resolve6(stagingDir, "plugins", sub);
6647
- if (!existsSync6(source)) {
6714
+ if (!existsSync7(source)) {
6648
6715
  console.log(`${TAG18} ${pluginName}/${sub}: source missing in staging \u2014 skipping`);
6649
6716
  continue;
6650
6717
  }
@@ -6658,7 +6725,7 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
6658
6725
  console.log(`${TAG18} ${pluginName} (bundle): ${delivered} delivered, ${skipped} already present`);
6659
6726
  } else {
6660
6727
  const target = resolve6(pluginsDir, pluginName);
6661
- if (existsSync6(resolve6(target, "PLUGIN.md"))) {
6728
+ if (existsSync7(resolve6(target, "PLUGIN.md"))) {
6662
6729
  console.log(`${TAG18} ${pluginName}: already present \u2014 skipping`);
6663
6730
  continue;
6664
6731
  }
@@ -6700,7 +6767,7 @@ function migratePluginRenames(accountDir, config2) {
6700
6767
  if (!changed) return;
6701
6768
  const configPath2 = resolve6(accountDir, "account.json");
6702
6769
  try {
6703
- const raw2 = readFileSync7(configPath2, "utf-8");
6770
+ const raw2 = readFileSync8(configPath2, "utf-8");
6704
6771
  const parsed = JSON.parse(raw2);
6705
6772
  parsed.enabledPlugins = migrated;
6706
6773
  writeFileSync5(configPath2, JSON.stringify(parsed, null, 2) + "\n");
@@ -6712,7 +6779,7 @@ function migratePluginRenames(accountDir, config2) {
6712
6779
  const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
6713
6780
  for (const oldName of Object.keys(PLUGIN_RENAMES)) {
6714
6781
  const orphan = resolve6(pluginsDir, oldName);
6715
- if (existsSync6(orphan)) {
6782
+ if (existsSync7(orphan)) {
6716
6783
  try {
6717
6784
  rmSync(orphan, { recursive: true });
6718
6785
  console.log(`${TAG18} removed orphan: ${oldName}`);
@@ -6727,20 +6794,20 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
6727
6794
  const TAG18 = "[bundle-agent-deliver]";
6728
6795
  const stagingRoot = resolve6(PLATFORM_ROOT4, "../premium-plugins");
6729
6796
  const specialistsDir = resolve6(accountDir, "specialists", "agents");
6730
- if (!existsSync6(stagingRoot)) return;
6731
- if (!existsSync6(specialistsDir)) {
6797
+ if (!existsSync7(stagingRoot)) return;
6798
+ if (!existsSync7(specialistsDir)) {
6732
6799
  mkdirSync4(specialistsDir, { recursive: true });
6733
6800
  }
6734
6801
  const agentsmdPath = resolve6(accountDir, "agents", "admin", "AGENTS.md");
6735
6802
  let agentsmd = "";
6736
6803
  try {
6737
- agentsmd = existsSync6(agentsmdPath) ? readFileSync7(agentsmdPath, "utf-8") : "";
6804
+ agentsmd = existsSync7(agentsmdPath) ? readFileSync8(agentsmdPath, "utf-8") : "";
6738
6805
  } catch {
6739
6806
  }
6740
6807
  let delivered = 0;
6741
6808
  for (const pluginName of purchasedPlugins) {
6742
6809
  const bundleAgentsDir = resolve6(stagingRoot, pluginName, "agents");
6743
- if (!existsSync6(bundleAgentsDir)) continue;
6810
+ if (!existsSync7(bundleAgentsDir)) continue;
6744
6811
  let entries;
6745
6812
  try {
6746
6813
  entries = readdirSync2(bundleAgentsDir).filter((f) => f.endsWith(".md"));
@@ -6749,7 +6816,7 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
6749
6816
  }
6750
6817
  for (const filename of entries) {
6751
6818
  const target = resolve6(specialistsDir, filename);
6752
- if (existsSync6(target)) continue;
6819
+ if (existsSync7(target)) continue;
6753
6820
  const source = resolve6(bundleAgentsDir, filename);
6754
6821
  try {
6755
6822
  cpSync(source, target);
@@ -6758,7 +6825,7 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
6758
6825
  continue;
6759
6826
  }
6760
6827
  try {
6761
- const content = readFileSync7(target, "utf-8");
6828
+ const content = readFileSync8(target, "utf-8");
6762
6829
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
6763
6830
  if (fmMatch) {
6764
6831
  const nameMatch = fmMatch[1].match(/^name:\s*(.+)/m);
@@ -6794,7 +6861,7 @@ function assemblePublicPluginContent(pluginDir) {
6794
6861
  const pluginPath = resolve6(pluginRoot, "PLUGIN.md");
6795
6862
  let raw2;
6796
6863
  try {
6797
- raw2 = readFileSync7(pluginPath, "utf-8");
6864
+ raw2 = readFileSync8(pluginPath, "utf-8");
6798
6865
  } catch {
6799
6866
  return null;
6800
6867
  }
@@ -6815,7 +6882,7 @@ function assemblePublicPluginContent(pluginDir) {
6815
6882
  const skillMdPath = resolve6(skillDir, "SKILL.md");
6816
6883
  let skillRaw;
6817
6884
  try {
6818
- skillRaw = readFileSync7(skillMdPath, "utf-8");
6885
+ skillRaw = readFileSync8(skillMdPath, "utf-8");
6819
6886
  } catch {
6820
6887
  continue;
6821
6888
  }
@@ -6866,7 +6933,7 @@ function assemblePublicPluginContent(pluginDir) {
6866
6933
  }
6867
6934
  for (const refFile of refFiles) {
6868
6935
  try {
6869
- const refContent = readFileSync7(resolve6(refsDir, refFile), "utf-8").trim();
6936
+ const refContent = readFileSync8(resolve6(refsDir, refFile), "utf-8").trim();
6870
6937
  if (refContent) {
6871
6938
  parts.push(`
6872
6939
  <!-- reference: ${refFile} -->`);
@@ -6940,7 +7007,7 @@ function loadEmbeddedPlugins(agentType, selectedPlugins, enabledPlugins) {
6940
7007
  const pluginPath = resolve6(pluginsDir, dir, "PLUGIN.md");
6941
7008
  let raw2;
6942
7009
  try {
6943
- raw2 = readFileSync7(pluginPath, "utf-8");
7010
+ raw2 = readFileSync8(pluginPath, "utf-8");
6944
7011
  } catch (err) {
6945
7012
  console.warn(`[plugins] ${dir}: failed to read PLUGIN.md for ${agentType} embed: ${String(err)}`);
6946
7013
  continue;
@@ -6965,7 +7032,7 @@ function fetchMcpToolsList(pluginDir) {
6965
7032
  const cached2 = mcpToolsCache.get(pluginDir);
6966
7033
  if (cached2) return Promise.resolve(cached2);
6967
7034
  const serverPath = resolve6(PLATFORM_ROOT4, "plugins", pluginDir, "mcp/dist/index.js");
6968
- if (!existsSync6(serverPath)) return Promise.resolve([]);
7035
+ if (!existsSync7(serverPath)) return Promise.resolve([]);
6969
7036
  const startMs = Date.now();
6970
7037
  return new Promise((resolvePromise) => {
6971
7038
  const proc = spawn2(process.execPath, [serverPath], {
@@ -7169,7 +7236,7 @@ ${specialist}: ${plugins.join(", ")}`);
7169
7236
  const references = [];
7170
7237
  const scanDir = (base, prefix, target) => {
7171
7238
  const scanPath = resolve6(pluginRoot, base);
7172
- if (!existsSync6(scanPath)) return;
7239
+ if (!existsSync7(scanPath)) return;
7173
7240
  try {
7174
7241
  const walk = (current, rel) => {
7175
7242
  for (const entry of readdirSync2(current)) {
@@ -7202,7 +7269,7 @@ ${specialist}: ${plugins.join(", ")}`);
7202
7269
  }
7203
7270
  } else if (parsed.tools.length > 0) {
7204
7271
  const serverPath = resolve6(PLATFORM_ROOT4, "plugins", dir, "mcp/dist/index.js");
7205
- if (existsSync6(serverPath)) {
7272
+ if (existsSync7(serverPath)) {
7206
7273
  fallbackSourced++;
7207
7274
  console.error(`[plugin-manifest] ${dir}: tools/list empty \u2014 fallback to frontmatter (${parsed.tools.length} tools)`);
7208
7275
  }
@@ -7277,16 +7344,16 @@ function getDefaultAccountId() {
7277
7344
  return resolveAccount()?.accountId ?? null;
7278
7345
  }
7279
7346
  function resolveUserAccounts(userId) {
7280
- if (!existsSync6(ACCOUNTS_DIR)) return [];
7347
+ if (!existsSync7(ACCOUNTS_DIR)) return [];
7281
7348
  const results = [];
7282
7349
  const entries = readdirSync2(ACCOUNTS_DIR, { withFileTypes: true });
7283
7350
  for (const entry of entries) {
7284
7351
  if (!entry.isDirectory()) continue;
7285
7352
  const configPath2 = resolve6(ACCOUNTS_DIR, entry.name, "account.json");
7286
- if (!existsSync6(configPath2)) continue;
7353
+ if (!existsSync7(configPath2)) continue;
7287
7354
  let config2;
7288
7355
  try {
7289
- config2 = JSON.parse(readFileSync7(configPath2, "utf-8"));
7356
+ config2 = JSON.parse(readFileSync8(configPath2, "utf-8"));
7290
7357
  } catch {
7291
7358
  console.error(`[session] account.json corrupt at ${configPath2} \u2014 skipping`);
7292
7359
  continue;
@@ -7606,7 +7673,7 @@ function getMcpServers(accountId, conversationId, userId, enabledPlugins) {
7606
7673
  }
7607
7674
  }
7608
7675
  const mcpEntry = resolve6(PLATFORM_ROOT4, "plugins", dir, "mcp/dist/index.js");
7609
- if (!existsSync6(mcpEntry)) continue;
7676
+ if (!existsSync7(mcpEntry)) continue;
7610
7677
  servers[dir] = {
7611
7678
  command: "node",
7612
7679
  args: [mcpEntry],
@@ -7691,6 +7758,8 @@ var ADMIN_CORE_TOOLS = [
7691
7758
  "mcp__cloudflare__tunnel-enable",
7692
7759
  "mcp__cloudflare__tunnel-disable",
7693
7760
  "mcp__cloudflare__tunnel-add-hostname",
7761
+ "mcp__cloudflare__cloudflare-setup-run",
7762
+ "mcp__cloudflare__cloudflare-setup-status",
7694
7763
  "mcp__cloudflare__dns-lookup",
7695
7764
  "mcp__tasks__task-create",
7696
7765
  "mcp__tasks__task-update",
@@ -7757,6 +7826,12 @@ function getAdminAllowedTools(enabledPlugins) {
7757
7826
  }
7758
7827
  return tools;
7759
7828
  }
7829
+ function assembleAllowedToolsForAdminSpawn(enabledPlugins) {
7830
+ const base = getAdminAllowedTools(enabledPlugins);
7831
+ const result = applyToolSurfaceFilters(base);
7832
+ logToolSurfaceFilter(result);
7833
+ return result.tools;
7834
+ }
7760
7835
  var QUERY_CLASSIFIER_MODEL = HAIKU_MODEL2;
7761
7836
  var QUERY_CLASSIFIER_TIMEOUT_MS = 3e3;
7762
7837
  var QUERY_CLASSIFIER_MSG_CAP = 500;
@@ -7845,7 +7920,7 @@ ${message.slice(0, QUERY_CLASSIFIER_MSG_CAP)}`
7845
7920
  }
7846
7921
  async function fetchMemoryContext(accountId, query, sessionKey, options) {
7847
7922
  const serverPath = resolve6(PLATFORM_ROOT4, "plugins/memory/mcp/dist/index.js");
7848
- if (!existsSync6(serverPath)) {
7923
+ if (!existsSync7(serverPath)) {
7849
7924
  console.error(`[fetchMemoryContext] MCP server not found: ${serverPath}`);
7850
7925
  return null;
7851
7926
  }
@@ -7943,7 +8018,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
7943
8018
  async function compactTrimmedMessages(accountId, trimmedMessages) {
7944
8019
  if (trimmedMessages.length === 0) return true;
7945
8020
  const serverPath = resolve6(PLATFORM_ROOT4, "plugins/memory/mcp/dist/index.js");
7946
- if (!existsSync6(serverPath)) return false;
8021
+ if (!existsSync7(serverPath)) return false;
7947
8022
  const briefing = trimmedMessages.map((m) => `[${m.role.toUpperCase()}] ${m.content}`).join("\n\n");
7948
8023
  return new Promise((resolvePromise) => {
7949
8024
  const proc = spawn2(process.execPath, [serverPath], {
@@ -8261,7 +8336,7 @@ var COMPACTION_TIMEOUT_MS = 45e3;
8261
8336
  async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSessionId, adminModel, conversationId, enabledPlugins) {
8262
8337
  const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, conversationId, void 0, enabledPlugins) });
8263
8338
  const specialistsDir = resolve6(accountDir, "specialists");
8264
- if (!existsSync6(specialistsDir)) agentLogStream("claude-agent-compaction-stream", accountDir, conversationId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
8339
+ if (!existsSync7(specialistsDir)) agentLogStream("claude-agent-compaction-stream", accountDir, conversationId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
8265
8340
  `);
8266
8341
  const args = [
8267
8342
  "--print",
@@ -8273,7 +8348,7 @@ async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSes
8273
8348
  "--mcp-config",
8274
8349
  mcpConfig,
8275
8350
  "--allowedTools",
8276
- getAdminAllowedTools(enabledPlugins).join(","),
8351
+ assembleAllowedToolsForAdminSpawn(enabledPlugins).join(","),
8277
8352
  "--permission-mode",
8278
8353
  "dontAsk",
8279
8354
  "--model",
@@ -9150,7 +9225,7 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
9150
9225
  const ccUserId = sessionKey ? getUserIdForSession(sessionKey) : void 0;
9151
9226
  const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, spawnConvId, ccUserId, enabledPlugins) });
9152
9227
  const specialistsDir = resolve6(accountDir, "specialists");
9153
- if (!existsSync6(specialistsDir)) agentLogStream("claude-agent-stream", accountDir, spawnConvId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
9228
+ if (!existsSync7(specialistsDir)) agentLogStream("claude-agent-stream", accountDir, spawnConvId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
9154
9229
  `);
9155
9230
  const args = [
9156
9231
  "--print",
@@ -9162,7 +9237,7 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
9162
9237
  "--mcp-config",
9163
9238
  mcpConfig,
9164
9239
  "--allowedTools",
9165
- getAdminAllowedTools(enabledPlugins).join(","),
9240
+ assembleAllowedToolsForAdminSpawn(enabledPlugins).join(","),
9166
9241
  "--permission-mode",
9167
9242
  "dontAsk",
9168
9243
  "--model",
@@ -9496,7 +9571,7 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
9496
9571
  const managedUserId = getUserIdForSession(sessionKey);
9497
9572
  const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, managedConvId, managedUserId, enabledPlugins) });
9498
9573
  const specialistsDir = resolve6(accountDir, "specialists");
9499
- if (!existsSync6(specialistsDir)) streamLog.write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
9574
+ if (!existsSync7(specialistsDir)) streamLog.write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
9500
9575
  `);
9501
9576
  const fullMessage = attachments.length > 0 ? message + buildAttachmentMetaText(attachments) : message;
9502
9577
  const args = [
@@ -9509,7 +9584,7 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
9509
9584
  "--mcp-config",
9510
9585
  mcpConfig,
9511
9586
  "--allowedTools",
9512
- getAdminAllowedTools(enabledPlugins).join(","),
9587
+ assembleAllowedToolsForAdminSpawn(enabledPlugins).join(","),
9513
9588
  "--permission-mode",
9514
9589
  "dontAsk",
9515
9590
  "--model",
@@ -10166,7 +10241,7 @@ ${sessionContext}`;
10166
10241
  const skillPath = resolve6(PLATFORM_ROOT4, "plugins/admin/skills/onboarding/SKILL.md");
10167
10242
  let skillContent = "";
10168
10243
  try {
10169
- skillContent = readFileSync7(skillPath, "utf-8");
10244
+ skillContent = readFileSync8(skillPath, "utf-8");
10170
10245
  } catch (err) {
10171
10246
  console.error(`[onboarding-inject] accountId=${accountId.slice(0, 8)}\u2026 error=skill-read-failed path=${skillPath} reason=${err instanceof Error ? err.message : String(err)}`);
10172
10247
  }
@@ -10366,7 +10441,7 @@ ${block}`;
10366
10441
  import { basename as basename2 } from "path";
10367
10442
 
10368
10443
  // app/lib/review-detector/rules.ts
10369
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync7, statSync as statSync4, mkdirSync as mkdirSync5, renameSync } from "fs";
10444
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync8, statSync as statSync4, mkdirSync as mkdirSync5, renameSync } from "fs";
10370
10445
  import { resolve as resolve7, dirname as dirname2 } from "path";
10371
10446
  var DEFAULT_SCAN_INTERVAL_MS = 5e3;
10372
10447
  var RATE_LIMIT_PATTERN = "rate[- ]?limit(?:ed| reached| hit)|(?:HTTP|status)[^a-z]{0,3}429|too many requests";
@@ -10696,6 +10771,38 @@ function defaultRules() {
10696
10771
  thresholdCount: 0,
10697
10772
  thresholdWindowMinutes: 0,
10698
10773
  suggestedAction: "A device-bound URL click failed to drive Chromium on the device's VNC display. Identify the `intent` and `hostname` from the log line, then check the VNC surface: read `vnc-boot.log` and confirm Chromium on :99 is responding on CDP port 9222. If CDP is unreachable, the operator needs to restart the VNC stack; if CDP is reachable but navigation errored, the URL itself may be malformed upstream \u2014 grep the stream log for the originating `[device-url:render]` line."
10774
+ },
10775
+ {
10776
+ // Task 547: catches agent prose that forks or narrates during an
10777
+ // orchestrated flow. The tool-surface gate filters the raw tunnel-*
10778
+ // tools, Playwright, and Bash/Write/Edit while cloudflare-setup-run
10779
+ // is mid-flow, so the agent cannot *call* a deviating tool — but the
10780
+ // agent could still narrate ("Want me to kick off the login flow
10781
+ // now?", "Or would you prefer to do it manually?"). This rule catches
10782
+ // that narration surface.
10783
+ //
10784
+ // The task file prescribes a `preceded-by` rule type (scopes the
10785
+ // followup pattern to a window after a `cloudflare-setup-run` tool
10786
+ // result). That type is introduced by Task 544, which has not
10787
+ // shipped at the time of writing. The fallback named in Task 547 is
10788
+ // a pure `repeated-error` with the followup pattern only — accepts
10789
+ // the false-positive surface (other contexts where the agent asks
10790
+ // "Want me to X, or Y?") until 544 lands. Any such false-positive is
10791
+ // also caught by the pre-existing `agent-choice-fork` rule, so the
10792
+ // net observability cost is zero; the name and suggestedAction below
10793
+ // point a reader at Task 547 specifically when this rule fires
10794
+ // during a cloudflare setup. When 544 ships, migrate this to
10795
+ // `preceded-by` with triggerPattern="cloudflare-setup-run" and
10796
+ // followupWindow=5 lines.
10797
+ id: "orchestrator-mid-flow-fork",
10798
+ name: "Agent narration or fork during an orchestrated flow",
10799
+ type: "repeated-error",
10800
+ logSource: "any",
10801
+ pattern: "(Want me to|Should I|Do you want me|Or would you|Either way|Meanwhile)[^\\n]+\\?",
10802
+ thresholdCount: 1,
10803
+ thresholdWindowMinutes: 60,
10804
+ scope: "session",
10805
+ suggestedAction: "Review Task 547 \u2014 during an orchestrated flow (e.g. cloudflare-setup-run), the agent's only permitted output is relaying the tool's result verbatim and passing the operator's input through. Any forking or narrative prose is a deviation even though the tool-surface gate has filtered the deviating tools out of the menu. Check whether the offending turn occurred during a cloudflare setup (grep `[cloudflare:setup-run:` near this line); if so, the IDENTITY.md Tool-Surface Gates section may need a sharper reminder."
10699
10806
  }
10700
10807
  ];
10701
10808
  }
@@ -10704,7 +10811,7 @@ function rulesFilePath(configDir2) {
10704
10811
  }
10705
10812
  function ensureRulesFile(configDir2) {
10706
10813
  const path2 = rulesFilePath(configDir2);
10707
- if (existsSync7(path2)) return { created: false, path: path2 };
10814
+ if (existsSync8(path2)) return { created: false, path: path2 };
10708
10815
  mkdirSync5(dirname2(path2), { recursive: true });
10709
10816
  const body = {
10710
10817
  scanIntervalMs: DEFAULT_SCAN_INTERVAL_MS,
@@ -10715,10 +10822,10 @@ function ensureRulesFile(configDir2) {
10715
10822
  }
10716
10823
  function loadRules(configDir2) {
10717
10824
  const path2 = rulesFilePath(configDir2);
10718
- if (!existsSync7(path2)) {
10825
+ if (!existsSync8(path2)) {
10719
10826
  throw new Error(`rules file missing at ${path2}`);
10720
10827
  }
10721
- const raw2 = readFileSync8(path2, "utf-8");
10828
+ const raw2 = readFileSync9(path2, "utf-8");
10722
10829
  let parsed;
10723
10830
  try {
10724
10831
  parsed = JSON.parse(raw2);
@@ -10883,16 +10990,16 @@ function validateRule(input, label, seenIds) {
10883
10990
  }
10884
10991
 
10885
10992
  // app/lib/review-detector/sources.ts
10886
- import { existsSync as existsSync8, readdirSync as readdirSync3, statSync as statSync5, writeFileSync as writeFileSync7, renameSync as renameSync2, mkdirSync as mkdirSync6, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, readFileSync as readFileSync9 } from "fs";
10887
- import { resolve as resolve8, join as join5, basename, dirname as dirname3 } from "path";
10993
+ import { existsSync as existsSync9, readdirSync as readdirSync3, statSync as statSync5, writeFileSync as writeFileSync7, renameSync as renameSync2, mkdirSync as mkdirSync6, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, readFileSync as readFileSync10 } from "fs";
10994
+ import { resolve as resolve8, join as join6, basename, dirname as dirname3 } from "path";
10888
10995
  function tailStatePath(configDir2) {
10889
10996
  return resolve8(configDir2, "review-state.json");
10890
10997
  }
10891
10998
  function loadTailState(configDir2) {
10892
10999
  const path2 = tailStatePath(configDir2);
10893
- if (!existsSync8(path2)) return {};
11000
+ if (!existsSync9(path2)) return {};
10894
11001
  try {
10895
- const raw2 = readFileSync9(path2, "utf-8");
11002
+ const raw2 = readFileSync10(path2, "utf-8");
10896
11003
  const parsed = JSON.parse(raw2);
10897
11004
  if (!parsed || typeof parsed !== "object") return {};
10898
11005
  const clean = {};
@@ -10918,18 +11025,18 @@ function saveTailState(configDir2, state) {
10918
11025
  function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
10919
11026
  if (logicalSource === "server") {
10920
11027
  const p = resolve8(configDir2, "logs", "server.log");
10921
- return existsSync8(p) ? [{ logicalSource: "server", filepath: p }] : [];
11028
+ return existsSync9(p) ? [{ logicalSource: "server", filepath: p }] : [];
10922
11029
  }
10923
11030
  if (logicalSource === "vnc") {
10924
11031
  const p = resolve8(configDir2, "logs", "vnc-boot.log");
10925
- return existsSync8(p) ? [{ logicalSource: "vnc", filepath: p }] : [];
11032
+ return existsSync9(p) ? [{ logicalSource: "vnc", filepath: p }] : [];
10926
11033
  }
10927
11034
  if (logicalSource === "cloudflared") {
10928
11035
  const files2 = [];
10929
11036
  const daemon = resolve8(configDir2, "logs", "cloudflared.log");
10930
- if (existsSync8(daemon)) files2.push({ logicalSource: "cloudflared", filepath: daemon });
11037
+ if (existsSync9(daemon)) files2.push({ logicalSource: "cloudflared", filepath: daemon });
10931
11038
  const login = resolve8(configDir2, "logs", "cloudflared-login.log");
10932
- if (existsSync8(login)) files2.push({ logicalSource: "cloudflared", filepath: login });
11039
+ if (existsSync9(login)) files2.push({ logicalSource: "cloudflared", filepath: login });
10933
11040
  return files2;
10934
11041
  }
10935
11042
  const prefix = {
@@ -10939,7 +11046,7 @@ function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
10939
11046
  public: "public-agent-stream-",
10940
11047
  mcp: "mcp-"
10941
11048
  }[logicalSource];
10942
- if (!existsSync8(accountLogDir2)) return [];
11049
+ if (!existsSync9(accountLogDir2)) return [];
10943
11050
  const files = [];
10944
11051
  let scanned = 0;
10945
11052
  let skippedPrefixMismatch = 0;
@@ -10949,7 +11056,7 @@ function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
10949
11056
  const matchesPrefix = entry.startsWith(prefix);
10950
11057
  const isLog = entry.endsWith(".log");
10951
11058
  if (matchesPrefix && isLog) {
10952
- files.push({ logicalSource, filepath: join5(accountLogDir2, entry) });
11059
+ files.push({ logicalSource, filepath: join6(accountLogDir2, entry) });
10953
11060
  } else if (!matchesPrefix) {
10954
11061
  skippedPrefixMismatch += 1;
10955
11062
  } else {
@@ -10981,7 +11088,7 @@ function discoverAllSources(configDir2, accountLogDir2) {
10981
11088
  ];
10982
11089
  }
10983
11090
  function readNewLines(filepath, prev) {
10984
- if (!existsSync8(filepath)) return null;
11091
+ if (!existsSync9(filepath)) return null;
10985
11092
  const stat4 = statSync5(filepath);
10986
11093
  const size = stat4.size;
10987
11094
  const inode = stat4.ino;
@@ -11034,12 +11141,12 @@ function readNewLines(filepath, prev) {
11034
11141
  }
11035
11142
  }
11036
11143
  function countRecentWrites(dir, sinceMs) {
11037
- if (!existsSync8(dir)) return 0;
11144
+ if (!existsSync9(dir)) return 0;
11038
11145
  let count = 0;
11039
11146
  for (const entry of readdirSync3(dir, { withFileTypes: true })) {
11040
11147
  if (!entry.isFile()) continue;
11041
11148
  try {
11042
- const st = statSync5(join5(dir, entry.name));
11149
+ const st = statSync5(join6(dir, entry.name));
11043
11150
  if (st.mtimeMs >= sinceMs) count += 1;
11044
11151
  } catch {
11045
11152
  }
@@ -11047,7 +11154,7 @@ function countRecentWrites(dir, sinceMs) {
11047
11154
  return count;
11048
11155
  }
11049
11156
  function fileLastWriteMs(path2) {
11050
- if (!existsSync8(path2)) return null;
11157
+ if (!existsSync9(path2)) return null;
11051
11158
  try {
11052
11159
  return statSync5(path2).mtimeMs;
11053
11160
  } catch {
@@ -11062,7 +11169,7 @@ function sourceKey(file2) {
11062
11169
  }
11063
11170
 
11064
11171
  // app/lib/review-detector/writer.ts
11065
- import { appendFileSync as appendFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync8, renameSync as renameSync3, statSync as statSync6 } from "fs";
11172
+ import { appendFileSync as appendFileSync2, existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync8, renameSync as renameSync3, statSync as statSync6 } from "fs";
11066
11173
  import { resolve as resolve9, dirname as dirname4 } from "path";
11067
11174
  import { randomUUID as randomUUID3 } from "crypto";
11068
11175
  function reviewLogPath(configDir2) {
@@ -11200,8 +11307,8 @@ function queueAlert(configDir2, accountId, match2) {
11200
11307
  }
11201
11308
  async function drainPendingAlerts(configDir2) {
11202
11309
  const path2 = pendingAlertsPath(configDir2);
11203
- if (!existsSync9(path2)) return { drained: 0, remaining: 0 };
11204
- const raw2 = readFileSync10(path2, "utf-8");
11310
+ if (!existsSync10(path2)) return { drained: 0, remaining: 0 };
11311
+ const raw2 = readFileSync11(path2, "utf-8");
11205
11312
  const lines = raw2.split("\n").filter((l) => l.trim().length > 0);
11206
11313
  if (lines.length === 0) return { drained: 0, remaining: 0 };
11207
11314
  const remaining = [];
@@ -25631,16 +25738,16 @@ var WhatsAppConfigSchema = external_exports.object({
25631
25738
  });
25632
25739
 
25633
25740
  // app/lib/whatsapp/config-persist.ts
25634
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync10 } from "fs";
25635
- import { resolve as resolve11, join as join6 } from "path";
25741
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, existsSync as existsSync11 } from "fs";
25742
+ import { resolve as resolve11, join as join7 } from "path";
25636
25743
  var TAG2 = "[whatsapp:config]";
25637
25744
  function configPath(accountDir) {
25638
25745
  return resolve11(accountDir, "account.json");
25639
25746
  }
25640
25747
  function readConfig(accountDir) {
25641
25748
  const path2 = configPath(accountDir);
25642
- if (!existsSync10(path2)) throw new Error(`account.json not found at ${path2}`);
25643
- return JSON.parse(readFileSync11(path2, "utf-8"));
25749
+ if (!existsSync11(path2)) throw new Error(`account.json not found at ${path2}`);
25750
+ return JSON.parse(readFileSync12(path2, "utf-8"));
25644
25751
  }
25645
25752
  function writeConfig(accountDir, config2) {
25646
25753
  const path2 = configPath(accountDir);
@@ -25814,8 +25921,8 @@ function setPublicAgent(accountDir, slug) {
25814
25921
  if (!trimmed) {
25815
25922
  return { ok: false, error: "Agent slug cannot be empty." };
25816
25923
  }
25817
- const agentConfigPath = join6(accountDir, "agents", trimmed, "config.json");
25818
- if (!existsSync10(agentConfigPath)) {
25924
+ const agentConfigPath = join7(accountDir, "agents", trimmed, "config.json");
25925
+ if (!existsSync11(agentConfigPath)) {
25819
25926
  return { ok: false, error: `Agent "${trimmed}" not found \u2014 no config.json at ${agentConfigPath}. Check the agent slug and try again.` };
25820
25927
  }
25821
25928
  try {
@@ -26855,7 +26962,7 @@ async function sendMediaMessage(sock, to, media, opts) {
26855
26962
  // app/lib/whatsapp/inbound/media.ts
26856
26963
  import { randomUUID as randomUUID5 } from "crypto";
26857
26964
  import { writeFile, mkdir } from "fs/promises";
26858
- import { join as join7 } from "path";
26965
+ import { join as join8 } from "path";
26859
26966
  import {
26860
26967
  downloadMediaMessage,
26861
26968
  downloadContentFromMessage,
@@ -26941,7 +27048,7 @@ async function downloadInboundMedia(msg, sock, opts) {
26941
27048
  await mkdir(MEDIA_DIR, { recursive: true });
26942
27049
  const ext = mimeToExt(mimetype ?? "application/octet-stream");
26943
27050
  const filename = `${randomUUID5()}.${ext}`;
26944
- const filePath = join7(MEDIA_DIR, filename);
27051
+ const filePath = join8(MEDIA_DIR, filename);
26945
27052
  await writeFile(filePath, buffer);
26946
27053
  const sizeKB = (buffer.length / 1024).toFixed(0);
26947
27054
  console.error(`${TAG8} media downloaded type=${mimetype ?? "unknown"} size=${sizeKB}KB path=${filePath}`);
@@ -27903,8 +28010,8 @@ async function GET(req, remoteAddress) {
27903
28010
  const browserTransport = resolveBrowserTransport(req, remoteAddress);
27904
28011
  let pinConfigured = false;
27905
28012
  try {
27906
- if (existsSync11(USERS_FILE)) {
27907
- const raw2 = readFileSync12(USERS_FILE, "utf-8").trim();
28013
+ if (existsSync12(USERS_FILE)) {
28014
+ const raw2 = readFileSync13(USERS_FILE, "utf-8").trim();
27908
28015
  if (raw2) {
27909
28016
  const users = JSON.parse(raw2);
27910
28017
  pinConfigured = Array.isArray(users) && users.length > 0;
@@ -27923,7 +28030,7 @@ async function GET(req, remoteAddress) {
27923
28030
  const vncRunning = await checkPort(6080);
27924
28031
  let apiKeyConfigured = false;
27925
28032
  try {
27926
- apiKeyConfigured = existsSync11(keyFilePath());
28033
+ apiKeyConfigured = existsSync12(keyFilePath());
27927
28034
  } catch {
27928
28035
  }
27929
28036
  let apiKeyStatus = "missing";
@@ -27991,7 +28098,7 @@ async function GET(req, remoteAddress) {
27991
28098
 
27992
28099
  // app/api/session/route.ts
27993
28100
  import { resolve as resolve12 } from "path";
27994
- import { existsSync as existsSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync8 } from "fs";
28101
+ import { existsSync as existsSync13, writeFileSync as writeFileSync10, mkdirSync as mkdirSync8 } from "fs";
27995
28102
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
27996
28103
  async function POST(req) {
27997
28104
  let body;
@@ -28042,7 +28149,7 @@ async function POST(req) {
28042
28149
  if (account) {
28043
28150
  const agentDir = resolve12(account.accountDir, "agents", agentSlug);
28044
28151
  const agentConfigPath = resolve12(agentDir, "config.json");
28045
- if (!existsSync12(agentDir) || !existsSync12(agentConfigPath)) {
28152
+ if (!existsSync13(agentDir) || !existsSync13(agentConfigPath)) {
28046
28153
  return Response.json({ error: "Agent not found" }, { status: 404 });
28047
28154
  }
28048
28155
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -28417,7 +28524,7 @@ async function storeGeneratedFile(accountId, filePath) {
28417
28524
  // app/lib/stt/voice-note.ts
28418
28525
  import { writeFile as writeFile3, mkdtemp, rm } from "fs/promises";
28419
28526
  import { tmpdir } from "os";
28420
- import { join as join8 } from "path";
28527
+ import { join as join9 } from "path";
28421
28528
  var TAG13 = "[voice]";
28422
28529
  var AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
28423
28530
  "audio/ogg",
@@ -28455,9 +28562,9 @@ async function transcribeVoiceNote(file2, source) {
28455
28562
  let tempDir;
28456
28563
  let tempPath;
28457
28564
  try {
28458
- tempDir = await mkdtemp(join8(tmpdir(), "voice-"));
28565
+ tempDir = await mkdtemp(join9(tmpdir(), "voice-"));
28459
28566
  const ext = audioExtension(mimeType);
28460
- tempPath = join8(tempDir, `recording${ext}`);
28567
+ tempPath = join9(tempDir, `recording${ext}`);
28461
28568
  const buffer = Buffer.from(await file2.arrayBuffer());
28462
28569
  await writeFile3(tempPath, buffer);
28463
28570
  } catch (err) {
@@ -29008,7 +29115,7 @@ async function POST2(req) {
29008
29115
 
29009
29116
  // app/lib/access-gate.ts
29010
29117
  import neo4j2 from "neo4j-driver";
29011
- import { readFileSync as readFileSync13 } from "fs";
29118
+ import { readFileSync as readFileSync14 } from "fs";
29012
29119
  import { resolve as resolve14 } from "path";
29013
29120
  import { randomUUID as randomUUID7, randomInt } from "crypto";
29014
29121
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
@@ -29017,7 +29124,7 @@ function readPassword2() {
29017
29124
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
29018
29125
  const passwordFile = resolve14(PLATFORM_ROOT6, "config/.neo4j-password");
29019
29126
  try {
29020
- return readFileSync13(passwordFile, "utf-8").trim();
29127
+ return readFileSync14(passwordFile, "utf-8").trim();
29021
29128
  } catch {
29022
29129
  throw new Error(
29023
29130
  `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
@@ -29615,7 +29722,7 @@ async function POST6(req) {
29615
29722
  }
29616
29723
 
29617
29724
  // app/lib/brevo-sms.ts
29618
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, existsSync as existsSync13, chmodSync } from "fs";
29725
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, existsSync as existsSync14, chmodSync } from "fs";
29619
29726
  import { dirname as dirname5 } from "path";
29620
29727
  import { resolve as resolve15 } from "path";
29621
29728
  var BREVO_API_KEY_FILE = resolve15(MAXY_DIR, ".brevo-api-key");
@@ -29626,8 +29733,8 @@ var platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
29626
29733
  if (platformRoot2) {
29627
29734
  try {
29628
29735
  const brandPath3 = resolve15(platformRoot2, "config", "brand.json");
29629
- if (existsSync13(brandPath3)) {
29630
- const brand = JSON.parse(readFileSync14(brandPath3, "utf-8"));
29736
+ if (existsSync14(brandPath3)) {
29737
+ const brand = JSON.parse(readFileSync15(brandPath3, "utf-8"));
29631
29738
  if (brand.productName) BREVO_SENDER = brand.productName;
29632
29739
  }
29633
29740
  } catch {
@@ -29635,7 +29742,7 @@ if (platformRoot2) {
29635
29742
  }
29636
29743
  function readBrevoApiKey() {
29637
29744
  try {
29638
- const key = readFileSync14(BREVO_API_KEY_FILE, "utf-8").trim();
29745
+ const key = readFileSync15(BREVO_API_KEY_FILE, "utf-8").trim();
29639
29746
  if (!key) {
29640
29747
  throw new Error(`Brevo API key file is empty: ${BREVO_API_KEY_FILE}`);
29641
29748
  }
@@ -29650,7 +29757,7 @@ function readBrevoApiKey() {
29650
29757
  }
29651
29758
  }
29652
29759
  function hasBrevoApiKey() {
29653
- return existsSync13(BREVO_API_KEY_FILE);
29760
+ return existsSync14(BREVO_API_KEY_FILE);
29654
29761
  }
29655
29762
  async function sendSms(recipient, content, opts) {
29656
29763
  let apiKey;
@@ -29815,15 +29922,15 @@ function checkTelegramAccess(params) {
29815
29922
  }
29816
29923
 
29817
29924
  // app/api/telegram/webhook/route.ts
29818
- import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
29925
+ import { existsSync as existsSync15, readFileSync as readFileSync16 } from "fs";
29819
29926
  import { timingSafeEqual as timingSafeEqual2 } from "crypto";
29820
29927
  var TAG15 = "[telegram-webhook]";
29821
29928
  var TELEGRAM_API = "https://api.telegram.org";
29822
29929
  function getWebhookSecret(botType) {
29823
29930
  const filePath = botType === "admin" ? TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE : TELEGRAM_WEBHOOK_SECRET_FILE;
29824
29931
  try {
29825
- if (!existsSync14(filePath)) return null;
29826
- const secret = readFileSync15(filePath, "utf-8").trim();
29932
+ if (!existsSync15(filePath)) return null;
29933
+ const secret = readFileSync16(filePath, "utf-8").trim();
29827
29934
  return secret || null;
29828
29935
  } catch {
29829
29936
  return null;
@@ -29980,7 +30087,7 @@ async function POST8(req) {
29980
30087
  }
29981
30088
 
29982
30089
  // app/api/whatsapp/login/start/route.ts
29983
- import { join as join9 } from "path";
30090
+ import { join as join10 } from "path";
29984
30091
 
29985
30092
  // app/lib/whatsapp/login.ts
29986
30093
  import { randomUUID as randomUUID8 } from "crypto";
@@ -30210,7 +30317,7 @@ async function POST9(req) {
30210
30317
  const body = await req.json().catch(() => ({}));
30211
30318
  const accountId = validateAccountId(body.accountId);
30212
30319
  const force = body.force ?? false;
30213
- const authDir = join9(MAXY_DIR, "credentials", "whatsapp", accountId);
30320
+ const authDir = join10(MAXY_DIR, "credentials", "whatsapp", accountId);
30214
30321
  const result = await startLogin({ accountId, authDir, force });
30215
30322
  console.error(`[whatsapp:api] login/start result account=${accountId} hasQr=${!!result.qrRaw}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
30216
30323
  return Response.json(result);
@@ -30424,7 +30531,7 @@ function serializeWhatsAppSchema() {
30424
30531
 
30425
30532
  // app/api/whatsapp/config/route.ts
30426
30533
  import { resolve as resolve16 } from "path";
30427
- import { readdirSync as readdirSync4, readFileSync as readFileSync16, existsSync as existsSync15 } from "fs";
30534
+ import { readdirSync as readdirSync4, readFileSync as readFileSync17, existsSync as existsSync16 } from "fs";
30428
30535
  async function POST14(req) {
30429
30536
  try {
30430
30537
  const body = await req.json().catch(() => ({}));
@@ -30474,15 +30581,15 @@ async function POST14(req) {
30474
30581
  case "list-public-agents": {
30475
30582
  const agentsDir = resolve16(account.accountDir, "agents");
30476
30583
  const agents = [];
30477
- if (existsSync15(agentsDir)) {
30584
+ if (existsSync16(agentsDir)) {
30478
30585
  try {
30479
30586
  const entries = readdirSync4(agentsDir, { withFileTypes: true });
30480
30587
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
30481
30588
  if (!entry.isDirectory() || entry.name === "admin") continue;
30482
30589
  const configPath2 = resolve16(agentsDir, entry.name, "config.json");
30483
- if (!existsSync15(configPath2)) continue;
30590
+ if (!existsSync16(configPath2)) continue;
30484
30591
  try {
30485
- const config2 = JSON.parse(readFileSync16(configPath2, "utf-8"));
30592
+ const config2 = JSON.parse(readFileSync17(configPath2, "utf-8"));
30486
30593
  agents.push({ slug: entry.name, displayName: config2.displayName ?? entry.name });
30487
30594
  } catch {
30488
30595
  console.error(`[whatsapp:api] config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
@@ -30898,15 +31005,15 @@ async function POST17(req, remoteAddress) {
30898
31005
  }
30899
31006
 
30900
31007
  // app/api/onboarding/set-pin/route.ts
30901
- import { existsSync as existsSync16, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync17, unlinkSync as unlinkSync2 } from "fs";
31008
+ import { existsSync as existsSync17, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync18, unlinkSync as unlinkSync2 } from "fs";
30902
31009
  import { createHash, randomUUID as randomUUID9 } from "crypto";
30903
31010
  import { dirname as dirname6 } from "path";
30904
31011
  function hashPin(pin) {
30905
31012
  return createHash("sha256").update(pin).digest("hex");
30906
31013
  }
30907
31014
  function readUsersFile() {
30908
- if (!existsSync16(USERS_FILE)) return null;
30909
- const raw2 = readFileSync17(USERS_FILE, "utf-8").trim();
31015
+ if (!existsSync17(USERS_FILE)) return null;
31016
+ const raw2 = readFileSync18(USERS_FILE, "utf-8").trim();
30910
31017
  if (!raw2) return [];
30911
31018
  return JSON.parse(raw2);
30912
31019
  }
@@ -30944,7 +31051,7 @@ async function POST18(req) {
30944
31051
  const account = resolveAccount();
30945
31052
  if (account) {
30946
31053
  try {
30947
- const config2 = JSON.parse(readFileSync17(`${account.accountDir}/account.json`, "utf-8"));
31054
+ const config2 = JSON.parse(readFileSync18(`${account.accountDir}/account.json`, "utf-8"));
30948
31055
  if (!config2.admins) config2.admins = [];
30949
31056
  if (!config2.admins.some((a) => a.userId === userId)) {
30950
31057
  config2.admins.push({ userId, role: "owner" });
@@ -30995,7 +31102,7 @@ async function DELETE(req) {
30995
31102
  }
30996
31103
 
30997
31104
  // app/api/onboarding/skip/route.ts
30998
- import { existsSync as existsSync17, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync18 } from "fs";
31105
+ import { existsSync as existsSync18, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync19 } from "fs";
30999
31106
  import { resolve as resolve18, dirname as dirname7 } from "path";
31000
31107
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
31001
31108
  async function POST19() {
@@ -31007,9 +31114,9 @@ async function POST19() {
31007
31114
  const { accountId, accountDir } = account;
31008
31115
  let agentName = "Maxy";
31009
31116
  const brandPath3 = PLATFORM_ROOT8 ? resolve18(PLATFORM_ROOT8, "config", "brand.json") : "";
31010
- if (brandPath3 && existsSync17(brandPath3)) {
31117
+ if (brandPath3 && existsSync18(brandPath3)) {
31011
31118
  try {
31012
- const brand = JSON.parse(readFileSync18(brandPath3, "utf-8"));
31119
+ const brand = JSON.parse(readFileSync19(brandPath3, "utf-8"));
31013
31120
  if (brand.productName) agentName = brand.productName;
31014
31121
  } catch (err) {
31015
31122
  console.error(`[onboarding-skip] brand.json read failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -31055,14 +31162,14 @@ async function POST19() {
31055
31162
  }
31056
31163
 
31057
31164
  // app/api/admin/session/route.ts
31058
- import { readFileSync as readFileSync19, existsSync as existsSync18 } from "fs";
31165
+ import { readFileSync as readFileSync20, existsSync as existsSync19 } from "fs";
31059
31166
  import { createHash as createHash2 } from "crypto";
31060
31167
  function hashPin2(pin) {
31061
31168
  return createHash2("sha256").update(pin).digest("hex");
31062
31169
  }
31063
31170
  function readUsersFile2() {
31064
- if (!existsSync18(USERS_FILE)) return null;
31065
- const raw2 = readFileSync19(USERS_FILE, "utf-8").trim();
31171
+ if (!existsSync19(USERS_FILE)) return null;
31172
+ const raw2 = readFileSync20(USERS_FILE, "utf-8").trim();
31066
31173
  if (!raw2) return [];
31067
31174
  return JSON.parse(raw2);
31068
31175
  }
@@ -31463,7 +31570,7 @@ async function POST22(req) {
31463
31570
  }
31464
31571
 
31465
31572
  // app/api/admin/logs/route.ts
31466
- import { existsSync as existsSync19, readdirSync as readdirSync5, readFileSync as readFileSync20, statSync as statSync7 } from "fs";
31573
+ import { existsSync as existsSync20, readdirSync as readdirSync5, readFileSync as readFileSync21, statSync as statSync7 } from "fs";
31467
31574
  import { resolve as resolve19, basename as basename5 } from "path";
31468
31575
  var TAIL_BYTES = 8192;
31469
31576
  async function GET9(request) {
@@ -31482,7 +31589,7 @@ async function GET9(request) {
31482
31589
  const filePath = resolve19(dir, safe);
31483
31590
  searched.push(filePath);
31484
31591
  try {
31485
- const content = readFileSync20(filePath, "utf-8");
31592
+ const content = readFileSync21(filePath, "utf-8");
31486
31593
  const headers = { "Content-Type": "text/plain; charset=utf-8" };
31487
31594
  if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
31488
31595
  return new Response(content, { headers });
@@ -31524,7 +31631,7 @@ async function GET9(request) {
31524
31631
  const filePath = resolve19(dir, fileName);
31525
31632
  searched.push(filePath);
31526
31633
  try {
31527
- const content = readFileSync20(filePath, "utf-8");
31634
+ const content = readFileSync21(filePath, "utf-8");
31528
31635
  const headers = { "Content-Type": "text/plain; charset=utf-8" };
31529
31636
  if (download) headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
31530
31637
  return new Response(content, { headers });
@@ -31539,7 +31646,7 @@ async function GET9(request) {
31539
31646
  const seen = /* @__PURE__ */ new Set();
31540
31647
  const logs = {};
31541
31648
  for (const dir of [accountLogDir2, LOG_DIR]) {
31542
- if (!dir || !existsSync19(dir)) continue;
31649
+ if (!dir || !existsSync20(dir)) continue;
31543
31650
  let files;
31544
31651
  try {
31545
31652
  files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
@@ -31551,7 +31658,7 @@ async function GET9(request) {
31551
31658
  files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync7(resolve19(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
31552
31659
  seen.add(name);
31553
31660
  try {
31554
- const content = readFileSync20(resolve19(dir, name));
31661
+ const content = readFileSync21(resolve19(dir, name));
31555
31662
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
31556
31663
  logs[name] = tail.trim() || "(empty)";
31557
31664
  } catch (err) {
@@ -31588,7 +31695,7 @@ async function GET10() {
31588
31695
 
31589
31696
  // app/api/admin/attachment/[attachmentId]/route.ts
31590
31697
  import { readFile as readFile3, readdir } from "fs/promises";
31591
- import { existsSync as existsSync20 } from "fs";
31698
+ import { existsSync as existsSync21 } from "fs";
31592
31699
  import { resolve as resolve20 } from "path";
31593
31700
  async function GET11(req, attachmentId) {
31594
31701
  const sessionKey = new URL(req.url).searchParams.get("session_key") ?? "";
@@ -31603,11 +31710,11 @@ async function GET11(req, attachmentId) {
31603
31710
  return new Response("Not found", { status: 404 });
31604
31711
  }
31605
31712
  const dir = resolve20(ATTACHMENTS_ROOT, accountId, attachmentId);
31606
- if (!existsSync20(dir)) {
31713
+ if (!existsSync21(dir)) {
31607
31714
  return new Response("Not found", { status: 404 });
31608
31715
  }
31609
31716
  const metaPath = resolve20(dir, `${attachmentId}.meta.json`);
31610
- if (!existsSync20(metaPath)) {
31717
+ if (!existsSync21(metaPath)) {
31611
31718
  return new Response("Not found", { status: 404 });
31612
31719
  }
31613
31720
  let meta3;
@@ -31633,7 +31740,7 @@ async function GET11(req, attachmentId) {
31633
31740
  }
31634
31741
 
31635
31742
  // app/api/admin/account/route.ts
31636
- import { readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "fs";
31743
+ import { readFileSync as readFileSync22, writeFileSync as writeFileSync15 } from "fs";
31637
31744
  import { resolve as resolve21 } from "path";
31638
31745
  var VALID_CONTEXT_MODES = ["managed", "claude-code"];
31639
31746
  async function PATCH(req) {
@@ -31659,7 +31766,7 @@ async function PATCH(req) {
31659
31766
  }
31660
31767
  const configPath2 = resolve21(account.accountDir, "account.json");
31661
31768
  try {
31662
- const raw2 = readFileSync21(configPath2, "utf-8");
31769
+ const raw2 = readFileSync22(configPath2, "utf-8");
31663
31770
  const config2 = JSON.parse(raw2);
31664
31771
  config2.contextMode = contextMode;
31665
31772
  writeFileSync15(configPath2, JSON.stringify(config2, null, 2) + "\n", "utf-8");
@@ -31673,14 +31780,14 @@ async function PATCH(req) {
31673
31780
 
31674
31781
  // app/api/admin/agents/route.ts
31675
31782
  import { resolve as resolve22 } from "path";
31676
- import { readdirSync as readdirSync6, readFileSync as readFileSync22, existsSync as existsSync21 } from "fs";
31783
+ import { readdirSync as readdirSync6, readFileSync as readFileSync23, existsSync as existsSync22 } from "fs";
31677
31784
  async function GET12() {
31678
31785
  const account = resolveAccount();
31679
31786
  if (!account) {
31680
31787
  return Response.json({ agents: [] });
31681
31788
  }
31682
31789
  const agentsDir = resolve22(account.accountDir, "agents");
31683
- if (!existsSync21(agentsDir)) {
31790
+ if (!existsSync22(agentsDir)) {
31684
31791
  return Response.json({ agents: [] });
31685
31792
  }
31686
31793
  const agents = [];
@@ -31690,9 +31797,9 @@ async function GET12() {
31690
31797
  if (!entry.isDirectory()) continue;
31691
31798
  if (entry.name === "admin") continue;
31692
31799
  const configPath2 = resolve22(agentsDir, entry.name, "config.json");
31693
- if (!existsSync21(configPath2)) continue;
31800
+ if (!existsSync22(configPath2)) continue;
31694
31801
  try {
31695
- const config2 = JSON.parse(readFileSync22(configPath2, "utf-8"));
31802
+ const config2 = JSON.parse(readFileSync23(configPath2, "utf-8"));
31696
31803
  agents.push({
31697
31804
  slug: entry.name,
31698
31805
  displayName: config2.displayName ?? entry.name,
@@ -31711,7 +31818,7 @@ async function GET12() {
31711
31818
 
31712
31819
  // app/api/admin/agents/[slug]/route.ts
31713
31820
  import { resolve as resolve23 } from "path";
31714
- import { existsSync as existsSync22, rmSync as rmSync2 } from "fs";
31821
+ import { existsSync as existsSync23, rmSync as rmSync2 } from "fs";
31715
31822
  async function DELETE2(_req, { params }) {
31716
31823
  const { slug } = await params;
31717
31824
  const account = resolveAccount();
@@ -31725,7 +31832,7 @@ async function DELETE2(_req, { params }) {
31725
31832
  return Response.json({ error: "Invalid agent slug" }, { status: 400 });
31726
31833
  }
31727
31834
  const agentDir = resolve23(account.accountDir, "agents", slug);
31728
- if (!existsSync22(agentDir)) {
31835
+ if (!existsSync23(agentDir)) {
31729
31836
  return Response.json({ error: "Agent not found" }, { status: 404 });
31730
31837
  }
31731
31838
  try {
@@ -31739,15 +31846,15 @@ async function DELETE2(_req, { params }) {
31739
31846
  }
31740
31847
 
31741
31848
  // app/api/admin/version/route.ts
31742
- import { readFileSync as readFileSync23, existsSync as existsSync23 } from "fs";
31743
- import { resolve as resolve24, join as join10 } from "path";
31849
+ import { readFileSync as readFileSync24, existsSync as existsSync24 } from "fs";
31850
+ import { resolve as resolve24, join as join11 } from "path";
31744
31851
  var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
31745
31852
  var brandHostname = "maxy";
31746
31853
  var brandNpmPackage = "@rubytech/create-maxy";
31747
- var brandJsonPath = join10(PLATFORM_ROOT9, "config", "brand.json");
31748
- if (existsSync23(brandJsonPath)) {
31854
+ var brandJsonPath = join11(PLATFORM_ROOT9, "config", "brand.json");
31855
+ if (existsSync24(brandJsonPath)) {
31749
31856
  try {
31750
- const brand = JSON.parse(readFileSync23(brandJsonPath, "utf-8"));
31857
+ const brand = JSON.parse(readFileSync24(brandJsonPath, "utf-8"));
31751
31858
  if (brand.hostname) brandHostname = brand.hostname;
31752
31859
  if (brand.npm?.packageName) brandNpmPackage = brand.npm.packageName;
31753
31860
  } catch {
@@ -31758,8 +31865,8 @@ var NPM_PACKAGE = brandNpmPackage;
31758
31865
  var REGISTRY_URL = `https://registry.npmjs.org/${NPM_PACKAGE}/latest`;
31759
31866
  var FETCH_TIMEOUT_MS = 5e3;
31760
31867
  function readInstalled() {
31761
- if (!existsSync23(VERSION_FILE)) return "unknown";
31762
- const content = readFileSync23(VERSION_FILE, "utf-8").trim();
31868
+ if (!existsSync24(VERSION_FILE)) return "unknown";
31869
+ const content = readFileSync24(VERSION_FILE, "utf-8").trim();
31763
31870
  return content || "unknown";
31764
31871
  }
31765
31872
  async function fetchLatest() {
@@ -31810,15 +31917,15 @@ async function GET13() {
31810
31917
 
31811
31918
  // app/api/admin/version/upgrade/route.ts
31812
31919
  import { spawn as spawn4 } from "child_process";
31813
- import { existsSync as existsSync24, statSync as statSync8, writeFileSync as writeFileSync16, readFileSync as readFileSync24, openSync as openSync4, closeSync as closeSync4 } from "fs";
31814
- import { resolve as resolve25, join as join11 } from "path";
31920
+ import { existsSync as existsSync25, statSync as statSync8, writeFileSync as writeFileSync16, readFileSync as readFileSync25, openSync as openSync4, closeSync as closeSync4 } from "fs";
31921
+ import { resolve as resolve25, join as join12 } from "path";
31815
31922
  var PLATFORM_ROOT10 = process.env.MAXY_PLATFORM_ROOT ?? resolve25(process.cwd(), "..");
31816
31923
  var upgradePkg = "@rubytech/create-maxy";
31817
31924
  var upgradeHostname = "maxy";
31818
- var brandPath = join11(PLATFORM_ROOT10, "config", "brand.json");
31819
- if (existsSync24(brandPath)) {
31925
+ var brandPath = join12(PLATFORM_ROOT10, "config", "brand.json");
31926
+ if (existsSync25(brandPath)) {
31820
31927
  try {
31821
- const brand = JSON.parse(readFileSync24(brandPath, "utf-8"));
31928
+ const brand = JSON.parse(readFileSync25(brandPath, "utf-8"));
31822
31929
  if (brand.npm?.packageName) upgradePkg = brand.npm.packageName;
31823
31930
  if (brand.hostname) upgradeHostname = brand.hostname;
31824
31931
  } catch {
@@ -31828,7 +31935,7 @@ var LOCK_FILE = `/tmp/${upgradeHostname}-upgrade.lock`;
31828
31935
  var LOG_FILE = `/tmp/${upgradeHostname}-upgrade.log`;
31829
31936
  var LOCK_MAX_AGE_MS = 20 * 60 * 1e3;
31830
31937
  function isLockFresh() {
31831
- if (!existsSync24(LOCK_FILE)) return false;
31938
+ if (!existsSync25(LOCK_FILE)) return false;
31832
31939
  try {
31833
31940
  const stat4 = statSync8(LOCK_FILE);
31834
31941
  return Date.now() - stat4.mtimeMs < LOCK_MAX_AGE_MS;
@@ -31888,14 +31995,14 @@ async function POST23(req) {
31888
31995
  }
31889
31996
 
31890
31997
  // app/api/admin/version/upgrade/progress/route.ts
31891
- import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
31892
- import { resolve as resolve26, join as join12 } from "path";
31998
+ import { existsSync as existsSync26, readFileSync as readFileSync26 } from "fs";
31999
+ import { resolve as resolve26, join as join13 } from "path";
31893
32000
  var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
31894
32001
  var upgradeHostname2 = "maxy";
31895
- var brandPath2 = join12(PLATFORM_ROOT11, "config", "brand.json");
31896
- if (existsSync25(brandPath2)) {
32002
+ var brandPath2 = join13(PLATFORM_ROOT11, "config", "brand.json");
32003
+ if (existsSync26(brandPath2)) {
31897
32004
  try {
31898
- const brand = JSON.parse(readFileSync25(brandPath2, "utf-8"));
32005
+ const brand = JSON.parse(readFileSync26(brandPath2, "utf-8"));
31899
32006
  if (brand.hostname) upgradeHostname2 = brand.hostname;
31900
32007
  } catch {
31901
32008
  }
@@ -31903,12 +32010,12 @@ if (existsSync25(brandPath2)) {
31903
32010
  var LOG_FILE2 = `/tmp/${upgradeHostname2}-upgrade.log`;
31904
32011
  var STEP_RE = /\[(\d+)\/(\d+)\]\s+(.+)/;
31905
32012
  async function GET14() {
31906
- if (!existsSync25(LOG_FILE2)) {
32013
+ if (!existsSync26(LOG_FILE2)) {
31907
32014
  return Response.json({ step: 0, total: 0, label: "", started: false });
31908
32015
  }
31909
32016
  let content;
31910
32017
  try {
31911
- content = readFileSync25(LOG_FILE2, "utf-8");
32018
+ content = readFileSync26(LOG_FILE2, "utf-8");
31912
32019
  } catch {
31913
32020
  return Response.json({ step: 0, total: 0, label: "", started: false });
31914
32021
  }
@@ -32374,14 +32481,14 @@ async function POST29(req) {
32374
32481
 
32375
32482
  // server/index.ts
32376
32483
  var PLATFORM_ROOT12 = process.env.MAXY_PLATFORM_ROOT || "";
32377
- var BRAND_JSON_PATH = PLATFORM_ROOT12 ? join13(PLATFORM_ROOT12, "config", "brand.json") : "";
32484
+ var BRAND_JSON_PATH = PLATFORM_ROOT12 ? join14(PLATFORM_ROOT12, "config", "brand.json") : "";
32378
32485
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
32379
- if (BRAND_JSON_PATH && !existsSync26(BRAND_JSON_PATH)) {
32486
+ if (BRAND_JSON_PATH && !existsSync27(BRAND_JSON_PATH)) {
32380
32487
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
32381
32488
  }
32382
- if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
32489
+ if (BRAND_JSON_PATH && existsSync27(BRAND_JSON_PATH)) {
32383
32490
  try {
32384
- const parsed = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
32491
+ const parsed = JSON.parse(readFileSync27(BRAND_JSON_PATH, "utf-8"));
32385
32492
  BRAND = { ...BRAND, ...parsed };
32386
32493
  } catch (err) {
32387
32494
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -32400,11 +32507,11 @@ var brandLoginOpts = {
32400
32507
  bodyFont: BRAND.defaultFonts?.body,
32401
32508
  logoContainsName: !!BRAND.logoContainsName
32402
32509
  };
32403
- var ALIAS_DOMAINS_PATH = join13(homedir4(), BRAND.configDir, "alias-domains.json");
32510
+ var ALIAS_DOMAINS_PATH = join14(homedir4(), BRAND.configDir, "alias-domains.json");
32404
32511
  function loadAliasDomains() {
32405
32512
  try {
32406
- if (!existsSync26(ALIAS_DOMAINS_PATH)) return null;
32407
- const parsed = JSON.parse(readFileSync26(ALIAS_DOMAINS_PATH, "utf-8"));
32513
+ if (!existsSync27(ALIAS_DOMAINS_PATH)) return null;
32514
+ const parsed = JSON.parse(readFileSync27(ALIAS_DOMAINS_PATH, "utf-8"));
32408
32515
  if (!Array.isArray(parsed)) {
32409
32516
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
32410
32517
  return null;
@@ -32822,14 +32929,14 @@ app.get("/agent-assets/:slug/:filename", (c) => {
32822
32929
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
32823
32930
  return c.text("Forbidden", 403);
32824
32931
  }
32825
- if (!existsSync26(filePath)) {
32932
+ if (!existsSync27(filePath)) {
32826
32933
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
32827
32934
  return c.text("Not found", 404);
32828
32935
  }
32829
32936
  const ext = "." + filename.split(".").pop()?.toLowerCase();
32830
32937
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
32831
32938
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
32832
- const body = readFileSync26(filePath);
32939
+ const body = readFileSync27(filePath);
32833
32940
  return c.body(body, 200, {
32834
32941
  "Content-Type": contentType,
32835
32942
  "Cache-Control": "public, max-age=3600"
@@ -32852,14 +32959,14 @@ app.get("/generated/:filename", (c) => {
32852
32959
  console.error(`[generated] serve file=${filename} status=403`);
32853
32960
  return c.text("Forbidden", 403);
32854
32961
  }
32855
- if (!existsSync26(filePath)) {
32962
+ if (!existsSync27(filePath)) {
32856
32963
  console.error(`[generated] serve file=${filename} status=404`);
32857
32964
  return c.text("Not found", 404);
32858
32965
  }
32859
32966
  const ext = "." + filename.split(".").pop()?.toLowerCase();
32860
32967
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
32861
32968
  console.log(`[generated] serve file=${filename} status=200`);
32862
- const body = readFileSync26(filePath);
32969
+ const body = readFileSync27(filePath);
32863
32970
  return c.body(body, 200, {
32864
32971
  "Content-Type": contentType,
32865
32972
  "Cache-Control": "public, max-age=86400"
@@ -32868,9 +32975,9 @@ app.get("/generated/:filename", (c) => {
32868
32975
  var htmlCache = /* @__PURE__ */ new Map();
32869
32976
  var brandLogoPath = "/brand/maxy-monochrome.png";
32870
32977
  var brandIconPath = "/brand/maxy-monochrome.png";
32871
- if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
32978
+ if (BRAND_JSON_PATH && existsSync27(BRAND_JSON_PATH)) {
32872
32979
  try {
32873
- const fullBrand = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
32980
+ const fullBrand = JSON.parse(readFileSync27(BRAND_JSON_PATH, "utf-8"));
32874
32981
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
32875
32982
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
32876
32983
  } catch {
@@ -32887,7 +32994,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
32887
32994
  function cachedHtml(file2) {
32888
32995
  let html = htmlCache.get(file2);
32889
32996
  if (!html) {
32890
- html = readFileSync26(resolve27(process.cwd(), "public", file2), "utf-8");
32997
+ html = readFileSync27(resolve27(process.cwd(), "public", file2), "utf-8");
32891
32998
  html = html.replace("<title>Maxy</title>", `<title>${escapeHtml2(BRAND.productName)}</title>`);
32892
32999
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml2(brandFaviconPath)}"`);
32893
33000
  html = html.replace("</head>", `${brandScript}
@@ -32898,26 +33005,26 @@ function cachedHtml(file2) {
32898
33005
  }
32899
33006
  var brandedHtmlCache = /* @__PURE__ */ new Map();
32900
33007
  function loadBrandingCache(agentSlug) {
32901
- const configDir2 = join13(homedir4(), BRAND.configDir);
33008
+ const configDir2 = join14(homedir4(), BRAND.configDir);
32902
33009
  try {
32903
- const accountJsonPath = join13(configDir2, "account.json");
32904
- if (!existsSync26(accountJsonPath)) return null;
32905
- const account = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
33010
+ const accountJsonPath = join14(configDir2, "account.json");
33011
+ if (!existsSync27(accountJsonPath)) return null;
33012
+ const account = JSON.parse(readFileSync27(accountJsonPath, "utf-8"));
32906
33013
  const accountId = account.accountId;
32907
33014
  if (!accountId) return null;
32908
- const cachePath = join13(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
32909
- if (!existsSync26(cachePath)) return null;
32910
- return JSON.parse(readFileSync26(cachePath, "utf-8"));
33015
+ const cachePath = join14(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
33016
+ if (!existsSync27(cachePath)) return null;
33017
+ return JSON.parse(readFileSync27(cachePath, "utf-8"));
32911
33018
  } catch {
32912
33019
  return null;
32913
33020
  }
32914
33021
  }
32915
33022
  function resolveDefaultSlug() {
32916
33023
  try {
32917
- const configDir2 = join13(homedir4(), BRAND.configDir);
32918
- const accountJsonPath = join13(configDir2, "account.json");
32919
- if (!existsSync26(accountJsonPath)) return null;
32920
- const account = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
33024
+ const configDir2 = join14(homedir4(), BRAND.configDir);
33025
+ const accountJsonPath = join14(configDir2, "account.json");
33026
+ if (!existsSync27(accountJsonPath)) return null;
33027
+ const account = JSON.parse(readFileSync27(accountJsonPath, "utf-8"));
32921
33028
  return account.defaultAgent || null;
32922
33029
  } catch {
32923
33030
  return null;
@@ -32990,7 +33097,7 @@ app.use("/vnc-popout.html", logViewerFetch);
32990
33097
  app.get("/vnc-popout.html", (c) => {
32991
33098
  let html = htmlCache.get("vnc-popout.html");
32992
33099
  if (!html) {
32993
- html = readFileSync26(resolve27(process.cwd(), "public", "vnc-popout.html"), "utf-8");
33100
+ html = readFileSync27(resolve27(process.cwd(), "public", "vnc-popout.html"), "utf-8");
32994
33101
  const name = escapeHtml2(BRAND.productName);
32995
33102
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
32996
33103
  html = html.replace("</head>", ` ${brandScript}
@@ -33044,8 +33151,8 @@ console.log(`${BRAND.productName} listening on http://${hostname3}:${port}`);
33044
33151
  (async () => {
33045
33152
  try {
33046
33153
  let userId = "";
33047
- if (existsSync26(USERS_FILE)) {
33048
- const users = JSON.parse(readFileSync26(USERS_FILE, "utf-8").trim() || "[]");
33154
+ if (existsSync27(USERS_FILE)) {
33155
+ const users = JSON.parse(readFileSync27(USERS_FILE, "utf-8").trim() || "[]");
33049
33156
  userId = users[0]?.userId ?? "";
33050
33157
  }
33051
33158
  await backfillNullUserIdConversations(userId);
@@ -33071,7 +33178,7 @@ if (bootAccountConfig?.whatsapp) {
33071
33178
  }
33072
33179
  init({
33073
33180
  configDir: configDirForWhatsApp,
33074
- platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ?? join13(__dirname, "..")),
33181
+ platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ?? join14(__dirname, "..")),
33075
33182
  accountConfig: bootAccountConfig,
33076
33183
  onMessage: async (msg) => {
33077
33184
  try {