@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.js CHANGED
@@ -390,8 +390,8 @@ var MailReceiver = class {
390
390
  }));
391
391
  }
392
392
  /** Create a new IMAP folder */
393
- async createFolder(path) {
394
- await this.client.mailboxCreate(path);
393
+ async createFolder(path2) {
394
+ await this.client.mailboxCreate(path2);
395
395
  }
396
396
  /** Batch mark multiple messages as seen */
397
397
  async batchMarkSeen(uids, mailbox = "INBOX") {
@@ -931,8 +931,8 @@ var StalwartAdmin = class {
931
931
  }
932
932
  baseUrl;
933
933
  authHeader;
934
- async request(method, path, body) {
935
- const url = `${this.baseUrl}/api${path}`;
934
+ async request(method, path2, body) {
935
+ const url = `${this.baseUrl}/api${path2}`;
936
936
  const response = await fetch(url, {
937
937
  method,
938
938
  headers: {
@@ -1093,14 +1093,14 @@ var StalwartAdmin = class {
1093
1093
  if (!isValidDomain(domain)) {
1094
1094
  throw new Error(`Invalid domain format: "${domain}"`);
1095
1095
  }
1096
- const { readFileSync: readFileSync7, writeFileSync: writeFileSync8 } = await import("fs");
1097
- const { homedir: homedir11 } = await import("os");
1098
- const { join: join13 } = await import("path");
1099
- const configPath = join13(homedir11(), ".agenticmail", "stalwart.toml");
1096
+ const { readFileSync: readFileSync9, writeFileSync: writeFileSync10 } = await import("fs");
1097
+ const { homedir: homedir13 } = await import("os");
1098
+ const { join: join15 } = await import("path");
1099
+ const configPath = join15(homedir13(), ".agenticmail", "stalwart.toml");
1100
1100
  try {
1101
- let config = readFileSync7(configPath, "utf-8");
1101
+ let config = readFileSync9(configPath, "utf-8");
1102
1102
  config = config.replace(/^hostname\s*=\s*"[^"]*"/m, `hostname = "${escapeTomlString(domain)}"`);
1103
- writeFileSync8(configPath, config);
1103
+ writeFileSync10(configPath, config);
1104
1104
  console.log(`[Stalwart] Updated hostname to "${domain}" in stalwart.toml`);
1105
1105
  } catch (err) {
1106
1106
  throw new Error(`Failed to set config server.hostname=${domain}`);
@@ -1109,15 +1109,15 @@ var StalwartAdmin = class {
1109
1109
  // --- DKIM ---
1110
1110
  /** Path to the host-side stalwart.toml (mounted read-only into container) */
1111
1111
  get configPath() {
1112
- const { homedir: homedir11 } = __require("os");
1113
- const { join: join13 } = __require("path");
1114
- return join13(homedir11(), ".agenticmail", "stalwart.toml");
1112
+ const { homedir: homedir13 } = __require("os");
1113
+ const { join: join15 } = __require("path");
1114
+ return join15(homedir13(), ".agenticmail", "stalwart.toml");
1115
1115
  }
1116
1116
  /** Path to host-side DKIM key directory */
1117
1117
  get dkimDir() {
1118
- const { homedir: homedir11 } = __require("os");
1119
- const { join: join13 } = __require("path");
1120
- return join13(homedir11(), ".agenticmail");
1118
+ const { homedir: homedir13 } = __require("os");
1119
+ const { join: join15 } = __require("path");
1120
+ return join15(homedir13(), ".agenticmail");
1121
1121
  }
1122
1122
  /**
1123
1123
  * Create/reuse a DKIM signing key for a domain.
@@ -1218,12 +1218,12 @@ var StalwartAdmin = class {
1218
1218
  * This bypasses the need for a PTR record on the sending IP.
1219
1219
  */
1220
1220
  async configureOutboundRelay(config) {
1221
- const { readFileSync: readFileSync7, writeFileSync: writeFileSync8 } = await import("fs");
1222
- const { homedir: homedir11 } = await import("os");
1223
- const { join: join13 } = await import("path");
1221
+ const { readFileSync: readFileSync9, writeFileSync: writeFileSync10 } = await import("fs");
1222
+ const { homedir: homedir13 } = await import("os");
1223
+ const { join: join15 } = await import("path");
1224
1224
  const routeName = config.routeName ?? "gmail";
1225
- const tomlPath = join13(homedir11(), ".agenticmail", "stalwart.toml");
1226
- let toml = readFileSync7(tomlPath, "utf-8");
1225
+ const tomlPath = join15(homedir13(), ".agenticmail", "stalwart.toml");
1226
+ let toml = readFileSync9(tomlPath, "utf-8");
1227
1227
  toml = toml.replace(/\n\[queue\.route\.gmail\][\s\S]*?(?=\n\[|$)/, "");
1228
1228
  toml = toml.replace(/\n\[queue\.strategy\][\s\S]*?(?=\n\[|$)/, "");
1229
1229
  const safeRouteName = routeName.replace(/[^a-zA-Z0-9_-]/g, "");
@@ -1243,7 +1243,7 @@ auth.secret = "${escapeTomlString(config.password)}"
1243
1243
  route = [ { if = "is_local_domain('', rcpt_domain)", then = "'local'" },
1244
1244
  { else = "'${safeRouteName}'" } ]
1245
1245
  `;
1246
- writeFileSync8(tomlPath, toml, "utf-8");
1246
+ writeFileSync10(tomlPath, toml, "utf-8");
1247
1247
  await this.restartContainer();
1248
1248
  }
1249
1249
  };
@@ -1626,11 +1626,11 @@ var AgentDeletionService = class {
1626
1626
  };
1627
1627
  }
1628
1628
  saveToFile(report) {
1629
- const dir = join2(homedir2(), ".agenticmail", "deletions");
1630
- mkdirSync2(dir, { recursive: true });
1629
+ const dir2 = join2(homedir2(), ".agenticmail", "deletions");
1630
+ mkdirSync2(dir2, { recursive: true });
1631
1631
  const timestamp = report.deletedAt.replace(/[:.]/g, "-");
1632
1632
  const filename = `${report.agent.name}_${timestamp}.json`;
1633
- const filePath = join2(dir, filename);
1633
+ const filePath = join2(dir2, filename);
1634
1634
  writeFileSync2(filePath, JSON.stringify(report, null, 2), "utf-8");
1635
1635
  return filePath;
1636
1636
  }
@@ -3917,8 +3917,8 @@ var CloudflareClient = class {
3917
3917
  return resp.result;
3918
3918
  }
3919
3919
  // --- Internal ---
3920
- async request(method, path, body) {
3921
- const url = `${CF_API_BASE}${path}`;
3920
+ async request(method, path2, body) {
3921
+ const url = `${CF_API_BASE}${path2}`;
3922
3922
  const response = await fetch(url, {
3923
3923
  method,
3924
3924
  headers: {
@@ -4240,9 +4240,9 @@ var TunnelManager = class {
4240
4240
  throw new Error(`Failed to download cloudflared: ${response.statusText}`);
4241
4241
  }
4242
4242
  const buffer = Buffer.from(await response.arrayBuffer());
4243
- const { writeFile: writeFile2, rename: rename2 } = await import("fs/promises");
4243
+ const { writeFile: writeFile4, rename: rename2 } = await import("fs/promises");
4244
4244
  const tmpPath = this.binPath + ".tmp";
4245
- await writeFile2(tmpPath, buffer);
4245
+ await writeFile4(tmpPath, buffer);
4246
4246
  await chmod(tmpPath, 493);
4247
4247
  await rename2(tmpPath, this.binPath);
4248
4248
  return this.binPath;
@@ -4534,6 +4534,33 @@ var SmsManager = class {
4534
4534
  meta.sms = config;
4535
4535
  this.db.prepare("UPDATE agents SET metadata = ?, updated_at = datetime('now') WHERE id = ?").run(JSON.stringify(meta), agentId);
4536
4536
  }
4537
+ /**
4538
+ * Resolve the operator's "where do I get pinged" address from an
4539
+ * agent's SMS config. Used by the dispatcher's bridge-escalation
4540
+ * path: when sub-agents mail a bridge with no fresh host session
4541
+ * available, we email the operator a digest at this address. Their
4542
+ * phone's Gmail push notification surfaces it within seconds —
4543
+ * effectively a free, programmatic alert channel.
4544
+ *
4545
+ * Returns the configured `forwardingEmail` (the same Gmail Google
4546
+ * Voice forwards inbound SMS to, which the operator already has
4547
+ * push notifications enabled for) when SMS is configured AND
4548
+ * enabled. Returns null otherwise — caller falls through to a
4549
+ * silent log + system event.
4550
+ *
4551
+ * Why we don't try real-SMS delivery yet: Google Voice's
4552
+ * `<number>@txt.voice.google.com` email-to-SMS gateway was
4553
+ * deprecated by Google years ago. A future `carrier` field on
4554
+ * SmsConfig (Verizon vtext.com / AT&T txt.att.net / etc) will let
4555
+ * the operator opt into actual SMS, but that's a follow-up — the
4556
+ * email path already gets the operator a phone notification.
4557
+ */
4558
+ getAlertEmail(agentId) {
4559
+ const cfg = this.getSmsConfig(agentId);
4560
+ if (!cfg || !cfg.enabled) return null;
4561
+ if (typeof cfg.forwardingEmail !== "string" || !cfg.forwardingEmail.includes("@")) return null;
4562
+ return cfg.forwardingEmail;
4563
+ }
4537
4564
  /** Remove SMS config from agent metadata */
4538
4565
  removeSmsConfig(agentId) {
4539
4566
  const row = this.db.prepare("SELECT metadata FROM agents WHERE id = ?").get(agentId);
@@ -5149,12 +5176,12 @@ var GatewayManager = class {
5149
5176
  zone = await this.cfClient.createZone(domain);
5150
5177
  }
5151
5178
  const existingRecords = await this.cfClient.listDnsRecords(zone.id);
5152
- const { homedir: homedir11 } = await import("os");
5153
- const backupDir = join4(homedir11(), ".agenticmail");
5179
+ const { homedir: homedir13 } = await import("os");
5180
+ const backupDir = join4(homedir13(), ".agenticmail");
5154
5181
  const backupPath = join4(backupDir, `dns-backup-${domain}-${Date.now()}.json`);
5155
- const { writeFileSync: writeFileSync8, mkdirSync: mkdirSync9 } = await import("fs");
5156
- mkdirSync9(backupDir, { recursive: true });
5157
- writeFileSync8(backupPath, JSON.stringify({
5182
+ const { writeFileSync: writeFileSync10, mkdirSync: mkdirSync11 } = await import("fs");
5183
+ mkdirSync11(backupDir, { recursive: true });
5184
+ writeFileSync10(backupPath, JSON.stringify({
5158
5185
  domain,
5159
5186
  zoneId: zone.id,
5160
5187
  backedUpAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -5915,8 +5942,8 @@ function isDisabled() {
5915
5942
  function getInstallId() {
5916
5943
  if (installId) return installId;
5917
5944
  try {
5918
- const dir = join5(homedir4(), ".agenticmail");
5919
- const idFile = join5(dir, ".telemetry-id");
5945
+ const dir2 = join5(homedir4(), ".agenticmail");
5946
+ const idFile = join5(dir2, ".telemetry-id");
5920
5947
  if (existsSync3(idFile)) {
5921
5948
  const id = readFileSync2(idFile, "utf8").trim();
5922
5949
  if (id && id.length > 10) {
@@ -5925,7 +5952,7 @@ function getInstallId() {
5925
5952
  }
5926
5953
  }
5927
5954
  installId = randomUUID();
5928
- if (!existsSync3(dir)) mkdirSync3(dir, { recursive: true });
5955
+ if (!existsSync3(dir2)) mkdirSync3(dir2, { recursive: true });
5929
5956
  writeFileSync3(idFile, installId, "utf8");
5930
5957
  return installId;
5931
5958
  } catch {
@@ -6096,6 +6123,131 @@ function redactObject(input, _depth = 0) {
6096
6123
  return out;
6097
6124
  }
6098
6125
 
6126
+ // src/operator-prefs.ts
6127
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync4 } from "fs";
6128
+ import { homedir as homedir5 } from "os";
6129
+ import { join as join7 } from "path";
6130
+ function dir() {
6131
+ return join7(homedir5(), ".agenticmail");
6132
+ }
6133
+ function path() {
6134
+ return join7(dir(), "operator-prefs.json");
6135
+ }
6136
+ function readFile() {
6137
+ if (!existsSync4(path())) return { version: 1 };
6138
+ try {
6139
+ const raw = readFileSync3(path(), "utf-8");
6140
+ if (!raw.trim()) return { version: 1 };
6141
+ const parsed = JSON.parse(raw);
6142
+ return { version: 1, operatorEmail: typeof parsed.operatorEmail === "string" ? parsed.operatorEmail : void 0 };
6143
+ } catch {
6144
+ return { version: 1 };
6145
+ }
6146
+ }
6147
+ function writeFile(shape) {
6148
+ const d = dir();
6149
+ const p = path();
6150
+ if (!existsSync4(d)) mkdirSync4(d, { recursive: true });
6151
+ const tmp = `${p}.agenticmail-tmp-${process.pid}`;
6152
+ writeFileSync4(tmp, JSON.stringify(shape, null, 2), "utf-8");
6153
+ renameSync(tmp, p);
6154
+ }
6155
+ function getOperatorEmail() {
6156
+ const shape = readFile();
6157
+ const email = shape.operatorEmail;
6158
+ if (typeof email !== "string") return null;
6159
+ const trimmed = email.trim();
6160
+ return trimmed.length > 0 && trimmed.includes("@") ? trimmed : null;
6161
+ }
6162
+ function setOperatorEmail(email) {
6163
+ const shape = readFile();
6164
+ if (!email || !email.trim()) {
6165
+ delete shape.operatorEmail;
6166
+ writeFile(shape);
6167
+ return null;
6168
+ }
6169
+ const trimmed = email.trim();
6170
+ if (!trimmed.includes("@")) {
6171
+ throw new Error("operator email must contain an @");
6172
+ }
6173
+ shape.operatorEmail = trimmed;
6174
+ writeFile(shape);
6175
+ return trimmed;
6176
+ }
6177
+ function operatorPrefsStoragePath() {
6178
+ return path();
6179
+ }
6180
+
6181
+ // src/host-sessions.ts
6182
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync5 } from "fs";
6183
+ import { join as join8 } from "path";
6184
+ import { homedir as homedir6 } from "os";
6185
+ function storageDir() {
6186
+ return join8(homedir6(), ".agenticmail");
6187
+ }
6188
+ function storagePath() {
6189
+ return join8(storageDir(), "host-sessions.json");
6190
+ }
6191
+ var DEFAULT_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
6192
+ function readFile2() {
6193
+ const p = storagePath();
6194
+ if (!existsSync5(p)) return { version: 1, sessions: {} };
6195
+ try {
6196
+ const raw = readFileSync4(p, "utf-8");
6197
+ if (!raw.trim()) return { version: 1, sessions: {} };
6198
+ const parsed = JSON.parse(raw);
6199
+ return {
6200
+ version: 1,
6201
+ sessions: parsed.sessions && typeof parsed.sessions === "object" ? parsed.sessions : {}
6202
+ };
6203
+ } catch {
6204
+ return { version: 1, sessions: {} };
6205
+ }
6206
+ }
6207
+ function writeFile2(shape) {
6208
+ const dir2 = storageDir();
6209
+ const p = storagePath();
6210
+ if (!existsSync5(dir2)) mkdirSync5(dir2, { recursive: true });
6211
+ const tmp = `${p}.agenticmail-tmp-${process.pid}`;
6212
+ writeFileSync5(tmp, JSON.stringify(shape, null, 2), "utf-8");
6213
+ renameSync2(tmp, p);
6214
+ }
6215
+ function saveHostSession(host, session) {
6216
+ if (!session.sessionId) return;
6217
+ try {
6218
+ const shape = readFile2();
6219
+ shape.sessions[host] = {
6220
+ ...session,
6221
+ lastSeenMs: Date.now()
6222
+ };
6223
+ writeFile2(shape);
6224
+ } catch {
6225
+ }
6226
+ }
6227
+ function loadHostSession(host, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
6228
+ const shape = readFile2();
6229
+ const record = shape.sessions[host];
6230
+ if (!record) return null;
6231
+ if (!isSessionFresh(record, maxAgeMs)) return null;
6232
+ return record;
6233
+ }
6234
+ function isSessionFresh(session, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
6235
+ if (!session || !Number.isFinite(session.lastSeenMs)) return false;
6236
+ return Date.now() - session.lastSeenMs <= maxAgeMs;
6237
+ }
6238
+ function forgetHostSession(host) {
6239
+ try {
6240
+ const shape = readFile2();
6241
+ if (!shape.sessions[host]) return;
6242
+ delete shape.sessions[host];
6243
+ writeFile2(shape);
6244
+ } catch {
6245
+ }
6246
+ }
6247
+ function hostSessionStoragePath() {
6248
+ return storagePath();
6249
+ }
6250
+
6099
6251
  // src/util/safe-url.ts
6100
6252
  var UnsafeApiUrlError = class extends Error {
6101
6253
  constructor(raw, reason) {
@@ -6138,21 +6290,21 @@ function validateApiUrl(raw) {
6138
6290
  return parsed.origin;
6139
6291
  }
6140
6292
  function buildApiUrl(baseOrigin, pathAndQuery) {
6141
- const path = pathAndQuery.startsWith("/") ? pathAndQuery : `/${pathAndQuery}`;
6142
- return new URL(path, baseOrigin + "/").toString();
6293
+ const path2 = pathAndQuery.startsWith("/") ? pathAndQuery : `/${pathAndQuery}`;
6294
+ return new URL(path2, baseOrigin + "/").toString();
6143
6295
  }
6144
6296
 
6145
6297
  // src/setup/index.ts
6146
6298
  import { randomBytes as randomBytes3 } from "crypto";
6147
- import { existsSync as existsSync7, readFileSync as readFileSync4, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, chmodSync as chmodSync2 } from "fs";
6148
- import { join as join10 } from "path";
6149
- import { homedir as homedir8 } from "os";
6299
+ import { existsSync as existsSync9, readFileSync as readFileSync6, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, chmodSync as chmodSync2 } from "fs";
6300
+ import { join as join12 } from "path";
6301
+ import { homedir as homedir10 } from "os";
6150
6302
 
6151
6303
  // src/setup/deps.ts
6152
6304
  import { execFileSync } from "child_process";
6153
- import { existsSync as existsSync4 } from "fs";
6154
- import { join as join7 } from "path";
6155
- import { homedir as homedir5 } from "os";
6305
+ import { existsSync as existsSync6 } from "fs";
6306
+ import { join as join9 } from "path";
6307
+ import { homedir as homedir7 } from "os";
6156
6308
  var DependencyChecker = class {
6157
6309
  async checkAll() {
6158
6310
  return Promise.all([
@@ -6202,8 +6354,8 @@ var DependencyChecker = class {
6202
6354
  }
6203
6355
  }
6204
6356
  async checkCloudflared() {
6205
- const binPath = join7(homedir5(), ".agenticmail", "bin", "cloudflared");
6206
- if (existsSync4(binPath)) {
6357
+ const binPath = join9(homedir7(), ".agenticmail", "bin", "cloudflared");
6358
+ if (existsSync6(binPath)) {
6207
6359
  let version;
6208
6360
  try {
6209
6361
  const output = execFileSync(binPath, ["--version"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
@@ -6225,10 +6377,10 @@ var DependencyChecker = class {
6225
6377
 
6226
6378
  // src/setup/installer.ts
6227
6379
  import { execFileSync as execFileSync2, execSync, spawn as spawnChild } from "child_process";
6228
- import { existsSync as existsSync5, mkdirSync as mkdirSync4, symlinkSync } from "fs";
6229
- import { writeFile, rename, chmod as chmod2, mkdir as mkdir2, unlink } from "fs/promises";
6230
- import { join as join8 } from "path";
6231
- import { homedir as homedir6, platform as platform3, arch as arch2 } from "os";
6380
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6, symlinkSync } from "fs";
6381
+ import { writeFile as writeFile3, rename, chmod as chmod2, mkdir as mkdir2, unlink } from "fs/promises";
6382
+ import { join as join10 } from "path";
6383
+ import { homedir as homedir8, platform as platform3, arch as arch2 } from "os";
6232
6384
  function runShellWithRollingOutput(cmd, opts = {}) {
6233
6385
  const maxLines = opts.maxLines ?? 20;
6234
6386
  const timeout = opts.timeout ?? 3e5;
@@ -6404,11 +6556,11 @@ var DependencyInstaller = class {
6404
6556
  try {
6405
6557
  const composeBin = execFileSync2("which", ["docker-compose"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
6406
6558
  if (!composeBin) return;
6407
- const pluginDir = join8(homedir6(), ".docker", "cli-plugins");
6408
- const pluginPath = join8(pluginDir, "docker-compose");
6409
- if (existsSync5(pluginPath)) return;
6559
+ const pluginDir = join10(homedir8(), ".docker", "cli-plugins");
6560
+ const pluginPath = join10(pluginDir, "docker-compose");
6561
+ if (existsSync7(pluginPath)) return;
6410
6562
  try {
6411
- mkdirSync4(pluginDir, { recursive: true });
6563
+ mkdirSync6(pluginDir, { recursive: true });
6412
6564
  } catch {
6413
6565
  }
6414
6566
  try {
@@ -6471,9 +6623,9 @@ var DependencyInstaller = class {
6471
6623
  return;
6472
6624
  }
6473
6625
  this.onProgress("__progress__:5:Installing Docker Engine...");
6474
- const tmpDir = join8(homedir6(), ".agenticmail", "tmp");
6626
+ const tmpDir = join10(homedir8(), ".agenticmail", "tmp");
6475
6627
  await mkdir2(tmpDir, { recursive: true });
6476
- const scriptPath = join8(tmpDir, "install-docker.sh");
6628
+ const scriptPath = join10(tmpDir, "install-docker.sh");
6477
6629
  const dlResult = await runShellWithRollingOutput(
6478
6630
  `curl -fsSL https://get.docker.com -o "${scriptPath}" && sudo sh "${scriptPath}"`,
6479
6631
  { timeout: 3e5 }
@@ -6541,8 +6693,8 @@ var DependencyInstaller = class {
6541
6693
  }
6542
6694
  try {
6543
6695
  const programFiles = process.env["ProgramFiles"] || "C:\\Program Files";
6544
- const dockerExe = join8(programFiles, "Docker", "Docker", "Docker Desktop.exe");
6545
- if (existsSync5(dockerExe)) {
6696
+ const dockerExe = join10(programFiles, "Docker", "Docker", "Docker Desktop.exe");
6697
+ if (existsSync7(dockerExe)) {
6546
6698
  execSync(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
6547
6699
  }
6548
6700
  } catch {
@@ -6592,8 +6744,8 @@ var DependencyInstaller = class {
6592
6744
  this.onProgress("__progress__:70:Docker Desktop installed. Starting...");
6593
6745
  try {
6594
6746
  const programFiles = process.env["ProgramFiles"] || "C:\\Program Files";
6595
- const dockerExe = join8(programFiles, "Docker", "Docker", "Docker Desktop.exe");
6596
- if (existsSync5(dockerExe)) {
6747
+ const dockerExe = join10(programFiles, "Docker", "Docker", "Docker Desktop.exe");
6748
+ if (existsSync7(dockerExe)) {
6597
6749
  execSync(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
6598
6750
  }
6599
6751
  } catch {
@@ -6630,7 +6782,7 @@ var DependencyInstaller = class {
6630
6782
  * Start the Stalwart mail server Docker container.
6631
6783
  */
6632
6784
  async startStalwart(composePath) {
6633
- if (!existsSync5(composePath)) {
6785
+ if (!existsSync7(composePath)) {
6634
6786
  throw new Error(`docker-compose.yml not found at: ${composePath}`);
6635
6787
  }
6636
6788
  if (!this.isDockerReady()) {
@@ -6689,16 +6841,16 @@ var DependencyInstaller = class {
6689
6841
  */
6690
6842
  async installCloudflared() {
6691
6843
  const os = platform3();
6692
- const binDir = join8(homedir6(), ".agenticmail", "bin");
6844
+ const binDir = join10(homedir8(), ".agenticmail", "bin");
6693
6845
  const binName = os === "win32" ? "cloudflared.exe" : "cloudflared";
6694
- const binPath = join8(binDir, binName);
6695
- if (existsSync5(binPath)) {
6846
+ const binPath = join10(binDir, binName);
6847
+ if (existsSync7(binPath)) {
6696
6848
  return binPath;
6697
6849
  }
6698
6850
  try {
6699
6851
  const whichCmd = os === "win32" ? "where" : "which";
6700
6852
  const sysPath = execFileSync2(whichCmd, ["cloudflared"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim().split("\n")[0];
6701
- if (sysPath && existsSync5(sysPath)) return sysPath;
6853
+ if (sysPath && existsSync7(sysPath)) return sysPath;
6702
6854
  } catch {
6703
6855
  }
6704
6856
  this.onProgress("Downloading cloudflared...");
@@ -6721,8 +6873,8 @@ var DependencyInstaller = class {
6721
6873
  }
6722
6874
  const buffer = Buffer.from(await response.arrayBuffer());
6723
6875
  if (os === "darwin") {
6724
- const tgzPath = join8(binDir, "cloudflared.tgz");
6725
- await writeFile(tgzPath, buffer);
6876
+ const tgzPath = join10(binDir, "cloudflared.tgz");
6877
+ await writeFile3(tgzPath, buffer);
6726
6878
  try {
6727
6879
  execFileSync2("tar", ["-xzf", tgzPath, "-C", binDir, "cloudflared"], { timeout: 15e3, stdio: "ignore" });
6728
6880
  await chmod2(binPath, 493);
@@ -6734,11 +6886,11 @@ var DependencyInstaller = class {
6734
6886
  }
6735
6887
  } else {
6736
6888
  const tmpPath = binPath + ".tmp";
6737
- await writeFile(tmpPath, buffer);
6889
+ await writeFile3(tmpPath, buffer);
6738
6890
  if (os !== "win32") await chmod2(tmpPath, 493);
6739
6891
  await rename(tmpPath, binPath);
6740
6892
  }
6741
- if (!existsSync5(binPath)) {
6893
+ if (!existsSync7(binPath)) {
6742
6894
  throw new Error("cloudflared download succeeded but binary not found after extraction");
6743
6895
  }
6744
6896
  this.onProgress("cloudflared installed");
@@ -6756,9 +6908,9 @@ var DependencyInstaller = class {
6756
6908
 
6757
6909
  // src/setup/service.ts
6758
6910
  import { execFileSync as execFileSync3, execSync as execSync2 } from "child_process";
6759
- import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync4, unlinkSync, mkdirSync as mkdirSync5, chmodSync } from "fs";
6760
- import { join as join9 } from "path";
6761
- import { homedir as homedir7, platform as platform4 } from "os";
6911
+ import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync6, unlinkSync, mkdirSync as mkdirSync7, chmodSync } from "fs";
6912
+ import { join as join11 } from "path";
6913
+ import { homedir as homedir9, platform as platform4 } from "os";
6762
6914
  import { createRequire as createRequire2 } from "module";
6763
6915
  var PLIST_LABEL = "com.agenticmail.server";
6764
6916
  var SYSTEMD_UNIT = "agenticmail.service";
@@ -6769,9 +6921,9 @@ var ServiceManager = class {
6769
6921
  */
6770
6922
  getServicePath() {
6771
6923
  if (this.os === "darwin") {
6772
- return join9(homedir7(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
6924
+ return join11(homedir9(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
6773
6925
  } else {
6774
- return join9(homedir7(), ".config", "systemd", "user", SYSTEMD_UNIT);
6926
+ return join11(homedir9(), ".config", "systemd", "user", SYSTEMD_UNIT);
6775
6927
  }
6776
6928
  }
6777
6929
  /**
@@ -6805,40 +6957,40 @@ var ServiceManager = class {
6805
6957
  try {
6806
6958
  const req = createRequire2(import.meta.url);
6807
6959
  const resolved = req.resolve("@agenticmail/api");
6808
- if (existsSync6(resolved)) return resolved;
6960
+ if (existsSync8(resolved)) return resolved;
6809
6961
  } catch {
6810
6962
  }
6811
6963
  const parentPackages = [
6812
- join9("@agenticmail", "cli"),
6964
+ join11("@agenticmail", "cli"),
6813
6965
  // current scoped package
6814
6966
  "agenticmail"
6815
6967
  // legacy unscoped package
6816
6968
  ];
6817
6969
  const baseDirs = [
6818
6970
  // user-local install
6819
- join9(homedir7(), "node_modules")
6971
+ join11(homedir9(), "node_modules")
6820
6972
  ];
6821
6973
  try {
6822
6974
  const prefix = execSync2("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
6823
- baseDirs.push(join9(prefix, "lib", "node_modules"));
6824
- baseDirs.push(join9(prefix, "node_modules"));
6975
+ baseDirs.push(join11(prefix, "lib", "node_modules"));
6976
+ baseDirs.push(join11(prefix, "node_modules"));
6825
6977
  } catch {
6826
6978
  }
6827
6979
  baseDirs.push("/opt/homebrew/lib/node_modules");
6828
6980
  baseDirs.push("/usr/local/lib/node_modules");
6829
6981
  for (const base of baseDirs) {
6830
- const sibling = join9(base, "@agenticmail", "api", "dist", "index.js");
6831
- if (existsSync6(sibling)) return sibling;
6982
+ const sibling = join11(base, "@agenticmail", "api", "dist", "index.js");
6983
+ if (existsSync8(sibling)) return sibling;
6832
6984
  for (const parent of parentPackages) {
6833
- const nested = join9(base, parent, "node_modules", "@agenticmail", "api", "dist", "index.js");
6834
- if (existsSync6(nested)) return nested;
6985
+ const nested = join11(base, parent, "node_modules", "@agenticmail", "api", "dist", "index.js");
6986
+ if (existsSync8(nested)) return nested;
6835
6987
  }
6836
6988
  }
6837
- const dataDir = join9(homedir7(), ".agenticmail");
6838
- const entryCache = join9(dataDir, "api-entry.path");
6839
- if (existsSync6(entryCache)) {
6840
- const cached = readFileSync3(entryCache, "utf-8").trim();
6841
- if (cached && existsSync6(cached)) return cached;
6989
+ const dataDir = join11(homedir9(), ".agenticmail");
6990
+ const entryCache = join11(dataDir, "api-entry.path");
6991
+ if (existsSync8(entryCache)) {
6992
+ const cached = readFileSync5(entryCache, "utf-8").trim();
6993
+ if (cached && existsSync8(cached)) return cached;
6842
6994
  }
6843
6995
  throw new Error("Could not find @agenticmail/api entry point. Run `agenticmail start` first to populate the cache.");
6844
6996
  }
@@ -6846,9 +6998,9 @@ var ServiceManager = class {
6846
6998
  * Cache the API entry path so the service can find it later.
6847
6999
  */
6848
7000
  cacheApiEntryPath(entryPath) {
6849
- const dataDir = join9(homedir7(), ".agenticmail");
6850
- if (!existsSync6(dataDir)) mkdirSync5(dataDir, { recursive: true });
6851
- writeFileSync4(join9(dataDir, "api-entry.path"), entryPath);
7001
+ const dataDir = join11(homedir9(), ".agenticmail");
7002
+ if (!existsSync8(dataDir)) mkdirSync7(dataDir, { recursive: true });
7003
+ writeFileSync6(join11(dataDir, "api-entry.path"), entryPath);
6852
7004
  }
6853
7005
  /**
6854
7006
  * Get the current package version.
@@ -6861,36 +7013,36 @@ var ServiceManager = class {
6861
7013
  try {
6862
7014
  const req = createRequire2(import.meta.url);
6863
7015
  const pkgJson = req.resolve("@agenticmail/cli/package.json");
6864
- if (existsSync6(pkgJson)) {
6865
- const pkg = JSON.parse(readFileSync3(pkgJson, "utf-8"));
7016
+ if (existsSync8(pkgJson)) {
7017
+ const pkg = JSON.parse(readFileSync5(pkgJson, "utf-8"));
6866
7018
  if (pkg.version) return pkg.version;
6867
7019
  }
6868
7020
  } catch {
6869
7021
  }
6870
7022
  try {
6871
7023
  const apiEntry = this.getApiEntryPath();
6872
- const apiPkg = join9(apiEntry, "..", "..", "package.json");
6873
- if (existsSync6(apiPkg)) {
6874
- const pkg = JSON.parse(readFileSync3(apiPkg, "utf-8"));
7024
+ const apiPkg = join11(apiEntry, "..", "..", "package.json");
7025
+ if (existsSync8(apiPkg)) {
7026
+ const pkg = JSON.parse(readFileSync5(apiPkg, "utf-8"));
6875
7027
  if (pkg.version) return pkg.version;
6876
7028
  }
6877
7029
  } catch {
6878
7030
  }
6879
7031
  const candidates = [
6880
- join9(homedir7(), "node_modules", "@agenticmail", "cli", "package.json"),
6881
- join9(homedir7(), "node_modules", "agenticmail", "package.json"),
6882
- join9(homedir7(), ".agenticmail", "package-version.json")
7032
+ join11(homedir9(), "node_modules", "@agenticmail", "cli", "package.json"),
7033
+ join11(homedir9(), "node_modules", "agenticmail", "package.json"),
7034
+ join11(homedir9(), ".agenticmail", "package-version.json")
6883
7035
  ];
6884
7036
  try {
6885
7037
  const prefix = execSync2("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
6886
- candidates.push(join9(prefix, "lib", "node_modules", "@agenticmail", "cli", "package.json"));
6887
- candidates.push(join9(prefix, "lib", "node_modules", "agenticmail", "package.json"));
7038
+ candidates.push(join11(prefix, "lib", "node_modules", "@agenticmail", "cli", "package.json"));
7039
+ candidates.push(join11(prefix, "lib", "node_modules", "agenticmail", "package.json"));
6888
7040
  } catch {
6889
7041
  }
6890
7042
  for (const p of candidates) {
6891
7043
  try {
6892
- if (existsSync6(p)) {
6893
- const pkg = JSON.parse(readFileSync3(p, "utf-8"));
7044
+ if (existsSync8(p)) {
7045
+ const pkg = JSON.parse(readFileSync5(p, "utf-8"));
6894
7046
  if (pkg.version) return pkg.version;
6895
7047
  }
6896
7048
  } catch {
@@ -6903,9 +7055,9 @@ var ServiceManager = class {
6903
7055
  * This ensures AgenticMail doesn't fail on boot when Docker is still loading.
6904
7056
  */
6905
7057
  generateStartScript(nodePath, apiEntry) {
6906
- const scriptPath = join9(homedir7(), ".agenticmail", "bin", "start-server.sh");
6907
- const scriptDir = join9(homedir7(), ".agenticmail", "bin");
6908
- if (!existsSync6(scriptDir)) mkdirSync5(scriptDir, { recursive: true });
7058
+ const scriptPath = join11(homedir9(), ".agenticmail", "bin", "start-server.sh");
7059
+ const scriptDir = join11(homedir9(), ".agenticmail", "bin");
7060
+ if (!existsSync8(scriptDir)) mkdirSync7(scriptDir, { recursive: true });
6909
7061
  const script = [
6910
7062
  "#!/bin/bash",
6911
7063
  "# AgenticMail auto-start script",
@@ -6956,7 +7108,7 @@ var ServiceManager = class {
6956
7108
  `log "Starting API server: ${nodePath} ${apiEntry}"`,
6957
7109
  `exec "${nodePath}" "${apiEntry}"`
6958
7110
  ].join("\n") + "\n";
6959
- writeFileSync4(scriptPath, script, { mode: 493 });
7111
+ writeFileSync6(scriptPath, script, { mode: 493 });
6960
7112
  return scriptPath;
6961
7113
  }
6962
7114
  /**
@@ -6969,9 +7121,9 @@ var ServiceManager = class {
6969
7121
  * - Service version tracking in env vars
6970
7122
  */
6971
7123
  generatePlist(nodePath, apiEntry, configPath) {
6972
- const config = JSON.parse(readFileSync3(configPath, "utf-8"));
6973
- const logDir = join9(homedir7(), ".agenticmail", "logs");
6974
- if (!existsSync6(logDir)) mkdirSync5(logDir, { recursive: true });
7124
+ const config = JSON.parse(readFileSync5(configPath, "utf-8"));
7125
+ const logDir = join11(homedir9(), ".agenticmail", "logs");
7126
+ if (!existsSync8(logDir)) mkdirSync7(logDir, { recursive: true });
6975
7127
  const version = this.getVersion();
6976
7128
  const startScript = this.generateStartScript(nodePath, apiEntry);
6977
7129
  return `<?xml version="1.0" encoding="UTF-8"?>
@@ -6992,9 +7144,9 @@ var ServiceManager = class {
6992
7144
  <key>EnvironmentVariables</key>
6993
7145
  <dict>
6994
7146
  <key>HOME</key>
6995
- <string>${homedir7()}</string>
7147
+ <string>${homedir9()}</string>
6996
7148
  <key>AGENTICMAIL_DATA_DIR</key>
6997
- <string>${config.dataDir || join9(homedir7(), ".agenticmail")}</string>
7149
+ <string>${config.dataDir || join11(homedir9(), ".agenticmail")}</string>
6998
7150
  <key>PATH</key>
6999
7151
  <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
7000
7152
  <key>AGENTICMAIL_SERVICE_VERSION</key>
@@ -7047,8 +7199,8 @@ var ServiceManager = class {
7047
7199
  * - Proper dependency ordering
7048
7200
  */
7049
7201
  generateSystemdUnit(nodePath, apiEntry, configPath) {
7050
- const config = JSON.parse(readFileSync3(configPath, "utf-8"));
7051
- const dataDir = config.dataDir || join9(homedir7(), ".agenticmail");
7202
+ const config = JSON.parse(readFileSync5(configPath, "utf-8"));
7203
+ const dataDir = config.dataDir || join11(homedir9(), ".agenticmail");
7052
7204
  const version = this.getVersion();
7053
7205
  const startScript = this.generateStartScript(nodePath, apiEntry);
7054
7206
  return `[Unit]
@@ -7065,7 +7217,7 @@ Restart=always
7065
7217
  RestartSec=15
7066
7218
  TimeoutStartSec=660
7067
7219
  LimitNOFILE=8192
7068
- Environment=HOME=${homedir7()}
7220
+ Environment=HOME=${homedir9()}
7069
7221
  Environment=AGENTICMAIL_DATA_DIR=${dataDir}
7070
7222
  Environment=PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin
7071
7223
  Environment=AGENTICMAIL_SERVICE_VERSION=${version}
@@ -7078,8 +7230,8 @@ WantedBy=default.target
7078
7230
  * Install the auto-start service.
7079
7231
  */
7080
7232
  install() {
7081
- const configPath = join9(homedir7(), ".agenticmail", "config.json");
7082
- if (!existsSync6(configPath)) {
7233
+ const configPath = join11(homedir9(), ".agenticmail", "config.json");
7234
+ if (!existsSync8(configPath)) {
7083
7235
  return { installed: false, message: "Config not found. Run agenticmail setup first." };
7084
7236
  }
7085
7237
  const nodePath = this.getNodePath();
@@ -7091,16 +7243,16 @@ WantedBy=default.target
7091
7243
  }
7092
7244
  const servicePath = this.getServicePath();
7093
7245
  if (this.os === "darwin") {
7094
- const dir = join9(homedir7(), "Library", "LaunchAgents");
7095
- if (!existsSync6(dir)) mkdirSync5(dir, { recursive: true });
7096
- if (existsSync6(servicePath)) {
7246
+ const dir2 = join11(homedir9(), "Library", "LaunchAgents");
7247
+ if (!existsSync8(dir2)) mkdirSync7(dir2, { recursive: true });
7248
+ if (existsSync8(servicePath)) {
7097
7249
  try {
7098
7250
  execFileSync3("launchctl", ["unload", servicePath], { timeout: 1e4, stdio: "ignore" });
7099
7251
  } catch {
7100
7252
  }
7101
7253
  }
7102
7254
  const plist = this.generatePlist(nodePath, apiEntry, configPath);
7103
- writeFileSync4(servicePath, plist);
7255
+ writeFileSync6(servicePath, plist);
7104
7256
  chmodSync(servicePath, 384);
7105
7257
  try {
7106
7258
  execFileSync3("launchctl", ["load", servicePath], { timeout: 1e4, stdio: "ignore" });
@@ -7109,10 +7261,10 @@ WantedBy=default.target
7109
7261
  }
7110
7262
  return { installed: true, message: `Service installed at ${servicePath}` };
7111
7263
  } else if (this.os === "linux") {
7112
- const dir = join9(homedir7(), ".config", "systemd", "user");
7113
- if (!existsSync6(dir)) mkdirSync5(dir, { recursive: true });
7264
+ const dir2 = join11(homedir9(), ".config", "systemd", "user");
7265
+ if (!existsSync8(dir2)) mkdirSync7(dir2, { recursive: true });
7114
7266
  const unit = this.generateSystemdUnit(nodePath, apiEntry, configPath);
7115
- writeFileSync4(servicePath, unit);
7267
+ writeFileSync6(servicePath, unit);
7116
7268
  chmodSync(servicePath, 384);
7117
7269
  try {
7118
7270
  execFileSync3("systemctl", ["--user", "daemon-reload"], { timeout: 1e4, stdio: "ignore" });
@@ -7135,7 +7287,7 @@ WantedBy=default.target
7135
7287
  */
7136
7288
  uninstall() {
7137
7289
  const servicePath = this.getServicePath();
7138
- if (!existsSync6(servicePath)) {
7290
+ if (!existsSync8(servicePath)) {
7139
7291
  return { removed: false, message: "Service is not installed." };
7140
7292
  }
7141
7293
  if (this.os === "darwin") {
@@ -7173,7 +7325,7 @@ WantedBy=default.target
7173
7325
  status() {
7174
7326
  const servicePath = this.getServicePath();
7175
7327
  const plat = this.os === "darwin" ? "launchd" : this.os === "linux" ? "systemd" : "unsupported";
7176
- const installed = existsSync6(servicePath);
7328
+ const installed = existsSync8(servicePath);
7177
7329
  let running = false;
7178
7330
  if (installed) {
7179
7331
  if (this.os === "darwin") {
@@ -7228,34 +7380,34 @@ WantedBy=default.target
7228
7380
  needsRepair() {
7229
7381
  if (this.os !== "darwin" && this.os !== "linux") return null;
7230
7382
  const servicePath = this.getServicePath();
7231
- if (!existsSync6(servicePath)) return null;
7383
+ if (!existsSync8(servicePath)) return null;
7232
7384
  let serviceContent = "";
7233
7385
  try {
7234
- serviceContent = readFileSync3(servicePath, "utf-8");
7386
+ serviceContent = readFileSync5(servicePath, "utf-8");
7235
7387
  } catch {
7236
7388
  return { reason: "Service file unreadable" };
7237
7389
  }
7238
- const startScript = join9(homedir7(), ".agenticmail", "bin", "start-server.sh");
7390
+ const startScript = join11(homedir9(), ".agenticmail", "bin", "start-server.sh");
7239
7391
  if (serviceContent.includes(startScript)) {
7240
- if (!existsSync6(startScript)) {
7392
+ if (!existsSync8(startScript)) {
7241
7393
  return { reason: "start-server.sh is missing" };
7242
7394
  }
7243
7395
  let scriptContent = "";
7244
7396
  try {
7245
- scriptContent = readFileSync3(startScript, "utf-8");
7397
+ scriptContent = readFileSync5(startScript, "utf-8");
7246
7398
  } catch {
7247
7399
  return { reason: "start-server.sh unreadable" };
7248
7400
  }
7249
7401
  const apiPathMatch = scriptContent.match(/(\/[^"\s]+@agenticmail\/api\/dist\/index\.js)/);
7250
7402
  if (apiPathMatch) {
7251
7403
  const referenced = apiPathMatch[1];
7252
- if (!existsSync6(referenced)) {
7404
+ if (!existsSync8(referenced)) {
7253
7405
  return { reason: `start-server.sh references missing path: ${referenced}` };
7254
7406
  }
7255
7407
  }
7256
7408
  if (/node_modules\/agenticmail\/(?!.*@agenticmail\/cli)/.test(scriptContent)) {
7257
7409
  const stale = /(\S*node_modules\/agenticmail\/\S*)/.exec(scriptContent)?.[1];
7258
- if (stale && !existsSync6(stale)) {
7410
+ if (stale && !existsSync8(stale)) {
7259
7411
  return { reason: `start-server.sh references legacy unscoped path: ${stale}` };
7260
7412
  }
7261
7413
  }
@@ -7268,11 +7420,11 @@ WantedBy=default.target
7268
7420
  return { reason: `Service version drift (current CLI is v${currentVersion})` };
7269
7421
  }
7270
7422
  }
7271
- const entryCache = join9(homedir7(), ".agenticmail", "api-entry.path");
7272
- if (existsSync6(entryCache)) {
7423
+ const entryCache = join11(homedir9(), ".agenticmail", "api-entry.path");
7424
+ if (existsSync8(entryCache)) {
7273
7425
  try {
7274
- const cached = readFileSync3(entryCache, "utf-8").trim();
7275
- if (cached && !existsSync6(cached)) {
7426
+ const cached = readFileSync5(entryCache, "utf-8").trim();
7427
+ if (cached && !existsSync8(cached)) {
7276
7428
  return { reason: `Cached API entry path no longer exists: ${cached}` };
7277
7429
  }
7278
7430
  } catch {
@@ -7311,8 +7463,8 @@ var SetupManager = class {
7311
7463
  async ensureStalwart(composePath) {
7312
7464
  const status = await this.checker.checkStalwart();
7313
7465
  if (status.installed) return;
7314
- const path = composePath ?? this.getComposePath();
7315
- await this.installer.startStalwart(path);
7466
+ const path2 = composePath ?? this.getComposePath();
7467
+ await this.installer.startStalwart(path2);
7316
7468
  }
7317
7469
  async ensureCloudflared() {
7318
7470
  return this.installer.installCloudflared();
@@ -7323,13 +7475,13 @@ var SetupManager = class {
7323
7475
  * falls back to monorepo location.
7324
7476
  */
7325
7477
  getComposePath() {
7326
- const standalonePath = join10(homedir8(), ".agenticmail", "docker-compose.yml");
7327
- if (existsSync7(standalonePath)) return standalonePath;
7478
+ const standalonePath = join12(homedir10(), ".agenticmail", "docker-compose.yml");
7479
+ if (existsSync9(standalonePath)) return standalonePath;
7328
7480
  const cwd = process.cwd();
7329
- const candidates = [cwd, join10(cwd, "..")];
7330
- for (const dir of candidates) {
7331
- const p = join10(dir, "docker-compose.yml");
7332
- if (existsSync7(p)) return p;
7481
+ const candidates = [cwd, join12(cwd, "..")];
7482
+ for (const dir2 of candidates) {
7483
+ const p = join12(dir2, "docker-compose.yml");
7484
+ if (existsSync9(p)) return p;
7333
7485
  }
7334
7486
  return standalonePath;
7335
7487
  }
@@ -7339,19 +7491,19 @@ var SetupManager = class {
7339
7491
  * Always regenerates Docker files to keep passwords in sync.
7340
7492
  */
7341
7493
  initConfig() {
7342
- const dataDir = join10(homedir8(), ".agenticmail");
7343
- const configPath = join10(dataDir, "config.json");
7344
- const envPath = join10(dataDir, ".env");
7345
- if (existsSync7(configPath)) {
7494
+ const dataDir = join12(homedir10(), ".agenticmail");
7495
+ const configPath = join12(dataDir, "config.json");
7496
+ const envPath = join12(dataDir, ".env");
7497
+ if (existsSync9(configPath)) {
7346
7498
  try {
7347
- const existing = JSON.parse(readFileSync4(configPath, "utf-8"));
7499
+ const existing = JSON.parse(readFileSync6(configPath, "utf-8"));
7348
7500
  this.generateDockerFiles(existing);
7349
7501
  return { configPath, envPath, config: existing, isNew: false };
7350
7502
  } catch {
7351
7503
  }
7352
7504
  }
7353
- if (!existsSync7(dataDir)) {
7354
- mkdirSync6(dataDir, { recursive: true });
7505
+ if (!existsSync9(dataDir)) {
7506
+ mkdirSync8(dataDir, { recursive: true });
7355
7507
  }
7356
7508
  const masterKey = `mk_${randomBytes3(24).toString("hex")}`;
7357
7509
  const stalwartPassword = randomBytes3(16).toString("hex");
@@ -7367,7 +7519,7 @@ var SetupManager = class {
7367
7519
  api: { port: 3829, host: "127.0.0.1" },
7368
7520
  dataDir
7369
7521
  };
7370
- writeFileSync5(configPath, JSON.stringify(config, null, 2));
7522
+ writeFileSync7(configPath, JSON.stringify(config, null, 2));
7371
7523
  chmodSync2(configPath, 384);
7372
7524
  const envContent = `# Auto-generated by agenticmail setup
7373
7525
  STALWART_ADMIN_USER=admin
@@ -7383,7 +7535,7 @@ SMTP_PORT=587
7383
7535
  IMAP_HOST=localhost
7384
7536
  IMAP_PORT=143
7385
7537
  `;
7386
- writeFileSync5(envPath, envContent);
7538
+ writeFileSync7(envPath, envContent);
7387
7539
  chmodSync2(envPath, 384);
7388
7540
  this.generateDockerFiles(config);
7389
7541
  return { configPath, envPath, config, isNew: true };
@@ -7393,13 +7545,13 @@ IMAP_PORT=143
7393
7545
  * with the correct admin password from config.
7394
7546
  */
7395
7547
  generateDockerFiles(config) {
7396
- const dataDir = config.dataDir || join10(homedir8(), ".agenticmail");
7397
- if (!existsSync7(dataDir)) {
7398
- mkdirSync6(dataDir, { recursive: true });
7548
+ const dataDir = config.dataDir || join12(homedir10(), ".agenticmail");
7549
+ if (!existsSync9(dataDir)) {
7550
+ mkdirSync8(dataDir, { recursive: true });
7399
7551
  }
7400
7552
  const password = config.stalwart?.adminPassword || "changeme";
7401
- const composePath = join10(dataDir, "docker-compose.yml");
7402
- writeFileSync5(composePath, `services:
7553
+ const composePath = join12(dataDir, "docker-compose.yml");
7554
+ writeFileSync7(composePath, `services:
7403
7555
  stalwart:
7404
7556
  # Pinned to v0.15.5 \u2014 Stalwart 0.16+ moved its config to JSON
7405
7557
  # at /etc/stalwart/config.json (hardcoded into the container
@@ -7429,8 +7581,8 @@ volumes:
7429
7581
  stalwart-data:
7430
7582
  `);
7431
7583
  chmodSync2(composePath, 384);
7432
- const tomlPath = join10(dataDir, "stalwart.toml");
7433
- writeFileSync5(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
7584
+ const tomlPath = join12(dataDir, "stalwart.toml");
7585
+ writeFileSync7(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
7434
7586
 
7435
7587
  [server]
7436
7588
  hostname = "localhost"
@@ -7486,8 +7638,8 @@ secret = "${password}"
7486
7638
  * Check if config has already been initialized.
7487
7639
  */
7488
7640
  isInitialized() {
7489
- const configPath = join10(homedir8(), ".agenticmail", "config.json");
7490
- return existsSync7(configPath);
7641
+ const configPath = join12(homedir10(), ".agenticmail", "config.json");
7642
+ return existsSync9(configPath);
7491
7643
  }
7492
7644
  };
7493
7645
 
@@ -7526,18 +7678,18 @@ function threadIdFor(input) {
7526
7678
 
7527
7679
  // src/threading/thread-cache.ts
7528
7680
  import {
7529
- existsSync as existsSync8,
7530
- mkdirSync as mkdirSync7,
7531
- readFileSync as readFileSync5,
7532
- writeFileSync as writeFileSync6,
7681
+ existsSync as existsSync10,
7682
+ mkdirSync as mkdirSync9,
7683
+ readFileSync as readFileSync7,
7684
+ writeFileSync as writeFileSync8,
7533
7685
  readdirSync,
7534
7686
  statSync,
7535
7687
  rmSync,
7536
- renameSync
7688
+ renameSync as renameSync3
7537
7689
  } from "fs";
7538
- import { homedir as homedir9 } from "os";
7539
- import { join as join11 } from "path";
7540
- var CACHE_DIR_DEFAULT = join11(homedir9(), ".agenticmail", "thread-cache");
7690
+ import { homedir as homedir11 } from "os";
7691
+ import { join as join13 } from "path";
7692
+ var CACHE_DIR_DEFAULT = join13(homedir11(), ".agenticmail", "thread-cache");
7541
7693
  var DEFAULT_K_MESSAGES = 10;
7542
7694
  var DEFAULT_LRU_CAP = 5e3;
7543
7695
  var PREVIEW_MAX_CHARS = 240;
@@ -7550,18 +7702,18 @@ var ThreadCache = class {
7550
7702
  this.k = opts.k ?? DEFAULT_K_MESSAGES;
7551
7703
  this.lruCap = opts.lruCap ?? DEFAULT_LRU_CAP;
7552
7704
  try {
7553
- mkdirSync7(this.dir, { recursive: true });
7705
+ mkdirSync9(this.dir, { recursive: true });
7554
7706
  } catch {
7555
7707
  }
7556
7708
  }
7557
7709
  pathFor(threadId) {
7558
- return join11(this.dir, `${threadId}.json`);
7710
+ return join13(this.dir, `${threadId}.json`);
7559
7711
  }
7560
7712
  read(threadId) {
7561
7713
  const p = this.pathFor(threadId);
7562
- if (!existsSync8(p)) return null;
7714
+ if (!existsSync10(p)) return null;
7563
7715
  try {
7564
- const raw = readFileSync5(p, "utf-8");
7716
+ const raw = readFileSync7(p, "utf-8");
7565
7717
  return JSON.parse(raw);
7566
7718
  } catch {
7567
7719
  try {
@@ -7626,8 +7778,8 @@ var ThreadCache = class {
7626
7778
  writeAtomic(threadId, entry) {
7627
7779
  const p = this.pathFor(threadId);
7628
7780
  const tmp = `${p}.tmp`;
7629
- writeFileSync6(tmp, JSON.stringify(entry), "utf-8");
7630
- renameSync(tmp, p);
7781
+ writeFileSync8(tmp, JSON.stringify(entry), "utf-8");
7782
+ renameSync3(tmp, p);
7631
7783
  }
7632
7784
  /**
7633
7785
  * Best-effort LRU eviction. Runs at most every 256 writes (we
@@ -7645,7 +7797,7 @@ var ThreadCache = class {
7645
7797
  }
7646
7798
  if (files.length <= this.lruCap) return;
7647
7799
  const stats = files.map((f) => {
7648
- const p = join11(this.dir, f);
7800
+ const p = join13(this.dir, f);
7649
7801
  try {
7650
7802
  return { p, mtime: statSync(p).mtimeMs };
7651
7803
  } catch {
@@ -7676,36 +7828,36 @@ function dedupAndCap(messages, k) {
7676
7828
 
7677
7829
  // src/threading/agent-memory.ts
7678
7830
  import {
7679
- existsSync as existsSync9,
7680
- mkdirSync as mkdirSync8,
7681
- readFileSync as readFileSync6,
7682
- writeFileSync as writeFileSync7,
7831
+ existsSync as existsSync11,
7832
+ mkdirSync as mkdirSync10,
7833
+ readFileSync as readFileSync8,
7834
+ writeFileSync as writeFileSync9,
7683
7835
  rmSync as rmSync2,
7684
- renameSync as renameSync2
7836
+ renameSync as renameSync4
7685
7837
  } from "fs";
7686
- import { homedir as homedir10 } from "os";
7687
- import { join as join12 } from "path";
7688
- var MEMORY_DIR_DEFAULT = join12(homedir10(), ".agenticmail", "agent-memory");
7838
+ import { homedir as homedir12 } from "os";
7839
+ import { join as join14 } from "path";
7840
+ var MEMORY_DIR_DEFAULT = join14(homedir12(), ".agenticmail", "agent-memory");
7689
7841
  var AgentMemoryStore = class {
7690
7842
  dir;
7691
7843
  constructor(opts = {}) {
7692
7844
  this.dir = opts.memoryDir ?? MEMORY_DIR_DEFAULT;
7693
7845
  try {
7694
- mkdirSync8(this.dir, { recursive: true });
7846
+ mkdirSync10(this.dir, { recursive: true });
7695
7847
  } catch {
7696
7848
  }
7697
7849
  }
7698
7850
  dirFor(agentId) {
7699
- return join12(this.dir, sanitizeId(agentId));
7851
+ return join14(this.dir, sanitizeId(agentId));
7700
7852
  }
7701
7853
  pathFor(agentId, threadId) {
7702
- return join12(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
7854
+ return join14(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
7703
7855
  }
7704
7856
  read(agentId, threadId) {
7705
7857
  const p = this.pathFor(agentId, threadId);
7706
- if (!existsSync9(p)) return null;
7858
+ if (!existsSync11(p)) return null;
7707
7859
  try {
7708
- const raw = readFileSync6(p, "utf-8");
7860
+ const raw = readFileSync8(p, "utf-8");
7709
7861
  const parsed = parse(raw);
7710
7862
  return { ...parsed, raw };
7711
7863
  } catch {
@@ -7715,14 +7867,14 @@ var AgentMemoryStore = class {
7715
7867
  write(agentId, threadId, fields) {
7716
7868
  const agentDir = this.dirFor(agentId);
7717
7869
  try {
7718
- mkdirSync8(agentDir, { recursive: true });
7870
+ mkdirSync10(agentDir, { recursive: true });
7719
7871
  } catch {
7720
7872
  }
7721
7873
  const body = render({ ...fields, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
7722
7874
  const p = this.pathFor(agentId, threadId);
7723
7875
  const tmp = `${p}.tmp`;
7724
- writeFileSync7(tmp, body, "utf-8");
7725
- renameSync2(tmp, p);
7876
+ writeFileSync9(tmp, body, "utf-8");
7877
+ renameSync4(tmp, p);
7726
7878
  }
7727
7879
  delete(agentId, threadId) {
7728
7880
  try {
@@ -7790,6 +7942,7 @@ export {
7790
7942
  CloudflareClient,
7791
7943
  DEFAULT_AGENT_NAME,
7792
7944
  DEFAULT_AGENT_ROLE,
7945
+ DEFAULT_SESSION_MAX_AGE_MS,
7793
7946
  DNSConfigurator,
7794
7947
  DependencyChecker,
7795
7948
  DependencyInstaller,
@@ -7826,12 +7979,18 @@ export {
7826
7979
  ensureDataDir,
7827
7980
  extractVerificationCode,
7828
7981
  flushTelemetry,
7982
+ forgetHostSession,
7829
7983
  getDatabase,
7984
+ getOperatorEmail,
7985
+ hostSessionStoragePath,
7830
7986
  isInternalEmail,
7987
+ isSessionFresh,
7831
7988
  isValidPhoneNumber,
7989
+ loadHostSession,
7832
7990
  normalizeAddress,
7833
7991
  normalizePhoneNumber,
7834
7992
  normalizeSubject,
7993
+ operatorPrefsStoragePath,
7835
7994
  parseEmail,
7836
7995
  parseGoogleVoiceSms,
7837
7996
  recordToolCall,
@@ -7841,8 +8000,10 @@ export {
7841
8000
  safeJoin,
7842
8001
  sanitizeEmail,
7843
8002
  saveConfig,
8003
+ saveHostSession,
7844
8004
  scanOutboundEmail,
7845
8005
  scoreEmail,
8006
+ setOperatorEmail,
7846
8007
  setTelemetryVersion,
7847
8008
  startRelayBridge,
7848
8009
  threadIdFor,