@agenticmail/core 0.5.10 → 0.5.13

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,19 +1440,16 @@ declare class DependencyInstaller {
1440
1440
  */
1441
1441
  private findDockerApp;
1442
1442
  /**
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)
1443
+ * Check if Docker Desktop license has already been accepted.
1444
+ * Returns true if we're confident the user has accepted before.
1445
+ */
1446
+ private isDockerLicenseAccepted;
1447
+ /**
1448
+ * Configure Docker Desktop to run headless after first-time setup.
1449
+ * Call this AFTER Docker has been started and license accepted.
1450
+ * Suppresses UI, dock icon, tips, analytics, and auto-updates.
1454
1451
  */
1455
- private preAcceptDockerLicense;
1452
+ private configureDockerHeadless;
1456
1453
  /**
1457
1454
  * Docker.app exists but CLI isn't available or daemon isn't running.
1458
1455
  * Runs the built-in installer silently (--accept-license to link CLI tools),
@@ -1460,8 +1457,8 @@ declare class DependencyInstaller {
1460
1457
  */
1461
1458
  private setupExistingDockerApp;
1462
1459
  /**
1463
- * Hide the Docker Desktop window using AppleScript.
1464
- * Called after starting Docker to suppress the welcome/dashboard GUI.
1460
+ * Hide Docker Desktop completely close all windows, hide from dock, make invisible.
1461
+ * Called after starting Docker to ensure the user never sees any Docker UI.
1465
1462
  */
1466
1463
  private hideDockerWindow;
1467
1464
  /**
package/dist/index.js CHANGED
@@ -6086,7 +6086,7 @@ var DependencyInstaller = class {
6086
6086
  }
6087
6087
  const dockerApp = this.findDockerApp();
6088
6088
  if (dockerApp) {
6089
- this.onProgress("__progress__:10:Docker Desktop found \u2014 setting it up...");
6089
+ this.onProgress("__progress__:10:Setting up mail server engine...");
6090
6090
  await this.setupExistingDockerApp(dockerApp);
6091
6091
  return;
6092
6092
  }
@@ -6150,52 +6150,67 @@ var DependencyInstaller = class {
6150
6150
  return null;
6151
6151
  }
6152
6152
  /**
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)
6153
+ * Check if Docker Desktop license has already been accepted.
6154
+ * Returns true if we're confident the user has accepted before.
6164
6155
  */
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 });
6156
+ isDockerLicenseAccepted() {
6169
6157
  try {
6170
- if (!existsSync4(systemDir)) {
6171
- execSync(`mkdir -p "${systemDir}"`, { timeout: 5e3, stdio: "ignore" });
6158
+ const systemFile = "/Library/Application Support/com.docker.docker/install-settings.json";
6159
+ if (existsSync4(systemFile)) {
6160
+ const raw = readFileSync2(systemFile, "utf-8");
6161
+ const data = JSON.parse(raw);
6162
+ if (data.acceptLicense) return true;
6172
6163
  }
6173
- writeFileSync3(systemFile, licenseJson, { mode: 420 });
6174
6164
  } 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 {
6165
+ }
6166
+ try {
6167
+ const settingsFile = join6(process.env.HOME || "", "Library/Group Containers/group.com.docker/settings-store.json");
6168
+ if (existsSync4(settingsFile)) {
6169
+ return true;
6182
6170
  }
6171
+ } catch {
6183
6172
  }
6173
+ return false;
6174
+ }
6175
+ /**
6176
+ * Configure Docker Desktop to run headless after first-time setup.
6177
+ * Call this AFTER Docker has been started and license accepted.
6178
+ * Suppresses UI, dock icon, tips, analytics, and auto-updates.
6179
+ */
6180
+ configureDockerHeadless() {
6184
6181
  try {
6185
6182
  const userDockerDir = join6(process.env.HOME || "", "Library/Group Containers/group.com.docker");
6186
6183
  const settingsFile = join6(userDockerDir, "settings-store.json");
6184
+ const headlessDefaults = {
6185
+ AutoStart: false,
6186
+ // Don't auto-start on login (we start it ourselves)
6187
+ OpenUIOnStartupDisabled: true,
6188
+ // Don't show dashboard on start
6189
+ TipShown: true,
6190
+ // Don't show tips/welcome
6191
+ SUAutomaticallyUpdate: false,
6192
+ // Don't nag about updates
6193
+ AnalyticsEnabled: false
6194
+ // No analytics prompts
6195
+ };
6187
6196
  if (existsSync4(settingsFile)) {
6188
6197
  const raw = readFileSync2(settingsFile, "utf-8");
6189
6198
  try {
6190
6199
  const settings = JSON.parse(raw);
6191
- if (!settings.AcceptedLicense) {
6192
- settings.AcceptedLicense = true;
6200
+ let changed = false;
6201
+ for (const [key, val] of Object.entries(headlessDefaults)) {
6202
+ if (settings[key] !== val) {
6203
+ settings[key] = val;
6204
+ changed = true;
6205
+ }
6206
+ }
6207
+ if (changed) {
6193
6208
  writeFileSync3(settingsFile, JSON.stringify(settings, null, 2));
6194
6209
  }
6195
6210
  } catch {
6196
6211
  }
6197
6212
  } else if (existsSync4(userDockerDir)) {
6198
- writeFileSync3(settingsFile, JSON.stringify({ AcceptedLicense: true }, null, 2));
6213
+ writeFileSync3(settingsFile, JSON.stringify(headlessDefaults, null, 2));
6199
6214
  }
6200
6215
  } catch {
6201
6216
  }
@@ -6207,9 +6222,9 @@ var DependencyInstaller = class {
6207
6222
  */
6208
6223
  async setupExistingDockerApp(appPath) {
6209
6224
  const installBin = join6(appPath, "Contents", "MacOS", "install");
6210
- this.preAcceptDockerLicense();
6225
+ const isFirstLaunch = !this.isDockerLicenseAccepted();
6211
6226
  if (existsSync4(installBin)) {
6212
- this.onProgress("__progress__:30:Setting up Docker CLI tools...");
6227
+ this.onProgress("__progress__:30:Setting up CLI tools...");
6213
6228
  const user = process.env.USER || execSync("whoami", { timeout: 5e3 }).toString().trim();
6214
6229
  try {
6215
6230
  execSync(`"${installBin}" --accept-license --user=${user}`, {
@@ -6219,14 +6234,25 @@ var DependencyInstaller = class {
6219
6234
  } catch {
6220
6235
  }
6221
6236
  }
6222
- this.onProgress("__progress__:50:Starting Docker engine...");
6223
- this.startDockerDaemon();
6224
- this.hideDockerWindow();
6225
- await this.waitForDocker();
6237
+ if (isFirstLaunch) {
6238
+ this.onProgress("__progress__:50:Opening Docker \u2014 please accept the license agreement...");
6239
+ try {
6240
+ execFileSync2("open", ["-a", appPath], { timeout: 1e4, stdio: "ignore" });
6241
+ } catch {
6242
+ }
6243
+ await this.waitForDocker();
6244
+ this.configureDockerHeadless();
6245
+ this.hideDockerWindow();
6246
+ } else {
6247
+ this.onProgress("__progress__:50:Starting engine...");
6248
+ this.startDockerDaemon();
6249
+ this.hideDockerWindow();
6250
+ await this.waitForDocker();
6251
+ }
6226
6252
  }
6227
6253
  /**
6228
- * Hide the Docker Desktop window using AppleScript.
6229
- * Called after starting Docker to suppress the welcome/dashboard GUI.
6254
+ * Hide Docker Desktop completely close all windows, hide from dock, make invisible.
6255
+ * Called after starting Docker to ensure the user never sees any Docker UI.
6230
6256
  */
6231
6257
  hideDockerWindow() {
6232
6258
  try {
@@ -6250,6 +6276,25 @@ var DependencyInstaller = class {
6250
6276
  );
6251
6277
  } catch {
6252
6278
  }
6279
+ const dockerApp = this.findDockerApp();
6280
+ if (dockerApp) {
6281
+ const plistPath = join6(dockerApp, "Contents", "Info.plist");
6282
+ try {
6283
+ const plistContent = readFileSync2(plistPath, "utf-8");
6284
+ if (!plistContent.includes("LSUIElement")) {
6285
+ execSync(
6286
+ `/usr/libexec/PlistBuddy -c "Add :LSUIElement bool true" "${plistPath}" 2>/dev/null`,
6287
+ { timeout: 5e3, stdio: "ignore" }
6288
+ );
6289
+ } else if (!plistContent.includes("<key>LSUIElement</key>\n <true/>") && !plistContent.includes("<key>LSUIElement</key><true/>")) {
6290
+ execSync(
6291
+ `/usr/libexec/PlistBuddy -c "Set :LSUIElement true" "${plistPath}" 2>/dev/null`,
6292
+ { timeout: 5e3, stdio: "ignore" }
6293
+ );
6294
+ }
6295
+ } catch {
6296
+ }
6297
+ }
6253
6298
  }
6254
6299
  /**
6255
6300
  * Full Docker Desktop install on macOS.
@@ -6258,7 +6303,7 @@ var DependencyInstaller = class {
6258
6303
  */
6259
6304
  async installDockerMac() {
6260
6305
  if (hasHomebrew()) {
6261
- this.onProgress("__progress__:5:Installing Docker Desktop...");
6306
+ this.onProgress("__progress__:5:Installing mail server engine...");
6262
6307
  try {
6263
6308
  const brewResult = await runSilent(
6264
6309
  "brew",
@@ -6266,7 +6311,7 @@ var DependencyInstaller = class {
6266
6311
  { timeout: 6e5 }
6267
6312
  );
6268
6313
  if (brewResult.exitCode === 0) {
6269
- this.onProgress("__progress__:45:Docker Desktop installed!");
6314
+ this.onProgress("__progress__:45:Mail server engine installed!");
6270
6315
  const appPath = this.findDockerApp();
6271
6316
  if (appPath) {
6272
6317
  await this.setupExistingDockerApp(appPath);
@@ -6281,7 +6326,7 @@ var DependencyInstaller = class {
6281
6326
  const archName = cpu === "arm64" ? "arm64" : "amd64";
6282
6327
  const dmgUrl = `https://desktop.docker.com/mac/main/${archName}/Docker.dmg`;
6283
6328
  const dmgPath = "/tmp/Docker.dmg";
6284
- this.onProgress("__progress__:5:Downloading Docker Desktop...");
6329
+ this.onProgress("__progress__:5:Downloading mail server engine...");
6285
6330
  const dlResult = await runSilent("curl", [
6286
6331
  "-fSL",
6287
6332
  "-o",
@@ -6291,7 +6336,7 @@ var DependencyInstaller = class {
6291
6336
  if (dlResult.exitCode !== 0) {
6292
6337
  throw new Error("Failed to download Docker Desktop. Check your internet connection and try again.");
6293
6338
  }
6294
- this.onProgress("__progress__:40:Installing Docker Desktop...");
6339
+ this.onProgress("__progress__:40:Installing mail server engine...");
6295
6340
  try {
6296
6341
  try {
6297
6342
  execSync("hdiutil detach /Volumes/Docker 2>/dev/null", { timeout: 1e4, stdio: "ignore" });
@@ -6301,8 +6346,7 @@ var DependencyInstaller = class {
6301
6346
  } catch {
6302
6347
  throw new Error("Failed to mount Docker DMG. The download may be corrupted \u2014 try again.");
6303
6348
  }
6304
- this.preAcceptDockerLicense();
6305
- this.onProgress("__progress__:55:Running Docker installer...");
6349
+ this.onProgress("__progress__:55:Running installer...");
6306
6350
  const user = process.env.USER || execSync("whoami", { timeout: 5e3 }).toString().trim();
6307
6351
  try {
6308
6352
  execSync(`/Volumes/Docker/Docker.app/Contents/MacOS/install --accept-license --user=${user}`, {
@@ -6315,7 +6359,7 @@ var DependencyInstaller = class {
6315
6359
  try {
6316
6360
  execSync('cp -R "/Volumes/Docker/Docker.app" /Applications/', { timeout: 6e4, stdio: "ignore" });
6317
6361
  } catch {
6318
- throw new Error("Failed to install Docker Desktop. You may need to run this with admin privileges.");
6362
+ throw new Error("Failed to install. You may need to run this with admin privileges.");
6319
6363
  }
6320
6364
  }
6321
6365
  }
@@ -6327,10 +6371,14 @@ var DependencyInstaller = class {
6327
6371
  await unlink(dmgPath);
6328
6372
  } catch {
6329
6373
  }
6330
- this.onProgress("__progress__:70:Starting Docker engine...");
6331
- this.startDockerDaemon();
6332
- this.hideDockerWindow();
6374
+ this.onProgress("__progress__:70:Opening Docker \u2014 please accept the license agreement...");
6375
+ try {
6376
+ execFileSync2("open", ["-a", "/Applications/Docker.app"], { timeout: 1e4, stdio: "ignore" });
6377
+ } catch {
6378
+ }
6333
6379
  await this.waitForDocker();
6380
+ this.configureDockerHeadless();
6381
+ this.hideDockerWindow();
6334
6382
  }
6335
6383
  /**
6336
6384
  * Install Docker Engine on Linux using Docker's official convenience script.
@@ -6496,10 +6544,10 @@ var DependencyInstaller = class {
6496
6544
  strategyIdx++;
6497
6545
  const strategy = strategies[strategyIdx];
6498
6546
  const msgs = {
6499
- cli: "Trying Docker CLI...",
6500
- reopen: "Restarting Docker Desktop...",
6547
+ cli: "Checking engine...",
6548
+ reopen: "Restarting engine...",
6501
6549
  background: "Trying direct launch...",
6502
- install: "Re-running Docker installer...",
6550
+ install: "Re-running installer...",
6503
6551
  service: "Trying service command...",
6504
6552
  snap: "Trying snap..."
6505
6553
  };
@@ -6507,9 +6555,9 @@ var DependencyInstaller = class {
6507
6555
  this.startDockerDaemon(strategy);
6508
6556
  } else {
6509
6557
  const msgs = [
6510
- "Starting Docker...",
6511
- "Waiting for Docker engine...",
6512
- "Docker is loading...",
6558
+ "Starting engine...",
6559
+ "Waiting for engine...",
6560
+ "Loading...",
6513
6561
  "Almost there...",
6514
6562
  "Still starting up...",
6515
6563
  "First launch takes a bit longer...",
@@ -6518,11 +6566,11 @@ var DependencyInstaller = class {
6518
6566
  const msgIdx = Math.floor(elapsed / 1e4) % msgs.length;
6519
6567
  this.onProgress(`__progress__:${pct}:${msgs[msgIdx]}`);
6520
6568
  }
6521
- if (os === "darwin") this.hideDockerWindow();
6569
+ if (os === "darwin" && this.isDockerLicenseAccepted()) this.hideDockerWindow();
6522
6570
  await new Promise((r) => setTimeout(r, 3e3));
6523
6571
  }
6524
6572
  throw new Error(
6525
- "Docker could not be started after trying all available methods. This usually means Docker Desktop needs a one-time manual launch to complete its setup. Open Docker from your Applications folder, then run this command again."
6573
+ "Engine could not be started after trying all available methods. If this is your first time, open Docker from your Applications folder, accept the license agreement, then run this command again."
6526
6574
  );
6527
6575
  }
6528
6576
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/core",
3
- "version": "0.5.10",
3
+ "version": "0.5.13",
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",