@koda-sl/baker-cli 0.212.0 → 0.214.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/README.md CHANGED
@@ -2691,7 +2691,11 @@ baker winning-ads follow "https://www.linkedin.com/company/acme" --platform link
2691
2691
 
2692
2692
  ### `baker winning-ads following`
2693
2693
 
2694
- List the brands you follow → `GET /api/ad-library/following`. Each row shows `status` (`ready` vs `adding…`) plus cached counts (`active_ad_count`, `total_ad_count`, `family_count`) and discovery progress (`adding_discovered`, `adding_enqueued`). `--full` adds `image_url` + `platforms`.
2694
+ List the brands you follow → `GET /api/ad-library/following`. Each row shows `status` (`ready` vs `adding…`) plus cached counts (`active_ad_count`, `total_ad_count`, `family_count`) and progress through the two stages of adding a brand (`adding_discovered`, `adding_enqueued`, `adding_ingested` — the last two are both counts for the current run, so they read as a fraction). `--full` adds `image_url` + `platforms`.
2695
+
2696
+ **A brand's counts only mean something once it is `ready`.** While it is `adding…` they are a lie in progress. And `discovery_failed: true` on a `ready` brand says we finished but couldn't see everything, so its counts are *short* — which is not the same as the brand running no ads, though both show zero. Re-run `follow` on it to try again.
2697
+
2698
+ Response `hints` name both cases: brands we couldn't finish, and brands still filling in. In `--output md`/`files` the table is the payload and the hints are written to **stderr** so they still surface without corrupting the output.
2695
2699
 
2696
2700
  ```bash
2697
2701
  baker winning-ads following --output md
package/dist/cli.js CHANGED
@@ -1441,7 +1441,7 @@ var resolvePreviewSchema = z2.object({
1441
1441
  website: z2.string().nullable(),
1442
1442
  followers: z2.number().nullable()
1443
1443
  });
1444
- var followedStatusSchema = z2.enum(["discovering", "ready"]);
1444
+ var followedStatusSchema = z2.enum(["discovering", "ingesting", "ready"]);
1445
1445
  var followedAdvertiserSchema = z2.object({
1446
1446
  // Baker subscription row id (used to unfollow).
1447
1447
  followed_id: z2.string(),
@@ -1453,9 +1453,15 @@ var followedAdvertiserSchema = z2.object({
1453
1453
  active_ad_count: z2.number().nullable(),
1454
1454
  total_ad_count: z2.number().nullable(),
1455
1455
  family_count: z2.number().nullable(),
1456
- // Progress while status === "discovering".
1456
+ // Progress while status is "discovering" or "ingesting". `adding_ingested`
1457
+ // and `adding_enqueued` are both counts for the CURRENT run, so they read as
1458
+ // a fraction; `total_ad_count` is the brand's whole corpus and is not.
1457
1459
  adding_discovered: z2.number().nullable(),
1458
- adding_enqueued: z2.number().nullable()
1460
+ adding_enqueued: z2.number().nullable(),
1461
+ adding_ingested: z2.number().nullable(),
1462
+ // A discovery job ended in failure, so this brand's ads are under-counted.
1463
+ // Distinguishes "we couldn't finish looking" from "this brand runs no ads".
1464
+ discovery_failed: z2.boolean().nullable()
1459
1465
  });
1460
1466
  var followingListResponseSchema = z2.object({
1461
1467
  following: z2.array(followedAdvertiserSchema)
@@ -40079,7 +40085,7 @@ registerSchema({
40079
40085
  prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false },
40080
40086
  template: {
40081
40087
  type: "string",
40082
- description: "Run one of Baker's templates on this schedule, by its id from `baker scheduled-actions templates --list`. The recipe's brief and prompt are resolved from the catalog every time it fires, so it stays current; use --description to carry what is specific to this company. Refused if that template is already set up here.",
40088
+ description: "Start this schedule from one of Baker's templates, by its id from `baker scheduled-actions templates --list`. The template's brief is **copied** onto the task, so the person who owns it can read and edit exactly what it will do; anything you pass in --prompt is appended after it. Editing the template later does not change a task already built from it, and the same template can be used more than once.",
40083
40089
  required: false
40084
40090
  }
40085
40091
  }
@@ -44207,7 +44213,7 @@ var followCompetitorsCommand = defineCommand207({
44207
44213
  import { defineCommand as defineCommand208 } from "citty";
44208
44214
  registerSchema({
44209
44215
  command: "winning-ads.following",
44210
- description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts.",
44216
+ description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts. A brand still adding has counts that are a lie in progress; one with `discovery_failed` has counts that are short because we couldn't finish looking, which is not the same as it running no ads.",
44211
44217
  args: {}
44212
44218
  });
44213
44219
  function displayStatus(status) {
@@ -44223,9 +44229,30 @@ function compactFollowed(record) {
44223
44229
  total_ad_count: record.total_ad_count ?? null,
44224
44230
  family_count: record.family_count ?? null,
44225
44231
  adding_discovered: record.adding_discovered ?? null,
44226
- adding_enqueued: record.adding_enqueued ?? null
44232
+ adding_enqueued: record.adding_enqueued ?? null,
44233
+ adding_ingested: record.adding_ingested ?? null,
44234
+ // Without this a brand we failed to finish looking at is indistinguishable
44235
+ // from one that genuinely runs no ads — both read `ready` with 0 ads.
44236
+ discovery_failed: record.discovery_failed ?? null
44227
44237
  };
44228
44238
  }
44239
+ function followingHints(records) {
44240
+ const hints = [];
44241
+ const label = (r) => String(r.label ?? r.advertiser_id ?? "");
44242
+ const incomplete = records.filter((r) => r.discovery_failed === true && r.status !== "adding\u2026");
44243
+ if (incomplete.length > 0) {
44244
+ hints.push(
44245
+ `${incomplete.length} brand(s) couldn't be fully added: ${incomplete.map(label).join(", ")}. Their counts are incomplete \u2014 re-run \`baker winning-ads follow <domain>\` for each to try again.`
44246
+ );
44247
+ }
44248
+ const adding = records.filter((r) => r.status === "adding\u2026");
44249
+ if (adding.length > 0) {
44250
+ hints.push(
44251
+ `${adding.length} brand(s) are still being added: ${adding.map(label).join(", ")}. Their ad counts fill in over the next few minutes \u2014 don't report them as final, and don't re-follow to speed it up.`
44252
+ );
44253
+ }
44254
+ return hints;
44255
+ }
44229
44256
  function followingNormalizer(record, full) {
44230
44257
  const compact2 = compactFollowed(record);
44231
44258
  if (!full) {
@@ -44240,7 +44267,7 @@ function followingNormalizer(record, full) {
44240
44267
  var followingCommand = defineCommand208({
44241
44268
  meta: {
44242
44269
  name: "following",
44243
- description: "List brands you follow, with status (ready / adding\u2026) and cached counts. Example: baker winning-ads following --output md"
44270
+ description: "List brands you follow, with status (ready / adding\u2026) and cached counts. A brand's counts are only final once it is ready. Example: baker winning-ads following --output md"
44244
44271
  },
44245
44272
  args: {
44246
44273
  output: { type: "string", description: "Output format: json|files|md", required: false, default: "json" },
@@ -44253,13 +44280,14 @@ var followingCommand = defineCommand208({
44253
44280
  const output = args.output || "json";
44254
44281
  const full = args.full;
44255
44282
  const rawList = Array.isArray(data?.following) ? data.following : [];
44283
+ const following = rawList.map((f) => followingNormalizer(f, full));
44284
+ const hints = followingHints(following);
44256
44285
  if (output === "json") {
44257
- const following = rawList.map((f) => followingNormalizer(f, full));
44258
- writeJson({ ok: true, data: { following } });
44286
+ writeJson({ ok: true, data: { following }, hints: hints.length > 0 ? hints : void 0 });
44259
44287
  return;
44260
44288
  }
44261
44289
  writeOutput(
44262
- { ok: true, data: rawList },
44290
+ { ok: true, data: rawList, hints: hints.length > 0 ? hints : void 0 },
44263
44291
  output,
44264
44292
  args.fields ? args.fields.split(",") : void 0,
44265
44293
  full,