@letterstory/cli 0.176.52 → 0.176.53

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 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.52";
88
+ export const VERSION = "0.176.53";
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;
@@ -117,10 +117,12 @@ export const BOOLEAN_FLAGS = new Set([
117
117
  "keep-key",
118
118
  "delete-key",
119
119
  "keep",
120
- // automate add/set: on or off; only identified visitors marked hot leads.
120
+ // automate add/set: on or off; only identified visitors marked hot leads; run the prompt in a Build sandbox.
121
121
  "on",
122
122
  "off",
123
123
  "hot-leads-only",
124
+ "sandbox",
125
+ "no-sandbox",
124
126
  // admin crm prospect-org: start (or retry) the org prepared for the booked call.
125
127
  "start",
126
128
  // site research-builds: run now even when the stored pass is under an hour old.
@@ -136,6 +138,8 @@ export const BOOLEAN_FLAGS = new Set([
136
138
  // build: repeat an open build's ask; post its progress in the org's Slack channel.
137
139
  "again",
138
140
  "plan-only",
141
+ // build: every change reads Letter's tools from its sandbox.
142
+ "primitives-access",
139
143
  // build list: only Build's Archived tab (--open, already listed, is its Open tab).
140
144
  "archived",
141
145
  // plan pending --queued: only the rows a person queued for later.
@@ -633,17 +637,22 @@ Reviewers:
633
637
  automate list Your automations: an event, which ones it acts on,
634
638
  and what Letterpress then does
635
639
  automate show <automation-id>
636
- automate add [--template post_new_issues|recommended_actions|competitor_pages|icp_visitors|vc_visitors|plan_updates]
637
- [--name <n>] [--trigger competitor_page|visitor_identified|issue_found|build_suggestion|plan_update|custom]
640
+ automate add [--template post_new_issues|fix_new_issues|recommended_actions|competitor_pages|competitor_takes|
641
+ icp_visitors|vc_visitors|plan_updates|weekly_release_notes|monthly_page_refresh]
642
+ [--name <n>] [--trigger competitor_page|visitor_identified|issue_found|build_suggestion|plan_update|custom|schedule]
638
643
  [--prompt <what Letterpress does with each event>] [--slack-channel <C…>] [--instruction <which events>]
639
644
  [--event <name>] [--kind post|landing] [--competitor <host>] [--site <host>]
645
+ [--every <n> --unit hours|days|weeks|months] [--sandbox]
640
646
  [--hot-leads-only] [--per-day <n>] [--backfill all|<YYYY-MM-DD>] [--off]
641
647
  Make one (a template fills what you leave out): it starts
642
648
  from now (--backfill also runs it on past events, oldest
643
649
  first), acts on its own, and posts each event it acts on
644
- to --slack-channel with its buttons
650
+ to --slack-channel with its buttons. --trigger schedule
651
+ --every 2 --unit weeks is a recurring one (on the calendar:
652
+ Monday, the 1st); --sandbox always runs its prompt in a Build
653
+ sandbox (off, Letterpress decides per event)
645
654
  automate set <automation-id> [--name <n>] [--instruction <text>] [--prompt <text>] [--slack-channel <C…>|none]
646
- [--backfill all|<YYYY-MM-DD>] [--on|--off] ...
655
+ [--sandbox|--no-sandbox] [--backfill all|<YYYY-MM-DD>] [--on|--off] ...
647
656
  automate try [<automation-id>] [--trigger <t> --prompt <text> --instruction <text> ...] [--limit <n>]
648
657
  What it would do with the latest events (acts on none)
649
658
  automate runs [--automation <id>] [--status acting|acted|skipped|failed|proposed|rejected] [--limit <n>]
@@ -1726,6 +1735,7 @@ Build (a change to your site, or launching what isn't code; the Build box's own
1726
1735
  build <words…> [--prompt <text>] [--site <host>] [--subject <host/path>]... [--action build|build_pr|build_merge|slack|linear]
1727
1736
  [--attach <path>]... [--attach-url <name>=<https url>]... [--attach-ref <path>]... [--attach-url-ref <name>=<https url>]...
1728
1737
  [--harness letterpress-1|claude-code|codex] [--effort low|medium|high|xhigh] [--notify-slack] [--again] [--new-site]
1738
+ [--primitives-access]
1729
1739
  Build from your words: "add a pricing page" opens a preview or PR;
1730
1740
  "launch a phantom for us", "set up mailers" or "onboard my blog" is
1731
1741
  done by Build itself (a phantom site buys its own domain), and the
@@ -7,15 +7,28 @@
7
7
  import { CliError } from "../client.mjs";
8
8
  import { printResult, ok, argsFromFlags, flagList, flagStr, refuseUnknownFlags } from "./shared.mjs";
9
9
 
10
- const TRIGGERS = ["competitor_page", "visitor_identified", "issue_found", "build_suggestion", "plan_update", "custom"];
10
+ const TRIGGERS = [
11
+ "competitor_page",
12
+ "visitor_identified",
13
+ "issue_found",
14
+ "build_suggestion",
15
+ "plan_update",
16
+ "custom",
17
+ "schedule",
18
+ ];
11
19
  const TEMPLATES = [
12
20
  "post_new_issues",
21
+ "fix_new_issues",
13
22
  "recommended_actions",
14
23
  "competitor_pages",
24
+ "competitor_takes",
15
25
  "icp_visitors",
16
26
  "vc_visitors",
17
27
  "plan_updates",
28
+ "weekly_release_notes",
29
+ "monthly_page_refresh",
18
30
  ];
31
+ const UNITS = ["hours", "days", "weeks", "months"];
19
32
  const STATUSES = ["pending", "proposed", "acting", "acted", "skipped", "failed", "rejected"];
20
33
 
21
34
  const triggerParams = {
@@ -26,8 +39,15 @@ const triggerParams = {
26
39
  hot_leads_only: { flag: "hot-leads-only", type: "bool" },
27
40
  event: { flag: "event" },
28
41
  per_day: { flag: "per-day", type: "num" },
42
+ // --trigger schedule --every 2 --unit weeks: a recurring automation, on the calendar (Monday, the 1st).
43
+ every: { flag: "every", type: "num" },
44
+ unit: { flag: "unit", enum: UNITS },
29
45
  },
30
46
  };
47
+ // --sandbox / --no-sandbox: always run the prompt in a Build sandbox (the repo and Letter's tools); off, Letterpress decides per event.
48
+ const sandbox = {
49
+ value: (flags) => (flags["no-sandbox"] === true ? false : flags.sandbox === true ? true : undefined),
50
+ };
31
51
  // --slack-channel C0123ABCD (repo slack-targets), or none to post nothing.
32
52
  const slackChannel = {
33
53
  value: (flags) =>
@@ -96,6 +116,7 @@ export const ARGS = {
96
116
  instruction: { flag: "instruction" },
97
117
  prompt: { flag: "prompt" },
98
118
  slack_channel: slackChannel,
119
+ sandbox,
99
120
  enabled,
100
121
  backfill,
101
122
  },
@@ -108,6 +129,7 @@ export const ARGS = {
108
129
  instruction: { flag: "instruction" },
109
130
  prompt: { flag: "prompt" },
110
131
  slack_channel: slackChannel,
132
+ sandbox,
111
133
  enabled,
112
134
  backfill,
113
135
  },
@@ -50,6 +50,8 @@ const ARGS = {
50
50
  files: { value: (_flags, _positionals, extra) => (extra.files?.length ? extra.files : undefined) },
51
51
  delivery: { flag: "action", enum: ["build", "build_pr", "build_merge", "slack", "linear"] },
52
52
  notify_slack: { flag: "notify-slack", type: "bool" },
53
+ // --primitives-access: every change reads Letter's tools from its sandbox (a read-only MCP key beside the repo).
54
+ primitives_access: { flag: "primitives-access", type: "bool" },
53
55
  harness: { flag: "harness", enum: ["letterpress-1", "claude-code", "codex"] },
54
56
  // --branch <name>: where its changes start and its pull requests go; omitted, the branch that builds the site.
55
57
  base_branch: "branch",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.176.52",
3
+ "version": "0.176.53",
4
4
  "description": "Spin up and manage Letter phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",