@agenticmail/cli 0.8.18 → 0.8.21

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/README.md CHANGED
@@ -23,6 +23,19 @@ It bundles a setup wizard, API server launcher, and a full interactive shell wit
23
23
  >
24
24
  > Zero prompts, ~2 minutes, fully autonomous. Then tell the user to restart Claude Code. Full agent-facing runbook — including verification, common failures, and "what if Node < 22" — is at [`AGENTS.md`](https://github.com/agenticmail/agenticmail/blob/main/AGENTS.md) in the repo (the [agents.md](https://agents.md) convention).
25
25
 
26
+ ## ✨ What's new in 0.8.19
27
+
28
+ - **🌐 Gmail-style web UI** — open every agent's inbox in your browser with `agenticmail web`. Three-pane layout, full markdown rendering, real-time SSE updates, compose + reply with the new `wake` parameter as a first-class field.
29
+ - **`wake: ["alice", "bob"]`** on `send_email` / `reply_email` / `forward_email` / `template_send` / `manage_drafts(send)` tells the dispatcher to give a Claude turn only to named agents — the biggest token saver on large threads.
30
+ - **`[FINAL]` / `[DONE]` / `[CLOSED]` / `[WRAP]` in a subject** closes a thread — the dispatcher stops waking workers on any further reply to it.
31
+ - **`check_activity` MCP tool** — see which agents the dispatcher has woken right now and how long they've been running.
32
+ - **Comprehensive markdown rendering** in the shell's email viewer — bold, italic, headings, lists, task lists, tables, fenced code, links, images, HTML entities, depth-colored quote stripes.
33
+ - **LLM-tolerant inputs** — `batch_mark_read({ uids: "[1,2,3]" })` and other common stringification mistakes now just work.
34
+ - **Wake-budget circuit breaker** — caps per-(agent, thread) wakes at 10/24h to stop reply loops and storms.
35
+ - **Inbox refresh keybind** — press `r` in the shell inbox navigator to refresh without leaving.
36
+
37
+ Full release notes in [CHANGELOG.md](https://github.com/agenticmail/agenticmail/blob/main/CHANGELOG.md).
38
+
26
39
  ## Install
27
40
 
28
41
  ```bash
@@ -107,6 +120,7 @@ All commands are available via `agenticmail <command>` or `npx @agenticmail/cli@
107
120
  | `agenticmail setup` | **Run the setup wizard.** Walks you through system checks, account creation, service startup, email connection, phone number setup, and OpenClaw integration. Safe to re-run anytime. |
108
121
  | `agenticmail start` | **Start the server and open the interactive shell.** Ensures Docker is running, Stalwart is up, and the API server is reachable. Automatically installs the auto-start service. |
109
122
  | `agenticmail shell` | **Drop into the interactive shell against the already-running server.** Use this when the server is already up (started by `agenticmail start`, `agenticmail bootstrap`, or the auto-start service) and you want to monitor every agent's inbox, send mail on their behalf, watch the dispatcher event feed, or run any of the 44+ shell commands. Exits cleanly with `/exit` — the server keeps running. |
123
+ | `agenticmail web` | 🌐 **Open the lightweight Gmail-style web UI in your browser.** Three-pane layout (agents / inbox / message), real-time SSE updates, full markdown rendering, compose + reply with the `wake` parameter surfaced as a field. Same master key as the API. Available at `http://127.0.0.1:3829/` whenever the API is running. |
110
124
  | `agenticmail stop` | **Stop the server.** Kills the background API server process. If auto-start is enabled, it will restart on next boot. |
111
125
  | `agenticmail status` | **Show what's running.** Displays Docker, Stalwart, API server, email connection, and auto-start service status. |
112
126
 
@@ -523,7 +537,7 @@ import {
523
537
  type ParsedEmail,
524
538
  type Agent,
525
539
  type GatewayConfig,
526
- } from 'agenticmail';
540
+ } from '@agenticmail/cli';
527
541
  ```
528
542
 
529
543
  See the [@agenticmail/core README](https://github.com/agenticmail/agenticmail/tree/main/packages/core) for complete SDK documentation.
@@ -610,12 +624,14 @@ Errors return JSON: `400` (missing `name`/`columns`), `409` (table already exist
610
624
 
611
625
  ### `agenticmail: command not found`
612
626
 
613
- If you installed locally with `npm install agenticmail`, use `npx agenticmail` instead. For a global install:
627
+ If you installed locally with `npm install @agenticmail/cli`, use `npx agenticmail` instead. For a global install:
614
628
 
615
629
  ```bash
616
630
  npm install -g @agenticmail/cli
617
631
  ```
618
632
 
633
+ > Note: the unscoped `agenticmail` package on npm is a zero-dependency redirect stub (since v0.8.20). The real CLI is `@agenticmail/cli`. If you accidentally installed `agenticmail` without the scope, run `npm uninstall -g agenticmail` and then `npm install -g @agenticmail/cli@latest`.
634
+
619
635
  ---
620
636
 
621
637
  ## License
package/dist/cli.js CHANGED
@@ -4224,7 +4224,7 @@ ${c.dim(boxChar.bl + boxChar.h.repeat(bWidth) + boxChar.br)}`);
4224
4224
  info(`Current version: ${c.bold(currentVersion)}`);
4225
4225
  let latestVersion = "unknown";
4226
4226
  try {
4227
- latestVersion = execSync("npm view agenticmail version", { encoding: "utf-8", timeout: 15e3 }).trim();
4227
+ latestVersion = execSync("npm view @agenticmail/cli version", { encoding: "utf-8", timeout: 15e3 }).trim();
4228
4228
  } catch {
4229
4229
  fail("Could not check npm for latest version. Check your internet connection.");
4230
4230
  return;
@@ -4247,7 +4247,7 @@ ${c.dim(boxChar.bl + boxChar.h.repeat(bWidth) + boxChar.br)}`);
4247
4247
  if (hasOpenClaw) {
4248
4248
  info(`OpenClaw detected: ${c.bold(openClawVersion)}`);
4249
4249
  try {
4250
- const peerDeps = execSync(`npm view agenticmail@${latestVersion} peerDependencies --json 2>/dev/null`, { encoding: "utf-8", timeout: 15e3 }).trim();
4250
+ const peerDeps = execSync(`npm view @agenticmail/cli@${latestVersion} peerDependencies --json 2>/dev/null`, { encoding: "utf-8", timeout: 15e3 }).trim();
4251
4251
  if (peerDeps) {
4252
4252
  const deps = JSON.parse(peerDeps);
4253
4253
  if (deps.openclaw) {
@@ -4283,12 +4283,19 @@ ${c.dim(boxChar.bl + boxChar.h.repeat(bWidth) + boxChar.br)}`);
4283
4283
  }
4284
4284
  let isGlobal = false;
4285
4285
  try {
4286
- const globalList = execSync(`${pm === "npm" ? "npm" : pm} list -g agenticmail 2>/dev/null`, { encoding: "utf-8", timeout: 1e4 });
4287
- if (globalList.includes("agenticmail")) isGlobal = true;
4286
+ const globalList = execSync(`${pm} list -g @agenticmail/cli 2>/dev/null`, { encoding: "utf-8", timeout: 1e4 });
4287
+ if (globalList.includes("@agenticmail/cli")) isGlobal = true;
4288
4288
  } catch {
4289
4289
  }
4290
+ if (!isGlobal) {
4291
+ try {
4292
+ const globalList = execSync(`${pm} list -g agenticmail 2>/dev/null`, { encoding: "utf-8", timeout: 1e4 });
4293
+ if (globalList.includes("agenticmail")) isGlobal = true;
4294
+ } catch {
4295
+ }
4296
+ }
4290
4297
  const scope = isGlobal ? "-g" : "";
4291
- const installCmd = pm === "bun" ? `bun add ${scope} agenticmail@latest` : `${pm} install ${scope} agenticmail@latest`;
4298
+ const installCmd = pm === "bun" ? `bun add ${scope} @agenticmail/cli@latest` : `${pm} install ${scope} @agenticmail/cli@latest`;
4292
4299
  info(`Running: ${c.dim(installCmd)}`);
4293
4300
  execSync(installCmd, { stdio: "inherit", timeout: 12e4 });
4294
4301
  if (hasOpenClaw) {
@@ -4309,12 +4316,12 @@ ${c.dim(boxChar.bl + boxChar.h.repeat(bWidth) + boxChar.br)}`);
4309
4316
  }
4310
4317
  }
4311
4318
  log("");
4312
- ok(`Updated to agenticmail@${latestVersion}`);
4319
+ ok(`Updated to @agenticmail/cli@${latestVersion}`);
4313
4320
  info("Restart the shell to use the new version.");
4314
4321
  log("");
4315
4322
  } catch (err) {
4316
4323
  fail(`Update failed: ${err.message}`);
4317
- info(`Try manually: ${c.green("npm install -g agenticmail@latest")}`);
4324
+ info(`Try manually: ${c.green("npm install -g @agenticmail/cli@latest")}`);
4318
4325
  log("");
4319
4326
  }
4320
4327
  }
@@ -6922,6 +6929,61 @@ async function isTunnelConfigured() {
6922
6929
  return false;
6923
6930
  }
6924
6931
  }
6932
+ async function cmdWeb() {
6933
+ log2("");
6934
+ log2(` ${c2.pinkBg(" \u{1F380} AgenticMail web UI ")}`);
6935
+ log2("");
6936
+ const configPath = join(homedir(), ".agenticmail", "config.json");
6937
+ if (!existsSync2(configPath)) {
6938
+ log2(` ${c2.red("\u2717")} AgenticMail isn't set up yet. Run ${c2.green("agenticmail setup")} first.`);
6939
+ log2("");
6940
+ return;
6941
+ }
6942
+ const { apiUrl } = readApiUrlFromConfig();
6943
+ let masterKey = "";
6944
+ try {
6945
+ const cfg = JSON.parse(readFileSync2(configPath, "utf-8"));
6946
+ if (typeof cfg?.masterKey === "string") masterKey = cfg.masterKey;
6947
+ } catch {
6948
+ }
6949
+ const url = masterKey ? `${apiUrl}/?key=${encodeURIComponent(masterKey)}` : apiUrl;
6950
+ let alive = false;
6951
+ try {
6952
+ const resp = await fetch(`${url}/api/agenticmail/health`, { signal: AbortSignal.timeout(2e3) });
6953
+ alive = resp.ok;
6954
+ } catch {
6955
+ }
6956
+ if (!alive) {
6957
+ log2(` ${c2.red("\u2717")} API server not reachable at ${c2.cyan(url)}.`);
6958
+ log2(` Start it with ${c2.green("agenticmail start")} (in another terminal) or ${c2.green("agenticmail service install")}.`);
6959
+ log2("");
6960
+ return;
6961
+ }
6962
+ log2(` ${c2.green("\u2713")} API server is running at ${c2.cyan(apiUrl)}`);
6963
+ log2("");
6964
+ if (masterKey) {
6965
+ log2(` ${c2.bold("Opening the web UI \u2014 you'll be signed in automatically.")}`);
6966
+ log2("");
6967
+ log2(` ${c2.dim(apiUrl)}`);
6968
+ } else {
6969
+ log2(` ${c2.yellow("!")} ${c2.bold("Master key not found in config; you'll need to paste it manually.")}`);
6970
+ log2("");
6971
+ log2(` ${c2.green(apiUrl)}`);
6972
+ log2("");
6973
+ log2(` ${c2.dim("When prompted:")}`);
6974
+ log2(` ${c2.dim("cat ~/.agenticmail/config.json | grep masterKey")}`);
6975
+ }
6976
+ log2("");
6977
+ const platform = process.platform;
6978
+ const opener = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
6979
+ try {
6980
+ const { spawn } = await import("child_process");
6981
+ spawn(opener, [url], { stdio: "ignore", detached: true }).unref();
6982
+ log2(` ${c2.dim(`Opening ${url} in your default browser\u2026`)}`);
6983
+ log2("");
6984
+ } catch {
6985
+ }
6986
+ }
6925
6987
  async function cmdStatus() {
6926
6988
  log2("");
6927
6989
  log2(` ${c2.pinkBg(" \u{1F380} AgenticMail Status ")}`);
@@ -7238,7 +7300,7 @@ async function cmdUpdate() {
7238
7300
  info2(`Current version: ${c2.bold(currentVersion)}`);
7239
7301
  let latestVersion = "unknown";
7240
7302
  try {
7241
- latestVersion = execSync("npm view agenticmail version", { encoding: "utf-8", timeout: 15e3 }).trim();
7303
+ latestVersion = execSync("npm view @agenticmail/cli version", { encoding: "utf-8", timeout: 15e3 }).trim();
7242
7304
  } catch {
7243
7305
  fail2("Could not check npm. Check your internet connection.");
7244
7306
  process.exit(1);
@@ -7272,19 +7334,26 @@ async function cmdUpdate() {
7272
7334
  }
7273
7335
  let isGlobal = false;
7274
7336
  try {
7275
- const list = execSync(`npm list -g agenticmail 2>/dev/null`, { encoding: "utf-8", timeout: 1e4 });
7276
- if (list.includes("agenticmail@")) isGlobal = true;
7337
+ const list = execSync(`npm list -g @agenticmail/cli 2>/dev/null`, { encoding: "utf-8", timeout: 1e4 });
7338
+ if (list.includes("@agenticmail/cli@")) isGlobal = true;
7277
7339
  } catch {
7278
7340
  }
7341
+ if (!isGlobal) {
7342
+ try {
7343
+ const list = execSync(`npm list -g agenticmail 2>/dev/null`, { encoding: "utf-8", timeout: 1e4 });
7344
+ if (list.includes("agenticmail@")) isGlobal = true;
7345
+ } catch {
7346
+ }
7347
+ }
7279
7348
  const scope = isGlobal ? "-g" : "";
7280
- const installCmd = pm === "bun" ? `bun add ${scope} agenticmail@latest`.trim() : `${pm} install ${scope} agenticmail@latest`.trim();
7349
+ const installCmd = pm === "bun" ? `bun add ${scope} @agenticmail/cli@latest`.trim() : `${pm} install ${scope} @agenticmail/cli@latest`.trim();
7281
7350
  info2(`Running: ${c2.dim(installCmd)}`);
7282
7351
  try {
7283
7352
  execSync(installCmd, { stdio: "inherit", timeout: 12e4 });
7284
- ok2(`Updated to agenticmail@${latestVersion}`);
7353
+ ok2(`Updated to @agenticmail/cli@${latestVersion}`);
7285
7354
  } catch (err) {
7286
7355
  fail2(`Update failed: ${err.message}`);
7287
- info2(`Try: ${c2.green("npm install -g agenticmail@latest")}`);
7356
+ info2(`Try: ${c2.green("npm install -g @agenticmail/cli@latest")}`);
7288
7357
  process.exit(1);
7289
7358
  }
7290
7359
  if (hasOpenClaw) {
@@ -7372,6 +7441,15 @@ switch (command) {
7372
7441
  process.exit(1);
7373
7442
  });
7374
7443
  break;
7444
+ case "web":
7445
+ case "ui":
7446
+ cmdWeb().then(() => {
7447
+ process.exit(0);
7448
+ }).catch((err) => {
7449
+ console.error(err);
7450
+ process.exit(1);
7451
+ });
7452
+ break;
7375
7453
  case "--version":
7376
7454
  case "-v":
7377
7455
  case "version": {
@@ -7400,6 +7478,8 @@ switch (command) {
7400
7478
  log2(` ${c2.green("agenticmail start")} Start the server`);
7401
7479
  log2(` ${c2.green("agenticmail stop")} Stop the server`);
7402
7480
  log2(` ${c2.green("agenticmail status")} See what's running`);
7481
+ log2(` ${c2.green("agenticmail shell")} Drop into the interactive REPL (44 commands)`);
7482
+ log2(` ${c2.green("agenticmail web")} Open the Gmail-style web UI in your browser`);
7403
7483
  log2(` ${c2.green("agenticmail openclaw")} Set up AgenticMail for OpenClaw`);
7404
7484
  log2(` ${c2.green("agenticmail claudecode")} Set up AgenticMail for Claude Code`);
7405
7485
  log2(` ${c2.green("agenticmail service")} Manage auto-start (install/uninstall/status)`);