agenticmail 0.4.0 → 0.5.1
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/cli.js +195 -11
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,8 @@ import { createRequire } from "module";
|
|
|
9
9
|
import { homedir } from "os";
|
|
10
10
|
import JSON5 from "json5";
|
|
11
11
|
import {
|
|
12
|
-
SetupManager
|
|
12
|
+
SetupManager,
|
|
13
|
+
ServiceManager
|
|
13
14
|
} from "@agenticmail/core";
|
|
14
15
|
|
|
15
16
|
// src/shell.ts
|
|
@@ -4215,6 +4216,8 @@ var c2 = {
|
|
|
4215
4216
|
yellow: (s) => `\x1B[33m${s}\x1B[0m`,
|
|
4216
4217
|
cyan: (s) => `\x1B[36m${s}\x1B[0m`,
|
|
4217
4218
|
magenta: (s) => `\x1B[35m${s}\x1B[0m`,
|
|
4219
|
+
pink: (s) => `\x1B[38;5;205m${s}\x1B[0m`,
|
|
4220
|
+
pinkBg: (s) => `\x1B[48;5;205m\x1B[97m${s}\x1B[0m`,
|
|
4218
4221
|
dim: (s) => `\x1B[90m${s}\x1B[0m`,
|
|
4219
4222
|
bold: (s) => `\x1B[1m${s}\x1B[0m`,
|
|
4220
4223
|
bgGreen: (s) => `\x1B[42m\x1B[30m${s}\x1B[0m`,
|
|
@@ -4299,6 +4302,8 @@ var Spinner = class {
|
|
|
4299
4302
|
msgChangeCounter = 0;
|
|
4300
4303
|
category;
|
|
4301
4304
|
currentMsg;
|
|
4305
|
+
progressPct = -1;
|
|
4306
|
+
// -1 = no progress bar
|
|
4302
4307
|
constructor(category, initialMsg) {
|
|
4303
4308
|
this.category = category;
|
|
4304
4309
|
const msgs = LOADING_MESSAGES[category] ?? LOADING_MESSAGES.general;
|
|
@@ -4308,13 +4313,23 @@ var Spinner = class {
|
|
|
4308
4313
|
this.frameIdx = 0;
|
|
4309
4314
|
this.msgIdx = 0;
|
|
4310
4315
|
this.msgChangeCounter = 0;
|
|
4316
|
+
this.progressPct = -1;
|
|
4311
4317
|
const msgs = LOADING_MESSAGES[this.category] ?? LOADING_MESSAGES.general;
|
|
4312
4318
|
this.interval = setInterval(() => {
|
|
4313
4319
|
const frame = SPINNER_FRAMES[this.frameIdx % SPINNER_FRAMES.length];
|
|
4314
|
-
|
|
4320
|
+
if (this.progressPct >= 0) {
|
|
4321
|
+
const barWidth = 20;
|
|
4322
|
+
const filled = Math.round(this.progressPct / 100 * barWidth);
|
|
4323
|
+
const empty = barWidth - filled;
|
|
4324
|
+
const bar = c2.pink("\u2588".repeat(filled)) + c2.dim("\u2591".repeat(empty));
|
|
4325
|
+
const pctStr = c2.pink(`${this.progressPct}%`);
|
|
4326
|
+
process.stdout.write(`\r ${c2.pink(frame)} ${bar} ${pctStr} ${c2.dim(this.currentMsg)}\x1B[K`);
|
|
4327
|
+
} else {
|
|
4328
|
+
process.stdout.write(`\r ${c2.cyan(frame)} ${c2.yellow(this.currentMsg)}\x1B[K`);
|
|
4329
|
+
}
|
|
4315
4330
|
this.frameIdx++;
|
|
4316
4331
|
this.msgChangeCounter++;
|
|
4317
|
-
if (this.msgChangeCounter >= 30) {
|
|
4332
|
+
if (this.msgChangeCounter >= 30 && this.progressPct < 0) {
|
|
4318
4333
|
this.msgChangeCounter = 0;
|
|
4319
4334
|
this.msgIdx = (this.msgIdx + 1) % msgs.length;
|
|
4320
4335
|
this.currentMsg = msgs[this.msgIdx];
|
|
@@ -4322,7 +4337,13 @@ var Spinner = class {
|
|
|
4322
4337
|
}, 100);
|
|
4323
4338
|
}
|
|
4324
4339
|
update(msg) {
|
|
4325
|
-
|
|
4340
|
+
const match = msg.match(/^__progress__:(\d+):(.*)$/);
|
|
4341
|
+
if (match) {
|
|
4342
|
+
this.progressPct = Math.min(100, parseInt(match[1], 10));
|
|
4343
|
+
this.currentMsg = match[2];
|
|
4344
|
+
} else {
|
|
4345
|
+
this.currentMsg = msg;
|
|
4346
|
+
}
|
|
4326
4347
|
this.msgChangeCounter = 0;
|
|
4327
4348
|
}
|
|
4328
4349
|
succeed(msg) {
|
|
@@ -4408,6 +4429,10 @@ async function startApiServer(config) {
|
|
|
4408
4429
|
const { spawn } = await import("child_process");
|
|
4409
4430
|
const apiEntry = resolveApiEntry();
|
|
4410
4431
|
const env = configToEnv(config);
|
|
4432
|
+
try {
|
|
4433
|
+
new ServiceManager().cacheApiEntryPath(apiEntry);
|
|
4434
|
+
} catch {
|
|
4435
|
+
}
|
|
4411
4436
|
const child = spawn(process.execPath, [apiEntry], {
|
|
4412
4437
|
detached: true,
|
|
4413
4438
|
stdio: "ignore",
|
|
@@ -4542,14 +4567,41 @@ async function cmdSetup() {
|
|
|
4542
4567
|
{
|
|
4543
4568
|
const spinner = new Spinner("docker");
|
|
4544
4569
|
spinner.start();
|
|
4570
|
+
const dockerSetup = new SetupManager((msg) => spinner.update(msg));
|
|
4545
4571
|
try {
|
|
4546
|
-
await
|
|
4572
|
+
await dockerSetup.ensureDocker();
|
|
4547
4573
|
spinner.succeed(`${c2.bold("Docker")} \u2014 engine running`);
|
|
4548
4574
|
} catch (err) {
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4575
|
+
const msg = err.message;
|
|
4576
|
+
if (msg === "DOCKER_MANUAL_START") {
|
|
4577
|
+
spinner.fail(`Docker installed but couldn't start automatically`);
|
|
4578
|
+
log2("");
|
|
4579
|
+
log2(` ${c2.pink(c2.bold("Don't worry! Here's how to fix this:"))}`);
|
|
4580
|
+
log2("");
|
|
4581
|
+
log2(` ${c2.pink("Step 1:")} Open a ${c2.bold("new terminal window")}`);
|
|
4582
|
+
log2(` ${c2.dim("(Command + T on Mac, or open Terminal from your dock)")}`);
|
|
4583
|
+
log2("");
|
|
4584
|
+
log2(` ${c2.pink("Step 2:")} Run this command:`);
|
|
4585
|
+
log2(` ${c2.cyan("open -a Docker")}`);
|
|
4586
|
+
log2("");
|
|
4587
|
+
log2(` ${c2.pink("Step 3:")} Wait for Docker Desktop to fully load`);
|
|
4588
|
+
log2(` ${c2.dim("You'll see a whale icon in your menu bar (top of screen).")}`);
|
|
4589
|
+
log2(` ${c2.dim("Wait until it stops animating \u2014 that means it's ready.")}`);
|
|
4590
|
+
log2("");
|
|
4591
|
+
log2(` ${c2.pink("Step 4:")} Close that terminal window`);
|
|
4592
|
+
log2(` ${c2.dim("Just close the window normally (Command + W). Don't press Ctrl+C.")}`);
|
|
4593
|
+
log2("");
|
|
4594
|
+
log2(` ${c2.pink("Step 5:")} Come back here and run:`);
|
|
4595
|
+
log2(` ${c2.green("npx agenticmail@latest")}`);
|
|
4596
|
+
log2("");
|
|
4597
|
+
log2(` ${c2.dim("That's it! Docker only needs this manual start the first time.")}`);
|
|
4598
|
+
log2(` ${c2.dim("After that, it starts automatically.")}`);
|
|
4599
|
+
} else {
|
|
4600
|
+
spinner.fail(`Couldn't start Docker: ${msg}`);
|
|
4601
|
+
log2("");
|
|
4602
|
+
log2(` ${c2.yellow("Tip:")} Install Docker manually from ${c2.cyan("https://docker.com/get-docker")}`);
|
|
4603
|
+
log2(` ${c2.dim("Then run")} ${c2.green("agenticmail setup")} ${c2.dim("again.")}`);
|
|
4604
|
+
}
|
|
4553
4605
|
process.exit(1);
|
|
4554
4606
|
}
|
|
4555
4607
|
await new Promise((r) => setTimeout(r, 300));
|
|
@@ -4558,8 +4610,9 @@ async function cmdSetup() {
|
|
|
4558
4610
|
if (!stalwart?.installed) {
|
|
4559
4611
|
const spinner = new Spinner("stalwart");
|
|
4560
4612
|
spinner.start();
|
|
4613
|
+
const stalwartSetup = new SetupManager((msg) => spinner.update(msg));
|
|
4561
4614
|
try {
|
|
4562
|
-
await
|
|
4615
|
+
await stalwartSetup.ensureStalwart();
|
|
4563
4616
|
spinner.succeed(`${c2.bold("Mail Server")} \u2014 up and running!`);
|
|
4564
4617
|
} catch (err) {
|
|
4565
4618
|
spinner.fail(`Couldn't start the mail server: ${err.message}`);
|
|
@@ -4831,6 +4884,23 @@ async function cmdSetup() {
|
|
|
4831
4884
|
log2("");
|
|
4832
4885
|
await registerWithOpenClaw(result.config);
|
|
4833
4886
|
}
|
|
4887
|
+
if (serverReady) {
|
|
4888
|
+
const svcSpinner = new Spinner("general", "Setting up auto-start...");
|
|
4889
|
+
svcSpinner.start();
|
|
4890
|
+
try {
|
|
4891
|
+
const svc = new ServiceManager();
|
|
4892
|
+
const svcResult = svc.install();
|
|
4893
|
+
if (svcResult.installed) {
|
|
4894
|
+
svcSpinner.succeed(`${c2.bold("Auto-start")} \u2014 AgenticMail will start on boot`);
|
|
4895
|
+
} else {
|
|
4896
|
+
svcSpinner.fail(`Auto-start: ${svcResult.message}`);
|
|
4897
|
+
info2("You can set this up later with: agenticmail service install");
|
|
4898
|
+
}
|
|
4899
|
+
} catch (err) {
|
|
4900
|
+
svcSpinner.fail(`Auto-start: ${err.message}`);
|
|
4901
|
+
}
|
|
4902
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
4903
|
+
}
|
|
4834
4904
|
printSummary(result, false);
|
|
4835
4905
|
if (serverReady) {
|
|
4836
4906
|
await interactiveShell({ config: result.config, onExit: () => {
|
|
@@ -6175,6 +6245,23 @@ async function cmdStatus() {
|
|
|
6175
6245
|
info2("Can't check email status \u2014 server isn't running");
|
|
6176
6246
|
}
|
|
6177
6247
|
log2("");
|
|
6248
|
+
log2(` ${c2.bold("Auto-Start:")}`);
|
|
6249
|
+
try {
|
|
6250
|
+
const svc = new ServiceManager();
|
|
6251
|
+
const svcStatus = svc.status();
|
|
6252
|
+
if (svcStatus.installed) {
|
|
6253
|
+
if (svcStatus.running) {
|
|
6254
|
+
ok2(`Enabled ${c2.dim(`(${svcStatus.platform}) \u2014 starts on boot`)}`);
|
|
6255
|
+
} else {
|
|
6256
|
+
ok2(`Installed ${c2.dim(`(${svcStatus.platform})`)} \u2014 ${c2.yellow("not currently running")}`);
|
|
6257
|
+
}
|
|
6258
|
+
} else {
|
|
6259
|
+
fail2(`Not installed ${c2.dim("\u2014 run: agenticmail service install")}`);
|
|
6260
|
+
}
|
|
6261
|
+
} catch {
|
|
6262
|
+
info2("Could not check auto-start status");
|
|
6263
|
+
}
|
|
6264
|
+
log2("");
|
|
6178
6265
|
}
|
|
6179
6266
|
async function cmdStart() {
|
|
6180
6267
|
const setup = new SetupManager();
|
|
@@ -6225,19 +6312,107 @@ async function cmdStart() {
|
|
|
6225
6312
|
serverSpinner.fail(`Couldn't start the server: ${err.message}`);
|
|
6226
6313
|
process.exit(1);
|
|
6227
6314
|
}
|
|
6315
|
+
try {
|
|
6316
|
+
const svc = new ServiceManager();
|
|
6317
|
+
const svcStatus = svc.status();
|
|
6318
|
+
if (!svcStatus.installed) {
|
|
6319
|
+
const svcResult = svc.install();
|
|
6320
|
+
if (svcResult.installed) {
|
|
6321
|
+
ok2(`${c2.bold("Auto-start")} enabled \u2014 survives reboots`);
|
|
6322
|
+
}
|
|
6323
|
+
}
|
|
6324
|
+
} catch {
|
|
6325
|
+
}
|
|
6228
6326
|
await interactiveShell({ config, onExit: () => {
|
|
6229
6327
|
} });
|
|
6230
6328
|
}
|
|
6231
6329
|
async function cmdStop() {
|
|
6232
6330
|
log2("");
|
|
6233
6331
|
const stopped = stopApiServer();
|
|
6234
|
-
|
|
6332
|
+
const svc = new ServiceManager();
|
|
6333
|
+
const svcStatus = svc.status();
|
|
6334
|
+
if (svcStatus.installed && svcStatus.running) {
|
|
6335
|
+
try {
|
|
6336
|
+
if (svcStatus.platform === "launchd") {
|
|
6337
|
+
const { execFileSync } = await import("child_process");
|
|
6338
|
+
execFileSync("launchctl", ["unload", svcStatus.servicePath], { timeout: 1e4, stdio: "ignore" });
|
|
6339
|
+
} else if (svcStatus.platform === "systemd") {
|
|
6340
|
+
const { execFileSync } = await import("child_process");
|
|
6341
|
+
execFileSync("systemctl", ["--user", "stop", "agenticmail.service"], { timeout: 1e4, stdio: "ignore" });
|
|
6342
|
+
}
|
|
6343
|
+
} catch {
|
|
6344
|
+
}
|
|
6345
|
+
}
|
|
6346
|
+
if (stopped || svcStatus.installed && svcStatus.running) {
|
|
6235
6347
|
ok2("AgenticMail server stopped");
|
|
6348
|
+
if (svcStatus.installed) {
|
|
6349
|
+
info2("Auto-start is still enabled. It will restart on next boot.");
|
|
6350
|
+
info2(`To disable: ${c2.green("agenticmail service uninstall")}`);
|
|
6351
|
+
}
|
|
6236
6352
|
} else {
|
|
6237
6353
|
info2("Server is not running");
|
|
6238
6354
|
}
|
|
6239
6355
|
log2("");
|
|
6240
6356
|
}
|
|
6357
|
+
async function cmdService() {
|
|
6358
|
+
const subCmd = process.argv[3] || "status";
|
|
6359
|
+
const svc = new ServiceManager();
|
|
6360
|
+
log2("");
|
|
6361
|
+
switch (subCmd) {
|
|
6362
|
+
case "install": {
|
|
6363
|
+
const result = svc.install();
|
|
6364
|
+
if (result.installed) {
|
|
6365
|
+
ok2(`Auto-start service installed`);
|
|
6366
|
+
info2(result.message);
|
|
6367
|
+
info2("AgenticMail will now start automatically when your computer boots.");
|
|
6368
|
+
} else {
|
|
6369
|
+
fail2(result.message);
|
|
6370
|
+
}
|
|
6371
|
+
break;
|
|
6372
|
+
}
|
|
6373
|
+
case "uninstall":
|
|
6374
|
+
case "remove": {
|
|
6375
|
+
const result = svc.uninstall();
|
|
6376
|
+
if (result.removed) {
|
|
6377
|
+
ok2("Auto-start service removed");
|
|
6378
|
+
info2("AgenticMail will no longer start on boot.");
|
|
6379
|
+
} else {
|
|
6380
|
+
fail2(result.message);
|
|
6381
|
+
}
|
|
6382
|
+
break;
|
|
6383
|
+
}
|
|
6384
|
+
case "reinstall": {
|
|
6385
|
+
const result = svc.reinstall();
|
|
6386
|
+
if (result.installed) {
|
|
6387
|
+
ok2("Auto-start service reinstalled");
|
|
6388
|
+
info2(result.message);
|
|
6389
|
+
} else {
|
|
6390
|
+
fail2(result.message);
|
|
6391
|
+
}
|
|
6392
|
+
break;
|
|
6393
|
+
}
|
|
6394
|
+
case "status":
|
|
6395
|
+
default: {
|
|
6396
|
+
const status = svc.status();
|
|
6397
|
+
log2(` ${c2.bold("Auto-Start Service")}`);
|
|
6398
|
+
log2("");
|
|
6399
|
+
if (status.installed) {
|
|
6400
|
+
ok2(`Installed ${c2.dim(`(${status.platform})`)}`);
|
|
6401
|
+
if (status.running) {
|
|
6402
|
+
ok2(`Running`);
|
|
6403
|
+
} else {
|
|
6404
|
+
fail2(`Not running ${c2.dim("\u2014 will start on next boot or: agenticmail service reinstall")}`);
|
|
6405
|
+
}
|
|
6406
|
+
info2(`Service file: ${status.servicePath}`);
|
|
6407
|
+
} else {
|
|
6408
|
+
fail2("Not installed");
|
|
6409
|
+
info2(`Install with: ${c2.green("agenticmail service install")}`);
|
|
6410
|
+
}
|
|
6411
|
+
break;
|
|
6412
|
+
}
|
|
6413
|
+
}
|
|
6414
|
+
log2("");
|
|
6415
|
+
}
|
|
6241
6416
|
async function cmdUpdate() {
|
|
6242
6417
|
const { execSync } = await import("child_process");
|
|
6243
6418
|
log2("");
|
|
@@ -6362,6 +6537,14 @@ switch (command) {
|
|
|
6362
6537
|
process.exit(1);
|
|
6363
6538
|
});
|
|
6364
6539
|
break;
|
|
6540
|
+
case "service":
|
|
6541
|
+
cmdService().then(() => {
|
|
6542
|
+
process.exit(0);
|
|
6543
|
+
}).catch((err) => {
|
|
6544
|
+
console.error(err);
|
|
6545
|
+
process.exit(1);
|
|
6546
|
+
});
|
|
6547
|
+
break;
|
|
6365
6548
|
case "update":
|
|
6366
6549
|
cmdUpdate().catch((err) => {
|
|
6367
6550
|
console.error(err);
|
|
@@ -6381,6 +6564,7 @@ switch (command) {
|
|
|
6381
6564
|
log2(` ${c2.green("agenticmail stop")} Stop the server`);
|
|
6382
6565
|
log2(` ${c2.green("agenticmail status")} See what's running`);
|
|
6383
6566
|
log2(` ${c2.green("agenticmail openclaw")} Set up AgenticMail for OpenClaw`);
|
|
6567
|
+
log2(` ${c2.green("agenticmail service")} Manage auto-start (install/uninstall/status)`);
|
|
6384
6568
|
log2(` ${c2.green("agenticmail update")} Update to the latest version`);
|
|
6385
6569
|
log2("");
|
|
6386
6570
|
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agenticmail",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Email infrastructure for AI agents — send and receive real email programmatically",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"prepublishOnly": "npm run build"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@agenticmail/api": "^0.
|
|
30
|
-
"@agenticmail/core": "^0.
|
|
29
|
+
"@agenticmail/api": "^0.5.0",
|
|
30
|
+
"@agenticmail/core": "^0.5.0",
|
|
31
31
|
"json5": "^2.2.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|