@koda-sl/baker-cli 0.159.0 → 0.160.0-dev.fa00ad797

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
@@ -495,6 +495,8 @@ Write commands **never touch the Google Ads API at stage time**. Each command st
495
495
 
496
496
  Reference not-yet-created resources with `g_temp_*` refs returned by earlier `create` commands (they map to Google's temporary negative-ID resource names inside one atomic batch).
497
497
 
498
+ **Staged ad copy is scanned for AI writing tells** (Google, Meta, and LinkedIn alike). When a headline, description, or primary text carries a construction that reads as machine-written — a negation pivot, a fake-candid opener, a participle hung off a comma, a vague attribution — the stage response carries an `AI COPY TELL` entry in `hints[]`. A headline set where several headlines are one claim with a swapped verb is reported as `synonym-cycling`: an AI tell *and* a real auction defect. These are advisory and can never fail a staged write, deliberately — refusing an ad over a fallible prose heuristic costs more than a tell that ships. Thresholds are stricter than the landing critic's (one occurrence is enough, since a 30-character headline has no room for a cluster), and conventions that are legitimate in ad copy are excluded outright: Title Case headlines, staccato ad rhythm, emoji, and curly quotes.
499
+
498
500
  ```bash
499
501
  # Build a Search campaign bottom-up, chaining temp refs
500
502
  baker ads google budgets create --customer-id 1234567890 --name "Search budget" --amount 50
@@ -531,6 +533,13 @@ baker ads google ads create --customer-id 1234567890 --ad-group-ref g_temp_<adgr
531
533
  baker ads google ads create --customer-id 1234567890 --ad-group-ref g_temp_<adgroup> --format demandGen \
532
534
  --headlines "Discover the app" --descriptions "Try it free today" --business-name "Acme" --final-url https://example.com \
533
535
  --image-assets g_temp_<img> --square-image-assets g_temp_<img_square> --logo-image-assets g_temp_<img_logo>
536
+ # App campaign ad — images are fields on the ad itself, same asset-ref flow
537
+ baker ads google ads create --customer-id 1234567890 --ad-group-ref g_temp_<adgroup> --format app \
538
+ --headlines "Insure your dog" --descriptions "Refunds in 2 hours" --image-assets g_temp_<img1>,g_temp_<img2>
539
+ # Change a live ad's content — every field you pass replaces its current value, so list what you want to keep
540
+ baker ads google ads update <adId> --customer-id 1234567890 --format app \
541
+ --headlines "Insure your dog" --descriptions "Refunds in 2 hours" \
542
+ --image-assets g_temp_<new_img>,<existing_asset_id>
534
543
  # Update a staged/live asset in place (flat partial — set only what changed)
535
544
  baker ads google assets update <assetId> --customer-id 1234567890 --link-text "New sitelink text" --final-urls https://example.com/new
536
545
 
@@ -4790,6 +4799,8 @@ baker landing critique spring-offer summer-offer claude # score three landings
4790
4799
  - **BRAND.md is the allowlist.** A font, hue, or ground that the client's `src/brand/BRAND.md` (mirrored into `src/styles/global.css` `@theme`, hex or oklch) commits is a decision, not a tell — matched values downgrade to advisory `brandDrift` so the critic never fights a real brand.
4791
4800
  - **Records a freshness snapshot** to `.cache/landing-critique/<slug>.json` (the source hash it scored). The publish quality gate reads it to enforce that every changed landing was critiqued and ships no block-tier tell. Re-run after edits so the snapshot stays fresh.
4792
4801
 
4802
+ - **AI writing tells are scored in the `copy` family, in English and Spanish.** Beyond buzzwords and em-dash density, the critic detects the constructions models over-produce: the negation pivot ("it's not just X, it's Y" / "no se trata solo de X, sino de Y"), fake-candid openers ("Honestly?", "La verdad es que"), participles hung off a comma (", ensuring…", ", permitiendo…"), copula avoidance ("serves as", "cuenta con"), vague attributions, signposting, filler, hollow closers, false ranges, staccato runs, Title Case headings, and chatbot framing that leaked into the page. Most need a **cluster** (≥2 on the page) before they fire — the source guidance is explicit that isolated tells prove nothing — with two deliberate exceptions: chatbot framing fires at one, and curly quotes are not detected at all, since every editor inserts them automatically. Nothing in this family is block-tier, so it never fails the publish gate. Pattern set adapted from Wikipedia's "Signs of AI writing" (WikiProject AI Cleanup).
4803
+
4793
4804
  - **Agent washing is a copy tell.** A page that claims autonomy ("fully autonomous", "while you sleep", "no human intervention") and never says anywhere what the buyer approves, overrides, or audits scores an `agent-washing` warn. One signal about oversight of the agent's actions — approval, review, override, undo/rollback, audit log, escalation — anywhere on the page clears it; the rule is page-scope precisely because the hero can defer the trust story to a section below it. Generic privacy boilerplate ("GDPR", "encrypted", "your data") deliberately does **not** clear it, since it appears in most footers and says nothing about who is in charge of the agent.
4794
4805
 
4795
4806
  Output is the standard envelope `{ ok, data, hints }` with `data = { advisory, slug, overall, counts, dimensions, findings }`. `dimensions` scores seven design families (typography, color, borders_depth, motion, spacing, copy, integrity) 0–1 (higher is better); `counts` is the block/warn/advisory tally.
@@ -4855,6 +4866,7 @@ This CLI is designed for AI agent consumption. Key patterns:
4855
4866
  - **0.150.0**: `baker landing critique` gains an `agent-washing` rule in the `copy` family — an autonomy claim ("fully autonomous", "while you sleep", "no human intervention") with no signal anywhere on the page about who oversees the agent (approval, review, override, undo/rollback, audit log, escalation) scores a warn. Page-scope, so a hero may defer the trust story to a later section; generic privacy boilerplate does not clear it. `CRITIC_VERSION` bumps to `2`.
4856
4867
  - **0.152.0**: `baker ads linkedin campaigns url-params <ad-set-id>` stages an ad set's URL tracking parameters (LinkedIn's `adTrackingParameters`) — `--param key=value` for fixed values (repeatable or `&`-joined), `--dynamic key=PLACEHOLDER` for values LinkedIn fills in per ad (`CAMPAIGN_NAME`, `CREATIVE_ID`, …), `--clear` to remove them. LinkedIn appends these to the landing URL of every ad in the ad set, including ads already running, so this replaces stamping the same UTM onto each ad's `--landing-url` — which missed later ads and double-appended keys the ad set already set. Account-level parameters remain UI-only (LinkedIn exposes no API for them).
4857
4868
  - **0.153.0**: `baker landing critique` accepts several slugs in one call (`baker landing critique a b c`). `data.landings[]` always carries one entry per slug; a single slug additionally keeps the old top-level `data.slug`/`counts`/`dimensions`/`findings` shape, so existing readers are unaffected. An invalid or missing slug anywhere in the batch still fails the whole call up front. The scaffold's Stop-hook critique gate now emits one batched command instead of one line per stale landing.
4869
+ - **0.159.0**: `baker ads google ads update` takes the same content flags as `ads create` (`--format` + `--headlines`/`--descriptions`/image refs/…), and `--format app` becomes a flag-buildable format on both, with `--image-assets` wiring an App campaign ad's images (`AppAdInfo.images`) the same way Responsive Display does. Content flags without `--format` now fail instead of being silently dropped. An ad content update replaces **every field it sends** — a list has to include the entries you want to keep, while an optional asset list you omit is left untouched on the ad — and a partial payload (only the images, or Google's read-shaped `{"appAd":{…}}`) is rejected at stage time with the fields it's missing, instead of staging cleanly and blocking publish later. Content updates also record the staged image assets they consume as dependencies, so discarding an asset no longer leaves the ad pointing at nothing.
4858
4870
 
4859
4871
  ## Publishing
4860
4872
 
@@ -7,9 +7,9 @@ import {
7
7
  __toESM
8
8
  } from "./chunk-RK67WL4O.js";
9
9
 
10
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
10
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/index.js
11
11
  var require_safe_stable_stringify = __commonJS({
12
- "../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js"(exports, module) {
12
+ "../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/index.js"(exports, module) {
13
13
  "use strict";
14
14
  var { hasOwnProperty } = Object.prototype;
15
15
  var stringify = configure2();
@@ -1075,7 +1075,7 @@ function resolveAdaptFormats(params) {
1075
1075
  return params.formats ?? [];
1076
1076
  }
1077
1077
 
1078
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
1078
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/esm/wrapper.js
1079
1079
  var import__ = __toESM(require_safe_stable_stringify(), 1);
1080
1080
  var configure = import__.default.configure;
1081
1081
  var wrapper_default = import__.default;
@@ -8028,4 +8028,4 @@ export {
8028
8028
  defaultRegistry,
8029
8029
  createEngineFromEnv
8030
8030
  };
8031
- //# sourceMappingURL=chunk-CG6OTNUU.js.map
8031
+ //# sourceMappingURL=chunk-K424D3CY.js.map