@rubytech/create-maxy 1.0.623 → 1.0.625

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 (26) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/anthropic-key/dist/index.d.ts +1 -0
  3. package/payload/platform/lib/anthropic-key/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/anthropic-key/dist/index.js +30 -0
  5. package/payload/platform/lib/anthropic-key/dist/index.js.map +1 -1
  6. package/payload/platform/plugins/admin/mcp/dist/index.js +21 -8
  7. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  8. package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +9 -12
  9. package/payload/platform/plugins/cloudflare/PLUGIN.md +31 -44
  10. package/payload/platform/plugins/cloudflare/mcp/dist/index.js +13 -875
  11. package/payload/platform/plugins/cloudflare/mcp/dist/index.js.map +1 -1
  12. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts.map +1 -1
  13. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js +1 -0
  14. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js.map +1 -1
  15. package/payload/platform/plugins/cloudflare/references/dashboard-guide.md +108 -0
  16. package/payload/platform/plugins/cloudflare/references/manual-setup.md +445 -0
  17. package/payload/platform/plugins/cloudflare/references/reset-guide.md +118 -0
  18. package/payload/platform/plugins/cloudflare/scripts/reset-tunnel.sh +65 -0
  19. package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +244 -0
  20. package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +96 -5
  21. package/payload/platform/plugins/docs/references/cloudflare.md +91 -34
  22. package/payload/platform/templates/agents/admin/IDENTITY.md +10 -4
  23. package/payload/platform/templates/specialists/agents/personal-assistant.md +9 -9
  24. package/payload/server/server.js +206 -298
  25. package/payload/platform/config/cloudflared.yml +0 -17
  26. package/payload/platform/plugins/cloudflare/references/setup-guide.md +0 -132
@@ -2896,8 +2896,8 @@ var serveStatic = (options = { root: "" }) => {
2896
2896
  };
2897
2897
 
2898
2898
  // server/index.ts
2899
- import { readFileSync as readFileSync27, existsSync as existsSync27, watchFile } from "fs";
2900
- import { resolve as resolve27, join as join14, basename as basename6 } from "path";
2899
+ import { readFileSync as readFileSync26, existsSync as existsSync26, watchFile } from "fs";
2900
+ import { resolve as resolve27, join as join13, 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 existsSync12, readFileSync as readFileSync13 } from "fs";
3832
+ import { existsSync as existsSync11, readFileSync as readFileSync12 } from "fs";
3833
3833
  import { createConnection as createConnection3 } from "net";
3834
3834
 
3835
3835
  // app/lib/claude-auth.ts
@@ -4005,6 +4005,7 @@ import {
4005
4005
  existsSync as existsSync4,
4006
4006
  mkdirSync as mkdirSync2,
4007
4007
  readFileSync as readFileSync4,
4008
+ unlinkSync,
4008
4009
  writeFileSync as writeFileSync3
4009
4010
  } from "fs";
4010
4011
  import { resolve as resolve3, join as join3, dirname } from "path";
@@ -4164,9 +4165,9 @@ function keyFilePath() {
4164
4165
  import Anthropic2 from "@anthropic-ai/sdk";
4165
4166
  import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
4166
4167
  import { randomUUID as randomUUID2 } from "crypto";
4167
- import { resolve as resolve6, join as join5 } from "path";
4168
+ import { resolve as resolve6, join as join4 } from "path";
4168
4169
  import { platform as osPlatform } from "os";
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
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, readdirSync as readdirSync2, existsSync as existsSync6, mkdirSync as mkdirSync4, createWriteStream, statSync as statSync3, unlinkSync as unlinkSync2, cpSync, rmSync } from "fs";
4170
4171
  import { lookup as dnsLookup } from "dns/promises";
4171
4172
  import { createConnection as netConnect } from "net";
4172
4173
  import { StringDecoder } from "string_decoder";
@@ -6037,73 +6038,6 @@ ${items}
6037
6038
  </commitment-detected>`;
6038
6039
  }
6039
6040
 
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
-
6107
6041
  // app/lib/claude-agent.ts
6108
6042
  var LOG_RETENTION_DAYS = 7;
6109
6043
  var BROWSER_TOOL_PREFIXES = [
@@ -6270,7 +6204,7 @@ function purgeOldLogs(logDir, prefix) {
6270
6204
  if (!file2.startsWith(prefix)) continue;
6271
6205
  const filePath = resolve6(logDir, file2);
6272
6206
  try {
6273
- if (statSync3(filePath).mtimeMs < cutoff) unlinkSync(filePath);
6207
+ if (statSync3(filePath).mtimeMs < cutoff) unlinkSync2(filePath);
6274
6208
  } catch (err) {
6275
6209
  const msg = err instanceof Error ? err.message : String(err);
6276
6210
  console.error(`[log-purge-err] file=${file2} reason=${msg}`);
@@ -6337,7 +6271,7 @@ function sampleProcState(pid) {
6337
6271
  let sockets2 = 0;
6338
6272
  for (const tcpFile of ["/proc/" + pid + "/net/tcp", "/proc/" + pid + "/net/tcp6"]) {
6339
6273
  try {
6340
- const raw2 = readFileSync8(tcpFile, "utf-8");
6274
+ const raw2 = readFileSync7(tcpFile, "utf-8");
6341
6275
  const lines2 = raw2.split("\n");
6342
6276
  for (let i = 1; i < lines2.length; i++) {
6343
6277
  const line = lines2[i].trim();
@@ -6353,7 +6287,7 @@ function sampleProcState(pid) {
6353
6287
  }
6354
6288
  let rssMb = 0;
6355
6289
  try {
6356
- const statm = readFileSync8(`/proc/${pid}/statm`, "utf-8").trim().split(/\s+/);
6290
+ const statm = readFileSync7(`/proc/${pid}/statm`, "utf-8").trim().split(/\s+/);
6357
6291
  const rssPages = parseInt(statm[1] ?? "0", 10);
6358
6292
  if (Number.isFinite(rssPages)) rssMb = Math.round(rssPages * 4096 / (1024 * 1024));
6359
6293
  } catch {
@@ -6388,19 +6322,19 @@ function sampleProcState(pid) {
6388
6322
  }
6389
6323
  var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "..");
6390
6324
  var ACCOUNTS_DIR = resolve6(PLATFORM_ROOT4, "..", "data/accounts");
6391
- if (!existsSync7(PLATFORM_ROOT4)) {
6325
+ if (!existsSync6(PLATFORM_ROOT4)) {
6392
6326
  throw new Error(
6393
6327
  `PLATFORM_ROOT does not exist: ${PLATFORM_ROOT4}
6394
6328
  Set the MAXY_PLATFORM_ROOT environment variable to the absolute path of the platform directory.`
6395
6329
  );
6396
6330
  }
6397
6331
  function resolveAccount() {
6398
- if (!existsSync7(ACCOUNTS_DIR)) return null;
6332
+ if (!existsSync6(ACCOUNTS_DIR)) return null;
6399
6333
  const usersFilePath = resolve6(PLATFORM_ROOT4, "config", "users.json");
6400
6334
  let usersJsonUserId = null;
6401
- if (existsSync7(usersFilePath)) {
6335
+ if (existsSync6(usersFilePath)) {
6402
6336
  try {
6403
- const raw2 = readFileSync8(usersFilePath, "utf-8").trim();
6337
+ const raw2 = readFileSync7(usersFilePath, "utf-8").trim();
6404
6338
  if (raw2) {
6405
6339
  const users = JSON.parse(raw2);
6406
6340
  if (users.length > 0) {
@@ -6415,8 +6349,8 @@ function resolveAccount() {
6415
6349
  for (const entry of entries) {
6416
6350
  if (!entry.isDirectory()) continue;
6417
6351
  const configPath2 = resolve6(ACCOUNTS_DIR, entry.name, "account.json");
6418
- if (!existsSync7(configPath2)) continue;
6419
- const raw2 = readFileSync8(configPath2, "utf-8");
6352
+ if (!existsSync6(configPath2)) continue;
6353
+ const raw2 = readFileSync7(configPath2, "utf-8");
6420
6354
  let config2;
6421
6355
  try {
6422
6356
  config2 = JSON.parse(raw2);
@@ -6450,8 +6384,8 @@ function resolveAccount() {
6450
6384
  }
6451
6385
  function readAgentFile(accountDir, agentName, filename) {
6452
6386
  const filePath = resolve6(accountDir, "agents", agentName, filename);
6453
- if (!existsSync7(filePath)) return null;
6454
- return readFileSync8(filePath, "utf-8");
6387
+ if (!existsSync6(filePath)) return null;
6388
+ return readFileSync7(filePath, "utf-8");
6455
6389
  }
6456
6390
  function readIdentity(accountDir, agentName) {
6457
6391
  return readAgentFile(accountDir, agentName, "IDENTITY.md");
@@ -6468,13 +6402,13 @@ function validateAgentSlug(slug) {
6468
6402
  }
6469
6403
  function resolveDefaultAgentSlug(accountDir) {
6470
6404
  const configPath2 = resolve6(accountDir, "account.json");
6471
- if (!existsSync7(configPath2)) {
6405
+ if (!existsSync6(configPath2)) {
6472
6406
  console.error("[agent-resolve] account.json not found \u2014 cannot resolve defaultAgent");
6473
6407
  return null;
6474
6408
  }
6475
6409
  let config2;
6476
6410
  try {
6477
- config2 = JSON.parse(readFileSync8(configPath2, "utf-8"));
6411
+ config2 = JSON.parse(readFileSync7(configPath2, "utf-8"));
6478
6412
  } catch (err) {
6479
6413
  console.error("[agent-resolve] failed to read account.json:", err);
6480
6414
  return null;
@@ -6484,7 +6418,7 @@ function resolveDefaultAgentSlug(accountDir) {
6484
6418
  return null;
6485
6419
  }
6486
6420
  const agentConfigPath = resolve6(accountDir, "agents", config2.defaultAgent, "config.json");
6487
- if (!existsSync7(agentConfigPath)) {
6421
+ if (!existsSync6(agentConfigPath)) {
6488
6422
  console.error(`[agent-resolve] defaultAgent="${config2.defaultAgent}" has no config.json at ${agentConfigPath}`);
6489
6423
  return null;
6490
6424
  }
@@ -6559,20 +6493,20 @@ function resolveAgentConfig(accountDir, agentName) {
6559
6493
  const agentDir = resolve6(accountDir, "agents", agentName);
6560
6494
  const knowledgePath = resolve6(agentDir, "KNOWLEDGE.md");
6561
6495
  const summaryPath = resolve6(agentDir, "KNOWLEDGE-SUMMARY.md");
6562
- const hasKnowledge = existsSync7(knowledgePath);
6563
- const hasSummary = existsSync7(summaryPath);
6496
+ const hasKnowledge = existsSync6(knowledgePath);
6497
+ const hasSummary = existsSync6(summaryPath);
6564
6498
  if (hasKnowledge && hasSummary) {
6565
6499
  const knowledgeMtime = statSync3(knowledgePath).mtimeMs;
6566
6500
  const summaryMtime = statSync3(summaryPath).mtimeMs;
6567
6501
  if (summaryMtime >= knowledgeMtime) {
6568
- knowledge = readFileSync8(summaryPath, "utf-8");
6502
+ knowledge = readFileSync7(summaryPath, "utf-8");
6569
6503
  } else {
6570
6504
  console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
6571
- knowledge = readFileSync8(knowledgePath, "utf-8");
6505
+ knowledge = readFileSync7(knowledgePath, "utf-8");
6572
6506
  }
6573
6507
  knowledgeBaked = true;
6574
6508
  } else if (hasKnowledge) {
6575
- knowledge = readFileSync8(knowledgePath, "utf-8");
6509
+ knowledge = readFileSync7(knowledgePath, "utf-8");
6576
6510
  knowledgeBaked = true;
6577
6511
  }
6578
6512
  let budget = null;
@@ -6595,10 +6529,10 @@ function resolveAgentConfig(accountDir, agentName) {
6595
6529
  }
6596
6530
  function parsePluginFrontmatter(pluginDir) {
6597
6531
  const pluginPath = resolve6(PLATFORM_ROOT4, "plugins", pluginDir, "PLUGIN.md");
6598
- if (!existsSync7(pluginPath)) return null;
6532
+ if (!existsSync6(pluginPath)) return null;
6599
6533
  let raw2;
6600
6534
  try {
6601
- raw2 = readFileSync8(pluginPath, "utf-8");
6535
+ raw2 = readFileSync7(pluginPath, "utf-8");
6602
6536
  } catch {
6603
6537
  console.warn(`[plugins] cannot read ${pluginPath}`);
6604
6538
  return null;
@@ -6659,22 +6593,22 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
6659
6593
  const TAG18 = "[premium-auto-deliver]";
6660
6594
  const stagingRoot = resolve6(PLATFORM_ROOT4, "../premium-plugins");
6661
6595
  const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
6662
- if (!existsSync7(stagingRoot)) {
6596
+ if (!existsSync6(stagingRoot)) {
6663
6597
  console.log(`${TAG18} no staging directory \u2014 skipping`);
6664
6598
  return;
6665
6599
  }
6666
6600
  for (const pluginName of purchasedPlugins) {
6667
6601
  const stagingDir = resolve6(stagingRoot, pluginName);
6668
- if (!existsSync7(stagingDir)) {
6602
+ if (!existsSync6(stagingDir)) {
6669
6603
  console.log(`${TAG18} ${pluginName}: not in staging \u2014 skipping`);
6670
6604
  continue;
6671
6605
  }
6672
- const bundlePath = join5(stagingDir, "BUNDLE.md");
6673
- const isBundle = existsSync7(bundlePath);
6606
+ const bundlePath = join4(stagingDir, "BUNDLE.md");
6607
+ const isBundle = existsSync6(bundlePath);
6674
6608
  if (isBundle) {
6675
6609
  let bundleRaw;
6676
6610
  try {
6677
- bundleRaw = readFileSync8(bundlePath, "utf-8");
6611
+ bundleRaw = readFileSync7(bundlePath, "utf-8");
6678
6612
  } catch (err) {
6679
6613
  console.log(`${TAG18} ${pluginName}: cannot read BUNDLE.md \u2014 ${err instanceof Error ? err.message : String(err)}`);
6680
6614
  continue;
@@ -6706,12 +6640,12 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
6706
6640
  let skipped = 0;
6707
6641
  for (const sub of subPlugins) {
6708
6642
  const target = resolve6(pluginsDir, sub);
6709
- if (existsSync7(resolve6(target, "PLUGIN.md"))) {
6643
+ if (existsSync6(resolve6(target, "PLUGIN.md"))) {
6710
6644
  skipped++;
6711
6645
  continue;
6712
6646
  }
6713
6647
  const source = resolve6(stagingDir, "plugins", sub);
6714
- if (!existsSync7(source)) {
6648
+ if (!existsSync6(source)) {
6715
6649
  console.log(`${TAG18} ${pluginName}/${sub}: source missing in staging \u2014 skipping`);
6716
6650
  continue;
6717
6651
  }
@@ -6725,7 +6659,7 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
6725
6659
  console.log(`${TAG18} ${pluginName} (bundle): ${delivered} delivered, ${skipped} already present`);
6726
6660
  } else {
6727
6661
  const target = resolve6(pluginsDir, pluginName);
6728
- if (existsSync7(resolve6(target, "PLUGIN.md"))) {
6662
+ if (existsSync6(resolve6(target, "PLUGIN.md"))) {
6729
6663
  console.log(`${TAG18} ${pluginName}: already present \u2014 skipping`);
6730
6664
  continue;
6731
6665
  }
@@ -6767,7 +6701,7 @@ function migratePluginRenames(accountDir, config2) {
6767
6701
  if (!changed) return;
6768
6702
  const configPath2 = resolve6(accountDir, "account.json");
6769
6703
  try {
6770
- const raw2 = readFileSync8(configPath2, "utf-8");
6704
+ const raw2 = readFileSync7(configPath2, "utf-8");
6771
6705
  const parsed = JSON.parse(raw2);
6772
6706
  parsed.enabledPlugins = migrated;
6773
6707
  writeFileSync5(configPath2, JSON.stringify(parsed, null, 2) + "\n");
@@ -6779,7 +6713,7 @@ function migratePluginRenames(accountDir, config2) {
6779
6713
  const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
6780
6714
  for (const oldName of Object.keys(PLUGIN_RENAMES)) {
6781
6715
  const orphan = resolve6(pluginsDir, oldName);
6782
- if (existsSync7(orphan)) {
6716
+ if (existsSync6(orphan)) {
6783
6717
  try {
6784
6718
  rmSync(orphan, { recursive: true });
6785
6719
  console.log(`${TAG18} removed orphan: ${oldName}`);
@@ -6794,20 +6728,20 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
6794
6728
  const TAG18 = "[bundle-agent-deliver]";
6795
6729
  const stagingRoot = resolve6(PLATFORM_ROOT4, "../premium-plugins");
6796
6730
  const specialistsDir = resolve6(accountDir, "specialists", "agents");
6797
- if (!existsSync7(stagingRoot)) return;
6798
- if (!existsSync7(specialistsDir)) {
6731
+ if (!existsSync6(stagingRoot)) return;
6732
+ if (!existsSync6(specialistsDir)) {
6799
6733
  mkdirSync4(specialistsDir, { recursive: true });
6800
6734
  }
6801
6735
  const agentsmdPath = resolve6(accountDir, "agents", "admin", "AGENTS.md");
6802
6736
  let agentsmd = "";
6803
6737
  try {
6804
- agentsmd = existsSync7(agentsmdPath) ? readFileSync8(agentsmdPath, "utf-8") : "";
6738
+ agentsmd = existsSync6(agentsmdPath) ? readFileSync7(agentsmdPath, "utf-8") : "";
6805
6739
  } catch {
6806
6740
  }
6807
6741
  let delivered = 0;
6808
6742
  for (const pluginName of purchasedPlugins) {
6809
6743
  const bundleAgentsDir = resolve6(stagingRoot, pluginName, "agents");
6810
- if (!existsSync7(bundleAgentsDir)) continue;
6744
+ if (!existsSync6(bundleAgentsDir)) continue;
6811
6745
  let entries;
6812
6746
  try {
6813
6747
  entries = readdirSync2(bundleAgentsDir).filter((f) => f.endsWith(".md"));
@@ -6816,7 +6750,7 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
6816
6750
  }
6817
6751
  for (const filename of entries) {
6818
6752
  const target = resolve6(specialistsDir, filename);
6819
- if (existsSync7(target)) continue;
6753
+ if (existsSync6(target)) continue;
6820
6754
  const source = resolve6(bundleAgentsDir, filename);
6821
6755
  try {
6822
6756
  cpSync(source, target);
@@ -6825,7 +6759,7 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
6825
6759
  continue;
6826
6760
  }
6827
6761
  try {
6828
- const content = readFileSync8(target, "utf-8");
6762
+ const content = readFileSync7(target, "utf-8");
6829
6763
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
6830
6764
  if (fmMatch) {
6831
6765
  const nameMatch = fmMatch[1].match(/^name:\s*(.+)/m);
@@ -6861,7 +6795,7 @@ function assemblePublicPluginContent(pluginDir) {
6861
6795
  const pluginPath = resolve6(pluginRoot, "PLUGIN.md");
6862
6796
  let raw2;
6863
6797
  try {
6864
- raw2 = readFileSync8(pluginPath, "utf-8");
6798
+ raw2 = readFileSync7(pluginPath, "utf-8");
6865
6799
  } catch {
6866
6800
  return null;
6867
6801
  }
@@ -6882,7 +6816,7 @@ function assemblePublicPluginContent(pluginDir) {
6882
6816
  const skillMdPath = resolve6(skillDir, "SKILL.md");
6883
6817
  let skillRaw;
6884
6818
  try {
6885
- skillRaw = readFileSync8(skillMdPath, "utf-8");
6819
+ skillRaw = readFileSync7(skillMdPath, "utf-8");
6886
6820
  } catch {
6887
6821
  continue;
6888
6822
  }
@@ -6933,7 +6867,7 @@ function assemblePublicPluginContent(pluginDir) {
6933
6867
  }
6934
6868
  for (const refFile of refFiles) {
6935
6869
  try {
6936
- const refContent = readFileSync8(resolve6(refsDir, refFile), "utf-8").trim();
6870
+ const refContent = readFileSync7(resolve6(refsDir, refFile), "utf-8").trim();
6937
6871
  if (refContent) {
6938
6872
  parts.push(`
6939
6873
  <!-- reference: ${refFile} -->`);
@@ -7007,7 +6941,7 @@ function loadEmbeddedPlugins(agentType, selectedPlugins, enabledPlugins) {
7007
6941
  const pluginPath = resolve6(pluginsDir, dir, "PLUGIN.md");
7008
6942
  let raw2;
7009
6943
  try {
7010
- raw2 = readFileSync8(pluginPath, "utf-8");
6944
+ raw2 = readFileSync7(pluginPath, "utf-8");
7011
6945
  } catch (err) {
7012
6946
  console.warn(`[plugins] ${dir}: failed to read PLUGIN.md for ${agentType} embed: ${String(err)}`);
7013
6947
  continue;
@@ -7032,7 +6966,7 @@ function fetchMcpToolsList(pluginDir) {
7032
6966
  const cached2 = mcpToolsCache.get(pluginDir);
7033
6967
  if (cached2) return Promise.resolve(cached2);
7034
6968
  const serverPath = resolve6(PLATFORM_ROOT4, "plugins", pluginDir, "mcp/dist/index.js");
7035
- if (!existsSync7(serverPath)) return Promise.resolve([]);
6969
+ if (!existsSync6(serverPath)) return Promise.resolve([]);
7036
6970
  const startMs = Date.now();
7037
6971
  return new Promise((resolvePromise) => {
7038
6972
  const proc = spawn2(process.execPath, [serverPath], {
@@ -7236,7 +7170,7 @@ ${specialist}: ${plugins.join(", ")}`);
7236
7170
  const references = [];
7237
7171
  const scanDir = (base, prefix, target) => {
7238
7172
  const scanPath = resolve6(pluginRoot, base);
7239
- if (!existsSync7(scanPath)) return;
7173
+ if (!existsSync6(scanPath)) return;
7240
7174
  try {
7241
7175
  const walk = (current, rel) => {
7242
7176
  for (const entry of readdirSync2(current)) {
@@ -7269,7 +7203,7 @@ ${specialist}: ${plugins.join(", ")}`);
7269
7203
  }
7270
7204
  } else if (parsed.tools.length > 0) {
7271
7205
  const serverPath = resolve6(PLATFORM_ROOT4, "plugins", dir, "mcp/dist/index.js");
7272
- if (existsSync7(serverPath)) {
7206
+ if (existsSync6(serverPath)) {
7273
7207
  fallbackSourced++;
7274
7208
  console.error(`[plugin-manifest] ${dir}: tools/list empty \u2014 fallback to frontmatter (${parsed.tools.length} tools)`);
7275
7209
  }
@@ -7344,16 +7278,16 @@ function getDefaultAccountId() {
7344
7278
  return resolveAccount()?.accountId ?? null;
7345
7279
  }
7346
7280
  function resolveUserAccounts(userId) {
7347
- if (!existsSync7(ACCOUNTS_DIR)) return [];
7281
+ if (!existsSync6(ACCOUNTS_DIR)) return [];
7348
7282
  const results = [];
7349
7283
  const entries = readdirSync2(ACCOUNTS_DIR, { withFileTypes: true });
7350
7284
  for (const entry of entries) {
7351
7285
  if (!entry.isDirectory()) continue;
7352
7286
  const configPath2 = resolve6(ACCOUNTS_DIR, entry.name, "account.json");
7353
- if (!existsSync7(configPath2)) continue;
7287
+ if (!existsSync6(configPath2)) continue;
7354
7288
  let config2;
7355
7289
  try {
7356
- config2 = JSON.parse(readFileSync8(configPath2, "utf-8"));
7290
+ config2 = JSON.parse(readFileSync7(configPath2, "utf-8"));
7357
7291
  } catch {
7358
7292
  console.error(`[session] account.json corrupt at ${configPath2} \u2014 skipping`);
7359
7293
  continue;
@@ -7673,7 +7607,7 @@ function getMcpServers(accountId, conversationId, userId, enabledPlugins) {
7673
7607
  }
7674
7608
  }
7675
7609
  const mcpEntry = resolve6(PLATFORM_ROOT4, "plugins", dir, "mcp/dist/index.js");
7676
- if (!existsSync7(mcpEntry)) continue;
7610
+ if (!existsSync6(mcpEntry)) continue;
7677
7611
  servers[dir] = {
7678
7612
  command: "node",
7679
7613
  args: [mcpEntry],
@@ -7751,16 +7685,6 @@ var ADMIN_CORE_TOOLS = [
7751
7685
  "mcp__admin__action-approve",
7752
7686
  "mcp__admin__action-reject",
7753
7687
  "mcp__admin__action-edit",
7754
- "mcp__cloudflare__tunnel-status",
7755
- "mcp__cloudflare__tunnel-install",
7756
- "mcp__cloudflare__tunnel-login",
7757
- "mcp__cloudflare__tunnel-create",
7758
- "mcp__cloudflare__tunnel-enable",
7759
- "mcp__cloudflare__tunnel-disable",
7760
- "mcp__cloudflare__tunnel-add-hostname",
7761
- "mcp__cloudflare__cloudflare-setup-run",
7762
- "mcp__cloudflare__cloudflare-setup-status",
7763
- "mcp__cloudflare__dns-lookup",
7764
7688
  "mcp__tasks__task-create",
7765
7689
  "mcp__tasks__task-update",
7766
7690
  "mcp__tasks__task-list",
@@ -7827,10 +7751,7 @@ function getAdminAllowedTools(enabledPlugins) {
7827
7751
  return tools;
7828
7752
  }
7829
7753
  function assembleAllowedToolsForAdminSpawn(enabledPlugins) {
7830
- const base = getAdminAllowedTools(enabledPlugins);
7831
- const result = applyToolSurfaceFilters(base);
7832
- logToolSurfaceFilter(result);
7833
- return result.tools;
7754
+ return getAdminAllowedTools(enabledPlugins);
7834
7755
  }
7835
7756
  var QUERY_CLASSIFIER_MODEL = HAIKU_MODEL2;
7836
7757
  var QUERY_CLASSIFIER_TIMEOUT_MS = 3e3;
@@ -7920,7 +7841,7 @@ ${message.slice(0, QUERY_CLASSIFIER_MSG_CAP)}`
7920
7841
  }
7921
7842
  async function fetchMemoryContext(accountId, query, sessionKey, options) {
7922
7843
  const serverPath = resolve6(PLATFORM_ROOT4, "plugins/memory/mcp/dist/index.js");
7923
- if (!existsSync7(serverPath)) {
7844
+ if (!existsSync6(serverPath)) {
7924
7845
  console.error(`[fetchMemoryContext] MCP server not found: ${serverPath}`);
7925
7846
  return null;
7926
7847
  }
@@ -8018,7 +7939,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
8018
7939
  async function compactTrimmedMessages(accountId, trimmedMessages) {
8019
7940
  if (trimmedMessages.length === 0) return true;
8020
7941
  const serverPath = resolve6(PLATFORM_ROOT4, "plugins/memory/mcp/dist/index.js");
8021
- if (!existsSync7(serverPath)) return false;
7942
+ if (!existsSync6(serverPath)) return false;
8022
7943
  const briefing = trimmedMessages.map((m) => `[${m.role.toUpperCase()}] ${m.content}`).join("\n\n");
8023
7944
  return new Promise((resolvePromise) => {
8024
7945
  const proc = spawn2(process.execPath, [serverPath], {
@@ -8336,7 +8257,7 @@ var COMPACTION_TIMEOUT_MS = 45e3;
8336
8257
  async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSessionId, adminModel, conversationId, enabledPlugins) {
8337
8258
  const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, conversationId, void 0, enabledPlugins) });
8338
8259
  const specialistsDir = resolve6(accountDir, "specialists");
8339
- if (!existsSync7(specialistsDir)) agentLogStream("claude-agent-compaction-stream", accountDir, conversationId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
8260
+ if (!existsSync6(specialistsDir)) agentLogStream("claude-agent-compaction-stream", accountDir, conversationId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
8340
8261
  `);
8341
8262
  const args = [
8342
8263
  "--print",
@@ -9225,7 +9146,7 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
9225
9146
  const ccUserId = sessionKey ? getUserIdForSession(sessionKey) : void 0;
9226
9147
  const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, spawnConvId, ccUserId, enabledPlugins) });
9227
9148
  const specialistsDir = resolve6(accountDir, "specialists");
9228
- if (!existsSync7(specialistsDir)) agentLogStream("claude-agent-stream", accountDir, spawnConvId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
9149
+ if (!existsSync6(specialistsDir)) agentLogStream("claude-agent-stream", accountDir, spawnConvId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
9229
9150
  `);
9230
9151
  const args = [
9231
9152
  "--print",
@@ -9571,7 +9492,7 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
9571
9492
  const managedUserId = getUserIdForSession(sessionKey);
9572
9493
  const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, managedConvId, managedUserId, enabledPlugins) });
9573
9494
  const specialistsDir = resolve6(accountDir, "specialists");
9574
- if (!existsSync7(specialistsDir)) streamLog.write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
9495
+ if (!existsSync6(specialistsDir)) streamLog.write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
9575
9496
  `);
9576
9497
  const fullMessage = attachments.length > 0 ? message + buildAttachmentMetaText(attachments) : message;
9577
9498
  const args = [
@@ -10241,7 +10162,7 @@ ${sessionContext}`;
10241
10162
  const skillPath = resolve6(PLATFORM_ROOT4, "plugins/admin/skills/onboarding/SKILL.md");
10242
10163
  let skillContent = "";
10243
10164
  try {
10244
- skillContent = readFileSync8(skillPath, "utf-8");
10165
+ skillContent = readFileSync7(skillPath, "utf-8");
10245
10166
  } catch (err) {
10246
10167
  console.error(`[onboarding-inject] accountId=${accountId.slice(0, 8)}\u2026 error=skill-read-failed path=${skillPath} reason=${err instanceof Error ? err.message : String(err)}`);
10247
10168
  }
@@ -10441,7 +10362,7 @@ ${block}`;
10441
10362
  import { basename as basename2 } from "path";
10442
10363
 
10443
10364
  // app/lib/review-detector/rules.ts
10444
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync8, statSync as statSync4, mkdirSync as mkdirSync5, renameSync } from "fs";
10365
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync7, statSync as statSync4, mkdirSync as mkdirSync5, renameSync } from "fs";
10445
10366
  import { resolve as resolve7, dirname as dirname2 } from "path";
10446
10367
  var DEFAULT_SCAN_INTERVAL_MS = 5e3;
10447
10368
  var RATE_LIMIT_PATTERN = "rate[- ]?limit(?:ed| reached| hit)|(?:HTTP|status)[^a-z]{0,3}429|too many requests";
@@ -10773,36 +10694,23 @@ function defaultRules() {
10773
10694
  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
10695
  },
10775
10696
  {
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",
10697
+ // Task 553: fires when `anthropic-setup` auto-resets a revoked API key.
10698
+ // The auto-reset is silent to the agent (the tool falls through to
10699
+ // awaiting_signin in the same call), but it is operator-visible — the
10700
+ // user's previously-stored key was just deleted because Anthropic
10701
+ // rejected it. Surfacing the event lets the admin agent explain on the
10702
+ // next turn why the user is being asked to sign in again instead of
10703
+ // continuing normally. The matching string is the exact stable prefix
10704
+ // emitted by the state machine immediately before `deleteKey()` is
10705
+ // invoked.
10706
+ id: "anthropic-setup-auth-error-auto-reset",
10707
+ name: "Anthropic API key auto-reset on auth_error",
10708
+ type: "silent-catch",
10800
10709
  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."
10710
+ pattern: "\\[anthropic-setup\\] auth_error",
10711
+ thresholdCount: 0,
10712
+ thresholdWindowMinutes: 0,
10713
+ suggestedAction: "The stored Anthropic API key was rejected by console.anthropic.com (invalid, revoked, or expired) and `anthropic-setup` auto-deleted it. On the next operator interaction, explain that the key was cleared and walk them through sign-in again via the onboarding skill \u2014 the tool already returned `awaiting_signin` with the correct `browser_evaluate` action on the same call."
10806
10714
  }
10807
10715
  ];
10808
10716
  }
@@ -10811,7 +10719,7 @@ function rulesFilePath(configDir2) {
10811
10719
  }
10812
10720
  function ensureRulesFile(configDir2) {
10813
10721
  const path2 = rulesFilePath(configDir2);
10814
- if (existsSync8(path2)) return { created: false, path: path2 };
10722
+ if (existsSync7(path2)) return { created: false, path: path2 };
10815
10723
  mkdirSync5(dirname2(path2), { recursive: true });
10816
10724
  const body = {
10817
10725
  scanIntervalMs: DEFAULT_SCAN_INTERVAL_MS,
@@ -10822,10 +10730,10 @@ function ensureRulesFile(configDir2) {
10822
10730
  }
10823
10731
  function loadRules(configDir2) {
10824
10732
  const path2 = rulesFilePath(configDir2);
10825
- if (!existsSync8(path2)) {
10733
+ if (!existsSync7(path2)) {
10826
10734
  throw new Error(`rules file missing at ${path2}`);
10827
10735
  }
10828
- const raw2 = readFileSync9(path2, "utf-8");
10736
+ const raw2 = readFileSync8(path2, "utf-8");
10829
10737
  let parsed;
10830
10738
  try {
10831
10739
  parsed = JSON.parse(raw2);
@@ -10990,16 +10898,16 @@ function validateRule(input, label, seenIds) {
10990
10898
  }
10991
10899
 
10992
10900
  // app/lib/review-detector/sources.ts
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";
10901
+ 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";
10902
+ import { resolve as resolve8, join as join5, basename, dirname as dirname3 } from "path";
10995
10903
  function tailStatePath(configDir2) {
10996
10904
  return resolve8(configDir2, "review-state.json");
10997
10905
  }
10998
10906
  function loadTailState(configDir2) {
10999
10907
  const path2 = tailStatePath(configDir2);
11000
- if (!existsSync9(path2)) return {};
10908
+ if (!existsSync8(path2)) return {};
11001
10909
  try {
11002
- const raw2 = readFileSync10(path2, "utf-8");
10910
+ const raw2 = readFileSync9(path2, "utf-8");
11003
10911
  const parsed = JSON.parse(raw2);
11004
10912
  if (!parsed || typeof parsed !== "object") return {};
11005
10913
  const clean = {};
@@ -11025,18 +10933,18 @@ function saveTailState(configDir2, state) {
11025
10933
  function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
11026
10934
  if (logicalSource === "server") {
11027
10935
  const p = resolve8(configDir2, "logs", "server.log");
11028
- return existsSync9(p) ? [{ logicalSource: "server", filepath: p }] : [];
10936
+ return existsSync8(p) ? [{ logicalSource: "server", filepath: p }] : [];
11029
10937
  }
11030
10938
  if (logicalSource === "vnc") {
11031
10939
  const p = resolve8(configDir2, "logs", "vnc-boot.log");
11032
- return existsSync9(p) ? [{ logicalSource: "vnc", filepath: p }] : [];
10940
+ return existsSync8(p) ? [{ logicalSource: "vnc", filepath: p }] : [];
11033
10941
  }
11034
10942
  if (logicalSource === "cloudflared") {
11035
10943
  const files2 = [];
11036
10944
  const daemon = resolve8(configDir2, "logs", "cloudflared.log");
11037
- if (existsSync9(daemon)) files2.push({ logicalSource: "cloudflared", filepath: daemon });
10945
+ if (existsSync8(daemon)) files2.push({ logicalSource: "cloudflared", filepath: daemon });
11038
10946
  const login = resolve8(configDir2, "logs", "cloudflared-login.log");
11039
- if (existsSync9(login)) files2.push({ logicalSource: "cloudflared", filepath: login });
10947
+ if (existsSync8(login)) files2.push({ logicalSource: "cloudflared", filepath: login });
11040
10948
  return files2;
11041
10949
  }
11042
10950
  const prefix = {
@@ -11046,7 +10954,7 @@ function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
11046
10954
  public: "public-agent-stream-",
11047
10955
  mcp: "mcp-"
11048
10956
  }[logicalSource];
11049
- if (!existsSync9(accountLogDir2)) return [];
10957
+ if (!existsSync8(accountLogDir2)) return [];
11050
10958
  const files = [];
11051
10959
  let scanned = 0;
11052
10960
  let skippedPrefixMismatch = 0;
@@ -11056,7 +10964,7 @@ function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
11056
10964
  const matchesPrefix = entry.startsWith(prefix);
11057
10965
  const isLog = entry.endsWith(".log");
11058
10966
  if (matchesPrefix && isLog) {
11059
- files.push({ logicalSource, filepath: join6(accountLogDir2, entry) });
10967
+ files.push({ logicalSource, filepath: join5(accountLogDir2, entry) });
11060
10968
  } else if (!matchesPrefix) {
11061
10969
  skippedPrefixMismatch += 1;
11062
10970
  } else {
@@ -11088,7 +10996,7 @@ function discoverAllSources(configDir2, accountLogDir2) {
11088
10996
  ];
11089
10997
  }
11090
10998
  function readNewLines(filepath, prev) {
11091
- if (!existsSync9(filepath)) return null;
10999
+ if (!existsSync8(filepath)) return null;
11092
11000
  const stat4 = statSync5(filepath);
11093
11001
  const size = stat4.size;
11094
11002
  const inode = stat4.ino;
@@ -11141,12 +11049,12 @@ function readNewLines(filepath, prev) {
11141
11049
  }
11142
11050
  }
11143
11051
  function countRecentWrites(dir, sinceMs) {
11144
- if (!existsSync9(dir)) return 0;
11052
+ if (!existsSync8(dir)) return 0;
11145
11053
  let count = 0;
11146
11054
  for (const entry of readdirSync3(dir, { withFileTypes: true })) {
11147
11055
  if (!entry.isFile()) continue;
11148
11056
  try {
11149
- const st = statSync5(join6(dir, entry.name));
11057
+ const st = statSync5(join5(dir, entry.name));
11150
11058
  if (st.mtimeMs >= sinceMs) count += 1;
11151
11059
  } catch {
11152
11060
  }
@@ -11154,7 +11062,7 @@ function countRecentWrites(dir, sinceMs) {
11154
11062
  return count;
11155
11063
  }
11156
11064
  function fileLastWriteMs(path2) {
11157
- if (!existsSync9(path2)) return null;
11065
+ if (!existsSync8(path2)) return null;
11158
11066
  try {
11159
11067
  return statSync5(path2).mtimeMs;
11160
11068
  } catch {
@@ -11169,7 +11077,7 @@ function sourceKey(file2) {
11169
11077
  }
11170
11078
 
11171
11079
  // app/lib/review-detector/writer.ts
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";
11080
+ import { appendFileSync as appendFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync8, renameSync as renameSync3, statSync as statSync6 } from "fs";
11173
11081
  import { resolve as resolve9, dirname as dirname4 } from "path";
11174
11082
  import { randomUUID as randomUUID3 } from "crypto";
11175
11083
  function reviewLogPath(configDir2) {
@@ -11307,8 +11215,8 @@ function queueAlert(configDir2, accountId, match2) {
11307
11215
  }
11308
11216
  async function drainPendingAlerts(configDir2) {
11309
11217
  const path2 = pendingAlertsPath(configDir2);
11310
- if (!existsSync10(path2)) return { drained: 0, remaining: 0 };
11311
- const raw2 = readFileSync11(path2, "utf-8");
11218
+ if (!existsSync9(path2)) return { drained: 0, remaining: 0 };
11219
+ const raw2 = readFileSync10(path2, "utf-8");
11312
11220
  const lines = raw2.split("\n").filter((l) => l.trim().length > 0);
11313
11221
  if (lines.length === 0) return { drained: 0, remaining: 0 };
11314
11222
  const remaining = [];
@@ -25738,16 +25646,16 @@ var WhatsAppConfigSchema = external_exports.object({
25738
25646
  });
25739
25647
 
25740
25648
  // app/lib/whatsapp/config-persist.ts
25741
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, existsSync as existsSync11 } from "fs";
25742
- import { resolve as resolve11, join as join7 } from "path";
25649
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync10 } from "fs";
25650
+ import { resolve as resolve11, join as join6 } from "path";
25743
25651
  var TAG2 = "[whatsapp:config]";
25744
25652
  function configPath(accountDir) {
25745
25653
  return resolve11(accountDir, "account.json");
25746
25654
  }
25747
25655
  function readConfig(accountDir) {
25748
25656
  const path2 = configPath(accountDir);
25749
- if (!existsSync11(path2)) throw new Error(`account.json not found at ${path2}`);
25750
- return JSON.parse(readFileSync12(path2, "utf-8"));
25657
+ if (!existsSync10(path2)) throw new Error(`account.json not found at ${path2}`);
25658
+ return JSON.parse(readFileSync11(path2, "utf-8"));
25751
25659
  }
25752
25660
  function writeConfig(accountDir, config2) {
25753
25661
  const path2 = configPath(accountDir);
@@ -25921,8 +25829,8 @@ function setPublicAgent(accountDir, slug) {
25921
25829
  if (!trimmed) {
25922
25830
  return { ok: false, error: "Agent slug cannot be empty." };
25923
25831
  }
25924
- const agentConfigPath = join7(accountDir, "agents", trimmed, "config.json");
25925
- if (!existsSync11(agentConfigPath)) {
25832
+ const agentConfigPath = join6(accountDir, "agents", trimmed, "config.json");
25833
+ if (!existsSync10(agentConfigPath)) {
25926
25834
  return { ok: false, error: `Agent "${trimmed}" not found \u2014 no config.json at ${agentConfigPath}. Check the agent slug and try again.` };
25927
25835
  }
25928
25836
  try {
@@ -26962,7 +26870,7 @@ async function sendMediaMessage(sock, to, media, opts) {
26962
26870
  // app/lib/whatsapp/inbound/media.ts
26963
26871
  import { randomUUID as randomUUID5 } from "crypto";
26964
26872
  import { writeFile, mkdir } from "fs/promises";
26965
- import { join as join8 } from "path";
26873
+ import { join as join7 } from "path";
26966
26874
  import {
26967
26875
  downloadMediaMessage,
26968
26876
  downloadContentFromMessage,
@@ -27048,7 +26956,7 @@ async function downloadInboundMedia(msg, sock, opts) {
27048
26956
  await mkdir(MEDIA_DIR, { recursive: true });
27049
26957
  const ext = mimeToExt(mimetype ?? "application/octet-stream");
27050
26958
  const filename = `${randomUUID5()}.${ext}`;
27051
- const filePath = join8(MEDIA_DIR, filename);
26959
+ const filePath = join7(MEDIA_DIR, filename);
27052
26960
  await writeFile(filePath, buffer);
27053
26961
  const sizeKB = (buffer.length / 1024).toFixed(0);
27054
26962
  console.error(`${TAG8} media downloaded type=${mimetype ?? "unknown"} size=${sizeKB}KB path=${filePath}`);
@@ -28010,8 +27918,8 @@ async function GET(req, remoteAddress) {
28010
27918
  const browserTransport = resolveBrowserTransport(req, remoteAddress);
28011
27919
  let pinConfigured = false;
28012
27920
  try {
28013
- if (existsSync12(USERS_FILE)) {
28014
- const raw2 = readFileSync13(USERS_FILE, "utf-8").trim();
27921
+ if (existsSync11(USERS_FILE)) {
27922
+ const raw2 = readFileSync12(USERS_FILE, "utf-8").trim();
28015
27923
  if (raw2) {
28016
27924
  const users = JSON.parse(raw2);
28017
27925
  pinConfigured = Array.isArray(users) && users.length > 0;
@@ -28030,7 +27938,7 @@ async function GET(req, remoteAddress) {
28030
27938
  const vncRunning = await checkPort(6080);
28031
27939
  let apiKeyConfigured = false;
28032
27940
  try {
28033
- apiKeyConfigured = existsSync12(keyFilePath());
27941
+ apiKeyConfigured = existsSync11(keyFilePath());
28034
27942
  } catch {
28035
27943
  }
28036
27944
  let apiKeyStatus = "missing";
@@ -28098,7 +28006,7 @@ async function GET(req, remoteAddress) {
28098
28006
 
28099
28007
  // app/api/session/route.ts
28100
28008
  import { resolve as resolve12 } from "path";
28101
- import { existsSync as existsSync13, writeFileSync as writeFileSync10, mkdirSync as mkdirSync8 } from "fs";
28009
+ import { existsSync as existsSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync8 } from "fs";
28102
28010
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
28103
28011
  async function POST(req) {
28104
28012
  let body;
@@ -28149,7 +28057,7 @@ async function POST(req) {
28149
28057
  if (account) {
28150
28058
  const agentDir = resolve12(account.accountDir, "agents", agentSlug);
28151
28059
  const agentConfigPath = resolve12(agentDir, "config.json");
28152
- if (!existsSync13(agentDir) || !existsSync13(agentConfigPath)) {
28060
+ if (!existsSync12(agentDir) || !existsSync12(agentConfigPath)) {
28153
28061
  return Response.json({ error: "Agent not found" }, { status: 404 });
28154
28062
  }
28155
28063
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -28524,7 +28432,7 @@ async function storeGeneratedFile(accountId, filePath) {
28524
28432
  // app/lib/stt/voice-note.ts
28525
28433
  import { writeFile as writeFile3, mkdtemp, rm } from "fs/promises";
28526
28434
  import { tmpdir } from "os";
28527
- import { join as join9 } from "path";
28435
+ import { join as join8 } from "path";
28528
28436
  var TAG13 = "[voice]";
28529
28437
  var AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
28530
28438
  "audio/ogg",
@@ -28562,9 +28470,9 @@ async function transcribeVoiceNote(file2, source) {
28562
28470
  let tempDir;
28563
28471
  let tempPath;
28564
28472
  try {
28565
- tempDir = await mkdtemp(join9(tmpdir(), "voice-"));
28473
+ tempDir = await mkdtemp(join8(tmpdir(), "voice-"));
28566
28474
  const ext = audioExtension(mimeType);
28567
- tempPath = join9(tempDir, `recording${ext}`);
28475
+ tempPath = join8(tempDir, `recording${ext}`);
28568
28476
  const buffer = Buffer.from(await file2.arrayBuffer());
28569
28477
  await writeFile3(tempPath, buffer);
28570
28478
  } catch (err) {
@@ -29115,7 +29023,7 @@ async function POST2(req) {
29115
29023
 
29116
29024
  // app/lib/access-gate.ts
29117
29025
  import neo4j2 from "neo4j-driver";
29118
- import { readFileSync as readFileSync14 } from "fs";
29026
+ import { readFileSync as readFileSync13 } from "fs";
29119
29027
  import { resolve as resolve14 } from "path";
29120
29028
  import { randomUUID as randomUUID7, randomInt } from "crypto";
29121
29029
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
@@ -29124,7 +29032,7 @@ function readPassword2() {
29124
29032
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
29125
29033
  const passwordFile = resolve14(PLATFORM_ROOT6, "config/.neo4j-password");
29126
29034
  try {
29127
- return readFileSync14(passwordFile, "utf-8").trim();
29035
+ return readFileSync13(passwordFile, "utf-8").trim();
29128
29036
  } catch {
29129
29037
  throw new Error(
29130
29038
  `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
@@ -29722,7 +29630,7 @@ async function POST6(req) {
29722
29630
  }
29723
29631
 
29724
29632
  // app/lib/brevo-sms.ts
29725
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, existsSync as existsSync14, chmodSync } from "fs";
29633
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, existsSync as existsSync13, chmodSync } from "fs";
29726
29634
  import { dirname as dirname5 } from "path";
29727
29635
  import { resolve as resolve15 } from "path";
29728
29636
  var BREVO_API_KEY_FILE = resolve15(MAXY_DIR, ".brevo-api-key");
@@ -29733,8 +29641,8 @@ var platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
29733
29641
  if (platformRoot2) {
29734
29642
  try {
29735
29643
  const brandPath3 = resolve15(platformRoot2, "config", "brand.json");
29736
- if (existsSync14(brandPath3)) {
29737
- const brand = JSON.parse(readFileSync15(brandPath3, "utf-8"));
29644
+ if (existsSync13(brandPath3)) {
29645
+ const brand = JSON.parse(readFileSync14(brandPath3, "utf-8"));
29738
29646
  if (brand.productName) BREVO_SENDER = brand.productName;
29739
29647
  }
29740
29648
  } catch {
@@ -29742,7 +29650,7 @@ if (platformRoot2) {
29742
29650
  }
29743
29651
  function readBrevoApiKey() {
29744
29652
  try {
29745
- const key = readFileSync15(BREVO_API_KEY_FILE, "utf-8").trim();
29653
+ const key = readFileSync14(BREVO_API_KEY_FILE, "utf-8").trim();
29746
29654
  if (!key) {
29747
29655
  throw new Error(`Brevo API key file is empty: ${BREVO_API_KEY_FILE}`);
29748
29656
  }
@@ -29757,7 +29665,7 @@ function readBrevoApiKey() {
29757
29665
  }
29758
29666
  }
29759
29667
  function hasBrevoApiKey() {
29760
- return existsSync14(BREVO_API_KEY_FILE);
29668
+ return existsSync13(BREVO_API_KEY_FILE);
29761
29669
  }
29762
29670
  async function sendSms(recipient, content, opts) {
29763
29671
  let apiKey;
@@ -29922,15 +29830,15 @@ function checkTelegramAccess(params) {
29922
29830
  }
29923
29831
 
29924
29832
  // app/api/telegram/webhook/route.ts
29925
- import { existsSync as existsSync15, readFileSync as readFileSync16 } from "fs";
29833
+ import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
29926
29834
  import { timingSafeEqual as timingSafeEqual2 } from "crypto";
29927
29835
  var TAG15 = "[telegram-webhook]";
29928
29836
  var TELEGRAM_API = "https://api.telegram.org";
29929
29837
  function getWebhookSecret(botType) {
29930
29838
  const filePath = botType === "admin" ? TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE : TELEGRAM_WEBHOOK_SECRET_FILE;
29931
29839
  try {
29932
- if (!existsSync15(filePath)) return null;
29933
- const secret = readFileSync16(filePath, "utf-8").trim();
29840
+ if (!existsSync14(filePath)) return null;
29841
+ const secret = readFileSync15(filePath, "utf-8").trim();
29934
29842
  return secret || null;
29935
29843
  } catch {
29936
29844
  return null;
@@ -30087,7 +29995,7 @@ async function POST8(req) {
30087
29995
  }
30088
29996
 
30089
29997
  // app/api/whatsapp/login/start/route.ts
30090
- import { join as join10 } from "path";
29998
+ import { join as join9 } from "path";
30091
29999
 
30092
30000
  // app/lib/whatsapp/login.ts
30093
30001
  import { randomUUID as randomUUID8 } from "crypto";
@@ -30317,7 +30225,7 @@ async function POST9(req) {
30317
30225
  const body = await req.json().catch(() => ({}));
30318
30226
  const accountId = validateAccountId(body.accountId);
30319
30227
  const force = body.force ?? false;
30320
- const authDir = join10(MAXY_DIR, "credentials", "whatsapp", accountId);
30228
+ const authDir = join9(MAXY_DIR, "credentials", "whatsapp", accountId);
30321
30229
  const result = await startLogin({ accountId, authDir, force });
30322
30230
  console.error(`[whatsapp:api] login/start result account=${accountId} hasQr=${!!result.qrRaw}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
30323
30231
  return Response.json(result);
@@ -30531,7 +30439,7 @@ function serializeWhatsAppSchema() {
30531
30439
 
30532
30440
  // app/api/whatsapp/config/route.ts
30533
30441
  import { resolve as resolve16 } from "path";
30534
- import { readdirSync as readdirSync4, readFileSync as readFileSync17, existsSync as existsSync16 } from "fs";
30442
+ import { readdirSync as readdirSync4, readFileSync as readFileSync16, existsSync as existsSync15 } from "fs";
30535
30443
  async function POST14(req) {
30536
30444
  try {
30537
30445
  const body = await req.json().catch(() => ({}));
@@ -30581,15 +30489,15 @@ async function POST14(req) {
30581
30489
  case "list-public-agents": {
30582
30490
  const agentsDir = resolve16(account.accountDir, "agents");
30583
30491
  const agents = [];
30584
- if (existsSync16(agentsDir)) {
30492
+ if (existsSync15(agentsDir)) {
30585
30493
  try {
30586
30494
  const entries = readdirSync4(agentsDir, { withFileTypes: true });
30587
30495
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
30588
30496
  if (!entry.isDirectory() || entry.name === "admin") continue;
30589
30497
  const configPath2 = resolve16(agentsDir, entry.name, "config.json");
30590
- if (!existsSync16(configPath2)) continue;
30498
+ if (!existsSync15(configPath2)) continue;
30591
30499
  try {
30592
- const config2 = JSON.parse(readFileSync17(configPath2, "utf-8"));
30500
+ const config2 = JSON.parse(readFileSync16(configPath2, "utf-8"));
30593
30501
  agents.push({ slug: entry.name, displayName: config2.displayName ?? entry.name });
30594
30502
  } catch {
30595
30503
  console.error(`[whatsapp:api] config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
@@ -31005,15 +30913,15 @@ async function POST17(req, remoteAddress) {
31005
30913
  }
31006
30914
 
31007
30915
  // app/api/onboarding/set-pin/route.ts
31008
- import { existsSync as existsSync17, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync18, unlinkSync as unlinkSync2 } from "fs";
30916
+ import { existsSync as existsSync16, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync17, unlinkSync as unlinkSync3 } from "fs";
31009
30917
  import { createHash, randomUUID as randomUUID9 } from "crypto";
31010
30918
  import { dirname as dirname6 } from "path";
31011
30919
  function hashPin(pin) {
31012
30920
  return createHash("sha256").update(pin).digest("hex");
31013
30921
  }
31014
30922
  function readUsersFile() {
31015
- if (!existsSync17(USERS_FILE)) return null;
31016
- const raw2 = readFileSync18(USERS_FILE, "utf-8").trim();
30923
+ if (!existsSync16(USERS_FILE)) return null;
30924
+ const raw2 = readFileSync17(USERS_FILE, "utf-8").trim();
31017
30925
  if (!raw2) return [];
31018
30926
  return JSON.parse(raw2);
31019
30927
  }
@@ -31051,7 +30959,7 @@ async function POST18(req) {
31051
30959
  const account = resolveAccount();
31052
30960
  if (account) {
31053
30961
  try {
31054
- const config2 = JSON.parse(readFileSync18(`${account.accountDir}/account.json`, "utf-8"));
30962
+ const config2 = JSON.parse(readFileSync17(`${account.accountDir}/account.json`, "utf-8"));
31055
30963
  if (!config2.admins) config2.admins = [];
31056
30964
  if (!config2.admins.some((a) => a.userId === userId)) {
31057
30965
  config2.admins.push({ userId, role: "owner" });
@@ -31092,7 +31000,7 @@ async function DELETE(req) {
31092
31000
  }
31093
31001
  const remaining = users.filter((u) => u.userId !== matchedUser.userId);
31094
31002
  if (remaining.length === 0) {
31095
- unlinkSync2(USERS_FILE);
31003
+ unlinkSync3(USERS_FILE);
31096
31004
  console.log(`[set-pin] cleared users.json (last entry removed): userId=${matchedUser.userId.slice(0, 8)}\u2026`);
31097
31005
  } else {
31098
31006
  writeFileSync13(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
@@ -31102,7 +31010,7 @@ async function DELETE(req) {
31102
31010
  }
31103
31011
 
31104
31012
  // app/api/onboarding/skip/route.ts
31105
- import { existsSync as existsSync18, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync19 } from "fs";
31013
+ import { existsSync as existsSync17, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync18 } from "fs";
31106
31014
  import { resolve as resolve18, dirname as dirname7 } from "path";
31107
31015
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
31108
31016
  async function POST19() {
@@ -31114,9 +31022,9 @@ async function POST19() {
31114
31022
  const { accountId, accountDir } = account;
31115
31023
  let agentName = "Maxy";
31116
31024
  const brandPath3 = PLATFORM_ROOT8 ? resolve18(PLATFORM_ROOT8, "config", "brand.json") : "";
31117
- if (brandPath3 && existsSync18(brandPath3)) {
31025
+ if (brandPath3 && existsSync17(brandPath3)) {
31118
31026
  try {
31119
- const brand = JSON.parse(readFileSync19(brandPath3, "utf-8"));
31027
+ const brand = JSON.parse(readFileSync18(brandPath3, "utf-8"));
31120
31028
  if (brand.productName) agentName = brand.productName;
31121
31029
  } catch (err) {
31122
31030
  console.error(`[onboarding-skip] brand.json read failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -31162,14 +31070,14 @@ async function POST19() {
31162
31070
  }
31163
31071
 
31164
31072
  // app/api/admin/session/route.ts
31165
- import { readFileSync as readFileSync20, existsSync as existsSync19 } from "fs";
31073
+ import { readFileSync as readFileSync19, existsSync as existsSync18 } from "fs";
31166
31074
  import { createHash as createHash2 } from "crypto";
31167
31075
  function hashPin2(pin) {
31168
31076
  return createHash2("sha256").update(pin).digest("hex");
31169
31077
  }
31170
31078
  function readUsersFile2() {
31171
- if (!existsSync19(USERS_FILE)) return null;
31172
- const raw2 = readFileSync20(USERS_FILE, "utf-8").trim();
31079
+ if (!existsSync18(USERS_FILE)) return null;
31080
+ const raw2 = readFileSync19(USERS_FILE, "utf-8").trim();
31173
31081
  if (!raw2) return [];
31174
31082
  return JSON.parse(raw2);
31175
31083
  }
@@ -31570,7 +31478,7 @@ async function POST22(req) {
31570
31478
  }
31571
31479
 
31572
31480
  // app/api/admin/logs/route.ts
31573
- import { existsSync as existsSync20, readdirSync as readdirSync5, readFileSync as readFileSync21, statSync as statSync7 } from "fs";
31481
+ import { existsSync as existsSync19, readdirSync as readdirSync5, readFileSync as readFileSync20, statSync as statSync7 } from "fs";
31574
31482
  import { resolve as resolve19, basename as basename5 } from "path";
31575
31483
  var TAIL_BYTES = 8192;
31576
31484
  async function GET9(request) {
@@ -31589,7 +31497,7 @@ async function GET9(request) {
31589
31497
  const filePath = resolve19(dir, safe);
31590
31498
  searched.push(filePath);
31591
31499
  try {
31592
- const content = readFileSync21(filePath, "utf-8");
31500
+ const content = readFileSync20(filePath, "utf-8");
31593
31501
  const headers = { "Content-Type": "text/plain; charset=utf-8" };
31594
31502
  if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
31595
31503
  return new Response(content, { headers });
@@ -31631,7 +31539,7 @@ async function GET9(request) {
31631
31539
  const filePath = resolve19(dir, fileName);
31632
31540
  searched.push(filePath);
31633
31541
  try {
31634
- const content = readFileSync21(filePath, "utf-8");
31542
+ const content = readFileSync20(filePath, "utf-8");
31635
31543
  const headers = { "Content-Type": "text/plain; charset=utf-8" };
31636
31544
  if (download) headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
31637
31545
  return new Response(content, { headers });
@@ -31646,7 +31554,7 @@ async function GET9(request) {
31646
31554
  const seen = /* @__PURE__ */ new Set();
31647
31555
  const logs = {};
31648
31556
  for (const dir of [accountLogDir2, LOG_DIR]) {
31649
- if (!dir || !existsSync20(dir)) continue;
31557
+ if (!dir || !existsSync19(dir)) continue;
31650
31558
  let files;
31651
31559
  try {
31652
31560
  files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
@@ -31658,7 +31566,7 @@ async function GET9(request) {
31658
31566
  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 }) => {
31659
31567
  seen.add(name);
31660
31568
  try {
31661
- const content = readFileSync21(resolve19(dir, name));
31569
+ const content = readFileSync20(resolve19(dir, name));
31662
31570
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
31663
31571
  logs[name] = tail.trim() || "(empty)";
31664
31572
  } catch (err) {
@@ -31695,7 +31603,7 @@ async function GET10() {
31695
31603
 
31696
31604
  // app/api/admin/attachment/[attachmentId]/route.ts
31697
31605
  import { readFile as readFile3, readdir } from "fs/promises";
31698
- import { existsSync as existsSync21 } from "fs";
31606
+ import { existsSync as existsSync20 } from "fs";
31699
31607
  import { resolve as resolve20 } from "path";
31700
31608
  async function GET11(req, attachmentId) {
31701
31609
  const sessionKey = new URL(req.url).searchParams.get("session_key") ?? "";
@@ -31710,11 +31618,11 @@ async function GET11(req, attachmentId) {
31710
31618
  return new Response("Not found", { status: 404 });
31711
31619
  }
31712
31620
  const dir = resolve20(ATTACHMENTS_ROOT, accountId, attachmentId);
31713
- if (!existsSync21(dir)) {
31621
+ if (!existsSync20(dir)) {
31714
31622
  return new Response("Not found", { status: 404 });
31715
31623
  }
31716
31624
  const metaPath = resolve20(dir, `${attachmentId}.meta.json`);
31717
- if (!existsSync21(metaPath)) {
31625
+ if (!existsSync20(metaPath)) {
31718
31626
  return new Response("Not found", { status: 404 });
31719
31627
  }
31720
31628
  let meta3;
@@ -31740,7 +31648,7 @@ async function GET11(req, attachmentId) {
31740
31648
  }
31741
31649
 
31742
31650
  // app/api/admin/account/route.ts
31743
- import { readFileSync as readFileSync22, writeFileSync as writeFileSync15 } from "fs";
31651
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "fs";
31744
31652
  import { resolve as resolve21 } from "path";
31745
31653
  var VALID_CONTEXT_MODES = ["managed", "claude-code"];
31746
31654
  async function PATCH(req) {
@@ -31766,7 +31674,7 @@ async function PATCH(req) {
31766
31674
  }
31767
31675
  const configPath2 = resolve21(account.accountDir, "account.json");
31768
31676
  try {
31769
- const raw2 = readFileSync22(configPath2, "utf-8");
31677
+ const raw2 = readFileSync21(configPath2, "utf-8");
31770
31678
  const config2 = JSON.parse(raw2);
31771
31679
  config2.contextMode = contextMode;
31772
31680
  writeFileSync15(configPath2, JSON.stringify(config2, null, 2) + "\n", "utf-8");
@@ -31780,14 +31688,14 @@ async function PATCH(req) {
31780
31688
 
31781
31689
  // app/api/admin/agents/route.ts
31782
31690
  import { resolve as resolve22 } from "path";
31783
- import { readdirSync as readdirSync6, readFileSync as readFileSync23, existsSync as existsSync22 } from "fs";
31691
+ import { readdirSync as readdirSync6, readFileSync as readFileSync22, existsSync as existsSync21 } from "fs";
31784
31692
  async function GET12() {
31785
31693
  const account = resolveAccount();
31786
31694
  if (!account) {
31787
31695
  return Response.json({ agents: [] });
31788
31696
  }
31789
31697
  const agentsDir = resolve22(account.accountDir, "agents");
31790
- if (!existsSync22(agentsDir)) {
31698
+ if (!existsSync21(agentsDir)) {
31791
31699
  return Response.json({ agents: [] });
31792
31700
  }
31793
31701
  const agents = [];
@@ -31797,9 +31705,9 @@ async function GET12() {
31797
31705
  if (!entry.isDirectory()) continue;
31798
31706
  if (entry.name === "admin") continue;
31799
31707
  const configPath2 = resolve22(agentsDir, entry.name, "config.json");
31800
- if (!existsSync22(configPath2)) continue;
31708
+ if (!existsSync21(configPath2)) continue;
31801
31709
  try {
31802
- const config2 = JSON.parse(readFileSync23(configPath2, "utf-8"));
31710
+ const config2 = JSON.parse(readFileSync22(configPath2, "utf-8"));
31803
31711
  agents.push({
31804
31712
  slug: entry.name,
31805
31713
  displayName: config2.displayName ?? entry.name,
@@ -31818,7 +31726,7 @@ async function GET12() {
31818
31726
 
31819
31727
  // app/api/admin/agents/[slug]/route.ts
31820
31728
  import { resolve as resolve23 } from "path";
31821
- import { existsSync as existsSync23, rmSync as rmSync2 } from "fs";
31729
+ import { existsSync as existsSync22, rmSync as rmSync2 } from "fs";
31822
31730
  async function DELETE2(_req, { params }) {
31823
31731
  const { slug } = await params;
31824
31732
  const account = resolveAccount();
@@ -31832,7 +31740,7 @@ async function DELETE2(_req, { params }) {
31832
31740
  return Response.json({ error: "Invalid agent slug" }, { status: 400 });
31833
31741
  }
31834
31742
  const agentDir = resolve23(account.accountDir, "agents", slug);
31835
- if (!existsSync23(agentDir)) {
31743
+ if (!existsSync22(agentDir)) {
31836
31744
  return Response.json({ error: "Agent not found" }, { status: 404 });
31837
31745
  }
31838
31746
  try {
@@ -31846,15 +31754,15 @@ async function DELETE2(_req, { params }) {
31846
31754
  }
31847
31755
 
31848
31756
  // app/api/admin/version/route.ts
31849
- import { readFileSync as readFileSync24, existsSync as existsSync24 } from "fs";
31850
- import { resolve as resolve24, join as join11 } from "path";
31757
+ import { readFileSync as readFileSync23, existsSync as existsSync23 } from "fs";
31758
+ import { resolve as resolve24, join as join10 } from "path";
31851
31759
  var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
31852
31760
  var brandHostname = "maxy";
31853
31761
  var brandNpmPackage = "@rubytech/create-maxy";
31854
- var brandJsonPath = join11(PLATFORM_ROOT9, "config", "brand.json");
31855
- if (existsSync24(brandJsonPath)) {
31762
+ var brandJsonPath = join10(PLATFORM_ROOT9, "config", "brand.json");
31763
+ if (existsSync23(brandJsonPath)) {
31856
31764
  try {
31857
- const brand = JSON.parse(readFileSync24(brandJsonPath, "utf-8"));
31765
+ const brand = JSON.parse(readFileSync23(brandJsonPath, "utf-8"));
31858
31766
  if (brand.hostname) brandHostname = brand.hostname;
31859
31767
  if (brand.npm?.packageName) brandNpmPackage = brand.npm.packageName;
31860
31768
  } catch {
@@ -31865,8 +31773,8 @@ var NPM_PACKAGE = brandNpmPackage;
31865
31773
  var REGISTRY_URL = `https://registry.npmjs.org/${NPM_PACKAGE}/latest`;
31866
31774
  var FETCH_TIMEOUT_MS = 5e3;
31867
31775
  function readInstalled() {
31868
- if (!existsSync24(VERSION_FILE)) return "unknown";
31869
- const content = readFileSync24(VERSION_FILE, "utf-8").trim();
31776
+ if (!existsSync23(VERSION_FILE)) return "unknown";
31777
+ const content = readFileSync23(VERSION_FILE, "utf-8").trim();
31870
31778
  return content || "unknown";
31871
31779
  }
31872
31780
  async function fetchLatest() {
@@ -31917,15 +31825,15 @@ async function GET13() {
31917
31825
 
31918
31826
  // app/api/admin/version/upgrade/route.ts
31919
31827
  import { spawn as spawn4 } from "child_process";
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";
31828
+ import { existsSync as existsSync24, statSync as statSync8, writeFileSync as writeFileSync16, readFileSync as readFileSync24, openSync as openSync4, closeSync as closeSync4 } from "fs";
31829
+ import { resolve as resolve25, join as join11 } from "path";
31922
31830
  var PLATFORM_ROOT10 = process.env.MAXY_PLATFORM_ROOT ?? resolve25(process.cwd(), "..");
31923
31831
  var upgradePkg = "@rubytech/create-maxy";
31924
31832
  var upgradeHostname = "maxy";
31925
- var brandPath = join12(PLATFORM_ROOT10, "config", "brand.json");
31926
- if (existsSync25(brandPath)) {
31833
+ var brandPath = join11(PLATFORM_ROOT10, "config", "brand.json");
31834
+ if (existsSync24(brandPath)) {
31927
31835
  try {
31928
- const brand = JSON.parse(readFileSync25(brandPath, "utf-8"));
31836
+ const brand = JSON.parse(readFileSync24(brandPath, "utf-8"));
31929
31837
  if (brand.npm?.packageName) upgradePkg = brand.npm.packageName;
31930
31838
  if (brand.hostname) upgradeHostname = brand.hostname;
31931
31839
  } catch {
@@ -31935,7 +31843,7 @@ var LOCK_FILE = `/tmp/${upgradeHostname}-upgrade.lock`;
31935
31843
  var LOG_FILE = `/tmp/${upgradeHostname}-upgrade.log`;
31936
31844
  var LOCK_MAX_AGE_MS = 20 * 60 * 1e3;
31937
31845
  function isLockFresh() {
31938
- if (!existsSync25(LOCK_FILE)) return false;
31846
+ if (!existsSync24(LOCK_FILE)) return false;
31939
31847
  try {
31940
31848
  const stat4 = statSync8(LOCK_FILE);
31941
31849
  return Date.now() - stat4.mtimeMs < LOCK_MAX_AGE_MS;
@@ -31995,14 +31903,14 @@ async function POST23(req) {
31995
31903
  }
31996
31904
 
31997
31905
  // app/api/admin/version/upgrade/progress/route.ts
31998
- import { existsSync as existsSync26, readFileSync as readFileSync26 } from "fs";
31999
- import { resolve as resolve26, join as join13 } from "path";
31906
+ import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
31907
+ import { resolve as resolve26, join as join12 } from "path";
32000
31908
  var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
32001
31909
  var upgradeHostname2 = "maxy";
32002
- var brandPath2 = join13(PLATFORM_ROOT11, "config", "brand.json");
32003
- if (existsSync26(brandPath2)) {
31910
+ var brandPath2 = join12(PLATFORM_ROOT11, "config", "brand.json");
31911
+ if (existsSync25(brandPath2)) {
32004
31912
  try {
32005
- const brand = JSON.parse(readFileSync26(brandPath2, "utf-8"));
31913
+ const brand = JSON.parse(readFileSync25(brandPath2, "utf-8"));
32006
31914
  if (brand.hostname) upgradeHostname2 = brand.hostname;
32007
31915
  } catch {
32008
31916
  }
@@ -32010,12 +31918,12 @@ if (existsSync26(brandPath2)) {
32010
31918
  var LOG_FILE2 = `/tmp/${upgradeHostname2}-upgrade.log`;
32011
31919
  var STEP_RE = /\[(\d+)\/(\d+)\]\s+(.+)/;
32012
31920
  async function GET14() {
32013
- if (!existsSync26(LOG_FILE2)) {
31921
+ if (!existsSync25(LOG_FILE2)) {
32014
31922
  return Response.json({ step: 0, total: 0, label: "", started: false });
32015
31923
  }
32016
31924
  let content;
32017
31925
  try {
32018
- content = readFileSync26(LOG_FILE2, "utf-8");
31926
+ content = readFileSync25(LOG_FILE2, "utf-8");
32019
31927
  } catch {
32020
31928
  return Response.json({ step: 0, total: 0, label: "", started: false });
32021
31929
  }
@@ -32481,14 +32389,14 @@ async function POST29(req) {
32481
32389
 
32482
32390
  // server/index.ts
32483
32391
  var PLATFORM_ROOT12 = process.env.MAXY_PLATFORM_ROOT || "";
32484
- var BRAND_JSON_PATH = PLATFORM_ROOT12 ? join14(PLATFORM_ROOT12, "config", "brand.json") : "";
32392
+ var BRAND_JSON_PATH = PLATFORM_ROOT12 ? join13(PLATFORM_ROOT12, "config", "brand.json") : "";
32485
32393
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
32486
- if (BRAND_JSON_PATH && !existsSync27(BRAND_JSON_PATH)) {
32394
+ if (BRAND_JSON_PATH && !existsSync26(BRAND_JSON_PATH)) {
32487
32395
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
32488
32396
  }
32489
- if (BRAND_JSON_PATH && existsSync27(BRAND_JSON_PATH)) {
32397
+ if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
32490
32398
  try {
32491
- const parsed = JSON.parse(readFileSync27(BRAND_JSON_PATH, "utf-8"));
32399
+ const parsed = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
32492
32400
  BRAND = { ...BRAND, ...parsed };
32493
32401
  } catch (err) {
32494
32402
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -32507,11 +32415,11 @@ var brandLoginOpts = {
32507
32415
  bodyFont: BRAND.defaultFonts?.body,
32508
32416
  logoContainsName: !!BRAND.logoContainsName
32509
32417
  };
32510
- var ALIAS_DOMAINS_PATH = join14(homedir4(), BRAND.configDir, "alias-domains.json");
32418
+ var ALIAS_DOMAINS_PATH = join13(homedir4(), BRAND.configDir, "alias-domains.json");
32511
32419
  function loadAliasDomains() {
32512
32420
  try {
32513
- if (!existsSync27(ALIAS_DOMAINS_PATH)) return null;
32514
- const parsed = JSON.parse(readFileSync27(ALIAS_DOMAINS_PATH, "utf-8"));
32421
+ if (!existsSync26(ALIAS_DOMAINS_PATH)) return null;
32422
+ const parsed = JSON.parse(readFileSync26(ALIAS_DOMAINS_PATH, "utf-8"));
32515
32423
  if (!Array.isArray(parsed)) {
32516
32424
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
32517
32425
  return null;
@@ -32929,14 +32837,14 @@ app.get("/agent-assets/:slug/:filename", (c) => {
32929
32837
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
32930
32838
  return c.text("Forbidden", 403);
32931
32839
  }
32932
- if (!existsSync27(filePath)) {
32840
+ if (!existsSync26(filePath)) {
32933
32841
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
32934
32842
  return c.text("Not found", 404);
32935
32843
  }
32936
32844
  const ext = "." + filename.split(".").pop()?.toLowerCase();
32937
32845
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
32938
32846
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
32939
- const body = readFileSync27(filePath);
32847
+ const body = readFileSync26(filePath);
32940
32848
  return c.body(body, 200, {
32941
32849
  "Content-Type": contentType,
32942
32850
  "Cache-Control": "public, max-age=3600"
@@ -32959,14 +32867,14 @@ app.get("/generated/:filename", (c) => {
32959
32867
  console.error(`[generated] serve file=${filename} status=403`);
32960
32868
  return c.text("Forbidden", 403);
32961
32869
  }
32962
- if (!existsSync27(filePath)) {
32870
+ if (!existsSync26(filePath)) {
32963
32871
  console.error(`[generated] serve file=${filename} status=404`);
32964
32872
  return c.text("Not found", 404);
32965
32873
  }
32966
32874
  const ext = "." + filename.split(".").pop()?.toLowerCase();
32967
32875
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
32968
32876
  console.log(`[generated] serve file=${filename} status=200`);
32969
- const body = readFileSync27(filePath);
32877
+ const body = readFileSync26(filePath);
32970
32878
  return c.body(body, 200, {
32971
32879
  "Content-Type": contentType,
32972
32880
  "Cache-Control": "public, max-age=86400"
@@ -32975,9 +32883,9 @@ app.get("/generated/:filename", (c) => {
32975
32883
  var htmlCache = /* @__PURE__ */ new Map();
32976
32884
  var brandLogoPath = "/brand/maxy-monochrome.png";
32977
32885
  var brandIconPath = "/brand/maxy-monochrome.png";
32978
- if (BRAND_JSON_PATH && existsSync27(BRAND_JSON_PATH)) {
32886
+ if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
32979
32887
  try {
32980
- const fullBrand = JSON.parse(readFileSync27(BRAND_JSON_PATH, "utf-8"));
32888
+ const fullBrand = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
32981
32889
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
32982
32890
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
32983
32891
  } catch {
@@ -32994,7 +32902,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
32994
32902
  function cachedHtml(file2) {
32995
32903
  let html = htmlCache.get(file2);
32996
32904
  if (!html) {
32997
- html = readFileSync27(resolve27(process.cwd(), "public", file2), "utf-8");
32905
+ html = readFileSync26(resolve27(process.cwd(), "public", file2), "utf-8");
32998
32906
  html = html.replace("<title>Maxy</title>", `<title>${escapeHtml2(BRAND.productName)}</title>`);
32999
32907
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml2(brandFaviconPath)}"`);
33000
32908
  html = html.replace("</head>", `${brandScript}
@@ -33005,26 +32913,26 @@ function cachedHtml(file2) {
33005
32913
  }
33006
32914
  var brandedHtmlCache = /* @__PURE__ */ new Map();
33007
32915
  function loadBrandingCache(agentSlug) {
33008
- const configDir2 = join14(homedir4(), BRAND.configDir);
32916
+ const configDir2 = join13(homedir4(), BRAND.configDir);
33009
32917
  try {
33010
- const accountJsonPath = join14(configDir2, "account.json");
33011
- if (!existsSync27(accountJsonPath)) return null;
33012
- const account = JSON.parse(readFileSync27(accountJsonPath, "utf-8"));
32918
+ const accountJsonPath = join13(configDir2, "account.json");
32919
+ if (!existsSync26(accountJsonPath)) return null;
32920
+ const account = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
33013
32921
  const accountId = account.accountId;
33014
32922
  if (!accountId) return null;
33015
- const cachePath = join14(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
33016
- if (!existsSync27(cachePath)) return null;
33017
- return JSON.parse(readFileSync27(cachePath, "utf-8"));
32923
+ const cachePath = join13(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
32924
+ if (!existsSync26(cachePath)) return null;
32925
+ return JSON.parse(readFileSync26(cachePath, "utf-8"));
33018
32926
  } catch {
33019
32927
  return null;
33020
32928
  }
33021
32929
  }
33022
32930
  function resolveDefaultSlug() {
33023
32931
  try {
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"));
32932
+ const configDir2 = join13(homedir4(), BRAND.configDir);
32933
+ const accountJsonPath = join13(configDir2, "account.json");
32934
+ if (!existsSync26(accountJsonPath)) return null;
32935
+ const account = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
33028
32936
  return account.defaultAgent || null;
33029
32937
  } catch {
33030
32938
  return null;
@@ -33097,7 +33005,7 @@ app.use("/vnc-popout.html", logViewerFetch);
33097
33005
  app.get("/vnc-popout.html", (c) => {
33098
33006
  let html = htmlCache.get("vnc-popout.html");
33099
33007
  if (!html) {
33100
- html = readFileSync27(resolve27(process.cwd(), "public", "vnc-popout.html"), "utf-8");
33008
+ html = readFileSync26(resolve27(process.cwd(), "public", "vnc-popout.html"), "utf-8");
33101
33009
  const name = escapeHtml2(BRAND.productName);
33102
33010
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
33103
33011
  html = html.replace("</head>", ` ${brandScript}
@@ -33151,8 +33059,8 @@ console.log(`${BRAND.productName} listening on http://${hostname3}:${port}`);
33151
33059
  (async () => {
33152
33060
  try {
33153
33061
  let userId = "";
33154
- if (existsSync27(USERS_FILE)) {
33155
- const users = JSON.parse(readFileSync27(USERS_FILE, "utf-8").trim() || "[]");
33062
+ if (existsSync26(USERS_FILE)) {
33063
+ const users = JSON.parse(readFileSync26(USERS_FILE, "utf-8").trim() || "[]");
33156
33064
  userId = users[0]?.userId ?? "";
33157
33065
  }
33158
33066
  await backfillNullUserIdConversations(userId);
@@ -33178,7 +33086,7 @@ if (bootAccountConfig?.whatsapp) {
33178
33086
  }
33179
33087
  init({
33180
33088
  configDir: configDirForWhatsApp,
33181
- platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ?? join14(__dirname, "..")),
33089
+ platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ?? join13(__dirname, "..")),
33182
33090
  accountConfig: bootAccountConfig,
33183
33091
  onMessage: async (msg) => {
33184
33092
  try {