@letterstory/cli 0.176.39 → 0.176.41
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 +10 -7
- package/lib/commands/automate.mjs +23 -1
- package/lib/commands/build.mjs +4 -2
- package/lib/commands/plan.mjs +4 -2
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
import { fetchParkedSections, withoutParked } from "./parked.mjs";
|
|
84
84
|
|
|
85
85
|
// Matches cli/package.json; publish-cli.yml rewrites both to the published version.
|
|
86
|
-
export const VERSION = "0.176.
|
|
86
|
+
export const VERSION = "0.176.41";
|
|
87
87
|
|
|
88
88
|
/** The exit code for a gate refusal (CARD_REQUIRED, PAYMENT_FAILED, OUT_OF_TOKENS): 1 is a plain error. */
|
|
89
89
|
export const EXIT_PAYMENT_REQUIRED = 3;
|
|
@@ -94,6 +94,8 @@ export const EXIT_PAYMENT_REQUIRED = 3;
|
|
|
94
94
|
export const BOOLEAN_FLAGS = new Set([
|
|
95
95
|
// build list: also move the builds' open changes along while polling.
|
|
96
96
|
"advance",
|
|
97
|
+
// build list: only what the Plan started.
|
|
98
|
+
"from-plan",
|
|
97
99
|
// build: a website or app of its own (deploy create's path). deploy create: hold until its build starts.
|
|
98
100
|
"new-site",
|
|
99
101
|
"wait",
|
|
@@ -625,16 +627,17 @@ Reviewers:
|
|
|
625
627
|
automate list Your automations: an event, which ones it acts on,
|
|
626
628
|
and what Letterpress then does
|
|
627
629
|
automate show <automation-id>
|
|
628
|
-
automate add [--template post_new_issues|recommended_actions|competitor_pages|icp_visitors|plan_updates]
|
|
630
|
+
automate add [--template post_new_issues|recommended_actions|competitor_pages|icp_visitors|vc_visitors|plan_updates]
|
|
629
631
|
[--name <n>] [--trigger competitor_page|visitor_identified|issue_found|build_suggestion|plan_update|custom]
|
|
630
632
|
[--prompt <what Letterpress does with each event>] [--slack-channel <C…>] [--instruction <which events>]
|
|
631
633
|
[--event <name>] [--kind post|landing] [--competitor <host>] [--site <host>]
|
|
632
|
-
[--hot-leads-only] [--per-day <n>] [--off]
|
|
634
|
+
[--hot-leads-only] [--per-day <n>] [--backfill all|<YYYY-MM-DD>] [--off]
|
|
633
635
|
Make one (a template fills what you leave out): it starts
|
|
634
|
-
from now
|
|
636
|
+
from now (--backfill also runs it on past events, oldest
|
|
637
|
+
first), acts on its own, and posts each event it acts on
|
|
635
638
|
to --slack-channel with its buttons
|
|
636
639
|
automate set <automation-id> [--name <n>] [--instruction <text>] [--prompt <text>] [--slack-channel <C…>|none]
|
|
637
|
-
[--on|--off] ...
|
|
640
|
+
[--backfill all|<YYYY-MM-DD>] [--on|--off] ...
|
|
638
641
|
automate try [<automation-id>] [--trigger <t> --prompt <text> --instruction <text> ...] [--limit <n>]
|
|
639
642
|
What it would do with the latest events (acts on none)
|
|
640
643
|
automate runs [--automation <id>] [--status acting|acted|skipped|failed|proposed|rejected] [--limit <n>]
|
|
@@ -1670,7 +1673,7 @@ Insights:
|
|
|
1670
1673
|
Plan tab's box), what's broken (--lens fix, most pressing
|
|
1671
1674
|
first), what to build (--lens build), or your own words. Nothing asked:
|
|
1672
1675
|
each list's head. The same answer as the console and Slack.
|
|
1673
|
-
plan auto [activate|disable] [--site host] [--veto-hours <1-168>|off] [--auto-merge on|off]
|
|
1676
|
+
plan auto [activate|disable] [--site host] [--veto-hours <1-168>|off] [--pace-hours <1-168>] [--auto-merge on|off]
|
|
1674
1677
|
[--aggression low|medium|high|xhigh] [--goal geo|seo|agent_conviction|inbound_conversion|any]
|
|
1675
1678
|
[--slack-channel <C…>|none]
|
|
1676
1679
|
Auto-Plan on a site: Letterpress picks its strategies and builds
|
|
@@ -1725,7 +1728,7 @@ Build (a change to your site, or launching what isn't code; the Build box's own
|
|
|
1725
1728
|
Staff only. The same prompt on Letterpress-1 (as Build runs it) and on
|
|
1726
1729
|
stock Claude Code and stock Codex, each a preview to compare
|
|
1727
1730
|
build benchmarks [--id <uuid>] [--limit <n>] Staff only. Benchmarks, each arm's state, preview, cost and agent time
|
|
1728
|
-
build list [--limit <n>] [--site <host>] [--kind build|fix] [--open|--archived]
|
|
1731
|
+
build list [--limit <n>] [--site <host>] [--kind build|fix] [--open|--archived] [--from-plan]
|
|
1729
1732
|
Your builds, newest first, with where each stands
|
|
1730
1733
|
build status <build-id> One build: each change's state, its preview and pull request
|
|
1731
1734
|
build follow <build-id> [--json] What its agents do, line by line, until nothing in it is at
|
|
@@ -8,7 +8,14 @@ import { CliError } from "../client.mjs";
|
|
|
8
8
|
import { printResult, ok, argsFromFlags, flagList, refuseUnknownFlags } from "./shared.mjs";
|
|
9
9
|
|
|
10
10
|
const TRIGGERS = ["competitor_page", "visitor_identified", "issue_found", "build_suggestion", "plan_update", "custom"];
|
|
11
|
-
const TEMPLATES = [
|
|
11
|
+
const TEMPLATES = [
|
|
12
|
+
"post_new_issues",
|
|
13
|
+
"recommended_actions",
|
|
14
|
+
"competitor_pages",
|
|
15
|
+
"icp_visitors",
|
|
16
|
+
"vc_visitors",
|
|
17
|
+
"plan_updates",
|
|
18
|
+
];
|
|
12
19
|
const STATUSES = ["pending", "proposed", "acting", "acted", "skipped", "failed", "rejected"];
|
|
13
20
|
|
|
14
21
|
const triggerParams = {
|
|
@@ -31,6 +38,19 @@ const slackChannel = {
|
|
|
31
38
|
: String(flags["slack-channel"]),
|
|
32
39
|
};
|
|
33
40
|
const enabled = { value: (flags) => (flags.off === true ? false : flags.on === true ? true : undefined) };
|
|
41
|
+
// --backfill all (the whole history the trigger's source keeps) or --backfill 2026-09-01 (from that day):
|
|
42
|
+
// also run it on past events, oldest first.
|
|
43
|
+
const backfill = {
|
|
44
|
+
value: (flags) => {
|
|
45
|
+
const v = flags.backfill;
|
|
46
|
+
if (v === undefined) return undefined;
|
|
47
|
+
if (v === true || v === "all") return "all";
|
|
48
|
+
const day = String(v);
|
|
49
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(day))
|
|
50
|
+
throw new CliError(`--backfill takes all or a day (YYYY-MM-DD), got: ${day}`);
|
|
51
|
+
return { since: `${day}T00:00:00Z` };
|
|
52
|
+
},
|
|
53
|
+
};
|
|
34
54
|
|
|
35
55
|
/** --fact plan=team --fact seats=40 → { plan: "team", seats: 40 } (numbers and true/false read as such). */
|
|
36
56
|
function factsOf(flags) {
|
|
@@ -69,6 +89,7 @@ export const ARGS = {
|
|
|
69
89
|
prompt: { flag: "prompt" },
|
|
70
90
|
slack_channel: slackChannel,
|
|
71
91
|
enabled,
|
|
92
|
+
backfill,
|
|
72
93
|
},
|
|
73
94
|
update_event_automation: {
|
|
74
95
|
automation_id: { positional: 0, label: "automation-id", required: true },
|
|
@@ -78,6 +99,7 @@ export const ARGS = {
|
|
|
78
99
|
prompt: { flag: "prompt" },
|
|
79
100
|
slack_channel: slackChannel,
|
|
80
101
|
enabled,
|
|
102
|
+
backfill,
|
|
81
103
|
},
|
|
82
104
|
delete_event_automation: {
|
|
83
105
|
automation_id: { positional: 0, label: "automation-id", required: true },
|
package/lib/commands/build.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// build benchmark <words…> → start_build_benchmark (staff only: Letterpress-1, stock Claude Code
|
|
9
9
|
// and stock Codex on the same prompt, each a preview)
|
|
10
10
|
// build benchmarks → list_build_benchmarks (staff only; --id <uuid> for one)
|
|
11
|
-
// build list → list_growth_builds (newest first; --site, --kind, --open/--archived)
|
|
11
|
+
// build list → list_growth_builds (newest first; --site, --kind, --open/--archived, --from-plan)
|
|
12
12
|
// build status <id> → list_growth_builds (one build: its steps, previews and PRs)
|
|
13
13
|
// build follow <id> → list_growth_builds (advance) + get_repo_change_activity, until nothing is at work
|
|
14
14
|
// build conversations → list_build_conversations
|
|
@@ -101,6 +101,8 @@ const ARGS = {
|
|
|
101
101
|
archived: { flag: "archived", type: "bool", negate: "open" },
|
|
102
102
|
// --advance: also move the builds' open changes along while polling (a queued change takes its sandbox, a merge asked for its next step).
|
|
103
103
|
advance: { flag: "advance", type: "bool" },
|
|
104
|
+
// --from-plan: only what the Plan started (a strategy's row, Auto-Plan's pick), as the Plan's Actions list shows it.
|
|
105
|
+
from_plan: { flag: "from-plan", type: "bool" },
|
|
104
106
|
},
|
|
105
107
|
list_build_conversations: { limit: { flag: "limit", type: "num" } },
|
|
106
108
|
get_build_conversation: {
|
|
@@ -272,7 +274,7 @@ async function readBuild(client, args) {
|
|
|
272
274
|
/** `build list`: the organization's builds, newest first. */
|
|
273
275
|
async function buildList(ctx) {
|
|
274
276
|
const { client, flags, io } = ctx;
|
|
275
|
-
refuseUnknownFlags(ctx, {}, ["limit", "kind", "site", "archived", "open", "advance"]);
|
|
277
|
+
refuseUnknownFlags(ctx, {}, ["limit", "kind", "site", "archived", "open", "advance", "from-plan"]);
|
|
276
278
|
const args = argsFromFlags(ARGS.list_growth_builds, flags, []);
|
|
277
279
|
const result = await client.callTool("list_growth_builds", args);
|
|
278
280
|
printResult(io, flags, result, (r) =>
|
package/lib/commands/plan.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// `plan` — Auto-Plan on one site (Plan → Auto-Plan; Plan is scoped to one website, --site, else the
|
|
2
2
|
// organization's own domain). The same calls as the Plan's modal and its sidebar's Pending rows.
|
|
3
3
|
// plan auto → get_auto_plan
|
|
4
|
-
// plan auto [activate|disable] [--veto-hours <1-168>|off] [--auto-merge on|off]
|
|
4
|
+
// plan auto [activate|disable] [--veto-hours <1-168>|off] [--pace-hours <1-168>] [--auto-merge on|off]
|
|
5
5
|
// [--aggression low|medium|high|xhigh] [--goal geo|seo|agent_conviction|inbound_conversion|any]
|
|
6
6
|
// [--slack-channel <C…>|none] → set_auto_plan
|
|
7
7
|
// plan pending → list_auto_plan_proposals (status pending)
|
|
@@ -43,6 +43,8 @@ export const ARGS = {
|
|
|
43
43
|
return n;
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
|
+
// --pace-hours <1-168> how often it picks the next action (1 every hour, 24 every day, 168 every week).
|
|
47
|
+
pace_hours: { flag: "pace-hours", type: "num" },
|
|
46
48
|
merge: { value: onOff("auto-merge") },
|
|
47
49
|
aggression: { flag: "aggression", enum: ["low", "medium", "high", "xhigh"] },
|
|
48
50
|
// --goal geo picks strategies for that goal only; --goal any (the default) reads every strategy.
|
|
@@ -87,7 +89,7 @@ export const ARGS = {
|
|
|
87
89
|
},
|
|
88
90
|
};
|
|
89
91
|
|
|
90
|
-
const SETTING_FLAGS = ["veto-hours", "auto-merge", "aggression", "goal", "slack-channel"];
|
|
92
|
+
const SETTING_FLAGS = ["veto-hours", "pace-hours", "auto-merge", "aggression", "goal", "slack-channel"];
|
|
91
93
|
|
|
92
94
|
export async function cmdPlan(ctx) {
|
|
93
95
|
const { client, flags, io } = ctx;
|