@letterstory/cli 0.133.0 → 0.134.1

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
@@ -62,7 +62,7 @@ import {
62
62
  } from "./commands.mjs";
63
63
 
64
64
  // Keep in sync with cli/package.json.
65
- export const VERSION = "0.133.0";
65
+ export const VERSION = "0.134.1";
66
66
 
67
67
  // Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
68
68
  // can't accidentally swallow the id as --json's value. Every `type: "bool"` flag (and its
@@ -449,6 +449,10 @@ Reviewers:
449
449
  automations show <automation-id> --collection <id> What it covers, its queued posts, its next ideas
450
450
  automations ideas --collection <id> The ideas waiting, grouped by the automation that owns each
451
451
  automations suggest --collection <id> What it could add: topics, series formats, signals
452
+ automations starter --collection <id> The first automations, from its evidence, with the
453
+ calls that accept them (steps)
454
+ automations ground --collection <id> Its ground: strengths, near wins and gaps, with the numbers
455
+ automations works --collection <id> What works: each post and automation against its peers
452
456
  automations preview topic|series --collection <id> [--name <name>|--topic <id>] [--brief <text>]
453
457
  What it would write, before adding it
454
458
  automations more --collection <id> New topics it doesn't cover yet
@@ -923,6 +927,7 @@ Admin (STAFF key — --staff-key / LETTERSTORY_STAFF_API_KEY; acts before an org
923
927
  [--save-result …] [--draft]
924
928
  | renewals [--days 90]
925
929
  | reach-outs [--day YYYY-MM-DD] [--fresh] the day's reach-outs, N of 5 (#crm-reminders' count)
930
+ | replies [--days 14] replies nobody has answered yet, newest first
926
931
  | track-record [--since YYYY-MM-DD] | at-risk | expansion-signals
927
932
  | weekly-note the Monday retention note for the last full week
928
933
  | collections [--org-ids a,b | --account-stages won,active]
@@ -14,7 +14,7 @@
14
14
  // The old names — evals, eval-add, eval-set, proposals, propose-eval, capture-eval, reject-eval — still work.)
15
15
  // admin evals scoreboard|cases|runs|run|triage|guard|retire … (fleet:read / tuning:experiment)
16
16
  // admin fleet-experiments list|articles|clients|mark|unmark|new|assign|assign-eligible|assign-orgs|spin-up|apply|start|stop|decide … (fleet:read / fleet:experiment)
17
- // admin crm import|capture|outreach|signals|record|signal|accounts|account|score|slack-channels|link-slack|white-glove|set-white-glove|churn|revenue|reach-outs|record-churn|draft-churn-reason|undo-churn|outcomes|record-outcome|renewals|track-record|weekly-note|at-risk|expansion-signals|collections|delivery-flags|pulse|case|onboard|onboarding|retry-onboarding|onboard-plan|payment-link … (crm:read / crm:write)
17
+ // admin crm import|capture|outreach|signals|record|signal|accounts|account|score|slack-channels|link-slack|white-glove|set-white-glove|churn|revenue|reach-outs|replies|record-churn|draft-churn-reason|undo-churn|outcomes|record-outcome|renewals|track-record|weekly-note|at-risk|expansion-signals|collections|delivery-flags|pulse|case|onboard|onboarding|retry-onboarding|onboard-plan|payment-link … (crm:read / crm:write)
18
18
  // admin spend summary|reconcile|pnl|margin|pricing|entries|add|import|usage|remove|reference|stripe-sync|services|service … (spend:read / spend:write)
19
19
  // admin brand-detection <org-id> (fleet:read)
20
20
  // admin brand-detection <org-id> [--term t]... [--exact t]... [--exclude p]... [--note "…"] | --clear [--note "…"] (fleet:instrument)
@@ -3399,6 +3399,16 @@ async function cmdAdminCrm(ctx) {
3399
3399
  ].join("\n")
3400
3400
  );
3401
3401
  }
3402
+ case "replies": {
3403
+ // admin crm replies [--days 14] — companies that answered us and that nobody has
3404
+ // reached since, newest first (src/lib/crm/replies-waiting.ts).
3405
+ const params = new URLSearchParams(compact({ days: flagStr(flags.days) }));
3406
+ return out(await staffRequest(ctx, "GET", `${CRM}/replies?${params}`), (r) =>
3407
+ r.replies.length === 0
3408
+ ? "No replies waiting."
3409
+ : r.replies.map((x) => `${x.at.slice(0, 10)} ${x.name} ${x.title ?? ""}`.trimEnd()).join("\n")
3410
+ );
3411
+ }
3402
3412
  case "reach-outs": {
3403
3413
  // admin crm reach-outs [--day YYYY-MM-DD] [--fresh] — the day's reach-out count toward
3404
3414
  // the target, the same number #crm-reminders posts (src/lib/crm/reach-out-day.ts).
@@ -3732,7 +3742,7 @@ async function cmdAdminCrm(ctx) {
3732
3742
  }
3733
3743
  default:
3734
3744
  throw new CliError(
3735
- "Usage: admin crm import|capture|outreach|signals|record|signal|accounts|account|score|slack-channels|link-slack|white-glove|set-white-glove|churn|revenue|reach-outs|record-churn|draft-churn-reason|undo-churn|outcomes|record-outcome|renewals|track-record|weekly-note|at-risk|expansion-signals|collections|delivery-flags|pulse|case|onboard|onboarding|retry-onboarding|onboard-plan|payment-link … (see --help)"
3745
+ "Usage: admin crm import|capture|outreach|signals|record|signal|accounts|account|score|slack-channels|link-slack|white-glove|set-white-glove|churn|revenue|reach-outs|replies|record-churn|draft-churn-reason|undo-churn|outcomes|record-outcome|renewals|track-record|weekly-note|at-risk|expansion-signals|collections|delivery-flags|pulse|case|onboard|onboarding|retry-onboarding|onboard-plan|payment-link … (see --help)"
3736
3746
  );
3737
3747
  }
3738
3748
  }
@@ -1,5 +1,5 @@
1
1
  // `automations` — a letterbase's automations (docs/architecture/automations.md): what it writes,
2
- // how often, and why. list / show / ideas / suggest / preview / more / add / set / dismiss / remove, through the same tools the app uses.
2
+ // how often, and why. list / show / ideas / suggest / starter / ground / works / preview / more / add / set / dismiss / remove, through the same tools the app uses.
3
3
  // Same flag/positional/io conventions as posts.mjs — no commander, no color.
4
4
 
5
5
  import { CliError } from "../client.mjs";
@@ -16,6 +16,15 @@ export const ARGS = {
16
16
  suggest_automations: {
17
17
  collection_id: { flag: "collection", required: true },
18
18
  },
19
+ suggest_starter_automations: {
20
+ collection_id: { flag: "collection", required: true },
21
+ },
22
+ get_ground_measures: {
23
+ collection_id: { flag: "collection", required: true },
24
+ },
25
+ get_what_works: {
26
+ collection_id: { flag: "collection", required: true },
27
+ },
19
28
  get_automation: {
20
29
  collection_id: { flag: "collection", required: true },
21
30
  automation_id: { positional: 0, label: "automation-id", required: true },
@@ -61,6 +70,7 @@ export const ARGS = {
61
70
  dismiss_subject: {
62
71
  collection_id: { flag: "collection", required: true },
63
72
  topic_id: { positional: 0, label: "topic-id", required: true },
73
+ reason: { flag: "reason" },
64
74
  },
65
75
  delete_automation: {
66
76
  collection_id: { flag: "collection", required: true },
@@ -81,6 +91,12 @@ export async function cmdAutomations(ctx) {
81
91
  return run(rest, "list_automation_ideas");
82
92
  case "suggest":
83
93
  return run(rest, "suggest_automations");
94
+ case "starter":
95
+ return run(rest, "suggest_starter_automations");
96
+ case "ground":
97
+ return run(rest, "get_ground_measures");
98
+ case "works":
99
+ return run(rest, "get_what_works");
84
100
  case "preview":
85
101
  return run(rest, "preview_automation");
86
102
  case "more":
@@ -97,7 +113,7 @@ export async function cmdAutomations(ctx) {
97
113
  return run(rest, "delete_automation", "Removed.");
98
114
  default:
99
115
  throw new CliError(
100
- `Unknown automations subcommand: ${sub ?? "(none)"}. Try: list, show, ideas, suggest, preview, more, add, set, dismiss, remove`
116
+ `Unknown automations subcommand: ${sub ?? "(none)"}. Try: list, show, ideas, suggest, starter, ground, works, preview, more, add, set, dismiss, remove`
101
117
  );
102
118
  }
103
119
  }
@@ -103,9 +103,11 @@ export async function cmdSuggestions(ctx) {
103
103
  return suggestionsDecide(rest, "dismiss");
104
104
  case "snooze":
105
105
  return suggestionsDecide(rest, "snooze");
106
+ case "undo":
107
+ return suggestionsDecide(rest, "undo");
106
108
  default:
107
109
  throw new CliError(
108
- "Usage: suggestions <list <collection_id>|approve|dismiss|snooze <verdict|proposal> <id>>"
110
+ "Usage: suggestions <list <collection_id>|approve|dismiss|snooze|undo <verdict|proposal> <id>>"
109
111
  );
110
112
  }
111
113
  }
@@ -117,7 +119,9 @@ function formatSuggestionLine(s) {
117
119
  ? `snoozed→${s.snoozed_until.slice(0, 10)}`
118
120
  : `auto→${(s.auto_apply_at ?? "").slice(0, 10)}`
119
121
  : "hold";
120
- return `${s.kind} ${s.id} [${when}] ${s.cluster_name ?? "site"}: ${s.title}`;
122
+ const line = `${s.kind} ${s.id} [${when}] ${s.cluster_name ?? "site"}: ${s.title}`;
123
+ // A change to the automations' week: the week after, and why.
124
+ return s.week ? `${line}\n ${s.week.line}\n ${s.reason ?? ""}` : line;
121
125
  }
122
126
 
123
127
  async function suggestionsList(ctx) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.133.0",
3
+ "version": "0.134.1",
4
4
  "description": "Spin up and manage Letterstory phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",