@letterstory/cli 0.176.79 → 0.176.81
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 +23 -4
- package/lib/commands/automate.mjs +32 -2
- 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.81";
|
|
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);
|
|
@@ -671,6 +684,12 @@ Reviewers:
|
|
|
671
684
|
automate send <event-name> --title <what happened> [--key <id>] [--url <u>] [--fact k=v ...]
|
|
672
685
|
[--email <e>] [--person <name>] [--company <c>]
|
|
673
686
|
Send an event from your own systems
|
|
687
|
+
automate findings [--state new|acted|dismissed|expired] [--automation <id>] [--site <host>] [--page <url>]
|
|
688
|
+
[--limit <n>] [--cursor <t>]
|
|
689
|
+
What the automations noticed: evidence, what it's about,
|
|
690
|
+
the button that acts on it, and how it ended
|
|
691
|
+
automate act <finding-id> Make the call a finding stores, as you
|
|
692
|
+
automate dismiss <finding-id> [--reason <why>] Set a finding aside
|
|
674
693
|
automate remove <automation-id>
|
|
675
694
|
reviewers invite <article-id> --email <e> [--name <n>]
|
|
676
695
|
Invite a guest to review one post
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// `automate` — Letterpress → Automations (docs/architecture/event-automations.md): an event, read
|
|
2
2
|
// against your filter (--instruction), then done by Letterpress as your prompt (--prompt) says.
|
|
3
|
-
// options / list / show / add / set / try / runs / approve / reject / send / remove, through the
|
|
3
|
+
// options / list / show / add / set / try / runs / approve / reject / send / findings / act / dismiss / remove, through the
|
|
4
4
|
// same tools the app uses. (A letterbase's writing automations are made and paced with `automations`.) `list` also
|
|
5
5
|
// shows the jobs Letter runs for the account (source "letter": internal links, the blog's sync, the site's re-audit,
|
|
6
6
|
// Fix autopilot, add-your-name suggestions, Auto-Plan, and each letterbase's writing automations), each with its
|
|
@@ -34,6 +34,7 @@ const TEMPLATES = [
|
|
|
34
34
|
];
|
|
35
35
|
const UNITS = ["hours", "days", "weeks", "months"];
|
|
36
36
|
const STATUSES = ["pending", "proposed", "acting", "acted", "answered", "skipped", "failed", "rejected"];
|
|
37
|
+
const FINDING_STATES = ["new", "acted", "dismissed", "expired"];
|
|
37
38
|
|
|
38
39
|
const triggerParams = {
|
|
39
40
|
object: {
|
|
@@ -164,6 +165,29 @@ export const ARGS = {
|
|
|
164
165
|
decision: { internal: "approve or reject, from the subcommand" },
|
|
165
166
|
reason: { flag: "reason" },
|
|
166
167
|
},
|
|
168
|
+
// What the automations noticed (docs/architecture/automation-findings.md): read, act on, dismiss.
|
|
169
|
+
list_findings: {
|
|
170
|
+
automation_id: { flag: "automation" },
|
|
171
|
+
state: { flag: "state", enum: FINDING_STATES },
|
|
172
|
+
about: {
|
|
173
|
+
object: {
|
|
174
|
+
host: { flag: "site" },
|
|
175
|
+
page_url: { flag: "page" },
|
|
176
|
+
collection_id: { flag: "letterbase" },
|
|
177
|
+
question: { flag: "question" },
|
|
178
|
+
target_id: { flag: "target" },
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
limit: { flag: "limit", type: "num" },
|
|
182
|
+
cursor: { flag: "cursor" },
|
|
183
|
+
},
|
|
184
|
+
act_on_finding: {
|
|
185
|
+
finding_id: { positional: 0, label: "finding-id", required: true },
|
|
186
|
+
},
|
|
187
|
+
dismiss_finding: {
|
|
188
|
+
finding_id: { positional: 0, label: "finding-id", required: true },
|
|
189
|
+
reason: { flag: "reason" },
|
|
190
|
+
},
|
|
167
191
|
send_automation_event: {
|
|
168
192
|
event: { positional: 0, label: "event-name", required: true },
|
|
169
193
|
key: { flag: "key" },
|
|
@@ -207,12 +231,18 @@ export async function cmdAutomate(ctx) {
|
|
|
207
231
|
return run(rest, "decide_automation_run", "Rejected.", { decision: "reject" });
|
|
208
232
|
case "send":
|
|
209
233
|
return run(rest, "send_automation_event");
|
|
234
|
+
case "findings":
|
|
235
|
+
return run(rest, "list_findings");
|
|
236
|
+
case "act":
|
|
237
|
+
return run(rest, "act_on_finding", "Done.");
|
|
238
|
+
case "dismiss":
|
|
239
|
+
return run(rest, "dismiss_finding", "Dismissed.");
|
|
210
240
|
case "remove":
|
|
211
241
|
case "rm":
|
|
212
242
|
return run(rest, "delete_event_automation", "Removed.");
|
|
213
243
|
default:
|
|
214
244
|
throw new CliError(
|
|
215
|
-
`Unknown automate subcommand: ${sub ?? "(none)"}. Try: options, list, show, add, set, try, runs, approve, reject, send, remove`
|
|
245
|
+
`Unknown automate subcommand: ${sub ?? "(none)"}. Try: options, list, show, add, set, try, runs, approve, reject, send, findings, act, dismiss, remove`
|
|
216
246
|
);
|
|
217
247
|
}
|
|
218
248
|
}
|