@koda-sl/baker-cli 0.394.0 → 0.395.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
@@ -3201,17 +3201,17 @@ Search the **ad-dna** corpus of scored "winning" competitor ads for reference cr
3201
3201
 
3202
3202
  ### `baker winning-ads search <query>`
3203
3203
 
3204
- Semantic search (dense recall + BM25 + rerank) → `POST /api/ad-library/winners/search`. The CLI projects each result to a **lean, decision-focused** shape so the agent's context stays small — default fields: `advertiser`, `advertiser_id`, `platform`, `format`, `relevance`, `winner_score`, `summary` (what the ad is about), `media_url`, and `visual` (what the viewer sees) + `container` (a static's layout pattern) when known; plus top-level `pool_size`, `match_confidence` (`high|medium|low`), and `below_floor_count` (matches dropped under the relevance floor). `--full` adds DNA detail (`angle`, `target_persona`, `hook_archetype`, `mechanism`, `awareness_stage`, `industry`) + longevity (`days_active`, `reach`, `active`, `winner_category`, `media_kind`). `--output json` (default) returns the lean objects; `--output md` prints a table.
3204
+ Semantic search (dense recall + BM25 + rerank) → `POST /api/ad-library/winners/search`. The CLI projects each result to a **lean, decision-focused** shape so the agent's context stays small — default fields: `advertiser`, `advertiser_id`, `platform`, `format`, `relevance`, `winner_score`, `summary` (what the ad is about), `media_url`, and `visual` (what the viewer sees) + `container` (a static's layout pattern) + `mechanism` (why it works) when known; plus top-level `pool_size`, `match_confidence` (`high|medium|low`), and `below_floor_count` (matches dropped under the relevance floor). `--full` adds DNA detail (`angle`, `target_persona`, `hook_archetype`, `awareness_stage`, `industry`) + longevity (`days_active`, `reach`, `active`, `winner_category`, `media_kind`). `--output json` (default) returns the lean objects; `--output md` prints a table.
3205
3205
 
3206
3206
  > `media_url` is the creative itself: for `static` it's the image, for `video` it's the video file. ad-dna stores **no separate poster** for videos, so a video result has only the video URL.
3207
3207
 
3208
- > Results are already de-junked and winner-first: the corpus auto-drops measured failures (duds, thrash) and ranks `final = relevance^0.25 × winner_score^0.75`. So `--winner-category winner` is usually unnecessary — it's a stricter filter that also removes `untested` (unproven-but-maybe-fresh) ads. Rely on the default + `--min-relevance`; only add `--winner-category` to force-exclude unproven creatives. (Restricting to a single `--advertiser-id` turns the failure-exclusion off — you then see that brand's duds too.)
3208
+ > Results are already de-junked and winner-first: the corpus auto-drops measured failures (duds, thrash) and ranks `final = relevance^0.25 × winner_score^0.75`. So `--winner-category winner` is usually unnecessary — it's a stricter filter that also removes `untested` (unproven-but-maybe-fresh) ads. Rely on the default + `--min-relevance`; only add `--winner-category` to force-exclude unproven creatives. (With a query, restricting to a single `--advertiser-id` turns the failure-exclusion and the per-advertiser cap off: you then see that brand's duds too. A search with no query is a browse, which always drops failures and `untested` ads. A company that follows one brand keeps both with `--scope followed`/`followed-first`.)
3209
3209
 
3210
3210
  ```bash
3211
3211
  # Only LinkedIn video ads:
3212
3212
  baker winning-ads search "B2B lead gen demo" --platform linkedin --format video --output md
3213
- # Cross-platform, exclude our own brand + an advertiser we already mined:
3214
- baker winning-ads search "fintech onboarding" --exclude-advertiser adv_ourbrand,adv_usedbefore --output md
3213
+ # Cross-platform, excluding our own brand (an ad we already adapted comes back last, marked already_adapted):
3214
+ baker winning-ads search "fintech onboarding" --exclude-advertiser adv_ourbrand --output md
3215
3215
  # Similar-to a reference ad, recent only:
3216
3216
  baker winning-ads search --ref-ad-id a_12345 --first-seen-after 2026-01-01T00:00:00Z --limit 5 --output md
3217
3217
  # One varied reference per concept (different brands, containers, hooks) in one call:
@@ -3225,22 +3225,24 @@ baker winning-ads search --format-pattern comparison_table --platform meta --out
3225
3225
  | `query` (positional) | Free-text natural-language query |
3226
3226
  | `--ref-ad-id <id>` | Find ads similar to this ad (instead of free text) |
3227
3227
  | `--limit <n>` | Max results 1–100 (**default 10** — shortlist size) |
3228
- | `--max-per-advertiser <n>` | Cap results per advertiser 1–50 (default 3) |
3228
+ | `--max-per-advertiser <n>` | Cap results per advertiser 0–50 (default 3; `0` = no cap) |
3229
3229
  | `--min-relevance <0-1>` | Relevance floor; trims weak matches |
3230
- | `--platform <list>` | `meta,linkedin` — pass a single value to search **only** that platform |
3230
+ | `--platform <list>` | `meta,linkedin,tiktok` — pass a single value to search **only** that platform |
3231
3231
  | `--format <list>` | `video,static,carousel` |
3232
3232
  | `--winner-category <list>` | `winner,scaled_winner,evergreen,rising,untested,dud,…` (default: all) |
3233
3233
  | `--awareness <list>` | `unaware,problem_aware,solution_aware,product_aware,most_aware` |
3234
3234
  | `--advertiser-id <list>` | **Restrict to** these advertiser ids (browse one brand's winners) |
3235
- | `--exclude-advertiser <list>` | **Drop** these advertiser ids — your own brand + already-used references |
3235
+ | `--exclude-advertiser <list>` | **Drop** these advertiser ids, usually your own brand |
3236
3236
  | `--country <list>` / `--language <list>` | Filter by country / language codes |
3237
- | `--first-seen-after` / `--first-seen-before` | ISO datetime bounds (recency) |
3237
+ | `--first-seen-after` / `--first-seen-before` | ISO date (`2026-01-01`, read as the start of that day in UTC) or datetime bounds (recency) |
3238
3238
  | `--hook-archetype <list>` | Narrow to ads on a proven hook **seed** (from `winning-ads hooks`) |
3239
3239
  | `--format-pattern <list>` | Narrow to statics in these containers (from `winning-ads formats`, e.g. `comparison_table`) |
3240
3240
  | `--diverse` | One varied page (different brands, containers, hooks) instead of rank order; ignores paging |
3241
3241
  | `--output json\|md\|files` | Output format (default json) |
3242
3242
  | `--full` | Include DNA detail + longevity |
3243
3243
 
3244
+ A value outside a closed list (`--platform`, `--format`, `--winner-category`, `--awareness`, `--format-pattern`), a non-numeric `--limit`/`--max-per-advertiser`/`--min-relevance`, or a bound that is not a date is refused before the search runs; a refused list value comes with `error.fix.validValues`. References this company already adapted (`already_adapted`) never take a fresh reference's place: `--limit N` returns up to N fresh ones first. The search waits up to 120 s (`followed-first` can run two library searches).
3245
+
3244
3246
  Reading the scores: **`relevance`** (0–1) = match of the creative to your query; **`winner_score`** = how proven the ad is in-market. Pick references that are both relevant *and* proven.
3245
3247
 
3246
3248
  ### `baker winning-ads hooks|mechanisms|formats`
@@ -3253,7 +3255,7 @@ guessing. The rollup is recomputed daily. (Distinct from `winning-ads patterns`,
3253
3255
 
3254
3256
  ```bash
3255
3257
  # Top winning hook seeds for problem-aware SaaS on Meta:
3256
- baker winning-ads hooks --platform meta --awareness problem_aware --industry saas --output md
3258
+ baker winning-ads hooks --platform meta --awareness problem_aware --industry "Software & SaaS" --output md
3257
3259
  # Then narrow a reference search to that proven hook:
3258
3260
  baker winning-ads search "onboarding demo" --hook-archetype callout --output md
3259
3261
  # Also: mechanisms (how the product claims to work, not the ad's device), formats (static ad layouts):
@@ -3265,7 +3267,7 @@ baker winning-ads formats --awareness solution_aware --output md
3265
3267
  |---|---|
3266
3268
  | `--platform <p>` | Segment on a single platform |
3267
3269
  | `--awareness <stage>` | Segment on a single awareness stage |
3268
- | `--industry <seed>` | Segment on a single industry seed |
3270
+ | `--industry <seed>` | Segment on a single industry seed from the extractor vocabulary (`seedVocabularies.yaml`), any case; a term naming exactly one seed resolves to it (`saas` → `Software & SaaS`), an ambiguous or unknown one is refused with the valid list |
3269
3271
  | `--limit <n>` | Max keys 1–100 (default 20) |
3270
3272
  | `--full` | Include the per-key segment breakdown |
3271
3273
 
@@ -967,6 +967,7 @@ function compactWinningAd(record) {
967
967
  media_url: String(record.media_url ?? ""),
968
968
  ...typeof dna.visual === "string" && dna.visual ? { visual: dna.visual } : {},
969
969
  ...typeof dna.container === "string" && dna.container ? { container: dna.container } : {},
970
+ ...typeof dna.mechanism === "string" && dna.mechanism ? { mechanism: dna.mechanism } : {},
970
971
  ...bakerUses(record.baker_uses),
971
972
  ...record.source === "followed" || record.source === "library" ? { source: record.source } : {}
972
973
  };
@@ -1310,4 +1311,4 @@ export {
1310
1311
  captureVimeoCookie,
1311
1312
  childEnvWith
1312
1313
  };
1313
- //# sourceMappingURL=chunk-53ATKV76.js.map
1314
+ //# sourceMappingURL=chunk-BRIJ4OWT.js.map