@agenticmail/core 0.9.6 → 0.9.8

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
@@ -191,6 +191,14 @@ var MailReceiver = class {
191
191
  name: a.name,
192
192
  address: a.address ?? ""
193
193
  })),
194
+ cc: (env.cc ?? []).map((a) => ({
195
+ name: a.name,
196
+ address: a.address ?? ""
197
+ })),
198
+ bcc: (env.bcc ?? []).map((a) => ({
199
+ name: a.name,
200
+ address: a.address ?? ""
201
+ })),
194
202
  date: env.date ?? /* @__PURE__ */ new Date(),
195
203
  flags: msg.flags ?? /* @__PURE__ */ new Set(),
196
204
  size: msg.size ?? 0
@@ -390,8 +398,8 @@ var MailReceiver = class {
390
398
  }));
391
399
  }
392
400
  /** Create a new IMAP folder */
393
- async createFolder(path) {
394
- await this.client.mailboxCreate(path);
401
+ async createFolder(path2) {
402
+ await this.client.mailboxCreate(path2);
395
403
  }
396
404
  /** Batch mark multiple messages as seen */
397
405
  async batchMarkSeen(uids, mailbox = "INBOX") {
@@ -931,8 +939,8 @@ var StalwartAdmin = class {
931
939
  }
932
940
  baseUrl;
933
941
  authHeader;
934
- async request(method, path, body) {
935
- const url = `${this.baseUrl}/api${path}`;
942
+ async request(method, path2, body) {
943
+ const url = `${this.baseUrl}/api${path2}`;
936
944
  const response = await fetch(url, {
937
945
  method,
938
946
  headers: {
@@ -1093,14 +1101,14 @@ var StalwartAdmin = class {
1093
1101
  if (!isValidDomain(domain)) {
1094
1102
  throw new Error(`Invalid domain format: "${domain}"`);
1095
1103
  }
1096
- const { readFileSync: readFileSync8, writeFileSync: writeFileSync9 } = await import("fs");
1097
- const { homedir: homedir12 } = await import("os");
1098
- const { join: join14 } = await import("path");
1099
- const configPath = join14(homedir12(), ".agenticmail", "stalwart.toml");
1104
+ const { readFileSync: readFileSync9, writeFileSync: writeFileSync10 } = await import("fs");
1105
+ const { homedir: homedir13 } = await import("os");
1106
+ const { join: join15 } = await import("path");
1107
+ const configPath = join15(homedir13(), ".agenticmail", "stalwart.toml");
1100
1108
  try {
1101
- let config = readFileSync8(configPath, "utf-8");
1109
+ let config = readFileSync9(configPath, "utf-8");
1102
1110
  config = config.replace(/^hostname\s*=\s*"[^"]*"/m, `hostname = "${escapeTomlString(domain)}"`);
1103
- writeFileSync9(configPath, config);
1111
+ writeFileSync10(configPath, config);
1104
1112
  console.log(`[Stalwart] Updated hostname to "${domain}" in stalwart.toml`);
1105
1113
  } catch (err) {
1106
1114
  throw new Error(`Failed to set config server.hostname=${domain}`);
@@ -1109,15 +1117,15 @@ var StalwartAdmin = class {
1109
1117
  // --- DKIM ---
1110
1118
  /** Path to the host-side stalwart.toml (mounted read-only into container) */
1111
1119
  get configPath() {
1112
- const { homedir: homedir12 } = __require("os");
1113
- const { join: join14 } = __require("path");
1114
- return join14(homedir12(), ".agenticmail", "stalwart.toml");
1120
+ const { homedir: homedir13 } = __require("os");
1121
+ const { join: join15 } = __require("path");
1122
+ return join15(homedir13(), ".agenticmail", "stalwart.toml");
1115
1123
  }
1116
1124
  /** Path to host-side DKIM key directory */
1117
1125
  get dkimDir() {
1118
- const { homedir: homedir12 } = __require("os");
1119
- const { join: join14 } = __require("path");
1120
- return join14(homedir12(), ".agenticmail");
1126
+ const { homedir: homedir13 } = __require("os");
1127
+ const { join: join15 } = __require("path");
1128
+ return join15(homedir13(), ".agenticmail");
1121
1129
  }
1122
1130
  /**
1123
1131
  * Create/reuse a DKIM signing key for a domain.
@@ -1218,12 +1226,12 @@ var StalwartAdmin = class {
1218
1226
  * This bypasses the need for a PTR record on the sending IP.
1219
1227
  */
1220
1228
  async configureOutboundRelay(config) {
1221
- const { readFileSync: readFileSync8, writeFileSync: writeFileSync9 } = await import("fs");
1222
- const { homedir: homedir12 } = await import("os");
1223
- const { join: join14 } = await import("path");
1229
+ const { readFileSync: readFileSync9, writeFileSync: writeFileSync10 } = await import("fs");
1230
+ const { homedir: homedir13 } = await import("os");
1231
+ const { join: join15 } = await import("path");
1224
1232
  const routeName = config.routeName ?? "gmail";
1225
- const tomlPath = join14(homedir12(), ".agenticmail", "stalwart.toml");
1226
- let toml = readFileSync8(tomlPath, "utf-8");
1233
+ const tomlPath = join15(homedir13(), ".agenticmail", "stalwart.toml");
1234
+ let toml = readFileSync9(tomlPath, "utf-8");
1227
1235
  toml = toml.replace(/\n\[queue\.route\.gmail\][\s\S]*?(?=\n\[|$)/, "");
1228
1236
  toml = toml.replace(/\n\[queue\.strategy\][\s\S]*?(?=\n\[|$)/, "");
1229
1237
  const safeRouteName = routeName.replace(/[^a-zA-Z0-9_-]/g, "");
@@ -1243,7 +1251,7 @@ auth.secret = "${escapeTomlString(config.password)}"
1243
1251
  route = [ { if = "is_local_domain('', rcpt_domain)", then = "'local'" },
1244
1252
  { else = "'${safeRouteName}'" } ]
1245
1253
  `;
1246
- writeFileSync9(tomlPath, toml, "utf-8");
1254
+ writeFileSync10(tomlPath, toml, "utf-8");
1247
1255
  await this.restartContainer();
1248
1256
  }
1249
1257
  };
@@ -1626,11 +1634,11 @@ var AgentDeletionService = class {
1626
1634
  };
1627
1635
  }
1628
1636
  saveToFile(report) {
1629
- const dir = join2(homedir2(), ".agenticmail", "deletions");
1630
- mkdirSync2(dir, { recursive: true });
1637
+ const dir2 = join2(homedir2(), ".agenticmail", "deletions");
1638
+ mkdirSync2(dir2, { recursive: true });
1631
1639
  const timestamp = report.deletedAt.replace(/[:.]/g, "-");
1632
1640
  const filename = `${report.agent.name}_${timestamp}.json`;
1633
- const filePath = join2(dir, filename);
1641
+ const filePath = join2(dir2, filename);
1634
1642
  writeFileSync2(filePath, JSON.stringify(report, null, 2), "utf-8");
1635
1643
  return filePath;
1636
1644
  }
@@ -3917,8 +3925,8 @@ var CloudflareClient = class {
3917
3925
  return resp.result;
3918
3926
  }
3919
3927
  // --- Internal ---
3920
- async request(method, path, body) {
3921
- const url = `${CF_API_BASE}${path}`;
3928
+ async request(method, path2, body) {
3929
+ const url = `${CF_API_BASE}${path2}`;
3922
3930
  const response = await fetch(url, {
3923
3931
  method,
3924
3932
  headers: {
@@ -4240,9 +4248,9 @@ var TunnelManager = class {
4240
4248
  throw new Error(`Failed to download cloudflared: ${response.statusText}`);
4241
4249
  }
4242
4250
  const buffer = Buffer.from(await response.arrayBuffer());
4243
- const { writeFile: writeFile3, rename: rename2 } = await import("fs/promises");
4251
+ const { writeFile: writeFile4, rename: rename2 } = await import("fs/promises");
4244
4252
  const tmpPath = this.binPath + ".tmp";
4245
- await writeFile3(tmpPath, buffer);
4253
+ await writeFile4(tmpPath, buffer);
4246
4254
  await chmod(tmpPath, 493);
4247
4255
  await rename2(tmpPath, this.binPath);
4248
4256
  return this.binPath;
@@ -4534,6 +4542,33 @@ var SmsManager = class {
4534
4542
  meta.sms = config;
4535
4543
  this.db.prepare("UPDATE agents SET metadata = ?, updated_at = datetime('now') WHERE id = ?").run(JSON.stringify(meta), agentId);
4536
4544
  }
4545
+ /**
4546
+ * Resolve the operator's "where do I get pinged" address from an
4547
+ * agent's SMS config. Used by the dispatcher's bridge-escalation
4548
+ * path: when sub-agents mail a bridge with no fresh host session
4549
+ * available, we email the operator a digest at this address. Their
4550
+ * phone's Gmail push notification surfaces it within seconds —
4551
+ * effectively a free, programmatic alert channel.
4552
+ *
4553
+ * Returns the configured `forwardingEmail` (the same Gmail Google
4554
+ * Voice forwards inbound SMS to, which the operator already has
4555
+ * push notifications enabled for) when SMS is configured AND
4556
+ * enabled. Returns null otherwise — caller falls through to a
4557
+ * silent log + system event.
4558
+ *
4559
+ * Why we don't try real-SMS delivery yet: Google Voice's
4560
+ * `<number>@txt.voice.google.com` email-to-SMS gateway was
4561
+ * deprecated by Google years ago. A future `carrier` field on
4562
+ * SmsConfig (Verizon vtext.com / AT&T txt.att.net / etc) will let
4563
+ * the operator opt into actual SMS, but that's a follow-up — the
4564
+ * email path already gets the operator a phone notification.
4565
+ */
4566
+ getAlertEmail(agentId) {
4567
+ const cfg = this.getSmsConfig(agentId);
4568
+ if (!cfg || !cfg.enabled) return null;
4569
+ if (typeof cfg.forwardingEmail !== "string" || !cfg.forwardingEmail.includes("@")) return null;
4570
+ return cfg.forwardingEmail;
4571
+ }
4537
4572
  /** Remove SMS config from agent metadata */
4538
4573
  removeSmsConfig(agentId) {
4539
4574
  const row = this.db.prepare("SELECT metadata FROM agents WHERE id = ?").get(agentId);
@@ -5149,12 +5184,12 @@ var GatewayManager = class {
5149
5184
  zone = await this.cfClient.createZone(domain);
5150
5185
  }
5151
5186
  const existingRecords = await this.cfClient.listDnsRecords(zone.id);
5152
- const { homedir: homedir12 } = await import("os");
5153
- const backupDir = join4(homedir12(), ".agenticmail");
5187
+ const { homedir: homedir13 } = await import("os");
5188
+ const backupDir = join4(homedir13(), ".agenticmail");
5154
5189
  const backupPath = join4(backupDir, `dns-backup-${domain}-${Date.now()}.json`);
5155
- const { writeFileSync: writeFileSync9, mkdirSync: mkdirSync10 } = await import("fs");
5156
- mkdirSync10(backupDir, { recursive: true });
5157
- writeFileSync9(backupPath, JSON.stringify({
5190
+ const { writeFileSync: writeFileSync10, mkdirSync: mkdirSync11 } = await import("fs");
5191
+ mkdirSync11(backupDir, { recursive: true });
5192
+ writeFileSync10(backupPath, JSON.stringify({
5158
5193
  domain,
5159
5194
  zoneId: zone.id,
5160
5195
  backedUpAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -5915,8 +5950,8 @@ function isDisabled() {
5915
5950
  function getInstallId() {
5916
5951
  if (installId) return installId;
5917
5952
  try {
5918
- const dir = join5(homedir4(), ".agenticmail");
5919
- const idFile = join5(dir, ".telemetry-id");
5953
+ const dir2 = join5(homedir4(), ".agenticmail");
5954
+ const idFile = join5(dir2, ".telemetry-id");
5920
5955
  if (existsSync3(idFile)) {
5921
5956
  const id = readFileSync2(idFile, "utf8").trim();
5922
5957
  if (id && id.length > 10) {
@@ -5925,7 +5960,7 @@ function getInstallId() {
5925
5960
  }
5926
5961
  }
5927
5962
  installId = randomUUID();
5928
- if (!existsSync3(dir)) mkdirSync3(dir, { recursive: true });
5963
+ if (!existsSync3(dir2)) mkdirSync3(dir2, { recursive: true });
5929
5964
  writeFileSync3(idFile, installId, "utf8");
5930
5965
  return installId;
5931
5966
  } catch {
@@ -6096,22 +6131,77 @@ function redactObject(input, _depth = 0) {
6096
6131
  return out;
6097
6132
  }
6098
6133
 
6099
- // src/host-sessions.ts
6134
+ // src/operator-prefs.ts
6100
6135
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync4 } from "fs";
6101
- import { join as join7 } from "path";
6102
6136
  import { homedir as homedir5 } from "os";
6103
- function storageDir() {
6137
+ import { join as join7 } from "path";
6138
+ function dir() {
6104
6139
  return join7(homedir5(), ".agenticmail");
6105
6140
  }
6141
+ function path() {
6142
+ return join7(dir(), "operator-prefs.json");
6143
+ }
6144
+ function readFile() {
6145
+ if (!existsSync4(path())) return { version: 1 };
6146
+ try {
6147
+ const raw = readFileSync3(path(), "utf-8");
6148
+ if (!raw.trim()) return { version: 1 };
6149
+ const parsed = JSON.parse(raw);
6150
+ return { version: 1, operatorEmail: typeof parsed.operatorEmail === "string" ? parsed.operatorEmail : void 0 };
6151
+ } catch {
6152
+ return { version: 1 };
6153
+ }
6154
+ }
6155
+ function writeFile(shape) {
6156
+ const d = dir();
6157
+ const p = path();
6158
+ if (!existsSync4(d)) mkdirSync4(d, { recursive: true });
6159
+ const tmp = `${p}.agenticmail-tmp-${process.pid}`;
6160
+ writeFileSync4(tmp, JSON.stringify(shape, null, 2), "utf-8");
6161
+ renameSync(tmp, p);
6162
+ }
6163
+ function getOperatorEmail() {
6164
+ const shape = readFile();
6165
+ const email = shape.operatorEmail;
6166
+ if (typeof email !== "string") return null;
6167
+ const trimmed = email.trim();
6168
+ return trimmed.length > 0 && trimmed.includes("@") ? trimmed : null;
6169
+ }
6170
+ function setOperatorEmail(email) {
6171
+ const shape = readFile();
6172
+ if (!email || !email.trim()) {
6173
+ delete shape.operatorEmail;
6174
+ writeFile(shape);
6175
+ return null;
6176
+ }
6177
+ const trimmed = email.trim();
6178
+ if (!trimmed.includes("@")) {
6179
+ throw new Error("operator email must contain an @");
6180
+ }
6181
+ shape.operatorEmail = trimmed;
6182
+ writeFile(shape);
6183
+ return trimmed;
6184
+ }
6185
+ function operatorPrefsStoragePath() {
6186
+ return path();
6187
+ }
6188
+
6189
+ // src/host-sessions.ts
6190
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync5 } from "fs";
6191
+ import { join as join8 } from "path";
6192
+ import { homedir as homedir6 } from "os";
6193
+ function storageDir() {
6194
+ return join8(homedir6(), ".agenticmail");
6195
+ }
6106
6196
  function storagePath() {
6107
- return join7(storageDir(), "host-sessions.json");
6197
+ return join8(storageDir(), "host-sessions.json");
6108
6198
  }
6109
6199
  var DEFAULT_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
6110
- function readFile() {
6200
+ function readFile2() {
6111
6201
  const p = storagePath();
6112
- if (!existsSync4(p)) return { version: 1, sessions: {} };
6202
+ if (!existsSync5(p)) return { version: 1, sessions: {} };
6113
6203
  try {
6114
- const raw = readFileSync3(p, "utf-8");
6204
+ const raw = readFileSync4(p, "utf-8");
6115
6205
  if (!raw.trim()) return { version: 1, sessions: {} };
6116
6206
  const parsed = JSON.parse(raw);
6117
6207
  return {
@@ -6122,28 +6212,28 @@ function readFile() {
6122
6212
  return { version: 1, sessions: {} };
6123
6213
  }
6124
6214
  }
6125
- function writeFile(shape) {
6126
- const dir = storageDir();
6215
+ function writeFile2(shape) {
6216
+ const dir2 = storageDir();
6127
6217
  const p = storagePath();
6128
- if (!existsSync4(dir)) mkdirSync4(dir, { recursive: true });
6218
+ if (!existsSync5(dir2)) mkdirSync5(dir2, { recursive: true });
6129
6219
  const tmp = `${p}.agenticmail-tmp-${process.pid}`;
6130
- writeFileSync4(tmp, JSON.stringify(shape, null, 2), "utf-8");
6131
- renameSync(tmp, p);
6220
+ writeFileSync5(tmp, JSON.stringify(shape, null, 2), "utf-8");
6221
+ renameSync2(tmp, p);
6132
6222
  }
6133
6223
  function saveHostSession(host, session) {
6134
6224
  if (!session.sessionId) return;
6135
6225
  try {
6136
- const shape = readFile();
6226
+ const shape = readFile2();
6137
6227
  shape.sessions[host] = {
6138
6228
  ...session,
6139
6229
  lastSeenMs: Date.now()
6140
6230
  };
6141
- writeFile(shape);
6231
+ writeFile2(shape);
6142
6232
  } catch {
6143
6233
  }
6144
6234
  }
6145
6235
  function loadHostSession(host, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
6146
- const shape = readFile();
6236
+ const shape = readFile2();
6147
6237
  const record = shape.sessions[host];
6148
6238
  if (!record) return null;
6149
6239
  if (!isSessionFresh(record, maxAgeMs)) return null;
@@ -6155,10 +6245,10 @@ function isSessionFresh(session, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
6155
6245
  }
6156
6246
  function forgetHostSession(host) {
6157
6247
  try {
6158
- const shape = readFile();
6248
+ const shape = readFile2();
6159
6249
  if (!shape.sessions[host]) return;
6160
6250
  delete shape.sessions[host];
6161
- writeFile(shape);
6251
+ writeFile2(shape);
6162
6252
  } catch {
6163
6253
  }
6164
6254
  }
@@ -6208,21 +6298,21 @@ function validateApiUrl(raw) {
6208
6298
  return parsed.origin;
6209
6299
  }
6210
6300
  function buildApiUrl(baseOrigin, pathAndQuery) {
6211
- const path = pathAndQuery.startsWith("/") ? pathAndQuery : `/${pathAndQuery}`;
6212
- return new URL(path, baseOrigin + "/").toString();
6301
+ const path2 = pathAndQuery.startsWith("/") ? pathAndQuery : `/${pathAndQuery}`;
6302
+ return new URL(path2, baseOrigin + "/").toString();
6213
6303
  }
6214
6304
 
6215
6305
  // src/setup/index.ts
6216
6306
  import { randomBytes as randomBytes3 } from "crypto";
6217
- import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, chmodSync as chmodSync2 } from "fs";
6218
- import { join as join11 } from "path";
6219
- import { homedir as homedir9 } from "os";
6307
+ import { existsSync as existsSync9, readFileSync as readFileSync6, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, chmodSync as chmodSync2 } from "fs";
6308
+ import { join as join12 } from "path";
6309
+ import { homedir as homedir10 } from "os";
6220
6310
 
6221
6311
  // src/setup/deps.ts
6222
6312
  import { execFileSync } from "child_process";
6223
- import { existsSync as existsSync5 } from "fs";
6224
- import { join as join8 } from "path";
6225
- import { homedir as homedir6 } from "os";
6313
+ import { existsSync as existsSync6 } from "fs";
6314
+ import { join as join9 } from "path";
6315
+ import { homedir as homedir7 } from "os";
6226
6316
  var DependencyChecker = class {
6227
6317
  async checkAll() {
6228
6318
  return Promise.all([
@@ -6272,8 +6362,8 @@ var DependencyChecker = class {
6272
6362
  }
6273
6363
  }
6274
6364
  async checkCloudflared() {
6275
- const binPath = join8(homedir6(), ".agenticmail", "bin", "cloudflared");
6276
- if (existsSync5(binPath)) {
6365
+ const binPath = join9(homedir7(), ".agenticmail", "bin", "cloudflared");
6366
+ if (existsSync6(binPath)) {
6277
6367
  let version;
6278
6368
  try {
6279
6369
  const output = execFileSync(binPath, ["--version"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
@@ -6295,10 +6385,10 @@ var DependencyChecker = class {
6295
6385
 
6296
6386
  // src/setup/installer.ts
6297
6387
  import { execFileSync as execFileSync2, execSync, spawn as spawnChild } from "child_process";
6298
- import { existsSync as existsSync6, mkdirSync as mkdirSync5, symlinkSync } from "fs";
6299
- import { writeFile as writeFile2, rename, chmod as chmod2, mkdir as mkdir2, unlink } from "fs/promises";
6300
- import { join as join9 } from "path";
6301
- import { homedir as homedir7, platform as platform3, arch as arch2 } from "os";
6388
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6, symlinkSync } from "fs";
6389
+ import { writeFile as writeFile3, rename, chmod as chmod2, mkdir as mkdir2, unlink } from "fs/promises";
6390
+ import { join as join10 } from "path";
6391
+ import { homedir as homedir8, platform as platform3, arch as arch2 } from "os";
6302
6392
  function runShellWithRollingOutput(cmd, opts = {}) {
6303
6393
  const maxLines = opts.maxLines ?? 20;
6304
6394
  const timeout = opts.timeout ?? 3e5;
@@ -6474,11 +6564,11 @@ var DependencyInstaller = class {
6474
6564
  try {
6475
6565
  const composeBin = execFileSync2("which", ["docker-compose"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
6476
6566
  if (!composeBin) return;
6477
- const pluginDir = join9(homedir7(), ".docker", "cli-plugins");
6478
- const pluginPath = join9(pluginDir, "docker-compose");
6479
- if (existsSync6(pluginPath)) return;
6567
+ const pluginDir = join10(homedir8(), ".docker", "cli-plugins");
6568
+ const pluginPath = join10(pluginDir, "docker-compose");
6569
+ if (existsSync7(pluginPath)) return;
6480
6570
  try {
6481
- mkdirSync5(pluginDir, { recursive: true });
6571
+ mkdirSync6(pluginDir, { recursive: true });
6482
6572
  } catch {
6483
6573
  }
6484
6574
  try {
@@ -6541,9 +6631,9 @@ var DependencyInstaller = class {
6541
6631
  return;
6542
6632
  }
6543
6633
  this.onProgress("__progress__:5:Installing Docker Engine...");
6544
- const tmpDir = join9(homedir7(), ".agenticmail", "tmp");
6634
+ const tmpDir = join10(homedir8(), ".agenticmail", "tmp");
6545
6635
  await mkdir2(tmpDir, { recursive: true });
6546
- const scriptPath = join9(tmpDir, "install-docker.sh");
6636
+ const scriptPath = join10(tmpDir, "install-docker.sh");
6547
6637
  const dlResult = await runShellWithRollingOutput(
6548
6638
  `curl -fsSL https://get.docker.com -o "${scriptPath}" && sudo sh "${scriptPath}"`,
6549
6639
  { timeout: 3e5 }
@@ -6611,8 +6701,8 @@ var DependencyInstaller = class {
6611
6701
  }
6612
6702
  try {
6613
6703
  const programFiles = process.env["ProgramFiles"] || "C:\\Program Files";
6614
- const dockerExe = join9(programFiles, "Docker", "Docker", "Docker Desktop.exe");
6615
- if (existsSync6(dockerExe)) {
6704
+ const dockerExe = join10(programFiles, "Docker", "Docker", "Docker Desktop.exe");
6705
+ if (existsSync7(dockerExe)) {
6616
6706
  execSync(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
6617
6707
  }
6618
6708
  } catch {
@@ -6662,8 +6752,8 @@ var DependencyInstaller = class {
6662
6752
  this.onProgress("__progress__:70:Docker Desktop installed. Starting...");
6663
6753
  try {
6664
6754
  const programFiles = process.env["ProgramFiles"] || "C:\\Program Files";
6665
- const dockerExe = join9(programFiles, "Docker", "Docker", "Docker Desktop.exe");
6666
- if (existsSync6(dockerExe)) {
6755
+ const dockerExe = join10(programFiles, "Docker", "Docker", "Docker Desktop.exe");
6756
+ if (existsSync7(dockerExe)) {
6667
6757
  execSync(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
6668
6758
  }
6669
6759
  } catch {
@@ -6700,7 +6790,7 @@ var DependencyInstaller = class {
6700
6790
  * Start the Stalwart mail server Docker container.
6701
6791
  */
6702
6792
  async startStalwart(composePath) {
6703
- if (!existsSync6(composePath)) {
6793
+ if (!existsSync7(composePath)) {
6704
6794
  throw new Error(`docker-compose.yml not found at: ${composePath}`);
6705
6795
  }
6706
6796
  if (!this.isDockerReady()) {
@@ -6759,16 +6849,16 @@ var DependencyInstaller = class {
6759
6849
  */
6760
6850
  async installCloudflared() {
6761
6851
  const os = platform3();
6762
- const binDir = join9(homedir7(), ".agenticmail", "bin");
6852
+ const binDir = join10(homedir8(), ".agenticmail", "bin");
6763
6853
  const binName = os === "win32" ? "cloudflared.exe" : "cloudflared";
6764
- const binPath = join9(binDir, binName);
6765
- if (existsSync6(binPath)) {
6854
+ const binPath = join10(binDir, binName);
6855
+ if (existsSync7(binPath)) {
6766
6856
  return binPath;
6767
6857
  }
6768
6858
  try {
6769
6859
  const whichCmd = os === "win32" ? "where" : "which";
6770
6860
  const sysPath = execFileSync2(whichCmd, ["cloudflared"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim().split("\n")[0];
6771
- if (sysPath && existsSync6(sysPath)) return sysPath;
6861
+ if (sysPath && existsSync7(sysPath)) return sysPath;
6772
6862
  } catch {
6773
6863
  }
6774
6864
  this.onProgress("Downloading cloudflared...");
@@ -6791,8 +6881,8 @@ var DependencyInstaller = class {
6791
6881
  }
6792
6882
  const buffer = Buffer.from(await response.arrayBuffer());
6793
6883
  if (os === "darwin") {
6794
- const tgzPath = join9(binDir, "cloudflared.tgz");
6795
- await writeFile2(tgzPath, buffer);
6884
+ const tgzPath = join10(binDir, "cloudflared.tgz");
6885
+ await writeFile3(tgzPath, buffer);
6796
6886
  try {
6797
6887
  execFileSync2("tar", ["-xzf", tgzPath, "-C", binDir, "cloudflared"], { timeout: 15e3, stdio: "ignore" });
6798
6888
  await chmod2(binPath, 493);
@@ -6804,11 +6894,11 @@ var DependencyInstaller = class {
6804
6894
  }
6805
6895
  } else {
6806
6896
  const tmpPath = binPath + ".tmp";
6807
- await writeFile2(tmpPath, buffer);
6897
+ await writeFile3(tmpPath, buffer);
6808
6898
  if (os !== "win32") await chmod2(tmpPath, 493);
6809
6899
  await rename(tmpPath, binPath);
6810
6900
  }
6811
- if (!existsSync6(binPath)) {
6901
+ if (!existsSync7(binPath)) {
6812
6902
  throw new Error("cloudflared download succeeded but binary not found after extraction");
6813
6903
  }
6814
6904
  this.onProgress("cloudflared installed");
@@ -6826,9 +6916,9 @@ var DependencyInstaller = class {
6826
6916
 
6827
6917
  // src/setup/service.ts
6828
6918
  import { execFileSync as execFileSync3, execSync as execSync2 } from "child_process";
6829
- import { existsSync as existsSync7, readFileSync as readFileSync4, writeFileSync as writeFileSync5, unlinkSync, mkdirSync as mkdirSync6, chmodSync } from "fs";
6830
- import { join as join10 } from "path";
6831
- import { homedir as homedir8, platform as platform4 } from "os";
6919
+ import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync6, unlinkSync, mkdirSync as mkdirSync7, chmodSync } from "fs";
6920
+ import { join as join11 } from "path";
6921
+ import { homedir as homedir9, platform as platform4 } from "os";
6832
6922
  import { createRequire as createRequire2 } from "module";
6833
6923
  var PLIST_LABEL = "com.agenticmail.server";
6834
6924
  var SYSTEMD_UNIT = "agenticmail.service";
@@ -6839,9 +6929,9 @@ var ServiceManager = class {
6839
6929
  */
6840
6930
  getServicePath() {
6841
6931
  if (this.os === "darwin") {
6842
- return join10(homedir8(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
6932
+ return join11(homedir9(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
6843
6933
  } else {
6844
- return join10(homedir8(), ".config", "systemd", "user", SYSTEMD_UNIT);
6934
+ return join11(homedir9(), ".config", "systemd", "user", SYSTEMD_UNIT);
6845
6935
  }
6846
6936
  }
6847
6937
  /**
@@ -6875,40 +6965,40 @@ var ServiceManager = class {
6875
6965
  try {
6876
6966
  const req = createRequire2(import.meta.url);
6877
6967
  const resolved = req.resolve("@agenticmail/api");
6878
- if (existsSync7(resolved)) return resolved;
6968
+ if (existsSync8(resolved)) return resolved;
6879
6969
  } catch {
6880
6970
  }
6881
6971
  const parentPackages = [
6882
- join10("@agenticmail", "cli"),
6972
+ join11("@agenticmail", "cli"),
6883
6973
  // current scoped package
6884
6974
  "agenticmail"
6885
6975
  // legacy unscoped package
6886
6976
  ];
6887
6977
  const baseDirs = [
6888
6978
  // user-local install
6889
- join10(homedir8(), "node_modules")
6979
+ join11(homedir9(), "node_modules")
6890
6980
  ];
6891
6981
  try {
6892
6982
  const prefix = execSync2("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
6893
- baseDirs.push(join10(prefix, "lib", "node_modules"));
6894
- baseDirs.push(join10(prefix, "node_modules"));
6983
+ baseDirs.push(join11(prefix, "lib", "node_modules"));
6984
+ baseDirs.push(join11(prefix, "node_modules"));
6895
6985
  } catch {
6896
6986
  }
6897
6987
  baseDirs.push("/opt/homebrew/lib/node_modules");
6898
6988
  baseDirs.push("/usr/local/lib/node_modules");
6899
6989
  for (const base of baseDirs) {
6900
- const sibling = join10(base, "@agenticmail", "api", "dist", "index.js");
6901
- if (existsSync7(sibling)) return sibling;
6990
+ const sibling = join11(base, "@agenticmail", "api", "dist", "index.js");
6991
+ if (existsSync8(sibling)) return sibling;
6902
6992
  for (const parent of parentPackages) {
6903
- const nested = join10(base, parent, "node_modules", "@agenticmail", "api", "dist", "index.js");
6904
- if (existsSync7(nested)) return nested;
6993
+ const nested = join11(base, parent, "node_modules", "@agenticmail", "api", "dist", "index.js");
6994
+ if (existsSync8(nested)) return nested;
6905
6995
  }
6906
6996
  }
6907
- const dataDir = join10(homedir8(), ".agenticmail");
6908
- const entryCache = join10(dataDir, "api-entry.path");
6909
- if (existsSync7(entryCache)) {
6910
- const cached = readFileSync4(entryCache, "utf-8").trim();
6911
- if (cached && existsSync7(cached)) return cached;
6997
+ const dataDir = join11(homedir9(), ".agenticmail");
6998
+ const entryCache = join11(dataDir, "api-entry.path");
6999
+ if (existsSync8(entryCache)) {
7000
+ const cached = readFileSync5(entryCache, "utf-8").trim();
7001
+ if (cached && existsSync8(cached)) return cached;
6912
7002
  }
6913
7003
  throw new Error("Could not find @agenticmail/api entry point. Run `agenticmail start` first to populate the cache.");
6914
7004
  }
@@ -6916,9 +7006,9 @@ var ServiceManager = class {
6916
7006
  * Cache the API entry path so the service can find it later.
6917
7007
  */
6918
7008
  cacheApiEntryPath(entryPath) {
6919
- const dataDir = join10(homedir8(), ".agenticmail");
6920
- if (!existsSync7(dataDir)) mkdirSync6(dataDir, { recursive: true });
6921
- writeFileSync5(join10(dataDir, "api-entry.path"), entryPath);
7009
+ const dataDir = join11(homedir9(), ".agenticmail");
7010
+ if (!existsSync8(dataDir)) mkdirSync7(dataDir, { recursive: true });
7011
+ writeFileSync6(join11(dataDir, "api-entry.path"), entryPath);
6922
7012
  }
6923
7013
  /**
6924
7014
  * Get the current package version.
@@ -6931,36 +7021,36 @@ var ServiceManager = class {
6931
7021
  try {
6932
7022
  const req = createRequire2(import.meta.url);
6933
7023
  const pkgJson = req.resolve("@agenticmail/cli/package.json");
6934
- if (existsSync7(pkgJson)) {
6935
- const pkg = JSON.parse(readFileSync4(pkgJson, "utf-8"));
7024
+ if (existsSync8(pkgJson)) {
7025
+ const pkg = JSON.parse(readFileSync5(pkgJson, "utf-8"));
6936
7026
  if (pkg.version) return pkg.version;
6937
7027
  }
6938
7028
  } catch {
6939
7029
  }
6940
7030
  try {
6941
7031
  const apiEntry = this.getApiEntryPath();
6942
- const apiPkg = join10(apiEntry, "..", "..", "package.json");
6943
- if (existsSync7(apiPkg)) {
6944
- const pkg = JSON.parse(readFileSync4(apiPkg, "utf-8"));
7032
+ const apiPkg = join11(apiEntry, "..", "..", "package.json");
7033
+ if (existsSync8(apiPkg)) {
7034
+ const pkg = JSON.parse(readFileSync5(apiPkg, "utf-8"));
6945
7035
  if (pkg.version) return pkg.version;
6946
7036
  }
6947
7037
  } catch {
6948
7038
  }
6949
7039
  const candidates = [
6950
- join10(homedir8(), "node_modules", "@agenticmail", "cli", "package.json"),
6951
- join10(homedir8(), "node_modules", "agenticmail", "package.json"),
6952
- join10(homedir8(), ".agenticmail", "package-version.json")
7040
+ join11(homedir9(), "node_modules", "@agenticmail", "cli", "package.json"),
7041
+ join11(homedir9(), "node_modules", "agenticmail", "package.json"),
7042
+ join11(homedir9(), ".agenticmail", "package-version.json")
6953
7043
  ];
6954
7044
  try {
6955
7045
  const prefix = execSync2("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
6956
- candidates.push(join10(prefix, "lib", "node_modules", "@agenticmail", "cli", "package.json"));
6957
- candidates.push(join10(prefix, "lib", "node_modules", "agenticmail", "package.json"));
7046
+ candidates.push(join11(prefix, "lib", "node_modules", "@agenticmail", "cli", "package.json"));
7047
+ candidates.push(join11(prefix, "lib", "node_modules", "agenticmail", "package.json"));
6958
7048
  } catch {
6959
7049
  }
6960
7050
  for (const p of candidates) {
6961
7051
  try {
6962
- if (existsSync7(p)) {
6963
- const pkg = JSON.parse(readFileSync4(p, "utf-8"));
7052
+ if (existsSync8(p)) {
7053
+ const pkg = JSON.parse(readFileSync5(p, "utf-8"));
6964
7054
  if (pkg.version) return pkg.version;
6965
7055
  }
6966
7056
  } catch {
@@ -6973,9 +7063,9 @@ var ServiceManager = class {
6973
7063
  * This ensures AgenticMail doesn't fail on boot when Docker is still loading.
6974
7064
  */
6975
7065
  generateStartScript(nodePath, apiEntry) {
6976
- const scriptPath = join10(homedir8(), ".agenticmail", "bin", "start-server.sh");
6977
- const scriptDir = join10(homedir8(), ".agenticmail", "bin");
6978
- if (!existsSync7(scriptDir)) mkdirSync6(scriptDir, { recursive: true });
7066
+ const scriptPath = join11(homedir9(), ".agenticmail", "bin", "start-server.sh");
7067
+ const scriptDir = join11(homedir9(), ".agenticmail", "bin");
7068
+ if (!existsSync8(scriptDir)) mkdirSync7(scriptDir, { recursive: true });
6979
7069
  const script = [
6980
7070
  "#!/bin/bash",
6981
7071
  "# AgenticMail auto-start script",
@@ -7026,7 +7116,7 @@ var ServiceManager = class {
7026
7116
  `log "Starting API server: ${nodePath} ${apiEntry}"`,
7027
7117
  `exec "${nodePath}" "${apiEntry}"`
7028
7118
  ].join("\n") + "\n";
7029
- writeFileSync5(scriptPath, script, { mode: 493 });
7119
+ writeFileSync6(scriptPath, script, { mode: 493 });
7030
7120
  return scriptPath;
7031
7121
  }
7032
7122
  /**
@@ -7039,9 +7129,9 @@ var ServiceManager = class {
7039
7129
  * - Service version tracking in env vars
7040
7130
  */
7041
7131
  generatePlist(nodePath, apiEntry, configPath) {
7042
- const config = JSON.parse(readFileSync4(configPath, "utf-8"));
7043
- const logDir = join10(homedir8(), ".agenticmail", "logs");
7044
- if (!existsSync7(logDir)) mkdirSync6(logDir, { recursive: true });
7132
+ const config = JSON.parse(readFileSync5(configPath, "utf-8"));
7133
+ const logDir = join11(homedir9(), ".agenticmail", "logs");
7134
+ if (!existsSync8(logDir)) mkdirSync7(logDir, { recursive: true });
7045
7135
  const version = this.getVersion();
7046
7136
  const startScript = this.generateStartScript(nodePath, apiEntry);
7047
7137
  return `<?xml version="1.0" encoding="UTF-8"?>
@@ -7062,9 +7152,9 @@ var ServiceManager = class {
7062
7152
  <key>EnvironmentVariables</key>
7063
7153
  <dict>
7064
7154
  <key>HOME</key>
7065
- <string>${homedir8()}</string>
7155
+ <string>${homedir9()}</string>
7066
7156
  <key>AGENTICMAIL_DATA_DIR</key>
7067
- <string>${config.dataDir || join10(homedir8(), ".agenticmail")}</string>
7157
+ <string>${config.dataDir || join11(homedir9(), ".agenticmail")}</string>
7068
7158
  <key>PATH</key>
7069
7159
  <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
7070
7160
  <key>AGENTICMAIL_SERVICE_VERSION</key>
@@ -7117,8 +7207,8 @@ var ServiceManager = class {
7117
7207
  * - Proper dependency ordering
7118
7208
  */
7119
7209
  generateSystemdUnit(nodePath, apiEntry, configPath) {
7120
- const config = JSON.parse(readFileSync4(configPath, "utf-8"));
7121
- const dataDir = config.dataDir || join10(homedir8(), ".agenticmail");
7210
+ const config = JSON.parse(readFileSync5(configPath, "utf-8"));
7211
+ const dataDir = config.dataDir || join11(homedir9(), ".agenticmail");
7122
7212
  const version = this.getVersion();
7123
7213
  const startScript = this.generateStartScript(nodePath, apiEntry);
7124
7214
  return `[Unit]
@@ -7135,7 +7225,7 @@ Restart=always
7135
7225
  RestartSec=15
7136
7226
  TimeoutStartSec=660
7137
7227
  LimitNOFILE=8192
7138
- Environment=HOME=${homedir8()}
7228
+ Environment=HOME=${homedir9()}
7139
7229
  Environment=AGENTICMAIL_DATA_DIR=${dataDir}
7140
7230
  Environment=PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin
7141
7231
  Environment=AGENTICMAIL_SERVICE_VERSION=${version}
@@ -7148,8 +7238,8 @@ WantedBy=default.target
7148
7238
  * Install the auto-start service.
7149
7239
  */
7150
7240
  install() {
7151
- const configPath = join10(homedir8(), ".agenticmail", "config.json");
7152
- if (!existsSync7(configPath)) {
7241
+ const configPath = join11(homedir9(), ".agenticmail", "config.json");
7242
+ if (!existsSync8(configPath)) {
7153
7243
  return { installed: false, message: "Config not found. Run agenticmail setup first." };
7154
7244
  }
7155
7245
  const nodePath = this.getNodePath();
@@ -7161,16 +7251,16 @@ WantedBy=default.target
7161
7251
  }
7162
7252
  const servicePath = this.getServicePath();
7163
7253
  if (this.os === "darwin") {
7164
- const dir = join10(homedir8(), "Library", "LaunchAgents");
7165
- if (!existsSync7(dir)) mkdirSync6(dir, { recursive: true });
7166
- if (existsSync7(servicePath)) {
7254
+ const dir2 = join11(homedir9(), "Library", "LaunchAgents");
7255
+ if (!existsSync8(dir2)) mkdirSync7(dir2, { recursive: true });
7256
+ if (existsSync8(servicePath)) {
7167
7257
  try {
7168
7258
  execFileSync3("launchctl", ["unload", servicePath], { timeout: 1e4, stdio: "ignore" });
7169
7259
  } catch {
7170
7260
  }
7171
7261
  }
7172
7262
  const plist = this.generatePlist(nodePath, apiEntry, configPath);
7173
- writeFileSync5(servicePath, plist);
7263
+ writeFileSync6(servicePath, plist);
7174
7264
  chmodSync(servicePath, 384);
7175
7265
  try {
7176
7266
  execFileSync3("launchctl", ["load", servicePath], { timeout: 1e4, stdio: "ignore" });
@@ -7179,10 +7269,10 @@ WantedBy=default.target
7179
7269
  }
7180
7270
  return { installed: true, message: `Service installed at ${servicePath}` };
7181
7271
  } else if (this.os === "linux") {
7182
- const dir = join10(homedir8(), ".config", "systemd", "user");
7183
- if (!existsSync7(dir)) mkdirSync6(dir, { recursive: true });
7272
+ const dir2 = join11(homedir9(), ".config", "systemd", "user");
7273
+ if (!existsSync8(dir2)) mkdirSync7(dir2, { recursive: true });
7184
7274
  const unit = this.generateSystemdUnit(nodePath, apiEntry, configPath);
7185
- writeFileSync5(servicePath, unit);
7275
+ writeFileSync6(servicePath, unit);
7186
7276
  chmodSync(servicePath, 384);
7187
7277
  try {
7188
7278
  execFileSync3("systemctl", ["--user", "daemon-reload"], { timeout: 1e4, stdio: "ignore" });
@@ -7205,7 +7295,7 @@ WantedBy=default.target
7205
7295
  */
7206
7296
  uninstall() {
7207
7297
  const servicePath = this.getServicePath();
7208
- if (!existsSync7(servicePath)) {
7298
+ if (!existsSync8(servicePath)) {
7209
7299
  return { removed: false, message: "Service is not installed." };
7210
7300
  }
7211
7301
  if (this.os === "darwin") {
@@ -7243,7 +7333,7 @@ WantedBy=default.target
7243
7333
  status() {
7244
7334
  const servicePath = this.getServicePath();
7245
7335
  const plat = this.os === "darwin" ? "launchd" : this.os === "linux" ? "systemd" : "unsupported";
7246
- const installed = existsSync7(servicePath);
7336
+ const installed = existsSync8(servicePath);
7247
7337
  let running = false;
7248
7338
  if (installed) {
7249
7339
  if (this.os === "darwin") {
@@ -7298,34 +7388,34 @@ WantedBy=default.target
7298
7388
  needsRepair() {
7299
7389
  if (this.os !== "darwin" && this.os !== "linux") return null;
7300
7390
  const servicePath = this.getServicePath();
7301
- if (!existsSync7(servicePath)) return null;
7391
+ if (!existsSync8(servicePath)) return null;
7302
7392
  let serviceContent = "";
7303
7393
  try {
7304
- serviceContent = readFileSync4(servicePath, "utf-8");
7394
+ serviceContent = readFileSync5(servicePath, "utf-8");
7305
7395
  } catch {
7306
7396
  return { reason: "Service file unreadable" };
7307
7397
  }
7308
- const startScript = join10(homedir8(), ".agenticmail", "bin", "start-server.sh");
7398
+ const startScript = join11(homedir9(), ".agenticmail", "bin", "start-server.sh");
7309
7399
  if (serviceContent.includes(startScript)) {
7310
- if (!existsSync7(startScript)) {
7400
+ if (!existsSync8(startScript)) {
7311
7401
  return { reason: "start-server.sh is missing" };
7312
7402
  }
7313
7403
  let scriptContent = "";
7314
7404
  try {
7315
- scriptContent = readFileSync4(startScript, "utf-8");
7405
+ scriptContent = readFileSync5(startScript, "utf-8");
7316
7406
  } catch {
7317
7407
  return { reason: "start-server.sh unreadable" };
7318
7408
  }
7319
7409
  const apiPathMatch = scriptContent.match(/(\/[^"\s]+@agenticmail\/api\/dist\/index\.js)/);
7320
7410
  if (apiPathMatch) {
7321
7411
  const referenced = apiPathMatch[1];
7322
- if (!existsSync7(referenced)) {
7412
+ if (!existsSync8(referenced)) {
7323
7413
  return { reason: `start-server.sh references missing path: ${referenced}` };
7324
7414
  }
7325
7415
  }
7326
7416
  if (/node_modules\/agenticmail\/(?!.*@agenticmail\/cli)/.test(scriptContent)) {
7327
7417
  const stale = /(\S*node_modules\/agenticmail\/\S*)/.exec(scriptContent)?.[1];
7328
- if (stale && !existsSync7(stale)) {
7418
+ if (stale && !existsSync8(stale)) {
7329
7419
  return { reason: `start-server.sh references legacy unscoped path: ${stale}` };
7330
7420
  }
7331
7421
  }
@@ -7338,11 +7428,11 @@ WantedBy=default.target
7338
7428
  return { reason: `Service version drift (current CLI is v${currentVersion})` };
7339
7429
  }
7340
7430
  }
7341
- const entryCache = join10(homedir8(), ".agenticmail", "api-entry.path");
7342
- if (existsSync7(entryCache)) {
7431
+ const entryCache = join11(homedir9(), ".agenticmail", "api-entry.path");
7432
+ if (existsSync8(entryCache)) {
7343
7433
  try {
7344
- const cached = readFileSync4(entryCache, "utf-8").trim();
7345
- if (cached && !existsSync7(cached)) {
7434
+ const cached = readFileSync5(entryCache, "utf-8").trim();
7435
+ if (cached && !existsSync8(cached)) {
7346
7436
  return { reason: `Cached API entry path no longer exists: ${cached}` };
7347
7437
  }
7348
7438
  } catch {
@@ -7381,8 +7471,8 @@ var SetupManager = class {
7381
7471
  async ensureStalwart(composePath) {
7382
7472
  const status = await this.checker.checkStalwart();
7383
7473
  if (status.installed) return;
7384
- const path = composePath ?? this.getComposePath();
7385
- await this.installer.startStalwart(path);
7474
+ const path2 = composePath ?? this.getComposePath();
7475
+ await this.installer.startStalwart(path2);
7386
7476
  }
7387
7477
  async ensureCloudflared() {
7388
7478
  return this.installer.installCloudflared();
@@ -7393,13 +7483,13 @@ var SetupManager = class {
7393
7483
  * falls back to monorepo location.
7394
7484
  */
7395
7485
  getComposePath() {
7396
- const standalonePath = join11(homedir9(), ".agenticmail", "docker-compose.yml");
7397
- if (existsSync8(standalonePath)) return standalonePath;
7486
+ const standalonePath = join12(homedir10(), ".agenticmail", "docker-compose.yml");
7487
+ if (existsSync9(standalonePath)) return standalonePath;
7398
7488
  const cwd = process.cwd();
7399
- const candidates = [cwd, join11(cwd, "..")];
7400
- for (const dir of candidates) {
7401
- const p = join11(dir, "docker-compose.yml");
7402
- if (existsSync8(p)) return p;
7489
+ const candidates = [cwd, join12(cwd, "..")];
7490
+ for (const dir2 of candidates) {
7491
+ const p = join12(dir2, "docker-compose.yml");
7492
+ if (existsSync9(p)) return p;
7403
7493
  }
7404
7494
  return standalonePath;
7405
7495
  }
@@ -7409,19 +7499,19 @@ var SetupManager = class {
7409
7499
  * Always regenerates Docker files to keep passwords in sync.
7410
7500
  */
7411
7501
  initConfig() {
7412
- const dataDir = join11(homedir9(), ".agenticmail");
7413
- const configPath = join11(dataDir, "config.json");
7414
- const envPath = join11(dataDir, ".env");
7415
- if (existsSync8(configPath)) {
7502
+ const dataDir = join12(homedir10(), ".agenticmail");
7503
+ const configPath = join12(dataDir, "config.json");
7504
+ const envPath = join12(dataDir, ".env");
7505
+ if (existsSync9(configPath)) {
7416
7506
  try {
7417
- const existing = JSON.parse(readFileSync5(configPath, "utf-8"));
7507
+ const existing = JSON.parse(readFileSync6(configPath, "utf-8"));
7418
7508
  this.generateDockerFiles(existing);
7419
7509
  return { configPath, envPath, config: existing, isNew: false };
7420
7510
  } catch {
7421
7511
  }
7422
7512
  }
7423
- if (!existsSync8(dataDir)) {
7424
- mkdirSync7(dataDir, { recursive: true });
7513
+ if (!existsSync9(dataDir)) {
7514
+ mkdirSync8(dataDir, { recursive: true });
7425
7515
  }
7426
7516
  const masterKey = `mk_${randomBytes3(24).toString("hex")}`;
7427
7517
  const stalwartPassword = randomBytes3(16).toString("hex");
@@ -7437,7 +7527,7 @@ var SetupManager = class {
7437
7527
  api: { port: 3829, host: "127.0.0.1" },
7438
7528
  dataDir
7439
7529
  };
7440
- writeFileSync6(configPath, JSON.stringify(config, null, 2));
7530
+ writeFileSync7(configPath, JSON.stringify(config, null, 2));
7441
7531
  chmodSync2(configPath, 384);
7442
7532
  const envContent = `# Auto-generated by agenticmail setup
7443
7533
  STALWART_ADMIN_USER=admin
@@ -7453,7 +7543,7 @@ SMTP_PORT=587
7453
7543
  IMAP_HOST=localhost
7454
7544
  IMAP_PORT=143
7455
7545
  `;
7456
- writeFileSync6(envPath, envContent);
7546
+ writeFileSync7(envPath, envContent);
7457
7547
  chmodSync2(envPath, 384);
7458
7548
  this.generateDockerFiles(config);
7459
7549
  return { configPath, envPath, config, isNew: true };
@@ -7463,13 +7553,13 @@ IMAP_PORT=143
7463
7553
  * with the correct admin password from config.
7464
7554
  */
7465
7555
  generateDockerFiles(config) {
7466
- const dataDir = config.dataDir || join11(homedir9(), ".agenticmail");
7467
- if (!existsSync8(dataDir)) {
7468
- mkdirSync7(dataDir, { recursive: true });
7556
+ const dataDir = config.dataDir || join12(homedir10(), ".agenticmail");
7557
+ if (!existsSync9(dataDir)) {
7558
+ mkdirSync8(dataDir, { recursive: true });
7469
7559
  }
7470
7560
  const password = config.stalwart?.adminPassword || "changeme";
7471
- const composePath = join11(dataDir, "docker-compose.yml");
7472
- writeFileSync6(composePath, `services:
7561
+ const composePath = join12(dataDir, "docker-compose.yml");
7562
+ writeFileSync7(composePath, `services:
7473
7563
  stalwart:
7474
7564
  # Pinned to v0.15.5 \u2014 Stalwart 0.16+ moved its config to JSON
7475
7565
  # at /etc/stalwart/config.json (hardcoded into the container
@@ -7499,8 +7589,8 @@ volumes:
7499
7589
  stalwart-data:
7500
7590
  `);
7501
7591
  chmodSync2(composePath, 384);
7502
- const tomlPath = join11(dataDir, "stalwart.toml");
7503
- writeFileSync6(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
7592
+ const tomlPath = join12(dataDir, "stalwart.toml");
7593
+ writeFileSync7(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
7504
7594
 
7505
7595
  [server]
7506
7596
  hostname = "localhost"
@@ -7556,8 +7646,8 @@ secret = "${password}"
7556
7646
  * Check if config has already been initialized.
7557
7647
  */
7558
7648
  isInitialized() {
7559
- const configPath = join11(homedir9(), ".agenticmail", "config.json");
7560
- return existsSync8(configPath);
7649
+ const configPath = join12(homedir10(), ".agenticmail", "config.json");
7650
+ return existsSync9(configPath);
7561
7651
  }
7562
7652
  };
7563
7653
 
@@ -7596,18 +7686,18 @@ function threadIdFor(input) {
7596
7686
 
7597
7687
  // src/threading/thread-cache.ts
7598
7688
  import {
7599
- existsSync as existsSync9,
7600
- mkdirSync as mkdirSync8,
7601
- readFileSync as readFileSync6,
7602
- writeFileSync as writeFileSync7,
7689
+ existsSync as existsSync10,
7690
+ mkdirSync as mkdirSync9,
7691
+ readFileSync as readFileSync7,
7692
+ writeFileSync as writeFileSync8,
7603
7693
  readdirSync,
7604
7694
  statSync,
7605
7695
  rmSync,
7606
- renameSync as renameSync2
7696
+ renameSync as renameSync3
7607
7697
  } from "fs";
7608
- import { homedir as homedir10 } from "os";
7609
- import { join as join12 } from "path";
7610
- var CACHE_DIR_DEFAULT = join12(homedir10(), ".agenticmail", "thread-cache");
7698
+ import { homedir as homedir11 } from "os";
7699
+ import { join as join13 } from "path";
7700
+ var CACHE_DIR_DEFAULT = join13(homedir11(), ".agenticmail", "thread-cache");
7611
7701
  var DEFAULT_K_MESSAGES = 10;
7612
7702
  var DEFAULT_LRU_CAP = 5e3;
7613
7703
  var PREVIEW_MAX_CHARS = 240;
@@ -7620,18 +7710,18 @@ var ThreadCache = class {
7620
7710
  this.k = opts.k ?? DEFAULT_K_MESSAGES;
7621
7711
  this.lruCap = opts.lruCap ?? DEFAULT_LRU_CAP;
7622
7712
  try {
7623
- mkdirSync8(this.dir, { recursive: true });
7713
+ mkdirSync9(this.dir, { recursive: true });
7624
7714
  } catch {
7625
7715
  }
7626
7716
  }
7627
7717
  pathFor(threadId) {
7628
- return join12(this.dir, `${threadId}.json`);
7718
+ return join13(this.dir, `${threadId}.json`);
7629
7719
  }
7630
7720
  read(threadId) {
7631
7721
  const p = this.pathFor(threadId);
7632
- if (!existsSync9(p)) return null;
7722
+ if (!existsSync10(p)) return null;
7633
7723
  try {
7634
- const raw = readFileSync6(p, "utf-8");
7724
+ const raw = readFileSync7(p, "utf-8");
7635
7725
  return JSON.parse(raw);
7636
7726
  } catch {
7637
7727
  try {
@@ -7696,8 +7786,8 @@ var ThreadCache = class {
7696
7786
  writeAtomic(threadId, entry) {
7697
7787
  const p = this.pathFor(threadId);
7698
7788
  const tmp = `${p}.tmp`;
7699
- writeFileSync7(tmp, JSON.stringify(entry), "utf-8");
7700
- renameSync2(tmp, p);
7789
+ writeFileSync8(tmp, JSON.stringify(entry), "utf-8");
7790
+ renameSync3(tmp, p);
7701
7791
  }
7702
7792
  /**
7703
7793
  * Best-effort LRU eviction. Runs at most every 256 writes (we
@@ -7715,7 +7805,7 @@ var ThreadCache = class {
7715
7805
  }
7716
7806
  if (files.length <= this.lruCap) return;
7717
7807
  const stats = files.map((f) => {
7718
- const p = join12(this.dir, f);
7808
+ const p = join13(this.dir, f);
7719
7809
  try {
7720
7810
  return { p, mtime: statSync(p).mtimeMs };
7721
7811
  } catch {
@@ -7746,36 +7836,36 @@ function dedupAndCap(messages, k) {
7746
7836
 
7747
7837
  // src/threading/agent-memory.ts
7748
7838
  import {
7749
- existsSync as existsSync10,
7750
- mkdirSync as mkdirSync9,
7751
- readFileSync as readFileSync7,
7752
- writeFileSync as writeFileSync8,
7839
+ existsSync as existsSync11,
7840
+ mkdirSync as mkdirSync10,
7841
+ readFileSync as readFileSync8,
7842
+ writeFileSync as writeFileSync9,
7753
7843
  rmSync as rmSync2,
7754
- renameSync as renameSync3
7844
+ renameSync as renameSync4
7755
7845
  } from "fs";
7756
- import { homedir as homedir11 } from "os";
7757
- import { join as join13 } from "path";
7758
- var MEMORY_DIR_DEFAULT = join13(homedir11(), ".agenticmail", "agent-memory");
7846
+ import { homedir as homedir12 } from "os";
7847
+ import { join as join14 } from "path";
7848
+ var MEMORY_DIR_DEFAULT = join14(homedir12(), ".agenticmail", "agent-memory");
7759
7849
  var AgentMemoryStore = class {
7760
7850
  dir;
7761
7851
  constructor(opts = {}) {
7762
7852
  this.dir = opts.memoryDir ?? MEMORY_DIR_DEFAULT;
7763
7853
  try {
7764
- mkdirSync9(this.dir, { recursive: true });
7854
+ mkdirSync10(this.dir, { recursive: true });
7765
7855
  } catch {
7766
7856
  }
7767
7857
  }
7768
7858
  dirFor(agentId) {
7769
- return join13(this.dir, sanitizeId(agentId));
7859
+ return join14(this.dir, sanitizeId(agentId));
7770
7860
  }
7771
7861
  pathFor(agentId, threadId) {
7772
- return join13(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
7862
+ return join14(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
7773
7863
  }
7774
7864
  read(agentId, threadId) {
7775
7865
  const p = this.pathFor(agentId, threadId);
7776
- if (!existsSync10(p)) return null;
7866
+ if (!existsSync11(p)) return null;
7777
7867
  try {
7778
- const raw = readFileSync7(p, "utf-8");
7868
+ const raw = readFileSync8(p, "utf-8");
7779
7869
  const parsed = parse(raw);
7780
7870
  return { ...parsed, raw };
7781
7871
  } catch {
@@ -7785,14 +7875,14 @@ var AgentMemoryStore = class {
7785
7875
  write(agentId, threadId, fields) {
7786
7876
  const agentDir = this.dirFor(agentId);
7787
7877
  try {
7788
- mkdirSync9(agentDir, { recursive: true });
7878
+ mkdirSync10(agentDir, { recursive: true });
7789
7879
  } catch {
7790
7880
  }
7791
7881
  const body = render({ ...fields, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
7792
7882
  const p = this.pathFor(agentId, threadId);
7793
7883
  const tmp = `${p}.tmp`;
7794
- writeFileSync8(tmp, body, "utf-8");
7795
- renameSync3(tmp, p);
7884
+ writeFileSync9(tmp, body, "utf-8");
7885
+ renameSync4(tmp, p);
7796
7886
  }
7797
7887
  delete(agentId, threadId) {
7798
7888
  try {
@@ -7899,6 +7989,7 @@ export {
7899
7989
  flushTelemetry,
7900
7990
  forgetHostSession,
7901
7991
  getDatabase,
7992
+ getOperatorEmail,
7902
7993
  hostSessionStoragePath,
7903
7994
  isInternalEmail,
7904
7995
  isSessionFresh,
@@ -7907,6 +7998,7 @@ export {
7907
7998
  normalizeAddress,
7908
7999
  normalizePhoneNumber,
7909
8000
  normalizeSubject,
8001
+ operatorPrefsStoragePath,
7910
8002
  parseEmail,
7911
8003
  parseGoogleVoiceSms,
7912
8004
  recordToolCall,
@@ -7919,6 +8011,7 @@ export {
7919
8011
  saveHostSession,
7920
8012
  scanOutboundEmail,
7921
8013
  scoreEmail,
8014
+ setOperatorEmail,
7922
8015
  setTelemetryVersion,
7923
8016
  startRelayBridge,
7924
8017
  threadIdFor,