@letterstory/cli 0.104.1 → 0.106.0

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
@@ -60,7 +60,7 @@ import {
60
60
  } from "./commands.mjs";
61
61
 
62
62
  // Keep in sync with cli/package.json.
63
- export const VERSION = "0.104.1";
63
+ export const VERSION = "0.106.0";
64
64
 
65
65
  // Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
66
66
  // can't accidentally swallow the id as --json's value. Every `type: "bool"` flag (and its
@@ -1176,9 +1176,11 @@ The Site (one model of your whole marketing site, keyed by host and path):
1176
1176
  Repo changes (Claude Code edits your repo in a sandbox; the Letterstory GitHub App opens a PR):
1177
1177
  repo repos Repos the Letterstory GitHub App can reach
1178
1178
  repo branches --repo owner/name Branches a change can start from (default first)
1179
+ repo prs [--repo owner/name] Every open PR (whoever opened it), longest-idle first
1179
1180
  repo suggestions Fixes found and not acted on yet, and how to start each
1180
1181
  repo settings [--action build|build_pr|slack] [--branch <name>|none] [--slack-agent <name|U…>|none]
1181
- [--slack-channel <C…>|none]
1182
+ [--slack-channel <C…>|none] [--autopilot on|off] [--autopilot-weekly <1-20>]
1183
+ [--autopilot-severity critical|warning]
1182
1184
  The org's defaults for every fix: build (preview first),
1183
1185
  build_pr, or slack (post it to --slack-channel for your
1184
1186
  own agent, tagging --slack-agent), and the branch changes go to
@@ -4,6 +4,7 @@
4
4
  // repo list → list_repo_changes repo cancel → cancel_repo_change
5
5
  // repo publish → publish_repo_change (Make PR on a preview)
6
6
  // repo repos → list_github_app_repos repo branches → list_repo_branches
7
+ // repo prs → list_open_pull_requests (every open PR, whoever opened it)
7
8
  // repo install-letterprove → letterprove_open_install_pr
8
9
  // repo suggestions → list_suggested_fixes
9
10
  // repo settings → get_repo_change_settings, or set_repo_change_settings with --action / --branch
@@ -94,6 +95,15 @@ const ARGS = {
94
95
  slack_channel: {
95
96
  value: (flags) => (flags["slack-channel"] === "none" ? null : flagStr(flags["slack-channel"])),
96
97
  },
98
+ // --autopilot on|off, --autopilot-weekly <1-20>, --autopilot-severity critical|warning
99
+ autopilot: {
100
+ value: (flags) =>
101
+ flags.autopilot === undefined ? undefined : ["on", "true", "1"].includes(String(flags.autopilot)),
102
+ },
103
+ autopilot_weekly_limit: {
104
+ value: (flags) => (flags["autopilot-weekly"] === undefined ? undefined : Number(flags["autopilot-weekly"])),
105
+ },
106
+ autopilot_min_severity: { flag: "autopilot-severity", enum: ["critical", "warning"] },
97
107
  },
98
108
  get_repo_change: { run_id: { positional: 0, required: true, label: "run-id" } },
99
109
  cancel_repo_change: { run_id: { positional: 0, required: true, label: "run-id" } },
@@ -109,6 +119,10 @@ const ARGS = {
109
119
  repo_owner: { value: (flags) => splitRepo(flags).owner },
110
120
  repo_name: { value: (flags) => splitRepo(flags).name },
111
121
  },
122
+ list_open_pull_requests: {
123
+ repo_owner: { value: (flags) => (flags.repo === undefined ? undefined : splitRepo(flags).owner) },
124
+ repo_name: { value: (flags) => (flags.repo === undefined ? undefined : splitRepo(flags).name) },
125
+ },
112
126
  };
113
127
 
114
128
  const TERMINAL = new Set(["succeeded", "no_changes", "failed", "cancelled"]);
@@ -154,6 +168,8 @@ export async function cmdRepo(ctx) {
154
168
  return repoRepos(rest);
155
169
  case "branches":
156
170
  return repoBranches(rest);
171
+ case "prs":
172
+ return repoPrs(rest);
157
173
  case "settings":
158
174
  return repoSettings(rest);
159
175
  case "suggestions":
@@ -164,7 +180,7 @@ export async function cmdRepo(ctx) {
164
180
  return repoSlackTest(rest);
165
181
  default:
166
182
  throw new CliError(
167
- `Unknown repo subcommand: ${sub ?? "(none)"}. Try: start, fix-audit, install-letterprove, sites, set-site, reset-site, status, list, publish, cancel, repos, branches, settings, suggestions, slack-targets, slack-test`
183
+ `Unknown repo subcommand: ${sub ?? "(none)"}. Try: start, fix-audit, install-letterprove, sites, set-site, reset-site, status, list, publish, cancel, repos, branches, prs, settings, suggestions, slack-targets, slack-test`
168
184
  );
169
185
  }
170
186
  }
@@ -401,6 +417,24 @@ async function repoRepos(ctx) {
401
417
  return 0;
402
418
  }
403
419
 
420
+ /** `repo prs [--repo owner/name]`: every open PR, longest-idle first, and which Letterstory opened. */
421
+ async function repoPrs(ctx) {
422
+ const { client, flags, io } = ctx;
423
+ refuseUnknownFlags(ctx, {}, ["repo"]);
424
+ const result = await client.callTool("list_open_pull_requests", argsFromFlags(ARGS.list_open_pull_requests, flags));
425
+ printResult(io, flags, result, (r) =>
426
+ r.pullRequests.length === 0
427
+ ? "No open pull requests."
428
+ : r.pullRequests
429
+ .map(
430
+ (p) =>
431
+ `${p.repo}#${p.number} ${p.title} (${p.daysSinceUpdate}d idle${p.draft ? ", draft" : ""}${p.letterRun ? `, Letterstory run ${p.letterRun.status}` : ""})\n ${p.url}`
432
+ )
433
+ .join("\n")
434
+ );
435
+ return 0;
436
+ }
437
+
404
438
  /** `repo branches --repo owner/name`: the branches a run can start from, default first. */
405
439
  async function repoBranches(ctx) {
406
440
  const { client, flags, io } = ctx;
@@ -418,12 +452,17 @@ async function repoBranches(ctx) {
418
452
  */
419
453
  async function repoSettings(ctx) {
420
454
  const { client, flags, io } = ctx;
421
- refuseUnknownFlags(ctx, {}, ["action", "branch", "slack-agent", "slack-channel"]);
422
- const setting =
423
- flags.action !== undefined ||
424
- flags.branch !== undefined ||
425
- flags["slack-agent"] !== undefined ||
426
- flags["slack-channel"] !== undefined;
455
+ const settingFlags = [
456
+ "action",
457
+ "branch",
458
+ "slack-agent",
459
+ "slack-channel",
460
+ "autopilot",
461
+ "autopilot-weekly",
462
+ "autopilot-severity",
463
+ ];
464
+ refuseUnknownFlags(ctx, {}, settingFlags);
465
+ const setting = settingFlags.some((f) => flags[f] !== undefined);
427
466
  const result = setting
428
467
  ? await client.callTool("set_repo_change_settings", argsFromFlags(ARGS.set_repo_change_settings, flags))
429
468
  : await client.callTool("get_repo_change_settings", {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.104.1",
3
+ "version": "0.106.0",
4
4
  "description": "Spin up and manage Letterstory phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",