@koda-sl/baker-cli 0.113.1 → 0.114.0-dev.249eaa8ed

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
@@ -653,6 +653,50 @@ baker ads google library search-competitors "crm software" --location uk
653
653
 
654
654
  ---
655
655
 
656
+ ### Staged writes (`baker ads google budgets|campaigns|...`)
657
+
658
+ Write commands **never touch the Google Ads API at stage time**. Each command stages a create/update/pause/resume/remove op against the current chat's draft (`BAKER_CHAT_ID`); the dashboard shows it as a pending "Google Ads" change, and the whole draft applies as one atomic `GoogleAdsService.Mutate` when the chat is published. Feature-flagged per company (`companies.googleAdsWriteEnabled`) — off by default = a fully simulated publish with zero real API calls.
659
+
660
+ 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).
661
+
662
+ ```bash
663
+ # Build a Search campaign bottom-up, chaining temp refs
664
+ baker ads google budgets create --customer-id 1234567890 --name "Search budget" --amount 50
665
+ # → { ref: "g_temp_ab12", ... }
666
+ baker ads google campaigns create --customer-id 1234567890 --name "Brand — Search" \
667
+ --channel-type SEARCH --budget-ref g_temp_ab12 --bidding-strategy MANUAL_CPC
668
+ baker ads google ad-groups create --customer-id 1234567890 --name "Brand terms" --campaign-ref g_temp_<campaign>
669
+ baker ads google keywords add --customer-id 1234567890 --ad-group-ref g_temp_<adgroup> --text "brand name" --match-type EXACT
670
+ # Shared negative keyword list → attach to the campaign
671
+ baker ads google keyword-lists create --customer-id 1234567890 --name "Brand exclusions"
672
+ baker ads google keyword-lists add --customer-id 1234567890 --list-ref g_temp_<list> --text "free" --match-type BROAD
673
+ baker ads google keyword-lists attach --customer-id 1234567890 --campaign-ref g_temp_<campaign> --list-ref g_temp_<list>
674
+
675
+ # Batch keywords — one command stages the whole set as ONE request (up to 500)
676
+ baker ads google keywords add --customer-id 1234567890 --ad-group-ref g_temp_<adgroup> \
677
+ --text "brand name, brand shop:PHRASE, brand store" --match-type EXACT
678
+ baker ads google keyword-lists add --customer-id 1234567890 --list-ref <list-id> --file negatives.txt
679
+ # negatives.txt: one keyword[:MATCH_TYPE] per line; blank lines and "# comments" are skipped
680
+ # Responsive search ad
681
+ baker ads google ads create --customer-id 1234567890 --ad-group-ref g_temp_<adgroup> \
682
+ --headlines "Fast Widgets,Buy Online,Free Shipping" --descriptions "Best widgets around.,Ships tomorrow." \
683
+ --final-url https://example.com
684
+
685
+ # Review / undo staged changes
686
+ baker ads google draft list # readable campaign ▸ ad group ▸ ad tree + completeness advisories
687
+ baker ads google draft list --json # raw JSON envelope for scripting
688
+ baker ads google draft remove g_temp_ab12 # cascades to dependents
689
+ baker ads google draft clear
690
+ ```
691
+
692
+ Command groups: `budgets`, `campaigns`, `ad-groups`, `keywords` (add/update/remove), `negative-keywords`, `keyword-lists`, `ads`, `assets`, `audiences`, `conversions`, `bidding-strategies`, `labels`, `campaign-criteria`, and `draft`. Amounts are in major currency units (converted to micros). Money/bids: `--amount`, `--cpc-bid`, `--target-cpa` take major units; `--target-roas` a ratio. Less-common ops accept a `--file <payload.json>` (flags override file keys). Updates target a resource name or bare id as the positional argument; a target that names an op staged earlier **amends it in place**.
693
+
694
+ **Reviewing the draft** — `baker ads google draft list` renders everything you've staged as a grouped campaign ▸ ad group ▸ ad tree (with the simulated/live mode banner and non-blocking completeness advisories), the CLI counterpart to the dashboard's Google Ads tab. Pass `--json` for the raw envelope. Aim for a fully built campaign — 2–4 ad groups, ≥5 keywords each, 2–4 RSAs with 8–12 headlines, ≥4 sitelinks / ≥3 callouts / ≥1 structured snippet, and ≥1 shared negative list; the advisories flag what's still thin.
695
+
696
+ **Batch keyword adds** — `keywords add`, `negative-keywords add`, and `keyword-lists add` take a whole batch in one command: comma-separate `--text` entries and/or pass `--file <list.txt>` (one keyword per line). A `:EXACT`/`:PHRASE`/`:BROAD` suffix per entry overrides the `--match-type` default. Batches stage all-or-nothing as one request (limit 500); each keyword still lands as its own draft op, so it stays individually removable/amendable.
697
+
698
+ ---
699
+
656
700
  ### Caching
657
701
 
658
702
  Google Ads data is cached at two levels:
@@ -2500,7 +2544,11 @@ baker mcp remove --name weather
2500
2544
  ```
2501
2545
 
2502
2546
  - `--url` must be HTTPS and public; loopback / private / cloud-metadata hosts are rejected.
2503
- - `--scope company` (default) shares with every chat in the company; `--scope org` needs an admin API key; `--scope user` binds to the current message sender (requires running inside a chat turn — the bridge supplies the sender via `BAKER_ACTING_USER_ID`).
2547
+ - Scope is two independent choices audience (just you / everyone) × level (this company / whole org):
2548
+ - `--scope company` (default) — everyone in this company.
2549
+ - `--scope org` — everyone across the org; needs an admin API key.
2550
+ - `--scope user` — only you, in this company; binds to the current message sender (requires a chat turn — the bridge supplies the sender via `BAKER_ACTING_USER_ID`).
2551
+ - `--scope user_org` — only you, across every company in the org; also binds to the sender (no admin needed — it only affects your own turns).
2504
2552
  - Repeat `--header "Key: Value"` for multiple auth headers. Header values are stored server-side and ride the MCP transport — `list` returns only the header keys, never the values.
2505
2553
 
2506
2554
  ---
@@ -24,9 +24,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  mod
25
25
  ));
26
26
 
27
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
27
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/index.js
28
28
  var require_safe_stable_stringify = __commonJS({
29
- "../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js"(exports, module) {
29
+ "../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/index.js"(exports, module) {
30
30
  "use strict";
31
31
  var { hasOwnProperty } = Object.prototype;
32
32
  var stringify = configure2();
@@ -902,7 +902,7 @@ function describeCause(c) {
902
902
  }
903
903
  }
904
904
 
905
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
905
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/esm/wrapper.js
906
906
  var import__ = __toESM(require_safe_stable_stringify(), 1);
907
907
  var configure = import__.default.configure;
908
908
  var wrapper_default = import__.default;
@@ -6351,4 +6351,4 @@ export {
6351
6351
  defaultRegistry,
6352
6352
  createEngineFromEnv
6353
6353
  };
6354
- //# sourceMappingURL=chunk-7K2YAWUT.js.map
6354
+ //# sourceMappingURL=chunk-5AWO4BHJ.js.map