@letterstory/cli 0.176.78 → 0.176.80
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 +22 -6
- package/lib/commands/admin.mjs +10 -0
- package/lib/commands/automate.mjs +4 -0
- package/package.json +1 -1
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.80";
|
|
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;
|
|
@@ -274,9 +274,9 @@ export const BOOLEAN_FLAGS = new Set([
|
|
|
274
274
|
"resolve",
|
|
275
275
|
"reopen",
|
|
276
276
|
"skip",
|
|
277
|
-
// `phantom-onboard domain` / `admin create-org --onboard` switches.
|
|
277
|
+
// `phantom-onboard domain` / `admin create-org --onboard` switches. (`--status` is a switch only on
|
|
278
|
+
// phantom-onboard, SWITCH_FLAGS_BY_COMMAND: everywhere else it takes a value, `--status parked`.)
|
|
278
279
|
"watch",
|
|
279
|
-
"status",
|
|
280
280
|
"no-phantom",
|
|
281
281
|
"no-visuals",
|
|
282
282
|
"no-enhance",
|
|
@@ -424,6 +424,13 @@ export const BOOLEAN_FLAGS = new Set([
|
|
|
424
424
|
*/
|
|
425
425
|
const VALUE_FLAGS_BY_COMMAND = { automations: new Set(["on"]) };
|
|
426
426
|
|
|
427
|
+
/**
|
|
428
|
+
* Flags that are switches on one command and take a value everywhere else. `--status` is "show me the job" on
|
|
429
|
+
* phantom-onboard (onboard.mjs), and a value on every other (`admin recipes save --status parked`, `admin crm
|
|
430
|
+
* prospect-orgs --status ready`): as a global switch, `--status parked` dropped "parked" (2026-11-09).
|
|
431
|
+
*/
|
|
432
|
+
export const SWITCH_FLAGS_BY_COMMAND = { "phantom-onboard": new Set(["status"]), onboard: new Set(["status"]) };
|
|
433
|
+
|
|
427
434
|
/**
|
|
428
435
|
* @param {string[]} argv
|
|
429
436
|
* @returns {{ positionals: string[], flags: Record<string, string | boolean | string[]> }}
|
|
@@ -432,6 +439,7 @@ export function parseArgs(argv) {
|
|
|
432
439
|
const positionals = [];
|
|
433
440
|
const flags = {};
|
|
434
441
|
const valueFlags = VALUE_FLAGS_BY_COMMAND[argv[0]] ?? new Set();
|
|
442
|
+
const switchFlags = SWITCH_FLAGS_BY_COMMAND[argv[0]] ?? new Set();
|
|
435
443
|
const setFlag = (name, value) => {
|
|
436
444
|
if (Object.prototype.hasOwnProperty.call(flags, name)) {
|
|
437
445
|
flags[name] = [].concat(flags[name], value);
|
|
@@ -452,7 +460,12 @@ export function parseArgs(argv) {
|
|
|
452
460
|
}
|
|
453
461
|
const name = tok.slice(2);
|
|
454
462
|
const next = argv[i + 1];
|
|
455
|
-
if (
|
|
463
|
+
if (
|
|
464
|
+
(BOOLEAN_FLAGS.has(name) && !valueFlags.has(name)) ||
|
|
465
|
+
switchFlags.has(name) ||
|
|
466
|
+
next === undefined ||
|
|
467
|
+
next.startsWith("--")
|
|
468
|
+
) {
|
|
456
469
|
flags[name] = true;
|
|
457
470
|
} else {
|
|
458
471
|
setFlag(name, next);
|
|
@@ -648,7 +661,7 @@ Reviewers:
|
|
|
648
661
|
schedule]
|
|
649
662
|
[--prompt <what Letterpress does with each event>] [--slack-channel <C…>] [--instruction <which events>]
|
|
650
663
|
[--event <name>] [--kind post|landing] [--competitor <host>] [--site <host>]
|
|
651
|
-
[--every <n> --unit hours|days|weeks|months] [--sandbox]
|
|
664
|
+
[--every <n> --unit hours|days|weeks|months] [--facts <a,b>] [--sandbox] [--recipe <id>]
|
|
652
665
|
[--hot-leads-only] [--per-day <n>] [--backfill all|<YYYY-MM-DD>] [--off]
|
|
653
666
|
Make one (a template fills what you leave out): it starts
|
|
654
667
|
from now (--backfill also runs it on past events, oldest
|
|
@@ -656,7 +669,10 @@ Reviewers:
|
|
|
656
669
|
to --slack-channel with its buttons. --trigger schedule
|
|
657
670
|
--every 2 --unit weeks is a recurring one (on the calendar:
|
|
658
671
|
Monday, the 1st); --sandbox always runs its prompt in a Build
|
|
659
|
-
sandbox (off, Letterpress decides per event)
|
|
672
|
+
sandbox (off, Letterpress decides per event); --facts
|
|
673
|
+
names what each tick carries (merged_changes, page_reads,
|
|
674
|
+
new_pages_unlinked, striking_queries, losing_pages);
|
|
675
|
+
--recipe makes a Plan recipe's own
|
|
660
676
|
automate set <automation-id> [--name <n>] [--instruction <text>] [--prompt <text>] [--slack-channel <C…>|none]
|
|
661
677
|
[--sandbox|--no-sandbox] [--backfill all|<YYYY-MM-DD>] [--on|--off] ...
|
|
662
678
|
automate try [<automation-id>] [--trigger <t> --prompt <text> --instruction <text> ...] [--limit <n>]
|
package/lib/commands/admin.mjs
CHANGED
|
@@ -5134,6 +5134,10 @@ const RECIPE_FILE_FIELDS = [
|
|
|
5134
5134
|
// The inputs the fit is told a recipe cannot run without (2026-11-08: left out here, an import never carried them).
|
|
5135
5135
|
"requires",
|
|
5136
5136
|
"runs",
|
|
5137
|
+
// The recurring automation a recipe carries (runs automation:recipe); left out here, an import never reached prod.
|
|
5138
|
+
"automation",
|
|
5139
|
+
// The build's declared tools and scoped writes (left out here, an export dropped them).
|
|
5140
|
+
"tool_access",
|
|
5137
5141
|
"primitives_access",
|
|
5138
5142
|
"immediate",
|
|
5139
5143
|
"status",
|
|
@@ -5176,6 +5180,12 @@ function recipeDetail(r) {
|
|
|
5176
5180
|
` reads: ${r.reads?.length ? r.reads.join(", ") : "— (not written: every probe runs)"}`,
|
|
5177
5181
|
` status: ${r.status === "parked" ? `parked${r.needs ? `, needs ${r.needs}` : ""}` : "live"}`,
|
|
5178
5182
|
` runs: ${r.runs || "one change to the site's code, from its own directions"}`,
|
|
5183
|
+
...(r.automation
|
|
5184
|
+
? [
|
|
5185
|
+
` automation: "${r.automation.name}" every ${r.automation.every} ${r.automation.unit}, carrying ${(r.automation.facts ?? []).join(", ") || "no facts"}`,
|
|
5186
|
+
` its prompt: ${r.automation.prompt}`,
|
|
5187
|
+
]
|
|
5188
|
+
: []),
|
|
5179
5189
|
...(r.primitives_access ? [" letter's tools: its build may use them (primitives_access)"] : []),
|
|
5180
5190
|
...(r.immediate ? [" immediate: a quick win: the Plan puts one in every top three"] : []),
|
|
5181
5191
|
...(variations.length > 1
|
|
@@ -46,6 +46,8 @@ const triggerParams = {
|
|
|
46
46
|
// --trigger schedule --every 2 --unit weeks: a recurring automation, on the calendar (Monday, the 1st).
|
|
47
47
|
every: { flag: "every", type: "num" },
|
|
48
48
|
unit: { flag: "unit", enum: UNITS },
|
|
49
|
+
// --facts striking_queries,losing_pages: what each tick of a schedule carries, read by Letter before the turn.
|
|
50
|
+
facts: { flag: "facts", type: "list" },
|
|
49
51
|
},
|
|
50
52
|
};
|
|
51
53
|
// --sandbox / --no-sandbox: always run the prompt in a Build sandbox (the repo and Letter's tools); off, Letterpress decides per event.
|
|
@@ -114,6 +116,8 @@ export const ARGS = {
|
|
|
114
116
|
create_event_automation: {
|
|
115
117
|
destination,
|
|
116
118
|
template: { flag: "template", enum: TEMPLATES },
|
|
119
|
+
// --recipe <id>: make the automation a Plan recipe carries (the Plan row's own call).
|
|
120
|
+
recipe: { flag: "recipe" },
|
|
117
121
|
name: { flag: "name" },
|
|
118
122
|
trigger: { flag: "trigger", enum: TRIGGERS },
|
|
119
123
|
trigger_params: triggerParams,
|