@letterstory/cli 0.176.60 → 0.176.62
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 +2 -1
- package/lib/cli.mjs +4 -3
- package/lib/commands/admin.mjs +2 -0
- package/lib/commands/domains.mjs +8 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -139,7 +139,8 @@ Your organization's domains, whatever each is used for, and finding new ones:
|
|
|
139
139
|
|
|
140
140
|
```bash
|
|
141
141
|
letterstory domains # every domain you hold and what it's used for
|
|
142
|
-
letterstory domains scan
|
|
142
|
+
letterstory domains scan # brainstorms the searches in your space, free .com/.org (no charge)
|
|
143
|
+
letterstory domains scan "nano banana pro" # or the phrases you give
|
|
143
144
|
letterstory domains scan "nano banana pro" --tld com,org,ai,xyz --expand space
|
|
144
145
|
letterstory domains buy nanobananaprofree.com --dry-run # the price and whose account pays
|
|
145
146
|
letterstory domains buy nanobananaprofree.com --yes # buys it (spends money; domains:write)
|
package/lib/cli.mjs
CHANGED
|
@@ -85,7 +85,7 @@ import {
|
|
|
85
85
|
import { fetchParkedSections, withoutParked } from "./parked.mjs";
|
|
86
86
|
|
|
87
87
|
// Matches cli/package.json; publish-cli.yml rewrites both to the published version.
|
|
88
|
-
export const VERSION = "0.176.
|
|
88
|
+
export const VERSION = "0.176.62";
|
|
89
89
|
|
|
90
90
|
/** The exit code for a gate refusal (CARD_REQUIRED, PAYMENT_FAILED, OUT_OF_TOKENS): 1 is a plain error. */
|
|
91
91
|
export const EXIT_PAYMENT_REQUIRED = 3;
|
|
@@ -1897,9 +1897,10 @@ Sim (Simulations: a free, simulated copy of your API for agents, and what they d
|
|
|
1897
1897
|
|
|
1898
1898
|
Domains (the domains you hold, and free ones that match what people search):
|
|
1899
1899
|
domains [list] Every domain you hold and what each is used for
|
|
1900
|
-
domains scan
|
|
1900
|
+
domains scan ["<phrase>" …] [--tld com,org,ai] [--expand none|searches|space]
|
|
1901
1901
|
[--no-modifiers] [--market US] [--limit <n>]
|
|
1902
|
-
Free domains
|
|
1902
|
+
Free .com/.org domains on what people search in your
|
|
1903
|
+
space (brainstormed, or the phrases given), ranked
|
|
1903
1904
|
domains buy <domain> --dry-run | --yes The price and whose account pays; --yes buys it
|
|
1904
1905
|
|
|
1905
1906
|
Vary (A/B tests of a page's words and images on your own site):
|
package/lib/commands/admin.mjs
CHANGED
|
@@ -5131,6 +5131,8 @@ const RECIPE_FILE_FIELDS = [
|
|
|
5131
5131
|
"weight",
|
|
5132
5132
|
"approaches",
|
|
5133
5133
|
"reads",
|
|
5134
|
+
// The inputs the fit is told a recipe cannot run without (2026-11-08: left out here, an import never carried them).
|
|
5135
|
+
"requires",
|
|
5134
5136
|
"runs",
|
|
5135
5137
|
"primitives_access",
|
|
5136
5138
|
"immediate",
|
package/lib/commands/domains.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// wrappers over list_domains, scan_domains and register_domain, the same lib functions the app calls.
|
|
4
4
|
//
|
|
5
5
|
// letterstory domains [list]
|
|
6
|
+
// letterstory domains scan brainstorms the searches in your space, checks .com and .org
|
|
6
7
|
// letterstory domains scan "nano banana pro" ["ai headshots" …] [--tld com,org,ai] [--expand none|searches|space]
|
|
7
8
|
// letterstory domains buy nanobananaprofree.com --dry-run the price and whose account pays; buys nothing
|
|
8
9
|
// letterstory domains buy nanobananaprofree.com --yes buys it (spends money; domains:write)
|
|
@@ -12,14 +13,9 @@ import { flagCsv, requirePositional, printResult, argsFromFlags } from "./shared
|
|
|
12
13
|
|
|
13
14
|
export const ARGS = {
|
|
14
15
|
list_domains: {},
|
|
15
|
-
// `domains scan "nano banana pro" ["ai headshots" …]` — each positional is one phrase.
|
|
16
|
+
// `domains scan "nano banana pro" ["ai headshots" …]` — each positional is one phrase; none brainstorms your space.
|
|
16
17
|
scan_domains: {
|
|
17
|
-
phrases: {
|
|
18
|
-
value: (flags, positionals) => {
|
|
19
|
-
requirePositional(positionals, 0, "phrase");
|
|
20
|
-
return positionals;
|
|
21
|
-
},
|
|
22
|
-
},
|
|
18
|
+
phrases: { value: (flags, positionals) => (positionals.length ? positionals : undefined) },
|
|
23
19
|
// `--tld com,org` or `--tld com --tld org`.
|
|
24
20
|
tlds: {
|
|
25
21
|
value: (flags) => {
|
|
@@ -79,7 +75,7 @@ async function domainsList(ctx) {
|
|
|
79
75
|
(d) =>
|
|
80
76
|
`${d.domain.padEnd(32)} ${(d.used_for.length ? d.used_for.map((u) => (u === "site" && d.site ? `site (${d.site.name})` : u)).join(", ") : "not yet used").padEnd(28)} ${d.status.padEnd(8)} ${d.registered_on === "org_vercel_key" ? "your Vercel" : d.registered_on === "letter" ? "Letter" : "connected"} ${usd(d.purchase_price_usd)}`
|
|
81
77
|
);
|
|
82
|
-
if (!lines.length) lines.push(
|
|
78
|
+
if (!lines.length) lines.push("No domains yet. Find one with: letterstory domains scan");
|
|
83
79
|
const g = r.registration;
|
|
84
80
|
lines.push(
|
|
85
81
|
"",
|
|
@@ -134,13 +130,15 @@ async function domainsScan(ctx) {
|
|
|
134
130
|
: p.purchase_usd == null
|
|
135
131
|
? "not sold here"
|
|
136
132
|
: `$${p.purchase_usd}${p.purchasable ? "" : " (over cap)"}`;
|
|
137
|
-
const lines = [
|
|
133
|
+
const lines = [];
|
|
134
|
+
if (r.space) lines.push(`Searches brainstormed for your space: ${r.space}`);
|
|
135
|
+
lines.push(`Free domains (${r.available} of ${r.checked} checked, searches in ${r.market}):`);
|
|
138
136
|
for (const d of r.domains) {
|
|
139
137
|
lines.push(
|
|
140
138
|
` ${String(d.score).padStart(5)} ${d.domain.padEnd(32)} ${d.match.padEnd(8)} ${searches(d.monthly_searches).padStart(8)}/mo ${d.phrase} ${price(d.price)}`
|
|
141
139
|
);
|
|
142
140
|
}
|
|
143
|
-
if (!r.domains.length) lines.push(" None free. Try
|
|
141
|
+
if (!r.domains.length) lines.push(" None free. Try phrases of your own, --expand space, or more --tld.");
|
|
144
142
|
lines.push("", `Exact match on each TLD (free / · taken):`);
|
|
145
143
|
lines.push(` ${"".padEnd(30)} ${"searches".padStart(8)} ${r.tlds.map((t) => t.padEnd(5)).join("")}`);
|
|
146
144
|
for (const row of r.coverage) {
|