@letterstory/cli 0.121.1 → 0.121.2

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.121.1";
63
+ export const VERSION = "0.121.2";
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
@@ -1262,6 +1262,7 @@ Repo changes (Claude Code edits your repo in a sandbox; the Letterstory GitHub A
1262
1262
  Say which site a repo builds (--not: correct a wrong label)
1263
1263
  repo reset-site --repo <owner/name> --site <host> Back to automatic detection
1264
1264
  repo status <run-id> Phase, spend, PR link and Claude's summary
1265
+ repo activity <run-id> [--follow] What the sandbox is doing, line by line (--follow: until it stops)
1265
1266
  repo list [--status running|succeeded|no_changes|failed|cancelled] [--limit n] [--audit <id>]
1266
1267
  [--source site_audit_issue|site_quick_check|letterprove_install]
1267
1268
  repo publish <run-id> Make PR on a preview in review
@@ -1,6 +1,7 @@
1
1
  // `repo` — changes to the org's own repos, made by Claude Code in a sandbox and opened as a
2
2
  // pull request by the Letterstory GitHub App (src/lib/repo-changes). One subcommand per tool:
3
3
  // repo start → start_repo_change repo status → get_repo_change
4
+ // repo activity → get_repo_change_activity (what the sandbox is doing; --follow polls)
4
5
  // repo list → list_repo_changes repo cancel → cancel_repo_change
5
6
  // repo publish → publish_repo_change (Make PR on a preview)
6
7
  // repo repos → list_github_app_repos repo branches → list_repo_branches
@@ -138,6 +139,7 @@ const ARGS = {
138
139
  autopilot_min_severity: { flag: "autopilot-severity", enum: ["critical", "warning"] },
139
140
  },
140
141
  get_repo_change: { run_id: { positional: 0, required: true, label: "run-id" } },
142
+ get_repo_change_activity: { run_id: { positional: 0, required: true, label: "run-id" } },
141
143
  cancel_repo_change: { run_id: { positional: 0, required: true, label: "run-id" } },
142
144
  publish_repo_change: { run_id: { positional: 0, required: true, label: "run-id" } },
143
145
  list_repo_changes: {
@@ -184,6 +186,8 @@ export async function cmdRepo(ctx) {
184
186
  return repoStart(rest);
185
187
  case "status":
186
188
  return repoStatus(rest);
189
+ case "activity":
190
+ return repoActivity(rest);
187
191
  case "fix-audit":
188
192
  return repoFixAudit(rest);
189
193
  case "install-letterprove":
@@ -407,6 +411,39 @@ async function repoStatus(ctx) {
407
411
  return 0;
408
412
  }
409
413
 
414
+ const ACTIVITY_MARK = { progress: "·", stage: "▸", say: "»", tool: "$", error: "!" };
415
+
416
+ /** `repo activity <run-id> [--follow]`: the build's feed; --follow prints new lines until it stops. */
417
+ async function repoActivity(ctx) {
418
+ const { client, flags, io } = ctx;
419
+ refuseUnknownFlags(ctx, {}, ["follow"]);
420
+ const args = argsFromFlags(ARGS.get_repo_change_activity, flags, ctx.positionals);
421
+ const line = (l) => `${l.at.slice(11, 19)} ${ACTIVITY_MARK[l.kind] ?? " "} ${l.text}`;
422
+ let { activity } = await client.callTool("get_repo_change_activity", args);
423
+ if (flags.json && !flags.follow) {
424
+ printResult(io, flags, activity);
425
+ return 0;
426
+ }
427
+ let seen = 0;
428
+ const print = () => {
429
+ for (const l of activity.lines.slice(seen)) io.log(flags.json ? JSON.stringify(l) : line(l));
430
+ seen = activity.lines.length;
431
+ };
432
+ print();
433
+ if (!flags.follow) return 0;
434
+ await followJob(
435
+ io,
436
+ async () => {
437
+ ({ activity } = await client.callTool("get_repo_change_activity", args));
438
+ print();
439
+ return { done: !activity.live, value: activity };
440
+ },
441
+ { intervalMs: 3000, ceilingMs: 60 * 60 * 1000 }
442
+ );
443
+ ok(ctx, `Run ${activity.runId} is ${activity.status} (${activity.phase}).`);
444
+ return 0;
445
+ }
446
+
410
447
  async function repoList(ctx) {
411
448
  const { client, flags, io } = ctx;
412
449
  const result = await client.callTool(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.121.1",
3
+ "version": "0.121.2",
4
4
  "description": "Spin up and manage Letterstory phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",