@koda-sl/baker-cli 0.386.0-dev.4e118c09a → 0.386.0-dev.d6e55699d

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 (967) hide show
  1. package/README.md +1057 -215
  2. package/canvas/tiktok-captions-composition/index.html +5 -6
  3. package/canvas/tiktok-captions-composition/meta.json +5 -0
  4. package/dist/account-5TGX45FO.js +79 -0
  5. package/dist/account-5TGX45FO.js.map +1 -0
  6. package/dist/account-CLOKMTTC.js +49 -0
  7. package/dist/account-CLOKMTTC.js.map +1 -0
  8. package/dist/account-XFK6VX2R.js +80 -0
  9. package/dist/account-XFK6VX2R.js.map +1 -0
  10. package/dist/account-reads-ZK5RMLB2.js +218 -0
  11. package/dist/account-reads-ZK5RMLB2.js.map +1 -0
  12. package/dist/account-writes-Y7EQXDXF.js +66 -0
  13. package/dist/account-writes-Y7EQXDXF.js.map +1 -0
  14. package/dist/accounts-7YD457YN.js +114 -0
  15. package/dist/accounts-7YD457YN.js.map +1 -0
  16. package/dist/accounts-BJ3X5JQT.js +115 -0
  17. package/dist/accounts-BJ3X5JQT.js.map +1 -0
  18. package/dist/accounts-HGAFFOA7.js +77 -0
  19. package/dist/accounts-HGAFFOA7.js.map +1 -0
  20. package/dist/accounts-OWMXUT6D.js +611 -0
  21. package/dist/accounts-OWMXUT6D.js.map +1 -0
  22. package/dist/accounts-RYBDLQ6H.js +75 -0
  23. package/dist/accounts-RYBDLQ6H.js.map +1 -0
  24. package/dist/actions-NSQYW7YS.js +55 -0
  25. package/dist/actions-NSQYW7YS.js.map +1 -0
  26. package/dist/active-entities-R6GZIO6Z.js +103 -0
  27. package/dist/active-entities-R6GZIO6Z.js.map +1 -0
  28. package/dist/activities-ESBF3GFS.js +74 -0
  29. package/dist/activities-ESBF3GFS.js.map +1 -0
  30. package/dist/ad-group-writes-I225OYDZ.js +170 -0
  31. package/dist/ad-group-writes-I225OYDZ.js.map +1 -0
  32. package/dist/ad-groups-O35MWNF6.js +68 -0
  33. package/dist/ad-groups-O35MWNF6.js.map +1 -0
  34. package/dist/ad-writes-SS5YZO5W.js +174 -0
  35. package/dist/ad-writes-SS5YZO5W.js.map +1 -0
  36. package/dist/add-HWIE5PGR.js +302 -0
  37. package/dist/add-HWIE5PGR.js.map +1 -0
  38. package/dist/add-IIW3NHZH.js +104 -0
  39. package/dist/add-IIW3NHZH.js.map +1 -0
  40. package/dist/add-QZHAWUBA.js +97 -0
  41. package/dist/add-QZHAWUBA.js.map +1 -0
  42. package/dist/add-TGQIVVXH.js +105 -0
  43. package/dist/add-TGQIVVXH.js.map +1 -0
  44. package/dist/add-accounts-6QYPOPR2.js +91 -0
  45. package/dist/add-accounts-6QYPOPR2.js.map +1 -0
  46. package/dist/ads-AUSRB4GU.js +128 -0
  47. package/dist/ads-AUSRB4GU.js.map +1 -0
  48. package/dist/ads-COYOTEKE.js +77 -0
  49. package/dist/ads-COYOTEKE.js.map +1 -0
  50. package/dist/ads-D6KKCQ3Q.js +40 -0
  51. package/dist/ads-D6KKCQ3Q.js.map +1 -0
  52. package/dist/ads-QKIHHXP5.js +113 -0
  53. package/dist/ads-QKIHHXP5.js.map +1 -0
  54. package/dist/adsets-7WMWU45E.js +176 -0
  55. package/dist/adsets-7WMWU45E.js.map +1 -0
  56. package/dist/advertisers-6NZ2M57X.js +120 -0
  57. package/dist/advertisers-6NZ2M57X.js.map +1 -0
  58. package/dist/advertisers-BCGKUMEH.js +125 -0
  59. package/dist/advertisers-BCGKUMEH.js.map +1 -0
  60. package/dist/analytics-QJC2BTZY.js +433 -0
  61. package/dist/analytics-QJC2BTZY.js.map +1 -0
  62. package/dist/analytics-SN6K7J7M.js +1980 -0
  63. package/dist/analytics-SN6K7J7M.js.map +1 -0
  64. package/dist/animate-JXIT77Y5.js +480 -0
  65. package/dist/animate-JXIT77Y5.js.map +1 -0
  66. package/dist/assign-XFDA42KL.js +77 -0
  67. package/dist/assign-XFDA42KL.js.map +1 -0
  68. package/dist/audience-size-DJPFYHPJ.js +94 -0
  69. package/dist/audience-size-DJPFYHPJ.js.map +1 -0
  70. package/dist/audiences-DC3IOG34.js +85 -0
  71. package/dist/audiences-DC3IOG34.js.map +1 -0
  72. package/dist/audiences-NEW3LLQR.js +268 -0
  73. package/dist/audiences-NEW3LLQR.js.map +1 -0
  74. package/dist/audiences-VXTIBZP6.js +78 -0
  75. package/dist/audiences-VXTIBZP6.js.map +1 -0
  76. package/dist/audit-M5B7TZGT.js +151 -0
  77. package/dist/audit-M5B7TZGT.js.map +1 -0
  78. package/dist/audit-UIPMTI5C.js +88 -0
  79. package/dist/audit-UIPMTI5C.js.map +1 -0
  80. package/dist/autocomplete-NWHEASQY.js +111 -0
  81. package/dist/autocomplete-NWHEASQY.js.map +1 -0
  82. package/dist/avatars-RNMUVMFM.js +38 -0
  83. package/dist/avatars-RNMUVMFM.js.map +1 -0
  84. package/dist/bid-pricing-EAY3HAHY.js +99 -0
  85. package/dist/bid-pricing-EAY3HAHY.js.map +1 -0
  86. package/dist/brand-XBHWYPMT.js +22 -0
  87. package/dist/brand-XBHWYPMT.js.map +1 -0
  88. package/dist/brief-XBAAPKRR.js +492 -0
  89. package/dist/brief-XBAAPKRR.js.map +1 -0
  90. package/dist/businesses-J7OP7MSK.js +53 -0
  91. package/dist/businesses-J7OP7MSK.js.map +1 -0
  92. package/dist/campaign-groups-7KA2RA5V.js +95 -0
  93. package/dist/campaign-groups-7KA2RA5V.js.map +1 -0
  94. package/dist/campaign-writes-5XA727KI.js +170 -0
  95. package/dist/campaign-writes-5XA727KI.js.map +1 -0
  96. package/dist/campaign-writes-D2UID2I6.js +165 -0
  97. package/dist/campaign-writes-D2UID2I6.js.map +1 -0
  98. package/dist/campaigns-JPYNVFQI.js +76 -0
  99. package/dist/campaigns-JPYNVFQI.js.map +1 -0
  100. package/dist/campaigns-NJ3KOPJS.js +107 -0
  101. package/dist/campaigns-NJ3KOPJS.js.map +1 -0
  102. package/dist/campaigns-QUTTH2TB.js +110 -0
  103. package/dist/campaigns-QUTTH2TB.js.map +1 -0
  104. package/dist/campaigns-SOO5RHYG.js +109 -0
  105. package/dist/campaigns-SOO5RHYG.js.map +1 -0
  106. package/dist/canvas-3VZ46BCF.js +46 -0
  107. package/dist/canvas-3VZ46BCF.js.map +1 -0
  108. package/dist/capabilities-KAYDPH7E.js +144 -0
  109. package/dist/capabilities-KAYDPH7E.js.map +1 -0
  110. package/dist/cards-7H32TNMO.js +85 -0
  111. package/dist/cards-7H32TNMO.js.map +1 -0
  112. package/dist/catalog-OTICZPJA.js +64 -0
  113. package/dist/catalog-OTICZPJA.js.map +1 -0
  114. package/dist/catalogs-ABCQLCDU.js +128 -0
  115. package/dist/catalogs-ABCQLCDU.js.map +1 -0
  116. package/dist/changes-22EO52IY.js +135 -0
  117. package/dist/changes-22EO52IY.js.map +1 -0
  118. package/dist/chatgpt-B3NHRJUE.js +47 -0
  119. package/dist/chatgpt-B3NHRJUE.js.map +1 -0
  120. package/dist/chats-QG3IRHOD.js +262 -0
  121. package/dist/chats-QG3IRHOD.js.map +1 -0
  122. package/dist/chunk-2CV7LX23.js +474 -0
  123. package/dist/chunk-2CV7LX23.js.map +1 -0
  124. package/dist/chunk-2SQJL7ZN.js +56 -0
  125. package/dist/chunk-2SQJL7ZN.js.map +1 -0
  126. package/dist/chunk-2Y5V23PU.js +29 -0
  127. package/dist/chunk-2Y5V23PU.js.map +1 -0
  128. package/dist/chunk-32CPGJPL.js +149 -0
  129. package/dist/chunk-32CPGJPL.js.map +1 -0
  130. package/dist/chunk-32PSERWG.js +363 -0
  131. package/dist/chunk-32PSERWG.js.map +1 -0
  132. package/dist/chunk-3ACMDRSE.js +39 -0
  133. package/dist/chunk-3ACMDRSE.js.map +1 -0
  134. package/dist/chunk-3UDSYYND.js +42 -0
  135. package/dist/chunk-3UDSYYND.js.map +1 -0
  136. package/dist/chunk-3V5E5SVE.js +382 -0
  137. package/dist/chunk-3V5E5SVE.js.map +1 -0
  138. package/dist/chunk-455BTAHM.js +57 -0
  139. package/dist/chunk-455BTAHM.js.map +1 -0
  140. package/dist/chunk-4MH6LONO.js +274 -0
  141. package/dist/chunk-4MH6LONO.js.map +1 -0
  142. package/dist/chunk-4NZ47VXO.js +137 -0
  143. package/dist/chunk-4NZ47VXO.js.map +1 -0
  144. package/dist/chunk-4OBO75XU.js +275 -0
  145. package/dist/chunk-4OBO75XU.js.map +1 -0
  146. package/dist/chunk-5HYSKH77.js +315 -0
  147. package/dist/chunk-5HYSKH77.js.map +1 -0
  148. package/dist/chunk-5MBPIONY.js +29 -0
  149. package/dist/chunk-5MBPIONY.js.map +1 -0
  150. package/dist/chunk-5OVOLYY3.js +74 -0
  151. package/dist/chunk-5OVOLYY3.js.map +1 -0
  152. package/dist/chunk-66USKCVY.js +4410 -0
  153. package/dist/chunk-66USKCVY.js.map +1 -0
  154. package/dist/chunk-6I7SYEYN.js +166 -0
  155. package/dist/chunk-6I7SYEYN.js.map +1 -0
  156. package/dist/chunk-6O7ISBC7.js +65 -0
  157. package/dist/chunk-6O7ISBC7.js.map +1 -0
  158. package/dist/chunk-752S7JF6.js +35 -0
  159. package/dist/chunk-752S7JF6.js.map +1 -0
  160. package/dist/chunk-AFJGYJ7Z.js +45 -0
  161. package/dist/chunk-AFJGYJ7Z.js.map +1 -0
  162. package/dist/chunk-AR7PU7BB.js +76 -0
  163. package/dist/chunk-AR7PU7BB.js.map +1 -0
  164. package/dist/chunk-ASL7JFBD.js +96 -0
  165. package/dist/chunk-ASL7JFBD.js.map +1 -0
  166. package/dist/chunk-AUCITRRT.js +310 -0
  167. package/dist/chunk-AUCITRRT.js.map +1 -0
  168. package/dist/chunk-AUSKKFVH.js +84 -0
  169. package/dist/chunk-AUSKKFVH.js.map +1 -0
  170. package/dist/chunk-BEGARAVC.js +174 -0
  171. package/dist/chunk-BEGARAVC.js.map +1 -0
  172. package/dist/{chunk-WWCLT3RG.js → chunk-BVM5IRZW.js} +16 -8
  173. package/dist/chunk-BVM5IRZW.js.map +1 -0
  174. package/dist/chunk-CAMX6OHF.js +3182 -0
  175. package/dist/chunk-CAMX6OHF.js.map +1 -0
  176. package/dist/chunk-CKI3RLMU.js +159 -0
  177. package/dist/chunk-CKI3RLMU.js.map +1 -0
  178. package/dist/chunk-CZENWCBS.js +333 -0
  179. package/dist/chunk-CZENWCBS.js.map +1 -0
  180. package/dist/chunk-D5FY4FAK.js +24 -0
  181. package/dist/chunk-D5FY4FAK.js.map +1 -0
  182. package/dist/chunk-DGCUPJZD.js +39 -0
  183. package/dist/chunk-DGCUPJZD.js.map +1 -0
  184. package/dist/chunk-DIICZGIS.js +509 -0
  185. package/dist/chunk-DIICZGIS.js.map +1 -0
  186. package/dist/chunk-DNCLWSHO.js +41 -0
  187. package/dist/chunk-DNCLWSHO.js.map +1 -0
  188. package/dist/chunk-DX4GIDO7.js +296 -0
  189. package/dist/chunk-DX4GIDO7.js.map +1 -0
  190. package/dist/chunk-DYZJBWT2.js +1079 -0
  191. package/dist/chunk-DYZJBWT2.js.map +1 -0
  192. package/dist/chunk-EDLZGTGN.js +216 -0
  193. package/dist/chunk-EDLZGTGN.js.map +1 -0
  194. package/dist/chunk-EDNX3AOS.js +76 -0
  195. package/dist/chunk-EDNX3AOS.js.map +1 -0
  196. package/dist/chunk-EF5DP6EB.js +52 -0
  197. package/dist/chunk-EF5DP6EB.js.map +1 -0
  198. package/dist/chunk-EQEZAYPL.js +541 -0
  199. package/dist/chunk-EQEZAYPL.js.map +1 -0
  200. package/dist/chunk-ERSX3MKH.js +34 -0
  201. package/dist/chunk-ERSX3MKH.js.map +1 -0
  202. package/dist/chunk-FKOECEVC.js +126 -0
  203. package/dist/chunk-FKOECEVC.js.map +1 -0
  204. package/dist/chunk-FYWWTMXP.js +2902 -0
  205. package/dist/chunk-FYWWTMXP.js.map +1 -0
  206. package/dist/chunk-G7AFVTUS.js +106 -0
  207. package/dist/chunk-G7AFVTUS.js.map +1 -0
  208. package/dist/chunk-GIW7ABMM.js +74 -0
  209. package/dist/chunk-GIW7ABMM.js.map +1 -0
  210. package/dist/chunk-GIWHHCD6.js +145 -0
  211. package/dist/chunk-GIWHHCD6.js.map +1 -0
  212. package/dist/chunk-GOJXKIFQ.js +1605 -0
  213. package/dist/chunk-GOJXKIFQ.js.map +1 -0
  214. package/dist/chunk-GPXIUYIA.js +592 -0
  215. package/dist/chunk-GPXIUYIA.js.map +1 -0
  216. package/dist/chunk-GRQ2AXDX.js +9 -0
  217. package/dist/chunk-GRQ2AXDX.js.map +1 -0
  218. package/dist/chunk-GXDLWBOY.js +73 -0
  219. package/dist/chunk-GXDLWBOY.js.map +1 -0
  220. package/dist/chunk-H7MLHG2I.js +94 -0
  221. package/dist/chunk-H7MLHG2I.js.map +1 -0
  222. package/dist/chunk-HAE4WWFQ.js +455 -0
  223. package/dist/chunk-HAE4WWFQ.js.map +1 -0
  224. package/dist/chunk-HB3LNR4Y.js +197 -0
  225. package/dist/chunk-HB3LNR4Y.js.map +1 -0
  226. package/dist/chunk-HDHWIEJJ.js +136 -0
  227. package/dist/chunk-HDHWIEJJ.js.map +1 -0
  228. package/dist/chunk-HJTIBTF7.js +98 -0
  229. package/dist/chunk-HJTIBTF7.js.map +1 -0
  230. package/dist/{chunk-VZEDAFAR.js → chunk-HLXWKMTK.js} +47 -8
  231. package/dist/chunk-HLXWKMTK.js.map +1 -0
  232. package/dist/{chunk-MF7YA62W.js → chunk-HREWXNTO.js} +10 -5
  233. package/dist/chunk-HREWXNTO.js.map +1 -0
  234. package/dist/chunk-HVJUMQYY.js +494 -0
  235. package/dist/chunk-HVJUMQYY.js.map +1 -0
  236. package/dist/chunk-I3DIZWN5.js +97 -0
  237. package/dist/chunk-I3DIZWN5.js.map +1 -0
  238. package/dist/chunk-IJMWEO4P.js +57 -0
  239. package/dist/chunk-IJMWEO4P.js.map +1 -0
  240. package/dist/chunk-IMORFIUT.js +207 -0
  241. package/dist/chunk-IMORFIUT.js.map +1 -0
  242. package/dist/chunk-IOCSDFF2.js +23992 -0
  243. package/dist/chunk-IOCSDFF2.js.map +1 -0
  244. package/dist/chunk-IRTYTT5D.js +665 -0
  245. package/dist/chunk-IRTYTT5D.js.map +1 -0
  246. package/dist/chunk-IVIJJXXT.js +62 -0
  247. package/dist/chunk-IVIJJXXT.js.map +1 -0
  248. package/dist/chunk-J57GWTPK.js +106 -0
  249. package/dist/chunk-J57GWTPK.js.map +1 -0
  250. package/dist/chunk-JAYT43KX.js +4227 -0
  251. package/dist/chunk-JAYT43KX.js.map +1 -0
  252. package/dist/chunk-JPK34QPS.js +134 -0
  253. package/dist/chunk-JPK34QPS.js.map +1 -0
  254. package/dist/chunk-JRCFCIE3.js +188 -0
  255. package/dist/chunk-JRCFCIE3.js.map +1 -0
  256. package/dist/chunk-JRGPCPT2.js +479 -0
  257. package/dist/chunk-JRGPCPT2.js.map +1 -0
  258. package/dist/chunk-JUAIGJ2A.js +76 -0
  259. package/dist/chunk-JUAIGJ2A.js.map +1 -0
  260. package/dist/chunk-K2RYUZ5Y.js +51 -0
  261. package/dist/chunk-K2RYUZ5Y.js.map +1 -0
  262. package/dist/chunk-K5OQES4V.js +58 -0
  263. package/dist/chunk-K5OQES4V.js.map +1 -0
  264. package/dist/chunk-KAHMADFH.js +455 -0
  265. package/dist/chunk-KAHMADFH.js.map +1 -0
  266. package/dist/chunk-KIGGMKAE.js +66 -0
  267. package/dist/chunk-KIGGMKAE.js.map +1 -0
  268. package/dist/chunk-KKJ4KJCW.js +29 -0
  269. package/dist/chunk-KKJ4KJCW.js.map +1 -0
  270. package/dist/chunk-KLK6KQLQ.js +55 -0
  271. package/dist/chunk-KLK6KQLQ.js.map +1 -0
  272. package/dist/chunk-KRIK2JR4.js +6212 -0
  273. package/dist/chunk-KRIK2JR4.js.map +1 -0
  274. package/dist/chunk-KZUHRZ2C.js +5187 -0
  275. package/dist/chunk-KZUHRZ2C.js.map +1 -0
  276. package/dist/chunk-L5WIRYNB.js +19 -0
  277. package/dist/chunk-L5WIRYNB.js.map +1 -0
  278. package/dist/chunk-LA6PPSNA.js +65 -0
  279. package/dist/chunk-LA6PPSNA.js.map +1 -0
  280. package/dist/chunk-LEIQAHWF.js +25 -0
  281. package/dist/chunk-LEIQAHWF.js.map +1 -0
  282. package/dist/chunk-LWBWCIWL.js +297 -0
  283. package/dist/chunk-LWBWCIWL.js.map +1 -0
  284. package/dist/chunk-M4PPFVYL.js +346 -0
  285. package/dist/chunk-M4PPFVYL.js.map +1 -0
  286. package/dist/chunk-M6UNISGO.js +66 -0
  287. package/dist/chunk-M6UNISGO.js.map +1 -0
  288. package/dist/chunk-MGKHFGLV.js +75 -0
  289. package/dist/chunk-MGKHFGLV.js.map +1 -0
  290. package/dist/chunk-MUVSWFLL.js +111 -0
  291. package/dist/chunk-MUVSWFLL.js.map +1 -0
  292. package/dist/chunk-NFSLRRIE.js +77 -0
  293. package/dist/chunk-NFSLRRIE.js.map +1 -0
  294. package/dist/chunk-NHU33T2S.js +60 -0
  295. package/dist/chunk-NHU33T2S.js.map +1 -0
  296. package/dist/chunk-O6QKCJE4.js +455 -0
  297. package/dist/chunk-O6QKCJE4.js.map +1 -0
  298. package/dist/chunk-OBNWER4H.js +1599 -0
  299. package/dist/chunk-OBNWER4H.js.map +1 -0
  300. package/dist/chunk-OFFAMC5H.js +225 -0
  301. package/dist/chunk-OFFAMC5H.js.map +1 -0
  302. package/dist/chunk-P4NSJS54.js +20 -0
  303. package/dist/chunk-P4NSJS54.js.map +1 -0
  304. package/dist/chunk-P5T7OZKV.js +26 -0
  305. package/dist/chunk-P5T7OZKV.js.map +1 -0
  306. package/dist/chunk-PAHLJMC3.js +175 -0
  307. package/dist/chunk-PAHLJMC3.js.map +1 -0
  308. package/dist/chunk-PBVLPFJ6.js +169 -0
  309. package/dist/chunk-PBVLPFJ6.js.map +1 -0
  310. package/dist/chunk-PFBQERWX.js +10 -0
  311. package/dist/chunk-PFBQERWX.js.map +1 -0
  312. package/dist/chunk-Q6ULQMWG.js +41 -0
  313. package/dist/chunk-Q6ULQMWG.js.map +1 -0
  314. package/dist/chunk-QKE7GXZ7.js +6683 -0
  315. package/dist/chunk-QKE7GXZ7.js.map +1 -0
  316. package/dist/chunk-QL573PLH.js +150 -0
  317. package/dist/chunk-QL573PLH.js.map +1 -0
  318. package/dist/chunk-QO23YHLK.js +84 -0
  319. package/dist/chunk-QO23YHLK.js.map +1 -0
  320. package/dist/chunk-R5OQM7FF.js +179 -0
  321. package/dist/chunk-R5OQM7FF.js.map +1 -0
  322. package/dist/chunk-RDLB54KF.js +629 -0
  323. package/dist/chunk-RDLB54KF.js.map +1 -0
  324. package/dist/chunk-RGIXQEGJ.js +502 -0
  325. package/dist/chunk-RGIXQEGJ.js.map +1 -0
  326. package/dist/chunk-RRIAHUWP.js +304 -0
  327. package/dist/chunk-RRIAHUWP.js.map +1 -0
  328. package/dist/chunk-S4LZ7KTG.js +160 -0
  329. package/dist/chunk-S4LZ7KTG.js.map +1 -0
  330. package/dist/chunk-SHTESUB6.js +1442 -0
  331. package/dist/chunk-SHTESUB6.js.map +1 -0
  332. package/dist/chunk-SLB46MSS.js +64 -0
  333. package/dist/chunk-SLB46MSS.js.map +1 -0
  334. package/dist/chunk-T7M4WFNV.js +172 -0
  335. package/dist/chunk-T7M4WFNV.js.map +1 -0
  336. package/dist/{chunk-JTZXQRXI.js → chunk-TPXI2GCW.js} +4 -4
  337. package/dist/chunk-TWNFQUBS.js +23 -0
  338. package/dist/chunk-TWNFQUBS.js.map +1 -0
  339. package/dist/chunk-U6VRBDNQ.js +1830 -0
  340. package/dist/chunk-U6VRBDNQ.js.map +1 -0
  341. package/dist/chunk-U7BBXM67.js +1743 -0
  342. package/dist/chunk-U7BBXM67.js.map +1 -0
  343. package/dist/chunk-UI6BKYQD.js +225 -0
  344. package/dist/chunk-UI6BKYQD.js.map +1 -0
  345. package/dist/chunk-USL5ARRE.js +26 -0
  346. package/dist/chunk-USL5ARRE.js.map +1 -0
  347. package/dist/chunk-UYC45JNS.js +139 -0
  348. package/dist/chunk-UYC45JNS.js.map +1 -0
  349. package/dist/chunk-V5GSRREZ.js +846 -0
  350. package/dist/chunk-V5GSRREZ.js.map +1 -0
  351. package/dist/chunk-V5HDRJQW.js +337 -0
  352. package/dist/chunk-V5HDRJQW.js.map +1 -0
  353. package/dist/chunk-VS4C7VAR.js +533 -0
  354. package/dist/chunk-VS4C7VAR.js.map +1 -0
  355. package/dist/chunk-W4W4ZRBP.js +191 -0
  356. package/dist/chunk-W4W4ZRBP.js.map +1 -0
  357. package/dist/chunk-WIRBRCTJ.js +228 -0
  358. package/dist/chunk-WIRBRCTJ.js.map +1 -0
  359. package/dist/chunk-WN4KX7GE.js +25 -0
  360. package/dist/chunk-WN4KX7GE.js.map +1 -0
  361. package/dist/chunk-WNFTXSGR.js +111 -0
  362. package/dist/chunk-WNFTXSGR.js.map +1 -0
  363. package/dist/chunk-WOTDHRNF.js +2109 -0
  364. package/dist/chunk-WOTDHRNF.js.map +1 -0
  365. package/dist/chunk-WPKOEFOE.js +103 -0
  366. package/dist/chunk-WPKOEFOE.js.map +1 -0
  367. package/dist/chunk-XE3WS3QE.js +183 -0
  368. package/dist/chunk-XE3WS3QE.js.map +1 -0
  369. package/dist/chunk-XGWKTYXQ.js +67 -0
  370. package/dist/chunk-XGWKTYXQ.js.map +1 -0
  371. package/dist/chunk-XIGIJJSF.js +66 -0
  372. package/dist/chunk-XIGIJJSF.js.map +1 -0
  373. package/dist/chunk-XNUXB63I.js +817 -0
  374. package/dist/chunk-XNUXB63I.js.map +1 -0
  375. package/dist/chunk-XQ3CCNJD.js +610 -0
  376. package/dist/chunk-XQ3CCNJD.js.map +1 -0
  377. package/dist/chunk-Y362QH54.js +98 -0
  378. package/dist/chunk-Y362QH54.js.map +1 -0
  379. package/dist/chunk-Y4HZNSBN.js +3151 -0
  380. package/dist/chunk-Y4HZNSBN.js.map +1 -0
  381. package/dist/chunk-Y4T6ATDQ.js +74 -0
  382. package/dist/chunk-Y4T6ATDQ.js.map +1 -0
  383. package/dist/chunk-YIMGUMXX.js +206 -0
  384. package/dist/chunk-YIMGUMXX.js.map +1 -0
  385. package/dist/chunk-YQSBHWOI.js +41 -0
  386. package/dist/chunk-YU26SDNT.js +46 -0
  387. package/dist/chunk-YU26SDNT.js.map +1 -0
  388. package/dist/chunk-YULENNA7.js +501 -0
  389. package/dist/chunk-YULENNA7.js.map +1 -0
  390. package/dist/chunk-YYSZYSAG.js +150 -0
  391. package/dist/chunk-YYSZYSAG.js.map +1 -0
  392. package/dist/chunk-Z3ENMCFE.js +94 -0
  393. package/dist/chunk-Z3ENMCFE.js.map +1 -0
  394. package/dist/chunk-ZCFSHQBF.js +92 -0
  395. package/dist/chunk-ZCFSHQBF.js.map +1 -0
  396. package/dist/chunk-ZH7ZM3ZM.js +125 -0
  397. package/dist/chunk-ZH7ZM3ZM.js.map +1 -0
  398. package/dist/chunk-ZIXHS6AM.js +42 -0
  399. package/dist/chunk-ZIXHS6AM.js.map +1 -0
  400. package/dist/chunk-ZLLJKSNS.js +96 -0
  401. package/dist/chunk-ZLLJKSNS.js.map +1 -0
  402. package/dist/claim-4AFNDV3A.js +197 -0
  403. package/dist/claim-4AFNDV3A.js.map +1 -0
  404. package/dist/cli.js +104 -71708
  405. package/dist/cli.js.map +1 -1
  406. package/dist/client-26SAJ46D.js +19 -0
  407. package/dist/code-MOWYJMDH.js +76 -0
  408. package/dist/code-MOWYJMDH.js.map +1 -0
  409. package/dist/companies-PZRRZZNV.js +195 -0
  410. package/dist/companies-PZRRZZNV.js.map +1 -0
  411. package/dist/complete-IBW5DNVZ.js +81 -0
  412. package/dist/complete-IBW5DNVZ.js.map +1 -0
  413. package/dist/config-X6GKOVQ6.js +88 -0
  414. package/dist/config-X6GKOVQ6.js.map +1 -0
  415. package/dist/connect-WYUYS5V4.js +42 -0
  416. package/dist/content-UYZC4AKN.js +85 -0
  417. package/dist/content-UYZC4AKN.js.map +1 -0
  418. package/dist/conversation-6AG3UBYY.js +93 -0
  419. package/dist/conversation-6AG3UBYY.js.map +1 -0
  420. package/dist/conversion-report-R4GJWWTK.js +125 -0
  421. package/dist/conversion-report-R4GJWWTK.js.map +1 -0
  422. package/dist/conversion-upload-command-YML2UNJB.js +438 -0
  423. package/dist/conversion-upload-command-YML2UNJB.js.map +1 -0
  424. package/dist/conversion-writes-WHFFUWWL.js +120 -0
  425. package/dist/conversion-writes-WHFFUWWL.js.map +1 -0
  426. package/dist/conversions-NOBBFNIU.js +135 -0
  427. package/dist/conversions-NOBBFNIU.js.map +1 -0
  428. package/dist/conversions-OXJAX5GB.js +76 -0
  429. package/dist/conversions-OXJAX5GB.js.map +1 -0
  430. package/dist/countries-PBXNB3BR.js +82 -0
  431. package/dist/countries-PBXNB3BR.js.map +1 -0
  432. package/dist/create-JK42P564.js +59 -0
  433. package/dist/create-JK42P564.js.map +1 -0
  434. package/dist/create-LAWUVPCY.js +207 -0
  435. package/dist/create-LAWUVPCY.js.map +1 -0
  436. package/dist/create-MUPQ5CTH.js +138 -0
  437. package/dist/create-MUPQ5CTH.js.map +1 -0
  438. package/dist/create-NQJNCFRO.js +236 -0
  439. package/dist/create-NQJNCFRO.js.map +1 -0
  440. package/dist/creatives-KCWFZIM5.js +182 -0
  441. package/dist/creatives-KCWFZIM5.js.map +1 -0
  442. package/dist/creatives-NNDWCSKJ.js +51 -0
  443. package/dist/creatives-NNDWCSKJ.js.map +1 -0
  444. package/dist/creatives-RHNHTS2R.js +87 -0
  445. package/dist/creatives-RHNHTS2R.js.map +1 -0
  446. package/dist/credentials-CEKGXR2C.js +287 -0
  447. package/dist/credentials-CEKGXR2C.js.map +1 -0
  448. package/dist/critique-HDDYER52.js +1449 -0
  449. package/dist/critique-HDDYER52.js.map +1 -0
  450. package/dist/critique-QIN2FO4F.js +216 -0
  451. package/dist/critique-QIN2FO4F.js.map +1 -0
  452. package/dist/crm-KBPWZC6J.js +318 -0
  453. package/dist/crm-KBPWZC6J.js.map +1 -0
  454. package/dist/crm-QBWD7CWB.js +224 -0
  455. package/dist/crm-QBWD7CWB.js.map +1 -0
  456. package/dist/crop-U3AD4DDR.js +113 -0
  457. package/dist/crop-U3AD4DDR.js.map +1 -0
  458. package/dist/currency-XTFGZFGB.js +88 -0
  459. package/dist/currency-XTFGZFGB.js.map +1 -0
  460. package/dist/custom-conversions-W3K33V33.js +125 -0
  461. package/dist/custom-conversions-W3K33V33.js.map +1 -0
  462. package/dist/customers-HYE7N2H5.js +56 -0
  463. package/dist/decide-YTHCBKM6.js +199 -0
  464. package/dist/decide-YTHCBKM6.js.map +1 -0
  465. package/dist/delete-64REPCY2.js +54 -0
  466. package/dist/delete-64REPCY2.js.map +1 -0
  467. package/dist/delete-AY3KL3N3.js +63 -0
  468. package/dist/delete-AY3KL3N3.js.map +1 -0
  469. package/dist/delete-DZUDLYPC.js +69 -0
  470. package/dist/delete-DZUDLYPC.js.map +1 -0
  471. package/dist/delete-NZGZP4YP.js +71 -0
  472. package/dist/delete-NZGZP4YP.js.map +1 -0
  473. package/dist/delete-VO2LZXE4.js +66 -0
  474. package/dist/delete-VO2LZXE4.js.map +1 -0
  475. package/dist/delete-VQMU56OH.js +71 -0
  476. package/dist/delete-VQMU56OH.js.map +1 -0
  477. package/dist/demographics-KOFLMGVW.js +138 -0
  478. package/dist/demographics-KOFLMGVW.js.map +1 -0
  479. package/dist/describe-JNTCQZNL.js +97 -0
  480. package/dist/describe-JNTCQZNL.js.map +1 -0
  481. package/dist/describe-MT4334NG.js +97 -0
  482. package/dist/describe-MT4334NG.js.map +1 -0
  483. package/dist/dimensions-FEZUJRAG.js +101 -0
  484. package/dist/dimensions-FEZUJRAG.js.map +1 -0
  485. package/dist/discard-H4RPXZHX.js +66 -0
  486. package/dist/discard-H4RPXZHX.js.map +1 -0
  487. package/dist/discover-4GD7QSF5.js +93 -0
  488. package/dist/discover-4GD7QSF5.js.map +1 -0
  489. package/dist/discover-L7OVXW4V.js +172 -0
  490. package/dist/discover-L7OVXW4V.js.map +1 -0
  491. package/dist/domain-HURQ23KR.js +98 -0
  492. package/dist/domain-HURQ23KR.js.map +1 -0
  493. package/dist/download-L27HWEOE.js +299 -0
  494. package/dist/download-L27HWEOE.js.map +1 -0
  495. package/dist/draft-25G2P2TE.js +281 -0
  496. package/dist/draft-25G2P2TE.js.map +1 -0
  497. package/dist/draft-5VH2PW3R.js +307 -0
  498. package/dist/draft-5VH2PW3R.js.map +1 -0
  499. package/dist/draft-D6UTKSAA.js +217 -0
  500. package/dist/draft-D6UTKSAA.js.map +1 -0
  501. package/dist/draft-KLULNBWP.js +233 -0
  502. package/dist/draft-KLULNBWP.js.map +1 -0
  503. package/dist/draft-MI7RWY2K.js +100 -0
  504. package/dist/draft-MI7RWY2K.js.map +1 -0
  505. package/dist/draft-P4IVYTY3.js +103 -0
  506. package/dist/draft-P4IVYTY3.js.map +1 -0
  507. package/dist/draft-UQYWDZS7.js +306 -0
  508. package/dist/draft-UQYWDZS7.js.map +1 -0
  509. package/dist/draft-YFAJHCKM.js +328 -0
  510. package/dist/draft-YFAJHCKM.js.map +1 -0
  511. package/dist/engine/index.d.ts +213 -127
  512. package/dist/engine/index.js +18 -4
  513. package/dist/{env-4P5HOGNA.js → env-FBTHZKGN.js} +12 -2
  514. package/dist/env-FBTHZKGN.js.map +1 -0
  515. package/dist/experiment-HDYTJPUY.js +1397 -0
  516. package/dist/experiment-HDYTJPUY.js.map +1 -0
  517. package/dist/export-TS5GYEMA.js +168 -0
  518. package/dist/export-TS5GYEMA.js.map +1 -0
  519. package/dist/extract-QVQFUOIK.js +113 -0
  520. package/dist/extract-QVQFUOIK.js.map +1 -0
  521. package/dist/facets-WYQUZMFJ.js +114 -0
  522. package/dist/facets-WYQUZMFJ.js.map +1 -0
  523. package/dist/favorites-7QP7BY5K.js +178 -0
  524. package/dist/favorites-7QP7BY5K.js.map +1 -0
  525. package/dist/feed-EETRO2FG.js +177 -0
  526. package/dist/feed-EETRO2FG.js.map +1 -0
  527. package/dist/feedback-SIMPRE37.js +66 -0
  528. package/dist/feedback-SIMPRE37.js.map +1 -0
  529. package/dist/feedback-record-L4MPIVML.js +177 -0
  530. package/dist/feedback-record-L4MPIVML.js.map +1 -0
  531. package/dist/fetch-DTBM3DE2.js +176 -0
  532. package/dist/fetch-DTBM3DE2.js.map +1 -0
  533. package/dist/fetch-Z7O3ZL4D.js +139 -0
  534. package/dist/fetch-Z7O3ZL4D.js.map +1 -0
  535. package/dist/find-KAQ6JDMO.js +134 -0
  536. package/dist/find-KAQ6JDMO.js.map +1 -0
  537. package/dist/fit-MY5GVZZZ.js +45 -0
  538. package/dist/fit-MY5GVZZZ.js.map +1 -0
  539. package/dist/flows-IUDXVDOS.js +247 -0
  540. package/dist/flows-IUDXVDOS.js.map +1 -0
  541. package/dist/follow-IX4XVK5Y.js +94 -0
  542. package/dist/follow-IX4XVK5Y.js.map +1 -0
  543. package/dist/follow-competitors-UZBUOYTH.js +112 -0
  544. package/dist/follow-competitors-UZBUOYTH.js.map +1 -0
  545. package/dist/following-VGOIUCIZ.js +113 -0
  546. package/dist/following-VGOIUCIZ.js.map +1 -0
  547. package/dist/fonts-EUDHI6CA.js +34 -0
  548. package/dist/fonts-EUDHI6CA.js.map +1 -0
  549. package/dist/forecast-BRSEH2H3.js +104 -0
  550. package/dist/forecast-BRSEH2H3.js.map +1 -0
  551. package/dist/forecast-QV4U7TOY.js +168 -0
  552. package/dist/forecast-QV4U7TOY.js.map +1 -0
  553. package/dist/funding-H5YO37OW.js +85 -0
  554. package/dist/funding-H5YO37OW.js.map +1 -0
  555. package/dist/funnel-JLF77MLF.js +394 -0
  556. package/dist/funnel-JLF77MLF.js.map +1 -0
  557. package/dist/ga4-YHJ2XMLC.js +55 -0
  558. package/dist/ga4-YHJ2XMLC.js.map +1 -0
  559. package/dist/generate-M2ZX5DMI.js +262 -0
  560. package/dist/generate-M2ZX5DMI.js.map +1 -0
  561. package/dist/get-4EYKCZ6F.js +59 -0
  562. package/dist/get-4EYKCZ6F.js.map +1 -0
  563. package/dist/get-637GALM2.js +63 -0
  564. package/dist/get-637GALM2.js.map +1 -0
  565. package/dist/get-AYX5HS64.js +56 -0
  566. package/dist/get-AYX5HS64.js.map +1 -0
  567. package/dist/get-AZARFR6O.js +61 -0
  568. package/dist/get-AZARFR6O.js.map +1 -0
  569. package/dist/get-EG2U7MIL.js +78 -0
  570. package/dist/get-EG2U7MIL.js.map +1 -0
  571. package/dist/get-N4BPOQCB.js +63 -0
  572. package/dist/get-N4BPOQCB.js.map +1 -0
  573. package/dist/get-RPZHLQ56.js +92 -0
  574. package/dist/get-RPZHLQ56.js.map +1 -0
  575. package/dist/gif-6PRTB2VR.js +94 -0
  576. package/dist/gif-6PRTB2VR.js.map +1 -0
  577. package/dist/google-52JRH7X3.js +136 -0
  578. package/dist/google-52JRH7X3.js.map +1 -0
  579. package/dist/google-ITTPCJ7N.js +3190 -0
  580. package/dist/google-ITTPCJ7N.js.map +1 -0
  581. package/dist/google-ads-U3JFFQLU.js +195 -0
  582. package/dist/google-ads-U3JFFQLU.js.map +1 -0
  583. package/dist/group-AAZ5QKC3.js +43 -0
  584. package/dist/group-AAZ5QKC3.js.map +1 -0
  585. package/dist/group-GSYCZORC.js +43 -0
  586. package/dist/group-GSYCZORC.js.map +1 -0
  587. package/dist/gsc-TS5T7ML2.js +30 -0
  588. package/dist/gsc-TS5T7ML2.js.map +1 -0
  589. package/dist/history-EW6LFFCX.js +67 -0
  590. package/dist/history-EW6LFFCX.js.map +1 -0
  591. package/dist/history-YTNCWSV3.js +133 -0
  592. package/dist/history-YTNCWSV3.js.map +1 -0
  593. package/dist/hubspot-LXWQNKKB.js +779 -0
  594. package/dist/hubspot-LXWQNKKB.js.map +1 -0
  595. package/dist/icon-K75KI6BV.js +137 -0
  596. package/dist/icon-K75KI6BV.js.map +1 -0
  597. package/dist/ideas-JJIHQFV4.js +35 -0
  598. package/dist/ideas-JJIHQFV4.js.map +1 -0
  599. package/dist/images-MWETBYKB.js +90 -0
  600. package/dist/images-MWETBYKB.js.map +1 -0
  601. package/dist/improve-L3BW4EQG.js +86 -0
  602. package/dist/improve-L3BW4EQG.js.map +1 -0
  603. package/dist/ingest-THFAV4NO.js +107 -0
  604. package/dist/ingest-THFAV4NO.js.map +1 -0
  605. package/dist/ingest-U6B7GR4A.js +23 -0
  606. package/dist/ingest-U6B7GR4A.js.map +1 -0
  607. package/dist/insights-FA6T6PT6.js +423 -0
  608. package/dist/insights-FA6T6PT6.js.map +1 -0
  609. package/dist/insights-PELVD4RY.js +122 -0
  610. package/dist/insights-PELVD4RY.js.map +1 -0
  611. package/dist/inspect-N2WVVWGP.js +189 -0
  612. package/dist/inspect-N2WVVWGP.js.map +1 -0
  613. package/dist/inspiration-Y2J2PUPC.js +53 -0
  614. package/dist/inspiration-Y2J2PUPC.js.map +1 -0
  615. package/dist/intent-YNAAVNHK.js +95 -0
  616. package/dist/intent-YNAAVNHK.js.map +1 -0
  617. package/dist/job-E2U4FS5P.js +202 -0
  618. package/dist/job-E2U4FS5P.js.map +1 -0
  619. package/dist/job-create-DFYCHVQ7.js +109 -0
  620. package/dist/job-create-DFYCHVQ7.js.map +1 -0
  621. package/dist/job-status-FFPMTSHB.js +74 -0
  622. package/dist/job-status-FFPMTSHB.js.map +1 -0
  623. package/dist/keep-GYZS2UTL.js +78 -0
  624. package/dist/keep-GYZS2UTL.js.map +1 -0
  625. package/dist/keyword-gap-4JKLWIBJ.js +130 -0
  626. package/dist/keyword-gap-4JKLWIBJ.js.map +1 -0
  627. package/dist/keyword-metrics-KU3OHTQK.js +197 -0
  628. package/dist/keyword-metrics-KU3OHTQK.js.map +1 -0
  629. package/dist/keywords-for-site-M4MFWMVK.js +128 -0
  630. package/dist/keywords-for-site-M4MFWMVK.js.map +1 -0
  631. package/dist/landing-7UVZ7IPP.js +28 -0
  632. package/dist/landing-7UVZ7IPP.js.map +1 -0
  633. package/dist/landings-F7LOAEJE.js +151 -0
  634. package/dist/landings-F7LOAEJE.js.map +1 -0
  635. package/dist/languages-PKYCZNUB.js +40 -0
  636. package/dist/languages-PKYCZNUB.js.map +1 -0
  637. package/dist/languages-XEJKTIFP.js +55 -0
  638. package/dist/languages-XEJKTIFP.js.map +1 -0
  639. package/dist/launches-TCFAYUA5.js +19 -0
  640. package/dist/launches-TCFAYUA5.js.map +1 -0
  641. package/dist/layerize-ZSKFIPZA.js +190 -0
  642. package/dist/layerize-ZSKFIPZA.js.map +1 -0
  643. package/dist/leads-CSRESOB2.js +293 -0
  644. package/dist/leads-CSRESOB2.js.map +1 -0
  645. package/dist/leads-MQPEA7DG.js +90 -0
  646. package/dist/leads-MQPEA7DG.js.map +1 -0
  647. package/dist/learn-K5YBUMBT.js +203 -0
  648. package/dist/learn-K5YBUMBT.js.map +1 -0
  649. package/dist/library-IP2UKNRU.js +109 -0
  650. package/dist/library-IP2UKNRU.js.map +1 -0
  651. package/dist/lighthouse-57XBJRCO.js +75 -0
  652. package/dist/lighthouse-57XBJRCO.js.map +1 -0
  653. package/dist/line-item-writes-73NR2J5L.js +208 -0
  654. package/dist/line-item-writes-73NR2J5L.js.map +1 -0
  655. package/dist/line-items-2YBGXOAQ.js +103 -0
  656. package/dist/line-items-2YBGXOAQ.js.map +1 -0
  657. package/dist/link-GVAWECJO.js +64 -0
  658. package/dist/link-GVAWECJO.js.map +1 -0
  659. package/dist/linkedin-PZDT22AT.js +1008 -0
  660. package/dist/linkedin-PZDT22AT.js.map +1 -0
  661. package/dist/list-6IKPWQGG.js +57 -0
  662. package/dist/list-6IKPWQGG.js.map +1 -0
  663. package/dist/list-CAUH3BMG.js +65 -0
  664. package/dist/list-CAUH3BMG.js.map +1 -0
  665. package/dist/list-FNDRV25Y.js +151 -0
  666. package/dist/list-FNDRV25Y.js.map +1 -0
  667. package/dist/list-GTOSN7DP.js +50 -0
  668. package/dist/list-GTOSN7DP.js.map +1 -0
  669. package/dist/list-HLJP4NVE.js +51 -0
  670. package/dist/list-HLJP4NVE.js.map +1 -0
  671. package/dist/list-LCUPF7EF.js +76 -0
  672. package/dist/list-LCUPF7EF.js.map +1 -0
  673. package/dist/list-REZGFWC5.js +63 -0
  674. package/dist/list-REZGFWC5.js.map +1 -0
  675. package/dist/list-S6MNXDTV.js +303 -0
  676. package/dist/list-S6MNXDTV.js.map +1 -0
  677. package/dist/locations-2BYWKIYA.js +67 -0
  678. package/dist/locations-2BYWKIYA.js.map +1 -0
  679. package/dist/locations-GJHHMV6Z.js +40 -0
  680. package/dist/locations-GJHHMV6Z.js.map +1 -0
  681. package/dist/log-HGDNLDUX.js +92 -0
  682. package/dist/log-HGDNLDUX.js.map +1 -0
  683. package/dist/logo-AJK2TDQU.js +18 -0
  684. package/dist/logo-AJK2TDQU.js.map +1 -0
  685. package/dist/lookup-H5GEM77H.js +22 -0
  686. package/dist/lookup-H5GEM77H.js.map +1 -0
  687. package/dist/make-BT26YJXZ.js +640 -0
  688. package/dist/make-BT26YJXZ.js.map +1 -0
  689. package/dist/map-J5EX4HOX.js +404 -0
  690. package/dist/map-J5EX4HOX.js.map +1 -0
  691. package/dist/mcp-MHDW6AFL.js +463 -0
  692. package/dist/mcp-MHDW6AFL.js.map +1 -0
  693. package/dist/media-RAGEJTZX.js +89 -0
  694. package/dist/media-RAGEJTZX.js.map +1 -0
  695. package/dist/media-RNB7JFJP.js +15 -0
  696. package/dist/media-RNB7JFJP.js.map +1 -0
  697. package/dist/media-sources-4NN3DWSG.js +32 -0
  698. package/dist/media-sources-4NN3DWSG.js.map +1 -0
  699. package/dist/members-AIWMXAQD.js +44 -0
  700. package/dist/members-AIWMXAQD.js.map +1 -0
  701. package/dist/meta-WAPZMZI7.js +69 -0
  702. package/dist/meta-WAPZMZI7.js.map +1 -0
  703. package/dist/metrics-6EHC4ESN.js +152 -0
  704. package/dist/metrics-6EHC4ESN.js.map +1 -0
  705. package/dist/models-5J4WFUD3.js +155 -0
  706. package/dist/models-5J4WFUD3.js.map +1 -0
  707. package/dist/normalize-DSFVTRXN.js +806 -0
  708. package/dist/normalize-DSFVTRXN.js.map +1 -0
  709. package/dist/normalize-ZAWN4XCS.js +141 -0
  710. package/dist/normalize-ZAWN4XCS.js.map +1 -0
  711. package/dist/options-3CZNT5KP.js +121 -0
  712. package/dist/options-3CZNT5KP.js.map +1 -0
  713. package/dist/output-DTCLVPUF.js +24 -0
  714. package/dist/output-DTCLVPUF.js.map +1 -0
  715. package/dist/page-N2ZO3O7F.js +105 -0
  716. package/dist/page-N2ZO3O7F.js.map +1 -0
  717. package/dist/pages-FQ4CBAJ2.js +66 -0
  718. package/dist/pages-FQ4CBAJ2.js.map +1 -0
  719. package/dist/performance-GOMJMHPE.js +24 -0
  720. package/dist/performance-GOMJMHPE.js.map +1 -0
  721. package/dist/pinterest-NV5XTNJE.js +96 -0
  722. package/dist/pinterest-NV5XTNJE.js.map +1 -0
  723. package/dist/pixels-CTJ43FZ4.js +108 -0
  724. package/dist/pixels-CTJ43FZ4.js.map +1 -0
  725. package/dist/pixels-HKINGZCH.js +60 -0
  726. package/dist/pixels-HKINGZCH.js.map +1 -0
  727. package/dist/plan-ZYTWLGWK.js +207 -0
  728. package/dist/plan-ZYTWLGWK.js.map +1 -0
  729. package/dist/preview-UKYLPAW2.js +169 -0
  730. package/dist/preview-UKYLPAW2.js.map +1 -0
  731. package/dist/profile-Q3PHR6FU.js +159 -0
  732. package/dist/profile-Q3PHR6FU.js.map +1 -0
  733. package/dist/promoted-tweet-writes-IYOAZTA5.js +180 -0
  734. package/dist/promoted-tweet-writes-IYOAZTA5.js.map +1 -0
  735. package/dist/promoted-tweets-G3XFD5YM.js +119 -0
  736. package/dist/promoted-tweets-G3XFD5YM.js.map +1 -0
  737. package/dist/properties-WLL6M2P6.js +101 -0
  738. package/dist/properties-WLL6M2P6.js.map +1 -0
  739. package/dist/publish-ZG4J2GTH.js +322 -0
  740. package/dist/publish-ZG4J2GTH.js.map +1 -0
  741. package/dist/query-7AGG77WH.js +61 -0
  742. package/dist/query-7AGG77WH.js.map +1 -0
  743. package/dist/query-IYZN5KHO.js +236 -0
  744. package/dist/query-IYZN5KHO.js.map +1 -0
  745. package/dist/query-UN2P6DBA.js +247 -0
  746. package/dist/query-UN2P6DBA.js.map +1 -0
  747. package/dist/questionnaire-Z2ZIKNBV.js +93 -0
  748. package/dist/questionnaire-Z2ZIKNBV.js.map +1 -0
  749. package/dist/read-GM7PQYJA.js +141 -0
  750. package/dist/read-GM7PQYJA.js.map +1 -0
  751. package/dist/reddit-FTO4SFQE.js +26 -0
  752. package/dist/reddit-FTO4SFQE.js.map +1 -0
  753. package/dist/refresh-OUENQ2FS.js +94 -0
  754. package/dist/refresh-OUENQ2FS.js.map +1 -0
  755. package/dist/release-5OG7AAFY.js +60 -0
  756. package/dist/release-5OG7AAFY.js.map +1 -0
  757. package/dist/relevant-pages-KUVDZPRU.js +99 -0
  758. package/dist/relevant-pages-KUVDZPRU.js.map +1 -0
  759. package/dist/remove-33HI27KM.js +50 -0
  760. package/dist/remove-33HI27KM.js.map +1 -0
  761. package/dist/remove-GOYW2G4R.js +48 -0
  762. package/dist/remove-GOYW2G4R.js.map +1 -0
  763. package/dist/reopen-KFFYE53A.js +63 -0
  764. package/dist/reopen-KFFYE53A.js.map +1 -0
  765. package/dist/rerun-P6XACA5Z.js +86 -0
  766. package/dist/rerun-P6XACA5Z.js.map +1 -0
  767. package/dist/research-BEO3JMZI.js +262 -0
  768. package/dist/research-BEO3JMZI.js.map +1 -0
  769. package/dist/research-QOC53DLS.js +62 -0
  770. package/dist/research-QOC53DLS.js.map +1 -0
  771. package/dist/reset-E3OWE2WF.js +54 -0
  772. package/dist/reset-E3OWE2WF.js.map +1 -0
  773. package/dist/reset-I7M3HYMB.js +54 -0
  774. package/dist/reset-I7M3HYMB.js.map +1 -0
  775. package/dist/resolve-GP7BHM6L.js +121 -0
  776. package/dist/resolve-GP7BHM6L.js.map +1 -0
  777. package/dist/retry-33ZJCNQI.js +62 -0
  778. package/dist/retry-33ZJCNQI.js.map +1 -0
  779. package/dist/retry-X5PU7QO3.js +60 -0
  780. package/dist/retry-X5PU7QO3.js.map +1 -0
  781. package/dist/retry-failed-BEFWRV4Z.js +45 -0
  782. package/dist/retry-failed-BEFWRV4Z.js.map +1 -0
  783. package/dist/run-REK3TEGY.js +65 -0
  784. package/dist/run-REK3TEGY.js.map +1 -0
  785. package/dist/run-TH2662IC.js +61 -0
  786. package/dist/run-TH2662IC.js.map +1 -0
  787. package/dist/scaffold-ad-3WDRKUFT.js +1550 -0
  788. package/dist/scaffold-ad-3WDRKUFT.js.map +1 -0
  789. package/dist/scaffold-static-ad-X5NT52NF.js +973 -0
  790. package/dist/scaffold-static-ad-X5NT52NF.js.map +1 -0
  791. package/dist/scaffold-video-WZPVACLE.js +874 -0
  792. package/dist/scaffold-video-WZPVACLE.js.map +1 -0
  793. package/dist/schedule-KQ7UIR3N.js +66 -0
  794. package/dist/schedule-KQ7UIR3N.js.map +1 -0
  795. package/dist/schedule-V4UHGY3V.js +61 -0
  796. package/dist/schedule-V4UHGY3V.js.map +1 -0
  797. package/dist/scheduled-agents-KLQ5H2PA.js +49 -0
  798. package/dist/scheduled-agents-KLQ5H2PA.js.map +1 -0
  799. package/dist/schema-G3T4PZDI.js +132 -0
  800. package/dist/schema-G3T4PZDI.js.map +1 -0
  801. package/dist/schema-QXTDLZVC.js +63 -0
  802. package/dist/schema-QXTDLZVC.js.map +1 -0
  803. package/dist/scrape-7YKJWFZE.js +2241 -0
  804. package/dist/scrape-7YKJWFZE.js.map +1 -0
  805. package/dist/screenshot-ZHBSG3SI.js +102 -0
  806. package/dist/screenshot-ZHBSG3SI.js.map +1 -0
  807. package/dist/search-332KFYZ6.js +224 -0
  808. package/dist/search-332KFYZ6.js.map +1 -0
  809. package/dist/search-4PBMXXUY.js +91 -0
  810. package/dist/search-4PBMXXUY.js.map +1 -0
  811. package/dist/search-6XKEGABN.js +174 -0
  812. package/dist/search-6XKEGABN.js.map +1 -0
  813. package/dist/search-AVNUU6TJ.js +26 -0
  814. package/dist/search-AVNUU6TJ.js.map +1 -0
  815. package/dist/search-F5INRFFK.js +92 -0
  816. package/dist/search-F5INRFFK.js.map +1 -0
  817. package/dist/search-copy-DZVBYG2B.js +168 -0
  818. package/dist/search-copy-DZVBYG2B.js.map +1 -0
  819. package/dist/seeds-5JTQN5WI.js +101 -0
  820. package/dist/seeds-5JTQN5WI.js.map +1 -0
  821. package/dist/select-N2V55BEX.js +96 -0
  822. package/dist/select-N2V55BEX.js.map +1 -0
  823. package/dist/sends-3L6QBS46.js +309 -0
  824. package/dist/sends-3L6QBS46.js.map +1 -0
  825. package/dist/sequences-YKFV7BDH.js +146 -0
  826. package/dist/sequences-YKFV7BDH.js.map +1 -0
  827. package/dist/set-prompt-7HVHERRU.js +188 -0
  828. package/dist/set-prompt-7HVHERRU.js.map +1 -0
  829. package/dist/setup-links-4VVNQVPU.js +141 -0
  830. package/dist/setup-links-4VVNQVPU.js.map +1 -0
  831. package/dist/{shared-AVM74EX7.js → shared-QAMP7FZV.js} +8 -6
  832. package/dist/shared-QAMP7FZV.js.map +1 -0
  833. package/dist/shopify-FSHM5M4I.js +3346 -0
  834. package/dist/shopify-FSHM5M4I.js.map +1 -0
  835. package/dist/site-Q2HTRLIW.js +177 -0
  836. package/dist/site-Q2HTRLIW.js.map +1 -0
  837. package/dist/sitemaps-XPGLW24S.js +87 -0
  838. package/dist/sitemaps-XPGLW24S.js.map +1 -0
  839. package/dist/sites-WMBY2HJV.js +101 -0
  840. package/dist/sites-WMBY2HJV.js.map +1 -0
  841. package/dist/skills-3HEILQCU.js +47 -0
  842. package/dist/skills-3HEILQCU.js.map +1 -0
  843. package/dist/sources-2KN4RJNJ.js +30 -0
  844. package/dist/sources-2KN4RJNJ.js.map +1 -0
  845. package/dist/sources-4I2YMS2K.js +421 -0
  846. package/dist/sources-4I2YMS2K.js.map +1 -0
  847. package/dist/stale-IN7WSBLC.js +66 -0
  848. package/dist/stale-IN7WSBLC.js.map +1 -0
  849. package/dist/stats-GNILHSKK.js +34 -0
  850. package/dist/stats-GNILHSKK.js.map +1 -0
  851. package/dist/status-6SLKZWNR.js +62 -0
  852. package/dist/status-6SLKZWNR.js.map +1 -0
  853. package/dist/sticker-KCV3VZHY.js +94 -0
  854. package/dist/sticker-KCV3VZHY.js.map +1 -0
  855. package/dist/stock-VTORKR4C.js +179 -0
  856. package/dist/stock-VTORKR4C.js.map +1 -0
  857. package/dist/studio-QCRA6BY5.js +49 -0
  858. package/dist/studio-QCRA6BY5.js.map +1 -0
  859. package/dist/sync-455DB46Y.js +54 -0
  860. package/dist/sync-455DB46Y.js.map +1 -0
  861. package/dist/sync-A4KKQ3B6.js +265 -0
  862. package/dist/sync-A4KKQ3B6.js.map +1 -0
  863. package/dist/sync-LFZV5NBN.js +54 -0
  864. package/dist/sync-LFZV5NBN.js.map +1 -0
  865. package/dist/sync-definition-IJISZ5VQ.js +55 -0
  866. package/dist/sync-definition-IJISZ5VQ.js.map +1 -0
  867. package/dist/tag-manager-E7QTXBWQ.js +43 -0
  868. package/dist/tag-manager-E7QTXBWQ.js.map +1 -0
  869. package/dist/tags-6OAZOQYO.js +26 -0
  870. package/dist/tags-6OAZOQYO.js.map +1 -0
  871. package/dist/tags-6YRMDX3R.js +20 -0
  872. package/dist/tags-6YRMDX3R.js.map +1 -0
  873. package/dist/tags-EWXZSZYE.js +20 -0
  874. package/dist/tags-EWXZSZYE.js.map +1 -0
  875. package/dist/tags-SZCNPE2D.js +224 -0
  876. package/dist/tags-SZCNPE2D.js.map +1 -0
  877. package/dist/tags-TCFFP534.js +20 -0
  878. package/dist/tags-TCFFP534.js.map +1 -0
  879. package/dist/targeting-constants-D64YO3E7.js +118 -0
  880. package/dist/targeting-constants-D64YO3E7.js.map +1 -0
  881. package/dist/targeting-criteria-ESOC7KNX.js +113 -0
  882. package/dist/targeting-criteria-ESOC7KNX.js.map +1 -0
  883. package/dist/targets-IPBEB5KU.js +102 -0
  884. package/dist/targets-IPBEB5KU.js.map +1 -0
  885. package/dist/templates-IJ7FR3LA.js +178 -0
  886. package/dist/templates-IJ7FR3LA.js.map +1 -0
  887. package/dist/testimonials-IXS7CP6P.js +32 -0
  888. package/dist/testimonials-IXS7CP6P.js.map +1 -0
  889. package/dist/themes-MXNKJWMW.js +94 -0
  890. package/dist/themes-MXNKJWMW.js.map +1 -0
  891. package/dist/top-companies-NO6L2V6M.js +108 -0
  892. package/dist/top-companies-NO6L2V6M.js.map +1 -0
  893. package/dist/translate-QCE5ZB7M.js +600 -0
  894. package/dist/translate-QCE5ZB7M.js.map +1 -0
  895. package/dist/triggers-KXUDMDSA.js +141 -0
  896. package/dist/triggers-KXUDMDSA.js.map +1 -0
  897. package/dist/tweets-ZUKQAAUQ.js +123 -0
  898. package/dist/tweets-ZUKQAAUQ.js.map +1 -0
  899. package/dist/unfollow-A4JVCJBF.js +46 -0
  900. package/dist/unfollow-A4JVCJBF.js.map +1 -0
  901. package/dist/unlink-E3N36NYQ.js +67 -0
  902. package/dist/unlink-E3N36NYQ.js.map +1 -0
  903. package/dist/unstage-TRMHSHED.js +84 -0
  904. package/dist/unstage-TRMHSHED.js.map +1 -0
  905. package/dist/unstage-ZRLLCSQF.js +95 -0
  906. package/dist/unstage-ZRLLCSQF.js.map +1 -0
  907. package/dist/update-EWGWAXAQ.js +142 -0
  908. package/dist/update-EWGWAXAQ.js.map +1 -0
  909. package/dist/update-OKOQE7U2.js +155 -0
  910. package/dist/update-OKOQE7U2.js.map +1 -0
  911. package/dist/update-VSFHID2D.js +63 -0
  912. package/dist/update-VSFHID2D.js.map +1 -0
  913. package/dist/update-XGCGQDJ4.js +98 -0
  914. package/dist/update-XGCGQDJ4.js.map +1 -0
  915. package/dist/upload-BOYMDDEQ.js +126 -0
  916. package/dist/upload-BOYMDDEQ.js.map +1 -0
  917. package/dist/upload-XEHWYMJG.js +150 -0
  918. package/dist/upload-XEHWYMJG.js.map +1 -0
  919. package/dist/upscale-I5P2OHTN.js +109 -0
  920. package/dist/upscale-I5P2OHTN.js.map +1 -0
  921. package/dist/url-options-PCZEQE66.js +130 -0
  922. package/dist/url-options-PCZEQE66.js.map +1 -0
  923. package/dist/url-params-DV37GEQF.js +98 -0
  924. package/dist/url-params-DV37GEQF.js.map +1 -0
  925. package/dist/use-U4HG2NF3.js +95 -0
  926. package/dist/use-U4HG2NF3.js.map +1 -0
  927. package/dist/validate-5AV4FJZ5.js +91 -0
  928. package/dist/validate-5AV4FJZ5.js.map +1 -0
  929. package/dist/variant-FOVE6URJ.js +338 -0
  930. package/dist/variant-FOVE6URJ.js.map +1 -0
  931. package/dist/videos-IJ67PPJV.js +39 -0
  932. package/dist/videos-IJ67PPJV.js.map +1 -0
  933. package/dist/view-HRI3FHCH.js +121 -0
  934. package/dist/view-HRI3FHCH.js.map +1 -0
  935. package/dist/viewer-check-JYUE24M6.js +68 -0
  936. package/dist/viewer-check-JYUE24M6.js.map +1 -0
  937. package/dist/web-LJ36FRWD.js +140 -0
  938. package/dist/web-LJ36FRWD.js.map +1 -0
  939. package/dist/winners-SMMDN6LW.js +113 -0
  940. package/dist/winners-SMMDN6LW.js.map +1 -0
  941. package/dist/winning-ads-JIG2MQHJ.js +84 -0
  942. package/dist/winning-ads-JIG2MQHJ.js.map +1 -0
  943. package/dist/write-commands-7Z34WG2J.js +206 -0
  944. package/dist/write-commands-7Z34WG2J.js.map +1 -0
  945. package/dist/write-commands-BLT2SEC4.js +713 -0
  946. package/dist/write-commands-BLT2SEC4.js.map +1 -0
  947. package/dist/write-commands-GOZU6ENR.js +1015 -0
  948. package/dist/write-commands-GOZU6ENR.js.map +1 -0
  949. package/dist/write-commands-KA3QXVSF.js +737 -0
  950. package/dist/write-commands-KA3QXVSF.js.map +1 -0
  951. package/dist/x-6HBVXIKH.js +47 -0
  952. package/dist/x-6HBVXIKH.js.map +1 -0
  953. package/package.json +9 -2
  954. package/dist/chunk-HJEMOSPH.js +0 -1292
  955. package/dist/chunk-HJEMOSPH.js.map +0 -1
  956. package/dist/chunk-JHKW6IDX.js +0 -9989
  957. package/dist/chunk-JHKW6IDX.js.map +0 -1
  958. package/dist/chunk-MF7YA62W.js.map +0 -1
  959. package/dist/chunk-VZEDAFAR.js.map +0 -1
  960. package/dist/chunk-WWCLT3RG.js.map +0 -1
  961. package/dist/client-GR6YL3YX.js +0 -17
  962. package/dist/output-VQSTVRH7.js +0 -18
  963. /package/dist/{chunk-JTZXQRXI.js.map → chunk-TPXI2GCW.js.map} +0 -0
  964. /package/dist/{client-GR6YL3YX.js.map → chunk-YQSBHWOI.js.map} +0 -0
  965. /package/dist/{env-4P5HOGNA.js.map → client-26SAJ46D.js.map} +0 -0
  966. /package/dist/{output-VQSTVRH7.js.map → connect-WYUYS5V4.js.map} +0 -0
  967. /package/dist/{shared-AVM74EX7.js.map → customers-HYE7N2H5.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/baker-child.ts","../src/commands/canvas/static-ad-canvas.ts","../src/commands/canvas/static-fix.ts","../src/commands/canvas/series-member.ts"],"sourcesContent":["/**\n * Another `baker` command run from this one, as a child process of the same CLI, read back by its\n * JSON answer: `creatives make` scaffolds through it, and `canvas run --series` renders each ad of\n * a series through it, all at once.\n */\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst run = promisify(execFile);\n\n/** The last JSON object a command printed, after any progress lines. Pure. */\nexport function lastJsonObject(stdout: string): Record<string, unknown> | null {\n for (let at = stdout.lastIndexOf(\"{\"); at >= 0; at = stdout.lastIndexOf(\"{\", at - 1)) {\n if (at > 0 && stdout[at - 1] !== \"\\n\") continue;\n try {\n const parsed: unknown = JSON.parse(stdout.slice(at));\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) return parsed as Record<string, unknown>;\n } catch {\n // Not the start of the final object: keep looking further back.\n }\n if (at === 0) break;\n }\n return null;\n}\n\n/** Run another `baker` command in this same CLI and read its JSON answer. */\nexport async function runBaker(args: string[], signal?: AbortSignal): Promise<Record<string, unknown>> {\n const entry = process.argv[1];\n const [file, argv] = entry ? [process.execPath, [...process.execArgv, entry, ...args]] : [\"baker\", args];\n try {\n const { stdout } = await run(file, argv, { maxBuffer: 32 * 1024 * 1024, ...(signal ? { signal } : {}) });\n return lastJsonObject(stdout) ?? { ok: false, error: { code: \"INTERNAL_ERROR\", message: \"no answer\" } };\n } catch (err) {\n // A scaffold reports its failure on stderr, other commands on stdout.\n const { stdout = \"\", stderr = \"\" } = err as { stdout?: string; stderr?: string };\n return (\n lastJsonObject(stdout) ??\n lastJsonObject(stderr) ?? {\n ok: false,\n error: { code: \"INTERNAL_ERROR\", message: err instanceof Error ? err.message.slice(0, 300) : String(err) },\n }\n );\n }\n}\n","import { STATIC_AD_ROLE } from \"../../engine/scaffold/static-render-briefs.ts\";\nimport { STATIC_VARIANTS_ROLE } from \"../../engine/scaffold/static-topology.ts\";\n\n/**\n * A static ad canvas, by role: an ingest tagged as the static ad's blueprint, or a node that\n * renders a static ad's variants. A canvas scaffolded by the overlay engine (a `compose_spec`\n * ingest) still counts, so a creative already in a client workspace reads as one until it is\n * re-scaffolded.\n */\nexport function isStaticAdCanvas(parsed: unknown): boolean {\n const nodes = (parsed as { nodes?: unknown } | null)?.nodes;\n if (!Array.isArray(nodes)) return false;\n return nodes.some((n) => {\n const role = (n as { tags?: { role?: unknown } } | null)?.tags?.role;\n if (role === STATIC_VARIANTS_ROLE) return true;\n return n?.type === \"ingest\" && (role === STATIC_AD_ROLE || n?.id === \"compose_spec\");\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { toModelSafeImage } from \"../../engine/nodes/ingest.ts\";\nimport type { VariantFile, VersionRun } from \"../../engine/scaffold/static-history.ts\";\nimport { NodeDecl } from \"../../engine/schema/canvas.ts\";\nimport { sha256Hex } from \"../../engine/storage/sha256.ts\";\nimport { fetchRunRecord } from \"./run-history.ts\";\n\nimport {\n rolesById,\n STATIC_ADAPT_FORMAT_ROLE,\n STATIC_FIX_ROLE,\n STATIC_MASTER_ROLE,\n STATIC_PICK_ROLE,\n STATIC_SAFE_FIT_ROLE,\n STATIC_SIZE_ROLE,\n STATIC_VARIANTS_ROLE,\n} from \"../../engine/scaffold/static-topology.ts\";\n\ntype Output = { url?: unknown; slot?: unknown; sha256?: unknown; path?: unknown };\n/** One node's outputs as a run keeps them: a list (`images`) or a single image, and its role when known. */\n/** A node's outputs by slot: a generation's `images`, a tool's `image`, an ingest's `asset`. */\ntype NodeOutputs = { images?: Output[]; image?: Output; asset?: Output; role?: string };\n\n/**\n * The finished ad a run chose, as the durable URL its record holds: its master (the chosen\n * picture before any logo is placed on it), or, on a run of the older graph, the judge's pick\n * or the lone take. Read from the local run folder first (`manifest.json`, outputs by node id,\n * given roles by `roles` — the canvas's), then from the company's run history (whose nodes\n * carry their roles), so a version rendered in another chat can be corrected too. Null when\n * the run is unknown or made no ad.\n */\nexport async function previousAdImage(\n canvasRoot: string,\n runId: string,\n fetchRecord: (\n runId: string,\n ) => Promise<{ nodes: Array<{ nodeId: string; role?: string; outputs: Output[] }> } | null> = fetchRunRecord,\n roles: Readonly<Record<string, string>> = {},\n): Promise<string | null> {\n try {\n const manifest = JSON.parse(await readFile(path.join(canvasRoot, runId, \"manifest.json\"), \"utf8\")) as {\n outputs_by_node?: Record<string, NodeOutputs>;\n };\n const byNode = Object.fromEntries(\n Object.entries(manifest.outputs_by_node ?? {}).map(([id, out]) => [id, { ...out, ...(roles[id] ? { role: roles[id] } : {}) }]),\n );\n const local = chosenUrl(byNode);\n if (local) return local;\n } catch {\n // Not rendered here: ask the run history.\n }\n const record = await fetchRecord(runId).catch(() => null);\n if (!record) return null;\n return chosenUrl(\n Object.fromEntries(\n record.nodes.map((n) => {\n const role = n.role ?? roles[n.nodeId];\n return [n.nodeId, { images: n.outputs, ...(role ? { role } : {}) }];\n }),\n ),\n );\n}\n\n/**\n * The sizes a run delivered (its `output` collect, `finalNode`), each with the format `labels`\n * gives it, from the local run folder: its local file, or its durable URL first (`prefer: \"url\"`).\n * Empty when the run was not rendered here.\n */\nexport async function previousDelivered(\n canvasRoot: string,\n runId: string,\n finalNode: string,\n labels: readonly (string | undefined)[],\n opts: { prefer?: \"url\" } = {},\n): Promise<Array<{ format: string; path: string }>> {\n try {\n const manifest = JSON.parse(await readFile(path.join(canvasRoot, runId, \"manifest.json\"), \"utf8\")) as {\n outputs_by_node?: Record<string, NodeOutputs>;\n };\n const images = manifest.outputs_by_node?.[finalNode]?.images ?? [];\n return images.flatMap((image, i) => {\n const local = typeof image.path === \"string\" ? image.path : null;\n const durable = typeof image.url === \"string\" ? image.url : null;\n const source = opts.prefer === \"url\" ? (durable ?? local) : (local ?? durable);\n const format = labels[i];\n return source && format ? [{ format, path: source }] : [];\n });\n } catch {\n return [];\n }\n}\n\n/** Which node holds the chosen ad, best first: by role on the one-picture graph, by id on an older one. */\nconst CHOSEN: ReadonlyArray<(id: string, out: NodeOutputs) => boolean> = [\n (_, out) => out.role === STATIC_MASTER_ROLE,\n (_, out) => out.role === STATIC_PICK_ROLE,\n (_, out) => out.role === STATIC_FIX_ROLE,\n (id, out) => id === \"pick\" && out.role === undefined,\n (id, out) => id === \"ad\" && out.role === undefined,\n];\n\nfunction urlOf(out: NodeOutputs): string | null {\n const url = out.images?.find((o) => typeof o?.url === \"string\")?.url ?? out.image?.url ?? out.asset?.url;\n return typeof url === \"string\" ? url : null;\n}\n\n/** The chosen ad among a run's node outputs (see `previousAdImage`). Never a variant the judge did not keep. Pure. */\nexport function chosenUrl(byNode: Record<string, NodeOutputs>): string | null {\n const entries = Object.entries(byNode).filter(([, out]) => out.role !== STATIC_VARIANTS_ROLE);\n for (const matches of CHOSEN) {\n for (const [id, out] of entries) {\n if (!matches(id, out)) continue;\n const url = urlOf(out);\n if (url) return url;\n }\n }\n return null;\n}\n\n/**\n * The picture a correction (`--fix`) or a person's choice (`--use-variant`) put in place of the\n * variants, the input its master was made from. Null for a plain render: the scaffolded graph\n * already reaches that picture through its own cache. Ids are the ones `fixStaticAd` and\n * `rederiveFromVariant` give those nodes; a run record also carries the correction's role. Pure.\n */\nexport function correctedUrl(byNode: Record<string, NodeOutputs>): string | null {\n // A version grown on top of others (`static-history.ts`) keeps every correction: it shows its last.\n // `fix` and `chosen` never share a graph with an `edit_<n>`: a chosen variant drops the edits before it.\n const editNumber = (id: string) => Number(id.match(/^edit_(\\d+)$/)?.[1] ?? 0);\n const entries = Object.entries(byNode).sort(([a], [b]) => editNumber(b) - editNumber(a));\n for (const [id, out] of entries) {\n if (id === \"fix\" || id === \"chosen\" || out.role === STATIC_FIX_ROLE) {\n const url = urlOf(out);\n if (url) return url;\n }\n }\n return null;\n}\n\n/** A run as the run history keeps it: each node's recorded outputs, and where the graph it ran is kept. */\ntype RecordedRun = {\n graphUrl?: string;\n nodes: ReadonlyArray<{ nodeId: string; outputs: ReadonlyArray<Record<string, unknown>> }>;\n};\n\ntype VersionSources = {\n record: (runId: string) => Promise<RecordedRun | null>;\n graph: (url: string) => Promise<unknown>;\n};\n\nasync function fetchGraph(url: string): Promise<unknown> {\n const res = await fetch(url);\n return res.ok ? res.json() : null;\n}\n\nconst HISTORY: VersionSources = { record: fetchRunRecord, graph: fetchGraph };\n\n/** The graph a version ran, as its manifest or the run history keeps it. */\nconst VersionGraph = z.object({ nodes: z.array(NodeDecl) });\n/** The part of a run's manifest a version grows from: the graph it ran and every node's outputs. */\nconst VersionManifest = z.object({\n canvas: VersionGraph,\n outputs_by_node: z.record(z.string(), z.record(z.string(), z.unknown())),\n});\n\n/**\n * The graph run `runId` ran and every node's outputs, so the next version can be grown on top of\n * it (`growFromVersion`): from its run folder here, else, for a version rendered in another\n * workspace (\"Edit creative …\" from a new chat), from the run history and the graph it kept. Null\n * when neither has it (a run recorded before graphs were kept): the caller corrects by URL.\n */\nexport async function versionRun(\n canvasRoot: string,\n runId: string,\n sources: VersionSources = HISTORY,\n): Promise<VersionRun | null> {\n try {\n const manifest = VersionManifest.safeParse(JSON.parse(await readFile(path.join(canvasRoot, runId, \"manifest.json\"), \"utf8\")));\n if (manifest.success) return { canvas: manifest.data.canvas, outputs: manifest.data.outputs_by_node };\n } catch {\n // Not rendered here: ask the run history.\n }\n const record = await sources.record(runId).catch(() => null);\n const graph = record?.graphUrl ? await sources.graph(record.graphUrl).catch(() => null) : null;\n const canvas = VersionGraph.safeParse(graph);\n return record && canvas.success ? { canvas: canvas.data, outputs: outputsByNode(record.nodes) } : null;\n}\n\n/**\n * What each workspace file the variants read is ingested as now, by node id (`makesSameVariants`):\n * the sha256 of its bytes, and for a picture also of the raster the ingest makes it into (an SVG\n * logo is ingested as a PNG). A file that cannot be read matches nothing.\n */\nexport async function ingestedNow(files: readonly VariantFile[], canvasDir: string): Promise<Record<string, string[]>> {\n const entries = await Promise.all(\n files.map(async (file): Promise<[string, string[]]> => {\n const bytes = await readFile(path.resolve(canvasDir, file.path)).catch(() => null);\n if (!bytes) return [file.id, []];\n const own = sha256Hex(bytes);\n if (file.expect !== \"image\") return [file.id, [own]];\n const raster = await toModelSafeImage(bytes).catch(() => null);\n return [file.id, raster ? [...new Set([own, sha256Hex(raster.bytes)])] : [own]];\n }),\n );\n return Object.fromEntries(entries);\n}\n\n/**\n * Each node's outputs as the engine hands them on, from the run record's flat list: `images#1`\n * back into `images[1]`, `image` as it is, each an asset ref. A node that recorded none is left out.\n * Pure.\n */\nfunction outputsByNode(nodes: RecordedRun[\"nodes\"]): Record<string, Record<string, unknown>> {\n const byNode: Record<string, Record<string, unknown>> = {};\n for (const node of nodes) {\n const outputs: Record<string, unknown> = {};\n for (const out of node.outputs) {\n const [slot = \"\", index] = String(out.slot ?? \"\").split(\"#\");\n const { slot: _slot, label: _label, durationMs, ...ref } = out;\n const asset = { ...ref, ...(typeof durationMs === \"number\" ? { duration_ms: durationMs } : {}) };\n if (index === undefined) outputs[slot] = asset;\n else {\n const list = (Array.isArray(outputs[slot]) ? outputs[slot] : []) as unknown[];\n list[Number(index)] = asset;\n outputs[slot] = list;\n }\n }\n if (Object.keys(outputs).length > 0) byNode[node.nodeId] = outputs;\n }\n return byNode;\n}\n\n/**\n * `correctedUrl` of a run: the local run folder first, then the company's run history, so a\n * version corrected in another chat is found too. Null for a plain render or an unknown run.\n */\nexport async function correctedPicture(\n canvasRoot: string,\n runId: string,\n fetchRecord: (\n runId: string,\n ) => Promise<{ nodes: Array<{ nodeId: string; role?: string; outputs: Output[] }> } | null> = fetchRunRecord,\n): Promise<string | null> {\n try {\n const manifest = JSON.parse(await readFile(path.join(canvasRoot, runId, \"manifest.json\"), \"utf8\")) as {\n outputs_by_node?: Record<string, NodeOutputs>;\n };\n if (manifest.outputs_by_node) return correctedUrl(manifest.outputs_by_node);\n } catch {\n // Not rendered here: ask the run history.\n }\n const record = await fetchRecord(runId).catch(() => null);\n if (!record) return null;\n return correctedUrl(\n Object.fromEntries(record.nodes.map((n) => [n.nodeId, { images: n.outputs, ...(n.role ? { role: n.role } : {}) }])),\n );\n}\n\n/**\n * How a version's picture came to be, where its canvas alone would not say: `chosen`, the person\n * picked it (`--use-variant`), so it is only ever corrected, never replaced, through every fix and\n * re-layout of it; `redrawn`, a new picture told what the last one got wrong (an autofix round),\n * which the scaffolded graph would not draw again.\n */\nexport type PictureRecord = { runId: string; chosen?: true; redrawn?: true };\n\n/**\n * The record of run `runId`'s picture: `chose`, the person picked it now; `keeps`, the run kept the\n * picture of version `from` (a fix, an edit, a re-layout), whose record `of` is. Pure.\n */\nexport function pictureRecord(\n runId: string,\n opts: { chose?: boolean; of?: PictureRecord | undefined; from?: string | undefined; keeps?: boolean; redrawn?: boolean },\n): PictureRecord {\n const chosen = opts.chose === true || (opts.keeps === true && keepsChosen(opts.of, opts.from));\n return { runId, ...(chosen ? { chosen: true as const } : {}), ...(opts.redrawn ? { redrawn: true as const } : {}) };\n}\n\n/** Whether version `from` shows a picture the person chose. Pure. */\nexport function keepsChosen(picture: PictureRecord | undefined, from: string | undefined): boolean {\n return picture?.chosen === true && from !== undefined && picture.runId === from;\n}\n\n/**\n * Whether `--regenerate` forces only re-laid-out sizes (their fills and safe fits): work that must start\n * from the picture the version already shows, never from new variants. Pure.\n */\nexport function relaysSizesOnly(canvas: unknown, ids: readonly string[]): boolean {\n const roles = rolesById(canvas);\n const sizing = new Set([STATIC_ADAPT_FORMAT_ROLE, STATIC_SIZE_ROLE, STATIC_SAFE_FIT_ROLE]);\n return ids.length > 0 && ids.every((id) => sizing.has(roles[id] ?? \"\"));\n}\n\n/** A sha256 or a unique prefix of one (at least 8 hex characters). */\nconst SHA_PREFIX = /^[0-9a-f]{8,64}$/;\n\n/** The URL of the variant whose sha256 starts with `sha` among one node's outputs; null when none or several match. */\nfunction matchVariant(outputs: readonly Output[], sha: string): string | null {\n const hits = outputs.filter((o) => typeof o?.sha256 === \"string\" && o.sha256.startsWith(sha) && typeof o.url === \"string\");\n const urls = [...new Set(hits.map((o) => o.url as string))];\n return urls.length === 1 ? (urls[0] as string) : null;\n}\n\n/**\n * The durable URL of the variant to make every size from instead of the judge's pick (`--use-variant`),\n * found by its sha256 among the run's variants, never by position: the local run folder first\n * (its outputs keyed by node id, given roles by `roles`), then the run history. Null when the\n * run or the variant is unknown.\n */\nexport async function variantImage(\n canvasRoot: string,\n runId: string,\n sha256: string,\n fetchRecord: (\n runId: string,\n ) => Promise<{ nodes: Array<{ nodeId: string; role?: string; outputs: Output[] }> } | null> = fetchRunRecord,\n roles: Readonly<Record<string, string>> = {},\n): Promise<string | null> {\n const sha = sha256.trim().toLowerCase();\n if (!SHA_PREFIX.test(sha)) return null;\n try {\n const manifest = JSON.parse(await readFile(path.join(canvasRoot, runId, \"manifest.json\"), \"utf8\")) as {\n outputs_by_node?: Record<string, NodeOutputs>;\n };\n for (const [id, out] of Object.entries(manifest.outputs_by_node ?? {})) {\n if (roles[id] !== STATIC_VARIANTS_ROLE) continue;\n const url = matchVariant(out.images ?? [], sha);\n if (url) return url;\n }\n } catch {\n // Not rendered here: ask the run history.\n }\n const record = await fetchRecord(runId).catch(() => null);\n const variants = record?.nodes.find((n) => n.role === STATIC_VARIANTS_ROLE);\n return variants ? matchVariant(variants.outputs, sha) : null;\n}\n","/**\n * An ad of a series, on disk: `src/creatives/<slug>/` holds its own words (`prompt.json`) and a\n * `_definition.md` naming its lead (`series: <lead>`); its canvas is written from the lead's,\n * every run, as an edit of the lead's ready version (`seriesMemberAd`). The ad never designs a\n * picture of its own, so ten messages in one style come out as one ad ten times.\n */\nimport { existsSync } from \"node:fs\";\nimport { readdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { CreativesRunData } from \"@baker/api\";\nimport { isAdSpec, readAdSpec } from \"../../engine/scaffold/static-ad-spec.ts\";\nimport { isCustomersWords, isSignatureLine } from \"../../engine/scaffold/static-proof.ts\";\nimport { sameTag } from \"../../language.ts\";\nimport { formatOfAdaptId } from \"../../engine/scaffold/static-adapt-briefs.ts\";\nimport {\n nodesWithRole,\n relaidPictureRole,\n rolesById,\n STATIC_ADAPT_FORMAT_ROLE,\n} from \"../../engine/scaffold/static-topology.ts\";\nimport { type SeriesLead, seriesMemberAd } from \"../../engine/scaffold/staticAd.ts\";\nimport { parseDefinitionStrategyFields } from \"./creative-definition.ts\";\nimport { localPathParam } from \"./resolve-paths.ts\";\nimport { readRenderState } from \"./render-state.ts\";\nimport { fetchRunRecord } from \"./run-history.ts\";\nimport { finalOutputLabelsFromCanvas } from \"./run-record.ts\";\nimport { isStaticAdCanvas } from \"./static-ad-canvas.ts\";\nimport { previousAdImage, previousDelivered } from \"./static-fix.ts\";\n\n/** Why a series ad cannot be made yet: what to tell the agent, and what to do. */\nexport type SeriesRefusal = { refused: { code: string; message: string; fix: string } };\n\ntype Fetch = (runId: string) => Promise<CreativesRunData | null>;\n\nconst creativeDir = (root: string, slug: string) => path.join(root, \"src\", \"creatives\", slug);\nconst canvasFile = (root: string, slug: string) => path.join(creativeDir(root, slug), `${slug}.canvas.json`);\n\n/** What a creative's `_definition.md` says of its series: its lead (`series:`) and the language its words are in. */\nasync function seriesFieldsOf(root: string, slug: string): Promise<{ seriesLead?: string; language?: string }> {\n const raw = await readFile(path.join(creativeDir(root, slug), \"_definition.md\"), \"utf8\").catch(() => null);\n return raw === null ? {} : parseDefinitionStrategyFields(raw);\n}\n\n/** The lead a creative's `_definition.md` names (`series:`); null when it is no ad of a series. */\nexport async function seriesLeadOf(root: string, slug: string): Promise<string | null> {\n return (await seriesFieldsOf(root, slug)).seriesLead ?? null;\n}\n\n/** The language a translation's words are in: its own, when it is not its lead's. Undefined on any other ad. */\nasync function translatedInto(root: string, slug: string, lead: string): Promise<string | undefined> {\n const own = (await seriesFieldsOf(root, slug)).language;\n const leads = (await seriesFieldsOf(root, lead)).language;\n return own && !(leads && sameTag(own, leads)) ? own : undefined;\n}\n\n/** How many leads up a series may chain: a design, its angle ads, their translations. */\nexport const SERIES_DEPTH = 3;\n\n/**\n * The leads above `slug`, nearest first, up to the ad whose design the whole series has (an angle\n * ad, then the design it was made from). Bounded and cycle-safe; empty for an ad in no series.\n */\nexport async function seriesLeadsAbove(root: string, slug: string): Promise<string[]> {\n const leads: string[] = [];\n let at = await seriesLeadOf(root, slug);\n while (at && at !== slug && !leads.includes(at) && leads.length < SERIES_DEPTH) {\n leads.push(at);\n at = await seriesLeadOf(root, at);\n }\n return leads;\n}\n\n/** Every ad of the series led by `lead`, by slug, in folder order. */\nexport async function seriesMembers(root: string, lead: string): Promise<string[]> {\n const slugs = await readdir(path.join(root, \"src\", \"creatives\")).catch(() => [] as string[]);\n const members: string[] = [];\n for (const slug of slugs.sort()) {\n if (slug !== lead && (await seriesLeadOf(root, slug)) === lead) members.push(slug);\n }\n return members;\n}\n\nfunction refusal(code: string, message: string, fix: string): SeriesRefusal {\n return { refused: { code, message, fix } };\n}\n\n/**\n * The lead's ready version: the one this workspace shows (its render state), its words as that\n * render drew them, its chosen picture and every size it delivered. A lead never rendered, or\n * whose version still needs fixes, is refused: every ad of the series copies it.\n */\nexport async function leadVersion(\n root: string,\n lead: string,\n fetchRecord: Fetch = fetchRunRecord,\n): Promise<{ lead: SeriesLead; canvas: unknown; spec: unknown } | SeriesRefusal> {\n const file = canvasFile(root, lead);\n const canvas: unknown = existsSync(file) ? JSON.parse(await readFile(file, \"utf8\")) : null;\n if (!canvas || !isStaticAdCanvas(canvas)) {\n return refusal(\n \"series_lead_not_found\",\n `The lead ad \"${lead}\" is not a static ad in this workspace.`,\n \"Name a static ad of this workspace as the lead: make it with `baker creatives make <idea>` and render it first.\",\n );\n }\n const canvasRoot = path.join(root, \"canvas\");\n const state = await readRenderState(canvasRoot, lead);\n const runId = state.rendered?.runId;\n if (!runId) {\n return refusal(\n \"series_lead_not_rendered\",\n `The lead ad \"${lead}\" has no finished version yet: every ad of its series is made from it.`,\n `Render the lead first and get it ready: baker canvas run --slug ${lead}. Then make the series.`,\n );\n }\n if ((state.blocking ?? []).length > 0) {\n return refusal(\n \"series_lead_not_ready\",\n `The lead ad \"${lead}\" still needs fixes (${(state.blocking ?? []).join(\" | \")}): the series would copy them.`,\n `Correct the lead until its verdict is ready (baker canvas run --slug ${lead}, or --fix \"<what to change>\"), then run the series again.`,\n );\n }\n const record = (): Promise<CreativesRunData | null> => fetchRecord(runId).catch(() => null);\n const picture = await previousAdImage(canvasRoot, runId, record, { ...rolesById(canvas), ...relaidPictureRole(canvas) });\n const sizes = await deliveredSizes(canvasRoot, runId, canvas, record);\n if (!picture) {\n return refusal(\n \"series_lead_not_rendered\",\n `The finished picture of the lead's version (${runId}) is not available.`,\n `Render the lead again (baker canvas run --slug ${lead}), then run the series.`,\n );\n }\n const drawn = state.prompt ?? JSON.parse(await readFile(path.join(creativeDir(root, lead), \"prompt.json\"), \"utf8\"));\n const copy = readAdSpec(drawn).copy.map((l) => ({ text: l.text, ...(l.role ? { role: l.role } : {}) }));\n return { lead: { slug: lead, runId, copy, picture, sizes }, canvas, spec: drawn };\n}\n\n/** Each re-laid-out size the lead's version delivered, by format: its local run folder first, else its record. */\nasync function deliveredSizes(\n canvasRoot: string,\n runId: string,\n canvas: unknown,\n record: () => Promise<CreativesRunData | null>,\n): Promise<Record<string, string>> {\n const wanted = new Set(nodesWithRole(canvas, STATIC_ADAPT_FORMAT_ROLE).flatMap((n) => formatOfAdaptId(n.id) ?? []));\n const labels = finalOutputLabelsFromCanvas(canvas);\n const local = await previousDelivered(canvasRoot, runId, labels?.nodeId ?? \"final\", labels?.labels ?? [], {\n prefer: \"url\",\n });\n const found = local.length > 0 ? local : ((await record())?.finalOutputs ?? []).flatMap((o) =>\n o.label && o.url ? [{ format: o.label, path: o.url }] : [],\n );\n return Object.fromEntries(found.filter((d) => wanted.has(d.format)).map((d) => [d.format, d.path]));\n}\n\n/**\n * The lead's canvas with its local paths read from the member's folder: the brand's font and\n * logo are the same files, the member's own `prompt.json` stays its own. Pure.\n */\nexport function rebaseLeadPaths<T>(canvas: T, leadDir: string, memberDir: string): T {\n const out = structuredClone(canvas) as { nodes?: Array<{ id?: unknown; type?: unknown; params?: Record<string, unknown> }> };\n for (const node of out.nodes ?? []) {\n const key = localPathParam(node);\n const value = key ? node.params?.[key] : undefined;\n if (!key || !node.params || typeof value !== \"string\" || node.id === \"prompt\" || path.isAbsolute(value)) continue;\n const rel = path.relative(memberDir, path.resolve(leadDir, value)).split(path.sep).join(\"/\");\n node.params[key] = rel.startsWith(\".\") ? rel : `./${rel}`;\n }\n return out as T;\n}\n\n/** What every ad of a series shares with its lead: everything in prompt.json but its words and who it speaks to. */\nconst DESIGN_FIELDS = [\n \"scene\",\n \"brand\",\n \"colors\",\n \"references\",\n \"logo\",\n \"logo_position\",\n \"third_party_brands\",\n \"formats\",\n \"direction\",\n] as const;\n\n/** The design a spec draws, as one comparable string; null when it does not read as an ad spec. Pure. */\nexport function seriesDesignOf(spec: unknown): string | null {\n try {\n const read = readAdSpec(spec) as Record<string, unknown>;\n return JSON.stringify(DESIGN_FIELDS.map((key) => read[key] ?? null));\n } catch {\n return null;\n }\n}\n\n/** `memberSpec` with the lead's design and its own words, viewer and message. Pure. */\nfunction withLeadDesign(memberSpec: unknown, leadSpec: unknown): Record<string, unknown> {\n // An older blueprint names its design in its own shape: each is taken as the ad spec it reads as.\n const asSpec = (spec: unknown): Record<string, unknown> =>\n isAdSpec(spec) ? (spec as Record<string, unknown>) : readAdSpec(spec);\n const lead = asSpec(leadSpec);\n const out = { ...asSpec(memberSpec) };\n for (const key of DESIGN_FIELDS) {\n if (key in lead) out[key] = lead[key];\n else delete out[key];\n }\n return out;\n}\n\n/** A series ad whose words are still the lead's renders the lead again: refused before anything bills. Pure. */\nexport function unchangedCopyRefusal(lead: SeriesLead, memberSpec: unknown): SeriesRefusal | null {\n const words = (copy: ReadonlyArray<{ text: string }>) => copy.map((l) => l.text.trim()).join(\"\\n\");\n let copy: ReadonlyArray<{ text: string }>;\n try {\n copy = readAdSpec(memberSpec).copy;\n } catch {\n return null;\n }\n if (words(copy) !== words(lead.copy)) return null;\n return refusal(\n \"series_copy_unchanged\",\n `This ad's words are still the lead's (\"${lead.copy[0]?.text ?? \"\"}\"): it would render the lead again.`,\n \"Write this ad's own words in its prompt.json `copy`, one line for each of the lead's (same roles), saying this ad's message. Keep everything else: the design is the lead's.\",\n );\n}\n\n/**\n * A translation whose lines the lead holds as a customer's words (a quote, signed by its shape or\n * its role, or by a signature on the line below) are not those words as the lead has them: the\n * translation puts words the customer never said under their name. Null when every one is kept. Pure.\n */\nexport function changedCustomerWordsRefusal(lead: SeriesLead, memberSpec: unknown): SeriesRefusal | null {\n let copy: ReadonlyArray<{ text: string }>;\n try {\n copy = readAdSpec(memberSpec).copy;\n } catch {\n return null;\n }\n const said = new Set(copy.map((l) => l.text.trim()));\n const changed = lead.copy.filter((line, i) => {\n const below = lead.copy[i + 1];\n const theirs = isCustomersWords(line) || (below !== undefined && isSignatureLine(below));\n return theirs && !said.has(line.text.trim());\n });\n if (changed.length === 0) return null;\n return refusal(\n \"series_customer_words_changed\",\n `This translation changed a customer's own words: ${changed.map((l) => `\"${l.text}\"`).join(\", \")} is how they said it, and translated it would be words they never said under their name.`,\n `Put ${changed.length === 1 ? \"that line\" : \"those lines\"} back in this ad's prompt.json exactly as the lead has ${changed.length === 1 ? \"it\" : \"them\"}: ${changed.map((l) => `\"${l.text}\"`).join(\", \")}. Translate only the advertiser's own lines.`,\n );\n}\n\n/**\n * A design edited on an ad of a series: it is made once, on the ad whose design the whole series\n * has (the last of `leads`), then carried down each series run, the farthest first. Pure.\n */\nexport function designChangedRefusal(lead: string, leads: readonly string[]): SeriesRefusal {\n const chain = leads.length > 0 ? leads : [lead];\n const design = chain[chain.length - 1] ?? lead;\n const runs = [...chain].reverse().map((l) => `baker canvas run --series ${l}`);\n return refusal(\n \"series_design_changed\",\n `This ad's design (its scene, colours, pictures or logo in prompt.json) was changed on the ad itself, but every ad of the series has the design of \"${design}\".`,\n `Make the change once, on ${design}: edit src/creatives/${design}/prompt.json (or baker canvas run --slug ${design} --fix \"<the change>\"), then ${runs.join(\", then \")}: every ad takes the new design, its own words kept. Only this ad's copy belongs in its own prompt.json.`,\n );\n}\n\n/**\n * Write the canvas of series ad `slug` from its lead's ready version. Null when `slug` is no ad\n * of a series; a refusal when its lead is not ready or its words are still the lead's (allowed\n * only when the ad is first made, before its words are written: `leadWords`).\n */\nexport async function writeSeriesMemberCanvas(\n root: string,\n slug: string,\n opts: { fetchRecord?: Fetch; leadWords?: boolean; takeLeadDesign?: boolean } = {},\n): Promise<\n | {\n lead: string;\n leadRunId: string;\n canvasPath: string;\n written: boolean;\n designFromLead: boolean;\n /** The ad was last made from an older version of its lead: this run is a new version of the ad. */\n newLeadVersion: boolean;\n }\n | SeriesRefusal\n | null\n> {\n const lead = await seriesLeadOf(root, slug);\n if (!lead) return null;\n const version = await leadVersion(root, lead, opts.fetchRecord);\n if (\"refused\" in version) return version;\n const dir = creativeDir(root, slug);\n const promptPath = path.join(dir, \"prompt.json\");\n let memberSpec = JSON.parse(await readFile(promptPath, \"utf8\").catch(() => \"null\"));\n const unchanged = opts.leadWords ? null : unchangedCopyRefusal(version.lead, memberSpec);\n if (unchanged) return unchanged;\n const language = await translatedInto(root, slug, lead);\n const rewritten = language ? changedCustomerWordsRefusal(version.lead, memberSpec) : null;\n if (rewritten) return rewritten;\n const file = canvasFile(root, slug);\n const before = await readFile(file, \"utf8\").catch(() => null);\n // The design is the lead's. A new version of the lead carries it to an ad untouched since; a\n // design edited on the ad itself is refused, unless the series run is asked to take the lead's back.\n const leadDesign = seriesDesignOf(version.spec);\n const ownDesign = seriesDesignOf(memberSpec);\n const previous = before\n ? (JSON.parse(before) as { metadata?: { series?: { design?: string; run_id?: string } } }).metadata?.series\n : undefined;\n const synced = previous?.design;\n let designFromLead = false;\n if (leadDesign !== null && ownDesign !== null && ownDesign !== leadDesign) {\n if (!opts.takeLeadDesign && ownDesign !== synced) {\n return designChangedRefusal(lead, await seriesLeadsAbove(root, slug));\n }\n memberSpec = withLeadDesign(memberSpec, version.spec);\n await writeFile(promptPath, `${JSON.stringify(memberSpec, null, 2)}\\n`, \"utf8\");\n designFromLead = true;\n }\n const canvas = seriesMemberAd(\n rebaseLeadPaths(version.canvas, creativeDir(root, lead), dir),\n { ...version.lead, ...(leadDesign !== null ? { design: leadDesign } : {}) },\n language ? { language } : {},\n );\n const text = `${JSON.stringify(canvas, null, 2)}\\n`;\n if (before !== text) await writeFile(file, text, \"utf8\");\n const madeFrom = (await readRenderState(path.join(root, \"canvas\"), slug)).seriesLeadRun;\n const newLeadVersion = madeFrom !== undefined && madeFrom !== version.lead.runId;\n return { lead, leadRunId: version.lead.runId, canvasPath: file, written: before !== text, designFromLead, newLeadVersion };\n}\n\n/**\n * What a run of an ad of a series, or of its lead, says to do next: a new version of the lead\n * reaches the series only through a series run, and a change to the design every ad shares is\n * made once, on the lead. Empty for an ad in no series. Pure.\n */\nexport function seriesRunHints(\n slug: string,\n series: { lead?: string | null; leads?: readonly string[]; members: readonly string[] },\n): string[] {\n // Nearest lead first: a translation of an angle ad takes its design from the ad at the top.\n const leads = series.leads?.length ? series.leads : series.lead ? [series.lead] : [];\n const root = leads[leads.length - 1];\n if (root) {\n const runs = [...leads].reverse().map((lead) => `baker canvas run --series ${lead}`);\n return [\n `This ad is one of the series led by ${leads[0]}: its picture is ${root}'s with its own words. A change to what every ad shares (the picture, colours, layout, logo) is made once, on ${root} (src/creatives/${root}/prompt.json, or baker canvas run --slug ${root} --fix \"<the change>\"), then ${runs.join(\", then \")}. Correct only this ad's own words or its own defect here.`,\n ];\n }\n if (series.members.length === 0) return [];\n return [\n `This ad leads a series of ${series.members.length + 1}: baker canvas run --series ${slug} makes ${series.members.join(\", \")} again from this version, each with its own words. Until then they show the lead's earlier version; an ad of the series run by itself (baker canvas run --slug ${series.members[0]}) is made from this version too, its design included.`,\n ];\n}\n"],"mappings":"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","names":["readFile","path","path","readFile","copy"]}
@@ -0,0 +1,41 @@
1
+ // src/commands/landing/inspiration/shot.ts
2
+ import { mkdir, writeFile } from "fs/promises";
3
+ import path from "path";
4
+ import sharp from "sharp";
5
+ var READABLE_SHOT = {
6
+ maxWidth: 1440,
7
+ maxHeight: 4e3,
8
+ quality: 82,
9
+ extension: "webp"
10
+ };
11
+ async function toReadableShot(original) {
12
+ try {
13
+ return await sharp(original).resize({
14
+ width: READABLE_SHOT.maxWidth,
15
+ height: READABLE_SHOT.maxHeight,
16
+ fit: "inside",
17
+ withoutEnlargement: true
18
+ }).webp({ quality: READABLE_SHOT.quality }).toBuffer();
19
+ } catch {
20
+ return original;
21
+ }
22
+ }
23
+ async function downloadReadableShot(url, file) {
24
+ if (!url) return null;
25
+ try {
26
+ const response = await fetch(url);
27
+ if (!response.ok) return null;
28
+ const shot = await toReadableShot(Buffer.from(await response.arrayBuffer()));
29
+ await mkdir(path.dirname(file), { recursive: true });
30
+ await writeFile(file, shot);
31
+ return path.relative(process.cwd(), file);
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+
37
+ export {
38
+ READABLE_SHOT,
39
+ downloadReadableShot
40
+ };
41
+ //# sourceMappingURL=chunk-DNCLWSHO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/landing/inspiration/shot.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport sharp from \"sharp\";\n\n/**\n * The size a section screenshot is worth reading at.\n *\n * Sections are captured at a 1440px viewport with `deviceScaleFactor: 2`, so\n * what R2 holds is a ~2880px-wide lossless PNG — the right archive, the wrong\n * thing to hand an agent. A vision model bills by pixel area and downsamples\n * anything past its own long-edge cap, so the extra resolution buys no legibility\n * and costs context on every hit; a default `search` writes eight of these, and\n * `view` three more per section.\n *\n * 1440 is the width the page was designed at, so halving the 2x capture back to\n * it is the same picture a human sees, not a lossy compromise — and the height\n * bound is what stops a 20,000px scrolling hero from being resized into an\n * unreadable ribbon.\n */\nexport const READABLE_SHOT = {\n maxWidth: 1440,\n maxHeight: 4000,\n quality: 82,\n extension: \"webp\",\n} as const;\n\n/**\n * Downscale a captured shot to the rendition an agent reads.\n *\n * Never enlarges, and never fails the caller: a shot that sharp cannot decode\n * (an HTML login wall saved as `.png` is the recurring case) is passed through\n * untouched, because a slightly-too-large image beats no image at all in a\n * library whose whole value is visual.\n */\nexport async function toReadableShot(original: Buffer): Promise<Buffer> {\n try {\n return await sharp(original)\n .resize({\n width: READABLE_SHOT.maxWidth,\n height: READABLE_SHOT.maxHeight,\n fit: \"inside\",\n withoutEnlargement: true,\n })\n .webp({ quality: READABLE_SHOT.quality })\n .toBuffer();\n } catch {\n return original;\n }\n}\n\n/**\n * Fetch a shot and put the readable rendition on disk.\n *\n * Returns the repo-relative path to `Read`, or null when there was nothing to\n * download — a missing screenshot is never worth failing a search or a view over.\n */\nexport async function downloadReadableShot(url: string | null | undefined, file: string): Promise<string | null> {\n if (!url) return null;\n try {\n const response = await fetch(url);\n if (!response.ok) return null;\n const shot = await toReadableShot(Buffer.from(await response.arrayBuffer()));\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, shot);\n return path.relative(process.cwd(), file);\n } catch {\n return null;\n }\n}\n"],"mappings":";AAAA,SAAS,OAAO,iBAAiB;AACjC,OAAO,UAAU;AACjB,OAAO,WAAW;AAiBX,IAAM,gBAAgB;AAAA,EAC3B,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,WAAW;AACb;AAUA,eAAsB,eAAe,UAAmC;AACtE,MAAI;AACF,WAAO,MAAM,MAAM,QAAQ,EACxB,OAAO;AAAA,MACN,OAAO,cAAc;AAAA,MACrB,QAAQ,cAAc;AAAA,MACtB,KAAK;AAAA,MACL,oBAAoB;AAAA,IACtB,CAAC,EACA,KAAK,EAAE,SAAS,cAAc,QAAQ,CAAC,EACvC,SAAS;AAAA,EACd,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,qBAAqB,KAAgC,MAAsC;AAC/G,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,QAAI,CAAC,SAAS,GAAI,QAAO;AACzB,UAAM,OAAO,MAAM,eAAe,OAAO,KAAK,MAAM,SAAS,YAAY,CAAC,CAAC;AAC3E,UAAM,MAAM,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,UAAM,UAAU,MAAM,IAAI;AAC1B,WAAO,KAAK,SAAS,QAAQ,IAAI,GAAG,IAAI;AAAA,EAC1C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,296 @@
1
+ import {
2
+ DIRECT_ROUTE,
3
+ captureProxyCredentials,
4
+ childEnvWith,
5
+ plannedRoutes,
6
+ shouldEscalate
7
+ } from "./chunk-O6QKCJE4.js";
8
+
9
+ // src/lib/vimeoCookie.ts
10
+ import { writeFile } from "fs/promises";
11
+ import path from "path";
12
+ var COOKIE_NAME = "vimeo";
13
+ async function writeVimeoCookieFile(cookie, workDir) {
14
+ const value = cookie?.trim();
15
+ if (!value) return void 0;
16
+ const expires = Math.floor(Date.now() / 1e3) + 365 * 24 * 60 * 60;
17
+ const jar = [
18
+ "# Netscape HTTP Cookie File",
19
+ [".vimeo.com", "TRUE", "/", "TRUE", String(expires), COOKIE_NAME, value].join(" "),
20
+ ""
21
+ ].join("\n");
22
+ const filePath = path.join(workDir, "vimeo-cookies.txt");
23
+ await writeFile(filePath, jar, { mode: 384 });
24
+ return filePath;
25
+ }
26
+ var VIMEO_AUTH_SIGNATURES = ["oauth token", "only works when logged-in", "unable to fetch new oauth tokens"];
27
+ function isVimeoAuthFailure(detail) {
28
+ const haystack = detail.toLowerCase();
29
+ if (!haystack.includes("[vimeo]")) return false;
30
+ return VIMEO_AUTH_SIGNATURES.some((signature) => haystack.includes(signature));
31
+ }
32
+
33
+ // src/lib/ytDlpSignal.ts
34
+ var HTTP_ERROR = /HTTP Error (\d{3})/i;
35
+ var CHALLENGE_PHRASES = [
36
+ "sign in to confirm you're not a bot",
37
+ "sign in to confirm you\u2019re not a bot",
38
+ "confirm you are not a bot",
39
+ "unusual traffic",
40
+ "captcha"
41
+ ];
42
+ var NOT_A_BLOCK_PHRASES = ["private video", "video unavailable", "members-only", "this video is available to"];
43
+ var PROXY_TUNNEL_FAILURE = /tunnel connection failed: 407|proxy authentication required|http error 407/i;
44
+ function ytDlpBlockSignal(stderr) {
45
+ const text = stderr.toLowerCase();
46
+ if (PROXY_TUNNEL_FAILURE.test(stderr)) return { status: 407 };
47
+ if (NOT_A_BLOCK_PHRASES.some((phrase) => text.includes(phrase))) return {};
48
+ const status = HTTP_ERROR.exec(stderr);
49
+ if (status) return { status: Number(status[1]) };
50
+ if (CHALLENGE_PHRASES.some((phrase) => text.includes(phrase))) return { challenge: true };
51
+ return {};
52
+ }
53
+
54
+ // src/lib/ytDlp.ts
55
+ import { spawn } from "child_process";
56
+ import { readdir, readFile } from "fs/promises";
57
+ import path2 from "path";
58
+
59
+ // src/lib/ytDlpFormat.ts
60
+ function videoFormatArgs(maxResolution) {
61
+ const sort = maxResolution ? ["-S", `res:${maxResolution}`] : [];
62
+ return ["--format", "bv*+ba/b", ...sort, "--merge-output-format", "mp4"];
63
+ }
64
+
65
+ // src/lib/ytDlpPlayerClient.ts
66
+ var YOUTUBE_FALLBACK_CLIENT_ARGS = ["--extractor-args", "youtube:player_client=android"];
67
+ var MEDIA_FETCH_REFUSED = "unable to download video data";
68
+ var YOUTUBE_HOSTS = ["youtube.com", "youtu.be"];
69
+ function isYouTube(url) {
70
+ let host;
71
+ try {
72
+ host = new URL(url).hostname.toLowerCase();
73
+ } catch {
74
+ return false;
75
+ }
76
+ return YOUTUBE_HOSTS.some((known) => host === known || host.endsWith(`.${known}`));
77
+ }
78
+ function needsPlayerClientRetry(url, stderr) {
79
+ return isYouTube(url) && stderr.toLowerCase().includes(MEDIA_FETCH_REFUSED);
80
+ }
81
+
82
+ // src/lib/ytDlp.ts
83
+ var YT_DLP_BIN = "yt-dlp";
84
+ var YT_DLP_TIMEOUT_MS = 10 * 60 * 1e3;
85
+ var YT_DLP_PROBE_TIMEOUT_MS = 60 * 1e3;
86
+ var TRUST_SYSTEM_CERTS = ["--compat-options", "no-certifi"];
87
+ var YtDlpError = class extends Error {
88
+ constructor(message, stderrTail) {
89
+ super(message);
90
+ this.stderrTail = stderrTail;
91
+ this.name = "YtDlpError";
92
+ }
93
+ };
94
+ function tail(text, maxLines) {
95
+ return text.split("\n").slice(-maxLines).join("\n");
96
+ }
97
+ async function runYtDlp(args) {
98
+ const outTemplate = path2.join(args.workDir, "out.%(ext)s");
99
+ const infoPath = path2.join(args.workDir, "out.info.json");
100
+ const argv = [
101
+ args.url,
102
+ "--no-playlist",
103
+ "--no-progress",
104
+ "--no-warnings",
105
+ "--quiet",
106
+ "--write-info-json",
107
+ ...TRUST_SYSTEM_CERTS,
108
+ "-o",
109
+ outTemplate
110
+ ];
111
+ if (args.audioOnly) {
112
+ argv.push("-x", "--audio-format", "m4a");
113
+ } else {
114
+ argv.push(...videoFormatArgs(args.maxHeight));
115
+ }
116
+ const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.workDir);
117
+ if (cookieFile) argv.push("--cookies", cookieFile);
118
+ args.onLog?.(`yt-dlp: downloading ${args.audioOnly ? "audio" : "video"}`);
119
+ const timeoutMs = args.timeoutMs ?? YT_DLP_TIMEOUT_MS;
120
+ const { code, stderr, tier, reducedQuality } = await downloadWithClientFallback({
121
+ url: args.url,
122
+ argv,
123
+ onLog: args.onLog,
124
+ ladder: (attemptArgv) => runViaLadder({ url: args.url, argv: attemptArgv, timeoutMs, onLog: args.onLog, country: args.country }),
125
+ repeat: (attemptArgv, route) => spawnAndWait(YT_DLP_BIN, attemptArgv, timeoutMs, { extraEnv: proxyEnvFor(route) })
126
+ });
127
+ if (code !== 0) {
128
+ throw new YtDlpError(`yt-dlp exited ${code}`, tail(stderr, 40));
129
+ }
130
+ const files = await readdir(args.workDir);
131
+ const wanted = args.audioOnly ? ".m4a" : ".mp4";
132
+ const downloaded = files.find((f) => f.startsWith("out.") && f.endsWith(wanted));
133
+ if (!downloaded) {
134
+ throw new YtDlpError(`yt-dlp finished but produced no ${wanted} file (saw: ${files.join(", ")})`, "");
135
+ }
136
+ let info = {};
137
+ try {
138
+ info = JSON.parse(await readFile(infoPath, "utf-8"));
139
+ } catch {
140
+ }
141
+ return { filePath: path2.join(args.workDir, downloaded), info, tier, reducedQuality };
142
+ }
143
+ async function probeYtDlp(args) {
144
+ const argv = [
145
+ args.url,
146
+ "--no-playlist",
147
+ "--no-warnings",
148
+ "--dump-single-json",
149
+ "--skip-download",
150
+ // Without this the probe fails wherever the *download* would fail, which
151
+ // defeats the point of probing: yt-dlp still runs format selection for
152
+ // `--dump-single-json`, so a binary too old to read a site's format list
153
+ // exits "Requested format is not available" and we learn nothing — measured
154
+ // against a stale build, which returned full metadata the moment this flag
155
+ // was added. Duration and id come from the page, not from a format.
156
+ "--ignore-no-formats-error",
157
+ ...TRUST_SYSTEM_CERTS
158
+ ];
159
+ if (args.cookieDir) {
160
+ const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.cookieDir);
161
+ if (cookieFile) argv.push("--cookies", cookieFile);
162
+ }
163
+ let stdout = "";
164
+ const { code, stderr, tier } = await walkYtDlpLadder({
165
+ url: args.url,
166
+ credentials: captureProxyCredentials(),
167
+ attempt: async (route) => {
168
+ const result = await spawnAndWait(YT_DLP_BIN, argv, args.timeoutMs ?? YT_DLP_PROBE_TIMEOUT_MS, {
169
+ extraEnv: proxyEnvFor(route),
170
+ captureStdout: true
171
+ });
172
+ stdout = result.stdout ?? "";
173
+ return result;
174
+ },
175
+ onLog: args.onLog,
176
+ country: args.country
177
+ });
178
+ if (code !== 0) {
179
+ throw new YtDlpError(`yt-dlp exited ${code}`, tail(stderr, 40));
180
+ }
181
+ let parsed;
182
+ try {
183
+ parsed = JSON.parse(stdout);
184
+ } catch {
185
+ throw new YtDlpError("yt-dlp returned metadata that could not be read", tail(stdout, 5));
186
+ }
187
+ if (parsed === null || typeof parsed !== "object") {
188
+ throw new YtDlpError("yt-dlp returned no metadata for that link", tail(stderr, 40));
189
+ }
190
+ return { info: parsed, tier };
191
+ }
192
+ function isAudioOnly(info) {
193
+ return info.vcodec === "none";
194
+ }
195
+ function durationSeconds(info) {
196
+ const raw = info.duration;
197
+ return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : void 0;
198
+ }
199
+ function canonicalUrl(info) {
200
+ const raw = info.webpage_url;
201
+ return typeof raw === "string" && raw.length > 0 ? raw : void 0;
202
+ }
203
+ async function walkYtDlpLadder(args) {
204
+ const routes = plannedRoutes(args.url, args.credentials, args.country ? { country: args.country } : void 0);
205
+ let last = { code: -1, stderr: "", tier: "direct", route: DIRECT_ROUTE };
206
+ for (const route of routes) {
207
+ const tier = route.kind === "proxy" ? route.tier : "direct";
208
+ if (route.kind === "proxy") args.onLog?.(`yt-dlp: retrying via ${tier}`);
209
+ last = { ...await args.attempt(route), tier, route };
210
+ if (last.code === 0) return last;
211
+ if (!shouldEscalate(ytDlpBlockSignal(last.stderr))) return last;
212
+ }
213
+ return last;
214
+ }
215
+ async function downloadWithClientFallback(args) {
216
+ const first = await args.ladder(args.argv);
217
+ if (first.code === 0 || !needsPlayerClientRetry(args.url, first.stderr)) {
218
+ return { ...first, reducedQuality: false };
219
+ }
220
+ args.onLog?.("yt-dlp: retrying with the fallback player client");
221
+ const again = await args.repeat([...args.argv, ...YOUTUBE_FALLBACK_CLIENT_ARGS], first.route);
222
+ return { ...again, tier: first.tier, route: first.route, reducedQuality: again.code === 0 };
223
+ }
224
+ function runViaLadder(args) {
225
+ return walkYtDlpLadder({
226
+ url: args.url,
227
+ credentials: captureProxyCredentials(),
228
+ attempt: (route) => spawnAndWait(YT_DLP_BIN, args.argv, args.timeoutMs, { extraEnv: proxyEnvFor(route) }),
229
+ onLog: args.onLog,
230
+ country: args.country
231
+ });
232
+ }
233
+ function proxyEnvFor(route) {
234
+ if (route.kind !== "proxy") return void 0;
235
+ const uri = new URL(route.server);
236
+ uri.username = encodeURIComponent(route.username);
237
+ uri.password = encodeURIComponent(route.password);
238
+ return {
239
+ HTTP_PROXY: uri.toString(),
240
+ HTTPS_PROXY: uri.toString(),
241
+ http_proxy: uri.toString(),
242
+ https_proxy: uri.toString()
243
+ };
244
+ }
245
+ function spawnAndWait(bin, argv, timeoutMs, options = {}) {
246
+ return new Promise((resolve, reject) => {
247
+ const child = spawn(bin, argv, {
248
+ stdio: ["ignore", "pipe", "pipe"],
249
+ // `childEnvWith` because `spawn`'s `env` REPLACES the environment rather
250
+ // than extending it — passing only the additions would strip PATH.
251
+ ...options.extraEnv ? { env: childEnvWith(options.extraEnv) } : {}
252
+ });
253
+ const stderrChunks = [];
254
+ const stdoutChunks = [];
255
+ let stderrLen = 0;
256
+ const MAX_STDERR = 256 * 1024;
257
+ child.stdout.on("data", (chunk) => {
258
+ if (options.captureStdout) stdoutChunks.push(chunk);
259
+ });
260
+ child.stderr.on("data", (chunk) => {
261
+ if (stderrLen < MAX_STDERR) {
262
+ stderrChunks.push(chunk);
263
+ stderrLen += chunk.length;
264
+ }
265
+ });
266
+ const timer = setTimeout(() => {
267
+ child.kill("SIGKILL");
268
+ reject(new Error(`${bin} timed out after ${timeoutMs}ms`));
269
+ }, timeoutMs);
270
+ child.on("error", (err) => {
271
+ clearTimeout(timer);
272
+ reject(new Error(`failed to spawn "${bin}" \u2014 ${err.message}`));
273
+ });
274
+ child.on("close", (code) => {
275
+ clearTimeout(timer);
276
+ resolve({
277
+ code: code ?? -1,
278
+ stderr: Buffer.concat(stderrChunks).toString("utf-8"),
279
+ ...options.captureStdout ? { stdout: Buffer.concat(stdoutChunks).toString("utf-8") } : {}
280
+ });
281
+ });
282
+ });
283
+ }
284
+
285
+ export {
286
+ isVimeoAuthFailure,
287
+ ytDlpBlockSignal,
288
+ YT_DLP_BIN,
289
+ YtDlpError,
290
+ runYtDlp,
291
+ probeYtDlp,
292
+ isAudioOnly,
293
+ durationSeconds,
294
+ canonicalUrl
295
+ };
296
+ //# sourceMappingURL=chunk-DX4GIDO7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/vimeoCookie.ts","../src/lib/ytDlpSignal.ts","../src/lib/ytDlp.ts","../src/lib/ytDlpFormat.ts","../src/lib/ytDlpPlayerClient.ts"],"sourcesContent":["import { writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Vimeo's session cookie, as a file yt-dlp can read.\n *\n * Vimeo is the only platform with no anonymous route left: every yt-dlp client\n * either cannot mint a token any more or refuses without a login, and the\n * failure is identical through direct, datacenter and residential exits, so it\n * is neither our IP nor our TLS fingerprint. A logged-in cookie is the whole\n * fix — measured, `vimeo` alone is sufficient and `vuid`/`auth_xsrft` without it\n * are worthless.\n *\n * The cookie arrives as a value, never as a path: the backend owns the secret\n * and the sandbox owns its filesystem, so nothing outside writes into the\n * Runtime. `--cookies <path>` then puts only the path in argv, keeping the\n * credential out of `ps` — the same rule that governs proxy passwords.\n */\n\n/** The single cookie yt-dlp's `_is_logged_in` actually checks. */\nconst COOKIE_NAME = \"vimeo\";\n\n/**\n * Write the cookie jar, returning its path — or undefined when unconfigured.\n *\n * Undefined rather than an empty file, because an empty jar is not the same as\n * no jar: yt-dlp would read it, find no session, and fail with the anonymous\n * error while looking as though credentials had been supplied.\n */\nexport async function writeVimeoCookieFile(cookie: string | undefined, workDir: string): Promise<string | undefined> {\n const value = cookie?.trim();\n if (!value) return undefined;\n\n // A year out. The jar's own expiry is a formality — Vimeo expires the session\n // server-side on its own schedule, and `isVimeoAuthFailure` is what notices.\n const expires = Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60;\n const jar = [\n \"# Netscape HTTP Cookie File\",\n [\".vimeo.com\", \"TRUE\", \"/\", \"TRUE\", String(expires), COOKIE_NAME, value].join(\"\\t\"),\n \"\",\n ].join(\"\\n\");\n\n const filePath = path.join(workDir, \"vimeo-cookies.txt\");\n // 0o600 at creation, not chmod-after: the sandbox runs the agent's own shell,\n // and a world-readable window between write and chmod is a window.\n await writeFile(filePath, jar, { mode: 0o600 });\n return filePath;\n}\n\n/**\n * Whether a Vimeo failure is about authentication rather than the video.\n *\n * Every one of these phrasings means the same thing to whoever pasted the link —\n * Vimeo would not talk to us — but Vimeo's own wording (\"Failed to fetch macos\n * OAuth token\") names an internal detail that sends the reader nowhere. The\n * distinction earns its place because this credential *expires*: without it, the\n * day the cookie lapses looks like a brand-new mystery instead of a five-minute\n * re-export.\n *\n * Scoped to `[vimeo]` so another platform's 401 cannot inherit advice about a\n * cookie that has nothing to do with it.\n */\nconst VIMEO_AUTH_SIGNATURES = [\"oauth token\", \"only works when logged-in\", \"unable to fetch new oauth tokens\"] as const;\n\nexport function isVimeoAuthFailure(detail: string): boolean {\n const haystack = detail.toLowerCase();\n if (!haystack.includes(\"[vimeo]\")) return false;\n return VIMEO_AUTH_SIGNATURES.some((signature) => haystack.includes(signature));\n}\n","import type { BlockSignal } from \"@baker/proxy\";\n\n/**\n * yt-dlp's stderr, read as the same signal every other surface produces.\n *\n * Deliberately only extraction — `shouldEscalate` still makes the decision, so\n * yt-dlp cannot drift into its own private idea of what a block is. The two\n * halves have to stay separate: a downloader that decided for itself would be\n * the one surface where a 404 could cost money.\n *\n * The parsing exists because yt-dlp gives us prose and an exit code, not a\n * response. There is no status line to read, so the status has to be recovered\n * from the sentence it was printed into.\n */\n\n/** `HTTP Error 403: Forbidden`, in any of the shapes yt-dlp writes it. */\nconst HTTP_ERROR = /HTTP Error (\\d{3})/i;\n\n/**\n * Refusals that arrive as prose with no status at all.\n *\n * YouTube's bot check is the one that matters: it is the single most common\n * reason a datacenter IP fails a download that a residential one completes, and\n * it looks like an ordinary successful page to everything except a human\n * reading the text.\n */\nconst CHALLENGE_PHRASES = [\n \"sign in to confirm you're not a bot\",\n \"sign in to confirm you’re not a bot\",\n \"confirm you are not a bot\",\n \"unusual traffic\",\n \"captcha\",\n];\n\n/**\n * Prose that must never escalate, checked *before* the phrases above.\n *\n * \"Private video. Sign in if you've been granted access\" contains a sign-in\n * demand and is not a block — no exit IP on earth opens it, and treating it as\n * one would spend the expensive rung on every private link an agent is handed.\n */\nconst NOT_A_BLOCK_PHRASES = [\"private video\", \"video unavailable\", \"members-only\", \"this video is available to\"];\n\n/**\n * Our own proxy refusing us, which yt-dlp writes without an `HTTP Error` prefix.\n *\n * Checked before everything else. A 407 cannot come from an origin server, so\n * recovering it is what lets `isProxyFailure` separate \"the platform's egress\n * credentials are wrong\" from \"this site blocked us\" — opposite remediations,\n * and the first is otherwise invisible: a rotated password reads downstream as\n * every site having simultaneously started refusing us.\n */\nconst PROXY_TUNNEL_FAILURE = /tunnel connection failed: 407|proxy authentication required|http error 407/i;\n\nexport function ytDlpBlockSignal(stderr: string): BlockSignal {\n const text = stderr.toLowerCase();\n\n if (PROXY_TUNNEL_FAILURE.test(stderr)) return { status: 407 };\n\n if (NOT_A_BLOCK_PHRASES.some((phrase) => text.includes(phrase))) return {};\n\n // First, not last. yt-dlp prints a line per retry, so the final line is\n // usually \"giving up after 3 retries\" — the verdict that started the sequence\n // is the one that says why.\n const status = HTTP_ERROR.exec(stderr);\n if (status) return { status: Number(status[1]) };\n\n if (CHALLENGE_PHRASES.some((phrase) => text.includes(phrase))) return { challenge: true };\n return {};\n}\n","import { spawn } from \"node:child_process\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ProxyCredentials, ProxyRoute, ProxyTier } from \"@baker/proxy\";\nimport { DIRECT_ROUTE, plannedRoutes, shouldEscalate } from \"@baker/proxy\";\nimport { captureProxyCredentials, childEnvWith } from \"../env.ts\";\nimport { writeVimeoCookieFile } from \"./vimeoCookie.ts\";\nimport { videoFormatArgs } from \"./ytDlpFormat.ts\";\nimport { needsPlayerClientRetry, YOUTUBE_FALLBACK_CLIENT_ARGS } from \"./ytDlpPlayerClient.ts\";\nimport { ytDlpBlockSignal } from \"./ytDlpSignal.ts\";\n\n/**\n * yt-dlp, run through the egress ladder, shared by the canvas `ingest` node and\n * `baker videos ingest`.\n *\n * Both download the same kinds of URL from the same sandbox and must agree about\n * what \"blocked\" means and how a credential is written down — and the second of\n * those is a decision that silently means two different passwords if it is made\n * twice (see `proxyEnvFor`). One copy is the point.\n *\n * Callers own how a failure is reported: the node wraps `YtDlpError` in a\n * `NodeExecutionError`, the command turns it into a `{ ok: false }` envelope.\n */\n\nexport const YT_DLP_BIN = \"yt-dlp\";\nexport const YT_DLP_TIMEOUT_MS = 10 * 60 * 1000;\n/** A probe fetches no media, so it gets a much shorter leash than a download. */\nexport const YT_DLP_PROBE_TIMEOUT_MS = 60 * 1000;\n\nexport type YtDlpInfo = Record<string, unknown>;\n\n/**\n * Verify TLS against the system bundle, never certifi's.\n *\n * The Runtime reads HTTPS through the credential broker, and the broker's CA is\n * installed in the system bundle (`SSL_CERT_FILE`) and nowhere else. yt-dlp is\n * installed with certifi and, left alone, verifies against certifi's own copy —\n * so once the broker shipped, every direct download in a Runtime failed with\n * `CERTIFICATE_VERIFY_FAILED` while `curl` to the same host answered. The agent\n * that hit it on our own CDN worked around it by pointing a committed canvas at\n * its gitignored local cache, which broke the next Session's publish. The\n * impersonating (curl_cffi) path reads `CURL_CA_BUNDLE`, which the broker also\n * sets, so it needs nothing here.\n */\nconst TRUST_SYSTEM_CERTS = [\"--compat-options\", \"no-certifi\"] as const;\n\nexport class YtDlpError extends Error {\n constructor(\n message: string,\n readonly stderrTail: string,\n ) {\n super(message);\n this.name = \"YtDlpError\";\n }\n}\n\nexport function tail(text: string, maxLines: number): string {\n return text.split(\"\\n\").slice(-maxLines).join(\"\\n\");\n}\n\n/**\n * Download `url` into `workDir`, climbing to a paid exit only if the host\n * refused the cheaper one. Returns the media file and yt-dlp's info.json\n * (best-effort — yt-dlp omits it for some direct file URLs).\n *\n * By default the best the site will release: `bv*+ba/b`. There used to be an\n * optional height cap here, on the reasoning that a 4K master is bytes we\n * re-encode anyway — but both callers now want the master, because capping\n * discards source pixels before the systems that make renditions from them ever\n * see them, and that loss is permanent while the saving is one download.\n * The one exception is opt-in: a bulk import may pass `maxHeight`.\n */\nexport async function runYtDlp(args: {\n url: string;\n audioOnly: boolean;\n workDir: string;\n timeoutMs?: number;\n onLog?: (message: string) => void;\n country?: string;\n /** Vimeo session cookie value; written to a jar in `workDir` when present. */\n vimeoCookie?: string;\n /** Opt-in resolution cap (shorter side) for bulk imports — see `videoFormatArgs`. */\n maxHeight?: number;\n}): Promise<{ filePath: string; info: YtDlpInfo; tier: EgressTier; reducedQuality: boolean }> {\n const outTemplate = path.join(args.workDir, \"out.%(ext)s\");\n const infoPath = path.join(args.workDir, \"out.info.json\");\n\n const argv: string[] = [\n args.url,\n \"--no-playlist\",\n \"--no-progress\",\n \"--no-warnings\",\n \"--quiet\",\n \"--write-info-json\",\n ...TRUST_SYSTEM_CERTS,\n \"-o\",\n outTemplate,\n ];\n\n if (args.audioOnly) {\n argv.push(\"-x\", \"--audio-format\", \"m4a\");\n } else {\n argv.push(...videoFormatArgs(args.maxHeight));\n }\n\n const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.workDir);\n if (cookieFile) argv.push(\"--cookies\", cookieFile);\n\n args.onLog?.(`yt-dlp: downloading ${args.audioOnly ? \"audio\" : \"video\"}`);\n const timeoutMs = args.timeoutMs ?? YT_DLP_TIMEOUT_MS;\n const { code, stderr, tier, reducedQuality } = await downloadWithClientFallback({\n url: args.url,\n argv,\n onLog: args.onLog,\n ladder: (attemptArgv) =>\n runViaLadder({ url: args.url, argv: attemptArgv, timeoutMs, onLog: args.onLog, country: args.country }),\n repeat: (attemptArgv, route) => spawnAndWait(YT_DLP_BIN, attemptArgv, timeoutMs, { extraEnv: proxyEnvFor(route) }),\n });\n\n if (code !== 0) {\n throw new YtDlpError(`yt-dlp exited ${code}`, tail(stderr, 40));\n }\n\n const files = await readdir(args.workDir);\n const wanted = args.audioOnly ? \".m4a\" : \".mp4\";\n const downloaded = files.find((f) => f.startsWith(\"out.\") && f.endsWith(wanted));\n if (!downloaded) {\n throw new YtDlpError(`yt-dlp finished but produced no ${wanted} file (saw: ${files.join(\", \")})`, \"\");\n }\n\n let info: YtDlpInfo = {};\n try {\n info = JSON.parse(await readFile(infoPath, \"utf-8\")) as YtDlpInfo;\n } catch {\n // info.json is best-effort — yt-dlp sometimes omits it for direct file URLs.\n }\n\n return { filePath: path.join(args.workDir, downloaded), info, tier, reducedQuality };\n}\n\n/**\n * Read a URL's metadata without fetching any media.\n *\n * Worth its own round trip because it settles the one thing that has to be known\n * before the expensive part starts: how long the video is. Measured, a ten-hour\n * link is now refused in ~3s, where the byte ceiling it replaced could only\n * refuse it after the download it was meant to avoid. It also carries the\n * provider id, which used to be readable only from the download's own info.json.\n *\n * Climbs the same egress ladder as the download, so a host that answers only a\n * paid exit is probed through one too.\n */\nexport async function probeYtDlp(args: {\n url: string;\n timeoutMs?: number;\n onLog?: (message: string) => void;\n country?: string;\n /** Vimeo session cookie value. `cookieDir` must be set for it to be used. */\n vimeoCookie?: string;\n cookieDir?: string;\n}): Promise<{ info: YtDlpInfo; tier: EgressTier }> {\n const argv = [\n args.url,\n \"--no-playlist\",\n \"--no-warnings\",\n \"--dump-single-json\",\n \"--skip-download\",\n // Without this the probe fails wherever the *download* would fail, which\n // defeats the point of probing: yt-dlp still runs format selection for\n // `--dump-single-json`, so a binary too old to read a site's format list\n // exits \"Requested format is not available\" and we learn nothing — measured\n // against a stale build, which returned full metadata the moment this flag\n // was added. Duration and id come from the page, not from a format.\n \"--ignore-no-formats-error\",\n ...TRUST_SYSTEM_CERTS,\n ];\n\n // The probe needs the same credential as the download: Vimeo refuses metadata\n // to an anonymous caller too, so probing without it fails before the duration\n // gate ever runs.\n if (args.cookieDir) {\n const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.cookieDir);\n if (cookieFile) argv.push(\"--cookies\", cookieFile);\n }\n\n let stdout = \"\";\n const { code, stderr, tier } = await walkYtDlpLadder({\n url: args.url,\n credentials: captureProxyCredentials(),\n attempt: async (route) => {\n const result = await spawnAndWait(YT_DLP_BIN, argv, args.timeoutMs ?? YT_DLP_PROBE_TIMEOUT_MS, {\n extraEnv: proxyEnvFor(route),\n captureStdout: true,\n });\n stdout = result.stdout ?? \"\";\n return result;\n },\n onLog: args.onLog,\n country: args.country,\n });\n\n if (code !== 0) {\n throw new YtDlpError(`yt-dlp exited ${code}`, tail(stderr, 40));\n }\n\n // Parsed, not trusted: yt-dlp prints a bare `null` for a page it recognised\n // but could not extract, and on at least one site it pairs that with a\n // non-zero exit — so the exit code alone is not enough to promise an object.\n let parsed: unknown;\n try {\n parsed = JSON.parse(stdout);\n } catch {\n throw new YtDlpError(\"yt-dlp returned metadata that could not be read\", tail(stdout, 5));\n }\n if (parsed === null || typeof parsed !== \"object\") {\n throw new YtDlpError(\"yt-dlp returned no metadata for that link\", tail(stderr, 40));\n }\n return { info: parsed as YtDlpInfo, tier };\n}\n\n/**\n * True only when the source explicitly says it carries no video.\n *\n * `vcodec: \"none\"` is the assertion; a *missing* vcodec is not, and that\n * distinction is the whole function. Measured: SoundCloud reports `\"none\"`,\n * while Streamable reports `null` and is perfectly good video. The obvious\n * version of this check — \"no format has a video codec\" — matches both and\n * would refuse Streamable, which ingests fine today.\n *\n * Caught at probe time because the alternative is what it replaces: the\n * download succeeds, produces an `.m4a`, and the caller fails looking for an\n * `.mp4` — surfaced as \"yt-dlp finished but produced no .mp4 file\", which names\n * an internal expectation rather than the fact that someone linked to audio.\n */\nexport function isAudioOnly(info: YtDlpInfo): boolean {\n return info.vcodec === \"none\";\n}\n\n/** The probed duration in seconds, when the site reported one that can be read. */\nexport function durationSeconds(info: YtDlpInfo): number | undefined {\n const raw = info.duration;\n return typeof raw === \"number\" && Number.isFinite(raw) && raw > 0 ? raw : undefined;\n}\n\n/**\n * The canonical page URL for what was probed, when the extractor resolved one.\n *\n * Worth preferring over the URL a person pasted, because yt-dlp has already done\n * the normalising: measured, it turns `youtu.be/<id>?si=…&t=42`,\n * `/shorts/<id>` and `m.youtube.com/watch?v=<id>&feature=share` all into the one\n * `www.youtube.com/watch?v=<id>`. Storing the raw paste instead files the same\n * video under a different `externalUrl` depending on where the link was copied\n * from, which is exactly the provenance question this field exists to answer.\n */\nexport function canonicalUrl(info: YtDlpInfo): string | undefined {\n const raw = info.webpage_url;\n return typeof raw === \"string\" && raw.length > 0 ? raw : undefined;\n}\n\n/**\n * Walk the ladder: direct first, then each configured tier, stopping the moment\n * the failure is one a different exit IP cannot fix.\n *\n * The escalation decision is `shouldEscalate`'s, not ours — the same closed\n * allow-list every other egress surface uses. A downloader that decided for\n * itself would be the one surface where a 404 could cost money.\n */\nexport type EgressTier = \"direct\" | ProxyTier;\n\n/**\n * Which rung produced this result — so a paid exit is never spent invisibly.\n *\n * The `route` is here, and not just the tier's name, because one caller needs to\n * *repeat* the rung rather than merely report it: the player-client fallback\n * re-runs on whichever exit already got far enough to be refused at the media\n * stage. A name cannot be handed back to `proxyEnvFor`; the route can.\n */\nexport type LadderResult = SpawnResult & { tier: EgressTier; route: ProxyRoute };\n\nexport async function walkYtDlpLadder(args: {\n url: string;\n credentials: ProxyCredentials;\n attempt: (route: ProxyRoute) => Promise<SpawnResult>;\n onLog?: (message: string) => void;\n /**\n * ISO-3166 alpha-2 exit country for the paid rungs. Omit for \"wherever\".\n *\n * Not inferred and never automatic: a country is only right when someone\n * knows *which* one opens the video, and guessing would multiply the cost of\n * every failure by the length of the guess list. `@baker/proxy` owns the\n * per-product syntax — datacenter and residential spell geo differently and\n * each rejects the other's token.\n */\n country?: string;\n}): Promise<LadderResult> {\n const routes = plannedRoutes(args.url, args.credentials, args.country ? { country: args.country } : undefined);\n let last: LadderResult = { code: -1, stderr: \"\", tier: \"direct\", route: DIRECT_ROUTE };\n\n for (const route of routes) {\n const tier: EgressTier = route.kind === \"proxy\" ? route.tier : \"direct\";\n if (route.kind === \"proxy\") args.onLog?.(`yt-dlp: retrying via ${tier}`);\n last = { ...(await args.attempt(route)), tier, route };\n if (last.code === 0) return last;\n if (!shouldEscalate(ytDlpBlockSignal(last.stderr))) return last;\n }\n return last;\n}\n\n/**\n * The download, plus the one retry that changes the player instead of the exit.\n *\n * Split out from `runYtDlp` with its two runners injected because the decision\n * this makes is the expensive one to get wrong and the hardest to observe: it\n * spends egress. A test can drive both branches here; it cannot drive them\n * through a function that spawns a binary.\n *\n * **The retry repeats one rung and opens no new one.** It re-runs on\n * `first.route` — whichever exit already got far enough to be refused at the\n * media stage — rather than walking the ladder again. Walking it again was the\n * first version of this and it was wrong in exactly the way this whole change\n * exists to stop: the trigger is a 403, `shouldEscalate` treats a 403 as\n * escalatable, so a fallback client that was also refused would climb through\n * datacenter and residential a second time, paying twice more for a verdict\n * that has already been shown not to depend on the address. Re-using the rung\n * is also what makes the retry correct when the *only* rung that reached the\n * media stage was a paid one — a direct-only retry would land back on the bot\n * wall that made us leave direct in the first place.\n */\nexport async function downloadWithClientFallback(args: {\n url: string;\n argv: readonly string[];\n ladder: (argv: readonly string[]) => Promise<LadderResult>;\n repeat: (argv: readonly string[], route: ProxyRoute) => Promise<SpawnResult>;\n onLog?: (message: string) => void;\n}): Promise<LadderResult & { reducedQuality: boolean }> {\n const first = await args.ladder(args.argv);\n if (first.code === 0 || !needsPlayerClientRetry(args.url, first.stderr)) {\n return { ...first, reducedQuality: false };\n }\n\n args.onLog?.(\"yt-dlp: retrying with the fallback player client\");\n const again = await args.repeat([...args.argv, ...YOUTUBE_FALLBACK_CLIENT_ARGS], first.route);\n\n // `tier` and `route` stay the first attempt's: the retry deliberately did not\n // move, so reporting a different rung would misstate what was spent.\n return { ...again, tier: first.tier, route: first.route, reducedQuality: again.code === 0 };\n}\n\nfunction runViaLadder(args: {\n url: string;\n argv: readonly string[];\n timeoutMs: number;\n onLog?: (message: string) => void;\n country?: string;\n}): Promise<LadderResult> {\n return walkYtDlpLadder({\n url: args.url,\n credentials: captureProxyCredentials(),\n attempt: (route) => spawnAndWait(YT_DLP_BIN, args.argv, args.timeoutMs, { extraEnv: proxyEnvFor(route) }),\n onLog: args.onLog,\n country: args.country,\n });\n}\n\n/**\n * A route as the environment a child process reads it from.\n *\n * Env, never `--proxy`: the flag would put the password in `argv`, readable by\n * any `ps` sharing the sandbox and printed by yt-dlp into the very stderr this\n * module reads back and attaches to an error. Both spellings, because \"which\n * case does this tool read\" is not worth being wrong about once — and `NO_PROXY`\n * is deliberately unset, since `plannedRoutes` has already refused to build a\n * proxy route for a private address.\n *\n * The percent-encoding is correct here and is deliberately **not** the same\n * decision as `browserProxyUrl` in `@baker/proxy`. Measured against both readers\n * with a proxy that logs what it receives: given `ab%3Dcd`, yt-dlp (Python)\n * authenticates as `ab=cd` — it decodes — while Chromium authenticates as the\n * literal `ab%3Dcd`. The same URL means two different passwords depending on who\n * reads it, so each side is written for its own reader. Do not harmonise them.\n */\nexport function proxyEnvFor(route: ProxyRoute): Record<string, string> | undefined {\n if (route.kind !== \"proxy\") return undefined;\n const uri = new URL(route.server);\n uri.username = encodeURIComponent(route.username);\n uri.password = encodeURIComponent(route.password);\n return {\n HTTP_PROXY: uri.toString(),\n HTTPS_PROXY: uri.toString(),\n http_proxy: uri.toString(),\n https_proxy: uri.toString(),\n };\n}\n\nexport type SpawnResult = { code: number; stderr: string; stdout?: string };\n\n/**\n * Spawn helper local to yt-dlp: the engine's `cli-runner` rejects URL arguments\n * by policy, which is directly at odds with yt-dlp's job.\n *\n * stdout is discarded unless asked for, because on a download it is the media\n * progress firehose; the probe is the one caller that actually wants it.\n */\nexport function spawnAndWait(\n bin: string,\n argv: readonly string[],\n timeoutMs: number,\n options: { extraEnv?: Record<string, string>; captureStdout?: boolean } = {},\n): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(bin, argv, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n // `childEnvWith` because `spawn`'s `env` REPLACES the environment rather\n // than extending it — passing only the additions would strip PATH.\n ...(options.extraEnv ? { env: childEnvWith(options.extraEnv) } : {}),\n });\n const stderrChunks: Buffer[] = [];\n const stdoutChunks: Buffer[] = [];\n let stderrLen = 0;\n const MAX_STDERR = 256 * 1024;\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (options.captureStdout) stdoutChunks.push(chunk);\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n if (stderrLen < MAX_STDERR) {\n stderrChunks.push(chunk);\n stderrLen += chunk.length;\n }\n });\n\n const timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n reject(new Error(`${bin} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n child.on(\"error\", (err) => {\n clearTimeout(timer);\n reject(new Error(`failed to spawn \"${bin}\" — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n resolve({\n code: code ?? -1,\n stderr: Buffer.concat(stderrChunks).toString(\"utf-8\"),\n ...(options.captureStdout ? { stdout: Buffer.concat(stdoutChunks).toString(\"utf-8\") } : {}),\n });\n });\n });\n}\n","/**\n * Which video yt-dlp keeps. By default the best the site releases — see\n * `runYtDlp` for why the master matters. A caller importing in bulk may cap\n * the resolution instead: a whole channel of 4K masters is five times the bytes\n * of 1080p, and those bytes are what overruns a download's time budget.\n *\n * The cap is on the shorter side (yt-dlp's `res` sort field), not the height: a\n * vertical Short's 1080p is 1080×1920, and a height cap would keep its 608×1080\n * rendition instead. A sort rather than a filter, so when nothing fits the cap\n * the closest there is still beats no video.\n */\nexport function videoFormatArgs(maxResolution?: number): string[] {\n const sort = maxResolution ? [\"-S\", `res:${maxResolution}`] : [];\n return [\"--format\", \"bv*+ba/b\", ...sort, \"--merge-output-format\", \"mp4\"];\n}\n","/**\n * The second thing to try when YouTube hands us a video and then refuses it.\n *\n * Distinct from the egress ladder, and the distinction is the whole point. The\n * ladder answers \"would a different IP help\"; this answers \"would a different\n * *client* help\" — and measured inside a Runtime, the second question is the one\n * that was failing. yt-dlp's default client selection lands on `android_vr`,\n * whose media URLs YouTube now signs and then rejects, so extraction succeeds,\n * a format is chosen, and the byte fetch comes back\n * `unable to download video data: HTTP Error 403: Forbidden`. That failure is\n * identical from every exit: direct, datacenter and residential all produced it,\n * so climbing the ladder spent both paid rungs to reproduce it.\n *\n * The `android` client resolves a progressive format whose URL is honoured from\n * the same address — verified on two unrelated videos from the Runtime's own IP\n * after the default clients had 403'd. It is a *fallback*, not the default: it\n * currently offers only 360p, so it is worth reaching for once the good formats\n * have already been refused and worth nothing before that.\n */\n\n/** yt-dlp's argv for the fallback client. Appended, never substituted. */\nexport const YOUTUBE_FALLBACK_CLIENT_ARGS = [\"--extractor-args\", \"youtube:player_client=android\"] as const;\n\n/**\n * The refusal that happens *after* a format was chosen.\n *\n * Deliberately this exact phrase rather than a bare 403: a 403 raised while\n * fetching the page is a block on us, which the egress ladder already owns and\n * can actually fix. This one is raised on the media URL yt-dlp was just given,\n * which no exit IP changes.\n */\nconst MEDIA_FETCH_REFUSED = \"unable to download video data\";\n\nconst YOUTUBE_HOSTS = [\"youtube.com\", \"youtu.be\"];\n\nfunction isYouTube(url: string): boolean {\n let host: string;\n try {\n host = new URL(url).hostname.toLowerCase();\n } catch {\n return false;\n }\n return YOUTUBE_HOSTS.some((known) => host === known || host.endsWith(`.${known}`));\n}\n\n/** True when re-running with the fallback client is worth one more attempt. */\nexport function needsPlayerClientRetry(url: string, stderr: string): boolean {\n return isYouTube(url) && stderr.toLowerCase().includes(MEDIA_FETCH_REFUSED);\n}\n"],"mappings":"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","names":["path","path"]}