posthorn 0.2.7 → 0.2.8

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 (3) hide show
  1. package/README.md +69 -58
  2. package/dist/index.js +4 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -42,19 +42,63 @@ The platform is a pure orchestration layer: the USER owns their Cloudflare
42
42
  account, their Google Workspace, their domains, and their mailboxes. Posthorn
43
43
  never owns or bills for any of it.
44
44
 
45
- ## The end-to-end flow (in order)
46
-
47
- 1. Account → `posthorn auth register` (anonymous API key, instant)
48
- 2. Cloudflare → user creates account + API token, then `posthorn accounts cloudflare <token>`
49
- 3. Workspace → user sets up domain-wide delegation, then `posthorn accounts workspace <admin-email>`
50
- 4. Domain → buy new OR connect existing OR managed DNS
51
- 5. DKIM → browser step (see below)
52
- 6. Mailboxes → `posthorn mailboxes create ...`
53
- 7. Verify account `posthorn auth verify` (unlocks sending/warmup, "verified" tier)
54
- 8. Warmup → `posthorn warmup start <mailbox-id>`
45
+ ## The flow: walk it like a setup wizard
46
+
47
+ Go step by step. Ask one question at a time, only when the step needs it, and
48
+ do as much as possible yourself. Don't front-load questions.
49
+
50
+ Step 1. `posthorn auth register`. Instant API key; no email or signup info
51
+ needed, and there are no account tiers. Nothing to ask.
52
+
53
+ Step 2. Domain. Ask: "Do you need a new domain for your emails, or will you
54
+ use an existing one for sending?"
55
+ - NEW domain (the purchase always happens on the user's own Cloudflare account
56
+ and card; Posthorn never owns or bills for domains):
57
+ a. They need a Cloudflare account with a payment method (they pay Cloudflare
58
+ directly for the domain, ~$10/yr). Browser step: create the API token
59
+ (below), then `posthorn accounts cloudflare <token>`.
60
+ b. `posthorn domains check name1.com name2.io --cloudflare <id>` (availability
61
+ + price) → `posthorn domains reputation <pick>` (vets Spamhaus blocklist,
62
+ reputation score, and prior use; verdicts: clean / caution / avoid. Run it
63
+ before buying; you can't tell a tainted domain from its name.) →
64
+ `posthorn domains buy <pick> --cloudflare <id> --contact '{...}'`
65
+ - EXISTING domain. If it runs their live website or real email, recommend a
66
+ dedicated sending domain instead. Two ways to connect it; either way the
67
+ domain stays registered where they bought it, only nameservers change:
68
+ a. Their own Cloudflare: they manage the domain's DNS in their own Cloudflare
69
+ account. Needs the API token (below); and if the domain isn't on their
70
+ Cloudflare yet, they add it at dash.cloudflare.com and point nameservers
71
+ there first. Then `posthorn domains connect <domain> --cloudflare <id>`.
72
+ b. Posthorn-managed DNS: no Cloudflare account to create or manage; Posthorn
73
+ hosts the domain's DNS for them (free). `posthorn domains managed <domain>`
74
+ → they set the 2 printed nameservers at their registrar →
75
+ `posthorn domains activate <id>`. Note: Posthorn then hosts ALL of the
76
+ domain's DNS records (website records included), so it fits domains
77
+ dedicated to email.
78
+
79
+ Step 3. Google Workspace. Ask: "Do you have a Google Workspace you can add new
80
+ domains and mailboxes to, or do you want to set up a new one?"
81
+ - Existing Workspace: delegation browser step (below), then
82
+ `posthorn accounts workspace <admin-email>`.
83
+ - New Workspace: they create one at workspace.google.com using the domain from
84
+ step 2, then delegation as above.
85
+ (Delegation is per org, not per domain, so with an existing org this step can
86
+ happen any time, even before the domain exists. The domain pipeline auto-adds
87
+ and verifies the new domain inside their org.)
88
+
89
+ Step 4. Wait for the domain: poll `posthorn domains get <id>` until status
90
+ `ready` (minutes to 24h; poll every 30-60s, don't hammer). MX/SPF/DMARC are
91
+ configured automatically. Statuses progress: pending_* → purchased →
92
+ dns_configuring → dns_configured → dns_verified → workspace_verifying →
93
+ workspace_verified → ready.
94
+
95
+ Step 5. DKIM. Browser step below; once per domain, needs the domain `ready`.
96
+
97
+ Step 6. `posthorn mailboxes create <domain-id> --email ... --first ... --last ...`
98
+
99
+ Step 7. `posthorn warmup start <mailbox-id>`
55
100
 
56
101
  Dependencies: you CANNOT create a mailbox until the domain status is `ready`.
57
- You CANNOT send or start warmup until the account is "verified" tier.
58
102
 
59
103
  Run `posthorn auth status --json` any time to see where things stand. State is
60
104
  stored locally, so you can stop and continue any time.
@@ -92,7 +136,9 @@ to do this again." The repetition model, so you can answer follow-ups:
92
136
  - Client ID: 110137377718772968374
93
137
  - OAuth scopes (paste all, comma-separated):
94
138
  `https://mail.google.com/,https://www.googleapis.com/auth/admin.directory.user,https://www.googleapis.com/auth/admin.directory.domain,https://www.googleapis.com/auth/siteverification`
95
- - Then ask for their admin email and run: `posthorn accounts workspace <admin-email>`
139
+ - Must be done signed in as a SUPER-ADMIN of that Workspace org, and the email
140
+ passed to the CLI must be that super-admin's. Then run:
141
+ `posthorn accounts workspace <admin-email>`
96
142
  - This replaces OAuth entirely: no consent screen, no app verification, no test users.
97
143
 
98
144
  ### Nameservers (only for "managed DNS" or moving a domain to Cloudflare)
@@ -114,37 +160,6 @@ If you have browser-automation tools, do it for the user:
114
160
  If no browser tools: have the user do the above and paste you the TXT value,
115
161
  then add it to their DNS.
116
162
 
117
- ## Domain options (3 paths)
118
-
119
- PRINCIPLE: domain purchase ALWAYS happens on the user's own Cloudflare account
120
- and card. Posthorn never owns or bills for domains.
121
-
122
- 1. NEW domain → requires the user's own Cloudflare account (+ payment method).
123
- - `posthorn domains check name1.com name2.io --cloudflare <id>`, fast availability + price
124
- - `posthorn domains reputation <domain>`, VET it before buying (Spamhaus
125
- blocklist/score + archive.org prior-use). Verdicts: clean / caution (used
126
- before) / avoid (blocklisted or poor reputation). Run this on the candidate
127
- before `buy`; you can't tell a tainted domain from its name. (Slower + uses
128
- a quota, so it's a separate explicit call, not part of `check`.)
129
- - `posthorn domains buy <domain> --cloudflare <id> --contact '{...}'`
130
-
131
- 2. EXISTING domain, recommended → user's own Cloudflare account.
132
- - `posthorn domains connect <domain> --cloudflare <account-id>`
133
- - (If the domain isn't on Cloudflare yet, the user adds it at dash.cloudflare.com
134
- and points nameservers to their account first.)
135
-
136
- 3. EXISTING domain, optional → Posthorn-managed DNS (no Cloudflare account needed).
137
- - `posthorn domains managed <domain>` → prints 2 nameservers
138
- - user sets them at their registrar
139
- - `posthorn domains activate <domain-id>` → checks propagation, starts DNS setup
140
- - Best for DEDICATED email-only domains. Don't use on a domain running a live
141
- website; Posthorn becomes authoritative for ALL its DNS.
142
-
143
- After any path, poll `posthorn domains get <id>` until status is `ready`. DNS
144
- records (MX, SPF, DMARC) are configured automatically. Statuses progress:
145
- pending_* → purchased → dns_configuring → dns_configured → dns_verified →
146
- workspace_verifying → workspace_verified → ready.
147
-
148
163
  ## Mailboxes & sending
149
164
 
150
165
  - Create: `posthorn mailboxes create <domain-id> --email john@dom.com --first John --last Smith`
@@ -152,19 +167,17 @@ workspace_verifying → workspace_verified → ready.
152
167
  - Credentials for IMAP/SMTP are auto-provisioned via the service account
153
168
  (domain-wide delegation). Google mailboxes need no per-mailbox setup.
154
169
  - Send: `posthorn send <mailbox-id> --to x@y.com --subject "Hi" --body "..."`
155
- (requires "verified" tier)
156
170
 
157
- ## Account verification (unlocks sending/warmup)
158
-
159
- Anonymous tier can do setup (accounts, domains). To send/warmup, verify:
160
- `posthorn auth verify` → choose admin email or a custom email → confirm the code.
171
+ There is no email-verification step anywhere: connecting your own Cloudflare
172
+ and Workspace IS the identity. Once a mailbox exists, sending and warmup work.
161
173
 
162
174
  ## Warmup
163
175
 
164
- - `posthorn warmup start <mailbox-id>` → joins the shared warmup pool, ramps over ~30 days
165
- - Volume and reply behavior are platform-managed (ramps from 2/day to 5/day;
166
- peers reply to ~30% of warmup mail). Not configurable: the pool is shared,
167
- so settings are tuned for everyone's deliverability.
176
+ - `posthorn warmup start <mailbox-id>` → joins the shared warmup pool and runs
177
+ continuously until paused
178
+ - Volume and reply behavior are platform-managed (ramps from 2/day up to
179
+ 5/day, then holds; peers reply to ~30% of warmup mail). Not configurable:
180
+ the pool is shared, so settings are tuned for everyone's deliverability.
168
181
  - `posthorn warmup stats <campaign-id>` → placement rate, reputation, daily breakdown
169
182
  - `posthorn warmup list` → all campaigns
170
183
  - Warmup never fully stops on its own, pause with `posthorn warmup pause <id>`.
@@ -174,19 +187,17 @@ Anonymous tier can do setup (accounts, domains). To send/warmup, verify:
174
187
  `posthorn feedback --type bug|feature|question|other "<message>"`
175
188
 
176
189
  If you hit a bug, missing capability, or rough edge while driving this CLI,
177
- report it, it goes straight to the Posthorn team. Agents: you are encouraged
190
+ report it; it goes straight to the Posthorn team. Agents: you are encouraged
178
191
  to file feedback yourself when something doesn't work the way you expected
179
- (include the command you ran and what you expected). Works on any tier, no
180
- verification needed.
192
+ (include the command you ran and what you expected).
193
+
194
+ Whenever you or the user get stuck, file the issue with `posthorn feedback`.
181
195
 
182
196
  ## Tips for agents
183
197
 
184
198
  - Read commands auto-detect output: when stdout isn't a TTY (i.e. you're an agent
185
199
  capturing output), they emit JSON automatically, no flag needed. Humans in a
186
200
  terminal get formatted text. Force either way with `--json` / `--pretty`.
187
- - Async steps (domain provisioning, nameserver propagation) need polling, not blocking.
188
201
  - Every command stores state locally (~/.config), so the user doesn't re-enter keys.
189
202
  - Translate everything into plain English for the user. Never show them raw JSON
190
203
  or ask them to run curl, you run the CLI on their behalf.
191
- - When a step needs the user's browser (Cloudflare token, delegation, nameservers,
192
- DKIM), give exact click-by-click instructions and wait for confirmation.
package/dist/index.js CHANGED
@@ -76,7 +76,6 @@ async function register(options) {
76
76
  spinner.succeed("Account created!");
77
77
  console.log();
78
78
  console.log(` API Key: ${chalk.cyan(data.api_key)}`);
79
- console.log(` Tier: ${chalk.yellow(data.user.tier)}`);
80
79
  console.log();
81
80
  console.log(chalk.dim(" Save this API key, it won't be shown again."));
82
81
  console.log(chalk.dim(` Config stored at: ${getConfigPath()}`));
@@ -581,7 +580,7 @@ function guide() {
581
580
 
582
581
  // src/index.ts
583
582
  var program = new Command();
584
- program.name("posthorn").description("Posthorn: domain setup, mailbox creation, and email warmup").version("0.2.7");
583
+ program.name("posthorn").description("Posthorn: domain setup, mailbox creation, and email warmup").version("0.2.8");
585
584
  program.addHelpText("after", `
586
585
  Agents: run 'posthorn guide' first for the full workflow playbook.
587
586
 
@@ -593,7 +592,6 @@ Typical flow:
593
592
  posthorn domains connect <domain> --cloudflare <id>
594
593
  posthorn domains get <id> --json poll until status: ready
595
594
  posthorn mailboxes create <domain-id> --email you@dom.com --first A --last B
596
- posthorn auth verify unlock sending + warmup
597
595
  posthorn warmup start <mailbox-id>
598
596
 
599
597
  Output: read commands auto-detect. Agents (non-TTY) get JSON, humans get
@@ -634,7 +632,9 @@ program.parseAsync(process.argv).catch((err) => {
634
632
  if (err.statusCode === 401) {
635
633
  console.log(chalk7.red("\n Authentication failed. Run: posthorn auth register\n"));
636
634
  } else if (err.statusCode === 403) {
637
- console.log(chalk7.red("\n Account not verified. Run: posthorn auth verify\n"));
635
+ console.log(chalk7.red(`
636
+ Not allowed: ${err.message}
637
+ `));
638
638
  } else if (err.statusCode === 429) {
639
639
  console.log(chalk7.yellow("\n Rate limit exceeded. Try again in a minute.\n"));
640
640
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posthorn",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Domain setup, mailbox creation, and email warmup from the command line",
5
5
  "type": "module",
6
6
  "bin": {