@agenticmail/core 0.5.7 → 0.5.9

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.d.ts CHANGED
@@ -1440,13 +1440,34 @@ declare class DependencyInstaller {
1440
1440
  */
1441
1441
  private findDockerApp;
1442
1442
  /**
1443
- * Docker.app exists but CLI isn't available.
1444
- * Run the built-in installer (--accept-license), start Docker Desktop, wait.
1443
+ * Pre-accept the Docker Desktop license agreement by writing the settings
1444
+ * file that Docker checks on startup. This prevents the license dialog from
1445
+ * appearing and blocking automated setup.
1446
+ *
1447
+ * Docker Desktop checks /Library/Application Support/com.docker.docker/install-settings.json
1448
+ * (system-level, requires sudo) for {"acceptLicense": true}. The --accept-license
1449
+ * flag on the installer binary tries to write this but fails without sudo.
1450
+ *
1451
+ * We try multiple approaches:
1452
+ * 1. Write to the system-level path (may fail without sudo — that's OK)
1453
+ * 2. Write to the user-level Docker settings (Group Containers)
1454
+ */
1455
+ private preAcceptDockerLicense;
1456
+ /**
1457
+ * Docker.app exists but CLI isn't available or daemon isn't running.
1458
+ * Runs the built-in installer silently (--accept-license to link CLI tools),
1459
+ * then starts Docker Desktop hidden (no GUI window).
1445
1460
  */
1446
1461
  private setupExistingDockerApp;
1462
+ /**
1463
+ * Hide the Docker Desktop window using AppleScript.
1464
+ * Called after starting Docker to suppress the welcome/dashboard GUI.
1465
+ */
1466
+ private hideDockerWindow;
1447
1467
  /**
1448
1468
  * Full Docker Desktop install on macOS.
1449
- * Tries Homebrew first (cleaner, handles updates), falls back to DMG download.
1469
+ * Tries Homebrew first (cleaner), falls back to DMG download.
1470
+ * All output is suppressed — only our progress spinner shows.
1450
1471
  */
1451
1472
  private installDockerMac;
1452
1473
  /**
package/dist/index.js CHANGED
@@ -850,14 +850,14 @@ var StalwartAdmin = class {
850
850
  * Critical for email deliverability — must match the sending domain.
851
851
  */
852
852
  async setHostname(domain) {
853
- const { readFileSync: readFileSync4, writeFileSync: writeFileSync5 } = await import("fs");
853
+ const { readFileSync: readFileSync5, writeFileSync: writeFileSync6 } = await import("fs");
854
854
  const { homedir: homedir8 } = await import("os");
855
855
  const { join: join9 } = await import("path");
856
856
  const configPath = join9(homedir8(), ".agenticmail", "stalwart.toml");
857
857
  try {
858
- let config = readFileSync4(configPath, "utf-8");
858
+ let config = readFileSync5(configPath, "utf-8");
859
859
  config = config.replace(/^hostname\s*=\s*"[^"]*"/m, `hostname = "${domain}"`);
860
- writeFileSync5(configPath, config);
860
+ writeFileSync6(configPath, config);
861
861
  console.log(`[Stalwart] Updated hostname to "${domain}" in stalwart.toml`);
862
862
  } catch (err) {
863
863
  throw new Error(`Failed to set config server.hostname=${domain}`);
@@ -975,12 +975,12 @@ var StalwartAdmin = class {
975
975
  * This bypasses the need for a PTR record on the sending IP.
976
976
  */
977
977
  async configureOutboundRelay(config) {
978
- const { readFileSync: readFileSync4, writeFileSync: writeFileSync5 } = await import("fs");
978
+ const { readFileSync: readFileSync5, writeFileSync: writeFileSync6 } = await import("fs");
979
979
  const { homedir: homedir8 } = await import("os");
980
980
  const { join: join9 } = await import("path");
981
981
  const routeName = config.routeName ?? "gmail";
982
982
  const tomlPath = join9(homedir8(), ".agenticmail", "stalwart.toml");
983
- let toml = readFileSync4(tomlPath, "utf-8");
983
+ let toml = readFileSync5(tomlPath, "utf-8");
984
984
  toml = toml.replace(/\n\[queue\.route\.gmail\][\s\S]*?(?=\n\[|$)/, "");
985
985
  toml = toml.replace(/\n\[queue\.strategy\][\s\S]*?(?=\n\[|$)/, "");
986
986
  toml += `
@@ -999,7 +999,7 @@ auth.secret = "${config.password}"
999
999
  route = [ { if = "is_local_domain('', rcpt_domain)", then = "'local'" },
1000
1000
  { else = "'${routeName}'" } ]
1001
1001
  `;
1002
- writeFileSync5(tomlPath, toml, "utf-8");
1002
+ writeFileSync6(tomlPath, toml, "utf-8");
1003
1003
  await this.restartContainer();
1004
1004
  }
1005
1005
  };
@@ -5180,9 +5180,9 @@ var GatewayManager = class {
5180
5180
  const { homedir: homedir8 } = await import("os");
5181
5181
  const backupDir = join4(homedir8(), ".agenticmail");
5182
5182
  const backupPath = join4(backupDir, `dns-backup-${domain}-${Date.now()}.json`);
5183
- const { writeFileSync: writeFileSync5, mkdirSync: mkdirSync5 } = await import("fs");
5183
+ const { writeFileSync: writeFileSync6, mkdirSync: mkdirSync5 } = await import("fs");
5184
5184
  mkdirSync5(backupDir, { recursive: true });
5185
- writeFileSync5(backupPath, JSON.stringify({
5185
+ writeFileSync6(backupPath, JSON.stringify({
5186
5186
  domain,
5187
5187
  zoneId: zone.id,
5188
5188
  backedUpAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -5813,7 +5813,7 @@ var RELAY_PRESETS = {
5813
5813
 
5814
5814
  // src/setup/index.ts
5815
5815
  import { randomBytes as randomBytes2 } from "crypto";
5816
- import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, chmodSync } from "fs";
5816
+ import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, chmodSync } from "fs";
5817
5817
  import { join as join8 } from "path";
5818
5818
  import { homedir as homedir7 } from "os";
5819
5819
 
@@ -5894,7 +5894,7 @@ var DependencyChecker = class {
5894
5894
 
5895
5895
  // src/setup/installer.ts
5896
5896
  import { execFileSync as execFileSync2, execSync, spawn as spawnChild } from "child_process";
5897
- import { existsSync as existsSync4, readdirSync, lstatSync, readlinkSync } from "fs";
5897
+ import { existsSync as existsSync4, readdirSync, lstatSync, readlinkSync, writeFileSync as writeFileSync3, readFileSync as readFileSync2 } from "fs";
5898
5898
  import { writeFile, rename, chmod as chmod2, mkdir as mkdir2, unlink } from "fs/promises";
5899
5899
  import { join as join6 } from "path";
5900
5900
  import { homedir as homedir5, platform as platform2, arch as arch2 } from "os";
@@ -6016,6 +6016,24 @@ function runShellWithRollingOutput(cmd, opts = {}) {
6016
6016
  });
6017
6017
  });
6018
6018
  }
6019
+ function runSilent(command, args, opts = {}) {
6020
+ const timeout = opts.timeout ?? 3e5;
6021
+ return new Promise((resolve, reject) => {
6022
+ const child = spawnChild(command, args, {
6023
+ stdio: ["ignore", "pipe", "pipe"],
6024
+ timeout
6025
+ });
6026
+ let fullOutput = "";
6027
+ child.stdout?.on("data", (d) => {
6028
+ fullOutput += d.toString();
6029
+ });
6030
+ child.stderr?.on("data", (d) => {
6031
+ fullOutput += d.toString();
6032
+ });
6033
+ child.on("close", (code) => resolve({ exitCode: code ?? 1, fullOutput }));
6034
+ child.on("error", reject);
6035
+ });
6036
+ }
6019
6037
  function existsReal(p) {
6020
6038
  try {
6021
6039
  const stat = lstatSync(p);
@@ -6132,56 +6150,140 @@ var DependencyInstaller = class {
6132
6150
  return null;
6133
6151
  }
6134
6152
  /**
6135
- * Docker.app exists but CLI isn't available.
6136
- * Run the built-in installer (--accept-license), start Docker Desktop, wait.
6153
+ * Pre-accept the Docker Desktop license agreement by writing the settings
6154
+ * file that Docker checks on startup. This prevents the license dialog from
6155
+ * appearing and blocking automated setup.
6156
+ *
6157
+ * Docker Desktop checks /Library/Application Support/com.docker.docker/install-settings.json
6158
+ * (system-level, requires sudo) for {"acceptLicense": true}. The --accept-license
6159
+ * flag on the installer binary tries to write this but fails without sudo.
6160
+ *
6161
+ * We try multiple approaches:
6162
+ * 1. Write to the system-level path (may fail without sudo — that's OK)
6163
+ * 2. Write to the user-level Docker settings (Group Containers)
6164
+ */
6165
+ preAcceptDockerLicense() {
6166
+ const systemDir = "/Library/Application Support/com.docker.docker";
6167
+ const systemFile = join6(systemDir, "install-settings.json");
6168
+ const licenseJson = JSON.stringify({ acceptLicense: true });
6169
+ try {
6170
+ if (!existsSync4(systemDir)) {
6171
+ execSync(`mkdir -p "${systemDir}"`, { timeout: 5e3, stdio: "ignore" });
6172
+ }
6173
+ writeFileSync3(systemFile, licenseJson, { mode: 420 });
6174
+ } catch {
6175
+ try {
6176
+ execSync(`sudo -n mkdir -p "${systemDir}" 2>/dev/null && sudo -n tee "${systemFile}" > /dev/null 2>&1`, {
6177
+ timeout: 5e3,
6178
+ input: licenseJson,
6179
+ stdio: ["pipe", "ignore", "ignore"]
6180
+ });
6181
+ } catch {
6182
+ }
6183
+ }
6184
+ try {
6185
+ const userDockerDir = join6(process.env.HOME || "", "Library/Group Containers/group.com.docker");
6186
+ const settingsFile = join6(userDockerDir, "settings-store.json");
6187
+ if (existsSync4(settingsFile)) {
6188
+ const raw = readFileSync2(settingsFile, "utf-8");
6189
+ try {
6190
+ const settings = JSON.parse(raw);
6191
+ if (!settings.AcceptedLicense) {
6192
+ settings.AcceptedLicense = true;
6193
+ writeFileSync3(settingsFile, JSON.stringify(settings, null, 2));
6194
+ }
6195
+ } catch {
6196
+ }
6197
+ } else if (existsSync4(userDockerDir)) {
6198
+ writeFileSync3(settingsFile, JSON.stringify({ AcceptedLicense: true }, null, 2));
6199
+ }
6200
+ } catch {
6201
+ }
6202
+ }
6203
+ /**
6204
+ * Docker.app exists but CLI isn't available or daemon isn't running.
6205
+ * Runs the built-in installer silently (--accept-license to link CLI tools),
6206
+ * then starts Docker Desktop hidden (no GUI window).
6137
6207
  */
6138
6208
  async setupExistingDockerApp(appPath) {
6139
6209
  const installBin = join6(appPath, "Contents", "MacOS", "install");
6210
+ this.preAcceptDockerLicense();
6140
6211
  if (existsSync4(installBin)) {
6141
- this.onProgress("__progress__:20:Installing Docker CLI tools...");
6212
+ this.onProgress("__progress__:30:Setting up Docker CLI tools...");
6142
6213
  const user = process.env.USER || execSync("whoami", { timeout: 5e3 }).toString().trim();
6143
6214
  try {
6144
- await runWithRollingOutput(installBin, ["--accept-license", `--user=${user}`], {
6145
- timeout: 12e4
6215
+ execSync(`"${installBin}" --accept-license --user=${user}`, {
6216
+ timeout: 12e4,
6217
+ stdio: "ignore"
6146
6218
  });
6147
6219
  } catch {
6148
6220
  }
6149
6221
  }
6150
- this.onProgress("__progress__:40:Starting Docker Desktop...");
6222
+ this.onProgress("__progress__:50:Starting Docker engine...");
6151
6223
  this.startDockerDaemon();
6224
+ this.hideDockerWindow();
6152
6225
  await this.waitForDocker();
6153
6226
  }
6227
+ /**
6228
+ * Hide the Docker Desktop window using AppleScript.
6229
+ * Called after starting Docker to suppress the welcome/dashboard GUI.
6230
+ */
6231
+ hideDockerWindow() {
6232
+ try {
6233
+ execSync(
6234
+ `osascript -e 'tell application "System Events" to tell process "Docker Desktop" to set visible to false' 2>/dev/null`,
6235
+ { timeout: 5e3, stdio: "ignore" }
6236
+ );
6237
+ } catch {
6238
+ }
6239
+ try {
6240
+ execSync(
6241
+ `osascript -e 'tell application "Docker Desktop" to close every window' 2>/dev/null`,
6242
+ { timeout: 5e3, stdio: "ignore" }
6243
+ );
6244
+ } catch {
6245
+ }
6246
+ try {
6247
+ execSync(
6248
+ `osascript -e 'tell application "Docker" to close every window' 2>/dev/null`,
6249
+ { timeout: 5e3, stdio: "ignore" }
6250
+ );
6251
+ } catch {
6252
+ }
6253
+ }
6154
6254
  /**
6155
6255
  * Full Docker Desktop install on macOS.
6156
- * Tries Homebrew first (cleaner, handles updates), falls back to DMG download.
6256
+ * Tries Homebrew first (cleaner), falls back to DMG download.
6257
+ * All output is suppressed — only our progress spinner shows.
6157
6258
  */
6158
6259
  async installDockerMac() {
6159
6260
  if (hasHomebrew()) {
6160
- this.onProgress("__progress__:5:Installing Docker Desktop via Homebrew...");
6161
- const brewResult = await runWithRollingOutput(
6162
- "brew",
6163
- ["install", "--cask", "docker"],
6164
- { timeout: 6e5 }
6165
- // can be slow on first install
6166
- );
6167
- if (brewResult.exitCode === 0) {
6168
- this.onProgress("__progress__:50:Docker Desktop installed!");
6169
- const appPath = this.findDockerApp();
6170
- if (appPath) {
6171
- await this.setupExistingDockerApp(appPath);
6172
- return;
6261
+ this.onProgress("__progress__:5:Installing Docker Desktop...");
6262
+ try {
6263
+ const brewResult = await runSilent(
6264
+ "brew",
6265
+ ["install", "--cask", "docker"],
6266
+ { timeout: 6e5 }
6267
+ );
6268
+ if (brewResult.exitCode === 0) {
6269
+ this.onProgress("__progress__:45:Docker Desktop installed!");
6270
+ const appPath = this.findDockerApp();
6271
+ if (appPath) {
6272
+ await this.setupExistingDockerApp(appPath);
6273
+ return;
6274
+ }
6173
6275
  }
6276
+ } catch {
6174
6277
  }
6175
- this.onProgress("__progress__:10:Homebrew install didn't work, downloading directly...");
6278
+ this.onProgress("__progress__:10:Trying direct download...");
6176
6279
  }
6177
6280
  const cpu = arch2();
6178
6281
  const archName = cpu === "arm64" ? "arm64" : "amd64";
6179
6282
  const dmgUrl = `https://desktop.docker.com/mac/main/${archName}/Docker.dmg`;
6180
6283
  const dmgPath = "/tmp/Docker.dmg";
6181
6284
  this.onProgress("__progress__:5:Downloading Docker Desktop...");
6182
- const dlResult = await runWithRollingOutput("curl", [
6285
+ const dlResult = await runSilent("curl", [
6183
6286
  "-fSL",
6184
- "--progress-bar",
6185
6287
  "-o",
6186
6288
  dmgPath,
6187
6289
  dmgUrl
@@ -6199,17 +6301,14 @@ var DependencyInstaller = class {
6199
6301
  } catch {
6200
6302
  throw new Error("Failed to mount Docker DMG. The download may be corrupted \u2014 try again.");
6201
6303
  }
6304
+ this.preAcceptDockerLicense();
6202
6305
  this.onProgress("__progress__:55:Running Docker installer...");
6203
6306
  const user = process.env.USER || execSync("whoami", { timeout: 5e3 }).toString().trim();
6204
6307
  try {
6205
- const installResult = await runWithRollingOutput(
6206
- "/Volumes/Docker/Docker.app/Contents/MacOS/install",
6207
- ["--accept-license", `--user=${user}`],
6208
- { timeout: 12e4 }
6209
- );
6210
- if (installResult.exitCode !== 0 && !existsSync4("/Applications/Docker.app")) {
6211
- throw new Error("Installer exited with errors");
6212
- }
6308
+ execSync(`/Volumes/Docker/Docker.app/Contents/MacOS/install --accept-license --user=${user}`, {
6309
+ timeout: 12e4,
6310
+ stdio: "ignore"
6311
+ });
6213
6312
  } catch {
6214
6313
  if (!existsSync4("/Applications/Docker.app")) {
6215
6314
  this.onProgress("__progress__:60:Trying alternative install method...");
@@ -6228,14 +6327,10 @@ var DependencyInstaller = class {
6228
6327
  await unlink(dmgPath);
6229
6328
  } catch {
6230
6329
  }
6231
- const installed = this.findDockerApp();
6232
- if (installed) {
6233
- await this.setupExistingDockerApp(installed);
6234
- } else {
6235
- this.onProgress("__progress__:70:Starting Docker Desktop...");
6236
- this.startDockerDaemon();
6237
- await this.waitForDocker();
6238
- }
6330
+ this.onProgress("__progress__:70:Starting Docker engine...");
6331
+ this.startDockerDaemon();
6332
+ this.hideDockerWindow();
6333
+ await this.waitForDocker();
6239
6334
  }
6240
6335
  /**
6241
6336
  * Install Docker Engine on Linux using Docker's official convenience script.
@@ -6423,6 +6518,7 @@ var DependencyInstaller = class {
6423
6518
  const msgIdx = Math.floor(elapsed / 1e4) % msgs.length;
6424
6519
  this.onProgress(`__progress__:${pct}:${msgs[msgIdx]}`);
6425
6520
  }
6521
+ if (os === "darwin") this.hideDockerWindow();
6426
6522
  await new Promise((r) => setTimeout(r, 3e3));
6427
6523
  }
6428
6524
  throw new Error(
@@ -6537,7 +6633,7 @@ var DependencyInstaller = class {
6537
6633
 
6538
6634
  // src/setup/service.ts
6539
6635
  import { execFileSync as execFileSync3, execSync as execSync2 } from "child_process";
6540
- import { existsSync as existsSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
6636
+ import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync4, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
6541
6637
  import { join as join7 } from "path";
6542
6638
  import { homedir as homedir6, platform as platform3 } from "os";
6543
6639
  var PLIST_LABEL = "com.agenticmail.server";
@@ -6600,7 +6696,7 @@ var ServiceManager = class {
6600
6696
  const dataDir = join7(homedir6(), ".agenticmail");
6601
6697
  const entryCache = join7(dataDir, "api-entry.path");
6602
6698
  if (existsSync5(entryCache)) {
6603
- const cached = readFileSync2(entryCache, "utf-8").trim();
6699
+ const cached = readFileSync3(entryCache, "utf-8").trim();
6604
6700
  if (existsSync5(cached)) return cached;
6605
6701
  }
6606
6702
  throw new Error("Could not find @agenticmail/api entry point. Run `agenticmail start` first to populate the cache.");
@@ -6611,7 +6707,7 @@ var ServiceManager = class {
6611
6707
  cacheApiEntryPath(entryPath) {
6612
6708
  const dataDir = join7(homedir6(), ".agenticmail");
6613
6709
  if (!existsSync5(dataDir)) mkdirSync3(dataDir, { recursive: true });
6614
- writeFileSync3(join7(dataDir, "api-entry.path"), entryPath);
6710
+ writeFileSync4(join7(dataDir, "api-entry.path"), entryPath);
6615
6711
  }
6616
6712
  /**
6617
6713
  * Get the current package version.
@@ -6629,7 +6725,7 @@ var ServiceManager = class {
6629
6725
  }
6630
6726
  for (const p of pkgPaths) {
6631
6727
  if (existsSync5(p)) {
6632
- const pkg = JSON.parse(readFileSync2(p, "utf-8"));
6728
+ const pkg = JSON.parse(readFileSync3(p, "utf-8"));
6633
6729
  if (pkg.version) return pkg.version;
6634
6730
  }
6635
6731
  }
@@ -6695,7 +6791,7 @@ var ServiceManager = class {
6695
6791
  `log "Starting API server: ${nodePath} ${apiEntry}"`,
6696
6792
  `exec "${nodePath}" "${apiEntry}"`
6697
6793
  ].join("\n") + "\n";
6698
- writeFileSync3(scriptPath, script, { mode: 493 });
6794
+ writeFileSync4(scriptPath, script, { mode: 493 });
6699
6795
  return scriptPath;
6700
6796
  }
6701
6797
  /**
@@ -6708,7 +6804,7 @@ var ServiceManager = class {
6708
6804
  * - Service version tracking in env vars
6709
6805
  */
6710
6806
  generatePlist(nodePath, apiEntry, configPath) {
6711
- const config = JSON.parse(readFileSync2(configPath, "utf-8"));
6807
+ const config = JSON.parse(readFileSync3(configPath, "utf-8"));
6712
6808
  const logDir = join7(homedir6(), ".agenticmail", "logs");
6713
6809
  if (!existsSync5(logDir)) mkdirSync3(logDir, { recursive: true });
6714
6810
  const version = this.getVersion();
@@ -6806,7 +6902,7 @@ var ServiceManager = class {
6806
6902
  * - Proper dependency ordering
6807
6903
  */
6808
6904
  generateSystemdUnit(nodePath, apiEntry, configPath) {
6809
- const config = JSON.parse(readFileSync2(configPath, "utf-8"));
6905
+ const config = JSON.parse(readFileSync3(configPath, "utf-8"));
6810
6906
  const dataDir = config.dataDir || join7(homedir6(), ".agenticmail");
6811
6907
  const version = this.getVersion();
6812
6908
  const startScript = this.generateStartScript(nodePath, apiEntry);
@@ -6869,7 +6965,7 @@ WantedBy=default.target
6869
6965
  }
6870
6966
  }
6871
6967
  const plist = this.generatePlist(nodePath, apiEntry, configPath);
6872
- writeFileSync3(servicePath, plist);
6968
+ writeFileSync4(servicePath, plist);
6873
6969
  try {
6874
6970
  execFileSync3("launchctl", ["load", servicePath], { timeout: 1e4, stdio: "ignore" });
6875
6971
  } catch (err) {
@@ -6880,7 +6976,7 @@ WantedBy=default.target
6880
6976
  const dir = join7(homedir6(), ".config", "systemd", "user");
6881
6977
  if (!existsSync5(dir)) mkdirSync3(dir, { recursive: true });
6882
6978
  const unit = this.generateSystemdUnit(nodePath, apiEntry, configPath);
6883
- writeFileSync3(servicePath, unit);
6979
+ writeFileSync4(servicePath, unit);
6884
6980
  try {
6885
6981
  execFileSync3("systemctl", ["--user", "daemon-reload"], { timeout: 1e4, stdio: "ignore" });
6886
6982
  execFileSync3("systemctl", ["--user", "enable", SYSTEMD_UNIT], { timeout: 1e4, stdio: "ignore" });
@@ -7031,7 +7127,7 @@ var SetupManager = class {
7031
7127
  const envPath = join8(dataDir, ".env");
7032
7128
  if (existsSync6(configPath)) {
7033
7129
  try {
7034
- const existing = JSON.parse(readFileSync3(configPath, "utf-8"));
7130
+ const existing = JSON.parse(readFileSync4(configPath, "utf-8"));
7035
7131
  this.generateDockerFiles(existing);
7036
7132
  return { configPath, envPath, config: existing, isNew: false };
7037
7133
  } catch {
@@ -7054,7 +7150,7 @@ var SetupManager = class {
7054
7150
  api: { port: 3100, host: "127.0.0.1" },
7055
7151
  dataDir
7056
7152
  };
7057
- writeFileSync4(configPath, JSON.stringify(config, null, 2));
7153
+ writeFileSync5(configPath, JSON.stringify(config, null, 2));
7058
7154
  chmodSync(configPath, 384);
7059
7155
  const envContent = `# Auto-generated by agenticmail setup
7060
7156
  STALWART_ADMIN_USER=admin
@@ -7070,7 +7166,7 @@ SMTP_PORT=587
7070
7166
  IMAP_HOST=localhost
7071
7167
  IMAP_PORT=143
7072
7168
  `;
7073
- writeFileSync4(envPath, envContent);
7169
+ writeFileSync5(envPath, envContent);
7074
7170
  chmodSync(envPath, 384);
7075
7171
  this.generateDockerFiles(config);
7076
7172
  return { configPath, envPath, config, isNew: true };
@@ -7086,7 +7182,7 @@ IMAP_PORT=143
7086
7182
  }
7087
7183
  const password = config.stalwart?.adminPassword || "changeme";
7088
7184
  const composePath = join8(dataDir, "docker-compose.yml");
7089
- writeFileSync4(composePath, `services:
7185
+ writeFileSync5(composePath, `services:
7090
7186
  stalwart:
7091
7187
  image: stalwartlabs/stalwart:latest
7092
7188
  container_name: agenticmail-stalwart
@@ -7109,7 +7205,7 @@ volumes:
7109
7205
  stalwart-data:
7110
7206
  `);
7111
7207
  const tomlPath = join8(dataDir, "stalwart.toml");
7112
- writeFileSync4(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
7208
+ writeFileSync5(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
7113
7209
 
7114
7210
  [server]
7115
7211
  hostname = "localhost"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/core",
3
- "version": "0.5.7",
3
+ "version": "0.5.9",
4
4
  "description": "Core SDK for AgenticMail \u2014 email, SMS, and phone number access for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",