@letterstory/cli 0.176.84 → 0.176.85

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
@@ -85,7 +85,7 @@ import {
85
85
  import { fetchParkedSections, withoutParked } from "./parked.mjs";
86
86
 
87
87
  // Matches cli/package.json; publish-cli.yml rewrites both to the published version.
88
- export const VERSION = "0.176.84";
88
+ export const VERSION = "0.176.85";
89
89
 
90
90
  /** The exit code for a gate refusal (CARD_REQUIRED, PAYMENT_FAILED, OUT_OF_TOKENS): 1 is a plain error. */
91
91
  export const EXIT_PAYMENT_REQUIRED = 3;
@@ -1841,6 +1841,8 @@ The Site (one model of your whole marketing site, keyed by host and path):
1841
1841
  site competitors [--since <iso> | --days <n>] [--limit <n>] Tracked competitors' sites: new and removed pages, by folder
1842
1842
  site watch-competitors [domain] [--limit <n>] Map competitors' sitemaps (the next few unmapped, or one now)
1843
1843
  site highlight <domain> [--off] Highlight a competitor; its changes lead the top changes
1844
+ site prospect <url> [--pages <n>] [--max-pages <n>] [--depth <n>]
1845
+ Staff: any company's site, no account: what Fix would list, each PR
1844
1846
 
1845
1847
  Repo changes (Claude Code edits your repo in a sandbox; the Letter GitHub App opens a PR):
1846
1848
  repo repos [--gitlab [--search <text>] [--page n]] Repos the Letter GitHub App can reach (--gitlab: the GitLab
@@ -14,6 +14,7 @@
14
14
  // site decide <proposal> → decide_site_proposal site fix <host> <id>… → fix_site_observations
15
15
  // site competitors → list_competitor_sites site watch-competitors [d] → watch_competitor_sites
16
16
  // site highlight <domain> [--off] → set_competitor_highlight
17
+ // site prospect <url> → read_prospect_site (staff: any company's site, no account, nothing stored)
17
18
 
18
19
  import { writeFileSync } from "node:fs";
19
20
 
@@ -69,6 +70,12 @@ const ARGS = {
69
70
  skip_suggest: { flag: "skip-suggest", type: "bool" },
70
71
  },
71
72
  unmap_site: { host: { positional: 0, required: true, label: "host" } },
73
+ read_prospect_site: {
74
+ url: { positional: 0, required: true, label: "url" },
75
+ pages: { flag: "pages", type: "num" },
76
+ max_pages: { flag: "max-pages", type: "num" },
77
+ depth: { flag: "depth", type: "num" },
78
+ },
72
79
  get_llms_txt: { host: { positional: 0, required: true, label: "host" } },
73
80
  get_site_tree: {
74
81
  host: { positional: 0, required: true, label: "host" },
@@ -255,9 +262,11 @@ export async function cmdSite(ctx) {
255
262
  return siteWatchCompetitors(rest);
256
263
  case "highlight":
257
264
  return siteHighlight(rest);
265
+ case "prospect":
266
+ return siteProspect(rest);
258
267
  default:
259
268
  throw new CliError(
260
- `Unknown site subcommand: ${sub ?? "(none)"}. Try: list, map, refresh, unmap, tree, builds, metrics, page, observations, observe, dismiss, families, decide-family, proposals, propose, decide, fix, competitors, watch-competitors, highlight`
269
+ `Unknown site subcommand: ${sub ?? "(none)"}. Try: list, map, refresh, unmap, tree, builds, metrics, page, observations, observe, dismiss, families, decide-family, proposals, propose, decide, fix, competitors, watch-competitors, highlight, prospect`
261
270
  );
262
271
  }
263
272
  }
@@ -387,6 +396,29 @@ async function siteMap(ctx) {
387
396
  return 0;
388
397
  }
389
398
 
399
+ /** Any company's site read as the Site and Fix read a customer's: what Fix would list, and each pull request. */
400
+ async function siteProspect(ctx) {
401
+ const { client, flags, io } = ctx;
402
+ refuseUnknownFlags(ctx, ARGS.read_prospect_site);
403
+ const read = await client.callTool(
404
+ "read_prospect_site",
405
+ argsFromFlags(ARGS.read_prospect_site, flags, ctx.positionals)
406
+ );
407
+ printResult(io, flags, read, (r) => {
408
+ const fixFor = new Map(r.fixes.map((f) => [f.itemId, f]));
409
+ const head = [
410
+ `${r.host}${r.platform ? ` (built with ${r.platform.name})` : ""}: ${r.map.pages} pages mapped${r.map.truncated ? ` of ${r.map.listed} listed` : ""}, ${r.read.answered} of ${r.read.pages} read, ${r.open.total} open issues`,
411
+ ...(r.note ? [r.note] : []),
412
+ ];
413
+ const rows = r.issues.map((i) => {
414
+ const fix = fixFor.get(i.id);
415
+ return ` ${GLYPH[i.tone] ?? "·"} ${i.summary} ${i.path}${fix ? `\n PR: ${fix.title} (${fix.branch})` : ""}`;
416
+ });
417
+ return [...head, ...rows].join("\n");
418
+ });
419
+ return 0;
420
+ }
421
+
390
422
  async function siteRefresh(ctx) {
391
423
  const { client, flags, io } = ctx;
392
424
  refuseUnknownFlags(ctx, ARGS.refresh_site);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.176.84",
3
+ "version": "0.176.85",
4
4
  "description": "Spin up and manage Letter phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",