@koda-sl/baker-cli 0.350.0 → 0.352.0-dev.09c54d90c

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
@@ -3927,8 +3927,9 @@ baker canvas sync-definition src/creatives/<slug>/
3927
3927
  # 3. Inspect a finished run (per-node timing, file list, optional video thumbs)
3928
3928
  baker canvas inspect <run_id>
3929
3929
 
3930
- # 4. Discover what's available (all node types, all models, all compositions)
3931
- baker canvas catalog | jq
3930
+ # 4. Discover what's available: a one-line index of every node, then one node's full schema
3931
+ baker canvas catalog
3932
+ baker canvas catalog --node video_generate
3932
3933
 
3933
3934
  # 5. Safely edit a node's prompt without hand-jq (UTF-8 safe — use --text-file for
3934
3935
  # multi-line / accented copy; the edit is re-validated before it is written back)
@@ -4068,7 +4069,7 @@ The top-level `output` declares the canvas's final result — the engine returns
4068
4069
 
4069
4070
  Every node shares the envelope `{ id, type, inputs?, params? }`. `inputs` wires other nodes' output slots in; `params` configures the node. The validator enforces required input kinds and per-model param shape **before** anything is billed.
4070
4071
 
4071
- `baker canvas catalog` prints the always-current machine-readable schema for every node and every model. The tables below mirror the catalog at time of write.
4072
+ `baker canvas catalog` prints a one-line index of every node; `baker canvas catalog --node <id>` prints that node's always-current machine-readable schema (params, inputs, outputs, every model), and `--full` prints every node's. The tables below mirror the catalog at time of write.
4072
4073
 
4073
4074
  In every table:
4074
4075
 
@@ -5231,8 +5232,8 @@ The tables above mirror `packages/canvas-contract/src/registry.ts` at the time o
5231
5232
 
5232
5233
  ```bash
5233
5234
  baker canvas catalog | jq '.categories | keys'
5234
- baker canvas catalog | jq '.categories.image_generate[].id'
5235
- baker canvas catalog | jq '.categories.video_generate[]'
5235
+ baker canvas catalog --node image_generate | jq '.entries[0].params'
5236
+ baker canvas catalog --node video_generate | jq '.entries[0].params'
5236
5237
  ```
5237
5238
 
5238
5239
  The validator surfaces unknown models / illegal aspect ratios / out-of-range params / missing required inputs with `did_you_mean` hints **before** the run starts.
@@ -5486,7 +5487,7 @@ Turn a source/inspiration image into a **runnable, self-validated static-ad canv
5486
5487
  2. **element selection** (`~google/gemini-flash-latest`) — picks the **main, identity-critical** elements (the brand logo, a showcased product, a trust badge) **plus any foreground/hero person or animal** — the emotional focal point — even a generic one, because a free-generated face/muzzle reads as AI and grows artifacts; the emotional hero always gets a real-reference slot. When the advertiser's logo appears in **more than one lockup** (a square/icon **mark** and a horizontal **wordmark**), each is emitted as its **own** element (e.g. `LOGO_MARK`, `LOGO_WORDMARK`) so you drop the right file in each slot instead of stretching one logo to cover both. The describe pass also records the ad's **typography** under a `fonts` block (each typeface's classification, a best-guess family, and its weight/case) so you know exactly what to drop at the brand-font slot. Background extras are dropped. Each element is stamped back onto its blueprint entry as a `reference_image` label so the JSON self-documents which slot grounds which subject.
5487
5488
  3. **global layout** (`~google/gemini-flash-latest`) — produces a structured `layout` block in `prompt.json`: the column/row grid, each region's `x_pct`/`y_pct` bounds, panel splits, background/shape, and every text block's relative size/weight/case/alignment. This is what gives the generator a precise composition to rebuild.
5488
5489
 
5489
- It then scaffolds a canvas that ingests `prompt.json`, wires **one `[TODO]` ingest slot per detected element** (plus an optional brand-font → type-specimen) into `image_generate`, and wires the original image in for composition only. Each **person/animal hero** is additionally fused into a generated **multi-view reference sheet** (`image_reference_sheet`, a turnaround built from the one dropped photo) that the render grounds on instead of the lone flat snapshot — the same identity lock the video scaffold uses, so the face/muzzle stays consistent and artifact-free from a single reference. Pass `--skip-actor-sheets` to ground straight on the dropped photo. The canvas is validated before it's written. stdout returns `{ ok, canvas_path, prompt_path, models, aspect_ratio, placements, output_formats, layout_regions, stats, checklist }` — the **checklist** lists every real asset to drop in (and which heroes get a sheet).
5490
+ It then scaffolds a canvas that ingests `prompt.json`, wires **one `[TODO]` ingest slot per detected element** (plus an optional brand-font → type-specimen) into `image_generate`, and wires the original image in for composition only — left out of the render when it shows a person, because the generator copies that face whatever the prompt says (the blueprint's layout carries the composition instead). Each **animal hero** is additionally fused into a generated **multi-view reference sheet** (`image_reference_sheet`, a turnaround built from the one dropped photo) that the render grounds on instead of the lone flat snapshot — the same identity lock the video scaffold uses, so the muzzle stays consistent and artifact-free from a single reference. Pass `--skip-actor-sheets` to ground straight on the dropped photo. A **person hero**'s slot takes a company Avatar's identity sheet (`baker avatars`) and the render keeps that face, so it is never a found photo of a real person. The canvas is validated before it's written. stdout returns `{ ok, canvas_path, prompt_path, models, aspect_ratio, placements, output_formats, layout_regions, stats, checklist }` — the **checklist** lists every real asset to drop in (and which heroes get a sheet).
5490
5491
 
5491
5492
  **Automatic placement fan-out.** By default the canvas doesn't stop at one ratio: the hero renders once at the platform's primary ratio, then an `image_aspect_adapt` node recomposes it into that platform's full placement set, and the canvas `output` points at the adapted images. The placement set is derived from `--platform` (`meta` → 4:5 + 9:16, `google` → 1:1 + 4:5 + 16:9, `linkedin` → 1:1, `tiktok` → 9:16, `youtube` → 16:9); override it with `--placements <preset>` or disable it with `--placements none` for a single base ad. The hero ratio passes through the adapt node **free**; each other ratio is a billed recomposition — and because adaptation re-generates, every ratio should be eyeballed for text and brand-color fidelity before publish (`ad-formats.md` in the scaffold skill covers this).
5492
5493
 
@@ -5515,7 +5516,7 @@ baker canvas run ./static-ad.canvas.json
5515
5516
  | `--placements <preset\|none>` | derived from `--platform` | Override the fan-out set: `meta_feed`\|`meta_feed_stories`\|`meta_all`\|`linkedin`\|`google_demandgen`\|`tiktok`\|`youtube`, or `none` for a single base ad. |
5516
5517
  | `--aspect <ratio>` | inferred from the image, else `9:16` | Force the hero's aspect ratio (clamped into the placement set so it stays a free pass-through). |
5517
5518
  | `--skip-font` | off | Skip the brand-font → type-specimen slot. |
5518
- | `--skip-actor-sheets` | off | Ground each person/animal on its lone dropped photo instead of a generated multi-view reference sheet. |
5519
+ | `--skip-actor-sheets` | off | Ground each animal hero on its lone dropped photo instead of a generated multi-view reference sheet. |
5519
5520
 
5520
5521
  Scaffolding runs (and bills) the two vision passes; **running** the result generates a billed image. `baker canvas validate` does not check that the `[TODO]` paths exist — supply the real files before `run`.
5521
5522
 
@@ -5552,11 +5553,18 @@ Resolves the run dir against `--outputs-dir` (default `./canvas`) or accepts an
5552
5553
 
5553
5554
  #### `baker canvas catalog`
5554
5555
 
5555
- 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`.
5556
+ 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:
5557
+
5558
+ - `--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`.
5559
+ - `--category <name>` — narrow the index to one category; add `--full` for that category's full entries.
5560
+ - `--full` — every node's full entry (~160 KB).
5561
+
5562
+ An unknown node or category exits 1 with `{ ok: false, error: { code: "NOT_FOUND", fix } }` naming the valid ones.
5556
5563
 
5557
5564
  ```bash
5558
- baker canvas catalog | jq '.categories | keys'
5559
- baker canvas catalog | jq '.compositions[].id'
5565
+ baker canvas catalog
5566
+ baker canvas catalog --node video_generate
5567
+ baker canvas catalog --category audio --full
5560
5568
  ```
5561
5569
 
5562
5570
  ---
@@ -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 && !knownCategories.includes(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-B7MLH3K6.js.map