@agenticmail/core 0.9.5 → 0.9.7

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,12 +753,18 @@ __export(index_exports, {
752
753
  ensureDataDir: () => ensureDataDir,
753
754
  extractVerificationCode: () => extractVerificationCode,
754
755
  flushTelemetry: () => flushTelemetry,
756
+ forgetHostSession: () => forgetHostSession,
755
757
  getDatabase: () => getDatabase,
758
+ getOperatorEmail: () => getOperatorEmail,
759
+ hostSessionStoragePath: () => hostSessionStoragePath,
756
760
  isInternalEmail: () => isInternalEmail,
761
+ isSessionFresh: () => isSessionFresh,
757
762
  isValidPhoneNumber: () => isValidPhoneNumber,
763
+ loadHostSession: () => loadHostSession,
758
764
  normalizeAddress: () => normalizeAddress,
759
765
  normalizePhoneNumber: () => normalizePhoneNumber,
760
766
  normalizeSubject: () => normalizeSubject,
767
+ operatorPrefsStoragePath: () => operatorPrefsStoragePath,
761
768
  parseEmail: () => parseEmail,
762
769
  parseGoogleVoiceSms: () => parseGoogleVoiceSms,
763
770
  recordToolCall: () => recordToolCall,
@@ -767,8 +774,10 @@ __export(index_exports, {
767
774
  safeJoin: () => safeJoin,
768
775
  sanitizeEmail: () => sanitizeEmail,
769
776
  saveConfig: () => saveConfig,
777
+ saveHostSession: () => saveHostSession,
770
778
  scanOutboundEmail: () => scanOutboundEmail,
771
779
  scoreEmail: () => scoreEmail,
780
+ setOperatorEmail: () => setOperatorEmail,
772
781
  setTelemetryVersion: () => setTelemetryVersion,
773
782
  startRelayBridge: () => startRelayBridge,
774
783
  threadIdFor: () => threadIdFor,
@@ -1159,8 +1168,8 @@ var MailReceiver = class {
1159
1168
  }));
1160
1169
  }
1161
1170
  /** Create a new IMAP folder */
1162
- async createFolder(path) {
1163
- await this.client.mailboxCreate(path);
1171
+ async createFolder(path2) {
1172
+ await this.client.mailboxCreate(path2);
1164
1173
  }
1165
1174
  /** Batch mark multiple messages as seen */
1166
1175
  async batchMarkSeen(uids, mailbox = "INBOX") {
@@ -1700,8 +1709,8 @@ var StalwartAdmin = class {
1700
1709
  }
1701
1710
  baseUrl;
1702
1711
  authHeader;
1703
- async request(method, path, body) {
1704
- const url = `${this.baseUrl}/api${path}`;
1712
+ async request(method, path2, body) {
1713
+ const url = `${this.baseUrl}/api${path2}`;
1705
1714
  const response = await fetch(url, {
1706
1715
  method,
1707
1716
  headers: {
@@ -1862,14 +1871,14 @@ var StalwartAdmin = class {
1862
1871
  if (!isValidDomain(domain)) {
1863
1872
  throw new Error(`Invalid domain format: "${domain}"`);
1864
1873
  }
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");
1874
+ const { readFileSync: readFileSync9, writeFileSync: writeFileSync10 } = await import("fs");
1875
+ const { homedir: homedir13 } = await import("os");
1876
+ const { join: join15 } = await import("path");
1877
+ const configPath = join15(homedir13(), ".agenticmail", "stalwart.toml");
1869
1878
  try {
1870
- let config = readFileSync7(configPath, "utf-8");
1879
+ let config = readFileSync9(configPath, "utf-8");
1871
1880
  config = config.replace(/^hostname\s*=\s*"[^"]*"/m, `hostname = "${escapeTomlString(domain)}"`);
1872
- writeFileSync8(configPath, config);
1881
+ writeFileSync10(configPath, config);
1873
1882
  console.log(`[Stalwart] Updated hostname to "${domain}" in stalwart.toml`);
1874
1883
  } catch (err) {
1875
1884
  throw new Error(`Failed to set config server.hostname=${domain}`);
@@ -1878,15 +1887,15 @@ var StalwartAdmin = class {
1878
1887
  // --- DKIM ---
1879
1888
  /** Path to the host-side stalwart.toml (mounted read-only into container) */
1880
1889
  get configPath() {
1881
- const { homedir: homedir11 } = require("os");
1882
- const { join: join13 } = require("path");
1883
- return join13(homedir11(), ".agenticmail", "stalwart.toml");
1890
+ const { homedir: homedir13 } = require("os");
1891
+ const { join: join15 } = require("path");
1892
+ return join15(homedir13(), ".agenticmail", "stalwart.toml");
1884
1893
  }
1885
1894
  /** Path to host-side DKIM key directory */
1886
1895
  get dkimDir() {
1887
- const { homedir: homedir11 } = require("os");
1888
- const { join: join13 } = require("path");
1889
- return join13(homedir11(), ".agenticmail");
1896
+ const { homedir: homedir13 } = require("os");
1897
+ const { join: join15 } = require("path");
1898
+ return join15(homedir13(), ".agenticmail");
1890
1899
  }
1891
1900
  /**
1892
1901
  * Create/reuse a DKIM signing key for a domain.
@@ -1987,12 +1996,12 @@ var StalwartAdmin = class {
1987
1996
  * This bypasses the need for a PTR record on the sending IP.
1988
1997
  */
1989
1998
  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");
1999
+ const { readFileSync: readFileSync9, writeFileSync: writeFileSync10 } = await import("fs");
2000
+ const { homedir: homedir13 } = await import("os");
2001
+ const { join: join15 } = await import("path");
1993
2002
  const routeName = config.routeName ?? "gmail";
1994
- const tomlPath = join13(homedir11(), ".agenticmail", "stalwart.toml");
1995
- let toml = readFileSync7(tomlPath, "utf-8");
2003
+ const tomlPath = join15(homedir13(), ".agenticmail", "stalwart.toml");
2004
+ let toml = readFileSync9(tomlPath, "utf-8");
1996
2005
  toml = toml.replace(/\n\[queue\.route\.gmail\][\s\S]*?(?=\n\[|$)/, "");
1997
2006
  toml = toml.replace(/\n\[queue\.strategy\][\s\S]*?(?=\n\[|$)/, "");
1998
2007
  const safeRouteName = routeName.replace(/[^a-zA-Z0-9_-]/g, "");
@@ -2012,7 +2021,7 @@ auth.secret = "${escapeTomlString(config.password)}"
2012
2021
  route = [ { if = "is_local_domain('', rcpt_domain)", then = "'local'" },
2013
2022
  { else = "'${safeRouteName}'" } ]
2014
2023
  `;
2015
- writeFileSync8(tomlPath, toml, "utf-8");
2024
+ writeFileSync10(tomlPath, toml, "utf-8");
2016
2025
  await this.restartContainer();
2017
2026
  }
2018
2027
  };
@@ -2395,11 +2404,11 @@ var AgentDeletionService = class {
2395
2404
  };
2396
2405
  }
2397
2406
  saveToFile(report) {
2398
- const dir = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".agenticmail", "deletions");
2399
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
2407
+ const dir2 = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".agenticmail", "deletions");
2408
+ (0, import_node_fs2.mkdirSync)(dir2, { recursive: true });
2400
2409
  const timestamp = report.deletedAt.replace(/[:.]/g, "-");
2401
2410
  const filename = `${report.agent.name}_${timestamp}.json`;
2402
- const filePath = (0, import_node_path2.join)(dir, filename);
2411
+ const filePath = (0, import_node_path2.join)(dir2, filename);
2403
2412
  (0, import_node_fs2.writeFileSync)(filePath, JSON.stringify(report, null, 2), "utf-8");
2404
2413
  return filePath;
2405
2414
  }
@@ -4690,8 +4699,8 @@ var CloudflareClient = class {
4690
4699
  return resp.result;
4691
4700
  }
4692
4701
  // --- Internal ---
4693
- async request(method, path, body) {
4694
- const url = `${CF_API_BASE}${path}`;
4702
+ async request(method, path2, body) {
4703
+ const url = `${CF_API_BASE}${path2}`;
4695
4704
  const response = await fetch(url, {
4696
4705
  method,
4697
4706
  headers: {
@@ -5013,9 +5022,9 @@ var TunnelManager = class {
5013
5022
  throw new Error(`Failed to download cloudflared: ${response.statusText}`);
5014
5023
  }
5015
5024
  const buffer = Buffer.from(await response.arrayBuffer());
5016
- const { writeFile: writeFile2, rename: rename2 } = await import("fs/promises");
5025
+ const { writeFile: writeFile4, rename: rename2 } = await import("fs/promises");
5017
5026
  const tmpPath = this.binPath + ".tmp";
5018
- await writeFile2(tmpPath, buffer);
5027
+ await writeFile4(tmpPath, buffer);
5019
5028
  await (0, import_promises.chmod)(tmpPath, 493);
5020
5029
  await rename2(tmpPath, this.binPath);
5021
5030
  return this.binPath;
@@ -5308,6 +5317,33 @@ var SmsManager = class {
5308
5317
  meta.sms = config;
5309
5318
  this.db.prepare("UPDATE agents SET metadata = ?, updated_at = datetime('now') WHERE id = ?").run(JSON.stringify(meta), agentId);
5310
5319
  }
5320
+ /**
5321
+ * Resolve the operator's "where do I get pinged" address from an
5322
+ * agent's SMS config. Used by the dispatcher's bridge-escalation
5323
+ * path: when sub-agents mail a bridge with no fresh host session
5324
+ * available, we email the operator a digest at this address. Their
5325
+ * phone's Gmail push notification surfaces it within seconds —
5326
+ * effectively a free, programmatic alert channel.
5327
+ *
5328
+ * Returns the configured `forwardingEmail` (the same Gmail Google
5329
+ * Voice forwards inbound SMS to, which the operator already has
5330
+ * push notifications enabled for) when SMS is configured AND
5331
+ * enabled. Returns null otherwise — caller falls through to a
5332
+ * silent log + system event.
5333
+ *
5334
+ * Why we don't try real-SMS delivery yet: Google Voice's
5335
+ * `<number>@txt.voice.google.com` email-to-SMS gateway was
5336
+ * deprecated by Google years ago. A future `carrier` field on
5337
+ * SmsConfig (Verizon vtext.com / AT&T txt.att.net / etc) will let
5338
+ * the operator opt into actual SMS, but that's a follow-up — the
5339
+ * email path already gets the operator a phone notification.
5340
+ */
5341
+ getAlertEmail(agentId) {
5342
+ const cfg = this.getSmsConfig(agentId);
5343
+ if (!cfg || !cfg.enabled) return null;
5344
+ if (typeof cfg.forwardingEmail !== "string" || !cfg.forwardingEmail.includes("@")) return null;
5345
+ return cfg.forwardingEmail;
5346
+ }
5311
5347
  /** Remove SMS config from agent metadata */
5312
5348
  removeSmsConfig(agentId) {
5313
5349
  const row = this.db.prepare("SELECT metadata FROM agents WHERE id = ?").get(agentId);
@@ -5923,12 +5959,12 @@ var GatewayManager = class {
5923
5959
  zone = await this.cfClient.createZone(domain);
5924
5960
  }
5925
5961
  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");
5962
+ const { homedir: homedir13 } = await import("os");
5963
+ const backupDir = (0, import_node_path4.join)(homedir13(), ".agenticmail");
5928
5964
  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({
5965
+ const { writeFileSync: writeFileSync10, mkdirSync: mkdirSync11 } = await import("fs");
5966
+ mkdirSync11(backupDir, { recursive: true });
5967
+ writeFileSync10(backupPath, JSON.stringify({
5932
5968
  domain,
5933
5969
  zoneId: zone.id,
5934
5970
  backedUpAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -6689,8 +6725,8 @@ function isDisabled() {
6689
6725
  function getInstallId() {
6690
6726
  if (installId) return installId;
6691
6727
  try {
6692
- const dir = (0, import_path.join)((0, import_os.homedir)(), ".agenticmail");
6693
- const idFile = (0, import_path.join)(dir, ".telemetry-id");
6728
+ const dir2 = (0, import_path.join)((0, import_os.homedir)(), ".agenticmail");
6729
+ const idFile = (0, import_path.join)(dir2, ".telemetry-id");
6694
6730
  if ((0, import_fs.existsSync)(idFile)) {
6695
6731
  const id = (0, import_fs.readFileSync)(idFile, "utf8").trim();
6696
6732
  if (id && id.length > 10) {
@@ -6699,7 +6735,7 @@ function getInstallId() {
6699
6735
  }
6700
6736
  }
6701
6737
  installId = (0, import_crypto.randomUUID)();
6702
- if (!(0, import_fs.existsSync)(dir)) (0, import_fs.mkdirSync)(dir, { recursive: true });
6738
+ if (!(0, import_fs.existsSync)(dir2)) (0, import_fs.mkdirSync)(dir2, { recursive: true });
6703
6739
  (0, import_fs.writeFileSync)(idFile, installId, "utf8");
6704
6740
  return installId;
6705
6741
  } catch {
@@ -6870,6 +6906,131 @@ function redactObject(input, _depth = 0) {
6870
6906
  return out;
6871
6907
  }
6872
6908
 
6909
+ // src/operator-prefs.ts
6910
+ var import_node_fs4 = require("fs");
6911
+ var import_node_os4 = require("os");
6912
+ var import_node_path6 = require("path");
6913
+ function dir() {
6914
+ return (0, import_node_path6.join)((0, import_node_os4.homedir)(), ".agenticmail");
6915
+ }
6916
+ function path() {
6917
+ return (0, import_node_path6.join)(dir(), "operator-prefs.json");
6918
+ }
6919
+ function readFile() {
6920
+ if (!(0, import_node_fs4.existsSync)(path())) return { version: 1 };
6921
+ try {
6922
+ const raw = (0, import_node_fs4.readFileSync)(path(), "utf-8");
6923
+ if (!raw.trim()) return { version: 1 };
6924
+ const parsed = JSON.parse(raw);
6925
+ return { version: 1, operatorEmail: typeof parsed.operatorEmail === "string" ? parsed.operatorEmail : void 0 };
6926
+ } catch {
6927
+ return { version: 1 };
6928
+ }
6929
+ }
6930
+ function writeFile(shape) {
6931
+ const d = dir();
6932
+ const p = path();
6933
+ if (!(0, import_node_fs4.existsSync)(d)) (0, import_node_fs4.mkdirSync)(d, { recursive: true });
6934
+ const tmp = `${p}.agenticmail-tmp-${process.pid}`;
6935
+ (0, import_node_fs4.writeFileSync)(tmp, JSON.stringify(shape, null, 2), "utf-8");
6936
+ (0, import_node_fs4.renameSync)(tmp, p);
6937
+ }
6938
+ function getOperatorEmail() {
6939
+ const shape = readFile();
6940
+ const email = shape.operatorEmail;
6941
+ if (typeof email !== "string") return null;
6942
+ const trimmed = email.trim();
6943
+ return trimmed.length > 0 && trimmed.includes("@") ? trimmed : null;
6944
+ }
6945
+ function setOperatorEmail(email) {
6946
+ const shape = readFile();
6947
+ if (!email || !email.trim()) {
6948
+ delete shape.operatorEmail;
6949
+ writeFile(shape);
6950
+ return null;
6951
+ }
6952
+ const trimmed = email.trim();
6953
+ if (!trimmed.includes("@")) {
6954
+ throw new Error("operator email must contain an @");
6955
+ }
6956
+ shape.operatorEmail = trimmed;
6957
+ writeFile(shape);
6958
+ return trimmed;
6959
+ }
6960
+ function operatorPrefsStoragePath() {
6961
+ return path();
6962
+ }
6963
+
6964
+ // src/host-sessions.ts
6965
+ var import_node_fs5 = require("fs");
6966
+ var import_node_path7 = require("path");
6967
+ var import_node_os5 = require("os");
6968
+ function storageDir() {
6969
+ return (0, import_node_path7.join)((0, import_node_os5.homedir)(), ".agenticmail");
6970
+ }
6971
+ function storagePath() {
6972
+ return (0, import_node_path7.join)(storageDir(), "host-sessions.json");
6973
+ }
6974
+ var DEFAULT_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
6975
+ function readFile2() {
6976
+ const p = storagePath();
6977
+ if (!(0, import_node_fs5.existsSync)(p)) return { version: 1, sessions: {} };
6978
+ try {
6979
+ const raw = (0, import_node_fs5.readFileSync)(p, "utf-8");
6980
+ if (!raw.trim()) return { version: 1, sessions: {} };
6981
+ const parsed = JSON.parse(raw);
6982
+ return {
6983
+ version: 1,
6984
+ sessions: parsed.sessions && typeof parsed.sessions === "object" ? parsed.sessions : {}
6985
+ };
6986
+ } catch {
6987
+ return { version: 1, sessions: {} };
6988
+ }
6989
+ }
6990
+ function writeFile2(shape) {
6991
+ const dir2 = storageDir();
6992
+ const p = storagePath();
6993
+ if (!(0, import_node_fs5.existsSync)(dir2)) (0, import_node_fs5.mkdirSync)(dir2, { recursive: true });
6994
+ const tmp = `${p}.agenticmail-tmp-${process.pid}`;
6995
+ (0, import_node_fs5.writeFileSync)(tmp, JSON.stringify(shape, null, 2), "utf-8");
6996
+ (0, import_node_fs5.renameSync)(tmp, p);
6997
+ }
6998
+ function saveHostSession(host, session) {
6999
+ if (!session.sessionId) return;
7000
+ try {
7001
+ const shape = readFile2();
7002
+ shape.sessions[host] = {
7003
+ ...session,
7004
+ lastSeenMs: Date.now()
7005
+ };
7006
+ writeFile2(shape);
7007
+ } catch {
7008
+ }
7009
+ }
7010
+ function loadHostSession(host, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
7011
+ const shape = readFile2();
7012
+ const record = shape.sessions[host];
7013
+ if (!record) return null;
7014
+ if (!isSessionFresh(record, maxAgeMs)) return null;
7015
+ return record;
7016
+ }
7017
+ function isSessionFresh(session, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
7018
+ if (!session || !Number.isFinite(session.lastSeenMs)) return false;
7019
+ return Date.now() - session.lastSeenMs <= maxAgeMs;
7020
+ }
7021
+ function forgetHostSession(host) {
7022
+ try {
7023
+ const shape = readFile2();
7024
+ if (!shape.sessions[host]) return;
7025
+ delete shape.sessions[host];
7026
+ writeFile2(shape);
7027
+ } catch {
7028
+ }
7029
+ }
7030
+ function hostSessionStoragePath() {
7031
+ return storagePath();
7032
+ }
7033
+
6873
7034
  // src/util/safe-url.ts
6874
7035
  var UnsafeApiUrlError = class extends Error {
6875
7036
  constructor(raw, reason) {
@@ -6912,21 +7073,21 @@ function validateApiUrl(raw) {
6912
7073
  return parsed.origin;
6913
7074
  }
6914
7075
  function buildApiUrl(baseOrigin, pathAndQuery) {
6915
- const path = pathAndQuery.startsWith("/") ? pathAndQuery : `/${pathAndQuery}`;
6916
- return new URL(path, baseOrigin + "/").toString();
7076
+ const path2 = pathAndQuery.startsWith("/") ? pathAndQuery : `/${pathAndQuery}`;
7077
+ return new URL(path2, baseOrigin + "/").toString();
6917
7078
  }
6918
7079
 
6919
7080
  // src/setup/index.ts
6920
7081
  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");
7082
+ var import_node_fs9 = require("fs");
7083
+ var import_node_path11 = require("path");
7084
+ var import_node_os9 = require("os");
6924
7085
 
6925
7086
  // src/setup/deps.ts
6926
7087
  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");
7088
+ var import_node_fs6 = require("fs");
7089
+ var import_node_path8 = require("path");
7090
+ var import_node_os6 = require("os");
6930
7091
  var DependencyChecker = class {
6931
7092
  async checkAll() {
6932
7093
  return Promise.all([
@@ -6976,8 +7137,8 @@ var DependencyChecker = class {
6976
7137
  }
6977
7138
  }
6978
7139
  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)) {
7140
+ const binPath = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "bin", "cloudflared");
7141
+ if ((0, import_node_fs6.existsSync)(binPath)) {
6981
7142
  let version;
6982
7143
  try {
6983
7144
  const output = (0, import_node_child_process2.execFileSync)(binPath, ["--version"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
@@ -6999,10 +7160,10 @@ var DependencyChecker = class {
6999
7160
 
7000
7161
  // src/setup/installer.ts
7001
7162
  var import_node_child_process3 = require("child_process");
7002
- var import_node_fs5 = require("fs");
7163
+ var import_node_fs7 = require("fs");
7003
7164
  var import_promises2 = require("fs/promises");
7004
- var import_node_path7 = require("path");
7005
- var import_node_os5 = require("os");
7165
+ var import_node_path9 = require("path");
7166
+ var import_node_os7 = require("os");
7006
7167
  function runShellWithRollingOutput(cmd, opts = {}) {
7007
7168
  const maxLines = opts.maxLines ?? 20;
7008
7169
  const timeout = opts.timeout ?? 3e5;
@@ -7112,7 +7273,7 @@ var DependencyInstaller = class {
7112
7273
  */
7113
7274
  async installDocker() {
7114
7275
  if (this.isDockerReady()) return;
7115
- const os = (0, import_node_os5.platform)();
7276
+ const os = (0, import_node_os7.platform)();
7116
7277
  if (os === "darwin") {
7117
7278
  await this.installDockerMac();
7118
7279
  } else if (os === "linux") {
@@ -7178,15 +7339,15 @@ var DependencyInstaller = class {
7178
7339
  try {
7179
7340
  const composeBin = (0, import_node_child_process3.execFileSync)("which", ["docker-compose"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
7180
7341
  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;
7342
+ const pluginDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".docker", "cli-plugins");
7343
+ const pluginPath = (0, import_node_path9.join)(pluginDir, "docker-compose");
7344
+ if ((0, import_node_fs7.existsSync)(pluginPath)) return;
7184
7345
  try {
7185
- (0, import_node_fs5.mkdirSync)(pluginDir, { recursive: true });
7346
+ (0, import_node_fs7.mkdirSync)(pluginDir, { recursive: true });
7186
7347
  } catch {
7187
7348
  }
7188
7349
  try {
7189
- (0, import_node_fs5.symlinkSync)(composeBin, pluginPath);
7350
+ (0, import_node_fs7.symlinkSync)(composeBin, pluginPath);
7190
7351
  } catch {
7191
7352
  }
7192
7353
  } catch {
@@ -7245,9 +7406,9 @@ var DependencyInstaller = class {
7245
7406
  return;
7246
7407
  }
7247
7408
  this.onProgress("__progress__:5:Installing Docker Engine...");
7248
- const tmpDir = (0, import_node_path7.join)((0, import_node_os5.homedir)(), ".agenticmail", "tmp");
7409
+ const tmpDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "tmp");
7249
7410
  await (0, import_promises2.mkdir)(tmpDir, { recursive: true });
7250
- const scriptPath = (0, import_node_path7.join)(tmpDir, "install-docker.sh");
7411
+ const scriptPath = (0, import_node_path9.join)(tmpDir, "install-docker.sh");
7251
7412
  const dlResult = await runShellWithRollingOutput(
7252
7413
  `curl -fsSL https://get.docker.com -o "${scriptPath}" && sudo sh "${scriptPath}"`,
7253
7414
  { timeout: 3e5 }
@@ -7315,8 +7476,8 @@ var DependencyInstaller = class {
7315
7476
  }
7316
7477
  try {
7317
7478
  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)) {
7479
+ const dockerExe = (0, import_node_path9.join)(programFiles, "Docker", "Docker", "Docker Desktop.exe");
7480
+ if ((0, import_node_fs7.existsSync)(dockerExe)) {
7320
7481
  (0, import_node_child_process3.execSync)(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
7321
7482
  }
7322
7483
  } catch {
@@ -7366,8 +7527,8 @@ var DependencyInstaller = class {
7366
7527
  this.onProgress("__progress__:70:Docker Desktop installed. Starting...");
7367
7528
  try {
7368
7529
  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)) {
7530
+ const dockerExe = (0, import_node_path9.join)(programFiles, "Docker", "Docker", "Docker Desktop.exe");
7531
+ if ((0, import_node_fs7.existsSync)(dockerExe)) {
7371
7532
  (0, import_node_child_process3.execSync)(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
7372
7533
  }
7373
7534
  } catch {
@@ -7404,12 +7565,12 @@ var DependencyInstaller = class {
7404
7565
  * Start the Stalwart mail server Docker container.
7405
7566
  */
7406
7567
  async startStalwart(composePath) {
7407
- if (!(0, import_node_fs5.existsSync)(composePath)) {
7568
+ if (!(0, import_node_fs7.existsSync)(composePath)) {
7408
7569
  throw new Error(`docker-compose.yml not found at: ${composePath}`);
7409
7570
  }
7410
7571
  if (!this.isDockerReady()) {
7411
7572
  this.onProgress("Starting Docker...");
7412
- const os = (0, import_node_os5.platform)();
7573
+ const os = (0, import_node_os7.platform)();
7413
7574
  if (os === "darwin") {
7414
7575
  await this.startColima();
7415
7576
  } else if (os === "win32") {
@@ -7427,7 +7588,7 @@ var DependencyInstaller = class {
7427
7588
  }
7428
7589
  }
7429
7590
  this.onProgress("__progress__:10:Pulling mail server image...");
7430
- if ((0, import_node_os5.platform)() === "darwin") this.linkComposePlugin();
7591
+ if ((0, import_node_os7.platform)() === "darwin") this.linkComposePlugin();
7431
7592
  let composeResult = await runSilent("docker", ["compose", "-f", composePath, "up", "-d"], { timeout: 12e4 });
7432
7593
  if (composeResult.exitCode !== 0 && hasCommand("docker-compose")) {
7433
7594
  composeResult = await runSilent("docker-compose", ["-f", composePath, "up", "-d"], { timeout: 12e4 });
@@ -7462,22 +7623,22 @@ var DependencyInstaller = class {
7462
7623
  * Returns the path to the installed binary.
7463
7624
  */
7464
7625
  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");
7626
+ const os = (0, import_node_os7.platform)();
7627
+ const binDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "bin");
7467
7628
  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)) {
7629
+ const binPath = (0, import_node_path9.join)(binDir, binName);
7630
+ if ((0, import_node_fs7.existsSync)(binPath)) {
7470
7631
  return binPath;
7471
7632
  }
7472
7633
  try {
7473
7634
  const whichCmd = os === "win32" ? "where" : "which";
7474
7635
  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;
7636
+ if (sysPath && (0, import_node_fs7.existsSync)(sysPath)) return sysPath;
7476
7637
  } catch {
7477
7638
  }
7478
7639
  this.onProgress("Downloading cloudflared...");
7479
7640
  await (0, import_promises2.mkdir)(binDir, { recursive: true });
7480
- const cpu = (0, import_node_os5.arch)();
7641
+ const cpu = (0, import_node_os7.arch)();
7481
7642
  const archName = cpu === "arm64" ? "arm64" : "amd64";
7482
7643
  let downloadUrl;
7483
7644
  if (os === "darwin") {
@@ -7495,7 +7656,7 @@ var DependencyInstaller = class {
7495
7656
  }
7496
7657
  const buffer = Buffer.from(await response.arrayBuffer());
7497
7658
  if (os === "darwin") {
7498
- const tgzPath = (0, import_node_path7.join)(binDir, "cloudflared.tgz");
7659
+ const tgzPath = (0, import_node_path9.join)(binDir, "cloudflared.tgz");
7499
7660
  await (0, import_promises2.writeFile)(tgzPath, buffer);
7500
7661
  try {
7501
7662
  (0, import_node_child_process3.execFileSync)("tar", ["-xzf", tgzPath, "-C", binDir, "cloudflared"], { timeout: 15e3, stdio: "ignore" });
@@ -7512,7 +7673,7 @@ var DependencyInstaller = class {
7512
7673
  if (os !== "win32") await (0, import_promises2.chmod)(tmpPath, 493);
7513
7674
  await (0, import_promises2.rename)(tmpPath, binPath);
7514
7675
  }
7515
- if (!(0, import_node_fs5.existsSync)(binPath)) {
7676
+ if (!(0, import_node_fs7.existsSync)(binPath)) {
7516
7677
  throw new Error("cloudflared download succeeded but binary not found after extraction");
7517
7678
  }
7518
7679
  this.onProgress("cloudflared installed");
@@ -7530,23 +7691,23 @@ var DependencyInstaller = class {
7530
7691
 
7531
7692
  // src/setup/service.ts
7532
7693
  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");
7694
+ var import_node_fs8 = require("fs");
7695
+ var import_node_path10 = require("path");
7696
+ var import_node_os8 = require("os");
7536
7697
  var import_node_module2 = require("module");
7537
7698
  var import_meta2 = {};
7538
7699
  var PLIST_LABEL = "com.agenticmail.server";
7539
7700
  var SYSTEMD_UNIT = "agenticmail.service";
7540
7701
  var ServiceManager = class {
7541
- os = (0, import_node_os6.platform)();
7702
+ os = (0, import_node_os8.platform)();
7542
7703
  /**
7543
7704
  * Get the path to the service file.
7544
7705
  */
7545
7706
  getServicePath() {
7546
7707
  if (this.os === "darwin") {
7547
- return (0, import_node_path8.join)((0, import_node_os6.homedir)(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
7708
+ return (0, import_node_path10.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
7548
7709
  } else {
7549
- return (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".config", "systemd", "user", SYSTEMD_UNIT);
7710
+ return (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".config", "systemd", "user", SYSTEMD_UNIT);
7550
7711
  }
7551
7712
  }
7552
7713
  /**
@@ -7580,40 +7741,40 @@ var ServiceManager = class {
7580
7741
  try {
7581
7742
  const req = (0, import_node_module2.createRequire)(import_meta2.url);
7582
7743
  const resolved = req.resolve("@agenticmail/api");
7583
- if ((0, import_node_fs6.existsSync)(resolved)) return resolved;
7744
+ if ((0, import_node_fs8.existsSync)(resolved)) return resolved;
7584
7745
  } catch {
7585
7746
  }
7586
7747
  const parentPackages = [
7587
- (0, import_node_path8.join)("@agenticmail", "cli"),
7748
+ (0, import_node_path10.join)("@agenticmail", "cli"),
7588
7749
  // current scoped package
7589
7750
  "agenticmail"
7590
7751
  // legacy unscoped package
7591
7752
  ];
7592
7753
  const baseDirs = [
7593
7754
  // user-local install
7594
- (0, import_node_path8.join)((0, import_node_os6.homedir)(), "node_modules")
7755
+ (0, import_node_path10.join)((0, import_node_os8.homedir)(), "node_modules")
7595
7756
  ];
7596
7757
  try {
7597
7758
  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"));
7759
+ baseDirs.push((0, import_node_path10.join)(prefix, "lib", "node_modules"));
7760
+ baseDirs.push((0, import_node_path10.join)(prefix, "node_modules"));
7600
7761
  } catch {
7601
7762
  }
7602
7763
  baseDirs.push("/opt/homebrew/lib/node_modules");
7603
7764
  baseDirs.push("/usr/local/lib/node_modules");
7604
7765
  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;
7766
+ const sibling = (0, import_node_path10.join)(base, "@agenticmail", "api", "dist", "index.js");
7767
+ if ((0, import_node_fs8.existsSync)(sibling)) return sibling;
7607
7768
  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;
7769
+ const nested = (0, import_node_path10.join)(base, parent, "node_modules", "@agenticmail", "api", "dist", "index.js");
7770
+ if ((0, import_node_fs8.existsSync)(nested)) return nested;
7610
7771
  }
7611
7772
  }
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;
7773
+ const dataDir = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail");
7774
+ const entryCache = (0, import_node_path10.join)(dataDir, "api-entry.path");
7775
+ if ((0, import_node_fs8.existsSync)(entryCache)) {
7776
+ const cached = (0, import_node_fs8.readFileSync)(entryCache, "utf-8").trim();
7777
+ if (cached && (0, import_node_fs8.existsSync)(cached)) return cached;
7617
7778
  }
7618
7779
  throw new Error("Could not find @agenticmail/api entry point. Run `agenticmail start` first to populate the cache.");
7619
7780
  }
@@ -7621,9 +7782,9 @@ var ServiceManager = class {
7621
7782
  * Cache the API entry path so the service can find it later.
7622
7783
  */
7623
7784
  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);
7785
+ const dataDir = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail");
7786
+ if (!(0, import_node_fs8.existsSync)(dataDir)) (0, import_node_fs8.mkdirSync)(dataDir, { recursive: true });
7787
+ (0, import_node_fs8.writeFileSync)((0, import_node_path10.join)(dataDir, "api-entry.path"), entryPath);
7627
7788
  }
7628
7789
  /**
7629
7790
  * Get the current package version.
@@ -7636,36 +7797,36 @@ var ServiceManager = class {
7636
7797
  try {
7637
7798
  const req = (0, import_node_module2.createRequire)(import_meta2.url);
7638
7799
  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"));
7800
+ if ((0, import_node_fs8.existsSync)(pkgJson)) {
7801
+ const pkg = JSON.parse((0, import_node_fs8.readFileSync)(pkgJson, "utf-8"));
7641
7802
  if (pkg.version) return pkg.version;
7642
7803
  }
7643
7804
  } catch {
7644
7805
  }
7645
7806
  try {
7646
7807
  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"));
7808
+ const apiPkg = (0, import_node_path10.join)(apiEntry, "..", "..", "package.json");
7809
+ if ((0, import_node_fs8.existsSync)(apiPkg)) {
7810
+ const pkg = JSON.parse((0, import_node_fs8.readFileSync)(apiPkg, "utf-8"));
7650
7811
  if (pkg.version) return pkg.version;
7651
7812
  }
7652
7813
  } catch {
7653
7814
  }
7654
7815
  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")
7816
+ (0, import_node_path10.join)((0, import_node_os8.homedir)(), "node_modules", "@agenticmail", "cli", "package.json"),
7817
+ (0, import_node_path10.join)((0, import_node_os8.homedir)(), "node_modules", "agenticmail", "package.json"),
7818
+ (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "package-version.json")
7658
7819
  ];
7659
7820
  try {
7660
7821
  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"));
7822
+ candidates.push((0, import_node_path10.join)(prefix, "lib", "node_modules", "@agenticmail", "cli", "package.json"));
7823
+ candidates.push((0, import_node_path10.join)(prefix, "lib", "node_modules", "agenticmail", "package.json"));
7663
7824
  } catch {
7664
7825
  }
7665
7826
  for (const p of candidates) {
7666
7827
  try {
7667
- if ((0, import_node_fs6.existsSync)(p)) {
7668
- const pkg = JSON.parse((0, import_node_fs6.readFileSync)(p, "utf-8"));
7828
+ if ((0, import_node_fs8.existsSync)(p)) {
7829
+ const pkg = JSON.parse((0, import_node_fs8.readFileSync)(p, "utf-8"));
7669
7830
  if (pkg.version) return pkg.version;
7670
7831
  }
7671
7832
  } catch {
@@ -7678,9 +7839,9 @@ var ServiceManager = class {
7678
7839
  * This ensures AgenticMail doesn't fail on boot when Docker is still loading.
7679
7840
  */
7680
7841
  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 });
7842
+ const scriptPath = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "bin", "start-server.sh");
7843
+ const scriptDir = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "bin");
7844
+ if (!(0, import_node_fs8.existsSync)(scriptDir)) (0, import_node_fs8.mkdirSync)(scriptDir, { recursive: true });
7684
7845
  const script = [
7685
7846
  "#!/bin/bash",
7686
7847
  "# AgenticMail auto-start script",
@@ -7731,7 +7892,7 @@ var ServiceManager = class {
7731
7892
  `log "Starting API server: ${nodePath} ${apiEntry}"`,
7732
7893
  `exec "${nodePath}" "${apiEntry}"`
7733
7894
  ].join("\n") + "\n";
7734
- (0, import_node_fs6.writeFileSync)(scriptPath, script, { mode: 493 });
7895
+ (0, import_node_fs8.writeFileSync)(scriptPath, script, { mode: 493 });
7735
7896
  return scriptPath;
7736
7897
  }
7737
7898
  /**
@@ -7744,9 +7905,9 @@ var ServiceManager = class {
7744
7905
  * - Service version tracking in env vars
7745
7906
  */
7746
7907
  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 });
7908
+ const config = JSON.parse((0, import_node_fs8.readFileSync)(configPath, "utf-8"));
7909
+ const logDir = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "logs");
7910
+ if (!(0, import_node_fs8.existsSync)(logDir)) (0, import_node_fs8.mkdirSync)(logDir, { recursive: true });
7750
7911
  const version = this.getVersion();
7751
7912
  const startScript = this.generateStartScript(nodePath, apiEntry);
7752
7913
  return `<?xml version="1.0" encoding="UTF-8"?>
@@ -7767,9 +7928,9 @@ var ServiceManager = class {
7767
7928
  <key>EnvironmentVariables</key>
7768
7929
  <dict>
7769
7930
  <key>HOME</key>
7770
- <string>${(0, import_node_os6.homedir)()}</string>
7931
+ <string>${(0, import_node_os8.homedir)()}</string>
7771
7932
  <key>AGENTICMAIL_DATA_DIR</key>
7772
- <string>${config.dataDir || (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail")}</string>
7933
+ <string>${config.dataDir || (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail")}</string>
7773
7934
  <key>PATH</key>
7774
7935
  <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
7775
7936
  <key>AGENTICMAIL_SERVICE_VERSION</key>
@@ -7822,8 +7983,8 @@ var ServiceManager = class {
7822
7983
  * - Proper dependency ordering
7823
7984
  */
7824
7985
  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");
7986
+ const config = JSON.parse((0, import_node_fs8.readFileSync)(configPath, "utf-8"));
7987
+ const dataDir = config.dataDir || (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail");
7827
7988
  const version = this.getVersion();
7828
7989
  const startScript = this.generateStartScript(nodePath, apiEntry);
7829
7990
  return `[Unit]
@@ -7840,7 +8001,7 @@ Restart=always
7840
8001
  RestartSec=15
7841
8002
  TimeoutStartSec=660
7842
8003
  LimitNOFILE=8192
7843
- Environment=HOME=${(0, import_node_os6.homedir)()}
8004
+ Environment=HOME=${(0, import_node_os8.homedir)()}
7844
8005
  Environment=AGENTICMAIL_DATA_DIR=${dataDir}
7845
8006
  Environment=PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin
7846
8007
  Environment=AGENTICMAIL_SERVICE_VERSION=${version}
@@ -7853,8 +8014,8 @@ WantedBy=default.target
7853
8014
  * Install the auto-start service.
7854
8015
  */
7855
8016
  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)) {
8017
+ const configPath = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "config.json");
8018
+ if (!(0, import_node_fs8.existsSync)(configPath)) {
7858
8019
  return { installed: false, message: "Config not found. Run agenticmail setup first." };
7859
8020
  }
7860
8021
  const nodePath = this.getNodePath();
@@ -7866,17 +8027,17 @@ WantedBy=default.target
7866
8027
  }
7867
8028
  const servicePath = this.getServicePath();
7868
8029
  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)) {
8030
+ const dir2 = (0, import_node_path10.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents");
8031
+ if (!(0, import_node_fs8.existsSync)(dir2)) (0, import_node_fs8.mkdirSync)(dir2, { recursive: true });
8032
+ if ((0, import_node_fs8.existsSync)(servicePath)) {
7872
8033
  try {
7873
8034
  (0, import_node_child_process4.execFileSync)("launchctl", ["unload", servicePath], { timeout: 1e4, stdio: "ignore" });
7874
8035
  } catch {
7875
8036
  }
7876
8037
  }
7877
8038
  const plist = this.generatePlist(nodePath, apiEntry, configPath);
7878
- (0, import_node_fs6.writeFileSync)(servicePath, plist);
7879
- (0, import_node_fs6.chmodSync)(servicePath, 384);
8039
+ (0, import_node_fs8.writeFileSync)(servicePath, plist);
8040
+ (0, import_node_fs8.chmodSync)(servicePath, 384);
7880
8041
  try {
7881
8042
  (0, import_node_child_process4.execFileSync)("launchctl", ["load", servicePath], { timeout: 1e4, stdio: "ignore" });
7882
8043
  } catch (err) {
@@ -7884,11 +8045,11 @@ WantedBy=default.target
7884
8045
  }
7885
8046
  return { installed: true, message: `Service installed at ${servicePath}` };
7886
8047
  } 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 });
8048
+ const dir2 = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".config", "systemd", "user");
8049
+ if (!(0, import_node_fs8.existsSync)(dir2)) (0, import_node_fs8.mkdirSync)(dir2, { recursive: true });
7889
8050
  const unit = this.generateSystemdUnit(nodePath, apiEntry, configPath);
7890
- (0, import_node_fs6.writeFileSync)(servicePath, unit);
7891
- (0, import_node_fs6.chmodSync)(servicePath, 384);
8051
+ (0, import_node_fs8.writeFileSync)(servicePath, unit);
8052
+ (0, import_node_fs8.chmodSync)(servicePath, 384);
7892
8053
  try {
7893
8054
  (0, import_node_child_process4.execFileSync)("systemctl", ["--user", "daemon-reload"], { timeout: 1e4, stdio: "ignore" });
7894
8055
  (0, import_node_child_process4.execFileSync)("systemctl", ["--user", "enable", SYSTEMD_UNIT], { timeout: 1e4, stdio: "ignore" });
@@ -7910,7 +8071,7 @@ WantedBy=default.target
7910
8071
  */
7911
8072
  uninstall() {
7912
8073
  const servicePath = this.getServicePath();
7913
- if (!(0, import_node_fs6.existsSync)(servicePath)) {
8074
+ if (!(0, import_node_fs8.existsSync)(servicePath)) {
7914
8075
  return { removed: false, message: "Service is not installed." };
7915
8076
  }
7916
8077
  if (this.os === "darwin") {
@@ -7919,7 +8080,7 @@ WantedBy=default.target
7919
8080
  } catch {
7920
8081
  }
7921
8082
  try {
7922
- (0, import_node_fs6.unlinkSync)(servicePath);
8083
+ (0, import_node_fs8.unlinkSync)(servicePath);
7923
8084
  } catch {
7924
8085
  }
7925
8086
  return { removed: true, message: "Service removed." };
@@ -7930,7 +8091,7 @@ WantedBy=default.target
7930
8091
  } catch {
7931
8092
  }
7932
8093
  try {
7933
- (0, import_node_fs6.unlinkSync)(servicePath);
8094
+ (0, import_node_fs8.unlinkSync)(servicePath);
7934
8095
  } catch {
7935
8096
  }
7936
8097
  try {
@@ -7948,7 +8109,7 @@ WantedBy=default.target
7948
8109
  status() {
7949
8110
  const servicePath = this.getServicePath();
7950
8111
  const plat = this.os === "darwin" ? "launchd" : this.os === "linux" ? "systemd" : "unsupported";
7951
- const installed = (0, import_node_fs6.existsSync)(servicePath);
8112
+ const installed = (0, import_node_fs8.existsSync)(servicePath);
7952
8113
  let running = false;
7953
8114
  if (installed) {
7954
8115
  if (this.os === "darwin") {
@@ -8003,34 +8164,34 @@ WantedBy=default.target
8003
8164
  needsRepair() {
8004
8165
  if (this.os !== "darwin" && this.os !== "linux") return null;
8005
8166
  const servicePath = this.getServicePath();
8006
- if (!(0, import_node_fs6.existsSync)(servicePath)) return null;
8167
+ if (!(0, import_node_fs8.existsSync)(servicePath)) return null;
8007
8168
  let serviceContent = "";
8008
8169
  try {
8009
- serviceContent = (0, import_node_fs6.readFileSync)(servicePath, "utf-8");
8170
+ serviceContent = (0, import_node_fs8.readFileSync)(servicePath, "utf-8");
8010
8171
  } catch {
8011
8172
  return { reason: "Service file unreadable" };
8012
8173
  }
8013
- const startScript = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "bin", "start-server.sh");
8174
+ const startScript = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "bin", "start-server.sh");
8014
8175
  if (serviceContent.includes(startScript)) {
8015
- if (!(0, import_node_fs6.existsSync)(startScript)) {
8176
+ if (!(0, import_node_fs8.existsSync)(startScript)) {
8016
8177
  return { reason: "start-server.sh is missing" };
8017
8178
  }
8018
8179
  let scriptContent = "";
8019
8180
  try {
8020
- scriptContent = (0, import_node_fs6.readFileSync)(startScript, "utf-8");
8181
+ scriptContent = (0, import_node_fs8.readFileSync)(startScript, "utf-8");
8021
8182
  } catch {
8022
8183
  return { reason: "start-server.sh unreadable" };
8023
8184
  }
8024
8185
  const apiPathMatch = scriptContent.match(/(\/[^"\s]+@agenticmail\/api\/dist\/index\.js)/);
8025
8186
  if (apiPathMatch) {
8026
8187
  const referenced = apiPathMatch[1];
8027
- if (!(0, import_node_fs6.existsSync)(referenced)) {
8188
+ if (!(0, import_node_fs8.existsSync)(referenced)) {
8028
8189
  return { reason: `start-server.sh references missing path: ${referenced}` };
8029
8190
  }
8030
8191
  }
8031
8192
  if (/node_modules\/agenticmail\/(?!.*@agenticmail\/cli)/.test(scriptContent)) {
8032
8193
  const stale = /(\S*node_modules\/agenticmail\/\S*)/.exec(scriptContent)?.[1];
8033
- if (stale && !(0, import_node_fs6.existsSync)(stale)) {
8194
+ if (stale && !(0, import_node_fs8.existsSync)(stale)) {
8034
8195
  return { reason: `start-server.sh references legacy unscoped path: ${stale}` };
8035
8196
  }
8036
8197
  }
@@ -8043,11 +8204,11 @@ WantedBy=default.target
8043
8204
  return { reason: `Service version drift (current CLI is v${currentVersion})` };
8044
8205
  }
8045
8206
  }
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)) {
8207
+ const entryCache = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "api-entry.path");
8208
+ if ((0, import_node_fs8.existsSync)(entryCache)) {
8048
8209
  try {
8049
- const cached = (0, import_node_fs6.readFileSync)(entryCache, "utf-8").trim();
8050
- if (cached && !(0, import_node_fs6.existsSync)(cached)) {
8210
+ const cached = (0, import_node_fs8.readFileSync)(entryCache, "utf-8").trim();
8211
+ if (cached && !(0, import_node_fs8.existsSync)(cached)) {
8051
8212
  return { reason: `Cached API entry path no longer exists: ${cached}` };
8052
8213
  }
8053
8214
  } catch {
@@ -8086,8 +8247,8 @@ var SetupManager = class {
8086
8247
  async ensureStalwart(composePath) {
8087
8248
  const status = await this.checker.checkStalwart();
8088
8249
  if (status.installed) return;
8089
- const path = composePath ?? this.getComposePath();
8090
- await this.installer.startStalwart(path);
8250
+ const path2 = composePath ?? this.getComposePath();
8251
+ await this.installer.startStalwart(path2);
8091
8252
  }
8092
8253
  async ensureCloudflared() {
8093
8254
  return this.installer.installCloudflared();
@@ -8098,13 +8259,13 @@ var SetupManager = class {
8098
8259
  * falls back to monorepo location.
8099
8260
  */
8100
8261
  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;
8262
+ const standalonePath = (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".agenticmail", "docker-compose.yml");
8263
+ if ((0, import_node_fs9.existsSync)(standalonePath)) return standalonePath;
8103
8264
  const cwd = process.cwd();
8104
- const candidates = [cwd, (0, import_node_path9.join)(cwd, "..")];
8105
- 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;
8265
+ const candidates = [cwd, (0, import_node_path11.join)(cwd, "..")];
8266
+ for (const dir2 of candidates) {
8267
+ const p = (0, import_node_path11.join)(dir2, "docker-compose.yml");
8268
+ if ((0, import_node_fs9.existsSync)(p)) return p;
8108
8269
  }
8109
8270
  return standalonePath;
8110
8271
  }
@@ -8114,19 +8275,19 @@ var SetupManager = class {
8114
8275
  * Always regenerates Docker files to keep passwords in sync.
8115
8276
  */
8116
8277
  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)) {
8278
+ const dataDir = (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".agenticmail");
8279
+ const configPath = (0, import_node_path11.join)(dataDir, "config.json");
8280
+ const envPath = (0, import_node_path11.join)(dataDir, ".env");
8281
+ if ((0, import_node_fs9.existsSync)(configPath)) {
8121
8282
  try {
8122
- const existing = JSON.parse((0, import_node_fs7.readFileSync)(configPath, "utf-8"));
8283
+ const existing = JSON.parse((0, import_node_fs9.readFileSync)(configPath, "utf-8"));
8123
8284
  this.generateDockerFiles(existing);
8124
8285
  return { configPath, envPath, config: existing, isNew: false };
8125
8286
  } catch {
8126
8287
  }
8127
8288
  }
8128
- if (!(0, import_node_fs7.existsSync)(dataDir)) {
8129
- (0, import_node_fs7.mkdirSync)(dataDir, { recursive: true });
8289
+ if (!(0, import_node_fs9.existsSync)(dataDir)) {
8290
+ (0, import_node_fs9.mkdirSync)(dataDir, { recursive: true });
8130
8291
  }
8131
8292
  const masterKey = `mk_${(0, import_node_crypto3.randomBytes)(24).toString("hex")}`;
8132
8293
  const stalwartPassword = (0, import_node_crypto3.randomBytes)(16).toString("hex");
@@ -8142,8 +8303,8 @@ var SetupManager = class {
8142
8303
  api: { port: 3829, host: "127.0.0.1" },
8143
8304
  dataDir
8144
8305
  };
8145
- (0, import_node_fs7.writeFileSync)(configPath, JSON.stringify(config, null, 2));
8146
- (0, import_node_fs7.chmodSync)(configPath, 384);
8306
+ (0, import_node_fs9.writeFileSync)(configPath, JSON.stringify(config, null, 2));
8307
+ (0, import_node_fs9.chmodSync)(configPath, 384);
8147
8308
  const envContent = `# Auto-generated by agenticmail setup
8148
8309
  STALWART_ADMIN_USER=admin
8149
8310
  STALWART_ADMIN_PASSWORD=${stalwartPassword}
@@ -8158,8 +8319,8 @@ SMTP_PORT=587
8158
8319
  IMAP_HOST=localhost
8159
8320
  IMAP_PORT=143
8160
8321
  `;
8161
- (0, import_node_fs7.writeFileSync)(envPath, envContent);
8162
- (0, import_node_fs7.chmodSync)(envPath, 384);
8322
+ (0, import_node_fs9.writeFileSync)(envPath, envContent);
8323
+ (0, import_node_fs9.chmodSync)(envPath, 384);
8163
8324
  this.generateDockerFiles(config);
8164
8325
  return { configPath, envPath, config, isNew: true };
8165
8326
  }
@@ -8168,13 +8329,13 @@ IMAP_PORT=143
8168
8329
  * with the correct admin password from config.
8169
8330
  */
8170
8331
  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 });
8332
+ const dataDir = config.dataDir || (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".agenticmail");
8333
+ if (!(0, import_node_fs9.existsSync)(dataDir)) {
8334
+ (0, import_node_fs9.mkdirSync)(dataDir, { recursive: true });
8174
8335
  }
8175
8336
  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:
8337
+ const composePath = (0, import_node_path11.join)(dataDir, "docker-compose.yml");
8338
+ (0, import_node_fs9.writeFileSync)(composePath, `services:
8178
8339
  stalwart:
8179
8340
  # Pinned to v0.15.5 \u2014 Stalwart 0.16+ moved its config to JSON
8180
8341
  # at /etc/stalwart/config.json (hardcoded into the container
@@ -8203,9 +8364,9 @@ IMAP_PORT=143
8203
8364
  volumes:
8204
8365
  stalwart-data:
8205
8366
  `);
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
8367
+ (0, import_node_fs9.chmodSync)(composePath, 384);
8368
+ const tomlPath = (0, import_node_path11.join)(dataDir, "stalwart.toml");
8369
+ (0, import_node_fs9.writeFileSync)(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
8209
8370
 
8210
8371
  [server]
8211
8372
  hostname = "localhost"
@@ -8255,14 +8416,14 @@ enable = true
8255
8416
  user = "admin"
8256
8417
  secret = "${password}"
8257
8418
  `);
8258
- (0, import_node_fs7.chmodSync)(tomlPath, 384);
8419
+ (0, import_node_fs9.chmodSync)(tomlPath, 384);
8259
8420
  }
8260
8421
  /**
8261
8422
  * Check if config has already been initialized.
8262
8423
  */
8263
8424
  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);
8425
+ const configPath = (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".agenticmail", "config.json");
8426
+ return (0, import_node_fs9.existsSync)(configPath);
8266
8427
  }
8267
8428
  };
8268
8429
 
@@ -8300,10 +8461,10 @@ function threadIdFor(input) {
8300
8461
  }
8301
8462
 
8302
8463
  // 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");
8464
+ var import_node_fs10 = require("fs");
8465
+ var import_node_os10 = require("os");
8466
+ var import_node_path12 = require("path");
8467
+ var CACHE_DIR_DEFAULT = (0, import_node_path12.join)((0, import_node_os10.homedir)(), ".agenticmail", "thread-cache");
8307
8468
  var DEFAULT_K_MESSAGES = 10;
8308
8469
  var DEFAULT_LRU_CAP = 5e3;
8309
8470
  var PREVIEW_MAX_CHARS = 240;
@@ -8316,22 +8477,22 @@ var ThreadCache = class {
8316
8477
  this.k = opts.k ?? DEFAULT_K_MESSAGES;
8317
8478
  this.lruCap = opts.lruCap ?? DEFAULT_LRU_CAP;
8318
8479
  try {
8319
- (0, import_node_fs8.mkdirSync)(this.dir, { recursive: true });
8480
+ (0, import_node_fs10.mkdirSync)(this.dir, { recursive: true });
8320
8481
  } catch {
8321
8482
  }
8322
8483
  }
8323
8484
  pathFor(threadId) {
8324
- return (0, import_node_path10.join)(this.dir, `${threadId}.json`);
8485
+ return (0, import_node_path12.join)(this.dir, `${threadId}.json`);
8325
8486
  }
8326
8487
  read(threadId) {
8327
8488
  const p = this.pathFor(threadId);
8328
- if (!(0, import_node_fs8.existsSync)(p)) return null;
8489
+ if (!(0, import_node_fs10.existsSync)(p)) return null;
8329
8490
  try {
8330
- const raw = (0, import_node_fs8.readFileSync)(p, "utf-8");
8491
+ const raw = (0, import_node_fs10.readFileSync)(p, "utf-8");
8331
8492
  return JSON.parse(raw);
8332
8493
  } catch {
8333
8494
  try {
8334
- (0, import_node_fs8.rmSync)(p, { force: true });
8495
+ (0, import_node_fs10.rmSync)(p, { force: true });
8335
8496
  } catch {
8336
8497
  }
8337
8498
  return null;
@@ -8372,7 +8533,7 @@ var ThreadCache = class {
8372
8533
  /** Permanently remove a thread's cache (called on [FINAL] / [DONE] / [CLOSED] / [WRAP]). */
8373
8534
  delete(threadId) {
8374
8535
  try {
8375
- (0, import_node_fs8.rmSync)(this.pathFor(threadId), { force: true });
8536
+ (0, import_node_fs10.rmSync)(this.pathFor(threadId), { force: true });
8376
8537
  } catch {
8377
8538
  }
8378
8539
  }
@@ -8392,8 +8553,8 @@ var ThreadCache = class {
8392
8553
  writeAtomic(threadId, entry) {
8393
8554
  const p = this.pathFor(threadId);
8394
8555
  const tmp = `${p}.tmp`;
8395
- (0, import_node_fs8.writeFileSync)(tmp, JSON.stringify(entry), "utf-8");
8396
- (0, import_node_fs8.renameSync)(tmp, p);
8556
+ (0, import_node_fs10.writeFileSync)(tmp, JSON.stringify(entry), "utf-8");
8557
+ (0, import_node_fs10.renameSync)(tmp, p);
8397
8558
  }
8398
8559
  /**
8399
8560
  * Best-effort LRU eviction. Runs at most every 256 writes (we
@@ -8405,15 +8566,15 @@ var ThreadCache = class {
8405
8566
  if (Math.random() > 1 / 256) return;
8406
8567
  let files;
8407
8568
  try {
8408
- files = (0, import_node_fs8.readdirSync)(this.dir).filter((f) => f.endsWith(".json"));
8569
+ files = (0, import_node_fs10.readdirSync)(this.dir).filter((f) => f.endsWith(".json"));
8409
8570
  } catch {
8410
8571
  return;
8411
8572
  }
8412
8573
  if (files.length <= this.lruCap) return;
8413
8574
  const stats = files.map((f) => {
8414
- const p = (0, import_node_path10.join)(this.dir, f);
8575
+ const p = (0, import_node_path12.join)(this.dir, f);
8415
8576
  try {
8416
- return { p, mtime: (0, import_node_fs8.statSync)(p).mtimeMs };
8577
+ return { p, mtime: (0, import_node_fs10.statSync)(p).mtimeMs };
8417
8578
  } catch {
8418
8579
  return { p, mtime: 0 };
8419
8580
  }
@@ -8422,7 +8583,7 @@ var ThreadCache = class {
8422
8583
  const dropCount = Math.max(1, Math.floor(this.lruCap * 0.1));
8423
8584
  for (let i = 0; i < dropCount; i++) {
8424
8585
  try {
8425
- (0, import_node_fs8.rmSync)(stats[i].p, { force: true });
8586
+ (0, import_node_fs10.rmSync)(stats[i].p, { force: true });
8426
8587
  } catch {
8427
8588
  }
8428
8589
  }
@@ -8441,30 +8602,30 @@ function dedupAndCap(messages, k) {
8441
8602
  }
8442
8603
 
8443
8604
  // 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");
8605
+ var import_node_fs11 = require("fs");
8606
+ var import_node_os11 = require("os");
8607
+ var import_node_path13 = require("path");
8608
+ var MEMORY_DIR_DEFAULT = (0, import_node_path13.join)((0, import_node_os11.homedir)(), ".agenticmail", "agent-memory");
8448
8609
  var AgentMemoryStore = class {
8449
8610
  dir;
8450
8611
  constructor(opts = {}) {
8451
8612
  this.dir = opts.memoryDir ?? MEMORY_DIR_DEFAULT;
8452
8613
  try {
8453
- (0, import_node_fs9.mkdirSync)(this.dir, { recursive: true });
8614
+ (0, import_node_fs11.mkdirSync)(this.dir, { recursive: true });
8454
8615
  } catch {
8455
8616
  }
8456
8617
  }
8457
8618
  dirFor(agentId) {
8458
- return (0, import_node_path11.join)(this.dir, sanitizeId(agentId));
8619
+ return (0, import_node_path13.join)(this.dir, sanitizeId(agentId));
8459
8620
  }
8460
8621
  pathFor(agentId, threadId) {
8461
- return (0, import_node_path11.join)(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
8622
+ return (0, import_node_path13.join)(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
8462
8623
  }
8463
8624
  read(agentId, threadId) {
8464
8625
  const p = this.pathFor(agentId, threadId);
8465
- if (!(0, import_node_fs9.existsSync)(p)) return null;
8626
+ if (!(0, import_node_fs11.existsSync)(p)) return null;
8466
8627
  try {
8467
- const raw = (0, import_node_fs9.readFileSync)(p, "utf-8");
8628
+ const raw = (0, import_node_fs11.readFileSync)(p, "utf-8");
8468
8629
  const parsed = parse(raw);
8469
8630
  return { ...parsed, raw };
8470
8631
  } catch {
@@ -8474,18 +8635,18 @@ var AgentMemoryStore = class {
8474
8635
  write(agentId, threadId, fields) {
8475
8636
  const agentDir = this.dirFor(agentId);
8476
8637
  try {
8477
- (0, import_node_fs9.mkdirSync)(agentDir, { recursive: true });
8638
+ (0, import_node_fs11.mkdirSync)(agentDir, { recursive: true });
8478
8639
  } catch {
8479
8640
  }
8480
8641
  const body = render({ ...fields, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
8481
8642
  const p = this.pathFor(agentId, threadId);
8482
8643
  const tmp = `${p}.tmp`;
8483
- (0, import_node_fs9.writeFileSync)(tmp, body, "utf-8");
8484
- (0, import_node_fs9.renameSync)(tmp, p);
8644
+ (0, import_node_fs11.writeFileSync)(tmp, body, "utf-8");
8645
+ (0, import_node_fs11.renameSync)(tmp, p);
8485
8646
  }
8486
8647
  delete(agentId, threadId) {
8487
8648
  try {
8488
- (0, import_node_fs9.rmSync)(this.pathFor(agentId, threadId), { force: true });
8649
+ (0, import_node_fs11.rmSync)(this.pathFor(agentId, threadId), { force: true });
8489
8650
  } catch {
8490
8651
  }
8491
8652
  }
@@ -8550,6 +8711,7 @@ function parse(raw) {
8550
8711
  CloudflareClient,
8551
8712
  DEFAULT_AGENT_NAME,
8552
8713
  DEFAULT_AGENT_ROLE,
8714
+ DEFAULT_SESSION_MAX_AGE_MS,
8553
8715
  DNSConfigurator,
8554
8716
  DependencyChecker,
8555
8717
  DependencyInstaller,
@@ -8586,12 +8748,18 @@ function parse(raw) {
8586
8748
  ensureDataDir,
8587
8749
  extractVerificationCode,
8588
8750
  flushTelemetry,
8751
+ forgetHostSession,
8589
8752
  getDatabase,
8753
+ getOperatorEmail,
8754
+ hostSessionStoragePath,
8590
8755
  isInternalEmail,
8756
+ isSessionFresh,
8591
8757
  isValidPhoneNumber,
8758
+ loadHostSession,
8592
8759
  normalizeAddress,
8593
8760
  normalizePhoneNumber,
8594
8761
  normalizeSubject,
8762
+ operatorPrefsStoragePath,
8595
8763
  parseEmail,
8596
8764
  parseGoogleVoiceSms,
8597
8765
  recordToolCall,
@@ -8601,8 +8769,10 @@ function parse(raw) {
8601
8769
  safeJoin,
8602
8770
  sanitizeEmail,
8603
8771
  saveConfig,
8772
+ saveHostSession,
8604
8773
  scanOutboundEmail,
8605
8774
  scoreEmail,
8775
+ setOperatorEmail,
8606
8776
  setTelemetryVersion,
8607
8777
  startRelayBridge,
8608
8778
  threadIdFor,