@koda-sl/baker-cli 0.244.0 → 0.245.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 +47 -20
- package/dist/cli.js +437 -217
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -278,7 +278,31 @@ baker ads google query --list-presets
|
|
|
278
278
|
}
|
|
279
279
|
```
|
|
280
280
|
|
|
281
|
-
Read it before interpreting any null.
|
|
281
|
+
Read it before interpreting any null. Field coverage is folded page by page on the `--out` path too, so the file summary reports it; `.resource_name` is never reported (the server strips it from every row).
|
|
282
|
+
|
|
283
|
+
**A page is not the data set.** Without `--all`, a query returns one page capped by `--limit` (default 200, or the `LIMIT` in the statement, whichever is smaller). With `--all` every page is followed, but the statement's `LIMIT` still caps the read — and preflight adds one at `--limit` to any query that arrives without it, so `--all` on its own still stops at 200 rows. When the rows fill whichever cap is in force, or the API returns a cursor the run did not follow, the response carries a `TRUNCATED_RESULTS` warning:
|
|
284
|
+
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"ok": true,
|
|
288
|
+
"warnings": [{ "code": "TRUNCATED_RESULTS", "message": "INCOMPLETE READ — ..." }],
|
|
289
|
+
"pagination": { "hasMore": true, "cursor": "eyJwYWdl..." },
|
|
290
|
+
"data": [...],
|
|
291
|
+
"notice": "Read the \"warnings\" above before using these rows: TRUNCATED_RESULTS."
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Never total or count from a response carrying it — re-run with `--all --limit 10000 --out data.csv` (the API accepts page sizes up to 10,000) and check the re-run came back without the warning. Warnings reach every output format, so no `--output` choice can hide one:
|
|
296
|
+
|
|
297
|
+
| `--output` | Where warnings land |
|
|
298
|
+
|------------|---------------------|
|
|
299
|
+
| `json` | `warnings` and `pagination` **before** `data`, one-line `notice` last |
|
|
300
|
+
| `csv` | `# baker <CODE>: …` comment lines under the header and after the last row |
|
|
301
|
+
| `md` | `> **<CODE>** — …` blockquote above and below the table |
|
|
302
|
+
| `jsonl` | a `{"_baker_warning":{…}}` line first and last |
|
|
303
|
+
| `--out` | the file summary carries `complete: true|false`, every warning, and the `notice` |
|
|
304
|
+
|
|
305
|
+
The same lines also go to stderr. A read with nothing to report prints none of it.
|
|
282
306
|
|
|
283
307
|
**Response (with pagination):**
|
|
284
308
|
|
|
@@ -311,7 +335,7 @@ Read it before interpreting any null. It does not fire on the `--out` path (rows
|
|
|
311
335
|
| `--include-paused` | Include paused entities in preset results. Off by default: presets return only actually-serving entities (enabled campaign **and** ad group **and** ad). Google Ads has no single serving flag, so the whole chain must be `ENABLED` for an entity to serve. |
|
|
312
336
|
| `--limit` | Max rows per page (default 200) |
|
|
313
337
|
| `--cursor` | Pagination cursor from previous response |
|
|
314
|
-
| `--all` | Auto-paginate all results
|
|
338
|
+
| `--all` | Auto-paginate all results. Exhausts the pages, not the statement's `LIMIT` — pair it with a `--limit` above the expected row count, and a read that still fills its cap is flagged `TRUNCATED_RESULTS` either way |
|
|
315
339
|
| `--out` | Write data to file (format from extension: .csv, .jsonl, .json) |
|
|
316
340
|
| `--append` | Append to existing file (skip CSV headers) |
|
|
317
341
|
| `--output` | Output format: `json` \| `csv` \| `jsonl` \| `md` |
|
|
@@ -337,7 +361,7 @@ Read it before interpreting any null. It does not fire on the `--out` path (rows
|
|
|
337
361
|
|
|
338
362
|
Every preset except the negatives lists and `account-summary` filters to **actually-serving entities** by default — the full status chain (`campaign.status = 'ENABLED' AND ad_group.status = 'ENABLED' AND ad_group_ad.status = 'ENABLED'`, as applicable) — and selects the status columns so you can see them. Pass `--include-paused` to widen to `!= 'REMOVED'` (keeps paused, still drops removed). Raw GAQL (no `--preset`) has no such default: a query over a serving-hierarchy resource without a status filter emits a `SERVING_SCOPE` warning reminding you to add the chain, because Google Ads has no single serving flag.
|
|
339
363
|
|
|
340
|
-
**"Eligible (Limited)" keywords:** an enabled keyword that barely shows is invisible in the performance presets — near-zero impressions look the same whether it is outbid, low quality, or rarely searched. `--preset keyword-serving` reads the signals behind Google Ads' status column: `ad_group_criterion.primary_status` and `primary_status_reasons` (the status enum has no `LIMITED` value — "(Limited)" lives in the reasons while the status stays `ELIGIBLE`), `position_estimates.first_page_cpc_micros` (the number in "Below first page bid (€3.63)"), the max CPC actually in force and where it comes from, quality score split into ad relevance / landing page / expected CTR, approval status, and `system_serving_status`. Any read whose rows carry those fields — preset or raw GAQL — comes back with a `KEYWORD_SERVING_LIMITED` warning naming the affected keywords (each by its ad group, since one keyword's copies share a criterion id) and the bid each would need. Below-first-page-bid and low-quality want opposite fixes (raise the bid vs. improve relevance), so the warning reports them separately. On `--out` the verdict is folded across pages as they stream to disk and returned on the file summary;
|
|
364
|
+
**"Eligible (Limited)" keywords:** an enabled keyword that barely shows is invisible in the performance presets — near-zero impressions look the same whether it is outbid, low quality, or rarely searched. `--preset keyword-serving` reads the signals behind Google Ads' status column: `ad_group_criterion.primary_status` and `primary_status_reasons` (the status enum has no `LIMITED` value — "(Limited)" lives in the reasons while the status stays `ELIGIBLE`), `position_estimates.first_page_cpc_micros` (the number in "Below first page bid (€3.63)"), the max CPC actually in force and where it comes from, quality score split into ad relevance / landing page / expected CTR, approval status, and `system_serving_status`. Any read whose rows carry those fields — preset or raw GAQL — comes back with a `KEYWORD_SERVING_LIMITED` warning naming the affected keywords (each by its ad group, since one keyword's copies share a criterion id) and the bid each would need. Below-first-page-bid and low-quality want opposite fixes (raise the bid vs. improve relevance), so the warning reports them separately. On `--out` the verdict is folded across pages as they stream to disk and returned on the file summary; like every other warning it also travels in `--output csv|jsonl|md`.
|
|
341
365
|
|
|
342
366
|
The warning defers to Google: when the query selects `primary_status_reasons`, a keyword Google did not flag is not reported, even if its bid sits under the first-page estimate — the estimate is advisory and the bid may not be the criterion's to set under a portfolio strategy. Only an estimates-only read (no reasons selected) falls back to inferring the limit from the bid gap.
|
|
343
367
|
|
|
@@ -432,13 +456,14 @@ baker ads google keywords discover --customer-id 1234567890 --url "https://compe
|
|
|
432
456
|
"data": {
|
|
433
457
|
"keywords": [
|
|
434
458
|
{
|
|
459
|
+
"source": "keyword_planner_estimate",
|
|
435
460
|
"keyword": "student services",
|
|
436
|
-
"
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"
|
|
440
|
-
"
|
|
441
|
-
"
|
|
461
|
+
"planner_avg_monthly_searches": "1000",
|
|
462
|
+
"planner_competition": "LOW",
|
|
463
|
+
"planner_competition_index": "4",
|
|
464
|
+
"planner_low_top_of_page_bid_micros": 0,
|
|
465
|
+
"planner_high_top_of_page_bid_micros": 0,
|
|
466
|
+
"planner_monthly_search_volumes": [
|
|
442
467
|
{ "year": "2025", "month": "APRIL", "monthly_searches": "590" }
|
|
443
468
|
]
|
|
444
469
|
}
|
|
@@ -447,12 +472,13 @@ baker ads google keywords discover --customer-id 1234567890 --url "https://compe
|
|
|
447
472
|
"next_page_token": "..."
|
|
448
473
|
},
|
|
449
474
|
"fields": {
|
|
475
|
+
"source": "Always \"keyword_planner_estimate\" — these rows are Keyword Planner ESTIMATES of total market search volume, NOT this account's data",
|
|
450
476
|
"keyword": "Suggested keyword text",
|
|
451
|
-
"
|
|
452
|
-
"
|
|
453
|
-
"
|
|
454
|
-
"
|
|
455
|
-
"
|
|
477
|
+
"planner_avg_monthly_searches": "ESTIMATE: average monthly searches across the whole market",
|
|
478
|
+
"planner_competition": "ESTIMATE: competition level — LOW, MEDIUM, HIGH, UNKNOWN",
|
|
479
|
+
"planner_competition_index": "ESTIMATE: competition index 0-100 (higher = more competitive)",
|
|
480
|
+
"planner_low_top_of_page_bid_micros": "ESTIMATE: low-range CPC bid in micros (÷ 1,000,000 for currency)",
|
|
481
|
+
"planner_high_top_of_page_bid_micros": "ESTIMATE: high-range CPC bid in micros (÷ 1,000,000 for currency)"
|
|
456
482
|
}
|
|
457
483
|
}
|
|
458
484
|
```
|
|
@@ -491,13 +517,14 @@ baker ads google keywords metrics --customer-id 1234567890 --keywords "running s
|
|
|
491
517
|
"data": {
|
|
492
518
|
"historical_metrics": [
|
|
493
519
|
{
|
|
520
|
+
"source": "keyword_planner_estimate",
|
|
494
521
|
"keyword": "running shoes",
|
|
495
|
-
"
|
|
496
|
-
"
|
|
497
|
-
"
|
|
498
|
-
"
|
|
499
|
-
"
|
|
500
|
-
"
|
|
522
|
+
"planner_avg_monthly_searches": "1000",
|
|
523
|
+
"planner_competition": "LOW",
|
|
524
|
+
"planner_competition_index": "4",
|
|
525
|
+
"planner_low_top_of_page_bid_micros": 0,
|
|
526
|
+
"planner_high_top_of_page_bid_micros": 0,
|
|
527
|
+
"planner_monthly_search_volumes": [
|
|
501
528
|
{ "year": "2025", "month": "APRIL", "monthly_searches": "590" }
|
|
502
529
|
]
|
|
503
530
|
}
|