@mailkite/cli 0.1.0 → 0.3.0
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 +8 -6
- package/cli.mjs +92 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -18,11 +18,13 @@ npm i -g @mailkite/cli # or install the `mailkite` binary globally
|
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
mailkite signup --email you@example.com --password •••••• # or: login
|
|
21
|
-
mailkite domains
|
|
21
|
+
mailkite domains check myapp.ai # available? + price
|
|
22
|
+
mailkite domains register myapp.ai --first-name … --email … --country US # buy + auto-DNS
|
|
23
|
+
mailkite domains add mail.myapp.ai # or add a domain you already own
|
|
22
24
|
# …add those records at your DNS provider…
|
|
23
25
|
mailkite domains verify <domainId> # MX/SPF/DKIM/DMARC
|
|
24
|
-
mailkite webhook set <domainId> https://
|
|
25
|
-
mailkite send --from hello@mail.
|
|
26
|
+
mailkite webhook set <domainId> https://myapp.ai/hooks/mailkite
|
|
27
|
+
mailkite send --from hello@mail.myapp.ai --to you@example.com \
|
|
26
28
|
--subject "It works" --html "<p>Hi from MailKite</p>"
|
|
27
29
|
mailkite messages tail # watch inbound arrive
|
|
28
30
|
```
|
|
@@ -31,8 +33,8 @@ Or do the whole flow in one command:
|
|
|
31
33
|
|
|
32
34
|
```bash
|
|
33
35
|
mailkite init --email you@example.com --password •••• \
|
|
34
|
-
--domain mail.
|
|
35
|
-
--webhook https://
|
|
36
|
+
--domain mail.myapp.ai --provider cloudflare \
|
|
37
|
+
--webhook https://myapp.ai/hooks/mailkite --to you@example.com --verify
|
|
36
38
|
```
|
|
37
39
|
|
|
38
40
|
## Built for scripts and agents
|
|
@@ -53,7 +55,7 @@ mailkite domains verify "$ID" --json | jq -e '.status=="verified"'
|
|
|
53
55
|
| Group | Commands |
|
|
54
56
|
| --- | --- |
|
|
55
57
|
| Auth | `login`, `signup`, `logout`, `whoami` |
|
|
56
|
-
| Send | `send` |
|
|
58
|
+
| Send | `send`, `agent`, `route` |
|
|
57
59
|
| Domains | `domains list\|add\|get\|verify\|rm`, `dns <id> [--provider]` |
|
|
58
60
|
| Webhooks | `webhook set\|rm\|test\|show`, `secret get\|rotate`, `verify-webhook` |
|
|
59
61
|
| Receiving | `messages list\|get\|tail`, `routes list\|create`, `deliveries retry` |
|
package/cli.mjs
CHANGED
|
@@ -217,6 +217,45 @@ commands.send = async ({ flags }) => {
|
|
|
217
217
|
out(res, flags, (r) => console.log(green("✓ ") + `Sent — id ${bold(r.id)}, status ${r.status}`));
|
|
218
218
|
};
|
|
219
219
|
|
|
220
|
+
// Send a message straight to an inbox agent and print its reply. Defaults to the account's
|
|
221
|
+
// default agent; --route-id / --address pick a specific one, --model overrides the model.
|
|
222
|
+
commands.agent = async ({ _, flags }) => {
|
|
223
|
+
const mk = client(flags);
|
|
224
|
+
const text = await need(_[0] || flags.text, "text", "Message to the agent: ");
|
|
225
|
+
const message = { text };
|
|
226
|
+
if (flags.subject) message.subject = flags.subject;
|
|
227
|
+
if (flags.from) message.from = flags.from;
|
|
228
|
+
if (flags["route-id"]) message.routeId = flags["route-id"];
|
|
229
|
+
if (flags.address) message.address = flags.address;
|
|
230
|
+
if (flags.model) message.model = flags.model;
|
|
231
|
+
let res;
|
|
232
|
+
try { res = await mk.agent(message); }
|
|
233
|
+
catch (e) { return die(e instanceof MailKiteError ? `Agent failed (${e.status}): ${e.message}` : e.message); }
|
|
234
|
+
out(res, flags, (r) => { if (r.ok) console.log(r.text || dim("(no reply)")); else die(r.error || "agent run failed"); });
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// Route a message to one of your registered routes (by id or address), running its action.
|
|
238
|
+
commands.route = async ({ _, flags }) => {
|
|
239
|
+
const mk = client(flags);
|
|
240
|
+
const from = await need(flags.from, "from", "From: ");
|
|
241
|
+
const message = { from };
|
|
242
|
+
if (flags["route-id"]) message.routeId = flags["route-id"];
|
|
243
|
+
if (flags.address) message.address = flags.address;
|
|
244
|
+
if (!message.routeId && !message.address) {
|
|
245
|
+
const target = await need(_[0] || "", "route", "Route id (rte_…) or address it matches: ");
|
|
246
|
+
if (target.startsWith("rte_")) message.routeId = target; else message.address = target;
|
|
247
|
+
}
|
|
248
|
+
if (flags.subject) message.subject = flags.subject;
|
|
249
|
+
let text = flags.text;
|
|
250
|
+
if (flags.file) text = readFileSync(flags.file, "utf8");
|
|
251
|
+
if (text) message.text = text;
|
|
252
|
+
if (flags.html) message.html = flags.html;
|
|
253
|
+
let res;
|
|
254
|
+
try { res = await mk.route(message); }
|
|
255
|
+
catch (e) { return die(e instanceof MailKiteError ? `Route failed (${e.status}): ${e.message}` : e.message); }
|
|
256
|
+
out(res, flags, (r) => console.log(green("✓ ") + `Routed — id ${bold(r.id)}, action ${r.action}`));
|
|
257
|
+
};
|
|
258
|
+
|
|
220
259
|
commands.domains = async ({ _, flags }) => {
|
|
221
260
|
const sub = _[0] || "list";
|
|
222
261
|
const mk = client(flags);
|
|
@@ -249,6 +288,51 @@ commands.domains = async ({ _, flags }) => {
|
|
|
249
288
|
const id = await need(_[1] || flags.id, "id", "Domain id: ");
|
|
250
289
|
return out(await mk.deleteDomain(id), flags, () => console.log(green("✓ ") + "Domain removed."));
|
|
251
290
|
}
|
|
291
|
+
if (sub === "check") {
|
|
292
|
+
const domain = await need(_[1] || flags.domain, "domain", "Domain to check: ");
|
|
293
|
+
const res = await mk.checkDomainAvailability(domain);
|
|
294
|
+
return out(res, flags, (r) => {
|
|
295
|
+
if (r.configured === false) return console.log(dim("Domain registration isn't enabled for this account."));
|
|
296
|
+
if (r.available) {
|
|
297
|
+
const p = r.price ? " " + dim(`${r.price.amount} ${r.price.currency} / ${r.price.period}${r.price.periodUnit}`) : "";
|
|
298
|
+
console.log(green("✓ ") + `${bold(r.domain)} is available${p}${r.premium ? red(" (premium)") : ""}`);
|
|
299
|
+
console.log(dim(`Register it: mailkite domains register ${r.domain}`));
|
|
300
|
+
} else {
|
|
301
|
+
console.log(red("✗ ") + `${bold(r.domain)} is not available${r.reason ? dim(` (${r.reason})`) : ""}`);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
if (sub === "register" || sub === "buy") {
|
|
306
|
+
const domain = await need(_[1] || flags.domain, "domain", "Domain to register: ");
|
|
307
|
+
// Show the price first (no charge) so the user confirms with eyes open.
|
|
308
|
+
const avail = await mk.checkDomainAvailability(domain).catch(() => null);
|
|
309
|
+
if (avail?.configured === false) die("Domain registration isn't enabled for this account.");
|
|
310
|
+
if (avail && !avail.available) die(`${domain} is not available${avail.reason ? ` (${avail.reason})` : ""}.`);
|
|
311
|
+
if (avail?.price) console.error(`Price: ${bold(`${avail.price.amount} ${avail.price.currency}`)} / ${avail.price.period}${avail.price.periodUnit}${avail.premium ? red(" (premium)") : ""}`);
|
|
312
|
+
const contact = {
|
|
313
|
+
firstName: await need(flags["first-name"], "first name", "First name: "),
|
|
314
|
+
lastName: await need(flags["last-name"], "last name", "Last name: "),
|
|
315
|
+
email: await need(flags.email, "email", "Email: "),
|
|
316
|
+
phone: await need(flags.phone, "phone", "Phone (+countrycode.number, e.g. +1.4155551234): "),
|
|
317
|
+
address: await need(flags.address, "address", "Address: "),
|
|
318
|
+
city: await need(flags.city, "city", "City: "),
|
|
319
|
+
zip: await need(flags.zip, "postal code", "Postal code: "),
|
|
320
|
+
country: await need(flags.country, "country", "Country (2-letter, e.g. US): "),
|
|
321
|
+
};
|
|
322
|
+
if (flags.state) contact.state = flags.state;
|
|
323
|
+
const org = flags.organization || flags.org;
|
|
324
|
+
if (org) { contact.organization = org; contact.type = flags.type || "company"; }
|
|
325
|
+
const years = flags.years ? Number(flags.years) : undefined;
|
|
326
|
+
// Final confirmation — this charges the registrar.
|
|
327
|
+
const ans = flags.yes || flags.force ? "y" : (await prompt(`Register ${bold(domain)} now? This charges your registrar. [y/N] `)).toLowerCase();
|
|
328
|
+
if (ans !== "y" && ans !== "yes") return console.error(dim("Cancelled."));
|
|
329
|
+
const res = await mk.registerDomain({ domain, contact, years });
|
|
330
|
+
return out(res, flags, (r) => {
|
|
331
|
+
console.log(green("✓ ") + `Registered ${bold(r.domain?.domain || domain)}${r.registration?.status ? dim(` (${r.registration.status})`) : ""}`);
|
|
332
|
+
if (r.dnsProvisioned) console.log(green("✓ ") + "Mail DNS provisioned automatically.");
|
|
333
|
+
else printDns(r.dns);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
252
336
|
die(`Unknown subcommand: domains ${sub}`);
|
|
253
337
|
};
|
|
254
338
|
|
|
@@ -467,9 +551,16 @@ ${bold("AUTH")}
|
|
|
467
551
|
${bold("SEND")}
|
|
468
552
|
send Send a message (--from --to --subject [--html|--text|--file] [--cc --bcc --reply-to --in-reply-to])
|
|
469
553
|
|
|
554
|
+
${bold("AGENTS")}
|
|
555
|
+
agent <text> Message an inbox agent and print its reply ([--route-id|--address] [--model --subject --from])
|
|
556
|
+
route Route a message to a registered route (--route-id <id>|--address <addr> --from [--subject --text|--file --html])
|
|
557
|
+
|
|
470
558
|
${bold("DOMAINS & DNS")}
|
|
471
559
|
domains list List your domains
|
|
472
|
-
domains add <domain> Add a domain; prints the DNS records to set
|
|
560
|
+
domains add <domain> Add a domain you own; prints the DNS records to set
|
|
561
|
+
domains check <domain> Check if a domain is available to register (+ price)
|
|
562
|
+
domains register <domain> Buy a domain; provisions DNS + adds it (--first-name --last-name
|
|
563
|
+
--email --phone --address --city --zip --country [--state --org --years --yes])
|
|
473
564
|
domains get <id> Show a domain (with DNS + webhook)
|
|
474
565
|
domains verify <id> Re-check DNS (MX/SPF/DKIM/DMARC)
|
|
475
566
|
domains rm <id> Remove a domain
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mailkite/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "MailKite command-line client — sign in, add domains, set DNS + webhooks, send mail, and tail inbound messages from your terminal. Built on the MailKite Node SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"homepage": "https://mailkite.dev/docs/cli",
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "https://github.com/
|
|
33
|
+
"url": "git+https://github.com/mailkite/mailkite.git",
|
|
34
34
|
"directory": "sdks/cli"
|
|
35
35
|
},
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"mailkite": "^0.
|
|
38
|
+
"mailkite": "^0.3.0"
|
|
39
39
|
}
|
|
40
40
|
}
|