@agenticmail/core 0.5.21 → 0.5.23
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 +8 -1
- package/dist/index.js +90 -117
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1456,6 +1456,12 @@ declare class DependencyInstaller {
|
|
|
1456
1456
|
* Runs the built-in installer silently (--accept-license to link CLI tools),
|
|
1457
1457
|
* then starts Docker Desktop hidden (no GUI window).
|
|
1458
1458
|
*/
|
|
1459
|
+
/**
|
|
1460
|
+
* Docker.app exists but daemon isn't running.
|
|
1461
|
+
* Simple approach: if Docker was already running, great. If not, just
|
|
1462
|
+
* tell the user to open Docker and accept the terms themselves.
|
|
1463
|
+
* No GUI manipulation, no programmatic license tricks — just wait.
|
|
1464
|
+
*/
|
|
1459
1465
|
private setupExistingDockerApp;
|
|
1460
1466
|
/**
|
|
1461
1467
|
* Hide Docker Desktop completely — close all windows, hide from dock, make invisible.
|
|
@@ -1465,7 +1471,8 @@ declare class DependencyInstaller {
|
|
|
1465
1471
|
/**
|
|
1466
1472
|
* Full Docker Desktop install on macOS.
|
|
1467
1473
|
* Tries Homebrew first (cleaner), falls back to DMG download.
|
|
1468
|
-
*
|
|
1474
|
+
* After install, tells the user to open Docker and accept the terms.
|
|
1475
|
+
* No GUI manipulation — the user handles Docker themselves.
|
|
1469
1476
|
*/
|
|
1470
1477
|
private installDockerMac;
|
|
1471
1478
|
/**
|
package/dist/index.js
CHANGED
|
@@ -5180,8 +5180,8 @@ 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: writeFileSync6, mkdirSync:
|
|
5184
|
-
|
|
5183
|
+
const { writeFileSync: writeFileSync6, mkdirSync: mkdirSync6 } = await import("fs");
|
|
5184
|
+
mkdirSync6(backupDir, { recursive: true });
|
|
5185
5185
|
writeFileSync6(backupPath, JSON.stringify({
|
|
5186
5186
|
domain,
|
|
5187
5187
|
zoneId: zone.id,
|
|
@@ -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 readFileSync4, writeFileSync as writeFileSync5, mkdirSync as
|
|
5816
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, chmodSync } from "fs";
|
|
5817
5817
|
import { join as join8 } from "path";
|
|
5818
5818
|
import { homedir as homedir7 } from "os";
|
|
5819
5819
|
|
|
@@ -6221,52 +6221,44 @@ var DependencyInstaller = class {
|
|
|
6221
6221
|
* Runs the built-in installer silently (--accept-license to link CLI tools),
|
|
6222
6222
|
* then starts Docker Desktop hidden (no GUI window).
|
|
6223
6223
|
*/
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
if (wasAlreadyRunning) {
|
|
6233
|
-
if (existsSync4(installBin)) {
|
|
6234
|
-
this.onProgress("__progress__:30:Setting up CLI tools...");
|
|
6235
|
-
const user = process.env.USER || execSync("whoami", { timeout: 5e3 }).toString().trim();
|
|
6236
|
-
try {
|
|
6237
|
-
execSync(`"${installBin}" --accept-license --user=${user}`, {
|
|
6238
|
-
timeout: 12e4,
|
|
6239
|
-
stdio: "ignore"
|
|
6240
|
-
});
|
|
6241
|
-
} catch {
|
|
6242
|
-
}
|
|
6243
|
-
}
|
|
6224
|
+
/**
|
|
6225
|
+
* Docker.app exists but daemon isn't running.
|
|
6226
|
+
* Simple approach: if Docker was already running, great. If not, just
|
|
6227
|
+
* tell the user to open Docker and accept the terms themselves.
|
|
6228
|
+
* No GUI manipulation, no programmatic license tricks — just wait.
|
|
6229
|
+
*/
|
|
6230
|
+
async setupExistingDockerApp(_appPath) {
|
|
6231
|
+
if (this.isDockerReady()) {
|
|
6244
6232
|
this.onProgress("__progress__:100:Engine is ready!");
|
|
6245
|
-
this.hideDockerWindow();
|
|
6246
|
-
this.configureDockerHeadless();
|
|
6247
6233
|
return;
|
|
6248
6234
|
}
|
|
6249
|
-
this.
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
} catch {
|
|
6254
|
-
}
|
|
6255
|
-
await this.waitForDocker();
|
|
6256
|
-
if (existsSync4(installBin)) {
|
|
6257
|
-
this.onProgress("Setting up CLI tools...");
|
|
6258
|
-
const user = process.env.USER || execSync("whoami", { timeout: 5e3 }).toString().trim();
|
|
6235
|
+
this.onProgress("Open Docker Desktop and accept the license agreement, then we'll continue automatically...");
|
|
6236
|
+
const totalTime = 6e5;
|
|
6237
|
+
const start = Date.now();
|
|
6238
|
+
while (Date.now() - start < totalTime) {
|
|
6259
6239
|
try {
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6240
|
+
execFileSync2("docker", ["info"], { timeout: 5e3, stdio: "ignore" });
|
|
6241
|
+
this.onProgress("__progress__:100:Engine is ready!");
|
|
6242
|
+
this.configureDockerHeadless();
|
|
6243
|
+
this.hideDockerWindow();
|
|
6244
|
+
return;
|
|
6264
6245
|
} catch {
|
|
6265
6246
|
}
|
|
6247
|
+
const elapsed = Date.now() - start;
|
|
6248
|
+
const pct = Math.min(95, Math.round(elapsed / totalTime * 100));
|
|
6249
|
+
const msgs = [
|
|
6250
|
+
"Open Docker Desktop and accept the license to continue...",
|
|
6251
|
+
"Waiting for Docker to be ready...",
|
|
6252
|
+
"Accept the terms in Docker Desktop to continue...",
|
|
6253
|
+
"Still waiting for Docker..."
|
|
6254
|
+
];
|
|
6255
|
+
const msgIdx = Math.floor(elapsed / 8e3) % msgs.length;
|
|
6256
|
+
this.onProgress(`__progress__:${pct}:${msgs[msgIdx]}`);
|
|
6257
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
6266
6258
|
}
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6259
|
+
throw new Error(
|
|
6260
|
+
"Docker did not start. Open Docker Desktop from your Applications folder, accept the license agreement, then run this command again."
|
|
6261
|
+
);
|
|
6270
6262
|
}
|
|
6271
6263
|
/**
|
|
6272
6264
|
* Hide Docker Desktop completely — close all windows, hide from dock, make invisible.
|
|
@@ -6317,103 +6309,84 @@ var DependencyInstaller = class {
|
|
|
6317
6309
|
/**
|
|
6318
6310
|
* Full Docker Desktop install on macOS.
|
|
6319
6311
|
* Tries Homebrew first (cleaner), falls back to DMG download.
|
|
6320
|
-
*
|
|
6312
|
+
* After install, tells the user to open Docker and accept the terms.
|
|
6313
|
+
* No GUI manipulation — the user handles Docker themselves.
|
|
6321
6314
|
*/
|
|
6322
6315
|
async installDockerMac() {
|
|
6316
|
+
let installed = false;
|
|
6323
6317
|
if (hasHomebrew()) {
|
|
6324
|
-
this.onProgress("__progress__:5:Installing
|
|
6318
|
+
this.onProgress("__progress__:5:Installing Docker Desktop...");
|
|
6325
6319
|
try {
|
|
6326
6320
|
const brewResult = await runSilent(
|
|
6327
6321
|
"brew",
|
|
6328
6322
|
["install", "--cask", "docker"],
|
|
6329
6323
|
{ timeout: 6e5 }
|
|
6330
6324
|
);
|
|
6331
|
-
if (brewResult.exitCode === 0) {
|
|
6332
|
-
|
|
6333
|
-
try {
|
|
6334
|
-
execSync(`osascript -e 'quit app "Docker Desktop"' 2>/dev/null`, { timeout: 5e3, stdio: "ignore" });
|
|
6335
|
-
} catch {
|
|
6336
|
-
}
|
|
6337
|
-
try {
|
|
6338
|
-
execSync(`osascript -e 'quit app "Docker"' 2>/dev/null`, { timeout: 5e3, stdio: "ignore" });
|
|
6339
|
-
} catch {
|
|
6340
|
-
}
|
|
6341
|
-
try {
|
|
6342
|
-
execSync("pkill -f Docker.app 2>/dev/null", { timeout: 5e3, stdio: "ignore" });
|
|
6343
|
-
} catch {
|
|
6344
|
-
}
|
|
6345
|
-
await new Promise((r) => setTimeout(r, 3e3));
|
|
6346
|
-
const appPath = this.findDockerApp();
|
|
6347
|
-
if (appPath) {
|
|
6348
|
-
await this.setupExistingDockerApp(appPath);
|
|
6349
|
-
return;
|
|
6350
|
-
}
|
|
6325
|
+
if (brewResult.exitCode === 0 && this.findDockerApp()) {
|
|
6326
|
+
installed = true;
|
|
6351
6327
|
}
|
|
6352
6328
|
} catch {
|
|
6353
6329
|
}
|
|
6354
|
-
this.onProgress("__progress__:10:Trying direct download...");
|
|
6355
6330
|
}
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
"
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6331
|
+
if (!installed) {
|
|
6332
|
+
const cpu = arch2();
|
|
6333
|
+
const archName = cpu === "arm64" ? "arm64" : "amd64";
|
|
6334
|
+
const dmgUrl = `https://desktop.docker.com/mac/main/${archName}/Docker.dmg`;
|
|
6335
|
+
const dmgPath = "/tmp/Docker.dmg";
|
|
6336
|
+
this.onProgress("__progress__:5:Downloading Docker Desktop...");
|
|
6337
|
+
const dlResult = await runSilent("curl", [
|
|
6338
|
+
"-fSL",
|
|
6339
|
+
"-o",
|
|
6340
|
+
dmgPath,
|
|
6341
|
+
dmgUrl
|
|
6342
|
+
], { timeout: 6e5 });
|
|
6343
|
+
if (dlResult.exitCode !== 0) {
|
|
6344
|
+
throw new Error("Failed to download Docker Desktop. Check your internet connection and try again.");
|
|
6345
|
+
}
|
|
6346
|
+
this.onProgress("__progress__:40:Installing Docker Desktop...");
|
|
6372
6347
|
try {
|
|
6373
|
-
|
|
6348
|
+
try {
|
|
6349
|
+
execSync("hdiutil detach /Volumes/Docker 2>/dev/null", { timeout: 1e4, stdio: "ignore" });
|
|
6350
|
+
} catch {
|
|
6351
|
+
}
|
|
6352
|
+
execSync(`hdiutil attach "${dmgPath}" -nobrowse -quiet`, { timeout: 3e4, stdio: "ignore" });
|
|
6353
|
+
} catch {
|
|
6354
|
+
throw new Error("Failed to mount Docker DMG. The download may be corrupted \u2014 try again.");
|
|
6355
|
+
}
|
|
6356
|
+
if (!existsSync4("/Applications/Docker.app")) {
|
|
6357
|
+
try {
|
|
6358
|
+
execSync('cp -R "/Volumes/Docker/Docker.app" /Applications/', { timeout: 6e4, stdio: "ignore" });
|
|
6359
|
+
} catch {
|
|
6360
|
+
throw new Error("Failed to install. You may need to run this with admin privileges.");
|
|
6361
|
+
}
|
|
6362
|
+
}
|
|
6363
|
+
try {
|
|
6364
|
+
execSync("hdiutil detach /Volumes/Docker -quiet", { timeout: 15e3, stdio: "ignore" });
|
|
6374
6365
|
} catch {
|
|
6375
6366
|
}
|
|
6376
|
-
execSync(`hdiutil attach "${dmgPath}" -nobrowse -quiet`, { timeout: 3e4, stdio: "ignore" });
|
|
6377
|
-
} catch {
|
|
6378
|
-
throw new Error("Failed to mount Docker DMG. The download may be corrupted \u2014 try again.");
|
|
6379
|
-
}
|
|
6380
|
-
this.onProgress("__progress__:55:Installing...");
|
|
6381
|
-
if (!existsSync4("/Applications/Docker.app")) {
|
|
6382
6367
|
try {
|
|
6383
|
-
|
|
6368
|
+
await unlink(dmgPath);
|
|
6384
6369
|
} catch {
|
|
6385
|
-
throw new Error("Failed to install. You may need to run this with admin privileges.");
|
|
6386
6370
|
}
|
|
6387
6371
|
}
|
|
6388
6372
|
try {
|
|
6389
|
-
execSync(
|
|
6373
|
+
execSync(`osascript -e 'quit app "Docker Desktop"' 2>/dev/null`, { timeout: 5e3, stdio: "ignore" });
|
|
6390
6374
|
} catch {
|
|
6391
6375
|
}
|
|
6392
6376
|
try {
|
|
6393
|
-
|
|
6377
|
+
execSync(`osascript -e 'quit app "Docker"' 2>/dev/null`, { timeout: 5e3, stdio: "ignore" });
|
|
6394
6378
|
} catch {
|
|
6395
6379
|
}
|
|
6396
|
-
this._firstLaunchMode = true;
|
|
6397
|
-
this.onProgress("__progress__:70:Please accept the Docker license agreement...");
|
|
6398
6380
|
try {
|
|
6399
|
-
|
|
6381
|
+
execSync("pkill -f Docker.app 2>/dev/null", { timeout: 5e3, stdio: "ignore" });
|
|
6400
6382
|
} catch {
|
|
6401
6383
|
}
|
|
6402
|
-
await
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
const user = process.env.USER || execSync("whoami", { timeout: 5e3 }).toString().trim();
|
|
6407
|
-
try {
|
|
6408
|
-
execSync(`"${installBin}" --accept-license --user=${user}`, {
|
|
6409
|
-
timeout: 12e4,
|
|
6410
|
-
stdio: "ignore"
|
|
6411
|
-
});
|
|
6412
|
-
} catch {
|
|
6413
|
-
}
|
|
6384
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
6385
|
+
const appPath = this.findDockerApp();
|
|
6386
|
+
if (!appPath) {
|
|
6387
|
+
throw new Error("Docker Desktop was installed but could not be found. Try again.");
|
|
6414
6388
|
}
|
|
6415
|
-
this.
|
|
6416
|
-
this.hideDockerWindow();
|
|
6389
|
+
await this.setupExistingDockerApp(appPath);
|
|
6417
6390
|
}
|
|
6418
6391
|
/**
|
|
6419
6392
|
* Install Docker Engine on Linux using Docker's official convenience script.
|
|
@@ -6727,7 +6700,7 @@ var DependencyInstaller = class {
|
|
|
6727
6700
|
|
|
6728
6701
|
// src/setup/service.ts
|
|
6729
6702
|
import { execFileSync as execFileSync3, execSync as execSync2 } from "child_process";
|
|
6730
|
-
import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync4, unlinkSync, mkdirSync as
|
|
6703
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync4, unlinkSync, mkdirSync as mkdirSync4 } from "fs";
|
|
6731
6704
|
import { join as join7 } from "path";
|
|
6732
6705
|
import { homedir as homedir6, platform as platform3 } from "os";
|
|
6733
6706
|
var PLIST_LABEL = "com.agenticmail.server";
|
|
@@ -6800,7 +6773,7 @@ var ServiceManager = class {
|
|
|
6800
6773
|
*/
|
|
6801
6774
|
cacheApiEntryPath(entryPath) {
|
|
6802
6775
|
const dataDir = join7(homedir6(), ".agenticmail");
|
|
6803
|
-
if (!existsSync5(dataDir))
|
|
6776
|
+
if (!existsSync5(dataDir)) mkdirSync4(dataDir, { recursive: true });
|
|
6804
6777
|
writeFileSync4(join7(dataDir, "api-entry.path"), entryPath);
|
|
6805
6778
|
}
|
|
6806
6779
|
/**
|
|
@@ -6834,7 +6807,7 @@ var ServiceManager = class {
|
|
|
6834
6807
|
generateStartScript(nodePath, apiEntry) {
|
|
6835
6808
|
const scriptPath = join7(homedir6(), ".agenticmail", "bin", "start-server.sh");
|
|
6836
6809
|
const scriptDir = join7(homedir6(), ".agenticmail", "bin");
|
|
6837
|
-
if (!existsSync5(scriptDir))
|
|
6810
|
+
if (!existsSync5(scriptDir)) mkdirSync4(scriptDir, { recursive: true });
|
|
6838
6811
|
const script = [
|
|
6839
6812
|
"#!/bin/bash",
|
|
6840
6813
|
"# AgenticMail auto-start script",
|
|
@@ -6900,7 +6873,7 @@ var ServiceManager = class {
|
|
|
6900
6873
|
generatePlist(nodePath, apiEntry, configPath) {
|
|
6901
6874
|
const config = JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
6902
6875
|
const logDir = join7(homedir6(), ".agenticmail", "logs");
|
|
6903
|
-
if (!existsSync5(logDir))
|
|
6876
|
+
if (!existsSync5(logDir)) mkdirSync4(logDir, { recursive: true });
|
|
6904
6877
|
const version = this.getVersion();
|
|
6905
6878
|
const startScript = this.generateStartScript(nodePath, apiEntry);
|
|
6906
6879
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -7051,7 +7024,7 @@ WantedBy=default.target
|
|
|
7051
7024
|
const servicePath = this.getServicePath();
|
|
7052
7025
|
if (this.os === "darwin") {
|
|
7053
7026
|
const dir = join7(homedir6(), "Library", "LaunchAgents");
|
|
7054
|
-
if (!existsSync5(dir))
|
|
7027
|
+
if (!existsSync5(dir)) mkdirSync4(dir, { recursive: true });
|
|
7055
7028
|
if (existsSync5(servicePath)) {
|
|
7056
7029
|
try {
|
|
7057
7030
|
execFileSync3("launchctl", ["unload", servicePath], { timeout: 1e4, stdio: "ignore" });
|
|
@@ -7068,7 +7041,7 @@ WantedBy=default.target
|
|
|
7068
7041
|
return { installed: true, message: `Service installed at ${servicePath}` };
|
|
7069
7042
|
} else if (this.os === "linux") {
|
|
7070
7043
|
const dir = join7(homedir6(), ".config", "systemd", "user");
|
|
7071
|
-
if (!existsSync5(dir))
|
|
7044
|
+
if (!existsSync5(dir)) mkdirSync4(dir, { recursive: true });
|
|
7072
7045
|
const unit = this.generateSystemdUnit(nodePath, apiEntry, configPath);
|
|
7073
7046
|
writeFileSync4(servicePath, unit);
|
|
7074
7047
|
try {
|
|
@@ -7228,7 +7201,7 @@ var SetupManager = class {
|
|
|
7228
7201
|
}
|
|
7229
7202
|
}
|
|
7230
7203
|
if (!existsSync6(dataDir)) {
|
|
7231
|
-
|
|
7204
|
+
mkdirSync5(dataDir, { recursive: true });
|
|
7232
7205
|
}
|
|
7233
7206
|
const masterKey = `mk_${randomBytes2(24).toString("hex")}`;
|
|
7234
7207
|
const stalwartPassword = randomBytes2(16).toString("hex");
|
|
@@ -7272,7 +7245,7 @@ IMAP_PORT=143
|
|
|
7272
7245
|
generateDockerFiles(config) {
|
|
7273
7246
|
const dataDir = config.dataDir || join8(homedir7(), ".agenticmail");
|
|
7274
7247
|
if (!existsSync6(dataDir)) {
|
|
7275
|
-
|
|
7248
|
+
mkdirSync5(dataDir, { recursive: true });
|
|
7276
7249
|
}
|
|
7277
7250
|
const password = config.stalwart?.adminPassword || "changeme";
|
|
7278
7251
|
const composePath = join8(dataDir, "docker-compose.yml");
|