@koda-sl/baker-cli 0.351.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/dist/cli.js CHANGED
@@ -68,7 +68,7 @@ import {
68
68
  validateCanvasDeep,
69
69
  withoutCastName,
70
70
  ytDlpBlockSignal
71
- } from "./chunk-4HRJQGVW.js";
71
+ } from "./chunk-B7MLH3K6.js";
72
72
  import {
73
73
  csvOrJson,
74
74
  daysAgoIso,
@@ -24817,7 +24817,12 @@ var metaDraftAdvisorySchema = z34.object({
24817
24817
  message: z34.string()
24818
24818
  });
24819
24819
  var metaDraftListResponseSchema = z34.object({
24820
- status: z34.enum(["active", "publishing", "applied", "discarded", "none"]),
24820
+ /**
24821
+ * `applied` means the publish finished with no op failed or skipped — when `mode` is `simulated`
24822
+ * nothing reached Meta. `partial` means the publish finished but at least one op failed or was
24823
+ * skipped — read each op's `result` for which one and why.
24824
+ */
24825
+ status: z34.enum(["active", "publishing", "applied", "partial", "discarded", "none"]),
24821
24826
  mode: metaWriteModeSchema,
24822
24827
  count: z34.number(),
24823
24828
  ops: z34.array(metaDraftOpViewSchema),
@@ -41325,7 +41330,6 @@ import { z as z40 } from "zod";
41325
41330
  var GEN_ASPECT_RATIOS = /* @__PURE__ */ new Set(["1:1", "4:5", "9:16", "16:9", "4:3", "3:4", "2:3", "3:2", "21:9"]);
41326
41331
  var DEFAULT_ASPECT_RATIO = "9:16";
41327
41332
  var SHEET_SUBJECT_TYPE2 = {
41328
- person: "person",
41329
41333
  animal: "character"
41330
41334
  };
41331
41335
  var ACTOR_SHEET_MODEL2 = "google/gemini-3-pro-image-preview";
@@ -41335,7 +41339,8 @@ var ADAPT_IMAGE_SIZE = "2K";
41335
41339
  var ADAPT_GUIDANCE = "Keep the headline, logo, CTA, and hero subject fully visible in every ratio. Reproduce every text string verbatim \u2014 no dropped, added, or altered characters \u2014 and preserve the exact brand-color treatment (e.g. a black\u2192red word pivot), never flattening it.";
41336
41340
  var Blueprint = z40.object({
41337
41341
  meta: z40.object({ estimated_aspect_ratio: z40.string().optional() }).loose().optional(),
41338
- text_content: z40.array(z40.object({ text: z40.string().optional() }).loose()).optional()
41342
+ text_content: z40.array(z40.object({ text: z40.string().optional() }).loose()).optional(),
41343
+ people: z40.array(z40.unknown()).optional()
41339
41344
  }).loose();
41340
41345
  var ElementLocator = z40.object({
41341
41346
  collection: z40.enum(["subjects", "people", "brands_logos"]),
@@ -41391,6 +41396,7 @@ function roleForType2(type) {
41391
41396
  case "product":
41392
41397
  return "the showcased product; keep this exact product identity. Ignore any caption text printed on this reference.";
41393
41398
  case "person":
41399
+ return "the emotional hero \u2014 the brand's cast person: a company Avatar's identity sheet, a multi-view turnaround of ONE person the brand may show. Keep this exact face, hair and build, and render them once in the pose, gaze, wardrobe and expression the blueprint specifies \u2014 never as a grid. Ignore the cell labels printed on the sheet.";
41394
41400
  case "animal":
41395
41401
  return "the emotional hero \u2014 the face/muzzle/eyes the viewer locks onto and exactly where AI artifacts (malformed mouths, teeth, foam, extra fingers) betray a fake. It MUST be grounded in this real reference, never invented from prose. Keep this identity AND the expression the blueprint specifies. Ignore any caption text printed on this reference.";
41396
41402
  default:
@@ -41401,7 +41407,10 @@ function todoPath2(el, label) {
41401
41407
  const desc = el.description ? ` \u2014 ${el.description}` : "";
41402
41408
  const expr = el.expression ? `, with a ${el.expression} expression` : "";
41403
41409
  const t = el.type.toLowerCase();
41404
- const lock = t === "person" || t === "animal" ? " \u2014 REQUIRED: this is the emotional hero; ground it in a real reference (image-library / video-library / Pinterest), do not delete this slot and free-generate" : "";
41410
+ if (t === "person") {
41411
+ return `[TODO: drop the identity sheet of a company Avatar for ${label}${desc}${expr} \u2014 REQUIRED: this is the emotional hero and the render keeps this face, so use \`baker avatars list\` or cast one with \`baker avatars create\`, then put its sheetUrl here; never a found photo of a real person (web search, the source ad), who never agreed to appear in this ad]`;
41412
+ }
41413
+ const lock = t === "animal" ? " \u2014 REQUIRED: this is the emotional hero; ground it in a real reference (image-library / video-library / Pinterest), do not delete this slot and free-generate" : "";
41405
41414
  return `[TODO: drop a real image for ${label} (${el.type})${desc}${expr}${lock} \u2014 replace with a path relative to this canvas file, never an absolute path]`;
41406
41415
  }
41407
41416
  function sheetSubjectDescription(el) {
@@ -41441,6 +41450,9 @@ function textFidelityDirective(blueprint, hasFont) {
41441
41450
  "Keep all type crisp, legible, and large enough to read cleanly; no garbled, warped, or duplicated characters, and no unreadable microtext."
41442
41451
  ].join("\n");
41443
41452
  }
41453
+ function showsPerson(blueprint, elements) {
41454
+ return (blueprint.people?.length ?? 0) > 0 || elements.some((el) => el.type.toLowerCase() === "person");
41455
+ }
41444
41456
  function scaffoldStaticAd(input, elementsInput, opts) {
41445
41457
  const blueprint = Blueprint.parse(input);
41446
41458
  const elements = MainElements.parse(elementsInput);
@@ -41506,15 +41518,18 @@ function scaffoldStaticAd(input, elementsInput, opts) {
41506
41518
  params: { text: specimenText(blueprint), font_size: 72, line_height: 1.2, max_width: 1600 }
41507
41519
  });
41508
41520
  }
41521
+ const originalAsReference = !showsPerson(blueprint, elements);
41509
41522
  const reference = [
41510
41523
  ...elementSlots.map((s) => s.ref),
41511
41524
  ...hasFont ? ["$ref:type_ref.image"] : [],
41512
- "$ref:original.asset"
41525
+ ...originalAsReference ? ["$ref:original.asset"] : []
41513
41526
  ];
41514
41527
  const legend = [
41515
41528
  ...elementSlots.map((s) => `- ${s.label} \u2014 ${roleForType2(s.type)}`),
41516
41529
  ...hasFont ? ["- TYPE SPECIMEN \u2014 render every text string in this exact typeface; ignore its color and layout."] : [],
41517
- "- ORIGINAL \u2014 use ONLY for composition, layout, and proportions. IGNORE its text, its logo, its brand name, and its colors entirely \u2014 they belong to a different brand."
41530
+ ...originalAsReference ? [
41531
+ "- ORIGINAL \u2014 use ONLY for composition, layout, and proportions. IGNORE its text, its logo, its brand name, and its colors entirely \u2014 they belong to a different brand."
41532
+ ] : []
41518
41533
  ].join("\n");
41519
41534
  const exclusionsLast = imageProfileFor(opts.genModel)?.constraintPlacement === "last";
41520
41535
  const exclusionsBlock = "Exclusions: no invented badges, icons, or seals; render exactly the subjects the blueprint names and no others; no competitor branding; no watermark.";
@@ -41578,7 +41593,7 @@ function scaffoldStaticAd(input, elementsInput, opts) {
41578
41593
  schema: "baker-canvas/1",
41579
41594
  metadata: {
41580
41595
  name: "static ad reproduction",
41581
- description: "Scaffolded by `baker canvas scaffold-static-ad`. Edit `prompt.json` (the blueprint generated from the source image) into the ad you want, drop a real asset at each [TODO] ingest path (logo/product/subject/badge + brand font), then `baker canvas run`. The original is wired for composition only."
41596
+ description: "Scaffolded by `baker canvas scaffold-static-ad`. Edit `prompt.json` (the blueprint generated from the source image) into the ad you want, drop a real asset at each [TODO] ingest path (logo/product/subject/badge + brand font), then `baker canvas run`. The original is wired for composition only, and left out of the render when it shows a person, whose face the generator would copy."
41582
41597
  },
41583
41598
  nodes,
41584
41599
  output: fanOut ? { node: "adapt", output: "images" } : { node: "gen", output: "images" }
@@ -42048,7 +42063,7 @@ var scaffoldStaticAdCommand = defineCommand114({
42048
42063
  "skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" },
42049
42064
  "skip-actor-sheets": {
42050
42065
  type: "boolean",
42051
- description: "Ground each person/animal on its lone dropped photo instead of a generated multi-view sheet"
42066
+ description: "Ground each animal hero on its lone dropped photo instead of a generated multi-view sheet (a person hero always grounds on the company Avatar sheet dropped at its slot)"
42052
42067
  }
42053
42068
  },
42054
42069
  async run({ args: args5 }) {
@@ -42189,7 +42204,7 @@ var scaffoldStaticAdCommand = defineCommand114({
42189
42204
  edit_prompt: `Edit ${path21.basename(blueprintPath)} \u2014 it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
42190
42205
  assets_to_supply: report.elements,
42191
42206
  font_slot: report.includes_font ? "Drop a brand font at the [TODO] brandfont path (the describe pass recorded the ad's typefaces under `fonts` in prompt.json \u2014 match those). The font is wired into the render as a TYPE SPECIMEN reference so generated text takes the brand letterforms. Delete the brandfont + type_ref nodes to skip it." : "skipped (--skip-font)",
42192
- actor_sheets: report.actor_sheets.length > 0 ? `Each living hero (${report.actor_sheets.join(", ")}) is fused into a generated multi-view reference sheet (image_reference_sheet) that the render grounds on \u2014 so drop ONE clean photo at that hero's ingest and the sheet builds the consistent turnaround. Pass --skip-actor-sheets to ground on the lone photo instead.` : "none (no person/animal heroes detected, or --skip-actor-sheets)",
42207
+ actor_sheets: report.actor_sheets.length > 0 ? `Each animal hero (${report.actor_sheets.join(", ")}) is fused into a generated multi-view reference sheet (image_reference_sheet) that the render grounds on \u2014 so drop ONE clean photo at that hero's ingest and the sheet builds the consistent turnaround. Pass --skip-actor-sheets to ground on the lone photo instead. A person hero takes a company Avatar's identity sheet at its slot (baker avatars), never a found photo.` : "none (no animal heroes detected, or --skip-actor-sheets). A person hero takes a company Avatar's identity sheet at its slot (baker avatars), never a found photo.",
42193
42208
  placements: report.placements === null ? `Single format (${report.aspect_ratio}). Pass --placements meta_feed_stories|meta_all|linkedin|\u2026 to auto-fan-out to a platform's set.` : `Auto-fans the approved hero out to ${report.placements} \u2192 ${report.output_formats.join(", ")}. The hero ratio (${report.aspect_ratio}) passes through free; each other ratio is a billed render, AI-recomposed (not cropped). Re-read the copy and confirm the brand-color treatment on EVERY ratio before publishing \u2014 adaptation re-generates and can silently mangle text or flatten a color device. Pass --placements none for a single base ad.`,
42194
42209
  note: "Populate as you go: for each [TODO] ingest slot, source its real asset and wire it into the slot right away \u2014 one at a time, not all sourced first then reconciled at the end. For any LOGO slot, use the company's committed brand logo from `src/brand/logos/` (per BRAND.md's Logos map) \u2014 do NOT re-fetch it with `baker images logo <domain>` when a brand logo exists, because the Brandfetch CDN often serves an OUTDATED mark and that is how an old logo ships on a live ad. When every slot is filled, `baker canvas validate` then `baker canvas run`. Running generates a billed image \u2014 it is not free."
42195
42210
  }