@koda-sl/baker-cli 0.347.0 → 0.348.0-dev.78a35388f

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
@@ -304,7 +304,7 @@ Read it before interpreting any null. Field coverage is folded page by page on t
304
304
  }
305
305
  ```
306
306
 
307
- 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. A read that returns one row by construction — `FROM customer` with no segment selected, such as `--preset account-summary` — has no page to fill, so it never carries `TRUNCATED_RESULTS`, nor `CONVERSION_MIX`, since one account-wide row has no campaigns to total or compare. Warnings reach every output format, so no `--output` choice can hide one:
307
+ Never total or count from a response carrying it — re-run with `--all --limit 8192 --out data.csv` (one read returns at most 8,192 rows; split a bigger data set into narrower queries — a shorter date range or one campaign each) and check the re-run came back without the warning. A read that returns one row by construction — `FROM customer` with no segment selected, such as `--preset account-summary` — has no page to fill, so it never carries `TRUNCATED_RESULTS`, nor `CONVERSION_MIX`, since one account-wide row has no campaigns to total or compare. Warnings reach every output format, so no `--output` choice can hide one:
308
308
 
309
309
  | `--output` | Where warnings land |
310
310
  |------------|---------------------|
@@ -343,11 +343,11 @@ The same lines also go to stderr. A read with nothing to report prints none of i
343
343
  |-----------------|--------------------------------------------------------------|
344
344
  | `--customer-id` | Google Ads customer ID (10 digits, no dashes). Falls back to `BAKER_GOOGLE_ADS_CUSTOMER_ID` env var. |
345
345
  | `--preset` | Named query template (see presets below) |
346
- | `--date-range` | Override preset date range (LAST_7_DAYS, LAST_30_DAYS, etc.) |
346
+ | `--date-range` | Override preset date range: a Google literal (LAST_7_DAYS, LAST_30_DAYS, LAST_MONTH, etc.) or `BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'` — there is no LAST_90_DAYS |
347
347
  | `--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. |
348
- | `--limit` | Max rows per page (default 200) |
348
+ | `--limit` | Max rows per page (default 200, at most 8,192) |
349
349
  | `--cursor` | Pagination cursor from previous response |
350
- | `--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 |
350
+ | `--all` | Auto-paginate all results. Exhausts the pages, not the statement's `LIMIT` — pair it with a `LIMIT` in the statement above the expected row count (at most 8,192 — split bigger reads into narrower queries), and a read that still fills its cap is flagged `TRUNCATED_RESULTS` either way |
351
351
  | `--out` | Write data to file (format from extension: .csv, .jsonl, .json) |
352
352
  | `--append` | Append to existing file (skip CSV headers) |
353
353
  | `--output` | Output format: `json` \| `csv` \| `jsonl` \| `md` |
@@ -391,6 +391,8 @@ The CLI rejects or automatically corrects common GAQL mistakes before hitting th
391
391
  | `shopping_performance_view.product_*` | Rewrites to `segments.product_*` | Field renamed |
392
392
  | `campaign.status = 'ACTIVE'` | Rewrites to `= 'ENABLED'` | Enum corrected |
393
393
  | `segments.conversion_action_name` with `metrics.cost_micros` | Rejects; split into separate conversion-action and spend queries | `INCOMPATIBLE_FIELDS` with `fix.action: "split_query"` |
394
+ | `DURING` with a literal Google does not accept (`LAST_90_DAYS`, `LAST_12_MONTHS`, `THIS_YEAR` …) | Rejects before any request; `DURING` takes only `TODAY`, `YESTERDAY`, `LAST_7_DAYS`, `LAST_14_DAYS`, `LAST_30_DAYS`, `LAST_BUSINESS_WEEK`, `THIS_MONTH`, `LAST_MONTH`, `THIS_WEEK_SUN_TODAY`, `THIS_WEEK_MON_TODAY`, `LAST_WEEK_SUN_SAT`, `LAST_WEEK_MON_SUN` | `INVALID_DATE_RANGE`, with `fix.correctedCommand` spelling the same window as `BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'` |
395
+ | `--limit` outside 1–8,192, or a statement `LIMIT` above 8,192 | Rejects before any request — one read returns at most 8,192 rows | `VALIDATION_ERROR` naming the cap and how to split a bigger read; a statement `LIMIT` also gets `fix.correctedCommand` at `LIMIT 8192` |
394
396
  | `FROM ad_group_criterion` without `negative` field | Warns | `"ad_group_criterion returns BOTH positive and negative keywords. Use --preset positive-keywords or negative-keywords."` |
395
397
 
396
398
  Auto-fixed queries proceed normally. Warnings appear in the response:
@@ -3924,8 +3926,9 @@ baker canvas sync-definition src/creatives/<slug>/
3924
3926
  # 3. Inspect a finished run (per-node timing, file list, optional video thumbs)
3925
3927
  baker canvas inspect <run_id>
3926
3928
 
3927
- # 4. Discover what's available (all node types, all models, all compositions)
3928
- baker canvas catalog | jq
3929
+ # 4. Discover what's available: a one-line index of every node, then one node's full schema
3930
+ baker canvas catalog
3931
+ baker canvas catalog --node video_generate
3929
3932
 
3930
3933
  # 5. Safely edit a node's prompt without hand-jq (UTF-8 safe — use --text-file for
3931
3934
  # multi-line / accented copy; the edit is re-validated before it is written back)
@@ -5228,8 +5231,8 @@ The tables above mirror `packages/canvas-contract/src/registry.ts` at the time o
5228
5231
 
5229
5232
  ```bash
5230
5233
  baker canvas catalog | jq '.categories | keys'
5231
- baker canvas catalog | jq '.categories.image_generate[].id'
5232
- baker canvas catalog | jq '.categories.video_generate[]'
5234
+ baker canvas catalog --node image_generate | jq '.entries[0].params'
5235
+ baker canvas catalog --node video_generate | jq '.entries[0].params'
5233
5236
  ```
5234
5237
 
5235
5238
  The validator surfaces unknown models / illegal aspect ratios / out-of-range params / missing required inputs with `did_you_mean` hints **before** the run starts.
@@ -5549,11 +5552,18 @@ Resolves the run dir against `--outputs-dir` (default `./canvas`) or accepts an
5549
5552
 
5550
5553
  #### `baker canvas catalog`
5551
5554
 
5552
- Prints the agent-facing node + composition catalog as JSON Schema. Every node has `id`, `version`, `location`, `category`, `summary`, `inputs`/`params`/`outputs` schemas, `cost_estimate_credits`, `runtime_estimate_seconds`, and (when present) `when_to_use`. Grouped by `category`. The `compositions` array enumerates every `@baker/*` composition with its full `meta.json`.
5555
+ Prints the agent-facing node catalog. By default it is a compact index (a few KB): `categories` (category → node ids) and `nodes` (node id → one line), plus `hints`. Ask for full JSON Schemas by name:
5556
+
5557
+ - `--node <id>[,<id>…]` — those nodes' full entries: `id`, `version`, `location`, `category`, `summary`, `when_to_use`, `inputs`/`params`/`outputs` schemas, `cost_estimate_credits`, `runtime_estimate_seconds`.
5558
+ - `--category <name>` — narrow the index to one category; add `--full` for that category's full entries.
5559
+ - `--full` — every node's full entry (~160 KB).
5560
+
5561
+ An unknown node or category exits 1 with `{ ok: false, error: { code: "NOT_FOUND", fix } }` naming the valid ones.
5553
5562
 
5554
5563
  ```bash
5555
- baker canvas catalog | jq '.categories | keys'
5556
- baker canvas catalog | jq '.compositions[].id'
5564
+ baker canvas catalog
5565
+ baker canvas catalog --node video_generate
5566
+ baker canvas catalog --category audio --full
5557
5567
  ```
5558
5568
 
5559
5569
  ---
@@ -20,9 +20,9 @@ import {
20
20
  shouldEscalate
21
21
  } from "./chunk-2OKSJNLA.js";
22
22
 
23
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
23
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/index.js
24
24
  var require_safe_stable_stringify = __commonJS({
25
- "../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js"(exports, module) {
25
+ "../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/index.js"(exports, module) {
26
26
  "use strict";
27
27
  var { hasOwnProperty } = Object.prototype;
28
28
  var stringify = configure2();
@@ -1114,7 +1114,7 @@ function resolveAdaptFormats(params) {
1114
1114
  return params.formats ?? [];
1115
1115
  }
1116
1116
 
1117
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
1117
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/esm/wrapper.js
1118
1118
  var import__ = __toESM(require_safe_stable_stringify(), 1);
1119
1119
  var configure = import__.default.configure;
1120
1120
  var wrapper_default = import__.default;
@@ -9605,6 +9605,83 @@ function generateCatalog(registry, opts = {}) {
9605
9605
  runtime_estimate_seconds: cost?.seconds_estimate
9606
9606
  };
9607
9607
  }).sort((a, b) => a.id.localeCompare(b.id));
9608
+ return {
9609
+ schema: "baker-canvas-catalog/2",
9610
+ generated_at: opts.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
9611
+ categories: groupIds(entries),
9612
+ entries
9613
+ };
9614
+ }
9615
+ var INDEX_SUMMARY_MAX = 160;
9616
+ var sentences = new Intl.Segmenter("en", { granularity: "sentence" });
9617
+ function oneLine(summary) {
9618
+ const first = sentences.segment(summary)[Symbol.iterator]().next().value?.segment.trim() ?? summary;
9619
+ if (first.length <= INDEX_SUMMARY_MAX) return first;
9620
+ const cut = first.slice(0, INDEX_SUMMARY_MAX);
9621
+ const lastSpace = cut.lastIndexOf(" ");
9622
+ return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\s,;:—-]+$/u, "")}\u2026`;
9623
+ }
9624
+ function listIds(value) {
9625
+ return (value ?? "").split(",").map((id) => id.trim()).filter((id) => id.length > 0);
9626
+ }
9627
+ function catalogView(catalog, opts) {
9628
+ const knownIds = catalog.entries.map((e) => e.id);
9629
+ const knownCategories = Object.keys(catalog.categories);
9630
+ if (opts.category !== void 0 && !catalog.categories[opts.category]) {
9631
+ return {
9632
+ ok: false,
9633
+ error: {
9634
+ code: "NOT_FOUND",
9635
+ message: `No node category "${opts.category}".`,
9636
+ fix: `Pass one of: ${knownCategories.join(", ")}.`
9637
+ }
9638
+ };
9639
+ }
9640
+ const requestedIds = listIds(opts.node);
9641
+ if (opts.node !== void 0 && requestedIds.length === 0) {
9642
+ return {
9643
+ ok: false,
9644
+ error: {
9645
+ code: "VALIDATION_ERROR",
9646
+ message: "--node needs a node id.",
9647
+ fix: "Run `baker canvas catalog` for the ids, then pass one (or several, comma-separated)."
9648
+ }
9649
+ };
9650
+ }
9651
+ const unknownIds = requestedIds.filter((id) => !knownIds.includes(id));
9652
+ if (unknownIds.length > 0) {
9653
+ return {
9654
+ ok: false,
9655
+ error: {
9656
+ code: "NOT_FOUND",
9657
+ message: `No node named ${unknownIds.map((id) => `"${id}"`).join(", ")}.`,
9658
+ fix: `Pass one of: ${knownIds.join(", ")}.`
9659
+ }
9660
+ };
9661
+ }
9662
+ const inCategory = (e) => opts.category === void 0 || e.category === opts.category;
9663
+ const categories = opts.category === void 0 ? catalog.categories : { [opts.category]: catalog.categories[opts.category] ?? [] };
9664
+ if (requestedIds.length > 0) {
9665
+ const entries = catalog.entries.filter((e) => requestedIds.includes(e.id));
9666
+ return { ok: true, schema: catalog.schema, categories: groupIds(entries), entries };
9667
+ }
9668
+ if (opts.full) {
9669
+ return { ok: true, schema: catalog.schema, categories, entries: catalog.entries.filter(inCategory) };
9670
+ }
9671
+ const nodes = {};
9672
+ for (const e of catalog.entries.filter(inCategory)) nodes[e.id] = oneLine(e.summary);
9673
+ return {
9674
+ ok: true,
9675
+ schema: catalog.schema,
9676
+ categories,
9677
+ nodes,
9678
+ hints: [
9679
+ "One node's params, inputs, outputs, models and when to use it: baker canvas catalog --node <id> (comma-separate several).",
9680
+ "Every schema in a category: --category <name> --full. Every node: --full (large; prefer --node)."
9681
+ ]
9682
+ };
9683
+ }
9684
+ function groupIds(entries) {
9608
9685
  const categories = {};
9609
9686
  for (const e of entries) {
9610
9687
  let bucket = categories[e.category];
@@ -9614,12 +9691,7 @@ function generateCatalog(registry, opts = {}) {
9614
9691
  }
9615
9692
  bucket.push(e.id);
9616
9693
  }
9617
- return {
9618
- schema: "baker-canvas-catalog/2",
9619
- generated_at: opts.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
9620
- categories,
9621
- entries
9622
- };
9694
+ return categories;
9623
9695
  }
9624
9696
  function safeCost(def) {
9625
9697
  if (!def.cost) return null;
@@ -9795,6 +9867,7 @@ export {
9795
9867
  durationSeconds,
9796
9868
  canonicalUrl,
9797
9869
  toModelSafeImage,
9870
+ catalogView,
9798
9871
  BackendClient2,
9799
9872
  Engine2 as Engine,
9800
9873
  LocalAssetStore2 as LocalAssetStore,
@@ -9805,4 +9878,4 @@ export {
9805
9878
  defaultRegistry,
9806
9879
  createEngineFromEnv
9807
9880
  };
9808
- //# sourceMappingURL=chunk-YBD3W4M7.js.map
9881
+ //# sourceMappingURL=chunk-4QG7SF4U.js.map