@koda-sl/baker-cli 0.482.0 → 0.483.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.
Files changed (164) hide show
  1. package/README.md +1 -1
  2. package/dist/{animate-3LV3LHXQ.js → animate-SVEPM267.js} +4 -4
  3. package/dist/{brand-CINQG3JG.js → brand-LAIIXZBL.js} +2 -2
  4. package/dist/{brief-WAQ2V6Q4.js → brief-7PICJ4CO.js} +13 -13
  5. package/dist/{canvas-A4XKEBN7.js → canvas-YS3ONCCX.js} +13 -13
  6. package/dist/{catalog-SJBGNNY4.js → catalog-RS4F5YK3.js} +8 -8
  7. package/dist/{check-GCZ2ZBKH.js → check-5RW2MX7V.js} +9 -9
  8. package/dist/{chunk-XSGO44OV.js → chunk-27DJRM3F.js} +4 -4
  9. package/dist/{chunk-WMVTIKET.js → chunk-3PXC2OXT.js} +2 -2
  10. package/dist/{chunk-U2452GLO.js → chunk-4AMIHNNP.js} +11 -6
  11. package/dist/chunk-4AMIHNNP.js.map +1 -0
  12. package/dist/{chunk-5YKC2WWG.js → chunk-4S4WDXJR.js} +6 -6
  13. package/dist/{chunk-GQ6JS5MR.js → chunk-4VB7F422.js} +56 -11
  14. package/dist/{chunk-GQ6JS5MR.js.map → chunk-4VB7F422.js.map} +1 -1
  15. package/dist/{chunk-ELL2IQMF.js → chunk-62JQQUAU.js} +12 -11
  16. package/dist/chunk-62JQQUAU.js.map +1 -0
  17. package/dist/{chunk-2DHHL4PU.js → chunk-66WEOQV5.js} +3 -3
  18. package/dist/{chunk-5RCCESDX.js → chunk-AXDKLXCG.js} +120 -41
  19. package/dist/chunk-AXDKLXCG.js.map +1 -0
  20. package/dist/{chunk-6KK26F2T.js → chunk-BTY4LZBG.js} +2 -2
  21. package/dist/{chunk-Q7YZL7PG.js → chunk-CS5JF52J.js} +2 -2
  22. package/dist/{chunk-5NS4CNF6.js → chunk-E2RFM6R2.js} +5 -5
  23. package/dist/{chunk-BSEB55E6.js → chunk-EOY6BK4C.js} +2 -2
  24. package/dist/{chunk-MMVLRUMK.js → chunk-G2LGMWNG.js} +27 -12
  25. package/dist/chunk-G2LGMWNG.js.map +1 -0
  26. package/dist/{chunk-ZBV5IV5T.js → chunk-IKCP5NCE.js} +2 -2
  27. package/dist/{chunk-RTWRNG3E.js → chunk-IN6AW5P3.js} +18 -8
  28. package/dist/{chunk-RTWRNG3E.js.map → chunk-IN6AW5P3.js.map} +1 -1
  29. package/dist/{chunk-DF22CTXE.js → chunk-IX2QLW6G.js} +2 -2
  30. package/dist/{chunk-65N4ZPQD.js → chunk-JAC6JVCI.js} +2 -2
  31. package/dist/{chunk-V6PXHQSI.js → chunk-JWSEPW7F.js} +2 -2
  32. package/dist/{chunk-AS5VL32C.js → chunk-JYALBYN7.js} +2 -2
  33. package/dist/{chunk-R2TAVQGZ.js → chunk-K2JTERIO.js} +2 -2
  34. package/dist/{chunk-3S5YZWB7.js → chunk-KDWH2JKT.js} +10 -7
  35. package/dist/chunk-KDWH2JKT.js.map +1 -0
  36. package/dist/{chunk-T6ATGN7Y.js → chunk-MCJ5I5LR.js} +1 -1
  37. package/dist/chunk-MCJ5I5LR.js.map +1 -0
  38. package/dist/{chunk-U4W4LULB.js → chunk-MGIOV72F.js} +7 -7
  39. package/dist/{chunk-ORQKMXHA.js → chunk-MZPS46OR.js} +2 -2
  40. package/dist/{chunk-RDCYPWQZ.js → chunk-NEOUY3Q7.js} +34 -9
  41. package/dist/chunk-NEOUY3Q7.js.map +1 -0
  42. package/dist/{chunk-K2Z3KGOH.js → chunk-NPMAATZG.js} +2 -2
  43. package/dist/{chunk-2K3NCVDI.js → chunk-OKJVBGMQ.js} +31 -19
  44. package/dist/{chunk-2K3NCVDI.js.map → chunk-OKJVBGMQ.js.map} +1 -1
  45. package/dist/{chunk-PQTY22FR.js → chunk-PZPSCYN3.js} +9 -8
  46. package/dist/chunk-PZPSCYN3.js.map +1 -0
  47. package/dist/{chunk-KQDAFZKR.js → chunk-Q4WWS3UQ.js} +2 -2
  48. package/dist/{chunk-A2FKWRKO.js → chunk-R3N4AIKS.js} +6 -6
  49. package/dist/{chunk-DCTEL4KG.js → chunk-RVXMK4X2.js} +3 -3
  50. package/dist/{chunk-LD4CHA7U.js → chunk-UKL7GWEH.js} +2 -2
  51. package/dist/{chunk-4VWTIT5C.js → chunk-UWXDNVS5.js} +2 -2
  52. package/dist/{chunk-U6IWRZQF.js → chunk-VNNCYWNN.js} +3 -3
  53. package/dist/{chunk-7U3V64YT.js → chunk-WKLQFSV6.js} +4 -4
  54. package/dist/{chunk-WD5BQBVY.js → chunk-Z5SOZUUB.js} +3 -3
  55. package/dist/{chunk-AQ5WISEG.js → chunk-ZCQVKDHV.js} +2 -2
  56. package/dist/{chunk-RCSOG2DV.js → chunk-ZINMEMOB.js} +5 -5
  57. package/dist/cli.js +7 -7
  58. package/dist/{creatives-U2M4F3D5.js → creatives-NK5HOXSF.js} +10 -10
  59. package/dist/{critique-43OVWKN7.js → critique-EDMP5P5R.js} +16 -16
  60. package/dist/{critique-JVKJEBAC.js → critique-N5OL42C6.js} +5 -5
  61. package/dist/{customers-P4N4NXLJ.js → customers-TLAHWJY6.js} +4 -4
  62. package/dist/engine/index.d.ts +1 -0
  63. package/dist/engine/index.js +7 -7
  64. package/dist/{feedback-3GU3PAEI.js → feedback-OCN3XNKF.js} +19 -19
  65. package/dist/{feedback-record-PIJDOJW3.js → feedback-record-Z66AXZ57.js} +20 -20
  66. package/dist/{fit-TVQ7RK52.js → fit-PMSNW2PF.js} +11 -11
  67. package/dist/{fonts-BMUNDGOZ.js → fonts-I434ILTG.js} +7 -7
  68. package/dist/{generate-4HWNFAH3.js → generate-OMXBFGGR.js} +3 -3
  69. package/dist/{ideas-UTSCGCT6.js → ideas-K6FQVDUA.js} +8 -8
  70. package/dist/{landing-AJO2BPC2.js → landing-EJGYTI5W.js} +2 -2
  71. package/dist/{learn-RGO5KDHS.js → learn-66SKYR36.js} +6 -6
  72. package/dist/{make-IHJROEKG.js → make-ZYEFMAR6.js} +51 -37
  73. package/dist/make-ZYEFMAR6.js.map +1 -0
  74. package/dist/{models-2DQ5NBMT.js → models-2XRYXSRA.js} +2 -2
  75. package/dist/{rerun-R3DNEV5U.js → rerun-DZKHTK66.js} +24 -24
  76. package/dist/{research-MBAPL35Y.js → research-L2DH5P22.js} +2 -2
  77. package/dist/{rules-SZIY67QF.js → rules-TPW37OVS.js} +8 -8
  78. package/dist/{rules-add-KTLHU3YD.js → rules-add-HTL6IFQJ.js} +8 -8
  79. package/dist/{run-QYIUO4NB.js → run-EID2OD4U.js} +24 -24
  80. package/dist/{scaffold-ad-NIVJSO73.js → scaffold-ad-SQZMHTRA.js} +24 -24
  81. package/dist/{scaffold-static-ad-QX2NUXFR.js → scaffold-static-ad-L2JCW5LF.js} +30 -30
  82. package/dist/{scaffold-video-NXBM54K3.js → scaffold-video-2WLFALNV.js} +21 -21
  83. package/dist/{select-Q4S4CPKV.js → select-POYNXE2L.js} +18 -18
  84. package/dist/{set-prompt-3MVZW3L6.js → set-prompt-2OXPI4ZF.js} +17 -17
  85. package/dist/{stale-NT2JRQHY.js → stale-6HL4ELJW.js} +17 -17
  86. package/dist/{studio-YB5WXQYC.js → studio-MARZ22J2.js} +4 -4
  87. package/dist/{sync-definition-6XPX6VJU.js → sync-definition-VVNXDNDC.js} +20 -20
  88. package/dist/{translate-27DIFMBU.js → translate-ACGKNKQP.js} +21 -21
  89. package/dist/{validate-AYPLNS7A.js → validate-SUW24MMI.js} +20 -20
  90. package/dist/{viewer-check-TSH3SAYJ.js → viewer-check-7S2EB32L.js} +10 -10
  91. package/dist/{winning-ads-SGBI3WHK.js → winning-ads-T4MOKDYT.js} +2 -2
  92. package/package.json +1 -1
  93. package/dist/chunk-3S5YZWB7.js.map +0 -1
  94. package/dist/chunk-5RCCESDX.js.map +0 -1
  95. package/dist/chunk-ELL2IQMF.js.map +0 -1
  96. package/dist/chunk-MMVLRUMK.js.map +0 -1
  97. package/dist/chunk-PQTY22FR.js.map +0 -1
  98. package/dist/chunk-RDCYPWQZ.js.map +0 -1
  99. package/dist/chunk-T6ATGN7Y.js.map +0 -1
  100. package/dist/chunk-U2452GLO.js.map +0 -1
  101. package/dist/make-IHJROEKG.js.map +0 -1
  102. /package/dist/{animate-3LV3LHXQ.js.map → animate-SVEPM267.js.map} +0 -0
  103. /package/dist/{brand-CINQG3JG.js.map → brand-LAIIXZBL.js.map} +0 -0
  104. /package/dist/{brief-WAQ2V6Q4.js.map → brief-7PICJ4CO.js.map} +0 -0
  105. /package/dist/{canvas-A4XKEBN7.js.map → canvas-YS3ONCCX.js.map} +0 -0
  106. /package/dist/{catalog-SJBGNNY4.js.map → catalog-RS4F5YK3.js.map} +0 -0
  107. /package/dist/{check-GCZ2ZBKH.js.map → check-5RW2MX7V.js.map} +0 -0
  108. /package/dist/{chunk-XSGO44OV.js.map → chunk-27DJRM3F.js.map} +0 -0
  109. /package/dist/{chunk-WMVTIKET.js.map → chunk-3PXC2OXT.js.map} +0 -0
  110. /package/dist/{chunk-5YKC2WWG.js.map → chunk-4S4WDXJR.js.map} +0 -0
  111. /package/dist/{chunk-2DHHL4PU.js.map → chunk-66WEOQV5.js.map} +0 -0
  112. /package/dist/{chunk-6KK26F2T.js.map → chunk-BTY4LZBG.js.map} +0 -0
  113. /package/dist/{chunk-Q7YZL7PG.js.map → chunk-CS5JF52J.js.map} +0 -0
  114. /package/dist/{chunk-5NS4CNF6.js.map → chunk-E2RFM6R2.js.map} +0 -0
  115. /package/dist/{chunk-BSEB55E6.js.map → chunk-EOY6BK4C.js.map} +0 -0
  116. /package/dist/{chunk-ZBV5IV5T.js.map → chunk-IKCP5NCE.js.map} +0 -0
  117. /package/dist/{chunk-DF22CTXE.js.map → chunk-IX2QLW6G.js.map} +0 -0
  118. /package/dist/{chunk-65N4ZPQD.js.map → chunk-JAC6JVCI.js.map} +0 -0
  119. /package/dist/{chunk-V6PXHQSI.js.map → chunk-JWSEPW7F.js.map} +0 -0
  120. /package/dist/{chunk-AS5VL32C.js.map → chunk-JYALBYN7.js.map} +0 -0
  121. /package/dist/{chunk-R2TAVQGZ.js.map → chunk-K2JTERIO.js.map} +0 -0
  122. /package/dist/{chunk-U4W4LULB.js.map → chunk-MGIOV72F.js.map} +0 -0
  123. /package/dist/{chunk-ORQKMXHA.js.map → chunk-MZPS46OR.js.map} +0 -0
  124. /package/dist/{chunk-K2Z3KGOH.js.map → chunk-NPMAATZG.js.map} +0 -0
  125. /package/dist/{chunk-KQDAFZKR.js.map → chunk-Q4WWS3UQ.js.map} +0 -0
  126. /package/dist/{chunk-A2FKWRKO.js.map → chunk-R3N4AIKS.js.map} +0 -0
  127. /package/dist/{chunk-DCTEL4KG.js.map → chunk-RVXMK4X2.js.map} +0 -0
  128. /package/dist/{chunk-LD4CHA7U.js.map → chunk-UKL7GWEH.js.map} +0 -0
  129. /package/dist/{chunk-4VWTIT5C.js.map → chunk-UWXDNVS5.js.map} +0 -0
  130. /package/dist/{chunk-U6IWRZQF.js.map → chunk-VNNCYWNN.js.map} +0 -0
  131. /package/dist/{chunk-7U3V64YT.js.map → chunk-WKLQFSV6.js.map} +0 -0
  132. /package/dist/{chunk-WD5BQBVY.js.map → chunk-Z5SOZUUB.js.map} +0 -0
  133. /package/dist/{chunk-AQ5WISEG.js.map → chunk-ZCQVKDHV.js.map} +0 -0
  134. /package/dist/{chunk-RCSOG2DV.js.map → chunk-ZINMEMOB.js.map} +0 -0
  135. /package/dist/{creatives-U2M4F3D5.js.map → creatives-NK5HOXSF.js.map} +0 -0
  136. /package/dist/{critique-43OVWKN7.js.map → critique-EDMP5P5R.js.map} +0 -0
  137. /package/dist/{critique-JVKJEBAC.js.map → critique-N5OL42C6.js.map} +0 -0
  138. /package/dist/{customers-P4N4NXLJ.js.map → customers-TLAHWJY6.js.map} +0 -0
  139. /package/dist/{feedback-3GU3PAEI.js.map → feedback-OCN3XNKF.js.map} +0 -0
  140. /package/dist/{feedback-record-PIJDOJW3.js.map → feedback-record-Z66AXZ57.js.map} +0 -0
  141. /package/dist/{fit-TVQ7RK52.js.map → fit-PMSNW2PF.js.map} +0 -0
  142. /package/dist/{fonts-BMUNDGOZ.js.map → fonts-I434ILTG.js.map} +0 -0
  143. /package/dist/{generate-4HWNFAH3.js.map → generate-OMXBFGGR.js.map} +0 -0
  144. /package/dist/{ideas-UTSCGCT6.js.map → ideas-K6FQVDUA.js.map} +0 -0
  145. /package/dist/{landing-AJO2BPC2.js.map → landing-EJGYTI5W.js.map} +0 -0
  146. /package/dist/{learn-RGO5KDHS.js.map → learn-66SKYR36.js.map} +0 -0
  147. /package/dist/{models-2DQ5NBMT.js.map → models-2XRYXSRA.js.map} +0 -0
  148. /package/dist/{rerun-R3DNEV5U.js.map → rerun-DZKHTK66.js.map} +0 -0
  149. /package/dist/{research-MBAPL35Y.js.map → research-L2DH5P22.js.map} +0 -0
  150. /package/dist/{rules-SZIY67QF.js.map → rules-TPW37OVS.js.map} +0 -0
  151. /package/dist/{rules-add-KTLHU3YD.js.map → rules-add-HTL6IFQJ.js.map} +0 -0
  152. /package/dist/{run-QYIUO4NB.js.map → run-EID2OD4U.js.map} +0 -0
  153. /package/dist/{scaffold-ad-NIVJSO73.js.map → scaffold-ad-SQZMHTRA.js.map} +0 -0
  154. /package/dist/{scaffold-static-ad-QX2NUXFR.js.map → scaffold-static-ad-L2JCW5LF.js.map} +0 -0
  155. /package/dist/{scaffold-video-NXBM54K3.js.map → scaffold-video-2WLFALNV.js.map} +0 -0
  156. /package/dist/{select-Q4S4CPKV.js.map → select-POYNXE2L.js.map} +0 -0
  157. /package/dist/{set-prompt-3MVZW3L6.js.map → set-prompt-2OXPI4ZF.js.map} +0 -0
  158. /package/dist/{stale-NT2JRQHY.js.map → stale-6HL4ELJW.js.map} +0 -0
  159. /package/dist/{studio-YB5WXQYC.js.map → studio-MARZ22J2.js.map} +0 -0
  160. /package/dist/{sync-definition-6XPX6VJU.js.map → sync-definition-VVNXDNDC.js.map} +0 -0
  161. /package/dist/{translate-27DIFMBU.js.map → translate-ACGKNKQP.js.map} +0 -0
  162. /package/dist/{validate-AYPLNS7A.js.map → validate-SUW24MMI.js.map} +0 -0
  163. /package/dist/{viewer-check-TSH3SAYJ.js.map → viewer-check-7S2EB32L.js.map} +0 -0
  164. /package/dist/{winning-ads-SGBI3WHK.js.map → winning-ads-T4MOKDYT.js.map} +0 -0
@@ -3,13 +3,13 @@ import {
3
3
  RULE_APPLIES,
4
4
  RULE_KINDS,
5
5
  RULE_STRENGTHS
6
- } from "./chunk-MMVLRUMK.js";
6
+ } from "./chunk-G2LGMWNG.js";
7
7
  import {
8
8
  holdWorkspaceSpend
9
9
  } from "./chunk-5WMTPYKT.js";
10
10
  import {
11
11
  askAboutText
12
- } from "./chunk-ZBV5IV5T.js";
12
+ } from "./chunk-IKCP5NCE.js";
13
13
  import {
14
14
  CREATIVE_FEEDBACK_REASON_LABELS
15
15
  } from "./chunk-FRK7SSEH.js";
@@ -153,4 +153,4 @@ export {
153
153
  repeatedReasons,
154
154
  ruleCandidateHints
155
155
  };
156
- //# sourceMappingURL=chunk-2DHHL4PU.js.map
156
+ //# sourceMappingURL=chunk-66WEOQV5.js.map
@@ -1,30 +1,30 @@
1
1
  import {
2
2
  readInsights
3
- } from "./chunk-BSEB55E6.js";
3
+ } from "./chunk-EOY6BK4C.js";
4
4
  import {
5
5
  heldRules,
6
6
  readAdWords,
7
7
  ruleGate
8
- } from "./chunk-RCSOG2DV.js";
8
+ } from "./chunk-ZINMEMOB.js";
9
9
  import {
10
10
  avatarRelation,
11
11
  castCompany
12
- } from "./chunk-LD4CHA7U.js";
12
+ } from "./chunk-UKL7GWEH.js";
13
13
  import {
14
14
  readAvatars
15
15
  } from "./chunk-LCW3U4EA.js";
16
16
  import {
17
17
  frontmatterOf,
18
18
  sourcesClaims
19
- } from "./chunk-MMVLRUMK.js";
19
+ } from "./chunk-G2LGMWNG.js";
20
20
  import {
21
21
  GENERIC_FAMILIES,
22
22
  resolveBrandFaces
23
- } from "./chunk-R2TAVQGZ.js";
23
+ } from "./chunk-K2JTERIO.js";
24
24
  import {
25
25
  LOGO_FILE,
26
26
  readWorkspaceBrandDoc
27
- } from "./chunk-AS5VL32C.js";
27
+ } from "./chunk-JYALBYN7.js";
28
28
  import {
29
29
  holdUnbilledSpend
30
30
  } from "./chunk-5WMTPYKT.js";
@@ -98,10 +98,10 @@ import {
98
98
  staticRenderNodes,
99
99
  trimmedRenderBand,
100
100
  wordCount
101
- } from "./chunk-ELL2IQMF.js";
101
+ } from "./chunk-62JQQUAU.js";
102
102
  import {
103
103
  blockingArea
104
- } from "./chunk-5NS4CNF6.js";
104
+ } from "./chunk-E2RFM6R2.js";
105
105
  import {
106
106
  ACTOR_SHEET_MODEL,
107
107
  AD_SPEC_SCHEMA,
@@ -142,13 +142,13 @@ import {
142
142
  unwrittenProblems,
143
143
  winningMechanisms,
144
144
  withRenderedLettering
145
- } from "./chunk-U2452GLO.js";
145
+ } from "./chunk-4AMIHNNP.js";
146
146
  import {
147
147
  askAboutText,
148
148
  briefRules,
149
149
  rulesBlock,
150
150
  withoutRulesDeep
151
- } from "./chunk-ZBV5IV5T.js";
151
+ } from "./chunk-IKCP5NCE.js";
152
152
  import {
153
153
  AD_DESCRIBE_MODEL,
154
154
  AD_IMAGE_MODEL,
@@ -178,7 +178,7 @@ import {
178
178
  platformFormats,
179
179
  supportedAspectRatios,
180
180
  supportsLastFrame
181
- } from "./chunk-T6ATGN7Y.js";
181
+ } from "./chunk-MCJ5I5LR.js";
182
182
  import {
183
183
  AWARENESS_VALUES,
184
184
  marketFromCompanyDoc
@@ -2635,20 +2635,82 @@ async function readNamedTypefaces(root = ".", opts = {}) {
2635
2635
  return namedTypefaces({ tokensJson, brandDoc });
2636
2636
  }
2637
2637
  var MARK_FILE = /isotype|isologo|symbol|logomark|brandmark|(^|[-_ ])(mark|icon|avatar)([-_ .]|$)/i;
2638
+ var VARIANT_WORDS = new Set(
2639
+ "logo logos logotype logotipo lockup wordmark isotype isotipo isologo symbol logomark brandmark mark icon avatar favicon brand primary secondary main default full horizontal vertical stacked square round circle alt outline transparent light dark white black mono inverse inverted negative positive negativo positivo reverse reversed color colour on blanco negro negra claro clara oscuro oscura rgb cmyk small large sm md lg red blue green yellow orange purple violet pink grey gray navy teal cyan magenta brown gold silver coral rojo roja azul verde amarillo amarilla naranja morado morada rosa gris dorado dorada plateado plateada".split(" ")
2640
+ );
2641
+ function artworkOwner(file, slug) {
2642
+ const rest = path.basename(file).replace(/\.[a-z0-9]+$/i, "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().split(/[^a-z0-9]+/).filter((w) => w && !VARIANT_WORDS.has(w) && !/^\d+(x|px|w|h)?$/.test(w)).join("");
2643
+ return slug.length > 2 ? rest.replace(slug, "") : rest;
2644
+ }
2645
+ function ownLogoFamily(files, slug) {
2646
+ const families = /* @__PURE__ */ new Map();
2647
+ for (const f of files) {
2648
+ const owner = artworkOwner(f, slug);
2649
+ families.set(owner, [...families.get(owner) ?? [], f]);
2650
+ }
2651
+ const own = families.get("");
2652
+ if (own) return own;
2653
+ const picked = pickBrandMark(files.map((f) => path.basename(f)));
2654
+ const ranked = [...families.values()].sort(
2655
+ (a, b) => b.length - a.length || Number(b.some((f) => path.basename(f) === picked)) - Number(a.some((f) => path.basename(f) === picked))
2656
+ );
2657
+ return ranked[0] ?? [];
2658
+ }
2638
2659
  async function readBrandLogoFiles(root, brandName) {
2639
2660
  const dir = path.join(root, BRAND_DIR, "logos");
2640
- const files = (await readdir(dir).catch(() => [])).filter((f) => /\.(png|jpe?g|webp|svg)$/i.test(f)).sort();
2641
2661
  const slug = (brandName ?? "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "");
2642
- const ours = (f) => LOGO_FILE.test(f) || slug.length > 2 && f.toLowerCase().replace(/[^a-z0-9]/g, "").includes(slug);
2662
+ const named2 = await tokenLogos(root);
2663
+ let candidates;
2664
+ if (named2.length > 0) {
2665
+ candidates = named2;
2666
+ } else {
2667
+ const files = (await readdir(dir).catch(() => [])).filter((f) => /\.(png|jpe?g|webp|svg)$/i.test(f)).sort();
2668
+ const ours = (f) => LOGO_FILE.test(f) || slug.length > 2 && f.toLowerCase().replace(/[^a-z0-9]/g, "").includes(slug);
2669
+ candidates = ownLogoFamily(files.filter(ours), slug).map((f) => path.join(dir, f));
2670
+ }
2671
+ const notes = await Promise.all(
2672
+ [path.join(root, BRAND_DIR, "BRAND.md"), path.join(dir, "README.md")].map(
2673
+ (f) => readFile(f, "utf8").catch(() => "")
2674
+ )
2675
+ );
2676
+ const retired = retiredLogos(notes.join("\n"));
2643
2677
  const real = [];
2644
- for (const f of files.filter(ours)) {
2645
- const full = path.join(dir, f);
2678
+ for (const full of candidates) {
2679
+ if (retired.has(path.basename(full).toLowerCase())) continue;
2646
2680
  if (await markIsReal(full, root)) real.push(full);
2647
2681
  }
2648
2682
  const mark = real.find((f) => MARK_FILE.test(path.basename(f)));
2649
2683
  const logos = real.filter((f) => f !== mark);
2650
2684
  return { logos: logos.length > 0 ? logos : real, ...mark ? { mark } : {} };
2651
2685
  }
2686
+ var RETIRED = /\b(retired|deprecated|legacy|outdated|obsolete|no longer (?:used|in use)|retirad[oa]|obsolet[oa]|antigu[oa])\b/i;
2687
+ function retiredLogos(notes) {
2688
+ const out = /* @__PURE__ */ new Set();
2689
+ for (const line of notes.split("\n")) {
2690
+ if (!RETIRED.test(line)) continue;
2691
+ const named2 = [...line.matchAll(/[\w.-]+\.(?:png|jpe?g|webp|svg)\b/gi)].map((m) => m[0].toLowerCase());
2692
+ if (new Set(named2).size === 1 && named2[0]) out.add(named2[0]);
2693
+ }
2694
+ return out;
2695
+ }
2696
+ async function tokenLogos(root) {
2697
+ const raw = await readFile(path.join(root, BRAND_DIR, "tokens.json"), "utf8").catch(() => null);
2698
+ if (!raw) return [];
2699
+ let json2;
2700
+ try {
2701
+ json2 = JSON.parse(raw);
2702
+ } catch {
2703
+ return [];
2704
+ }
2705
+ const parsed = brandTokensSchema.safeParse(json2);
2706
+ if (!parsed.success) return [];
2707
+ const out = [];
2708
+ for (const logo of parsed.data.logos) {
2709
+ const abs = path.join(root, logo.path);
2710
+ if (/\.(png|jpe?g|webp|svg)$/i.test(abs) && await exists(abs) && !out.includes(abs)) out.push(abs);
2711
+ }
2712
+ return out;
2713
+ }
2652
2714
 
2653
2715
  // src/engine/scaffold/static-native-graph.ts
2654
2716
  var NATIVE_PHOTO_ROLE = "native_photo";
@@ -2708,11 +2770,12 @@ function nativeCanvas(canvas, spec, opts) {
2708
2770
  const kept = nodesOf3(canvas).filter(
2709
2771
  (n) => n.tags?.role === STATIC_AD_ROLE || n.id === "original" || n.id === "font_headline"
2710
2772
  );
2711
- const logos = opts.logos.map((file, i) => ({
2773
+ const wired = logosWired(canvas, opts);
2774
+ const logos = wired.map((where, i) => ({
2712
2775
  id: logoId(i),
2713
2776
  type: "ingest",
2714
- params: { ...locate(file, opts), expect: "image" },
2715
- ...i === 0 ? { tags: { role: BRAND_LOGO_ROLE } } : {}
2777
+ params: { ...where, expect: "image" },
2778
+ ...i === 0 ? { tags: { role: BRAND_LOGO_ROLE, wired: wired.map(placeOf) } } : {}
2716
2779
  }));
2717
2780
  const mark = opts.mark ? [
2718
2781
  {
@@ -2775,6 +2838,31 @@ function nativeCanvas(canvas, spec, opts) {
2775
2838
  };
2776
2839
  return { ...canvas, nodes: [...kept, ...logos, ...mark, ...photos, ...screens, final] };
2777
2840
  }
2841
+ function placeOf(where) {
2842
+ return where.source === "url" ? where.url : where.path;
2843
+ }
2844
+ function logosWired(canvas, opts) {
2845
+ const own = opts.logos.map((file) => locate(file, opts));
2846
+ const ownPlaces = new Set(own.map(placeOf));
2847
+ const ingests = nodesOf3(canvas).filter(
2848
+ (n) => n.type === "ingest" && typeof n.id === "string" && /^brand_logo(_\d+)?$/.test(n.id)
2849
+ );
2850
+ const present = ingests.flatMap((n) => {
2851
+ const p = n.params;
2852
+ if (p?.source === "url" && typeof p.url === "string") return [locate(p.url, opts)];
2853
+ if (p?.source === "path" && typeof p.path === "string") return [locate(p.path, opts)];
2854
+ return [];
2855
+ });
2856
+ const lastWired = ingests.map((n) => n.tags?.wired).find(Array.isArray);
2857
+ const byHand = lastWired !== void 0 && (lastWired.length !== present.length || present.some((where, i) => placeOf(where) !== lastWired[i]));
2858
+ if (!byHand) return own;
2859
+ const chosen = present.filter((where) => {
2860
+ if (!ownPlaces.has(placeOf(where))) return false;
2861
+ ownPlaces.delete(placeOf(where));
2862
+ return true;
2863
+ });
2864
+ return chosen.length > 0 ? chosen : own;
2865
+ }
2778
2866
  function locate(file, opts) {
2779
2867
  return /^https?:\/\//i.test(file) ? { source: "url", url: file } : opts.resolve(file);
2780
2868
  }
@@ -7021,6 +7109,7 @@ function lookFirst(reference) {
7021
7109
  }
7022
7110
  function planFormat(format, reference) {
7023
7111
  const theirs = reference?.container;
7112
+ if (!format) return theirs ? `the format (the proven ad's ${theirs.replace(/_/g, " ")})` : "the format";
7024
7113
  if (!theirs || theirs === format) return `the format (${format})`;
7025
7114
  const words = (f) => f.replace(/_/g, " ");
7026
7115
  return `the format (the proven ad is a ${words(theirs)}, the idea named a ${words(format)}: keep the proven ad's unless the idea's says the message better, and say which)`;
@@ -7135,7 +7224,7 @@ function memesRecord(audience) {
7135
7224
  }
7136
7225
  function thinkingOutline(input) {
7137
7226
  const { idea, reference } = input;
7138
- const sections = [];
7227
+ const sections = [["The moment in the feed", feedMoment(idea, reference, input.audience)]];
7139
7228
  if (reference) {
7140
7229
  sections.push(
7141
7230
  [
@@ -7153,31 +7242,12 @@ function thinkingOutline(input) {
7153
7242
  );
7154
7243
  const combined = takeFromWhich(reference);
7155
7244
  if (combined) sections.push(["What we take, from which ad", combined]);
7156
- } else {
7157
- sections.push([
7158
- "Why it should work",
7159
- question(
7160
- "no proven ad fits, so this is a bet. What should stop this viewer, and why should they believe it? Say what would prove the bet wrong."
7161
- )
7162
- ]);
7163
7245
  }
7164
7246
  sections.push(
7165
7247
  [
7166
- "Does it fit our audience",
7167
- `${memesRecord(input.audience)}${question(
7168
- `our viewer is ${idea.who.replace(/[-_]/g, " ")}. Would they get the joke, recognise the format, see themselves in it? What in it would fall flat or put them off, and what do they care about that it does not say yet?`
7169
- )}`
7170
- ],
7171
- [
7172
- "The hook, ours",
7248
+ "The hook, the angle and the call to action",
7173
7249
  question(
7174
- `our message is "${idea.message}". Write the hook ${reference ? "the reference's hook becomes" : "that opens it"} for us, in our customers' words, and say why it should stop this viewer. Give the two or three you weighed and why this one won.`
7175
- )
7176
- ],
7177
- [
7178
- "The angle and the call to action",
7179
- question(
7180
- `the angle the ${reference ? "reference wins on" : "idea takes"} (pain, desire, fear of loss, status, identity, savings, convenience, proof, authority, urgency, us against them, contrarian) and ours (the idea says "${idea.angle}"): why it is the right one for this viewer at this stage. Then the call to action: what we ask, how big an ask it is for this viewer, what lowers the risk (an offer, a guarantee, a free step), and where and how it shows (a button, a line, a native ask like "comment X", or none).`
7250
+ `our message is "${idea.message}". Write the hook ${reference ? "the reference's hook becomes" : "that opens it"} for us, in our customers' words, and say why it stops this viewer; give the two or three you weighed and why this one won. The angle (the idea says "${idea.angle}"${reference ? "; say the one the reference wins on" : ""}) and why it is right for this viewer at this stage. Then the call to action: what we ask, how big an ask it is for this viewer, what lowers the risk (an offer, a guarantee, a free step), and where and how it shows (a button, a line, a native ask, or none).`
7181
7251
  )
7182
7252
  ],
7183
7253
  [CAST_HEADING, castAndShow(input.inventory, input.rules ?? [])]
@@ -7198,6 +7268,15 @@ function thinkingOutline(input) {
7198
7268
  ]);
7199
7269
  return [THINKING_HEADING, "", ...sections.flatMap(([title, body]) => [`### ${title}`, "", body, ""])].join("\n");
7200
7270
  }
7271
+ function feedMoment(idea, reference, audience) {
7272
+ const viewer = idea.who.replace(/[-_]/g, " ");
7273
+ const shows = idea.shows ? `What ours shows first: ${idea.shows}.
7274
+
7275
+ ` : "";
7276
+ const ask = `${viewer} is scrolling, not looking for an ad. In the first second ours must break their pattern (they stop), make them think "this is for me" (their problem, their words, someone like them) and make them want to know more. Say what of ours does each of the three${idea.shows ? "" : ", starting with what the picture shows"}, and what would leave them scrolling.`;
7277
+ const tied = reference ? ` Then: does proven ad ${reference.adId} show that, or the same kind of picture doing the same job? If it does not, it is the wrong reference: find one that does (\`baker winning-ads search "<what ours shows>"\`) and rebuild on it (\`baker creatives make <idea> --reference <adId>\`) before answering anything below.` : " No proven ad fits, so this is a bet: say why it should stop them and what would prove it wrong.";
7278
+ return `${shows}${memesRecord(audience)}${question(`${ask}${tied}`)}`;
7279
+ }
7201
7280
  function withThinking(definition, outline) {
7202
7281
  if (definition.split("\n").some((line) => line.trim() === THINKING_HEADING)) return definition;
7203
7282
  return `${definition.trimEnd()}
@@ -8857,4 +8936,4 @@ export {
8857
8936
  prepareCanvas,
8858
8937
  exitOnPrepareError
8859
8938
  };
8860
- //# sourceMappingURL=chunk-5RCCESDX.js.map
8939
+ //# sourceMappingURL=chunk-AXDKLXCG.js.map