agenticmail 0.3.10 → 0.3.12

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.
Files changed (2) hide show
  1. package/dist/cli.js +146 -16
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -4216,21 +4216,6 @@ async function cmdSetup() {
4216
4216
  await new Promise((r) => setTimeout(r, 800));
4217
4217
  log2(` ${c2.bold("Step 4 of 4")} ${c2.dim("\u2014")} ${c2.bold("Connect your email")}`);
4218
4218
  log2("");
4219
- log2(` How should your AI agent send and receive email?`);
4220
- log2("");
4221
- log2(` ${c2.cyan("1.")} Use my Gmail or Outlook`);
4222
- log2(` ${c2.dim("Easiest option \u2014 connect your existing email account.")}`);
4223
- log2(` ${c2.dim("Your agent emails as you+agent@gmail.com")}`);
4224
- log2("");
4225
- log2(` ${c2.cyan("2.")} Use my own domain`);
4226
- log2(` ${c2.dim("Your agent gets a custom address like agent@yourcompany.com")}`);
4227
- log2(` ${c2.dim("Requires a Cloudflare account and a domain.")}`);
4228
- log2("");
4229
- log2(` ${c2.cyan("3.")} Skip for now`);
4230
- log2(` ${c2.dim("You can always set this up later.")}`);
4231
- log2("");
4232
- const choice = await pick(` ${c2.magenta(">")} `, ["1", "2", "3"]);
4233
- log2("");
4234
4219
  const serverSpinner = new Spinner("server", "Starting the server...");
4235
4220
  serverSpinner.start();
4236
4221
  let serverReady = false;
@@ -4281,6 +4266,62 @@ async function cmdSetup() {
4281
4266
  serverSpinner.fail(`Could not start server: ${err.message}`);
4282
4267
  }
4283
4268
  }
4269
+ let existingEmail = null;
4270
+ let existingProvider = null;
4271
+ if (serverReady) {
4272
+ try {
4273
+ const base = `http://${result.config.api.host}:${result.config.api.port}`;
4274
+ const statusResp = await fetch(`${base}/api/agenticmail/gateway/status`, {
4275
+ headers: { "Authorization": `Bearer ${result.config.masterKey}` },
4276
+ signal: AbortSignal.timeout(5e3)
4277
+ });
4278
+ if (statusResp.ok) {
4279
+ const status = await statusResp.json();
4280
+ if (status.mode === "relay" && status.relay?.email) {
4281
+ existingEmail = status.relay.email;
4282
+ existingProvider = status.relay.provider || "custom";
4283
+ }
4284
+ }
4285
+ } catch {
4286
+ }
4287
+ }
4288
+ let choice;
4289
+ if (existingEmail) {
4290
+ const provLabel = existingProvider === "gmail" ? "Gmail" : existingProvider === "outlook" ? "Outlook" : existingProvider;
4291
+ log2("");
4292
+ ok2(`Email already connected: ${c2.cyan(existingEmail)} ${c2.dim(`(${provLabel})`)}`);
4293
+ log2("");
4294
+ log2(` ${c2.cyan("1.")} Keep current email`);
4295
+ log2(` ${c2.cyan("2.")} Remove and connect a different email`);
4296
+ log2(` ${c2.cyan("3.")} Set up a custom domain instead`);
4297
+ log2("");
4298
+ const existChoice = await pick(` ${c2.magenta(">")} `, ["1", "2", "3"]);
4299
+ if (existChoice === "1") {
4300
+ choice = "3";
4301
+ log2("");
4302
+ ok2(`Keeping ${c2.cyan(existingEmail)}`);
4303
+ } else if (existChoice === "3") {
4304
+ choice = "2";
4305
+ } else {
4306
+ choice = "1";
4307
+ }
4308
+ } else {
4309
+ log2(` How should your AI agent send and receive email?`);
4310
+ log2("");
4311
+ log2(` ${c2.cyan("1.")} Use my Gmail or Outlook`);
4312
+ log2(` ${c2.dim("Easiest option \u2014 connect your existing email account.")}`);
4313
+ log2(` ${c2.dim("Your agent emails as you+agent@gmail.com")}`);
4314
+ log2("");
4315
+ log2(` ${c2.cyan("2.")} Use my own domain`);
4316
+ log2(` ${c2.dim("Your agent gets a custom address like agent@yourcompany.com")}`);
4317
+ log2(` ${c2.dim("Requires a Cloudflare account and a domain.")}`);
4318
+ log2("");
4319
+ log2(` ${c2.cyan("3.")} Skip for now`);
4320
+ log2(` ${c2.dim("You can always set this up later.")}`);
4321
+ log2("");
4322
+ choice = await pick(` ${c2.magenta(">")} `, ["1", "2", "3"]);
4323
+ }
4324
+ log2("");
4284
4325
  if (choice === "1" || choice === "2") {
4285
4326
  if (!serverReady) {
4286
4327
  info2("You can configure email later by running: agenticmail setup");
@@ -4294,9 +4335,12 @@ async function cmdSetup() {
4294
4335
  } else {
4295
4336
  await setupDomain(result.config);
4296
4337
  }
4297
- } else {
4338
+ } else if (!existingEmail) {
4298
4339
  info2("No problem! You can set up email anytime by running this again.");
4299
4340
  }
4341
+ if (serverReady) {
4342
+ await registerWithOpenClaw(result.config);
4343
+ }
4300
4344
  printSummary(result, false);
4301
4345
  if (serverReady) {
4302
4346
  await interactiveShell({ config: result.config, onExit: cleanupChild });
@@ -4319,6 +4363,92 @@ function printSummary(result, exitAfter) {
4319
4363
  process.exit(0);
4320
4364
  }
4321
4365
  }
4366
+ async function registerWithOpenClaw(config) {
4367
+ const openclawConfig = join(homedir(), ".openclaw", "openclaw.json");
4368
+ if (!existsSync2(openclawConfig)) return;
4369
+ try {
4370
+ const raw = readFileSync2(openclawConfig, "utf8");
4371
+ const ocConfig = JSON.parse(raw);
4372
+ if (ocConfig.plugins?.entries?.agenticmail?.config?.apiKey) {
4373
+ ok2(`OpenClaw integration already configured`);
4374
+ return;
4375
+ }
4376
+ let pluginPath = null;
4377
+ try {
4378
+ const resolved = import.meta.resolve("@agenticmail/openclaw");
4379
+ const resolvedPath = fileURLToPath(resolved);
4380
+ pluginPath = dirname(dirname(resolvedPath));
4381
+ } catch {
4382
+ }
4383
+ if (!pluginPath) {
4384
+ const thisDir = dirname(fileURLToPath(import.meta.url));
4385
+ let dir = thisDir;
4386
+ for (let i = 0; i < 10; i++) {
4387
+ const candidate = join(dir, "node_modules", "@agenticmail", "openclaw");
4388
+ if (existsSync2(join(candidate, "package.json"))) {
4389
+ pluginPath = candidate;
4390
+ break;
4391
+ }
4392
+ const parent = dirname(dir);
4393
+ if (parent === dir) break;
4394
+ dir = parent;
4395
+ }
4396
+ }
4397
+ if (!pluginPath) {
4398
+ try {
4399
+ const { execSync } = await import("child_process");
4400
+ const prefix = execSync("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
4401
+ const globalCandidate = join(prefix, "lib", "node_modules", "@agenticmail", "openclaw");
4402
+ if (existsSync2(join(globalCandidate, "package.json"))) pluginPath = globalCandidate;
4403
+ if (!pluginPath) {
4404
+ const globalCandidate2 = join(prefix, "node_modules", "@agenticmail", "openclaw");
4405
+ if (existsSync2(join(globalCandidate2, "package.json"))) pluginPath = globalCandidate2;
4406
+ }
4407
+ } catch {
4408
+ }
4409
+ }
4410
+ if (!pluginPath) return;
4411
+ try {
4412
+ pluginPath = realpathSync(pluginPath);
4413
+ } catch {
4414
+ }
4415
+ let apiKey = "";
4416
+ try {
4417
+ const base = `http://${config.api.host}:${config.api.port}`;
4418
+ const resp = await fetch(`${base}/api/agenticmail/accounts`, {
4419
+ headers: { "Authorization": `Bearer ${config.masterKey}` },
4420
+ signal: AbortSignal.timeout(5e3)
4421
+ });
4422
+ if (resp.ok) {
4423
+ const data = await resp.json();
4424
+ const agents = data.agents || data || [];
4425
+ if (agents.length > 0) {
4426
+ apiKey = agents[0].apiKey;
4427
+ }
4428
+ }
4429
+ } catch {
4430
+ }
4431
+ if (!apiKey) return;
4432
+ if (!ocConfig.plugins) ocConfig.plugins = {};
4433
+ if (!ocConfig.plugins.load) ocConfig.plugins.load = {};
4434
+ if (!ocConfig.plugins.load.paths) ocConfig.plugins.load.paths = [];
4435
+ if (!ocConfig.plugins.entries) ocConfig.plugins.entries = {};
4436
+ if (!ocConfig.plugins.load.paths.includes(pluginPath)) {
4437
+ ocConfig.plugins.load.paths.push(pluginPath);
4438
+ }
4439
+ ocConfig.plugins.entries.agenticmail = {
4440
+ enabled: true,
4441
+ config: {
4442
+ apiUrl: `http://${config.api.host}:${config.api.port}`,
4443
+ apiKey,
4444
+ masterKey: config.masterKey
4445
+ }
4446
+ };
4447
+ writeFileSync2(openclawConfig, JSON.stringify(ocConfig, null, 2) + "\n", "utf8");
4448
+ ok2(`OpenClaw integration configured \u2014 your agents can now use email!`);
4449
+ } catch {
4450
+ }
4451
+ }
4322
4452
  async function setupRelay(config) {
4323
4453
  log2(" Which email service do you use?");
4324
4454
  log2(` ${c2.cyan("1.")} Gmail`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agenticmail",
3
- "version": "0.3.10",
3
+ "version": "0.3.12",
4
4
  "description": "Email infrastructure for AI agents — send and receive real email programmatically",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",