@letterstory/cli 0.137.0 → 0.138.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
@@ -63,7 +63,7 @@ import {
63
63
  } from "./commands.mjs";
64
64
 
65
65
  // Keep in sync with cli/package.json.
66
- export const VERSION = "0.137.0";
66
+ export const VERSION = "0.138.0";
67
67
 
68
68
  // Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
69
69
  // can't accidentally swallow the id as --json's value. Every `type: "bool"` flag (and its
@@ -1329,6 +1329,7 @@ Insights:
1329
1329
  insights reads [--period …] [--site all|own|phantoms|<key>]... [--path <path>] [--engine <operator>]
1330
1330
  Measure → Reads: AI engines and people reading your sites, counted one way
1331
1331
  insights questions [--period 14d|30d|90d] Measure → Questions: every question we ask, named / share / change / cited
1332
+ insights pages [--period 14d|30d|90d] [--site own|phantoms|<key>] Measure → Pages: your pages AI answers cited, won questions first
1332
1333
  insights competitors [--period 14d|30d|90d] GEO → Competitors: share of mentions per brand, is it moving, by engine/question
1333
1334
  insights question <key> [--period 14d|30d|90d] [--filter all|named_you|rival_not_you|no_one] [--limit n]
1334
1335
  One By-question row: the wordings asked and the AI answers
@@ -1401,6 +1402,9 @@ Repo changes (Claude Code edits your repo in a sandbox; the Letterstory GitHub A
1401
1402
  repo install-letterprove --repo <owner/name> [--branch <base>] [--action build|build_pr|build_merge|slack|linear] [--wait]
1402
1403
  One PR adding Letterprove's script and identify calls
1403
1404
  (pick the repo where users sign in)
1405
+ repo install-visitors [--site <id>] [--repo <owner/name>] [--branch <base>] [--action build|build_pr|build_merge|slack|linear] [--wait]
1406
+ One PR adding the Visitors script tag to the repo that
1407
+ builds the site (--repo: another repo)
1404
1408
  repo sites [--detect [--force]] Which website each repo builds, and the evidence
1405
1409
  repo set-site --repo <owner/name> --site <host> [--not] [--branch <name>|none]
1406
1410
  Say which site a repo builds (--not: correct a wrong label)
@@ -1414,7 +1418,7 @@ Repo changes (Claude Code edits your repo in a sandbox; the Letterstory GitHub A
1414
1418
  repo status <run-id> Phase, spend, PR link and Claude's summary
1415
1419
  repo activity <run-id> [--follow] What the sandbox is doing, line by line (--follow: until it stops)
1416
1420
  repo list [--status running|succeeded|no_changes|failed|cancelled] [--limit n] [--audit <id>]
1417
- [--source site_audit_issue|site_quick_check|letterprove_install]
1421
+ [--source site_audit_issue|site_quick_check|letterprove_install|visitors_install]
1418
1422
  repo publish <run-id> Make PR on a preview in review
1419
1423
  repo revise <run-id> --instructions <text>|--instructions-file <path|->
1420
1424
  Ask for more on a preview; it takes over the preview's link
@@ -2,7 +2,7 @@
2
2
  // network, single-post, and top-posts levels (ported from phantomstory-cli's
3
3
  // insights.ts); plus Measure's Overview (`summary`), GEO → Competitors
4
4
  // (`competitors`), AI Visibility Bank (`bank`) and phantom Page Access (`access`);
5
- // Measure → Reads (`reads`) and Questions (`questions`), and the live feed of what
5
+ // Measure → Reads (`reads`), Questions (`questions`) and Pages (`pages`), and the live feed of what
6
6
  // is reading the phantom sites (`activity`) — the same reads the web app renders.
7
7
 
8
8
  import { CliError } from "../client.mjs";
@@ -38,6 +38,10 @@ export const ARGS = {
38
38
  list_measure_questions: {
39
39
  period: { flag: "period", enum: PERIODS },
40
40
  },
41
+ list_cited_pages: {
42
+ period: { flag: "period", enum: PERIODS },
43
+ sites: { flag: "site", type: "list" },
44
+ },
41
45
  get_recent_activity: {
42
46
  phantom_id: { flag: "phantom" },
43
47
  limit: { flag: "limit", type: "num" },
@@ -76,11 +80,13 @@ export async function cmdInsights(ctx) {
76
80
  return call(rest, "get_reads");
77
81
  case "questions":
78
82
  return call(rest, "list_measure_questions");
83
+ case "pages":
84
+ return call(rest, "list_cited_pages");
79
85
  case "activity":
80
86
  return call(rest, "get_recent_activity");
81
87
  default:
82
88
  throw new CliError(
83
- `Unknown insights subcommand: ${sub ?? "(none)"}. Try: summary, reads, questions, competitors, question, detection, activity, site, post, top, bank, access`
89
+ `Unknown insights subcommand: ${sub ?? "(none)"}. Try: summary, reads, questions, pages, competitors, question, detection, activity, site, post, top, bank, access`
84
90
  );
85
91
  }
86
92
  }
@@ -8,6 +8,7 @@
8
8
  // repo repos → list_github_app_repos repo branches → list_repo_branches
9
9
  // repo prs → list_open_pull_requests (every open PR, whoever opened it)
10
10
  // repo install-letterprove → letterprove_open_install_pr
11
+ // repo install-visitors → visitors_open_install_pr
11
12
  // repo secrets → list_repo_preview_secrets repo set-secret → set_repo_preview_secret
12
13
  // repo delete-secret → delete_repo_preview_secret
13
14
  // repo suggestions → list_suggested_fixes
@@ -117,6 +118,13 @@ const ARGS = {
117
118
  base_branch: "branch",
118
119
  action: { flag: "action", enum: ["build", "build_pr", "build_merge", "slack", "linear"] },
119
120
  },
121
+ visitors_open_install_pr: {
122
+ site_id: "site",
123
+ repo_owner: { value: (flags) => splitRepo(flags).owner },
124
+ repo_name: { value: (flags) => splitRepo(flags).name },
125
+ base_branch: "branch",
126
+ action: { flag: "action", enum: ["build", "build_pr", "build_merge", "slack", "linear"] },
127
+ },
120
128
  get_repo_change_settings: {},
121
129
  list_suggested_fixes: {},
122
130
  list_slack_fix_targets: {},
@@ -187,7 +195,13 @@ const ARGS = {
187
195
  audit_id: "audit",
188
196
  source_kind: {
189
197
  flag: "source",
190
- enum: ["site_audit_issue", "site_quick_check", "letterprove_install", "collection_publish"],
198
+ enum: [
199
+ "site_audit_issue",
200
+ "site_quick_check",
201
+ "letterprove_install",
202
+ "visitors_install",
203
+ "collection_publish",
204
+ ],
191
205
  },
192
206
  site_host: "site",
193
207
  },
@@ -247,6 +261,8 @@ export async function cmdRepo(ctx) {
247
261
  return repoFixAudit(rest);
248
262
  case "install-letterprove":
249
263
  return repoInstallLetterprove(rest);
264
+ case "install-visitors":
265
+ return repoInstallVisitors(rest);
250
266
  case "sites":
251
267
  return repoSites(rest);
252
268
  case "set-site":
@@ -283,7 +299,7 @@ export async function cmdRepo(ctx) {
283
299
  return repoSlackTest(rest);
284
300
  default:
285
301
  throw new CliError(
286
- `Unknown repo subcommand: ${sub ?? "(none)"}. Try: start, fix-audit, install-letterprove, sites, set-site, reset-site, secrets, set-secret, delete-secret, status, list, publish, cancel, repos, branches, prs, settings, suggestions, slack-targets, slack-test`
302
+ `Unknown repo subcommand: ${sub ?? "(none)"}. Try: start, fix-audit, install-letterprove, install-visitors, sites, set-site, reset-site, secrets, set-secret, delete-secret, status, list, publish, cancel, repos, branches, prs, settings, suggestions, slack-targets, slack-test`
287
303
  );
288
304
  }
289
305
  }
@@ -434,6 +450,22 @@ async function repoInstallLetterprove(ctx) {
434
450
  return followRun(ctx, result.run);
435
451
  }
436
452
 
453
+ /** `repo install-visitors [--site id] [--repo owner/name] [--branch b] [--wait]`: the Visitors script tag → one PR. */
454
+ async function repoInstallVisitors(ctx) {
455
+ const { client, flags, io } = ctx;
456
+ refuseUnknownFlags(ctx, {}, ["site", "repo", "owner", "name", "branch", "action", "wait"]);
457
+ const result = await client.callTool(
458
+ "visitors_open_install_pr",
459
+ argsFromFlags(ARGS.visitors_open_install_pr, flags, ctx.positionals)
460
+ );
461
+ ok(ctx, result.message);
462
+ if (!flags.wait) {
463
+ printResult(io, flags, result.run, describe);
464
+ return 0;
465
+ }
466
+ return followRun(ctx, result.run);
467
+ }
468
+
437
469
  /** `repo sites [--detect] [--force]`: which website each repo builds, and why. */
438
470
  async function repoSites(ctx) {
439
471
  const { client, flags, io } = ctx;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.137.0",
3
+ "version": "0.138.0",
4
4
  "description": "Spin up and manage Letterstory phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",