@agenticmail/core 0.9.5 → 0.9.6

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.
package/dist/index.cjs CHANGED
@@ -716,6 +716,7 @@ __export(index_exports, {
716
716
  CloudflareClient: () => CloudflareClient,
717
717
  DEFAULT_AGENT_NAME: () => DEFAULT_AGENT_NAME,
718
718
  DEFAULT_AGENT_ROLE: () => DEFAULT_AGENT_ROLE,
719
+ DEFAULT_SESSION_MAX_AGE_MS: () => DEFAULT_SESSION_MAX_AGE_MS,
719
720
  DNSConfigurator: () => DNSConfigurator,
720
721
  DependencyChecker: () => DependencyChecker,
721
722
  DependencyInstaller: () => DependencyInstaller,
@@ -752,9 +753,13 @@ __export(index_exports, {
752
753
  ensureDataDir: () => ensureDataDir,
753
754
  extractVerificationCode: () => extractVerificationCode,
754
755
  flushTelemetry: () => flushTelemetry,
756
+ forgetHostSession: () => forgetHostSession,
755
757
  getDatabase: () => getDatabase,
758
+ hostSessionStoragePath: () => hostSessionStoragePath,
756
759
  isInternalEmail: () => isInternalEmail,
760
+ isSessionFresh: () => isSessionFresh,
757
761
  isValidPhoneNumber: () => isValidPhoneNumber,
762
+ loadHostSession: () => loadHostSession,
758
763
  normalizeAddress: () => normalizeAddress,
759
764
  normalizePhoneNumber: () => normalizePhoneNumber,
760
765
  normalizeSubject: () => normalizeSubject,
@@ -767,6 +772,7 @@ __export(index_exports, {
767
772
  safeJoin: () => safeJoin,
768
773
  sanitizeEmail: () => sanitizeEmail,
769
774
  saveConfig: () => saveConfig,
775
+ saveHostSession: () => saveHostSession,
770
776
  scanOutboundEmail: () => scanOutboundEmail,
771
777
  scoreEmail: () => scoreEmail,
772
778
  setTelemetryVersion: () => setTelemetryVersion,
@@ -1862,14 +1868,14 @@ var StalwartAdmin = class {
1862
1868
  if (!isValidDomain(domain)) {
1863
1869
  throw new Error(`Invalid domain format: "${domain}"`);
1864
1870
  }
1865
- const { readFileSync: readFileSync7, writeFileSync: writeFileSync8 } = await import("fs");
1866
- const { homedir: homedir11 } = await import("os");
1867
- const { join: join13 } = await import("path");
1868
- const configPath = join13(homedir11(), ".agenticmail", "stalwart.toml");
1871
+ const { readFileSync: readFileSync8, writeFileSync: writeFileSync9 } = await import("fs");
1872
+ const { homedir: homedir12 } = await import("os");
1873
+ const { join: join14 } = await import("path");
1874
+ const configPath = join14(homedir12(), ".agenticmail", "stalwart.toml");
1869
1875
  try {
1870
- let config = readFileSync7(configPath, "utf-8");
1876
+ let config = readFileSync8(configPath, "utf-8");
1871
1877
  config = config.replace(/^hostname\s*=\s*"[^"]*"/m, `hostname = "${escapeTomlString(domain)}"`);
1872
- writeFileSync8(configPath, config);
1878
+ writeFileSync9(configPath, config);
1873
1879
  console.log(`[Stalwart] Updated hostname to "${domain}" in stalwart.toml`);
1874
1880
  } catch (err) {
1875
1881
  throw new Error(`Failed to set config server.hostname=${domain}`);
@@ -1878,15 +1884,15 @@ var StalwartAdmin = class {
1878
1884
  // --- DKIM ---
1879
1885
  /** Path to the host-side stalwart.toml (mounted read-only into container) */
1880
1886
  get configPath() {
1881
- const { homedir: homedir11 } = require("os");
1882
- const { join: join13 } = require("path");
1883
- return join13(homedir11(), ".agenticmail", "stalwart.toml");
1887
+ const { homedir: homedir12 } = require("os");
1888
+ const { join: join14 } = require("path");
1889
+ return join14(homedir12(), ".agenticmail", "stalwart.toml");
1884
1890
  }
1885
1891
  /** Path to host-side DKIM key directory */
1886
1892
  get dkimDir() {
1887
- const { homedir: homedir11 } = require("os");
1888
- const { join: join13 } = require("path");
1889
- return join13(homedir11(), ".agenticmail");
1893
+ const { homedir: homedir12 } = require("os");
1894
+ const { join: join14 } = require("path");
1895
+ return join14(homedir12(), ".agenticmail");
1890
1896
  }
1891
1897
  /**
1892
1898
  * Create/reuse a DKIM signing key for a domain.
@@ -1987,12 +1993,12 @@ var StalwartAdmin = class {
1987
1993
  * This bypasses the need for a PTR record on the sending IP.
1988
1994
  */
1989
1995
  async configureOutboundRelay(config) {
1990
- const { readFileSync: readFileSync7, writeFileSync: writeFileSync8 } = await import("fs");
1991
- const { homedir: homedir11 } = await import("os");
1992
- const { join: join13 } = await import("path");
1996
+ const { readFileSync: readFileSync8, writeFileSync: writeFileSync9 } = await import("fs");
1997
+ const { homedir: homedir12 } = await import("os");
1998
+ const { join: join14 } = await import("path");
1993
1999
  const routeName = config.routeName ?? "gmail";
1994
- const tomlPath = join13(homedir11(), ".agenticmail", "stalwart.toml");
1995
- let toml = readFileSync7(tomlPath, "utf-8");
2000
+ const tomlPath = join14(homedir12(), ".agenticmail", "stalwart.toml");
2001
+ let toml = readFileSync8(tomlPath, "utf-8");
1996
2002
  toml = toml.replace(/\n\[queue\.route\.gmail\][\s\S]*?(?=\n\[|$)/, "");
1997
2003
  toml = toml.replace(/\n\[queue\.strategy\][\s\S]*?(?=\n\[|$)/, "");
1998
2004
  const safeRouteName = routeName.replace(/[^a-zA-Z0-9_-]/g, "");
@@ -2012,7 +2018,7 @@ auth.secret = "${escapeTomlString(config.password)}"
2012
2018
  route = [ { if = "is_local_domain('', rcpt_domain)", then = "'local'" },
2013
2019
  { else = "'${safeRouteName}'" } ]
2014
2020
  `;
2015
- writeFileSync8(tomlPath, toml, "utf-8");
2021
+ writeFileSync9(tomlPath, toml, "utf-8");
2016
2022
  await this.restartContainer();
2017
2023
  }
2018
2024
  };
@@ -5013,9 +5019,9 @@ var TunnelManager = class {
5013
5019
  throw new Error(`Failed to download cloudflared: ${response.statusText}`);
5014
5020
  }
5015
5021
  const buffer = Buffer.from(await response.arrayBuffer());
5016
- const { writeFile: writeFile2, rename: rename2 } = await import("fs/promises");
5022
+ const { writeFile: writeFile3, rename: rename2 } = await import("fs/promises");
5017
5023
  const tmpPath = this.binPath + ".tmp";
5018
- await writeFile2(tmpPath, buffer);
5024
+ await writeFile3(tmpPath, buffer);
5019
5025
  await (0, import_promises.chmod)(tmpPath, 493);
5020
5026
  await rename2(tmpPath, this.binPath);
5021
5027
  return this.binPath;
@@ -5923,12 +5929,12 @@ var GatewayManager = class {
5923
5929
  zone = await this.cfClient.createZone(domain);
5924
5930
  }
5925
5931
  const existingRecords = await this.cfClient.listDnsRecords(zone.id);
5926
- const { homedir: homedir11 } = await import("os");
5927
- const backupDir = (0, import_node_path4.join)(homedir11(), ".agenticmail");
5932
+ const { homedir: homedir12 } = await import("os");
5933
+ const backupDir = (0, import_node_path4.join)(homedir12(), ".agenticmail");
5928
5934
  const backupPath = (0, import_node_path4.join)(backupDir, `dns-backup-${domain}-${Date.now()}.json`);
5929
- const { writeFileSync: writeFileSync8, mkdirSync: mkdirSync9 } = await import("fs");
5930
- mkdirSync9(backupDir, { recursive: true });
5931
- writeFileSync8(backupPath, JSON.stringify({
5935
+ const { writeFileSync: writeFileSync9, mkdirSync: mkdirSync10 } = await import("fs");
5936
+ mkdirSync10(backupDir, { recursive: true });
5937
+ writeFileSync9(backupPath, JSON.stringify({
5932
5938
  domain,
5933
5939
  zoneId: zone.id,
5934
5940
  backedUpAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -6870,6 +6876,76 @@ function redactObject(input, _depth = 0) {
6870
6876
  return out;
6871
6877
  }
6872
6878
 
6879
+ // src/host-sessions.ts
6880
+ var import_node_fs4 = require("fs");
6881
+ var import_node_path6 = require("path");
6882
+ var import_node_os4 = require("os");
6883
+ function storageDir() {
6884
+ return (0, import_node_path6.join)((0, import_node_os4.homedir)(), ".agenticmail");
6885
+ }
6886
+ function storagePath() {
6887
+ return (0, import_node_path6.join)(storageDir(), "host-sessions.json");
6888
+ }
6889
+ var DEFAULT_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
6890
+ function readFile() {
6891
+ const p = storagePath();
6892
+ if (!(0, import_node_fs4.existsSync)(p)) return { version: 1, sessions: {} };
6893
+ try {
6894
+ const raw = (0, import_node_fs4.readFileSync)(p, "utf-8");
6895
+ if (!raw.trim()) return { version: 1, sessions: {} };
6896
+ const parsed = JSON.parse(raw);
6897
+ return {
6898
+ version: 1,
6899
+ sessions: parsed.sessions && typeof parsed.sessions === "object" ? parsed.sessions : {}
6900
+ };
6901
+ } catch {
6902
+ return { version: 1, sessions: {} };
6903
+ }
6904
+ }
6905
+ function writeFile(shape) {
6906
+ const dir = storageDir();
6907
+ const p = storagePath();
6908
+ if (!(0, import_node_fs4.existsSync)(dir)) (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
6909
+ const tmp = `${p}.agenticmail-tmp-${process.pid}`;
6910
+ (0, import_node_fs4.writeFileSync)(tmp, JSON.stringify(shape, null, 2), "utf-8");
6911
+ (0, import_node_fs4.renameSync)(tmp, p);
6912
+ }
6913
+ function saveHostSession(host, session) {
6914
+ if (!session.sessionId) return;
6915
+ try {
6916
+ const shape = readFile();
6917
+ shape.sessions[host] = {
6918
+ ...session,
6919
+ lastSeenMs: Date.now()
6920
+ };
6921
+ writeFile(shape);
6922
+ } catch {
6923
+ }
6924
+ }
6925
+ function loadHostSession(host, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
6926
+ const shape = readFile();
6927
+ const record = shape.sessions[host];
6928
+ if (!record) return null;
6929
+ if (!isSessionFresh(record, maxAgeMs)) return null;
6930
+ return record;
6931
+ }
6932
+ function isSessionFresh(session, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
6933
+ if (!session || !Number.isFinite(session.lastSeenMs)) return false;
6934
+ return Date.now() - session.lastSeenMs <= maxAgeMs;
6935
+ }
6936
+ function forgetHostSession(host) {
6937
+ try {
6938
+ const shape = readFile();
6939
+ if (!shape.sessions[host]) return;
6940
+ delete shape.sessions[host];
6941
+ writeFile(shape);
6942
+ } catch {
6943
+ }
6944
+ }
6945
+ function hostSessionStoragePath() {
6946
+ return storagePath();
6947
+ }
6948
+
6873
6949
  // src/util/safe-url.ts
6874
6950
  var UnsafeApiUrlError = class extends Error {
6875
6951
  constructor(raw, reason) {
@@ -6918,15 +6994,15 @@ function buildApiUrl(baseOrigin, pathAndQuery) {
6918
6994
 
6919
6995
  // src/setup/index.ts
6920
6996
  var import_node_crypto3 = require("crypto");
6921
- var import_node_fs7 = require("fs");
6922
- var import_node_path9 = require("path");
6923
- var import_node_os7 = require("os");
6997
+ var import_node_fs8 = require("fs");
6998
+ var import_node_path10 = require("path");
6999
+ var import_node_os8 = require("os");
6924
7000
 
6925
7001
  // src/setup/deps.ts
6926
7002
  var import_node_child_process2 = require("child_process");
6927
- var import_node_fs4 = require("fs");
6928
- var import_node_path6 = require("path");
6929
- var import_node_os4 = require("os");
7003
+ var import_node_fs5 = require("fs");
7004
+ var import_node_path7 = require("path");
7005
+ var import_node_os5 = require("os");
6930
7006
  var DependencyChecker = class {
6931
7007
  async checkAll() {
6932
7008
  return Promise.all([
@@ -6976,8 +7052,8 @@ var DependencyChecker = class {
6976
7052
  }
6977
7053
  }
6978
7054
  async checkCloudflared() {
6979
- const binPath = (0, import_node_path6.join)((0, import_node_os4.homedir)(), ".agenticmail", "bin", "cloudflared");
6980
- if ((0, import_node_fs4.existsSync)(binPath)) {
7055
+ const binPath = (0, import_node_path7.join)((0, import_node_os5.homedir)(), ".agenticmail", "bin", "cloudflared");
7056
+ if ((0, import_node_fs5.existsSync)(binPath)) {
6981
7057
  let version;
6982
7058
  try {
6983
7059
  const output = (0, import_node_child_process2.execFileSync)(binPath, ["--version"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
@@ -6999,10 +7075,10 @@ var DependencyChecker = class {
6999
7075
 
7000
7076
  // src/setup/installer.ts
7001
7077
  var import_node_child_process3 = require("child_process");
7002
- var import_node_fs5 = require("fs");
7078
+ var import_node_fs6 = require("fs");
7003
7079
  var import_promises2 = require("fs/promises");
7004
- var import_node_path7 = require("path");
7005
- var import_node_os5 = require("os");
7080
+ var import_node_path8 = require("path");
7081
+ var import_node_os6 = require("os");
7006
7082
  function runShellWithRollingOutput(cmd, opts = {}) {
7007
7083
  const maxLines = opts.maxLines ?? 20;
7008
7084
  const timeout = opts.timeout ?? 3e5;
@@ -7112,7 +7188,7 @@ var DependencyInstaller = class {
7112
7188
  */
7113
7189
  async installDocker() {
7114
7190
  if (this.isDockerReady()) return;
7115
- const os = (0, import_node_os5.platform)();
7191
+ const os = (0, import_node_os6.platform)();
7116
7192
  if (os === "darwin") {
7117
7193
  await this.installDockerMac();
7118
7194
  } else if (os === "linux") {
@@ -7178,15 +7254,15 @@ var DependencyInstaller = class {
7178
7254
  try {
7179
7255
  const composeBin = (0, import_node_child_process3.execFileSync)("which", ["docker-compose"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
7180
7256
  if (!composeBin) return;
7181
- const pluginDir = (0, import_node_path7.join)((0, import_node_os5.homedir)(), ".docker", "cli-plugins");
7182
- const pluginPath = (0, import_node_path7.join)(pluginDir, "docker-compose");
7183
- if ((0, import_node_fs5.existsSync)(pluginPath)) return;
7257
+ const pluginDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".docker", "cli-plugins");
7258
+ const pluginPath = (0, import_node_path8.join)(pluginDir, "docker-compose");
7259
+ if ((0, import_node_fs6.existsSync)(pluginPath)) return;
7184
7260
  try {
7185
- (0, import_node_fs5.mkdirSync)(pluginDir, { recursive: true });
7261
+ (0, import_node_fs6.mkdirSync)(pluginDir, { recursive: true });
7186
7262
  } catch {
7187
7263
  }
7188
7264
  try {
7189
- (0, import_node_fs5.symlinkSync)(composeBin, pluginPath);
7265
+ (0, import_node_fs6.symlinkSync)(composeBin, pluginPath);
7190
7266
  } catch {
7191
7267
  }
7192
7268
  } catch {
@@ -7245,9 +7321,9 @@ var DependencyInstaller = class {
7245
7321
  return;
7246
7322
  }
7247
7323
  this.onProgress("__progress__:5:Installing Docker Engine...");
7248
- const tmpDir = (0, import_node_path7.join)((0, import_node_os5.homedir)(), ".agenticmail", "tmp");
7324
+ const tmpDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "tmp");
7249
7325
  await (0, import_promises2.mkdir)(tmpDir, { recursive: true });
7250
- const scriptPath = (0, import_node_path7.join)(tmpDir, "install-docker.sh");
7326
+ const scriptPath = (0, import_node_path8.join)(tmpDir, "install-docker.sh");
7251
7327
  const dlResult = await runShellWithRollingOutput(
7252
7328
  `curl -fsSL https://get.docker.com -o "${scriptPath}" && sudo sh "${scriptPath}"`,
7253
7329
  { timeout: 3e5 }
@@ -7315,8 +7391,8 @@ var DependencyInstaller = class {
7315
7391
  }
7316
7392
  try {
7317
7393
  const programFiles = process.env["ProgramFiles"] || "C:\\Program Files";
7318
- const dockerExe = (0, import_node_path7.join)(programFiles, "Docker", "Docker", "Docker Desktop.exe");
7319
- if ((0, import_node_fs5.existsSync)(dockerExe)) {
7394
+ const dockerExe = (0, import_node_path8.join)(programFiles, "Docker", "Docker", "Docker Desktop.exe");
7395
+ if ((0, import_node_fs6.existsSync)(dockerExe)) {
7320
7396
  (0, import_node_child_process3.execSync)(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
7321
7397
  }
7322
7398
  } catch {
@@ -7366,8 +7442,8 @@ var DependencyInstaller = class {
7366
7442
  this.onProgress("__progress__:70:Docker Desktop installed. Starting...");
7367
7443
  try {
7368
7444
  const programFiles = process.env["ProgramFiles"] || "C:\\Program Files";
7369
- const dockerExe = (0, import_node_path7.join)(programFiles, "Docker", "Docker", "Docker Desktop.exe");
7370
- if ((0, import_node_fs5.existsSync)(dockerExe)) {
7445
+ const dockerExe = (0, import_node_path8.join)(programFiles, "Docker", "Docker", "Docker Desktop.exe");
7446
+ if ((0, import_node_fs6.existsSync)(dockerExe)) {
7371
7447
  (0, import_node_child_process3.execSync)(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
7372
7448
  }
7373
7449
  } catch {
@@ -7404,12 +7480,12 @@ var DependencyInstaller = class {
7404
7480
  * Start the Stalwart mail server Docker container.
7405
7481
  */
7406
7482
  async startStalwart(composePath) {
7407
- if (!(0, import_node_fs5.existsSync)(composePath)) {
7483
+ if (!(0, import_node_fs6.existsSync)(composePath)) {
7408
7484
  throw new Error(`docker-compose.yml not found at: ${composePath}`);
7409
7485
  }
7410
7486
  if (!this.isDockerReady()) {
7411
7487
  this.onProgress("Starting Docker...");
7412
- const os = (0, import_node_os5.platform)();
7488
+ const os = (0, import_node_os6.platform)();
7413
7489
  if (os === "darwin") {
7414
7490
  await this.startColima();
7415
7491
  } else if (os === "win32") {
@@ -7427,7 +7503,7 @@ var DependencyInstaller = class {
7427
7503
  }
7428
7504
  }
7429
7505
  this.onProgress("__progress__:10:Pulling mail server image...");
7430
- if ((0, import_node_os5.platform)() === "darwin") this.linkComposePlugin();
7506
+ if ((0, import_node_os6.platform)() === "darwin") this.linkComposePlugin();
7431
7507
  let composeResult = await runSilent("docker", ["compose", "-f", composePath, "up", "-d"], { timeout: 12e4 });
7432
7508
  if (composeResult.exitCode !== 0 && hasCommand("docker-compose")) {
7433
7509
  composeResult = await runSilent("docker-compose", ["-f", composePath, "up", "-d"], { timeout: 12e4 });
@@ -7462,22 +7538,22 @@ var DependencyInstaller = class {
7462
7538
  * Returns the path to the installed binary.
7463
7539
  */
7464
7540
  async installCloudflared() {
7465
- const os = (0, import_node_os5.platform)();
7466
- const binDir = (0, import_node_path7.join)((0, import_node_os5.homedir)(), ".agenticmail", "bin");
7541
+ const os = (0, import_node_os6.platform)();
7542
+ const binDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "bin");
7467
7543
  const binName = os === "win32" ? "cloudflared.exe" : "cloudflared";
7468
- const binPath = (0, import_node_path7.join)(binDir, binName);
7469
- if ((0, import_node_fs5.existsSync)(binPath)) {
7544
+ const binPath = (0, import_node_path8.join)(binDir, binName);
7545
+ if ((0, import_node_fs6.existsSync)(binPath)) {
7470
7546
  return binPath;
7471
7547
  }
7472
7548
  try {
7473
7549
  const whichCmd = os === "win32" ? "where" : "which";
7474
7550
  const sysPath = (0, import_node_child_process3.execFileSync)(whichCmd, ["cloudflared"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim().split("\n")[0];
7475
- if (sysPath && (0, import_node_fs5.existsSync)(sysPath)) return sysPath;
7551
+ if (sysPath && (0, import_node_fs6.existsSync)(sysPath)) return sysPath;
7476
7552
  } catch {
7477
7553
  }
7478
7554
  this.onProgress("Downloading cloudflared...");
7479
7555
  await (0, import_promises2.mkdir)(binDir, { recursive: true });
7480
- const cpu = (0, import_node_os5.arch)();
7556
+ const cpu = (0, import_node_os6.arch)();
7481
7557
  const archName = cpu === "arm64" ? "arm64" : "amd64";
7482
7558
  let downloadUrl;
7483
7559
  if (os === "darwin") {
@@ -7495,7 +7571,7 @@ var DependencyInstaller = class {
7495
7571
  }
7496
7572
  const buffer = Buffer.from(await response.arrayBuffer());
7497
7573
  if (os === "darwin") {
7498
- const tgzPath = (0, import_node_path7.join)(binDir, "cloudflared.tgz");
7574
+ const tgzPath = (0, import_node_path8.join)(binDir, "cloudflared.tgz");
7499
7575
  await (0, import_promises2.writeFile)(tgzPath, buffer);
7500
7576
  try {
7501
7577
  (0, import_node_child_process3.execFileSync)("tar", ["-xzf", tgzPath, "-C", binDir, "cloudflared"], { timeout: 15e3, stdio: "ignore" });
@@ -7512,7 +7588,7 @@ var DependencyInstaller = class {
7512
7588
  if (os !== "win32") await (0, import_promises2.chmod)(tmpPath, 493);
7513
7589
  await (0, import_promises2.rename)(tmpPath, binPath);
7514
7590
  }
7515
- if (!(0, import_node_fs5.existsSync)(binPath)) {
7591
+ if (!(0, import_node_fs6.existsSync)(binPath)) {
7516
7592
  throw new Error("cloudflared download succeeded but binary not found after extraction");
7517
7593
  }
7518
7594
  this.onProgress("cloudflared installed");
@@ -7530,23 +7606,23 @@ var DependencyInstaller = class {
7530
7606
 
7531
7607
  // src/setup/service.ts
7532
7608
  var import_node_child_process4 = require("child_process");
7533
- var import_node_fs6 = require("fs");
7534
- var import_node_path8 = require("path");
7535
- var import_node_os6 = require("os");
7609
+ var import_node_fs7 = require("fs");
7610
+ var import_node_path9 = require("path");
7611
+ var import_node_os7 = require("os");
7536
7612
  var import_node_module2 = require("module");
7537
7613
  var import_meta2 = {};
7538
7614
  var PLIST_LABEL = "com.agenticmail.server";
7539
7615
  var SYSTEMD_UNIT = "agenticmail.service";
7540
7616
  var ServiceManager = class {
7541
- os = (0, import_node_os6.platform)();
7617
+ os = (0, import_node_os7.platform)();
7542
7618
  /**
7543
7619
  * Get the path to the service file.
7544
7620
  */
7545
7621
  getServicePath() {
7546
7622
  if (this.os === "darwin") {
7547
- return (0, import_node_path8.join)((0, import_node_os6.homedir)(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
7623
+ return (0, import_node_path9.join)((0, import_node_os7.homedir)(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
7548
7624
  } else {
7549
- return (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".config", "systemd", "user", SYSTEMD_UNIT);
7625
+ return (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".config", "systemd", "user", SYSTEMD_UNIT);
7550
7626
  }
7551
7627
  }
7552
7628
  /**
@@ -7580,40 +7656,40 @@ var ServiceManager = class {
7580
7656
  try {
7581
7657
  const req = (0, import_node_module2.createRequire)(import_meta2.url);
7582
7658
  const resolved = req.resolve("@agenticmail/api");
7583
- if ((0, import_node_fs6.existsSync)(resolved)) return resolved;
7659
+ if ((0, import_node_fs7.existsSync)(resolved)) return resolved;
7584
7660
  } catch {
7585
7661
  }
7586
7662
  const parentPackages = [
7587
- (0, import_node_path8.join)("@agenticmail", "cli"),
7663
+ (0, import_node_path9.join)("@agenticmail", "cli"),
7588
7664
  // current scoped package
7589
7665
  "agenticmail"
7590
7666
  // legacy unscoped package
7591
7667
  ];
7592
7668
  const baseDirs = [
7593
7669
  // user-local install
7594
- (0, import_node_path8.join)((0, import_node_os6.homedir)(), "node_modules")
7670
+ (0, import_node_path9.join)((0, import_node_os7.homedir)(), "node_modules")
7595
7671
  ];
7596
7672
  try {
7597
7673
  const prefix = (0, import_node_child_process4.execSync)("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
7598
- baseDirs.push((0, import_node_path8.join)(prefix, "lib", "node_modules"));
7599
- baseDirs.push((0, import_node_path8.join)(prefix, "node_modules"));
7674
+ baseDirs.push((0, import_node_path9.join)(prefix, "lib", "node_modules"));
7675
+ baseDirs.push((0, import_node_path9.join)(prefix, "node_modules"));
7600
7676
  } catch {
7601
7677
  }
7602
7678
  baseDirs.push("/opt/homebrew/lib/node_modules");
7603
7679
  baseDirs.push("/usr/local/lib/node_modules");
7604
7680
  for (const base of baseDirs) {
7605
- const sibling = (0, import_node_path8.join)(base, "@agenticmail", "api", "dist", "index.js");
7606
- if ((0, import_node_fs6.existsSync)(sibling)) return sibling;
7681
+ const sibling = (0, import_node_path9.join)(base, "@agenticmail", "api", "dist", "index.js");
7682
+ if ((0, import_node_fs7.existsSync)(sibling)) return sibling;
7607
7683
  for (const parent of parentPackages) {
7608
- const nested = (0, import_node_path8.join)(base, parent, "node_modules", "@agenticmail", "api", "dist", "index.js");
7609
- if ((0, import_node_fs6.existsSync)(nested)) return nested;
7684
+ const nested = (0, import_node_path9.join)(base, parent, "node_modules", "@agenticmail", "api", "dist", "index.js");
7685
+ if ((0, import_node_fs7.existsSync)(nested)) return nested;
7610
7686
  }
7611
7687
  }
7612
- const dataDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail");
7613
- const entryCache = (0, import_node_path8.join)(dataDir, "api-entry.path");
7614
- if ((0, import_node_fs6.existsSync)(entryCache)) {
7615
- const cached = (0, import_node_fs6.readFileSync)(entryCache, "utf-8").trim();
7616
- if (cached && (0, import_node_fs6.existsSync)(cached)) return cached;
7688
+ const dataDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail");
7689
+ const entryCache = (0, import_node_path9.join)(dataDir, "api-entry.path");
7690
+ if ((0, import_node_fs7.existsSync)(entryCache)) {
7691
+ const cached = (0, import_node_fs7.readFileSync)(entryCache, "utf-8").trim();
7692
+ if (cached && (0, import_node_fs7.existsSync)(cached)) return cached;
7617
7693
  }
7618
7694
  throw new Error("Could not find @agenticmail/api entry point. Run `agenticmail start` first to populate the cache.");
7619
7695
  }
@@ -7621,9 +7697,9 @@ var ServiceManager = class {
7621
7697
  * Cache the API entry path so the service can find it later.
7622
7698
  */
7623
7699
  cacheApiEntryPath(entryPath) {
7624
- const dataDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail");
7625
- if (!(0, import_node_fs6.existsSync)(dataDir)) (0, import_node_fs6.mkdirSync)(dataDir, { recursive: true });
7626
- (0, import_node_fs6.writeFileSync)((0, import_node_path8.join)(dataDir, "api-entry.path"), entryPath);
7700
+ const dataDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail");
7701
+ if (!(0, import_node_fs7.existsSync)(dataDir)) (0, import_node_fs7.mkdirSync)(dataDir, { recursive: true });
7702
+ (0, import_node_fs7.writeFileSync)((0, import_node_path9.join)(dataDir, "api-entry.path"), entryPath);
7627
7703
  }
7628
7704
  /**
7629
7705
  * Get the current package version.
@@ -7636,36 +7712,36 @@ var ServiceManager = class {
7636
7712
  try {
7637
7713
  const req = (0, import_node_module2.createRequire)(import_meta2.url);
7638
7714
  const pkgJson = req.resolve("@agenticmail/cli/package.json");
7639
- if ((0, import_node_fs6.existsSync)(pkgJson)) {
7640
- const pkg = JSON.parse((0, import_node_fs6.readFileSync)(pkgJson, "utf-8"));
7715
+ if ((0, import_node_fs7.existsSync)(pkgJson)) {
7716
+ const pkg = JSON.parse((0, import_node_fs7.readFileSync)(pkgJson, "utf-8"));
7641
7717
  if (pkg.version) return pkg.version;
7642
7718
  }
7643
7719
  } catch {
7644
7720
  }
7645
7721
  try {
7646
7722
  const apiEntry = this.getApiEntryPath();
7647
- const apiPkg = (0, import_node_path8.join)(apiEntry, "..", "..", "package.json");
7648
- if ((0, import_node_fs6.existsSync)(apiPkg)) {
7649
- const pkg = JSON.parse((0, import_node_fs6.readFileSync)(apiPkg, "utf-8"));
7723
+ const apiPkg = (0, import_node_path9.join)(apiEntry, "..", "..", "package.json");
7724
+ if ((0, import_node_fs7.existsSync)(apiPkg)) {
7725
+ const pkg = JSON.parse((0, import_node_fs7.readFileSync)(apiPkg, "utf-8"));
7650
7726
  if (pkg.version) return pkg.version;
7651
7727
  }
7652
7728
  } catch {
7653
7729
  }
7654
7730
  const candidates = [
7655
- (0, import_node_path8.join)((0, import_node_os6.homedir)(), "node_modules", "@agenticmail", "cli", "package.json"),
7656
- (0, import_node_path8.join)((0, import_node_os6.homedir)(), "node_modules", "agenticmail", "package.json"),
7657
- (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "package-version.json")
7731
+ (0, import_node_path9.join)((0, import_node_os7.homedir)(), "node_modules", "@agenticmail", "cli", "package.json"),
7732
+ (0, import_node_path9.join)((0, import_node_os7.homedir)(), "node_modules", "agenticmail", "package.json"),
7733
+ (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "package-version.json")
7658
7734
  ];
7659
7735
  try {
7660
7736
  const prefix = (0, import_node_child_process4.execSync)("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
7661
- candidates.push((0, import_node_path8.join)(prefix, "lib", "node_modules", "@agenticmail", "cli", "package.json"));
7662
- candidates.push((0, import_node_path8.join)(prefix, "lib", "node_modules", "agenticmail", "package.json"));
7737
+ candidates.push((0, import_node_path9.join)(prefix, "lib", "node_modules", "@agenticmail", "cli", "package.json"));
7738
+ candidates.push((0, import_node_path9.join)(prefix, "lib", "node_modules", "agenticmail", "package.json"));
7663
7739
  } catch {
7664
7740
  }
7665
7741
  for (const p of candidates) {
7666
7742
  try {
7667
- if ((0, import_node_fs6.existsSync)(p)) {
7668
- const pkg = JSON.parse((0, import_node_fs6.readFileSync)(p, "utf-8"));
7743
+ if ((0, import_node_fs7.existsSync)(p)) {
7744
+ const pkg = JSON.parse((0, import_node_fs7.readFileSync)(p, "utf-8"));
7669
7745
  if (pkg.version) return pkg.version;
7670
7746
  }
7671
7747
  } catch {
@@ -7678,9 +7754,9 @@ var ServiceManager = class {
7678
7754
  * This ensures AgenticMail doesn't fail on boot when Docker is still loading.
7679
7755
  */
7680
7756
  generateStartScript(nodePath, apiEntry) {
7681
- const scriptPath = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "bin", "start-server.sh");
7682
- const scriptDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "bin");
7683
- if (!(0, import_node_fs6.existsSync)(scriptDir)) (0, import_node_fs6.mkdirSync)(scriptDir, { recursive: true });
7757
+ const scriptPath = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "bin", "start-server.sh");
7758
+ const scriptDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "bin");
7759
+ if (!(0, import_node_fs7.existsSync)(scriptDir)) (0, import_node_fs7.mkdirSync)(scriptDir, { recursive: true });
7684
7760
  const script = [
7685
7761
  "#!/bin/bash",
7686
7762
  "# AgenticMail auto-start script",
@@ -7731,7 +7807,7 @@ var ServiceManager = class {
7731
7807
  `log "Starting API server: ${nodePath} ${apiEntry}"`,
7732
7808
  `exec "${nodePath}" "${apiEntry}"`
7733
7809
  ].join("\n") + "\n";
7734
- (0, import_node_fs6.writeFileSync)(scriptPath, script, { mode: 493 });
7810
+ (0, import_node_fs7.writeFileSync)(scriptPath, script, { mode: 493 });
7735
7811
  return scriptPath;
7736
7812
  }
7737
7813
  /**
@@ -7744,9 +7820,9 @@ var ServiceManager = class {
7744
7820
  * - Service version tracking in env vars
7745
7821
  */
7746
7822
  generatePlist(nodePath, apiEntry, configPath) {
7747
- const config = JSON.parse((0, import_node_fs6.readFileSync)(configPath, "utf-8"));
7748
- const logDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "logs");
7749
- if (!(0, import_node_fs6.existsSync)(logDir)) (0, import_node_fs6.mkdirSync)(logDir, { recursive: true });
7823
+ const config = JSON.parse((0, import_node_fs7.readFileSync)(configPath, "utf-8"));
7824
+ const logDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "logs");
7825
+ if (!(0, import_node_fs7.existsSync)(logDir)) (0, import_node_fs7.mkdirSync)(logDir, { recursive: true });
7750
7826
  const version = this.getVersion();
7751
7827
  const startScript = this.generateStartScript(nodePath, apiEntry);
7752
7828
  return `<?xml version="1.0" encoding="UTF-8"?>
@@ -7767,9 +7843,9 @@ var ServiceManager = class {
7767
7843
  <key>EnvironmentVariables</key>
7768
7844
  <dict>
7769
7845
  <key>HOME</key>
7770
- <string>${(0, import_node_os6.homedir)()}</string>
7846
+ <string>${(0, import_node_os7.homedir)()}</string>
7771
7847
  <key>AGENTICMAIL_DATA_DIR</key>
7772
- <string>${config.dataDir || (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail")}</string>
7848
+ <string>${config.dataDir || (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail")}</string>
7773
7849
  <key>PATH</key>
7774
7850
  <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
7775
7851
  <key>AGENTICMAIL_SERVICE_VERSION</key>
@@ -7822,8 +7898,8 @@ var ServiceManager = class {
7822
7898
  * - Proper dependency ordering
7823
7899
  */
7824
7900
  generateSystemdUnit(nodePath, apiEntry, configPath) {
7825
- const config = JSON.parse((0, import_node_fs6.readFileSync)(configPath, "utf-8"));
7826
- const dataDir = config.dataDir || (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail");
7901
+ const config = JSON.parse((0, import_node_fs7.readFileSync)(configPath, "utf-8"));
7902
+ const dataDir = config.dataDir || (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail");
7827
7903
  const version = this.getVersion();
7828
7904
  const startScript = this.generateStartScript(nodePath, apiEntry);
7829
7905
  return `[Unit]
@@ -7840,7 +7916,7 @@ Restart=always
7840
7916
  RestartSec=15
7841
7917
  TimeoutStartSec=660
7842
7918
  LimitNOFILE=8192
7843
- Environment=HOME=${(0, import_node_os6.homedir)()}
7919
+ Environment=HOME=${(0, import_node_os7.homedir)()}
7844
7920
  Environment=AGENTICMAIL_DATA_DIR=${dataDir}
7845
7921
  Environment=PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin
7846
7922
  Environment=AGENTICMAIL_SERVICE_VERSION=${version}
@@ -7853,8 +7929,8 @@ WantedBy=default.target
7853
7929
  * Install the auto-start service.
7854
7930
  */
7855
7931
  install() {
7856
- const configPath = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "config.json");
7857
- if (!(0, import_node_fs6.existsSync)(configPath)) {
7932
+ const configPath = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "config.json");
7933
+ if (!(0, import_node_fs7.existsSync)(configPath)) {
7858
7934
  return { installed: false, message: "Config not found. Run agenticmail setup first." };
7859
7935
  }
7860
7936
  const nodePath = this.getNodePath();
@@ -7866,17 +7942,17 @@ WantedBy=default.target
7866
7942
  }
7867
7943
  const servicePath = this.getServicePath();
7868
7944
  if (this.os === "darwin") {
7869
- const dir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), "Library", "LaunchAgents");
7870
- if (!(0, import_node_fs6.existsSync)(dir)) (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
7871
- if ((0, import_node_fs6.existsSync)(servicePath)) {
7945
+ const dir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), "Library", "LaunchAgents");
7946
+ if (!(0, import_node_fs7.existsSync)(dir)) (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
7947
+ if ((0, import_node_fs7.existsSync)(servicePath)) {
7872
7948
  try {
7873
7949
  (0, import_node_child_process4.execFileSync)("launchctl", ["unload", servicePath], { timeout: 1e4, stdio: "ignore" });
7874
7950
  } catch {
7875
7951
  }
7876
7952
  }
7877
7953
  const plist = this.generatePlist(nodePath, apiEntry, configPath);
7878
- (0, import_node_fs6.writeFileSync)(servicePath, plist);
7879
- (0, import_node_fs6.chmodSync)(servicePath, 384);
7954
+ (0, import_node_fs7.writeFileSync)(servicePath, plist);
7955
+ (0, import_node_fs7.chmodSync)(servicePath, 384);
7880
7956
  try {
7881
7957
  (0, import_node_child_process4.execFileSync)("launchctl", ["load", servicePath], { timeout: 1e4, stdio: "ignore" });
7882
7958
  } catch (err) {
@@ -7884,11 +7960,11 @@ WantedBy=default.target
7884
7960
  }
7885
7961
  return { installed: true, message: `Service installed at ${servicePath}` };
7886
7962
  } else if (this.os === "linux") {
7887
- const dir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".config", "systemd", "user");
7888
- if (!(0, import_node_fs6.existsSync)(dir)) (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
7963
+ const dir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".config", "systemd", "user");
7964
+ if (!(0, import_node_fs7.existsSync)(dir)) (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
7889
7965
  const unit = this.generateSystemdUnit(nodePath, apiEntry, configPath);
7890
- (0, import_node_fs6.writeFileSync)(servicePath, unit);
7891
- (0, import_node_fs6.chmodSync)(servicePath, 384);
7966
+ (0, import_node_fs7.writeFileSync)(servicePath, unit);
7967
+ (0, import_node_fs7.chmodSync)(servicePath, 384);
7892
7968
  try {
7893
7969
  (0, import_node_child_process4.execFileSync)("systemctl", ["--user", "daemon-reload"], { timeout: 1e4, stdio: "ignore" });
7894
7970
  (0, import_node_child_process4.execFileSync)("systemctl", ["--user", "enable", SYSTEMD_UNIT], { timeout: 1e4, stdio: "ignore" });
@@ -7910,7 +7986,7 @@ WantedBy=default.target
7910
7986
  */
7911
7987
  uninstall() {
7912
7988
  const servicePath = this.getServicePath();
7913
- if (!(0, import_node_fs6.existsSync)(servicePath)) {
7989
+ if (!(0, import_node_fs7.existsSync)(servicePath)) {
7914
7990
  return { removed: false, message: "Service is not installed." };
7915
7991
  }
7916
7992
  if (this.os === "darwin") {
@@ -7919,7 +7995,7 @@ WantedBy=default.target
7919
7995
  } catch {
7920
7996
  }
7921
7997
  try {
7922
- (0, import_node_fs6.unlinkSync)(servicePath);
7998
+ (0, import_node_fs7.unlinkSync)(servicePath);
7923
7999
  } catch {
7924
8000
  }
7925
8001
  return { removed: true, message: "Service removed." };
@@ -7930,7 +8006,7 @@ WantedBy=default.target
7930
8006
  } catch {
7931
8007
  }
7932
8008
  try {
7933
- (0, import_node_fs6.unlinkSync)(servicePath);
8009
+ (0, import_node_fs7.unlinkSync)(servicePath);
7934
8010
  } catch {
7935
8011
  }
7936
8012
  try {
@@ -7948,7 +8024,7 @@ WantedBy=default.target
7948
8024
  status() {
7949
8025
  const servicePath = this.getServicePath();
7950
8026
  const plat = this.os === "darwin" ? "launchd" : this.os === "linux" ? "systemd" : "unsupported";
7951
- const installed = (0, import_node_fs6.existsSync)(servicePath);
8027
+ const installed = (0, import_node_fs7.existsSync)(servicePath);
7952
8028
  let running = false;
7953
8029
  if (installed) {
7954
8030
  if (this.os === "darwin") {
@@ -8003,34 +8079,34 @@ WantedBy=default.target
8003
8079
  needsRepair() {
8004
8080
  if (this.os !== "darwin" && this.os !== "linux") return null;
8005
8081
  const servicePath = this.getServicePath();
8006
- if (!(0, import_node_fs6.existsSync)(servicePath)) return null;
8082
+ if (!(0, import_node_fs7.existsSync)(servicePath)) return null;
8007
8083
  let serviceContent = "";
8008
8084
  try {
8009
- serviceContent = (0, import_node_fs6.readFileSync)(servicePath, "utf-8");
8085
+ serviceContent = (0, import_node_fs7.readFileSync)(servicePath, "utf-8");
8010
8086
  } catch {
8011
8087
  return { reason: "Service file unreadable" };
8012
8088
  }
8013
- const startScript = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "bin", "start-server.sh");
8089
+ const startScript = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "bin", "start-server.sh");
8014
8090
  if (serviceContent.includes(startScript)) {
8015
- if (!(0, import_node_fs6.existsSync)(startScript)) {
8091
+ if (!(0, import_node_fs7.existsSync)(startScript)) {
8016
8092
  return { reason: "start-server.sh is missing" };
8017
8093
  }
8018
8094
  let scriptContent = "";
8019
8095
  try {
8020
- scriptContent = (0, import_node_fs6.readFileSync)(startScript, "utf-8");
8096
+ scriptContent = (0, import_node_fs7.readFileSync)(startScript, "utf-8");
8021
8097
  } catch {
8022
8098
  return { reason: "start-server.sh unreadable" };
8023
8099
  }
8024
8100
  const apiPathMatch = scriptContent.match(/(\/[^"\s]+@agenticmail\/api\/dist\/index\.js)/);
8025
8101
  if (apiPathMatch) {
8026
8102
  const referenced = apiPathMatch[1];
8027
- if (!(0, import_node_fs6.existsSync)(referenced)) {
8103
+ if (!(0, import_node_fs7.existsSync)(referenced)) {
8028
8104
  return { reason: `start-server.sh references missing path: ${referenced}` };
8029
8105
  }
8030
8106
  }
8031
8107
  if (/node_modules\/agenticmail\/(?!.*@agenticmail\/cli)/.test(scriptContent)) {
8032
8108
  const stale = /(\S*node_modules\/agenticmail\/\S*)/.exec(scriptContent)?.[1];
8033
- if (stale && !(0, import_node_fs6.existsSync)(stale)) {
8109
+ if (stale && !(0, import_node_fs7.existsSync)(stale)) {
8034
8110
  return { reason: `start-server.sh references legacy unscoped path: ${stale}` };
8035
8111
  }
8036
8112
  }
@@ -8043,11 +8119,11 @@ WantedBy=default.target
8043
8119
  return { reason: `Service version drift (current CLI is v${currentVersion})` };
8044
8120
  }
8045
8121
  }
8046
- const entryCache = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "api-entry.path");
8047
- if ((0, import_node_fs6.existsSync)(entryCache)) {
8122
+ const entryCache = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "api-entry.path");
8123
+ if ((0, import_node_fs7.existsSync)(entryCache)) {
8048
8124
  try {
8049
- const cached = (0, import_node_fs6.readFileSync)(entryCache, "utf-8").trim();
8050
- if (cached && !(0, import_node_fs6.existsSync)(cached)) {
8125
+ const cached = (0, import_node_fs7.readFileSync)(entryCache, "utf-8").trim();
8126
+ if (cached && !(0, import_node_fs7.existsSync)(cached)) {
8051
8127
  return { reason: `Cached API entry path no longer exists: ${cached}` };
8052
8128
  }
8053
8129
  } catch {
@@ -8098,13 +8174,13 @@ var SetupManager = class {
8098
8174
  * falls back to monorepo location.
8099
8175
  */
8100
8176
  getComposePath() {
8101
- const standalonePath = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "docker-compose.yml");
8102
- if ((0, import_node_fs7.existsSync)(standalonePath)) return standalonePath;
8177
+ const standalonePath = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "docker-compose.yml");
8178
+ if ((0, import_node_fs8.existsSync)(standalonePath)) return standalonePath;
8103
8179
  const cwd = process.cwd();
8104
- const candidates = [cwd, (0, import_node_path9.join)(cwd, "..")];
8180
+ const candidates = [cwd, (0, import_node_path10.join)(cwd, "..")];
8105
8181
  for (const dir of candidates) {
8106
- const p = (0, import_node_path9.join)(dir, "docker-compose.yml");
8107
- if ((0, import_node_fs7.existsSync)(p)) return p;
8182
+ const p = (0, import_node_path10.join)(dir, "docker-compose.yml");
8183
+ if ((0, import_node_fs8.existsSync)(p)) return p;
8108
8184
  }
8109
8185
  return standalonePath;
8110
8186
  }
@@ -8114,19 +8190,19 @@ var SetupManager = class {
8114
8190
  * Always regenerates Docker files to keep passwords in sync.
8115
8191
  */
8116
8192
  initConfig() {
8117
- const dataDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail");
8118
- const configPath = (0, import_node_path9.join)(dataDir, "config.json");
8119
- const envPath = (0, import_node_path9.join)(dataDir, ".env");
8120
- if ((0, import_node_fs7.existsSync)(configPath)) {
8193
+ const dataDir = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail");
8194
+ const configPath = (0, import_node_path10.join)(dataDir, "config.json");
8195
+ const envPath = (0, import_node_path10.join)(dataDir, ".env");
8196
+ if ((0, import_node_fs8.existsSync)(configPath)) {
8121
8197
  try {
8122
- const existing = JSON.parse((0, import_node_fs7.readFileSync)(configPath, "utf-8"));
8198
+ const existing = JSON.parse((0, import_node_fs8.readFileSync)(configPath, "utf-8"));
8123
8199
  this.generateDockerFiles(existing);
8124
8200
  return { configPath, envPath, config: existing, isNew: false };
8125
8201
  } catch {
8126
8202
  }
8127
8203
  }
8128
- if (!(0, import_node_fs7.existsSync)(dataDir)) {
8129
- (0, import_node_fs7.mkdirSync)(dataDir, { recursive: true });
8204
+ if (!(0, import_node_fs8.existsSync)(dataDir)) {
8205
+ (0, import_node_fs8.mkdirSync)(dataDir, { recursive: true });
8130
8206
  }
8131
8207
  const masterKey = `mk_${(0, import_node_crypto3.randomBytes)(24).toString("hex")}`;
8132
8208
  const stalwartPassword = (0, import_node_crypto3.randomBytes)(16).toString("hex");
@@ -8142,8 +8218,8 @@ var SetupManager = class {
8142
8218
  api: { port: 3829, host: "127.0.0.1" },
8143
8219
  dataDir
8144
8220
  };
8145
- (0, import_node_fs7.writeFileSync)(configPath, JSON.stringify(config, null, 2));
8146
- (0, import_node_fs7.chmodSync)(configPath, 384);
8221
+ (0, import_node_fs8.writeFileSync)(configPath, JSON.stringify(config, null, 2));
8222
+ (0, import_node_fs8.chmodSync)(configPath, 384);
8147
8223
  const envContent = `# Auto-generated by agenticmail setup
8148
8224
  STALWART_ADMIN_USER=admin
8149
8225
  STALWART_ADMIN_PASSWORD=${stalwartPassword}
@@ -8158,8 +8234,8 @@ SMTP_PORT=587
8158
8234
  IMAP_HOST=localhost
8159
8235
  IMAP_PORT=143
8160
8236
  `;
8161
- (0, import_node_fs7.writeFileSync)(envPath, envContent);
8162
- (0, import_node_fs7.chmodSync)(envPath, 384);
8237
+ (0, import_node_fs8.writeFileSync)(envPath, envContent);
8238
+ (0, import_node_fs8.chmodSync)(envPath, 384);
8163
8239
  this.generateDockerFiles(config);
8164
8240
  return { configPath, envPath, config, isNew: true };
8165
8241
  }
@@ -8168,13 +8244,13 @@ IMAP_PORT=143
8168
8244
  * with the correct admin password from config.
8169
8245
  */
8170
8246
  generateDockerFiles(config) {
8171
- const dataDir = config.dataDir || (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail");
8172
- if (!(0, import_node_fs7.existsSync)(dataDir)) {
8173
- (0, import_node_fs7.mkdirSync)(dataDir, { recursive: true });
8247
+ const dataDir = config.dataDir || (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail");
8248
+ if (!(0, import_node_fs8.existsSync)(dataDir)) {
8249
+ (0, import_node_fs8.mkdirSync)(dataDir, { recursive: true });
8174
8250
  }
8175
8251
  const password = config.stalwart?.adminPassword || "changeme";
8176
- const composePath = (0, import_node_path9.join)(dataDir, "docker-compose.yml");
8177
- (0, import_node_fs7.writeFileSync)(composePath, `services:
8252
+ const composePath = (0, import_node_path10.join)(dataDir, "docker-compose.yml");
8253
+ (0, import_node_fs8.writeFileSync)(composePath, `services:
8178
8254
  stalwart:
8179
8255
  # Pinned to v0.15.5 \u2014 Stalwart 0.16+ moved its config to JSON
8180
8256
  # at /etc/stalwart/config.json (hardcoded into the container
@@ -8203,9 +8279,9 @@ IMAP_PORT=143
8203
8279
  volumes:
8204
8280
  stalwart-data:
8205
8281
  `);
8206
- (0, import_node_fs7.chmodSync)(composePath, 384);
8207
- const tomlPath = (0, import_node_path9.join)(dataDir, "stalwart.toml");
8208
- (0, import_node_fs7.writeFileSync)(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
8282
+ (0, import_node_fs8.chmodSync)(composePath, 384);
8283
+ const tomlPath = (0, import_node_path10.join)(dataDir, "stalwart.toml");
8284
+ (0, import_node_fs8.writeFileSync)(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
8209
8285
 
8210
8286
  [server]
8211
8287
  hostname = "localhost"
@@ -8255,14 +8331,14 @@ enable = true
8255
8331
  user = "admin"
8256
8332
  secret = "${password}"
8257
8333
  `);
8258
- (0, import_node_fs7.chmodSync)(tomlPath, 384);
8334
+ (0, import_node_fs8.chmodSync)(tomlPath, 384);
8259
8335
  }
8260
8336
  /**
8261
8337
  * Check if config has already been initialized.
8262
8338
  */
8263
8339
  isInitialized() {
8264
- const configPath = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "config.json");
8265
- return (0, import_node_fs7.existsSync)(configPath);
8340
+ const configPath = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "config.json");
8341
+ return (0, import_node_fs8.existsSync)(configPath);
8266
8342
  }
8267
8343
  };
8268
8344
 
@@ -8300,10 +8376,10 @@ function threadIdFor(input) {
8300
8376
  }
8301
8377
 
8302
8378
  // src/threading/thread-cache.ts
8303
- var import_node_fs8 = require("fs");
8304
- var import_node_os8 = require("os");
8305
- var import_node_path10 = require("path");
8306
- var CACHE_DIR_DEFAULT = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "thread-cache");
8379
+ var import_node_fs9 = require("fs");
8380
+ var import_node_os9 = require("os");
8381
+ var import_node_path11 = require("path");
8382
+ var CACHE_DIR_DEFAULT = (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".agenticmail", "thread-cache");
8307
8383
  var DEFAULT_K_MESSAGES = 10;
8308
8384
  var DEFAULT_LRU_CAP = 5e3;
8309
8385
  var PREVIEW_MAX_CHARS = 240;
@@ -8316,22 +8392,22 @@ var ThreadCache = class {
8316
8392
  this.k = opts.k ?? DEFAULT_K_MESSAGES;
8317
8393
  this.lruCap = opts.lruCap ?? DEFAULT_LRU_CAP;
8318
8394
  try {
8319
- (0, import_node_fs8.mkdirSync)(this.dir, { recursive: true });
8395
+ (0, import_node_fs9.mkdirSync)(this.dir, { recursive: true });
8320
8396
  } catch {
8321
8397
  }
8322
8398
  }
8323
8399
  pathFor(threadId) {
8324
- return (0, import_node_path10.join)(this.dir, `${threadId}.json`);
8400
+ return (0, import_node_path11.join)(this.dir, `${threadId}.json`);
8325
8401
  }
8326
8402
  read(threadId) {
8327
8403
  const p = this.pathFor(threadId);
8328
- if (!(0, import_node_fs8.existsSync)(p)) return null;
8404
+ if (!(0, import_node_fs9.existsSync)(p)) return null;
8329
8405
  try {
8330
- const raw = (0, import_node_fs8.readFileSync)(p, "utf-8");
8406
+ const raw = (0, import_node_fs9.readFileSync)(p, "utf-8");
8331
8407
  return JSON.parse(raw);
8332
8408
  } catch {
8333
8409
  try {
8334
- (0, import_node_fs8.rmSync)(p, { force: true });
8410
+ (0, import_node_fs9.rmSync)(p, { force: true });
8335
8411
  } catch {
8336
8412
  }
8337
8413
  return null;
@@ -8372,7 +8448,7 @@ var ThreadCache = class {
8372
8448
  /** Permanently remove a thread's cache (called on [FINAL] / [DONE] / [CLOSED] / [WRAP]). */
8373
8449
  delete(threadId) {
8374
8450
  try {
8375
- (0, import_node_fs8.rmSync)(this.pathFor(threadId), { force: true });
8451
+ (0, import_node_fs9.rmSync)(this.pathFor(threadId), { force: true });
8376
8452
  } catch {
8377
8453
  }
8378
8454
  }
@@ -8392,8 +8468,8 @@ var ThreadCache = class {
8392
8468
  writeAtomic(threadId, entry) {
8393
8469
  const p = this.pathFor(threadId);
8394
8470
  const tmp = `${p}.tmp`;
8395
- (0, import_node_fs8.writeFileSync)(tmp, JSON.stringify(entry), "utf-8");
8396
- (0, import_node_fs8.renameSync)(tmp, p);
8471
+ (0, import_node_fs9.writeFileSync)(tmp, JSON.stringify(entry), "utf-8");
8472
+ (0, import_node_fs9.renameSync)(tmp, p);
8397
8473
  }
8398
8474
  /**
8399
8475
  * Best-effort LRU eviction. Runs at most every 256 writes (we
@@ -8405,15 +8481,15 @@ var ThreadCache = class {
8405
8481
  if (Math.random() > 1 / 256) return;
8406
8482
  let files;
8407
8483
  try {
8408
- files = (0, import_node_fs8.readdirSync)(this.dir).filter((f) => f.endsWith(".json"));
8484
+ files = (0, import_node_fs9.readdirSync)(this.dir).filter((f) => f.endsWith(".json"));
8409
8485
  } catch {
8410
8486
  return;
8411
8487
  }
8412
8488
  if (files.length <= this.lruCap) return;
8413
8489
  const stats = files.map((f) => {
8414
- const p = (0, import_node_path10.join)(this.dir, f);
8490
+ const p = (0, import_node_path11.join)(this.dir, f);
8415
8491
  try {
8416
- return { p, mtime: (0, import_node_fs8.statSync)(p).mtimeMs };
8492
+ return { p, mtime: (0, import_node_fs9.statSync)(p).mtimeMs };
8417
8493
  } catch {
8418
8494
  return { p, mtime: 0 };
8419
8495
  }
@@ -8422,7 +8498,7 @@ var ThreadCache = class {
8422
8498
  const dropCount = Math.max(1, Math.floor(this.lruCap * 0.1));
8423
8499
  for (let i = 0; i < dropCount; i++) {
8424
8500
  try {
8425
- (0, import_node_fs8.rmSync)(stats[i].p, { force: true });
8501
+ (0, import_node_fs9.rmSync)(stats[i].p, { force: true });
8426
8502
  } catch {
8427
8503
  }
8428
8504
  }
@@ -8441,30 +8517,30 @@ function dedupAndCap(messages, k) {
8441
8517
  }
8442
8518
 
8443
8519
  // src/threading/agent-memory.ts
8444
- var import_node_fs9 = require("fs");
8445
- var import_node_os9 = require("os");
8446
- var import_node_path11 = require("path");
8447
- var MEMORY_DIR_DEFAULT = (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".agenticmail", "agent-memory");
8520
+ var import_node_fs10 = require("fs");
8521
+ var import_node_os10 = require("os");
8522
+ var import_node_path12 = require("path");
8523
+ var MEMORY_DIR_DEFAULT = (0, import_node_path12.join)((0, import_node_os10.homedir)(), ".agenticmail", "agent-memory");
8448
8524
  var AgentMemoryStore = class {
8449
8525
  dir;
8450
8526
  constructor(opts = {}) {
8451
8527
  this.dir = opts.memoryDir ?? MEMORY_DIR_DEFAULT;
8452
8528
  try {
8453
- (0, import_node_fs9.mkdirSync)(this.dir, { recursive: true });
8529
+ (0, import_node_fs10.mkdirSync)(this.dir, { recursive: true });
8454
8530
  } catch {
8455
8531
  }
8456
8532
  }
8457
8533
  dirFor(agentId) {
8458
- return (0, import_node_path11.join)(this.dir, sanitizeId(agentId));
8534
+ return (0, import_node_path12.join)(this.dir, sanitizeId(agentId));
8459
8535
  }
8460
8536
  pathFor(agentId, threadId) {
8461
- return (0, import_node_path11.join)(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
8537
+ return (0, import_node_path12.join)(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
8462
8538
  }
8463
8539
  read(agentId, threadId) {
8464
8540
  const p = this.pathFor(agentId, threadId);
8465
- if (!(0, import_node_fs9.existsSync)(p)) return null;
8541
+ if (!(0, import_node_fs10.existsSync)(p)) return null;
8466
8542
  try {
8467
- const raw = (0, import_node_fs9.readFileSync)(p, "utf-8");
8543
+ const raw = (0, import_node_fs10.readFileSync)(p, "utf-8");
8468
8544
  const parsed = parse(raw);
8469
8545
  return { ...parsed, raw };
8470
8546
  } catch {
@@ -8474,18 +8550,18 @@ var AgentMemoryStore = class {
8474
8550
  write(agentId, threadId, fields) {
8475
8551
  const agentDir = this.dirFor(agentId);
8476
8552
  try {
8477
- (0, import_node_fs9.mkdirSync)(agentDir, { recursive: true });
8553
+ (0, import_node_fs10.mkdirSync)(agentDir, { recursive: true });
8478
8554
  } catch {
8479
8555
  }
8480
8556
  const body = render({ ...fields, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
8481
8557
  const p = this.pathFor(agentId, threadId);
8482
8558
  const tmp = `${p}.tmp`;
8483
- (0, import_node_fs9.writeFileSync)(tmp, body, "utf-8");
8484
- (0, import_node_fs9.renameSync)(tmp, p);
8559
+ (0, import_node_fs10.writeFileSync)(tmp, body, "utf-8");
8560
+ (0, import_node_fs10.renameSync)(tmp, p);
8485
8561
  }
8486
8562
  delete(agentId, threadId) {
8487
8563
  try {
8488
- (0, import_node_fs9.rmSync)(this.pathFor(agentId, threadId), { force: true });
8564
+ (0, import_node_fs10.rmSync)(this.pathFor(agentId, threadId), { force: true });
8489
8565
  } catch {
8490
8566
  }
8491
8567
  }
@@ -8550,6 +8626,7 @@ function parse(raw) {
8550
8626
  CloudflareClient,
8551
8627
  DEFAULT_AGENT_NAME,
8552
8628
  DEFAULT_AGENT_ROLE,
8629
+ DEFAULT_SESSION_MAX_AGE_MS,
8553
8630
  DNSConfigurator,
8554
8631
  DependencyChecker,
8555
8632
  DependencyInstaller,
@@ -8586,9 +8663,13 @@ function parse(raw) {
8586
8663
  ensureDataDir,
8587
8664
  extractVerificationCode,
8588
8665
  flushTelemetry,
8666
+ forgetHostSession,
8589
8667
  getDatabase,
8668
+ hostSessionStoragePath,
8590
8669
  isInternalEmail,
8670
+ isSessionFresh,
8591
8671
  isValidPhoneNumber,
8672
+ loadHostSession,
8592
8673
  normalizeAddress,
8593
8674
  normalizePhoneNumber,
8594
8675
  normalizeSubject,
@@ -8601,6 +8682,7 @@ function parse(raw) {
8601
8682
  safeJoin,
8602
8683
  sanitizeEmail,
8603
8684
  saveConfig,
8685
+ saveHostSession,
8604
8686
  scanOutboundEmail,
8605
8687
  scoreEmail,
8606
8688
  setTelemetryVersion,