@letterstory/cli 0.105.0 → 0.106.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
@@ -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.105.0";
63
+ export const VERSION = "0.106.1";
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
@@ -1179,7 +1179,8 @@ Repo changes (Claude Code edits your repo in a sandbox; the Letterstory GitHub A
1179
1179
  repo prs [--repo owner/name] Every open PR (whoever opened it), longest-idle first
1180
1180
  repo suggestions Fixes found and not acted on yet, and how to start each
1181
1181
  repo settings [--action build|build_pr|slack] [--branch <name>|none] [--slack-agent <name|U…>|none]
1182
- [--slack-channel <C…>|none]
1182
+ [--slack-channel <C…>|none] [--autopilot on|off] [--autopilot-weekly <1-20>]
1183
+ [--autopilot-severity critical|warning]
1183
1184
  The org's defaults for every fix: build (preview first),
1184
1185
  build_pr, or slack (post it to --slack-channel for your
1185
1186
  own agent, tagging --slack-agent), and the branch changes go to
@@ -83,7 +83,11 @@ async function staffRequest(ctx, method, path, body) {
83
83
  }
84
84
  if (!res.ok) {
85
85
  const message = payload?.error ?? `${res.status} ${res.statusText}`;
86
- throw new CliError(`${path} failed: ${message}`);
86
+ const err = new CliError(`${path} failed: ${message}`);
87
+ // The server's code and sentence, for a command that prints a refusal as it was said.
88
+ err.code = payload?.code ?? null;
89
+ err.serverMessage = payload?.error ?? null;
90
+ throw err;
87
91
  }
88
92
  return payload ?? {};
89
93
  }
@@ -3277,12 +3281,21 @@ async function cmdAdminCrm(ctx) {
3277
3281
  );
3278
3282
  }
3279
3283
  const note = flagStr(flags.note);
3280
- const r = await staffRequest(
3281
- ctx,
3282
- "PATCH",
3283
- `${CRM}/accounts/${id}`,
3284
- compact({ white_glove: action === "on", white_glove_note: note })
3285
- );
3284
+ let r;
3285
+ try {
3286
+ r = await staffRequest(
3287
+ ctx,
3288
+ "PATCH",
3289
+ `${CRM}/accounts/${id}`,
3290
+ compact({ white_glove: action === "on", white_glove_note: note })
3291
+ );
3292
+ } catch (err) {
3293
+ // A churned account is refused (409 ACCOUNT_CHURNED): say the server's sentence, not "PATCH failed".
3294
+ if (err instanceof CliError && err.code === "ACCOUNT_CHURNED" && err.serverMessage) {
3295
+ throw new CliError(err.serverMessage);
3296
+ }
3297
+ throw err;
3298
+ }
3286
3299
  return out(r, () => (action === "on" ? "moved to white glove" : "left white glove"));
3287
3300
  }
3288
3301
  case "churn": {
@@ -95,6 +95,15 @@ const ARGS = {
95
95
  slack_channel: {
96
96
  value: (flags) => (flags["slack-channel"] === "none" ? null : flagStr(flags["slack-channel"])),
97
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"] },
98
107
  },
99
108
  get_repo_change: { run_id: { positional: 0, required: true, label: "run-id" } },
100
109
  cancel_repo_change: { run_id: { positional: 0, required: true, label: "run-id" } },
@@ -443,12 +452,17 @@ async function repoBranches(ctx) {
443
452
  */
444
453
  async function repoSettings(ctx) {
445
454
  const { client, flags, io } = ctx;
446
- refuseUnknownFlags(ctx, {}, ["action", "branch", "slack-agent", "slack-channel"]);
447
- const setting =
448
- flags.action !== undefined ||
449
- flags.branch !== undefined ||
450
- flags["slack-agent"] !== undefined ||
451
- 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);
452
466
  const result = setting
453
467
  ? await client.callTool("set_repo_change_settings", argsFromFlags(ARGS.set_repo_change_settings, flags))
454
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.105.0",
3
+ "version": "0.106.1",
4
4
  "description": "Spin up and manage Letterstory phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",