@letterstory/cli 0.177.8 → 0.177.10
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/lib/cli.mjs +14 -1
- package/lib/commands/admin.mjs +68 -1
- package/lib/commands/build.mjs +3 -0
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -87,7 +87,7 @@ import {
|
|
|
87
87
|
import { fetchParkedSections, withoutParked } from "./parked.mjs";
|
|
88
88
|
|
|
89
89
|
// Matches cli/package.json; publish-cli.yml rewrites both to the published version.
|
|
90
|
-
export const VERSION = "0.177.
|
|
90
|
+
export const VERSION = "0.177.10";
|
|
91
91
|
|
|
92
92
|
/** The exit code for a gate refusal (CARD_REQUIRED, PAYMENT_FAILED, OUT_OF_TOKENS): 1 is a plain error. */
|
|
93
93
|
export const EXIT_PAYMENT_REQUIRED = 3;
|
|
@@ -100,6 +100,11 @@ export const BOOLEAN_FLAGS = new Set([
|
|
|
100
100
|
"connect-only",
|
|
101
101
|
// admin demo ideas: every live recipe, not only the Ideas that fit.
|
|
102
102
|
"library",
|
|
103
|
+
// admin demo sweep: prepare each recipe's org for a person to start, pull requests, make orgs, skip the refit.
|
|
104
|
+
"prepare",
|
|
105
|
+
"pull-requests",
|
|
106
|
+
"make-orgs",
|
|
107
|
+
"no-refit",
|
|
103
108
|
// admin targets check: check every target again, checked or not.
|
|
104
109
|
"recheck",
|
|
105
110
|
// build list: also move the builds' open changes along while polling.
|
|
@@ -1204,6 +1209,14 @@ Admin (STAFF key — --staff-key / LETTERSTORY_STAFF_API_KEY; acts before an org
|
|
|
1204
1209
|
admin demo check <org-id> Is it ready to show? Competitors, targets, answers, the
|
|
1205
1210
|
Plan's rows, the issues open, no PR open, GitHub, the
|
|
1206
1211
|
phantom's site. Exits 1 when not ready.
|
|
1212
|
+
admin demo ideas <org-id> [--library] [--preview] [--force] | --status [--id <run>]
|
|
1213
|
+
Start every Idea on a demo org for real (pull requests, or
|
|
1214
|
+
previews), or read how the latest run went.
|
|
1215
|
+
admin demo sweep [--prepare] [--pull-requests] [--recipes a,b] [--orgs a,b] [--exclude a,b] [--buy a,b] [--make-orgs] [--no-refit] | --status [--id <sweep>]
|
|
1216
|
+
Every live recipe end to end: each gets a test org whose Ideas
|
|
1217
|
+
offers it, its Start pressed (or, with --prepare, left for you
|
|
1218
|
+
to press in the app), and its outcome judged, with who owns a
|
|
1219
|
+
failure. Exits 1 when the sweep failed.
|
|
1207
1220
|
admin brand-detection <org-id> [--term <t>]... [--exact <t>]... [--exclude <phrase>]... [--note "…"] | --clear [--note "…"]
|
|
1208
1221
|
How a client's brand is detected in AI answers, with
|
|
1209
1222
|
every earlier setting; with flags, set the exact set
|
package/lib/commands/admin.mjs
CHANGED
|
@@ -6910,7 +6910,7 @@ const DEMO_ITEM_FLAGS = [
|
|
|
6910
6910
|
"setup",
|
|
6911
6911
|
];
|
|
6912
6912
|
const DEMO_USAGE =
|
|
6913
|
-
"Usage: admin demo guide | list [--enrollable] | show <org-id> [--moves] | set <org-id> [--enroll] [--unenroll] [--file <state.json>] [--phantom parked|shown] [--main-blog …] [--visitors …] [--probes not_run|shown] [--cms hidden|shown] [--publish-target …] [--search-console …] [--github …] [--domain …] [--setup fresh|finished] [--domain-cap n] [--inject <key>]... [--hide <key>]... [--save-as <name>] [--baseline <owner/repo>[@sha] | --clear-baseline] [--copy-from <org-id> [--copy-scenarios a,b] [--overwrite]] [--auto-reset <scenario>|off] [--every <minutes>] [--release] | domains | new <domain> [--name <n>] [--brief <t>] [--full] [--host vercel|pages] [--no-wait] | teardown <org-id> [--keep-repo] | bootstrap <org-id>... --from <org-id> [--scenarios a,b] [--overwrite] | reset <org-id> <scenario> [--clean-slate] [--close-prs since_applied|all_open|none] [--hold <minutes>] [--restore-repo revert|force] [--rebuild] [--reread-company] [--forget-company] [--forget-site] | check <org-id> | ideas <org-id> [--library] [--preview] [--force] | ideas <org-id> --status [--id <run-id>]";
|
|
6913
|
+
"Usage: admin demo guide | list [--enrollable] | show <org-id> [--moves] | set <org-id> [--enroll] [--unenroll] [--file <state.json>] [--phantom parked|shown] [--main-blog …] [--visitors …] [--probes not_run|shown] [--cms hidden|shown] [--publish-target …] [--search-console …] [--github …] [--domain …] [--setup fresh|finished] [--domain-cap n] [--inject <key>]... [--hide <key>]... [--save-as <name>] [--baseline <owner/repo>[@sha] | --clear-baseline] [--copy-from <org-id> [--copy-scenarios a,b] [--overwrite]] [--auto-reset <scenario>|off] [--every <minutes>] [--release] | domains | new <domain> [--name <n>] [--brief <t>] [--full] [--host vercel|pages] [--no-wait] | teardown <org-id> [--keep-repo] | bootstrap <org-id>... --from <org-id> [--scenarios a,b] [--overwrite] | reset <org-id> <scenario> [--clean-slate] [--close-prs since_applied|all_open|none] [--hold <minutes>] [--restore-repo revert|force] [--rebuild] [--reread-company] [--forget-company] [--forget-site] | check <org-id> | ideas <org-id> [--library] [--preview] [--force] | ideas <org-id> --status [--id <run-id>] | sweep [--prepare] [--pull-requests] [--recipes <id>,…] [--orgs <id>,…] [--exclude <id>,…] [--buy <recipe-id>,…] [--make-orgs] [--no-refit] | sweep --status [--id <sweep-id>]";
|
|
6914
6914
|
|
|
6915
6915
|
const readinessLines = (r) =>
|
|
6916
6916
|
r
|
|
@@ -6936,6 +6936,49 @@ const ideasRunLines = (run) =>
|
|
|
6936
6936
|
].join("\n")
|
|
6937
6937
|
: "No run yet.";
|
|
6938
6938
|
|
|
6939
|
+
const SWEEP_MARK = {
|
|
6940
|
+
ready: "READY",
|
|
6941
|
+
passed: "PASS",
|
|
6942
|
+
failed: "FAIL",
|
|
6943
|
+
waiting: "WAIT",
|
|
6944
|
+
held: "HELD",
|
|
6945
|
+
no_org: "NO ORG",
|
|
6946
|
+
not_derivable: "NO PROFILE",
|
|
6947
|
+
pending: "…",
|
|
6948
|
+
};
|
|
6949
|
+
|
|
6950
|
+
/** A recipe sweep's report (get_recipe_sweep), one block per recipe. */
|
|
6951
|
+
const recipeSweepLines = (sweep, appUrl) =>
|
|
6952
|
+
sweep
|
|
6953
|
+
? [
|
|
6954
|
+
`${sweep.summary} (${sweep.state}${sweep.note && sweep.state !== "done" ? `: ${sweep.note}` : ""})`,
|
|
6955
|
+
`${sweep.start ? "started by the sweep" : "prepared for you to start"}, ${sweep.delivery === "build" ? "previews" : "pull requests"}, by ${sweep.started_by_name ?? "staff"} at ${sweep.created_at} sweep ${sweep.id}`,
|
|
6956
|
+
...sweep.items.map((i) =>
|
|
6957
|
+
[
|
|
6958
|
+
`\n${(SWEEP_MARK[i.result] ?? i.result).padEnd(10)} ${i.name}`,
|
|
6959
|
+
i.org ? ` org: ${i.org.name} (${i.org.host})${i.org.made ? ", made for it" : ""}` : null,
|
|
6960
|
+
i.fit[0] ? ` fit: ${i.fit[0].fits}: ${i.fit[0].why}` : null,
|
|
6961
|
+
i.row
|
|
6962
|
+
? ` row: ${i.row.title}${i.row.line ? ` / ${i.row.line}` : ""}${i.row.button ? ` [${i.row.button}]` : ""}`
|
|
6963
|
+
: null,
|
|
6964
|
+
i.did
|
|
6965
|
+
? ` did: ${i.did.tools.join(", ") || "no tools"}${i.did.sandbox ? ", a sandbox" : ""}${i.did.cost_usd != null ? `, $${i.did.cost_usd}` : ""}`
|
|
6966
|
+
: null,
|
|
6967
|
+
i.verdict ? ` outcome: ${i.verdict.state}: ${i.verdict.observed}` : null,
|
|
6968
|
+
i.cause ? ` cause: ${i.cause.owner}: ${i.cause.why}` : null,
|
|
6969
|
+
i.profile_problem ? ` profile: ${i.profile_problem}` : null,
|
|
6970
|
+
i.profile?.unsettable?.length
|
|
6971
|
+
? ` can't be made on a test org: ${i.profile.unsettable.map((u) => u.key).join(", ")}`
|
|
6972
|
+
: null,
|
|
6973
|
+
i.links?.ideas ? ` open: ${appUrl}${i.links.ideas}` : null,
|
|
6974
|
+
i.links?.build ? ` build: ${appUrl}${i.links.build}` : null,
|
|
6975
|
+
]
|
|
6976
|
+
.filter(Boolean)
|
|
6977
|
+
.join("\n")
|
|
6978
|
+
),
|
|
6979
|
+
].join("\n")
|
|
6980
|
+
: "No sweep yet.";
|
|
6981
|
+
|
|
6939
6982
|
async function cmdAdminDemo(ctx) {
|
|
6940
6983
|
const { flags, positionals, io } = ctx;
|
|
6941
6984
|
const sub = positionals[0];
|
|
@@ -7194,6 +7237,30 @@ async function cmdAdminDemo(ctx) {
|
|
|
7194
7237
|
printResult(io, flags, result, (r) => ideasRunLines(r.run));
|
|
7195
7238
|
return result.run?.state === "failed" ? 1 : 0;
|
|
7196
7239
|
}
|
|
7240
|
+
case "sweep": {
|
|
7241
|
+
// Every live recipe end to end on test orgs (run_recipe_sweep), or the latest sweep's report (get_recipe_sweep).
|
|
7242
|
+
const path = `${DEMO}/sweeps`;
|
|
7243
|
+
const id = flagStr(flags.id);
|
|
7244
|
+
const result =
|
|
7245
|
+
flagBool(flags.status) || id
|
|
7246
|
+
? await staffRequest(ctx, "GET", id ? `${path}?id=${encodeURIComponent(id)}` : path)
|
|
7247
|
+
: await staffPost(
|
|
7248
|
+
ctx,
|
|
7249
|
+
path,
|
|
7250
|
+
compact({
|
|
7251
|
+
start: flagBool(flags.prepare) ? false : undefined,
|
|
7252
|
+
delivery: flagBool(flags["pull-requests"]) ? "build_pr" : undefined,
|
|
7253
|
+
recipes: flags.recipes ? flagList(flags.recipes) : undefined,
|
|
7254
|
+
orgs: flags.orgs ? flagList(flags.orgs) : undefined,
|
|
7255
|
+
exclude: flags.exclude ? flagList(flags.exclude) : undefined,
|
|
7256
|
+
purchases: flags.buy ? flagList(flags.buy) : undefined,
|
|
7257
|
+
make_orgs: flagBool(flags["make-orgs"]) || undefined,
|
|
7258
|
+
refit: flagBool(flags["no-refit"]) ? false : undefined,
|
|
7259
|
+
})
|
|
7260
|
+
);
|
|
7261
|
+
printResult(io, flags, result, (r) => recipeSweepLines(r.sweep, ctx.client.url));
|
|
7262
|
+
return result.sweep?.state === "failed" ? 1 : 0;
|
|
7263
|
+
}
|
|
7197
7264
|
default:
|
|
7198
7265
|
throw new CliError(DEMO_USAGE);
|
|
7199
7266
|
}
|
package/lib/commands/build.mjs
CHANGED
|
@@ -44,6 +44,8 @@ const ARGS = {
|
|
|
44
44
|
prompt: { value: (flags, positionals) => flagStr(flags.prompt) ?? (positionals.join(" ").trim() || undefined) },
|
|
45
45
|
// --ask "<words>": the person's own words, when --prompt was written from them.
|
|
46
46
|
ask: "ask",
|
|
47
|
+
// --confirms <build id>: the person's yes to the price a build stopped on.
|
|
48
|
+
confirms: "confirms",
|
|
47
49
|
// --build-it: the words are a request to build, never read as a question.
|
|
48
50
|
asked_to_build: { flag: "build-it", type: "bool" },
|
|
49
51
|
domain: "site",
|
|
@@ -254,6 +256,7 @@ async function buildStart(ctx) {
|
|
|
254
256
|
"prompt",
|
|
255
257
|
"ask",
|
|
256
258
|
"build-it",
|
|
259
|
+
"confirms",
|
|
257
260
|
"site",
|
|
258
261
|
"subject",
|
|
259
262
|
"recipe",
|