@koda-sl/baker-cli 0.449.0 → 0.450.0-dev.d6701597d

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.
Files changed (158) hide show
  1. package/README.md +8 -0
  2. package/dist/{account-F6MHQ64I.js → account-4H7QVBRK.js} +3 -3
  3. package/dist/{account-writes-ISE4U2FQ.js → account-writes-AK42HGRM.js} +3 -3
  4. package/dist/{ad-group-writes-UU5NNKSO.js → ad-group-writes-QQS4223F.js} +3 -3
  5. package/dist/{ad-groups-CGFXZNIA.js → ad-groups-WGPDPUI2.js} +7 -7
  6. package/dist/{ad-writes-NALDYWOR.js → ad-writes-XE2IE4DS.js} +3 -3
  7. package/dist/{ads-C47NA2HH.js → ads-73PGA4YC.js} +2 -2
  8. package/dist/{ads-PV7GZXPR.js → ads-BCOSQALY.js} +8 -8
  9. package/dist/{animate-FWWHSYPL.js → animate-AIZ3GS4J.js} +4 -4
  10. package/dist/{audiences-VEKGLWBG.js → audiences-TGD5US2M.js} +3 -3
  11. package/dist/{brief-UO52ZHFI.js → brief-YFJHQ5VQ.js} +5 -5
  12. package/dist/{campaign-writes-SX52CJYW.js → campaign-writes-SXLZFYF6.js} +3 -3
  13. package/dist/{campaigns-X3DPCCSN.js → campaigns-YS3OGQXO.js} +7 -7
  14. package/dist/{canvas-DPCBGW7K.js → canvas-5NB27FX2.js} +13 -13
  15. package/dist/{catalog-ME44ZRZF.js → catalog-VSSY6FGI.js} +6 -6
  16. package/dist/{catalogs-G3YEVG6S.js → catalogs-BRXEDE56.js} +3 -3
  17. package/dist/{chatgpt-QNUN63YS.js → chatgpt-7W75X3ER.js} +13 -13
  18. package/dist/{chunk-K7FZXIOZ.js → chunk-464O4MT2.js} +2 -2
  19. package/dist/{chunk-647RO73Q.js → chunk-6NB47MRW.js} +3 -3
  20. package/dist/{chunk-35XWJEWH.js → chunk-7J6EHOH6.js} +2 -2
  21. package/dist/{chunk-CHSNHVYF.js → chunk-CAMX6OHF.js} +4 -4
  22. package/dist/chunk-CAMX6OHF.js.map +1 -0
  23. package/dist/{chunk-GBMP4F45.js → chunk-CMPEUZOR.js} +19 -13
  24. package/dist/{chunk-GBMP4F45.js.map → chunk-CMPEUZOR.js.map} +1 -1
  25. package/dist/{chunk-HBTF25YG.js → chunk-DGUNI37S.js} +2 -2
  26. package/dist/{chunk-54UVGFX3.js → chunk-EAP4O4FE.js} +4 -4
  27. package/dist/{chunk-K66OLA6Y.js → chunk-EBWBG6YV.js} +54 -27
  28. package/dist/chunk-EBWBG6YV.js.map +1 -0
  29. package/dist/{chunk-KLBTXETO.js → chunk-FTWJFDIN.js} +169 -169
  30. package/dist/chunk-FTWJFDIN.js.map +1 -0
  31. package/dist/{chunk-KQTYTCKQ.js → chunk-HZUDRKGR.js} +2 -2
  32. package/dist/{chunk-5Y5UAJWD.js → chunk-KAUOHQTF.js} +2 -2
  33. package/dist/{chunk-TT5R35PJ.js → chunk-LECGCWT5.js} +6 -6
  34. package/dist/{chunk-KFE3S63W.js → chunk-NCWCZY5P.js} +3 -3
  35. package/dist/{chunk-7ZHMGXE2.js → chunk-NJXNU2G6.js} +3 -3
  36. package/dist/{chunk-GLCPTMPG.js → chunk-OQ6663F4.js} +5 -5
  37. package/dist/{chunk-HQSCJYZO.js → chunk-P5T7OZKV.js} +2 -2
  38. package/dist/{chunk-VB6WJJR3.js → chunk-PZXCWSKV.js} +2 -2
  39. package/dist/{chunk-J5IY3GVE.js → chunk-Q2V6E6SL.js} +4 -4
  40. package/dist/{chunk-2QHODRR6.js → chunk-RZBEK2VE.js} +2 -2
  41. package/dist/{chunk-IBURXTL4.js → chunk-S3A3YOKO.js} +6 -6
  42. package/dist/{chunk-LYBXCXJB.js → chunk-VNUNE5AB.js} +2 -2
  43. package/dist/{chunk-ULJ5RFOV.js → chunk-XFGAUP5B.js} +2 -2
  44. package/dist/{chunk-FD27ZDVP.js → chunk-Y6ZQXUZ7.js} +3 -3
  45. package/dist/{chunk-Z2EOC6PL.js → chunk-YUCLMOEG.js} +5 -5
  46. package/dist/chunk-YUCLMOEG.js.map +1 -0
  47. package/dist/cli.js +7 -7
  48. package/dist/{conversion-report-N4HANYOB.js → conversion-report-XQBJ6LG4.js} +2 -2
  49. package/dist/{conversion-writes-LW4HQKK5.js → conversion-writes-UBCVXP2E.js} +3 -3
  50. package/dist/{conversions-TS723AZV.js → conversions-D236RTUK.js} +5 -5
  51. package/dist/{creatives-SJTJU6VT.js → creatives-B5NTXPUB.js} +7 -7
  52. package/dist/{credentials-VOZTILFO.js → credentials-C33K6XCJ.js} +14 -14
  53. package/dist/credentials-C33K6XCJ.js.map +1 -0
  54. package/dist/{critique-65W63MFZ.js → critique-4V5SKH7C.js} +6 -6
  55. package/dist/{customers-4AWBFDUF.js → customers-A36LOZOB.js} +3 -3
  56. package/dist/{draft-THPZFASM.js → draft-MNFJ4G3C.js} +3 -3
  57. package/dist/engine/index.js +5 -5
  58. package/dist/{feedback-XNJQ63DS.js → feedback-OLTCHE6C.js} +2 -2
  59. package/dist/{feedback-record-FDLMWMDG.js → feedback-record-7WZ4H7EP.js} +8 -8
  60. package/dist/{fit-7237F5EB.js → fit-UOFYFJ4Q.js} +5 -5
  61. package/dist/{generate-MMBYB44G.js → generate-3XYYITU6.js} +3 -3
  62. package/dist/{history-DBIEYQHY.js → history-Q3QCT64S.js} +3 -3
  63. package/dist/{insights-ZIU6FJMS.js → insights-LNAXV2CG.js} +2 -2
  64. package/dist/{learn-3VO6DXUX.js → learn-FUQSY7DN.js} +4 -4
  65. package/dist/{locations-74TPQWAT.js → locations-2NKBJKBT.js} +2 -2
  66. package/dist/{make-LCNP76OF.js → make-BMWRKIIY.js} +16 -13
  67. package/dist/{make-LCNP76OF.js.map → make-BMWRKIIY.js.map} +1 -1
  68. package/dist/{models-7U3GRYHF.js → models-3Z6MDHQW.js} +2 -2
  69. package/dist/{pixels-45A55MOP.js → pixels-TZPF746S.js} +3 -3
  70. package/dist/{rerun-CET74VPF.js → rerun-6XZG7BGK.js} +14 -14
  71. package/dist/{research-EY7C7JJY.js → research-2BLEISBG.js} +2 -2
  72. package/dist/{run-XQ7EM3JT.js → run-MMEDKJDB.js} +14 -14
  73. package/dist/{scaffold-ad-U2KSHKBC.js → scaffold-ad-PBTEWDAC.js} +12 -12
  74. package/dist/{scaffold-static-ad-63LQKUSO.js → scaffold-static-ad-RM4M4X5U.js} +21 -21
  75. package/dist/scaffold-static-ad-RM4M4X5U.js.map +1 -0
  76. package/dist/{scaffold-video-MUS6LHJQ.js → scaffold-video-O2TTKZIE.js} +11 -11
  77. package/dist/{select-4Z7BW5RH.js → select-OEUKOVZ5.js} +8 -8
  78. package/dist/{set-prompt-OB2V3XJP.js → set-prompt-5E5I7QAZ.js} +7 -7
  79. package/dist/{stale-DAYXOY3Z.js → stale-IGFUKEN2.js} +7 -7
  80. package/dist/{studio-C5K3YX3P.js → studio-RA7QQH4O.js} +4 -4
  81. package/dist/{sync-definition-ILS2B2BJ.js → sync-definition-UGSDX2SZ.js} +10 -10
  82. package/dist/{translate-TA5KQIU7.js → translate-VP5R67PL.js} +11 -11
  83. package/dist/{validate-LDBAAXQO.js → validate-CSJM7XZM.js} +8 -8
  84. package/dist/{viewer-check-45T2HLAH.js → viewer-check-L4B4LIAX.js} +4 -4
  85. package/dist/{winning-ads-ASH5DSV3.js → winning-ads-2WS7FI4E.js} +2 -2
  86. package/package.json +1 -1
  87. package/dist/chunk-CHSNHVYF.js.map +0 -1
  88. package/dist/chunk-K66OLA6Y.js.map +0 -1
  89. package/dist/chunk-KLBTXETO.js.map +0 -1
  90. package/dist/chunk-Z2EOC6PL.js.map +0 -1
  91. package/dist/credentials-VOZTILFO.js.map +0 -1
  92. package/dist/scaffold-static-ad-63LQKUSO.js.map +0 -1
  93. /package/dist/{account-F6MHQ64I.js.map → account-4H7QVBRK.js.map} +0 -0
  94. /package/dist/{account-writes-ISE4U2FQ.js.map → account-writes-AK42HGRM.js.map} +0 -0
  95. /package/dist/{ad-group-writes-UU5NNKSO.js.map → ad-group-writes-QQS4223F.js.map} +0 -0
  96. /package/dist/{ad-groups-CGFXZNIA.js.map → ad-groups-WGPDPUI2.js.map} +0 -0
  97. /package/dist/{ad-writes-NALDYWOR.js.map → ad-writes-XE2IE4DS.js.map} +0 -0
  98. /package/dist/{ads-C47NA2HH.js.map → ads-73PGA4YC.js.map} +0 -0
  99. /package/dist/{ads-PV7GZXPR.js.map → ads-BCOSQALY.js.map} +0 -0
  100. /package/dist/{animate-FWWHSYPL.js.map → animate-AIZ3GS4J.js.map} +0 -0
  101. /package/dist/{audiences-VEKGLWBG.js.map → audiences-TGD5US2M.js.map} +0 -0
  102. /package/dist/{brief-UO52ZHFI.js.map → brief-YFJHQ5VQ.js.map} +0 -0
  103. /package/dist/{campaign-writes-SX52CJYW.js.map → campaign-writes-SXLZFYF6.js.map} +0 -0
  104. /package/dist/{campaigns-X3DPCCSN.js.map → campaigns-YS3OGQXO.js.map} +0 -0
  105. /package/dist/{canvas-DPCBGW7K.js.map → canvas-5NB27FX2.js.map} +0 -0
  106. /package/dist/{catalog-ME44ZRZF.js.map → catalog-VSSY6FGI.js.map} +0 -0
  107. /package/dist/{catalogs-G3YEVG6S.js.map → catalogs-BRXEDE56.js.map} +0 -0
  108. /package/dist/{chatgpt-QNUN63YS.js.map → chatgpt-7W75X3ER.js.map} +0 -0
  109. /package/dist/{chunk-K7FZXIOZ.js.map → chunk-464O4MT2.js.map} +0 -0
  110. /package/dist/{chunk-647RO73Q.js.map → chunk-6NB47MRW.js.map} +0 -0
  111. /package/dist/{chunk-35XWJEWH.js.map → chunk-7J6EHOH6.js.map} +0 -0
  112. /package/dist/{chunk-HBTF25YG.js.map → chunk-DGUNI37S.js.map} +0 -0
  113. /package/dist/{chunk-54UVGFX3.js.map → chunk-EAP4O4FE.js.map} +0 -0
  114. /package/dist/{chunk-KQTYTCKQ.js.map → chunk-HZUDRKGR.js.map} +0 -0
  115. /package/dist/{chunk-5Y5UAJWD.js.map → chunk-KAUOHQTF.js.map} +0 -0
  116. /package/dist/{chunk-TT5R35PJ.js.map → chunk-LECGCWT5.js.map} +0 -0
  117. /package/dist/{chunk-KFE3S63W.js.map → chunk-NCWCZY5P.js.map} +0 -0
  118. /package/dist/{chunk-7ZHMGXE2.js.map → chunk-NJXNU2G6.js.map} +0 -0
  119. /package/dist/{chunk-GLCPTMPG.js.map → chunk-OQ6663F4.js.map} +0 -0
  120. /package/dist/{chunk-HQSCJYZO.js.map → chunk-P5T7OZKV.js.map} +0 -0
  121. /package/dist/{chunk-VB6WJJR3.js.map → chunk-PZXCWSKV.js.map} +0 -0
  122. /package/dist/{chunk-J5IY3GVE.js.map → chunk-Q2V6E6SL.js.map} +0 -0
  123. /package/dist/{chunk-2QHODRR6.js.map → chunk-RZBEK2VE.js.map} +0 -0
  124. /package/dist/{chunk-IBURXTL4.js.map → chunk-S3A3YOKO.js.map} +0 -0
  125. /package/dist/{chunk-LYBXCXJB.js.map → chunk-VNUNE5AB.js.map} +0 -0
  126. /package/dist/{chunk-ULJ5RFOV.js.map → chunk-XFGAUP5B.js.map} +0 -0
  127. /package/dist/{chunk-FD27ZDVP.js.map → chunk-Y6ZQXUZ7.js.map} +0 -0
  128. /package/dist/{conversion-report-N4HANYOB.js.map → conversion-report-XQBJ6LG4.js.map} +0 -0
  129. /package/dist/{conversion-writes-LW4HQKK5.js.map → conversion-writes-UBCVXP2E.js.map} +0 -0
  130. /package/dist/{conversions-TS723AZV.js.map → conversions-D236RTUK.js.map} +0 -0
  131. /package/dist/{creatives-SJTJU6VT.js.map → creatives-B5NTXPUB.js.map} +0 -0
  132. /package/dist/{critique-65W63MFZ.js.map → critique-4V5SKH7C.js.map} +0 -0
  133. /package/dist/{customers-4AWBFDUF.js.map → customers-A36LOZOB.js.map} +0 -0
  134. /package/dist/{draft-THPZFASM.js.map → draft-MNFJ4G3C.js.map} +0 -0
  135. /package/dist/{feedback-XNJQ63DS.js.map → feedback-OLTCHE6C.js.map} +0 -0
  136. /package/dist/{feedback-record-FDLMWMDG.js.map → feedback-record-7WZ4H7EP.js.map} +0 -0
  137. /package/dist/{fit-7237F5EB.js.map → fit-UOFYFJ4Q.js.map} +0 -0
  138. /package/dist/{generate-MMBYB44G.js.map → generate-3XYYITU6.js.map} +0 -0
  139. /package/dist/{history-DBIEYQHY.js.map → history-Q3QCT64S.js.map} +0 -0
  140. /package/dist/{insights-ZIU6FJMS.js.map → insights-LNAXV2CG.js.map} +0 -0
  141. /package/dist/{learn-3VO6DXUX.js.map → learn-FUQSY7DN.js.map} +0 -0
  142. /package/dist/{locations-74TPQWAT.js.map → locations-2NKBJKBT.js.map} +0 -0
  143. /package/dist/{models-7U3GRYHF.js.map → models-3Z6MDHQW.js.map} +0 -0
  144. /package/dist/{pixels-45A55MOP.js.map → pixels-TZPF746S.js.map} +0 -0
  145. /package/dist/{rerun-CET74VPF.js.map → rerun-6XZG7BGK.js.map} +0 -0
  146. /package/dist/{research-EY7C7JJY.js.map → research-2BLEISBG.js.map} +0 -0
  147. /package/dist/{run-XQ7EM3JT.js.map → run-MMEDKJDB.js.map} +0 -0
  148. /package/dist/{scaffold-ad-U2KSHKBC.js.map → scaffold-ad-PBTEWDAC.js.map} +0 -0
  149. /package/dist/{scaffold-video-MUS6LHJQ.js.map → scaffold-video-O2TTKZIE.js.map} +0 -0
  150. /package/dist/{select-4Z7BW5RH.js.map → select-OEUKOVZ5.js.map} +0 -0
  151. /package/dist/{set-prompt-OB2V3XJP.js.map → set-prompt-5E5I7QAZ.js.map} +0 -0
  152. /package/dist/{stale-DAYXOY3Z.js.map → stale-IGFUKEN2.js.map} +0 -0
  153. /package/dist/{studio-C5K3YX3P.js.map → studio-RA7QQH4O.js.map} +0 -0
  154. /package/dist/{sync-definition-ILS2B2BJ.js.map → sync-definition-UGSDX2SZ.js.map} +0 -0
  155. /package/dist/{translate-TA5KQIU7.js.map → translate-VP5R67PL.js.map} +0 -0
  156. /package/dist/{validate-LDBAAXQO.js.map → validate-CSJM7XZM.js.map} +0 -0
  157. /package/dist/{viewer-check-45T2HLAH.js.map → viewer-check-L4B4LIAX.js.map} +0 -0
  158. /package/dist/{winning-ads-ASH5DSV3.js.map → winning-ads-2WS7FI4E.js.map} +0 -0
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-DZSIUEGH.js";
11
11
  import {
12
12
  CUSTOMER_INSIGHTS_MODEL
13
- } from "./chunk-CHSNHVYF.js";
13
+ } from "./chunk-CAMX6OHF.js";
14
14
  import {
15
15
  askAboutText
16
16
  } from "./chunk-RX6F3GEA.js";
@@ -589,4 +589,4 @@ export {
589
589
  researchCustomers,
590
590
  customersCommand
591
591
  };
592
- //# sourceMappingURL=chunk-HBTF25YG.js.map
592
+ //# sourceMappingURL=chunk-DGUNI37S.js.map
@@ -6,13 +6,13 @@ import {
6
6
  } from "./chunk-DZSIUEGH.js";
7
7
  import {
8
8
  bytesOf
9
- } from "./chunk-KFE3S63W.js";
9
+ } from "./chunk-NCWCZY5P.js";
10
10
  import {
11
11
  CONCEPT_CARRY_LEVELS
12
- } from "./chunk-VB6WJJR3.js";
12
+ } from "./chunk-PZXCWSKV.js";
13
13
  import {
14
14
  AD_DESCRIBE_MODEL
15
- } from "./chunk-CHSNHVYF.js";
15
+ } from "./chunk-CAMX6OHF.js";
16
16
  import {
17
17
  askAboutImages
18
18
  } from "./chunk-RX6F3GEA.js";
@@ -437,4 +437,4 @@ export {
437
437
  fitReference,
438
438
  fitCommand
439
439
  };
440
- //# sourceMappingURL=chunk-54UVGFX3.js.map
440
+ //# sourceMappingURL=chunk-EAP4O4FE.js.map
@@ -7,7 +7,7 @@ import {
7
7
  safeRectPx,
8
8
  staticSafeArea,
9
9
  textMismatch
10
- } from "./chunk-KFE3S63W.js";
10
+ } from "./chunk-NCWCZY5P.js";
11
11
  import {
12
12
  HAND_LETTERED,
13
13
  conceptSummary,
@@ -15,7 +15,7 @@ import {
15
15
  readAdSpec,
16
16
  seesReferenceStructure,
17
17
  withRenderedLettering
18
- } from "./chunk-VB6WJJR3.js";
18
+ } from "./chunk-PZXCWSKV.js";
19
19
  import {
20
20
  AD_IMAGE_MODEL,
21
21
  MODEL_REGISTRY,
@@ -28,7 +28,7 @@ import {
28
28
  supportsParam,
29
29
  validateModelInputs,
30
30
  validateModelParams
31
- } from "./chunk-CHSNHVYF.js";
31
+ } from "./chunk-CAMX6OHF.js";
32
32
  import {
33
33
  askAboutImages
34
34
  } from "./chunk-RX6F3GEA.js";
@@ -251,11 +251,12 @@ function logoInstruction(p, ctx) {
251
251
  const plate = ctx.plates.length > 0 ? ctx.plates.map((u) => `${u.name} (${u.hex})`).join(" or ") : "white or black";
252
252
  const where = `at least a fifth of the frame wide, on an area it contrasts with or a small ${plate} plate`;
253
253
  if (ctx.short)
254
- return "the brand's real logo. Reproduce it once, exactly as drawn, at least a fifth of the frame wide.";
254
+ return "the brand's real logo. Reproduce it once, apart from the product, exactly as drawn, at least a fifth of the frame wide.";
255
255
  return ctx.flowing ? `the brand's real logo. Reproduce it once, apart from the product${at}, exactly as drawn in Image ${p.index}, ${where}.` : `the brand's real logo. Reproduce it once, never on the product${at}, exactly as drawn, ${where}.`;
256
256
  }
257
- function identityInstruction(p, what, keep, flowing) {
257
+ function identityInstruction(p, what, keep, flowing, short) {
258
258
  if (p.spec && personOrAnimal(p.spec) === "person") {
259
+ if (short) return `${what} Same face, hair, skin tone and build; one person, once.${keep}`;
259
260
  return flowing ? `${what} Keep their facial features, hair, skin tone and build exactly the same as in Image ${p.index}, and show them once; several views in that picture are all this one person.${keep}` : `${what} Keep this exact face, hair, skin tone and build, and show them once; several views in the picture are all this one person.${keep}`;
260
261
  }
261
262
  return flowing ? `${what} Keep its face, markings and colours exactly the same as in Image ${p.index}, and show it once; several views in that picture are all this one animal.${keep}` : `${what} Keep its exact face, markings and colours, and show it once; several views in the picture are all this one animal.${keep}`;
@@ -271,9 +272,9 @@ function pictureInstruction(p, ctx) {
271
272
  const keep = p.spec?.keep ? ` Keep ${plain(p.spec.keep, ctx.clean)}.` : "";
272
273
  switch (p.role) {
273
274
  case "base":
274
- return ctx.job === "fix" ? "the current version of this ad, to edit." : ctx.job === "series" ? "the finished ad this series repeats, to copy exactly with new words." : "the finished ad, to re-lay for this shape.";
275
+ return "screen content takes priority over other references unless explicitly changed.";
275
276
  case "identity":
276
- return identityInstruction(p, what, keep, ctx.flowing);
277
+ return identityInstruction(p, what, keep, ctx.flowing, ctx.short);
277
278
  // The user saw one label come back two ways (E4 gallery, BENCH.md § "E1 v2"): the label is the product's.
278
279
  case "product":
279
280
  return ctx.flowing ? `${what} Keep it and its label, text and design, exactly as in Image ${p.index}.${keep}` : `${what} Reproduce this exact product and its label, text and design unchanged.${keep}`;
@@ -655,7 +656,8 @@ function deliverableSection(c) {
655
656
  return c.flowing ? `Image 1 is a finished ad of this series. Make the next ad of the same series${forBrand}: ${change} Keep everything else in Image 1 exactly the same, preserving its picture, layout, background, shapes, colours, lettering style and logo, each word in the place and style of the one it replaces.` : `Edit: Image 1 is a finished ad of this series. Make the next ad of the same series${forBrand}. ${capitalize(change)} Keep everything else exactly as it is in Image 1: the picture, the layout, the background, the shapes, the colours, the lettering style and the logo, each new line in the place, size and style of the line it replaces.`;
656
657
  }
657
658
  if (c.job === "relay") {
658
- return c.flowing ? `Image 1 is a finished ad. Recompose this same ad as a ${noun}${forBrand}: the same picture, colours, lettering and every word, rearranged for the new shape, with more of the scene revealed at the edges.` : `Deliverable: the same ad as Image 1, re-laid as a finished ${noun}${forBrand}. Keep the same picture, colours, lettering and every word, rearranged for the new shape; show more of the scene rather than cropping it.`;
659
+ const ui = "Keep any depicted app interface exact, with marketing overlays visibly separate from its native controls.";
660
+ return c.flowing ? `Image 1 is a finished ad. Adapt this same ad to a ${noun}${forBrand}: move and scale its existing elements, keeping its picture, background, colours, lettering and every word. Extend only its existing background where needed. ${ui}` : `Deliverable: the same ad as Image 1, re-laid as a finished ${noun}${forBrand}. Move and scale its existing elements; keep its picture, background, colours, lettering and every word. Extend only its existing background where needed. ${ui}`;
659
661
  }
660
662
  const lead = c.flowing ? "Create a finished" : "Deliverable: a finished";
661
663
  return `${lead} ${noun}${forBrand}${audienceText(c.viewer, c.level, c.clean)}.${marketText(c)}${recognitionText(c)}${ideaText(c.spec, c.level, c.clean)}${conceptText(c)}${deviceText(c)}`;
@@ -697,10 +699,11 @@ function conceptText(c) {
697
699
  const layers = [w.disguise, w.voice, w.trigger, w.attention, w.logic].flatMap(
698
700
  (t) => t?.trim() ? [plain(t, c.clean)] : []
699
701
  );
700
- const idea = layers.length > 0 && c.level < LAST_RESORT_LEVEL ? sentence(layers.join("; ")) : "";
702
+ const continuing = c.job !== "generate";
703
+ const idea = layers.length > 0 && (continuing || c.level < LAST_RESORT_LEVEL) ? sentence(layers.join("; ")) : "";
701
704
  const keep = mustKeep(c);
702
705
  const keepLine = keep.length > 0 ? sentence(keep.join("; ")) : "";
703
- const carry = kept.carry && c.level < LAST_RESORT_LEVEL ? CARRIED[kept.carry] : "";
706
+ const carry = kept.carry && (continuing || c.level < LAST_RESORT_LEVEL) ? CARRIED[kept.carry] : "";
704
707
  const parts = [
705
708
  carry,
706
709
  idea ? `The idea: ${idea}` : "",
@@ -710,6 +713,12 @@ function conceptText(c) {
710
713
  return parts.flatMap((part) => part ? [`${separator}${part}`] : []).join("");
711
714
  }
712
715
  function deviceText(c) {
716
+ if (c.job !== "generate") {
717
+ const mechanisms = c.spec.mechanism.map(
718
+ (m) => [plain(m.device, c.clean), m.why_it_works ? plain(m.why_it_works, c.clean) : ""].filter(Boolean).join(": ")
719
+ );
720
+ return mechanisms.length > 0 ? `Keep the persuasion mechanism: ${sentence(mechanisms.join("; "))}` : "";
721
+ }
713
722
  const device = c.spec.mechanism[0]?.device;
714
723
  if (!device || c.level >= 1) return "";
715
724
  const text = plain(device, c.clean);
@@ -818,12 +827,22 @@ var SCREENS = {
818
827
  var SCREENSHOT = /\b(screenshots?|screen ?grabs?|screens?)\b/i;
819
828
  var screenshotOf = (pics) => pics.find((p) => p.spec && p.role !== "identity" && SCREENSHOT.test(p.spec.what));
820
829
  function screensText(c) {
830
+ const laptop = /\b(laptops?|notebook computers?|macbooks?)\b/i.test(c.spec.scene.description);
831
+ const device = laptop ? "laptop" : "phone";
821
832
  const shot = screenshotOf(c.pics);
822
833
  if (shot) {
823
- return c.flowing ? ` Every screen shows Image ${shot.index} exactly as it is, on a real phone, photographed.` : `
824
- Screens: every screen shows Image ${shot.index} exactly as it is, on a real phone, photographed.`;
834
+ return c.flowing ? ` Every screen shows Image ${shot.index} exactly as it is, on a real ${device}, photographed.` : `
835
+ Screens: every screen shows Image ${shot.index} exactly as it is, on a real ${device}, photographed.`;
836
+ }
837
+ if (!showsScreen(c.spec)) return "";
838
+ if (c.level >= EXTRAS_SHORT_LEVEL)
839
+ return c.flowing ? ` Every ${device} or app screen looks like a real ${device} photographed or a real screenshot.` : `
840
+ Screens: a real ${device} photographed, or a real screenshot.`;
841
+ if (laptop) {
842
+ const screen = "a real laptop photographed, or a real screenshot; display, keyboard and hinge in consistent perspective; any words on it from the quoted lines.";
843
+ return c.flowing ? ` Every laptop screen looks like ${screen}` : `
844
+ Screens: ${screen}`;
825
845
  }
826
- if (!showsScreen(c.spec) || c.level >= EXTRAS_SHORT_LEVEL) return "";
827
846
  return c.flowing ? ` ${SCREENS.flowing}` : `
828
847
  ${SCREENS.labelled}`;
829
848
  }
@@ -941,8 +960,11 @@ function constraintsSection(c) {
941
960
  ...logo ? [`Image ${logo.index}`] : [],
942
961
  ...thirdPartyNames(c.spec) ? [thirdPartyNames(c.spec)] : []
943
962
  ];
963
+ const repeatedWordLimit = n > 0 && c.level >= LAST_RESORT_LEVEL;
964
+ const wordLimit = n > 0 ? `any words other than the ${n} quoted lines` : "any words or letters";
944
965
  const avoid = [
945
- n > 0 ? `any words other than the ${n} quoted lines` : "any words or letters",
966
+ // At the final trim level the Text section already states the complete word allow-list.
967
+ ...repeatedWordLimit ? [] : [wordLimit],
946
968
  // A Toyota badge appeared on a car-loan ad's SUV (BENCH.md § "Final"): the allow-list covers the scene's things too.
947
969
  // The words and the identity's "show them once" are said above; brief v2 spends the words on the logo and the button.
948
970
  `${logos.length > 0 ? `any logo, badge, icon, seal or sticker other than ${logos.join(" and ")}` : "any logo or wordmark, badge, icon, seal or sticker"}, on vehicles, packaging and clothing too`,
@@ -954,8 +976,14 @@ function constraintsSection(c) {
954
976
  return `Avoid: ${avoid.join("; ")}.`;
955
977
  }
956
978
  function assemble(c) {
979
+ const continuity = c.job !== "generate" ? (conceptText(c) || deviceText(c)).trim() : "";
957
980
  return [
958
981
  deliverableSection(c),
982
+ "Real-world anatomy, devices, scale, perspective and supports stay plausible. Scale proportionally; reflow text; preserve letter shapes.",
983
+ // A continuation needs the original idea as well as the previous picture. Keep this
984
+ // separate: the per-format adapter replaces the deliverable paragraph.
985
+ ...continuity ? [continuity] : [],
986
+ ...c.job === "fix" || c.job === "series" ? ["Keep any depicted app interface exact, with marketing overlays visibly separate from its native controls."] : [],
959
987
  ...picturesSection(c),
960
988
  ...sceneSection(c),
961
989
  textSection(c),
@@ -1208,12 +1236,13 @@ function adaptNoun(plan) {
1208
1236
  function adaptDeliverable(plan, spec, flowing, ground, short) {
1209
1237
  const brand = spec.brand?.name;
1210
1238
  const noun = `${adaptNoun(plan)}${brand ? ` for ${brand}` : ""}`;
1239
+ const background = "Extend only the background at Image 1's outer edges; textures stay on their existing surfaces.";
1211
1240
  if (short && !flowing) {
1212
1241
  const keep = [
1213
1242
  ...showsPeople2(spec) ? ["each person the same face and clothes"] : [],
1214
1243
  ...isBeforeAfter(spec) ? ["the two states as different"] : []
1215
1244
  ];
1216
- return `Deliverable: the ad in Image 1, re-laid out as a finished ${noun}: the same message, words, people, product, logo, colours and typeface, the scene filling the frame edge to edge, never Image 1 shrunk onto a background. Every person, product and line appears whole and once, as in Image 1${keep.length > 0 ? `, ${keep.join(", ")}` : ""}; add nothing new.`;
1245
+ return `Deliverable: adapt Image 1 to a ${noun}. Move and scale existing elements first; reflow the contents for this frame, keeping its words, people, product, logo, colours and typeface. ${background} Keep any depicted app interface exact, with marketing overlays visibly separate from its native controls. Every person, product and line appears whole and once${keep.length > 0 ? `, ${keep.join(", ")}` : ""}; add nothing new; never Image 1 shrunk onto a background.`;
1217
1246
  }
1218
1247
  const cast = [
1219
1248
  SAME_CAST,
@@ -1221,13 +1250,14 @@ function adaptDeliverable(plan, spec, flowing, ground, short) {
1221
1250
  ...isBeforeAfter(spec) ? [SAME_CHANGE] : [],
1222
1251
  ...ground ? [GROUND_ONLY] : []
1223
1252
  ].join(" ");
1224
- return flowing ? `Image 1 is a finished ad. Re-lay out this exact ad as a ${noun}: the same message, words, people, product, logo, colours and typeface in a new layout for this frame, the scene filling it edge to edge rather than Image 1 set on a background as a card, panel or square. ${cast}` : `Deliverable: the ad in Image 1, re-laid out as a finished ${noun}: the same message, words, people, product, logo, colours and typeface in a new layout for this frame, the scene filling it edge to edge, never Image 1 shrunk onto a background or set as a card, panel or square. ${cast}`;
1253
+ const continuity = `Move and scale existing elements first; reflow the contents for this frame instead of pasting a smaller copy on a backdrop. Keep the visual hierarchy. ${background} Keep any depicted app interface exact, with marketing overlays visibly separate from its native controls.`;
1254
+ return flowing ? `Image 1 is a finished ad. Adapt this same ad to a ${noun}, keeping its message, words, people, product, logo, colours and typeface. ${continuity} ${cast}` : `Deliverable: the ad in Image 1, re-laid out as a finished ${noun}, keeping its message, words, people, product, logo, colours and typeface; never Image 1 shrunk onto a background. ${continuity} ${cast}`;
1225
1255
  }
1226
1256
  var SAME_CAST = "Every person, product and line appears whole and once, the same individuals as in Image 1; add no person, animal, product or object that Image 1 does not show.";
1227
1257
  var SAME_PERSON = "Each person is the same person as in Image 1: same face, same hair, same clothes.";
1228
1258
  var SAME_CHANGE = "The two states it compares stay as clearly different as in Image 1.";
1229
1259
  var showsPeople2 = (spec) => spec.references.some((r) => r.id.startsWith("PERSON_")) || spec.scene.look !== "illustration" && PEOPLE.test(`${spec.scene.description} ${spec.scene.layout ?? ""}`);
1230
- var GROUND_ONLY = "Image 1 shows no people and no product, so the room this frame adds carries more of Image 1's own background and the brand's colours, never a new scene.";
1260
+ var GROUND_ONLY = "Image 1 shows no people and no product, so the room this frame adds carries only Image 1's own background and the brand's colours already present there, never a new scene.";
1231
1261
  function wordsOnly(spec) {
1232
1262
  return spec.references.length === 0 && spec.scene.look !== "photo" && !PEOPLE.test(`${spec.scene.description} ${spec.scene.layout ?? ""}`);
1233
1263
  }
@@ -1248,7 +1278,7 @@ function scaleText(plan, spec, flowing, zoned, short) {
1248
1278
  var COVERED_HEADROOM = { top: 0.06, bottom: 0.08, side: 0.02 };
1249
1279
  var NO_HEADROOM = { top: 0, bottom: 0, side: 0 };
1250
1280
  var pct = (share) => `${Math.round(share * 100)}%`;
1251
- function zonesText(plan, flowing, ground, short) {
1281
+ function zonesText(plan, flowing, short) {
1252
1282
  const covered = staticSafeArea(plan.format, plan.placements).placement !== "feed";
1253
1283
  const room = isTall(plan) && covered ? COVERED_HEADROOM : NO_HEADROOM;
1254
1284
  const top = plan.safe.top + room.top;
@@ -1256,14 +1286,14 @@ function zonesText(plan, flowing, ground, short) {
1256
1286
  const side = Math.max(plan.safe.left, plan.safe.right) + room.side;
1257
1287
  const band = `from ${pct(top)} to ${pct(1 - bottom)} of the height, at least ${pct(side)} in from each side`;
1258
1288
  if (short && !flowing) {
1259
- const around = isTall(plan) && covered ? "only the ad's own picture, larger, never a flat colour, a panel or a square" : "only the ad's own picture";
1289
+ const around = "Image 1's existing background treatment, including any intentional flat colour";
1260
1290
  return `Zones: every word, the logo and the button sit ${band}; around them, ${around}.`;
1261
1291
  }
1262
1292
  if (!(isTall(plan) && covered)) {
1263
1293
  return flowing ? `The logo, every line and the button sit ${band}; around them the frame shows only the ad's own picture.` : `Zones: the logo, every line and the button sit ${band}; around them, only the ad's own picture.`;
1264
1294
  }
1265
- const picture = ground ? "Image 1's background with its shapes and graphics enlarged in the brand's colours" : "Image 1's people, product and setting extended";
1266
- return flowing ? `The words' band runs ${band}, holding the logo, every line and the button. Above and below it the app's interface covers the frame, so there it shows only the ad's own picture, larger: ${picture}, edge to edge.` : `Zones: the app's buttons and captions cover the top and the bottom of this frame, hiding any word there. The logo, every line and the button sit in one band, ${band}: the headline starts below the top fifth, and the button ends directly under the last line, never at the bottom edge where a feed ad puts it. Above and below it, where the app's interface covers the frame, only the ad's own picture, larger: ${picture}, never a flat empty colour, a panel or a square on a background.`;
1295
+ const picture = "Image 1's existing background treatment, including any intentional flat colour";
1296
+ return flowing ? `The words' band runs ${band}, holding the logo, every line and the button. Above and below it the placement's interface covers the frame: continue only ${picture}.` : `Zones: the app's buttons and captions cover the top and the bottom of this frame, hiding any word there. The logo, every line and the button sit in one band, ${band}: the headline starts below the top fifth, and the button ends directly under the last line, never at the bottom edge where a feed ad puts it. Above and below it, where the placement's interface covers the frame, continue only ${picture}.`;
1267
1297
  }
1268
1298
  function adaptBrief(spec, profile, opts) {
1269
1299
  const { plan, images } = opts;
@@ -1298,14 +1328,11 @@ function adaptBrief(spec, profile, opts) {
1298
1328
  const first = spec.copy[0] ? quotedCopy(spec.copy[0].text) : void 0;
1299
1329
  const textAt = first ? paragraphs.findIndex((p) => p.includes(first)) : -1;
1300
1330
  if (textAt >= 0) {
1301
- const added = [
1302
- ...zoned ? [zonesText(plan, flowing, ground, short)] : [],
1303
- scaleText(plan, spec, flowing, zoned, short)
1304
- ];
1331
+ const added = [...zoned ? [zonesText(plan, flowing, short)] : [], scaleText(plan, spec, flowing, zoned, short)];
1305
1332
  paragraphs.splice(textAt + 1, 0, ...added);
1306
1333
  } else if (zoned) {
1307
1334
  const layoutAt = paragraphs.findIndex((p) => p.startsWith("Layout:"));
1308
- paragraphs.splice(layoutAt > 0 ? layoutAt : 1, 0, zonesText(plan, flowing, ground, short));
1335
+ paragraphs.splice(layoutAt > 0 ? layoutAt : 1, 0, zonesText(plan, flowing, short));
1309
1336
  }
1310
1337
  return paragraphs.join("\n\n");
1311
1338
  };
@@ -4380,4 +4407,4 @@ export {
4380
4407
  canSpellNumbers,
4381
4408
  spellNumber
4382
4409
  };
4383
- //# sourceMappingURL=chunk-K66OLA6Y.js.map
4410
+ //# sourceMappingURL=chunk-EBWBG6YV.js.map