@koda-sl/baker-cli 0.386.0-dev.8b1f99042 → 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 (968) hide show
  1. package/README.md +1091 -211
  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-XHC4LMK4.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-VLUGGVJL.js → chunk-TPXI2GCW.js} +12 -4
  337. package/dist/chunk-TPXI2GCW.js.map +1 -0
  338. package/dist/chunk-TWNFQUBS.js +23 -0
  339. package/dist/chunk-TWNFQUBS.js.map +1 -0
  340. package/dist/chunk-U6VRBDNQ.js +1830 -0
  341. package/dist/chunk-U6VRBDNQ.js.map +1 -0
  342. package/dist/chunk-U7BBXM67.js +1743 -0
  343. package/dist/chunk-U7BBXM67.js.map +1 -0
  344. package/dist/chunk-UI6BKYQD.js +225 -0
  345. package/dist/chunk-UI6BKYQD.js.map +1 -0
  346. package/dist/chunk-USL5ARRE.js +26 -0
  347. package/dist/chunk-USL5ARRE.js.map +1 -0
  348. package/dist/chunk-UYC45JNS.js +139 -0
  349. package/dist/chunk-UYC45JNS.js.map +1 -0
  350. package/dist/chunk-V5GSRREZ.js +846 -0
  351. package/dist/chunk-V5GSRREZ.js.map +1 -0
  352. package/dist/chunk-V5HDRJQW.js +337 -0
  353. package/dist/chunk-V5HDRJQW.js.map +1 -0
  354. package/dist/chunk-VS4C7VAR.js +533 -0
  355. package/dist/chunk-VS4C7VAR.js.map +1 -0
  356. package/dist/chunk-W4W4ZRBP.js +191 -0
  357. package/dist/chunk-W4W4ZRBP.js.map +1 -0
  358. package/dist/chunk-WIRBRCTJ.js +228 -0
  359. package/dist/chunk-WIRBRCTJ.js.map +1 -0
  360. package/dist/chunk-WN4KX7GE.js +25 -0
  361. package/dist/chunk-WN4KX7GE.js.map +1 -0
  362. package/dist/chunk-WNFTXSGR.js +111 -0
  363. package/dist/chunk-WNFTXSGR.js.map +1 -0
  364. package/dist/chunk-WOTDHRNF.js +2109 -0
  365. package/dist/chunk-WOTDHRNF.js.map +1 -0
  366. package/dist/chunk-WPKOEFOE.js +103 -0
  367. package/dist/chunk-WPKOEFOE.js.map +1 -0
  368. package/dist/chunk-XE3WS3QE.js +183 -0
  369. package/dist/chunk-XE3WS3QE.js.map +1 -0
  370. package/dist/chunk-XGWKTYXQ.js +67 -0
  371. package/dist/chunk-XGWKTYXQ.js.map +1 -0
  372. package/dist/chunk-XIGIJJSF.js +66 -0
  373. package/dist/chunk-XIGIJJSF.js.map +1 -0
  374. package/dist/chunk-XNUXB63I.js +817 -0
  375. package/dist/chunk-XNUXB63I.js.map +1 -0
  376. package/dist/chunk-XQ3CCNJD.js +610 -0
  377. package/dist/chunk-XQ3CCNJD.js.map +1 -0
  378. package/dist/chunk-Y362QH54.js +98 -0
  379. package/dist/chunk-Y362QH54.js.map +1 -0
  380. package/dist/chunk-Y4HZNSBN.js +3151 -0
  381. package/dist/chunk-Y4HZNSBN.js.map +1 -0
  382. package/dist/chunk-Y4T6ATDQ.js +74 -0
  383. package/dist/chunk-Y4T6ATDQ.js.map +1 -0
  384. package/dist/chunk-YIMGUMXX.js +206 -0
  385. package/dist/chunk-YIMGUMXX.js.map +1 -0
  386. package/dist/chunk-YQSBHWOI.js +41 -0
  387. package/dist/chunk-YU26SDNT.js +46 -0
  388. package/dist/chunk-YU26SDNT.js.map +1 -0
  389. package/dist/chunk-YULENNA7.js +501 -0
  390. package/dist/chunk-YULENNA7.js.map +1 -0
  391. package/dist/chunk-YYSZYSAG.js +150 -0
  392. package/dist/chunk-YYSZYSAG.js.map +1 -0
  393. package/dist/chunk-Z3ENMCFE.js +94 -0
  394. package/dist/chunk-Z3ENMCFE.js.map +1 -0
  395. package/dist/chunk-ZCFSHQBF.js +92 -0
  396. package/dist/chunk-ZCFSHQBF.js.map +1 -0
  397. package/dist/chunk-ZH7ZM3ZM.js +125 -0
  398. package/dist/chunk-ZH7ZM3ZM.js.map +1 -0
  399. package/dist/chunk-ZIXHS6AM.js +42 -0
  400. package/dist/chunk-ZIXHS6AM.js.map +1 -0
  401. package/dist/chunk-ZLLJKSNS.js +96 -0
  402. package/dist/chunk-ZLLJKSNS.js.map +1 -0
  403. package/dist/claim-4AFNDV3A.js +197 -0
  404. package/dist/claim-4AFNDV3A.js.map +1 -0
  405. package/dist/cli.js +104 -69909
  406. package/dist/cli.js.map +1 -1
  407. package/dist/client-26SAJ46D.js +19 -0
  408. package/dist/code-MOWYJMDH.js +76 -0
  409. package/dist/code-MOWYJMDH.js.map +1 -0
  410. package/dist/companies-PZRRZZNV.js +195 -0
  411. package/dist/companies-PZRRZZNV.js.map +1 -0
  412. package/dist/complete-IBW5DNVZ.js +81 -0
  413. package/dist/complete-IBW5DNVZ.js.map +1 -0
  414. package/dist/config-X6GKOVQ6.js +88 -0
  415. package/dist/config-X6GKOVQ6.js.map +1 -0
  416. package/dist/connect-WYUYS5V4.js +42 -0
  417. package/dist/content-UYZC4AKN.js +85 -0
  418. package/dist/content-UYZC4AKN.js.map +1 -0
  419. package/dist/conversation-6AG3UBYY.js +93 -0
  420. package/dist/conversation-6AG3UBYY.js.map +1 -0
  421. package/dist/conversion-report-R4GJWWTK.js +125 -0
  422. package/dist/conversion-report-R4GJWWTK.js.map +1 -0
  423. package/dist/conversion-upload-command-YML2UNJB.js +438 -0
  424. package/dist/conversion-upload-command-YML2UNJB.js.map +1 -0
  425. package/dist/conversion-writes-WHFFUWWL.js +120 -0
  426. package/dist/conversion-writes-WHFFUWWL.js.map +1 -0
  427. package/dist/conversions-NOBBFNIU.js +135 -0
  428. package/dist/conversions-NOBBFNIU.js.map +1 -0
  429. package/dist/conversions-OXJAX5GB.js +76 -0
  430. package/dist/conversions-OXJAX5GB.js.map +1 -0
  431. package/dist/countries-PBXNB3BR.js +82 -0
  432. package/dist/countries-PBXNB3BR.js.map +1 -0
  433. package/dist/create-JK42P564.js +59 -0
  434. package/dist/create-JK42P564.js.map +1 -0
  435. package/dist/create-LAWUVPCY.js +207 -0
  436. package/dist/create-LAWUVPCY.js.map +1 -0
  437. package/dist/create-MUPQ5CTH.js +138 -0
  438. package/dist/create-MUPQ5CTH.js.map +1 -0
  439. package/dist/create-NQJNCFRO.js +236 -0
  440. package/dist/create-NQJNCFRO.js.map +1 -0
  441. package/dist/creatives-KCWFZIM5.js +182 -0
  442. package/dist/creatives-KCWFZIM5.js.map +1 -0
  443. package/dist/creatives-NNDWCSKJ.js +51 -0
  444. package/dist/creatives-NNDWCSKJ.js.map +1 -0
  445. package/dist/creatives-RHNHTS2R.js +87 -0
  446. package/dist/creatives-RHNHTS2R.js.map +1 -0
  447. package/dist/credentials-CEKGXR2C.js +287 -0
  448. package/dist/credentials-CEKGXR2C.js.map +1 -0
  449. package/dist/critique-HDDYER52.js +1449 -0
  450. package/dist/critique-HDDYER52.js.map +1 -0
  451. package/dist/critique-QIN2FO4F.js +216 -0
  452. package/dist/critique-QIN2FO4F.js.map +1 -0
  453. package/dist/crm-KBPWZC6J.js +318 -0
  454. package/dist/crm-KBPWZC6J.js.map +1 -0
  455. package/dist/crm-QBWD7CWB.js +224 -0
  456. package/dist/crm-QBWD7CWB.js.map +1 -0
  457. package/dist/crop-U3AD4DDR.js +113 -0
  458. package/dist/crop-U3AD4DDR.js.map +1 -0
  459. package/dist/currency-XTFGZFGB.js +88 -0
  460. package/dist/currency-XTFGZFGB.js.map +1 -0
  461. package/dist/custom-conversions-W3K33V33.js +125 -0
  462. package/dist/custom-conversions-W3K33V33.js.map +1 -0
  463. package/dist/customers-HYE7N2H5.js +56 -0
  464. package/dist/decide-YTHCBKM6.js +199 -0
  465. package/dist/decide-YTHCBKM6.js.map +1 -0
  466. package/dist/delete-64REPCY2.js +54 -0
  467. package/dist/delete-64REPCY2.js.map +1 -0
  468. package/dist/delete-AY3KL3N3.js +63 -0
  469. package/dist/delete-AY3KL3N3.js.map +1 -0
  470. package/dist/delete-DZUDLYPC.js +69 -0
  471. package/dist/delete-DZUDLYPC.js.map +1 -0
  472. package/dist/delete-NZGZP4YP.js +71 -0
  473. package/dist/delete-NZGZP4YP.js.map +1 -0
  474. package/dist/delete-VO2LZXE4.js +66 -0
  475. package/dist/delete-VO2LZXE4.js.map +1 -0
  476. package/dist/delete-VQMU56OH.js +71 -0
  477. package/dist/delete-VQMU56OH.js.map +1 -0
  478. package/dist/demographics-KOFLMGVW.js +138 -0
  479. package/dist/demographics-KOFLMGVW.js.map +1 -0
  480. package/dist/describe-JNTCQZNL.js +97 -0
  481. package/dist/describe-JNTCQZNL.js.map +1 -0
  482. package/dist/describe-MT4334NG.js +97 -0
  483. package/dist/describe-MT4334NG.js.map +1 -0
  484. package/dist/dimensions-FEZUJRAG.js +101 -0
  485. package/dist/dimensions-FEZUJRAG.js.map +1 -0
  486. package/dist/discard-H4RPXZHX.js +66 -0
  487. package/dist/discard-H4RPXZHX.js.map +1 -0
  488. package/dist/discover-4GD7QSF5.js +93 -0
  489. package/dist/discover-4GD7QSF5.js.map +1 -0
  490. package/dist/discover-L7OVXW4V.js +172 -0
  491. package/dist/discover-L7OVXW4V.js.map +1 -0
  492. package/dist/domain-HURQ23KR.js +98 -0
  493. package/dist/domain-HURQ23KR.js.map +1 -0
  494. package/dist/download-L27HWEOE.js +299 -0
  495. package/dist/download-L27HWEOE.js.map +1 -0
  496. package/dist/draft-25G2P2TE.js +281 -0
  497. package/dist/draft-25G2P2TE.js.map +1 -0
  498. package/dist/draft-5VH2PW3R.js +307 -0
  499. package/dist/draft-5VH2PW3R.js.map +1 -0
  500. package/dist/draft-D6UTKSAA.js +217 -0
  501. package/dist/draft-D6UTKSAA.js.map +1 -0
  502. package/dist/draft-KLULNBWP.js +233 -0
  503. package/dist/draft-KLULNBWP.js.map +1 -0
  504. package/dist/draft-MI7RWY2K.js +100 -0
  505. package/dist/draft-MI7RWY2K.js.map +1 -0
  506. package/dist/draft-P4IVYTY3.js +103 -0
  507. package/dist/draft-P4IVYTY3.js.map +1 -0
  508. package/dist/draft-UQYWDZS7.js +306 -0
  509. package/dist/draft-UQYWDZS7.js.map +1 -0
  510. package/dist/draft-YFAJHCKM.js +328 -0
  511. package/dist/draft-YFAJHCKM.js.map +1 -0
  512. package/dist/engine/index.d.ts +213 -127
  513. package/dist/engine/index.js +18 -4
  514. package/dist/{env-4P5HOGNA.js → env-FBTHZKGN.js} +12 -2
  515. package/dist/env-FBTHZKGN.js.map +1 -0
  516. package/dist/experiment-HDYTJPUY.js +1397 -0
  517. package/dist/experiment-HDYTJPUY.js.map +1 -0
  518. package/dist/export-TS5GYEMA.js +168 -0
  519. package/dist/export-TS5GYEMA.js.map +1 -0
  520. package/dist/extract-QVQFUOIK.js +113 -0
  521. package/dist/extract-QVQFUOIK.js.map +1 -0
  522. package/dist/facets-WYQUZMFJ.js +114 -0
  523. package/dist/facets-WYQUZMFJ.js.map +1 -0
  524. package/dist/favorites-7QP7BY5K.js +178 -0
  525. package/dist/favorites-7QP7BY5K.js.map +1 -0
  526. package/dist/feed-EETRO2FG.js +177 -0
  527. package/dist/feed-EETRO2FG.js.map +1 -0
  528. package/dist/feedback-SIMPRE37.js +66 -0
  529. package/dist/feedback-SIMPRE37.js.map +1 -0
  530. package/dist/feedback-record-L4MPIVML.js +177 -0
  531. package/dist/feedback-record-L4MPIVML.js.map +1 -0
  532. package/dist/fetch-DTBM3DE2.js +176 -0
  533. package/dist/fetch-DTBM3DE2.js.map +1 -0
  534. package/dist/fetch-Z7O3ZL4D.js +139 -0
  535. package/dist/fetch-Z7O3ZL4D.js.map +1 -0
  536. package/dist/find-KAQ6JDMO.js +134 -0
  537. package/dist/find-KAQ6JDMO.js.map +1 -0
  538. package/dist/fit-MY5GVZZZ.js +45 -0
  539. package/dist/fit-MY5GVZZZ.js.map +1 -0
  540. package/dist/flows-IUDXVDOS.js +247 -0
  541. package/dist/flows-IUDXVDOS.js.map +1 -0
  542. package/dist/follow-IX4XVK5Y.js +94 -0
  543. package/dist/follow-IX4XVK5Y.js.map +1 -0
  544. package/dist/follow-competitors-UZBUOYTH.js +112 -0
  545. package/dist/follow-competitors-UZBUOYTH.js.map +1 -0
  546. package/dist/following-VGOIUCIZ.js +113 -0
  547. package/dist/following-VGOIUCIZ.js.map +1 -0
  548. package/dist/fonts-EUDHI6CA.js +34 -0
  549. package/dist/fonts-EUDHI6CA.js.map +1 -0
  550. package/dist/forecast-BRSEH2H3.js +104 -0
  551. package/dist/forecast-BRSEH2H3.js.map +1 -0
  552. package/dist/forecast-QV4U7TOY.js +168 -0
  553. package/dist/forecast-QV4U7TOY.js.map +1 -0
  554. package/dist/funding-H5YO37OW.js +85 -0
  555. package/dist/funding-H5YO37OW.js.map +1 -0
  556. package/dist/funnel-JLF77MLF.js +394 -0
  557. package/dist/funnel-JLF77MLF.js.map +1 -0
  558. package/dist/ga4-YHJ2XMLC.js +55 -0
  559. package/dist/ga4-YHJ2XMLC.js.map +1 -0
  560. package/dist/generate-M2ZX5DMI.js +262 -0
  561. package/dist/generate-M2ZX5DMI.js.map +1 -0
  562. package/dist/get-4EYKCZ6F.js +59 -0
  563. package/dist/get-4EYKCZ6F.js.map +1 -0
  564. package/dist/get-637GALM2.js +63 -0
  565. package/dist/get-637GALM2.js.map +1 -0
  566. package/dist/get-AYX5HS64.js +56 -0
  567. package/dist/get-AYX5HS64.js.map +1 -0
  568. package/dist/get-AZARFR6O.js +61 -0
  569. package/dist/get-AZARFR6O.js.map +1 -0
  570. package/dist/get-EG2U7MIL.js +78 -0
  571. package/dist/get-EG2U7MIL.js.map +1 -0
  572. package/dist/get-N4BPOQCB.js +63 -0
  573. package/dist/get-N4BPOQCB.js.map +1 -0
  574. package/dist/get-RPZHLQ56.js +92 -0
  575. package/dist/get-RPZHLQ56.js.map +1 -0
  576. package/dist/gif-6PRTB2VR.js +94 -0
  577. package/dist/gif-6PRTB2VR.js.map +1 -0
  578. package/dist/google-52JRH7X3.js +136 -0
  579. package/dist/google-52JRH7X3.js.map +1 -0
  580. package/dist/google-ITTPCJ7N.js +3190 -0
  581. package/dist/google-ITTPCJ7N.js.map +1 -0
  582. package/dist/google-ads-U3JFFQLU.js +195 -0
  583. package/dist/google-ads-U3JFFQLU.js.map +1 -0
  584. package/dist/group-AAZ5QKC3.js +43 -0
  585. package/dist/group-AAZ5QKC3.js.map +1 -0
  586. package/dist/group-GSYCZORC.js +43 -0
  587. package/dist/group-GSYCZORC.js.map +1 -0
  588. package/dist/gsc-TS5T7ML2.js +30 -0
  589. package/dist/gsc-TS5T7ML2.js.map +1 -0
  590. package/dist/history-EW6LFFCX.js +67 -0
  591. package/dist/history-EW6LFFCX.js.map +1 -0
  592. package/dist/history-YTNCWSV3.js +133 -0
  593. package/dist/history-YTNCWSV3.js.map +1 -0
  594. package/dist/hubspot-LXWQNKKB.js +779 -0
  595. package/dist/hubspot-LXWQNKKB.js.map +1 -0
  596. package/dist/icon-K75KI6BV.js +137 -0
  597. package/dist/icon-K75KI6BV.js.map +1 -0
  598. package/dist/ideas-JJIHQFV4.js +35 -0
  599. package/dist/ideas-JJIHQFV4.js.map +1 -0
  600. package/dist/images-MWETBYKB.js +90 -0
  601. package/dist/images-MWETBYKB.js.map +1 -0
  602. package/dist/improve-L3BW4EQG.js +86 -0
  603. package/dist/improve-L3BW4EQG.js.map +1 -0
  604. package/dist/ingest-THFAV4NO.js +107 -0
  605. package/dist/ingest-THFAV4NO.js.map +1 -0
  606. package/dist/ingest-U6B7GR4A.js +23 -0
  607. package/dist/ingest-U6B7GR4A.js.map +1 -0
  608. package/dist/insights-FA6T6PT6.js +423 -0
  609. package/dist/insights-FA6T6PT6.js.map +1 -0
  610. package/dist/insights-PELVD4RY.js +122 -0
  611. package/dist/insights-PELVD4RY.js.map +1 -0
  612. package/dist/inspect-N2WVVWGP.js +189 -0
  613. package/dist/inspect-N2WVVWGP.js.map +1 -0
  614. package/dist/inspiration-Y2J2PUPC.js +53 -0
  615. package/dist/inspiration-Y2J2PUPC.js.map +1 -0
  616. package/dist/intent-YNAAVNHK.js +95 -0
  617. package/dist/intent-YNAAVNHK.js.map +1 -0
  618. package/dist/job-E2U4FS5P.js +202 -0
  619. package/dist/job-E2U4FS5P.js.map +1 -0
  620. package/dist/job-create-DFYCHVQ7.js +109 -0
  621. package/dist/job-create-DFYCHVQ7.js.map +1 -0
  622. package/dist/job-status-FFPMTSHB.js +74 -0
  623. package/dist/job-status-FFPMTSHB.js.map +1 -0
  624. package/dist/keep-GYZS2UTL.js +78 -0
  625. package/dist/keep-GYZS2UTL.js.map +1 -0
  626. package/dist/keyword-gap-4JKLWIBJ.js +130 -0
  627. package/dist/keyword-gap-4JKLWIBJ.js.map +1 -0
  628. package/dist/keyword-metrics-KU3OHTQK.js +197 -0
  629. package/dist/keyword-metrics-KU3OHTQK.js.map +1 -0
  630. package/dist/keywords-for-site-M4MFWMVK.js +128 -0
  631. package/dist/keywords-for-site-M4MFWMVK.js.map +1 -0
  632. package/dist/landing-7UVZ7IPP.js +28 -0
  633. package/dist/landing-7UVZ7IPP.js.map +1 -0
  634. package/dist/landings-F7LOAEJE.js +151 -0
  635. package/dist/landings-F7LOAEJE.js.map +1 -0
  636. package/dist/languages-PKYCZNUB.js +40 -0
  637. package/dist/languages-PKYCZNUB.js.map +1 -0
  638. package/dist/languages-XEJKTIFP.js +55 -0
  639. package/dist/languages-XEJKTIFP.js.map +1 -0
  640. package/dist/launches-TCFAYUA5.js +19 -0
  641. package/dist/launches-TCFAYUA5.js.map +1 -0
  642. package/dist/layerize-ZSKFIPZA.js +190 -0
  643. package/dist/layerize-ZSKFIPZA.js.map +1 -0
  644. package/dist/leads-CSRESOB2.js +293 -0
  645. package/dist/leads-CSRESOB2.js.map +1 -0
  646. package/dist/leads-MQPEA7DG.js +90 -0
  647. package/dist/leads-MQPEA7DG.js.map +1 -0
  648. package/dist/learn-K5YBUMBT.js +203 -0
  649. package/dist/learn-K5YBUMBT.js.map +1 -0
  650. package/dist/library-IP2UKNRU.js +109 -0
  651. package/dist/library-IP2UKNRU.js.map +1 -0
  652. package/dist/lighthouse-57XBJRCO.js +75 -0
  653. package/dist/lighthouse-57XBJRCO.js.map +1 -0
  654. package/dist/line-item-writes-73NR2J5L.js +208 -0
  655. package/dist/line-item-writes-73NR2J5L.js.map +1 -0
  656. package/dist/line-items-2YBGXOAQ.js +103 -0
  657. package/dist/line-items-2YBGXOAQ.js.map +1 -0
  658. package/dist/link-GVAWECJO.js +64 -0
  659. package/dist/link-GVAWECJO.js.map +1 -0
  660. package/dist/linkedin-PZDT22AT.js +1008 -0
  661. package/dist/linkedin-PZDT22AT.js.map +1 -0
  662. package/dist/list-6IKPWQGG.js +57 -0
  663. package/dist/list-6IKPWQGG.js.map +1 -0
  664. package/dist/list-CAUH3BMG.js +65 -0
  665. package/dist/list-CAUH3BMG.js.map +1 -0
  666. package/dist/list-FNDRV25Y.js +151 -0
  667. package/dist/list-FNDRV25Y.js.map +1 -0
  668. package/dist/list-GTOSN7DP.js +50 -0
  669. package/dist/list-GTOSN7DP.js.map +1 -0
  670. package/dist/list-HLJP4NVE.js +51 -0
  671. package/dist/list-HLJP4NVE.js.map +1 -0
  672. package/dist/list-LCUPF7EF.js +76 -0
  673. package/dist/list-LCUPF7EF.js.map +1 -0
  674. package/dist/list-REZGFWC5.js +63 -0
  675. package/dist/list-REZGFWC5.js.map +1 -0
  676. package/dist/list-S6MNXDTV.js +303 -0
  677. package/dist/list-S6MNXDTV.js.map +1 -0
  678. package/dist/locations-2BYWKIYA.js +67 -0
  679. package/dist/locations-2BYWKIYA.js.map +1 -0
  680. package/dist/locations-GJHHMV6Z.js +40 -0
  681. package/dist/locations-GJHHMV6Z.js.map +1 -0
  682. package/dist/log-HGDNLDUX.js +92 -0
  683. package/dist/log-HGDNLDUX.js.map +1 -0
  684. package/dist/logo-AJK2TDQU.js +18 -0
  685. package/dist/logo-AJK2TDQU.js.map +1 -0
  686. package/dist/lookup-H5GEM77H.js +22 -0
  687. package/dist/lookup-H5GEM77H.js.map +1 -0
  688. package/dist/make-BT26YJXZ.js +640 -0
  689. package/dist/make-BT26YJXZ.js.map +1 -0
  690. package/dist/map-J5EX4HOX.js +404 -0
  691. package/dist/map-J5EX4HOX.js.map +1 -0
  692. package/dist/mcp-MHDW6AFL.js +463 -0
  693. package/dist/mcp-MHDW6AFL.js.map +1 -0
  694. package/dist/media-RAGEJTZX.js +89 -0
  695. package/dist/media-RAGEJTZX.js.map +1 -0
  696. package/dist/media-RNB7JFJP.js +15 -0
  697. package/dist/media-RNB7JFJP.js.map +1 -0
  698. package/dist/media-sources-4NN3DWSG.js +32 -0
  699. package/dist/media-sources-4NN3DWSG.js.map +1 -0
  700. package/dist/members-AIWMXAQD.js +44 -0
  701. package/dist/members-AIWMXAQD.js.map +1 -0
  702. package/dist/meta-WAPZMZI7.js +69 -0
  703. package/dist/meta-WAPZMZI7.js.map +1 -0
  704. package/dist/metrics-6EHC4ESN.js +152 -0
  705. package/dist/metrics-6EHC4ESN.js.map +1 -0
  706. package/dist/models-5J4WFUD3.js +155 -0
  707. package/dist/models-5J4WFUD3.js.map +1 -0
  708. package/dist/normalize-DSFVTRXN.js +806 -0
  709. package/dist/normalize-DSFVTRXN.js.map +1 -0
  710. package/dist/normalize-ZAWN4XCS.js +141 -0
  711. package/dist/normalize-ZAWN4XCS.js.map +1 -0
  712. package/dist/options-3CZNT5KP.js +121 -0
  713. package/dist/options-3CZNT5KP.js.map +1 -0
  714. package/dist/output-DTCLVPUF.js +24 -0
  715. package/dist/output-DTCLVPUF.js.map +1 -0
  716. package/dist/page-N2ZO3O7F.js +105 -0
  717. package/dist/page-N2ZO3O7F.js.map +1 -0
  718. package/dist/pages-FQ4CBAJ2.js +66 -0
  719. package/dist/pages-FQ4CBAJ2.js.map +1 -0
  720. package/dist/performance-GOMJMHPE.js +24 -0
  721. package/dist/performance-GOMJMHPE.js.map +1 -0
  722. package/dist/pinterest-NV5XTNJE.js +96 -0
  723. package/dist/pinterest-NV5XTNJE.js.map +1 -0
  724. package/dist/pixels-CTJ43FZ4.js +108 -0
  725. package/dist/pixels-CTJ43FZ4.js.map +1 -0
  726. package/dist/pixels-HKINGZCH.js +60 -0
  727. package/dist/pixels-HKINGZCH.js.map +1 -0
  728. package/dist/plan-ZYTWLGWK.js +207 -0
  729. package/dist/plan-ZYTWLGWK.js.map +1 -0
  730. package/dist/preview-UKYLPAW2.js +169 -0
  731. package/dist/preview-UKYLPAW2.js.map +1 -0
  732. package/dist/profile-Q3PHR6FU.js +159 -0
  733. package/dist/profile-Q3PHR6FU.js.map +1 -0
  734. package/dist/promoted-tweet-writes-IYOAZTA5.js +180 -0
  735. package/dist/promoted-tweet-writes-IYOAZTA5.js.map +1 -0
  736. package/dist/promoted-tweets-G3XFD5YM.js +119 -0
  737. package/dist/promoted-tweets-G3XFD5YM.js.map +1 -0
  738. package/dist/properties-WLL6M2P6.js +101 -0
  739. package/dist/properties-WLL6M2P6.js.map +1 -0
  740. package/dist/publish-ZG4J2GTH.js +322 -0
  741. package/dist/publish-ZG4J2GTH.js.map +1 -0
  742. package/dist/query-7AGG77WH.js +61 -0
  743. package/dist/query-7AGG77WH.js.map +1 -0
  744. package/dist/query-IYZN5KHO.js +236 -0
  745. package/dist/query-IYZN5KHO.js.map +1 -0
  746. package/dist/query-UN2P6DBA.js +247 -0
  747. package/dist/query-UN2P6DBA.js.map +1 -0
  748. package/dist/questionnaire-Z2ZIKNBV.js +93 -0
  749. package/dist/questionnaire-Z2ZIKNBV.js.map +1 -0
  750. package/dist/read-GM7PQYJA.js +141 -0
  751. package/dist/read-GM7PQYJA.js.map +1 -0
  752. package/dist/reddit-FTO4SFQE.js +26 -0
  753. package/dist/reddit-FTO4SFQE.js.map +1 -0
  754. package/dist/refresh-OUENQ2FS.js +94 -0
  755. package/dist/refresh-OUENQ2FS.js.map +1 -0
  756. package/dist/release-5OG7AAFY.js +60 -0
  757. package/dist/release-5OG7AAFY.js.map +1 -0
  758. package/dist/relevant-pages-KUVDZPRU.js +99 -0
  759. package/dist/relevant-pages-KUVDZPRU.js.map +1 -0
  760. package/dist/remove-33HI27KM.js +50 -0
  761. package/dist/remove-33HI27KM.js.map +1 -0
  762. package/dist/remove-GOYW2G4R.js +48 -0
  763. package/dist/remove-GOYW2G4R.js.map +1 -0
  764. package/dist/reopen-KFFYE53A.js +63 -0
  765. package/dist/reopen-KFFYE53A.js.map +1 -0
  766. package/dist/rerun-P6XACA5Z.js +86 -0
  767. package/dist/rerun-P6XACA5Z.js.map +1 -0
  768. package/dist/research-BEO3JMZI.js +262 -0
  769. package/dist/research-BEO3JMZI.js.map +1 -0
  770. package/dist/research-QOC53DLS.js +62 -0
  771. package/dist/research-QOC53DLS.js.map +1 -0
  772. package/dist/reset-E3OWE2WF.js +54 -0
  773. package/dist/reset-E3OWE2WF.js.map +1 -0
  774. package/dist/reset-I7M3HYMB.js +54 -0
  775. package/dist/reset-I7M3HYMB.js.map +1 -0
  776. package/dist/resolve-GP7BHM6L.js +121 -0
  777. package/dist/resolve-GP7BHM6L.js.map +1 -0
  778. package/dist/retry-33ZJCNQI.js +62 -0
  779. package/dist/retry-33ZJCNQI.js.map +1 -0
  780. package/dist/retry-X5PU7QO3.js +60 -0
  781. package/dist/retry-X5PU7QO3.js.map +1 -0
  782. package/dist/retry-failed-BEFWRV4Z.js +45 -0
  783. package/dist/retry-failed-BEFWRV4Z.js.map +1 -0
  784. package/dist/run-REK3TEGY.js +65 -0
  785. package/dist/run-REK3TEGY.js.map +1 -0
  786. package/dist/run-TH2662IC.js +61 -0
  787. package/dist/run-TH2662IC.js.map +1 -0
  788. package/dist/scaffold-ad-3WDRKUFT.js +1550 -0
  789. package/dist/scaffold-ad-3WDRKUFT.js.map +1 -0
  790. package/dist/scaffold-static-ad-X5NT52NF.js +973 -0
  791. package/dist/scaffold-static-ad-X5NT52NF.js.map +1 -0
  792. package/dist/scaffold-video-WZPVACLE.js +874 -0
  793. package/dist/scaffold-video-WZPVACLE.js.map +1 -0
  794. package/dist/schedule-KQ7UIR3N.js +66 -0
  795. package/dist/schedule-KQ7UIR3N.js.map +1 -0
  796. package/dist/schedule-V4UHGY3V.js +61 -0
  797. package/dist/schedule-V4UHGY3V.js.map +1 -0
  798. package/dist/scheduled-agents-KLQ5H2PA.js +49 -0
  799. package/dist/scheduled-agents-KLQ5H2PA.js.map +1 -0
  800. package/dist/schema-G3T4PZDI.js +132 -0
  801. package/dist/schema-G3T4PZDI.js.map +1 -0
  802. package/dist/schema-QXTDLZVC.js +63 -0
  803. package/dist/schema-QXTDLZVC.js.map +1 -0
  804. package/dist/scrape-7YKJWFZE.js +2241 -0
  805. package/dist/scrape-7YKJWFZE.js.map +1 -0
  806. package/dist/screenshot-ZHBSG3SI.js +102 -0
  807. package/dist/screenshot-ZHBSG3SI.js.map +1 -0
  808. package/dist/search-332KFYZ6.js +224 -0
  809. package/dist/search-332KFYZ6.js.map +1 -0
  810. package/dist/search-4PBMXXUY.js +91 -0
  811. package/dist/search-4PBMXXUY.js.map +1 -0
  812. package/dist/search-6XKEGABN.js +174 -0
  813. package/dist/search-6XKEGABN.js.map +1 -0
  814. package/dist/search-AVNUU6TJ.js +26 -0
  815. package/dist/search-AVNUU6TJ.js.map +1 -0
  816. package/dist/search-F5INRFFK.js +92 -0
  817. package/dist/search-F5INRFFK.js.map +1 -0
  818. package/dist/search-copy-DZVBYG2B.js +168 -0
  819. package/dist/search-copy-DZVBYG2B.js.map +1 -0
  820. package/dist/seeds-5JTQN5WI.js +101 -0
  821. package/dist/seeds-5JTQN5WI.js.map +1 -0
  822. package/dist/select-N2V55BEX.js +96 -0
  823. package/dist/select-N2V55BEX.js.map +1 -0
  824. package/dist/sends-3L6QBS46.js +309 -0
  825. package/dist/sends-3L6QBS46.js.map +1 -0
  826. package/dist/sequences-YKFV7BDH.js +146 -0
  827. package/dist/sequences-YKFV7BDH.js.map +1 -0
  828. package/dist/set-prompt-7HVHERRU.js +188 -0
  829. package/dist/set-prompt-7HVHERRU.js.map +1 -0
  830. package/dist/setup-links-4VVNQVPU.js +141 -0
  831. package/dist/setup-links-4VVNQVPU.js.map +1 -0
  832. package/dist/{shared-J7DQZ2ED.js → shared-QAMP7FZV.js} +8 -6
  833. package/dist/shared-QAMP7FZV.js.map +1 -0
  834. package/dist/shopify-FSHM5M4I.js +3346 -0
  835. package/dist/shopify-FSHM5M4I.js.map +1 -0
  836. package/dist/site-Q2HTRLIW.js +177 -0
  837. package/dist/site-Q2HTRLIW.js.map +1 -0
  838. package/dist/sitemaps-XPGLW24S.js +87 -0
  839. package/dist/sitemaps-XPGLW24S.js.map +1 -0
  840. package/dist/sites-WMBY2HJV.js +101 -0
  841. package/dist/sites-WMBY2HJV.js.map +1 -0
  842. package/dist/skills-3HEILQCU.js +47 -0
  843. package/dist/skills-3HEILQCU.js.map +1 -0
  844. package/dist/sources-2KN4RJNJ.js +30 -0
  845. package/dist/sources-2KN4RJNJ.js.map +1 -0
  846. package/dist/sources-4I2YMS2K.js +421 -0
  847. package/dist/sources-4I2YMS2K.js.map +1 -0
  848. package/dist/stale-IN7WSBLC.js +66 -0
  849. package/dist/stale-IN7WSBLC.js.map +1 -0
  850. package/dist/stats-GNILHSKK.js +34 -0
  851. package/dist/stats-GNILHSKK.js.map +1 -0
  852. package/dist/status-6SLKZWNR.js +62 -0
  853. package/dist/status-6SLKZWNR.js.map +1 -0
  854. package/dist/sticker-KCV3VZHY.js +94 -0
  855. package/dist/sticker-KCV3VZHY.js.map +1 -0
  856. package/dist/stock-VTORKR4C.js +179 -0
  857. package/dist/stock-VTORKR4C.js.map +1 -0
  858. package/dist/studio-QCRA6BY5.js +49 -0
  859. package/dist/studio-QCRA6BY5.js.map +1 -0
  860. package/dist/sync-455DB46Y.js +54 -0
  861. package/dist/sync-455DB46Y.js.map +1 -0
  862. package/dist/sync-A4KKQ3B6.js +265 -0
  863. package/dist/sync-A4KKQ3B6.js.map +1 -0
  864. package/dist/sync-LFZV5NBN.js +54 -0
  865. package/dist/sync-LFZV5NBN.js.map +1 -0
  866. package/dist/sync-definition-IJISZ5VQ.js +55 -0
  867. package/dist/sync-definition-IJISZ5VQ.js.map +1 -0
  868. package/dist/tag-manager-E7QTXBWQ.js +43 -0
  869. package/dist/tag-manager-E7QTXBWQ.js.map +1 -0
  870. package/dist/tags-6OAZOQYO.js +26 -0
  871. package/dist/tags-6OAZOQYO.js.map +1 -0
  872. package/dist/tags-6YRMDX3R.js +20 -0
  873. package/dist/tags-6YRMDX3R.js.map +1 -0
  874. package/dist/tags-EWXZSZYE.js +20 -0
  875. package/dist/tags-EWXZSZYE.js.map +1 -0
  876. package/dist/tags-SZCNPE2D.js +224 -0
  877. package/dist/tags-SZCNPE2D.js.map +1 -0
  878. package/dist/tags-TCFFP534.js +20 -0
  879. package/dist/tags-TCFFP534.js.map +1 -0
  880. package/dist/targeting-constants-D64YO3E7.js +118 -0
  881. package/dist/targeting-constants-D64YO3E7.js.map +1 -0
  882. package/dist/targeting-criteria-ESOC7KNX.js +113 -0
  883. package/dist/targeting-criteria-ESOC7KNX.js.map +1 -0
  884. package/dist/targets-IPBEB5KU.js +102 -0
  885. package/dist/targets-IPBEB5KU.js.map +1 -0
  886. package/dist/templates-IJ7FR3LA.js +178 -0
  887. package/dist/templates-IJ7FR3LA.js.map +1 -0
  888. package/dist/testimonials-IXS7CP6P.js +32 -0
  889. package/dist/testimonials-IXS7CP6P.js.map +1 -0
  890. package/dist/themes-MXNKJWMW.js +94 -0
  891. package/dist/themes-MXNKJWMW.js.map +1 -0
  892. package/dist/top-companies-NO6L2V6M.js +108 -0
  893. package/dist/top-companies-NO6L2V6M.js.map +1 -0
  894. package/dist/translate-QCE5ZB7M.js +600 -0
  895. package/dist/translate-QCE5ZB7M.js.map +1 -0
  896. package/dist/triggers-KXUDMDSA.js +141 -0
  897. package/dist/triggers-KXUDMDSA.js.map +1 -0
  898. package/dist/tweets-ZUKQAAUQ.js +123 -0
  899. package/dist/tweets-ZUKQAAUQ.js.map +1 -0
  900. package/dist/unfollow-A4JVCJBF.js +46 -0
  901. package/dist/unfollow-A4JVCJBF.js.map +1 -0
  902. package/dist/unlink-E3N36NYQ.js +67 -0
  903. package/dist/unlink-E3N36NYQ.js.map +1 -0
  904. package/dist/unstage-TRMHSHED.js +84 -0
  905. package/dist/unstage-TRMHSHED.js.map +1 -0
  906. package/dist/unstage-ZRLLCSQF.js +95 -0
  907. package/dist/unstage-ZRLLCSQF.js.map +1 -0
  908. package/dist/update-EWGWAXAQ.js +142 -0
  909. package/dist/update-EWGWAXAQ.js.map +1 -0
  910. package/dist/update-OKOQE7U2.js +155 -0
  911. package/dist/update-OKOQE7U2.js.map +1 -0
  912. package/dist/update-VSFHID2D.js +63 -0
  913. package/dist/update-VSFHID2D.js.map +1 -0
  914. package/dist/update-XGCGQDJ4.js +98 -0
  915. package/dist/update-XGCGQDJ4.js.map +1 -0
  916. package/dist/upload-BOYMDDEQ.js +126 -0
  917. package/dist/upload-BOYMDDEQ.js.map +1 -0
  918. package/dist/upload-XEHWYMJG.js +150 -0
  919. package/dist/upload-XEHWYMJG.js.map +1 -0
  920. package/dist/upscale-I5P2OHTN.js +109 -0
  921. package/dist/upscale-I5P2OHTN.js.map +1 -0
  922. package/dist/url-options-PCZEQE66.js +130 -0
  923. package/dist/url-options-PCZEQE66.js.map +1 -0
  924. package/dist/url-params-DV37GEQF.js +98 -0
  925. package/dist/url-params-DV37GEQF.js.map +1 -0
  926. package/dist/use-U4HG2NF3.js +95 -0
  927. package/dist/use-U4HG2NF3.js.map +1 -0
  928. package/dist/validate-5AV4FJZ5.js +91 -0
  929. package/dist/validate-5AV4FJZ5.js.map +1 -0
  930. package/dist/variant-FOVE6URJ.js +338 -0
  931. package/dist/variant-FOVE6URJ.js.map +1 -0
  932. package/dist/videos-IJ67PPJV.js +39 -0
  933. package/dist/videos-IJ67PPJV.js.map +1 -0
  934. package/dist/view-HRI3FHCH.js +121 -0
  935. package/dist/view-HRI3FHCH.js.map +1 -0
  936. package/dist/viewer-check-JYUE24M6.js +68 -0
  937. package/dist/viewer-check-JYUE24M6.js.map +1 -0
  938. package/dist/web-LJ36FRWD.js +140 -0
  939. package/dist/web-LJ36FRWD.js.map +1 -0
  940. package/dist/winners-SMMDN6LW.js +113 -0
  941. package/dist/winners-SMMDN6LW.js.map +1 -0
  942. package/dist/winning-ads-JIG2MQHJ.js +84 -0
  943. package/dist/winning-ads-JIG2MQHJ.js.map +1 -0
  944. package/dist/write-commands-7Z34WG2J.js +206 -0
  945. package/dist/write-commands-7Z34WG2J.js.map +1 -0
  946. package/dist/write-commands-BLT2SEC4.js +713 -0
  947. package/dist/write-commands-BLT2SEC4.js.map +1 -0
  948. package/dist/write-commands-GOZU6ENR.js +1015 -0
  949. package/dist/write-commands-GOZU6ENR.js.map +1 -0
  950. package/dist/write-commands-KA3QXVSF.js +737 -0
  951. package/dist/write-commands-KA3QXVSF.js.map +1 -0
  952. package/dist/x-6HBVXIKH.js +47 -0
  953. package/dist/x-6HBVXIKH.js.map +1 -0
  954. package/package.json +9 -2
  955. package/dist/chunk-CHJOTJTZ.js +0 -9989
  956. package/dist/chunk-CHJOTJTZ.js.map +0 -1
  957. package/dist/chunk-HJEMOSPH.js +0 -1292
  958. package/dist/chunk-HJEMOSPH.js.map +0 -1
  959. package/dist/chunk-MF7YA62W.js.map +0 -1
  960. package/dist/chunk-VLUGGVJL.js.map +0 -1
  961. package/dist/chunk-VZEDAFAR.js.map +0 -1
  962. package/dist/chunk-XHC4LMK4.js.map +0 -1
  963. package/dist/client-GR6YL3YX.js +0 -17
  964. package/dist/output-NMQXZF3Z.js +0 -18
  965. /package/dist/{client-GR6YL3YX.js.map → chunk-YQSBHWOI.js.map} +0 -0
  966. /package/dist/{env-4P5HOGNA.js.map → client-26SAJ46D.js.map} +0 -0
  967. /package/dist/{output-NMQXZF3Z.js.map → connect-WYUYS5V4.js.map} +0 -0
  968. /package/dist/{shared-J7DQZ2ED.js.map → customers-HYE7N2H5.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/research/customers.ts"],"sourcesContent":["import { mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type {\n ResearchFetchRequest,\n ResearchFetchResponse,\n ResearchRedditItem,\n TestimonialsSearchRequest,\n} from \"@baker/api\";\nimport { CUSTOMER_INSIGHTS_MODEL } from \"@baker/canvas-contract\";\nimport { defineCommand } from \"citty\";\nimport { parse as parseYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport { apiGet, apiPost } from \"../../client.ts\";\nimport { askAboutText, type ReviewUsage } from \"../../engine/nodes/local/lib/render-review.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { findWorkspaceRoot } from \"../canvas/normalize-paths.ts\";\nimport { holdUnbilledSpend } from \"../canvas/unbilled-spend.ts\";\nimport { findSubreddits, searchReddit } from \"./reddit.ts\";\n\n/**\n * `baker research customers` — what real customers say, kept only where they said it.\n *\n * Ads start from a customer's own words. An agent asked for those words writes plausible ones,\n * and a plausible quote is the one thing an ad must never carry. So nothing here is written by\n * the agent or the model: the model only POINTS at a span of a fetched text, and the code keeps\n * that span only if it is in that text as written (`keepVerbatim`). One Knowledge file per\n * insight, `status: observed`.\n */\n\nexport const INSIGHT_TYPES = [\n \"accommodation\",\n \"failed_solution\",\n \"nearly_didnt\",\n \"word\",\n \"moment\",\n \"pain\",\n \"objection\",\n \"desire\",\n \"proof\",\n \"other\",\n] as const;\nexport type InsightType = (typeof INSIGHT_TYPES)[number];\n\nexport const FORCES = [\"push\", \"pull\", \"anxiety\", \"habit\"] as const;\nexport type Force = (typeof FORCES)[number];\n\nexport type SourceKind = \"review\" | \"testimonial\" | \"reddit\" | \"web\";\n\n/** One text a customer wrote, as the model is shown it and the gate checks it. */\nexport type CustomerSource = {\n /** What the insight cites: a URL, or `testimonials:<id>`. */\n ref: string;\n kind: SourceKind;\n text: string;\n /** One line: who said it, where. */\n context: string;\n /** When it was said, YYYY-MM-DD, when the source knows. */\n saidOn?: string;\n};\n\n/** What the model points at: a span of source number `source` (1-based, as the prompt numbers them). */\nexport type Candidate = {\n source: number;\n quote: string;\n type: InsightType;\n force?: Force;\n persona?: string;\n};\n\n/** A candidate whose quote is in its source as written. */\nexport type VerbatimInsight = Omit<Candidate, \"source\"> & { source: CustomerSource };\n\nexport const MAX_QUOTE_CHARS = 280;\n\n/** Curly and prime quote marks, by code point: single ones read as ', double ones as \". */\nconst SINGLE_QUOTES = new Set([0x2018, 0x2019, 0x201a, 0x201b, 0x2032]);\nconst DOUBLE_QUOTES = new Set([0x201c, 0x201d, 0x201e, 0x201f, 0x2033]);\n\nfunction foldChar(char: string): string {\n if (/\\s/.test(char)) return \" \";\n const code = char.codePointAt(0) ?? 0;\n if (SINGLE_QUOTES.has(code)) return \"'\";\n if (DOUBLE_QUOTES.has(code)) return '\"';\n return char.normalize(\"NFKC\").toLowerCase();\n}\n\n/**\n * A text in the form quotes are compared in (curly quotes straightened, spacing collapsed, case\n * folded), with, for each folded character, where it starts in the original.\n */\nfunction foldWithOffsets(text: string): { folded: string; offsets: number[] } {\n let folded = \"\";\n const offsets: number[] = [];\n let at = 0;\n for (const char of text) {\n const out = foldChar(char);\n const collapses = out === \" \" && (folded.length === 0 || folded.endsWith(\" \"));\n if (!collapses) {\n for (const piece of out) {\n folded += piece;\n offsets.push(at);\n }\n }\n at += char.length;\n }\n if (folded.endsWith(\" \")) {\n folded = folded.slice(0, -1);\n offsets.pop();\n }\n return { folded, offsets };\n}\n\n/**\n * Where `quote` sits in `text` under the comparison form, as the original's own characters\n * (spacing collapsed), or null when it is not there.\n */\nfunction findVerbatim(quote: string, text: string): string | null {\n const needle = foldWithOffsets(quote).folded;\n if (needle.length === 0) return null;\n const { folded, offsets } = foldWithOffsets(text);\n const start = folded.indexOf(needle);\n if (start < 0) return null;\n const last = offsets[start + needle.length - 1] ?? 0;\n const end = last + (String.fromCodePoint(text.codePointAt(last) ?? 0).length || 1);\n return text.slice(offsets[start], end).replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * The gate: a candidate survives only if its quote is in the source it cites, and what is kept\n * is the source's own spelling of that span, not the model's copy of it. Everything else (a\n * paraphrase, a quote cited to the wrong text, a source that does not exist) is dropped and\n * counted, never repaired; a span longer than MAX_QUOTE_CHARS is counted apart. Pure.\n */\nexport function keepVerbatim(\n candidates: readonly Candidate[],\n sources: readonly CustomerSource[],\n): { kept: VerbatimInsight[]; dropped: number; tooLong: number } {\n const kept: VerbatimInsight[] = [];\n let dropped = 0;\n let tooLong = 0;\n for (const { source: index, ...rest } of candidates) {\n const source = sources[index - 1];\n const quote = source ? findVerbatim(rest.quote, source.text) : null;\n if (!source || !quote) {\n dropped++;\n continue;\n }\n if (quote.length > MAX_QUOTE_CHARS) {\n tooLong++;\n continue;\n }\n kept.push({ ...rest, quote, source });\n }\n return { kept, dropped, tooLong };\n}\n\nconst SLUG_WORDS = 6;\n\n/** Lowercase ASCII words, accents dropped. */\nfunction asciiWords(text: string): string[] {\n return text\n .normalize(\"NFKD\")\n .replace(/\\p{M}/gu, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \" \")\n .trim()\n .split(\" \")\n .filter(Boolean);\n}\n\n/** The file name an insight gets: its type, then the first words of its quote, kebab-case ASCII. Pure. */\nfunction insightSlug(type: InsightType, quote: string): string {\n return [type.replace(/_/g, \"-\"), ...asciiWords(quote).slice(0, SLUG_WORDS)].join(\"-\");\n}\n\nexport type PlannedInsight = { id: string; insight: VerbatimInsight };\n\n/**\n * Which insights to write and under what id. The first five types first (they write most of an\n * ad), at most `limit`. A quote already on file (or already planned) is skipped; an id held by a\n * different quote gets a `-2`, `-3`… so a file is never overwritten. Pure.\n */\nexport function planInsightWrites(\n insights: readonly VerbatimInsight[],\n existing: readonly { id: string; quote: string }[],\n limit: number,\n): { writes: PlannedInsight[]; skippedExisting: number } {\n const quotes = new Set(existing.map((e) => foldWithOffsets(e.quote).folded));\n const ids = new Set(existing.map((e) => e.id));\n const ranked = [...insights].sort((a, b) => INSIGHT_TYPES.indexOf(a.type) - INSIGHT_TYPES.indexOf(b.type));\n const writes: PlannedInsight[] = [];\n let skippedExisting = 0;\n for (const insight of ranked) {\n const folded = foldWithOffsets(insight.quote).folded;\n if (quotes.has(folded)) {\n skippedExisting++;\n continue;\n }\n if (writes.length >= limit) continue;\n const base = insightSlug(insight.type, insight.quote);\n let id = base;\n for (let n = 2; ids.has(id); n++) id = `${base}-${n}`;\n quotes.add(folded);\n ids.add(id);\n writes.push({ id, insight });\n }\n return { writes, skippedExisting };\n}\n\n/** A frontmatter string, YAML-safe: a JSON string is a valid double-quoted YAML scalar. */\nfunction yamlScalar(value: string): string {\n return JSON.stringify(value);\n}\n\nconst TITLE_CHARS = 70;\n\n/** The quote's opening words as the entry's title, in quote marks, so the Knowledge list reads as what was said. */\nfunction insightTitle(quote: string): string {\n const text = quote.replace(/[\"“”]/g, \"\").replace(/\\s+/g, \" \").trim();\n if (text.length <= TITLE_CHARS) return `“${text}”`;\n const cut = text.slice(0, TITLE_CHARS);\n return `“${cut.slice(0, cut.lastIndexOf(\" \")).replace(/[,;:.]$/, \"\")}…”`;\n}\n\n/**\n * The insight's Knowledge file (`src/content/insights/<id>.md`): frontmatter per the `insights`\n * collection, `status: observed`, and one line of context as the body. Pure.\n */\nexport function renderInsightFile(insight: VerbatimInsight, opts: { today: string; product?: string }): string {\n const { source } = insight;\n const lines = [\n \"---\",\n `title: ${yamlScalar(insightTitle(insight.quote))}`,\n `type: ${insight.type}`,\n `quote: ${yamlScalar(insight.quote)}`,\n `source: ${yamlScalar(source.ref)}`,\n `sourceKind: ${source.kind}`,\n `seenAt: ${yamlScalar(source.saidOn ?? opts.today)}`,\n \"status: observed\",\n ];\n if (insight.force) lines.push(`force: ${insight.force}`);\n if (insight.persona?.trim()) lines.push(`persona: ${yamlScalar(insight.persona.trim())}`);\n if (opts.product) lines.push(`product: ${yamlScalar(opts.product)}`);\n lines.push(\"---\", \"\", source.context.replace(/\\s+/g, \" \").trim(), \"\");\n return lines.join(\"\\n\");\n}\n\n/** How much of one review or comment the model reads (and the gate checks against). */\nconst MAX_SHORT_SOURCE_CHARS = 1_500;\n\nconst PLATFORM_NAMES: Record<string, string> = {\n google: \"Google\",\n trustpilot: \"Trustpilot\",\n yelp: \"Yelp\",\n tripadvisor: \"Tripadvisor\",\n g2: \"G2\",\n capterra: \"Capterra\",\n amazon: \"Amazon\",\n app_store: \"App Store\",\n google_play: \"Google Play\",\n};\n\n/** One library review as `/api/testimonials` returns it, read loosely so a new field never empties the list. */\nconst LibraryReviewSchema = z.object({\n _id: z.string().min(1),\n reviewText: z.string(),\n sourceType: z.string().optional(),\n reviewerName: z.string().optional(),\n rating: z.number().optional(),\n reviewDate: z.number().optional(),\n});\n\nfunction dayOf(ms: number | string): string | undefined {\n const date = new Date(ms);\n return Number.isNaN(date.getTime()) ? undefined : date.toISOString().slice(0, 10);\n}\n\n/** \"A …\" or \"An …\", ending in one full stop. */\nfunction sentence(rest: string): string {\n const line = `${/^[aeiou]/i.test(rest) ? \"An\" : \"A\"} ${rest}`;\n return line.endsWith(\".\") ? line : `${line}.`;\n}\n\n/** \"A 4★ Trustpilot review by Marta G.\" */\nfunction reviewContext(review: z.infer<typeof LibraryReviewSchema>): string {\n const platform = review.sourceType ? `${PLATFORM_NAMES[review.sourceType] ?? review.sourceType} ` : \"\";\n const rating = review.rating !== undefined ? `${review.rating}★ ` : \"\";\n const by = review.reviewerName?.trim() ? ` by ${review.reviewerName.trim()}` : \"\";\n return sentence(`${rating}${platform}review${by}`);\n}\n\n/** The company's reviews (a plain list from `/api/testimonials`) as sources, each cited `testimonials:<id>`. Pure. */\nexport function sourcesFromTestimonials(data: unknown): CustomerSource[] {\n const list = Array.isArray(data) ? data : [];\n return list.flatMap((item): CustomerSource[] => {\n const parsed = LibraryReviewSchema.safeParse(item);\n if (!parsed.success) return [];\n const review = parsed.data;\n const text = review.reviewText.trim().slice(0, MAX_SHORT_SOURCE_CHARS);\n if (!text) return [];\n const saidOn = review.reviewDate !== undefined ? dayOf(review.reviewDate) : undefined;\n return [\n {\n ref: `testimonials:${review._id}`,\n kind: \"review\",\n text,\n context: reviewContext(review),\n ...(saidOn ? { saidOn } : {}),\n },\n ];\n });\n}\n\n/** Reddit posts and comments as sources, each cited by its own permalink; a post's title counts as its words. Pure. */\nexport function sourcesFromReddit(items: readonly ResearchRedditItem[]): CustomerSource[] {\n return items.flatMap((item): CustomerSource[] => {\n const words = item.kind === \"post\" ? [item.title ?? \"\", item.text].filter((t) => t.trim()).join(\"\\n\\n\") : item.text;\n const text = words.trim().slice(0, MAX_SHORT_SOURCE_CHARS);\n if (!text) return [];\n const under = item.kind === \"comment\" && item.title ? `, under ${JSON.stringify(item.title)}` : \"\";\n const saidOn = dayOf(item.createdAt);\n return [\n {\n ref: item.permalink,\n kind: \"reddit\",\n text,\n context: `A Reddit ${item.kind} in r/${item.subreddit}${under}.`,\n ...(saidOn ? { saidOn } : {}),\n },\n ];\n });\n}\n\n/** How much of one web page the model reads (and the gate checks against). */\nconst MAX_PAGE_SOURCE_CHARS = 6_000;\n\n/** Pages read with `research fetch` as sources, each cited by where the read landed. Pure. */\nexport function sourcesFromPages(pages: readonly ResearchFetchResponse[]): CustomerSource[] {\n return pages.flatMap((page): CustomerSource[] => {\n const text = page.content.trim().slice(0, MAX_PAGE_SOURCE_CHARS);\n if (!text) return [];\n const host = URL.canParse(page.finalUrl) ? new URL(page.finalUrl).host : page.finalUrl;\n const title = page.title?.trim() ? `, ${JSON.stringify(page.title.trim())}` : \"\";\n return [{ ref: page.finalUrl, kind: \"web\", text, context: `A page on ${host}${title}.` }];\n });\n}\n\n/**\n * The classification prompt: numbered texts, and the instruction to point at exact spans of\n * them. What comes back is only a pointer; `keepVerbatim` decides what is kept. Pure.\n */\nexport function buildCustomersPrompt(sources: readonly CustomerSource[], focus?: string): string {\n return [\n `Below are ${sources.length} numbered texts written by real customers (reviews, testimonials, forum posts and comments, web pages)${focus ? `, gathered about: ${focus}` : \"\"}.`,\n \"Find the customer truths in them, the material ads are written from.\",\n \"\",\n \"Rules:\",\n \"- Every quote must be an EXACT substring of the text it cites: the same words, in the same order, with the same spelling and typos. Copy, never paraphrase, translate, summarize, correct or join two passages.\",\n `- The shortest span that carries the truth, at most ${MAX_QUOTE_CHARS} characters.`,\n \"- Only the customer's own words: skip a seller's reply, an ad, a page's marketing copy, and a text with no truth in it. Return fewer, or none, rather than invent.\",\n \"- type: accommodation (a workaround they live with), failed_solution (what they tried before that failed them), nearly_didnt (what nearly stopped them buying), word (their own word or phrase for the problem), moment (the moment that started their search), pain, objection, desire, proof (a result they got), other.\",\n \"- force, when it speaks to one: push (what pushes them off the old way), pull (what draws them to the new one), anxiety (what they fear about changing), habit (what keeps them where they are).\",\n '- persona: a few words on who is speaking, only when the text says it (\"restaurant owner\", \"night-shift courier\").',\n \"\",\n 'Reply with only this JSON: {\"insights\":[{\"source\":1,\"quote\":\"\",\"type\":\"\",\"force\":\"\",\"persona\":\"\"}]}',\n \"\",\n \"Texts:\",\n ...sources.map((source, i) => `[${i + 1}] ${source.text}`),\n ].join(\"\\n\");\n}\n\nconst AnswerSchema = z.object({ insights: z.array(z.unknown()) });\n\nconst CandidateSchema = z.object({\n source: z.coerce.number().int().positive(),\n quote: z.string().trim().min(1),\n type: z.enum(INSIGHT_TYPES).catch(\"other\"),\n force: z.enum(FORCES).optional().catch(undefined),\n persona: z.string().trim().optional().catch(undefined),\n});\n\n/** The model's spans, or null when the reply is not the asked shape. An item that is not a span is dropped. Pure. */\nexport function candidatesFrom(answer: unknown): Candidate[] | null {\n const parsed = AnswerSchema.safeParse(answer);\n if (!parsed.success) return null;\n return parsed.data.insights.flatMap((item): Candidate[] => {\n const candidate = CandidateSchema.safeParse(item);\n if (!candidate.success) return [];\n const { source, quote, type, force, persona } = candidate.data;\n return [{ source, quote, type, ...(force ? { force } : {}), ...(persona ? { persona } : {}) }];\n });\n}\n\n/** Sources in batches of at most `budget` characters of text; a source is never split. Pure. */\nexport function batchSources(sources: readonly CustomerSource[], budget: number): CustomerSource[][] {\n const batches: CustomerSource[][] = [];\n let current: CustomerSource[] = [];\n let size = 0;\n for (const source of sources) {\n if (current.length > 0 && size + source.text.length > budget) {\n batches.push(current);\n current = [];\n size = 0;\n }\n current.push(source);\n size += source.text.length;\n }\n if (current.length > 0) batches.push(current);\n return batches;\n}\n\n/** How many insights answered per source; null when the source was not asked or did not answer. */\nexport type SourceCounts = { testimonials: number | null; reddit: number | null; web: number | null };\n\nconst FEW_OBSERVED = 5;\n\n/** What the agent does next. Pure. */\nexport function customersHints(input: { written: number; sources: SourceCounts }): string[] {\n const { written, sources } = input;\n const widen =\n 'Search in the customers\\' own words with --query \"<the words they write>\" (their phrasing, not a category name), or add --web.';\n if (written === 0) {\n return [\n \"No customer words were found to keep, so nothing was written. Import where customers already talk: `baker testimonials sources add <review page link>` (Google, Trustpilot, G2, app stores…) brings their reviews into the library; then run this again.\",\n ...(sources.reddit === null\n ? ['Reddit was not read: pass --focus \"<product>\" or --query \"<their words>\".']\n : [widen]),\n \"Until there are observed truths, ad ideas go in as explore bets: an idea with an empty `evidence` list.\",\n ];\n }\n const cite = `Cite these by id in an idea's \\`evidence\\` (src/creatives/_ideas/<idea>.md); write the ad from the quote as said.`;\n return written < FEW_OBSERVED ? [`Only ${written} observed. ${widen}`, cite] : [cite];\n}\n\n// ---------------------------------------------------------------------------\n// The command: gather, classify, gate, write\n// ---------------------------------------------------------------------------\n\nconst INSIGHTS_DIR = path.join(\"src\", \"content\", \"insights\");\nconst BATCH_CHARS = 24_000;\nconst MAX_BATCHES = 5;\nconst WEB_PAGES = 3;\nconst DEFAULT_LIMIT = 20;\nconst SHOWN_QUOTE_CHARS = 120;\nconst READ_TIMEOUT_MS = 180_000;\n\nconst DESCRIPTION = `Gather what real customers say and keep it as Knowledge: one file per customer truth in src/content/insights/<id>.md, each a quote found word for word in its source (status: observed). Ads and ideas are written from these.\n\nStart here: baker research customers --focus \"<product or persona>\"\n\nReads the company's review library, Reddit (with --focus or --query) and, with --web, a few web pages. A model only points at spans; a quote is kept only if it appears verbatim in the text it came from, and everything else is dropped and counted. Never write an insight by hand.\n\nExamples:\n baker research customers --focus \"payroll app for restaurants\"\n baker research customers --query \"chasing invoices\" --web\n baker research customers --dry-run`;\n\nconst ARGS = {\n focus: {\n type: \"string\",\n required: false,\n description:\n 'The product or persona to listen for, e.g. \"payroll for restaurants\". Also the Reddit search when --query is not given.',\n },\n query: {\n type: \"string\",\n required: false,\n description: 'Search terms in the customers\\' own words, e.g. \"chasing invoices\". Used for Reddit and the web.',\n },\n limit: { type: \"string\", required: false, description: `Most insights written (default ${DEFAULT_LIMIT}).` },\n web: {\n type: \"boolean\",\n required: false,\n default: false,\n description: `Also read up to ${WEB_PAGES} web pages where customers talk about it (slower).`,\n },\n \"dry-run\": {\n type: \"boolean\",\n required: false,\n default: false,\n description: \"Show what would be written; write nothing.\",\n },\n full: {\n type: \"boolean\",\n required: false,\n default: false,\n description: \"Add each insight's whole quote, source and context.\",\n },\n} as const;\n\nregisterSchema({ command: \"research.customers\", description: DESCRIPTION, args: ARGS });\n\nconst QuoteFrontmatter = z.object({ quote: z.string() });\n\n/** An insight file's `quote`, or \"\" when it has none that reads. */\nfunction quoteOf(raw: string): string {\n const front = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/)?.[1];\n if (!front) return \"\";\n try {\n const parsed = QuoteFrontmatter.safeParse(parseYaml(front));\n return parsed.success ? parsed.data.quote : \"\";\n } catch {\n return \"\";\n }\n}\n\n/** The insights already on file, id and quote. Never throws. */\nasync function readExistingInsights(dir: string): Promise<{ id: string; quote: string }[]> {\n const files = (await readdir(dir).catch(() => [] as string[])).filter((f) => f.endsWith(\".md\"));\n return await Promise.all(\n files.map(async (file) => ({\n id: file.slice(0, -3),\n quote: quoteOf(await readFile(path.join(dir, file), \"utf8\").catch(() => \"\")),\n })),\n );\n}\n\n/** The product entries' names (file slugs). Never throws. */\nasync function productSlugs(root: string): Promise<string[]> {\n const files = await readdir(path.join(root, \"src\", \"content\", \"products\")).catch(() => [] as string[]);\n return files.filter((f) => f.endsWith(\".md\")).map((f) => f.slice(0, -3));\n}\n\n/** The library's reviews: the ones about --focus when given, else the latest. Null when the library did not answer. */\nasync function gatherTestimonials(focus: string | undefined): Promise<CustomerSource[] | null> {\n try {\n const search: TestimonialsSearchRequest = { query: focus ?? \"\", limit: 40 };\n const data = focus\n ? await apiPost<unknown>(\"/api/testimonials/search\", search)\n : await apiGet<unknown>(\"/api/testimonials\", { limit: \"50\" });\n return sourcesFromTestimonials(data);\n } catch {\n return null;\n }\n}\n\n/** Reddit posts and comments matching `query`, in the subreddits where it is talked about. Null when Reddit did not answer. */\nasync function gatherReddit(query: string): Promise<CustomerSource[] | null> {\n const subreddits = await findSubreddits({ query: query.slice(0, 100), limit: 3 })\n .then((r) => r.results.filter((s) => s.access !== \"private\").map((s) => s.name))\n .catch(() => [] as string[]);\n const answers = await Promise.allSettled([\n searchReddit({ query, subreddits, kind: \"posts\", limit: 15 }),\n ...(subreddits.length > 0 ? [searchReddit({ query, subreddits, kind: \"comments\", limit: 25 })] : []),\n ]);\n if (answers.every((a) => a.status === \"rejected\")) return null;\n const seen = new Set<string>();\n const items = answers\n .flatMap((a) => (a.status === \"fulfilled\" ? a.value.results : []))\n .filter((item) => !seen.has(item.id) && Boolean(seen.add(item.id)));\n return sourcesFromReddit(items);\n}\n\nconst ExploreAnswer = z.object({ sources: z.array(z.object({ url: z.string() })) });\n\n/**\n * Web research cites its pages through Google's grounding redirect; a quote must cite the page\n * itself, so the redirect is followed once (no body read). Any other URL, or a redirect that does\n * not answer, is kept as it is.\n */\nasync function resolveGroundingRedirect(url: string): Promise<string> {\n if (!URL.canParse(url) || new URL(url).host !== \"vertexaisearch.cloud.google.com\") return url;\n try {\n const response = await fetch(url, { method: \"HEAD\", redirect: \"manual\", signal: AbortSignal.timeout(15_000) });\n const location = response.headers.get(\"location\");\n return location && URL.canParse(location) ? location : url;\n } catch {\n return url;\n }\n}\n\n/** A few web pages where customers talk about `topic`, each read whole. Null when the web did not answer. */\nasync function gatherWeb(topic: string): Promise<CustomerSource[] | null> {\n let urls: string[];\n try {\n const found = ExploreAnswer.parse(\n await apiPost<unknown>(\n \"/api/research/explore\",\n {\n question: `Which pages carry first-hand customer comments about ${topic}, in the customers' own words: reviews, complaints, forum threads?`,\n depth: \"medium\",\n },\n { timeoutMs: READ_TIMEOUT_MS },\n ),\n );\n urls = (await Promise.all(found.sources.slice(0, WEB_PAGES * 2).map((s) => resolveGroundingRedirect(s.url))))\n .filter((u) => !/reddit\\.com/i.test(u))\n .filter((u, i, all) => all.indexOf(u) === i);\n } catch {\n return null;\n }\n const pages = await Promise.allSettled(\n urls.slice(0, WEB_PAGES).map((url) => {\n const body: ResearchFetchRequest = { url };\n return apiPost<ResearchFetchResponse>(\"/api/research/fetch\", body, { timeoutMs: READ_TIMEOUT_MS });\n }),\n );\n return sourcesFromPages(pages.flatMap((p) => (p.status === \"fulfilled\" ? [p.value] : [])));\n}\n\n/** One batch's spans, asked at most twice; null when the model never answered in shape. */\nasync function classifyBatch(\n batch: CustomerSource[],\n focus: string | undefined,\n onSpend: (usage: ReviewUsage) => void,\n): Promise<Candidate[] | null> {\n const prompt = buildCustomersPrompt(batch, focus);\n for (let attempt = 0; attempt < 2; attempt++) {\n const candidates = candidatesFrom(await askAboutText(CUSTOMER_INSIGHTS_MODEL, prompt, onSpend));\n if (candidates) return candidates;\n }\n return null;\n}\n\n/** Sources taken in turn from each list, so every kind reaches the model when there is more than it reads. */\nfunction interleave(lists: readonly CustomerSource[][]): CustomerSource[] {\n const out: CustomerSource[] = [];\n const longest = Math.max(0, ...lists.map((l) => l.length));\n for (let i = 0; i < longest; i++) {\n for (const list of lists) {\n const source = list[i];\n if (source) out.push(source);\n }\n }\n return out;\n}\n\nfunction fail(code: string, message: string, fix: string): never {\n writeJson({ ok: false, error: { code, message, fix } });\n process.exit(1);\n}\n\n/** Every source asked at once; one that does not answer is null and never stops the rest. */\nasync function gatherSources(opts: { focus?: string; topic?: string; web: boolean }) {\n const { focus, topic, web: withWeb } = opts;\n const [testimonials, reddit, web] = await Promise.all([\n gatherTestimonials(focus),\n topic ? gatherReddit(topic) : Promise.resolve(null),\n withWeb && topic ? gatherWeb(topic) : Promise.resolve(null),\n ]);\n const counts: SourceCounts = {\n testimonials: testimonials?.length ?? null,\n reddit: reddit?.length ?? null,\n web: web?.length ?? null,\n };\n return { all: interleave([testimonials ?? [], reddit ?? [], web ?? []]), counts };\n}\n\n/**\n * Every batch classified and gated; null when the model answered no batch at all. The spend\n * waits in the workspace's canvas cache: no run record carries these calls, so the next render\n * of this workspace bills them.\n */\nasync function classifyAll(\n sources: readonly CustomerSource[],\n focus: string | undefined,\n root: string,\n): Promise<{ kept: VerbatimInsight[]; dropped: number; tooLong: number } | null> {\n const batches = batchSources(sources, BATCH_CHARS).slice(0, MAX_BATCHES);\n const spent: ReviewUsage[] = [];\n const answers = await Promise.all(batches.map((batch) => classifyBatch(batch, focus, (u) => spent.push(u))));\n await holdUnbilledSpend(path.join(root, \"canvas\", \".cache\"), spent);\n if (batches.length > 0 && answers.every((a) => a === null)) return null;\n const result = { kept: [] as VerbatimInsight[], dropped: 0, tooLong: 0 };\n batches.forEach((batch, i) => {\n const gated = keepVerbatim(answers[i] ?? [], batch);\n result.kept.push(...gated.kept);\n result.dropped += gated.dropped;\n result.tooLong += gated.tooLong;\n });\n return result;\n}\n\n/** Writes each planned file, never over one that appeared since the plan (`wx`); returns what was written. */\nasync function writeInsights(\n dir: string,\n writes: readonly PlannedInsight[],\n opts: { today: string; product?: string },\n): Promise<PlannedInsight[]> {\n if (writes.length === 0) return [];\n await mkdir(dir, { recursive: true });\n const written: PlannedInsight[] = [];\n for (const entry of writes) {\n const file = renderInsightFile(entry.insight, opts);\n const ok = await writeFile(path.join(dir, `${entry.id}.md`), file, { encoding: \"utf8\", flag: \"wx\" }).then(\n () => true,\n () => false,\n );\n if (ok) written.push(entry);\n }\n return written;\n}\n\nfunction writtenRow({ id, insight }: PlannedInsight, full: boolean) {\n const quote =\n insight.quote.length > SHOWN_QUOTE_CHARS ? `${insight.quote.slice(0, SHOWN_QUOTE_CHARS)}…` : insight.quote;\n if (!full) return { id, type: insight.type, quote };\n return {\n id,\n type: insight.type,\n quote,\n full_quote: insight.quote,\n source: insight.source.ref,\n context: insight.source.context,\n ...(insight.force ? { force: insight.force } : {}),\n ...(insight.persona ? { persona: insight.persona } : {}),\n };\n}\n\n/** What the run listens for: the product a --focus names, and the words Reddit and the web are searched with. */\nasync function resolveTopic(root: string, focus: string | undefined, query: string | undefined) {\n const products = await productSlugs(root);\n const product = focus ? products.find((slug) => slug === asciiWords(focus).join(\"-\")) : undefined;\n const firstProduct = products[0];\n const topic = query ?? focus ?? (firstProduct ? asciiWords(firstProduct).join(\" \") : undefined);\n return { product, topic };\n}\n\n/**\n * Gathers, classifies, gates and writes customer truths into the workspace; null when the model\n * answered no batch. Shared with `baker creatives brief`, which runs it when few quotes are on file.\n */\nexport async function researchCustomers(\n root: string,\n opts: { focus?: string; query?: string; limit?: number; web?: boolean; dryRun?: boolean },\n) {\n const { focus, query, limit = DEFAULT_LIMIT, web = false, dryRun = false } = opts;\n const { product, topic } = await resolveTopic(root, focus, query);\n const { all, counts } = await gatherSources({ focus, topic, web });\n const gated = await classifyAll(all, focus, root);\n if (!gated) return null;\n const dir = path.join(root, INSIGHTS_DIR);\n const plan = planInsightWrites(gated.kept, await readExistingInsights(dir), limit);\n const today = new Date().toISOString().slice(0, 10);\n const shown = dryRun\n ? plan.writes\n : await writeInsights(dir, plan.writes, { today, ...(product ? { product } : {}) });\n return { shown, plan, gated, counts };\n}\n\nexport const customersCommand = defineCommand({\n meta: { name: \"customers\", description: DESCRIPTION },\n args: ARGS,\n async run({ args }) {\n const focus = args.focus?.trim() || undefined;\n const query = args.query?.trim() || undefined;\n const limit = args.limit === undefined ? DEFAULT_LIMIT : Number(args.limit);\n if (!Number.isInteger(limit) || limit < 1 || limit > 100) {\n fail(\"VALIDATION_ERROR\", \"--limit must be a whole number from 1 to 100.\", \"Run it again with --limit 20.\");\n }\n const dryRun = Boolean(args[\"dry-run\"]);\n const root = findWorkspaceRoot(process.cwd()) ?? process.cwd();\n const found = await researchCustomers(root, { focus, query, limit, web: Boolean(args.web), dryRun });\n if (!found) {\n fail(\n \"UNAVAILABLE\",\n \"The model that picks out customer words did not answer (no gateway key here, or it failed twice).\",\n \"Run it again. Do not write insights by hand: an insight is only a quote this command found in its source.\",\n );\n }\n const { shown, plan, gated, counts } = found;\n\n writeJson({\n ok: true,\n data: {\n ...(dryRun ? { dry_run: true } : {}),\n written: shown.map((entry) => writtenRow(entry, Boolean(args.full))),\n skipped_existing: plan.skippedExisting,\n dropped_not_verbatim: gated.dropped,\n ...(gated.tooLong > 0 ? { dropped_too_long: gated.tooLong } : {}),\n sources: counts,\n },\n hints: customersHints({ written: shown.length, sources: counts }),\n });\n },\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,9 @@
1
+ // ../api/src/event-ingest/mode.ts
2
+ var INGEST_MODE_HEADER = "X-Baker-Mode";
3
+ var INGEST_MODES = ["live", "test"];
4
+
5
+ export {
6
+ INGEST_MODE_HEADER,
7
+ INGEST_MODES
8
+ };
9
+ //# sourceMappingURL=chunk-GRQ2AXDX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../api/src/event-ingest/mode.ts"],"sourcesContent":["/**\n * Whether a request is a rehearsal, decided by the request.\n *\n * ## Why this is not a property of the key\n *\n * It was, and that was the wrong shape. A key that means \"test\" makes the mode\n * a deploy-time decision belonging to whoever set an environment variable,\n * which is a long way from the person deciding to rehearse. It also gives one\n * integration two credentials to hold, rotate and tell apart — and the moment\n * there are two, every surface that shows a key has to explain which one this\n * is, which is how a key list becomes a second species of key.\n *\n * Test versus live is a property of *this request*. The same CRM, with the same\n * credential, sends a rehearsal now and a real deal in an hour. So it travels\n * as a header, and the credential goes back to answering only the question a\n * credential should answer: who is this, and what may they reach.\n *\n * ## The one thing a separate key bought, and how it is bought back\n *\n * Worth stating plainly, because it is a real trade and not a free win. A key\n * that *cannot* write live data is a hard guarantee: a staging server holding\n * one can never pollute a client's reports, however it is configured. A header\n * can be forgotten, and a forgotten header means a rehearsal lands in the real\n * numbers — silently, because it is a perfectly valid request.\n *\n * Two things buy that back, and both matter:\n *\n * - **An unrecognised value is refused, never assumed.** `X-Baker-Mode: testing`\n * or `true` is a `400`, not a shrug that falls through to live. A typo is the\n * likely way this gets sent wrong, and it is now the loud way rather than the\n * silent one. Only a header that is genuinely absent means live.\n * - **The response says which mode it was treated as**, so the answer to \"did\n * my rehearsal count?\" is in the reply to the request that asked, rather than\n * in a report somebody reads next week.\n */\n\nexport const INGEST_MODE_HEADER = \"X-Baker-Mode\";\n\nexport const INGEST_MODES = [\"live\", \"test\"] as const;\nexport type IngestMode = (typeof INGEST_MODES)[number];\n\n/**\n * The mode a header asks for: `live` when it is absent, the named mode when it\n * is one this endpoint knows, and `null` for anything else — which the caller\n * turns into a `400` rather than guessing.\n *\n * Whitespace and case are forgiven because they are not what anybody means to\n * send; an unknown word is not, because it is.\n */\nexport function parseIngestMode(header: string | null | undefined): IngestMode | null {\n if (header === null || header === undefined || header.trim() === \"\") return \"live\";\n const value = header.trim().toLowerCase();\n return (INGEST_MODES as readonly string[]).includes(value) ? (value as IngestMode) : null;\n}\n"],"mappings":";AAoCO,IAAM,qBAAqB;AAE3B,IAAM,eAAe,CAAC,QAAQ,MAAM;","names":[]}
@@ -0,0 +1,73 @@
1
+ // ../api/src/media-sources.ts
2
+ import { z } from "zod";
3
+ var mediaSourcePlatformSchema = z.enum([
4
+ "instagram",
5
+ "tiktok",
6
+ "youtube",
7
+ "linkedin",
8
+ "facebook",
9
+ "google_drive"
10
+ ]);
11
+ var mediaSourceRefreshIntervalSchema = z.enum(["never", "daily", "weekly", "monthly"]);
12
+ var mediaSourceSyncStatusSchema = z.enum(["idle", "fetching", "processing", "error"]);
13
+ var mediaSourceHalfSchema = z.object({
14
+ sourceId: z.string(),
15
+ syncStatus: mediaSourceSyncStatusSchema,
16
+ storedCount: z.number().optional(),
17
+ pendingItems: z.number().optional(),
18
+ failedItems: z.number().optional(),
19
+ lastSyncedAt: z.number().optional(),
20
+ errorMessage: z.string().optional()
21
+ });
22
+ var mediaSourceSummarySchema = z.object({
23
+ key: z.string(),
24
+ platform: mediaSourcePlatformSchema,
25
+ platformLabel: z.string(),
26
+ handle: z.string(),
27
+ label: z.string(),
28
+ profileUrl: z.string(),
29
+ profileImageUrl: z.string().optional(),
30
+ refreshInterval: mediaSourceRefreshIntervalSchema,
31
+ /** Absent for a platform that feeds no images (YouTube). */
32
+ images: mediaSourceHalfSchema.optional(),
33
+ videos: mediaSourceHalfSchema.optional(),
34
+ createdAt: z.number()
35
+ });
36
+ var mediaSourceProfileSchema = z.object({
37
+ platform: mediaSourcePlatformSchema,
38
+ handle: z.string(),
39
+ displayName: z.string(),
40
+ avatarUrl: z.string(),
41
+ bio: z.string(),
42
+ followers: z.number().optional(),
43
+ postCount: z.number().optional(),
44
+ isPrivate: z.boolean(),
45
+ profileUrl: z.string(),
46
+ channelId: z.string().optional()
47
+ });
48
+ var mediaSourcesAddRequestSchema = z.object({
49
+ /** A profile URL or a Drive folder link, or an @handle together with `platform`. */
50
+ input: z.string().trim().min(1, "Pass the account's profile URL or @handle"),
51
+ /** Needed only when `input` is a bare handle; a URL names its own platform. */
52
+ platform: mediaSourcePlatformSchema.optional(),
53
+ /** Auto-sync cadence. Omitted = weekly, for every platform. */
54
+ every: mediaSourceRefreshIntervalSchema.optional()
55
+ });
56
+ var mediaSourceKeySchema = z.string().trim().regex(/^(instagram|tiktok|youtube|linkedin|facebook|google_drive):.+$/, "Pass a source key like tiktok:nike");
57
+ var mediaSourcesSyncRequestSchema = z.object({ key: mediaSourceKeySchema });
58
+ var mediaSourcesRemoveRequestSchema = z.object({ key: mediaSourceKeySchema });
59
+ var mediaSourcesScheduleRequestSchema = z.object({
60
+ key: mediaSourceKeySchema,
61
+ every: mediaSourceRefreshIntervalSchema
62
+ });
63
+
64
+ export {
65
+ mediaSourcePlatformSchema,
66
+ mediaSourceRefreshIntervalSchema,
67
+ mediaSourcesAddRequestSchema,
68
+ mediaSourceKeySchema,
69
+ mediaSourcesSyncRequestSchema,
70
+ mediaSourcesRemoveRequestSchema,
71
+ mediaSourcesScheduleRequestSchema
72
+ };
73
+ //# sourceMappingURL=chunk-GXDLWBOY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../api/src/media-sources.ts"],"sourcesContent":["/**\n * Contract for `/api/media-sources/...` — connecting a social account, or a\n * Google Drive folder the company's Google Drive connection can open, as a\n * source for the image and video libraries.\n *\n * A source is named by its key, `<platform>:<handle>` (`tiktok:nike`), never by\n * a row id: it is stored as two rows (its image half and its video half), and\n * the key is the one name both halves share.\n *\n * Mirrors `convex/lib/mediaSourcePlatforms.ts` (`MEDIA_SOURCE_PLATFORMS`) and\n * `convex/mediaSources/queries.ts` (`MediaSourceSummary`).\n */\nimport { z } from \"zod\";\n\nexport const mediaSourcePlatformSchema = z.enum([\n \"instagram\",\n \"tiktok\",\n \"youtube\",\n \"linkedin\",\n \"facebook\",\n \"google_drive\",\n]);\nexport type MediaSourcePlatform = z.infer<typeof mediaSourcePlatformSchema>;\n\nexport const mediaSourceRefreshIntervalSchema = z.enum([\"never\", \"daily\", \"weekly\", \"monthly\"]);\nexport type MediaSourceRefreshInterval = z.infer<typeof mediaSourceRefreshIntervalSchema>;\n\nexport const mediaSourceSyncStatusSchema = z.enum([\"idle\", \"fetching\", \"processing\", \"error\"]);\n\nexport const mediaSourceHalfSchema = z.object({\n sourceId: z.string(),\n syncStatus: mediaSourceSyncStatusSchema,\n storedCount: z.number().optional(),\n pendingItems: z.number().optional(),\n failedItems: z.number().optional(),\n lastSyncedAt: z.number().optional(),\n errorMessage: z.string().optional(),\n});\n\nexport const mediaSourceSummarySchema = z.object({\n key: z.string(),\n platform: mediaSourcePlatformSchema,\n platformLabel: z.string(),\n handle: z.string(),\n label: z.string(),\n profileUrl: z.string(),\n profileImageUrl: z.string().optional(),\n refreshInterval: mediaSourceRefreshIntervalSchema,\n /** Absent for a platform that feeds no images (YouTube). */\n images: mediaSourceHalfSchema.optional(),\n videos: mediaSourceHalfSchema.optional(),\n createdAt: z.number(),\n});\nexport type MediaSourceSummary = z.infer<typeof mediaSourceSummarySchema>;\n\nexport const mediaSourceProfileSchema = z.object({\n platform: mediaSourcePlatformSchema,\n handle: z.string(),\n displayName: z.string(),\n avatarUrl: z.string(),\n bio: z.string(),\n followers: z.number().optional(),\n postCount: z.number().optional(),\n isPrivate: z.boolean(),\n profileUrl: z.string(),\n channelId: z.string().optional(),\n});\n\n// --- POST /api/media-sources/add ---\nexport const mediaSourcesAddRequestSchema = z.object({\n /** A profile URL or a Drive folder link, or an @handle together with `platform`. */\n input: z.string().trim().min(1, \"Pass the account's profile URL or @handle\"),\n /** Needed only when `input` is a bare handle; a URL names its own platform. */\n platform: mediaSourcePlatformSchema.optional(),\n /** Auto-sync cadence. Omitted = weekly, for every platform. */\n every: mediaSourceRefreshIntervalSchema.optional(),\n});\nexport type MediaSourcesAddRequest = z.infer<typeof mediaSourcesAddRequestSchema>;\nexport type MediaSourcesAddResponse = {\n /** False when the account was already connected — adding is idempotent. */\n created: boolean;\n source: MediaSourceSummary;\n profile: z.infer<typeof mediaSourceProfileSchema>;\n};\n\n// --- GET /api/media-sources/list ---\nexport type MediaSourcesListResponse = { sources: MediaSourceSummary[] };\n\n// --- POST /api/media-sources/{sync,remove,schedule} ---\nexport const mediaSourceKeySchema = z\n .string()\n .trim()\n .regex(/^(instagram|tiktok|youtube|linkedin|facebook|google_drive):.+$/, \"Pass a source key like tiktok:nike\");\n\nexport const mediaSourcesSyncRequestSchema = z.object({ key: mediaSourceKeySchema });\nexport type MediaSourcesSyncRequest = z.infer<typeof mediaSourcesSyncRequestSchema>;\nexport type MediaSourcesSyncResponse = { key: string; started: boolean };\n\nexport const mediaSourcesRemoveRequestSchema = z.object({ key: mediaSourceKeySchema });\nexport type MediaSourcesRemoveRequest = z.infer<typeof mediaSourcesRemoveRequestSchema>;\nexport type MediaSourcesRemoveResponse = { key: string };\n\nexport const mediaSourcesScheduleRequestSchema = z.object({\n key: mediaSourceKeySchema,\n every: mediaSourceRefreshIntervalSchema,\n});\nexport type MediaSourcesScheduleRequest = z.infer<typeof mediaSourcesScheduleRequestSchema>;\nexport type MediaSourcesScheduleResponse = { key: string };\n"],"mappings":";AAYA,SAAS,SAAS;AAEX,IAAM,4BAA4B,EAAE,KAAK;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,mCAAmC,EAAE,KAAK,CAAC,SAAS,SAAS,UAAU,SAAS,CAAC;AAGvF,IAAM,8BAA8B,EAAE,KAAK,CAAC,QAAQ,YAAY,cAAc,OAAO,CAAC;AAEtF,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,UAAU,EAAE,OAAO;AAAA,EACnB,YAAY;AAAA,EACZ,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,cAAc,EAAE,OAAO,EAAE,SAAS;AACpC,CAAC;AAEM,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,KAAK,EAAE,OAAO;AAAA,EACd,UAAU;AAAA,EACV,eAAe,EAAE,OAAO;AAAA,EACxB,QAAQ,EAAE,OAAO;AAAA,EACjB,OAAO,EAAE,OAAO;AAAA,EAChB,YAAY,EAAE,OAAO;AAAA,EACrB,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,iBAAiB;AAAA;AAAA,EAEjB,QAAQ,sBAAsB,SAAS;AAAA,EACvC,QAAQ,sBAAsB,SAAS;AAAA,EACvC,WAAW,EAAE,OAAO;AACtB,CAAC;AAGM,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,UAAU;AAAA,EACV,QAAQ,EAAE,OAAO;AAAA,EACjB,aAAa,EAAE,OAAO;AAAA,EACtB,WAAW,EAAE,OAAO;AAAA,EACpB,KAAK,EAAE,OAAO;AAAA,EACd,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,QAAQ;AAAA,EACrB,YAAY,EAAE,OAAO;AAAA,EACrB,WAAW,EAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAGM,IAAM,+BAA+B,EAAE,OAAO;AAAA;AAAA,EAEnD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,2CAA2C;AAAA;AAAA,EAE3E,UAAU,0BAA0B,SAAS;AAAA;AAAA,EAE7C,OAAO,iCAAiC,SAAS;AACnD,CAAC;AAaM,IAAM,uBAAuB,EACjC,OAAO,EACP,KAAK,EACL,MAAM,kEAAkE,oCAAoC;AAExG,IAAM,gCAAgC,EAAE,OAAO,EAAE,KAAK,qBAAqB,CAAC;AAI5E,IAAM,kCAAkC,EAAE,OAAO,EAAE,KAAK,qBAAqB,CAAC;AAI9E,IAAM,oCAAoC,EAAE,OAAO;AAAA,EACxD,KAAK;AAAA,EACL,OAAO;AACT,CAAC;","names":[]}
@@ -0,0 +1,94 @@
1
+ import {
2
+ ApiError
3
+ } from "./chunk-HREWXNTO.js";
4
+ import {
5
+ writeJson
6
+ } from "./chunk-WOTDHRNF.js";
7
+
8
+ // src/commands/landing/inspiration/shared.ts
9
+ var INSPIRATION_HINTS = {
10
+ adapt: "Reference only. Re-express this in the client's BRAND.md palette, type and imagery register. Reusing a headline, subhead or CTA verbatim is a Tier 0 message-match failure (references/gotchas.md).",
11
+ structureNotCopy: "Take the structural decision, not the furniture: what the eye hits first, the grid ratio, what was deliberately left out. Your copy must come from the client's own offer."
12
+ };
13
+ function favoritesScopeHints(health, resultCount) {
14
+ if (!health) return [];
15
+ const hints = [];
16
+ if (health.savedPages === 0) {
17
+ hints.push(
18
+ "This company hasn't saved any reference pages yet, so there is no taste profile to search \u2014 an empty result here says nothing about the library. Search the whole shared library with --scope all, or save a page the client admires with `baker landing inspiration add <url>`."
19
+ );
20
+ return hints;
21
+ }
22
+ if (health.failedPages > 0) {
23
+ const retryable = health.failedExamples.filter((example) => example.retryable).map((example) => example.url);
24
+ const permanent = health.failedExamples.filter((example) => !example.retryable).map((example) => example.url);
25
+ hints.push(
26
+ `${health.failedPages} of this company's ${health.savedPages} saved pages could not be read, so they hold no sections \u2014 only ${health.usablePages} are usable, which is why this result is thin. Search the whole library with --scope all.`
27
+ );
28
+ if (retryable.length > 0) {
29
+ hints.push(
30
+ `Worth another go: ${retryable.join(", ")} \u2014 run \`baker landing inspiration add <url>\` on one of them to study it again.`
31
+ );
32
+ }
33
+ if (permanent.length > 0) {
34
+ hints.push(`Not worth retrying \u2014 these sites refuse automated readers: ${permanent.join(", ")}.`);
35
+ }
36
+ }
37
+ if (health.studyingPages > 0) {
38
+ hints.push(
39
+ `${health.studyingPages} saved ${health.studyingPages === 1 ? "page is" : "pages are"} still being studied and will be searchable in a few minutes. Carry on; do not wait on them.`
40
+ );
41
+ }
42
+ if (resultCount === 0 && health.failedPages === 0 && health.studyingPages === 0) {
43
+ hints.push(
44
+ `Nothing in this company's ${health.usablePages} readable saved pages matches. The saved set is healthy, so this is the query, not the library \u2014 loosen the filters or search everything with --scope all.`
45
+ );
46
+ }
47
+ return hints;
48
+ }
49
+ function fidelityHint(fidelity) {
50
+ if (fidelity == null) return null;
51
+ if (fidelity >= 0.9) return null;
52
+ if (fidelity >= 0.75) {
53
+ return `Reproduction fidelity ${fidelity.toFixed(2)} \u2014 the markup is close but not exact. Trust the screenshot over the code.`;
54
+ }
55
+ return `Reproduction fidelity ${fidelity.toFixed(2)} \u2014 this section is scroll- or JS-driven and the extracted markup does NOT render like the original. Use the screenshot and the notes; treat the code as a hint only.`;
56
+ }
57
+ var STALE_COPY_AFTER_MS = 30 * 24 * 60 * 60 * 1e3;
58
+ function staleCopyHint(studiedAt, filedUrl, now = Date.now()) {
59
+ if (!studiedAt || now - studiedAt < STALE_COPY_AFTER_MS) return null;
60
+ const date = new Date(studiedAt).toLocaleDateString("en-US", { month: "short", day: "numeric", timeZone: "UTC" });
61
+ return `This copy of the page was read on ${date}. If the user says the live page looks different, run: baker landing inspiration add ${filedUrl} --refresh`;
62
+ }
63
+ function reportError(error) {
64
+ if (error instanceof ApiError) {
65
+ writeJson({ ok: false, error: { code: error.code, message: error.message } });
66
+ } else {
67
+ writeJson({
68
+ ok: false,
69
+ error: { code: "UNKNOWN", message: error instanceof Error ? error.message : String(error) }
70
+ });
71
+ }
72
+ process.exit(1);
73
+ }
74
+ function splitList(value) {
75
+ if (!value) return void 0;
76
+ const parts = value.split(",").map((part) => part.trim()).filter(Boolean);
77
+ return parts.length > 0 ? parts : void 0;
78
+ }
79
+ function parseNumber(value) {
80
+ if (value === void 0 || value === "") return void 0;
81
+ const parsed = Number(value);
82
+ return Number.isFinite(parsed) ? parsed : void 0;
83
+ }
84
+
85
+ export {
86
+ INSPIRATION_HINTS,
87
+ favoritesScopeHints,
88
+ fidelityHint,
89
+ staleCopyHint,
90
+ reportError,
91
+ splitList,
92
+ parseNumber
93
+ };
94
+ //# sourceMappingURL=chunk-H7MLHG2I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/landing/inspiration/shared.ts"],"sourcesContent":["import type { InspirationFavoritesHealth } from \"@baker/api/landing-library\";\nimport { ApiError } from \"../../../client.ts\";\nimport { writeJson } from \"../../../output.ts\";\n\n/**\n * The framing every consumer of the library gets.\n *\n * These are not decoration. The corpus only earns its keep if what comes out of\n * it gets re-expressed rather than pasted, and a hint that fires on every single\n * call is the cheapest place to say so — cheaper than a doc the agent may not\n * re-read, and softer than the critic that will block a clone at publish.\n */\nexport const INSPIRATION_HINTS = {\n adapt:\n \"Reference only. Re-express this in the client's BRAND.md palette, type and imagery register. \" +\n \"Reusing a headline, subhead or CTA verbatim is a Tier 0 message-match failure (references/gotchas.md).\",\n structureNotCopy:\n \"Take the structural decision, not the furniture: what the eye hits first, the grid ratio, \" +\n \"what was deliberately left out. Your copy must come from the client's own offer.\",\n} as const;\n\n/**\n * Say what is actually true about a thin favorites result.\n *\n * `search` defaults to this company's saved sections, and that default is a\n * deliberate choice — those are the client's own taste signals, and quietly\n * widening it would replace their taste with the library's average. But a thin\n * favorites result has three completely different causes that look identical\n * from the outside:\n *\n * 1. the client has no taste profile yet,\n * 2. the client saved plenty and the pages failed to be read,\n * 3. the query simply did not match.\n *\n * They call for opposite next moves, and one production company sat in case 2\n * with **211 of 234 saved pages holding no sections at all** — where the honest\n * answer, \"your library is broken\", was being delivered as \"nothing saved yet\".\n *\n * So: never widen the scope, always name the cause, and always leave the\n * decision with the caller.\n */\nexport function favoritesScopeHints(health: InspirationFavoritesHealth | undefined, resultCount: number): string[] {\n if (!health) return [];\n\n const hints: string[] = [];\n\n if (health.savedPages === 0) {\n hints.push(\n \"This company hasn't saved any reference pages yet, so there is no taste profile to search — an empty result here says nothing about the library. \" +\n \"Search the whole shared library with --scope all, or save a page the client admires with `baker landing inspiration add <url>`.\",\n );\n return hints;\n }\n\n if (health.failedPages > 0) {\n const retryable = health.failedExamples.filter((example) => example.retryable).map((example) => example.url);\n const permanent = health.failedExamples.filter((example) => !example.retryable).map((example) => example.url);\n hints.push(\n `${health.failedPages} of this company's ${health.savedPages} saved pages could not be read, so they hold no sections — ` +\n `only ${health.usablePages} are usable, which is why this result is thin. Search the whole library with --scope all.`,\n );\n if (retryable.length > 0) {\n hints.push(\n `Worth another go: ${retryable.join(\", \")} — run \\`baker landing inspiration add <url>\\` on one of them to study it again.`,\n );\n }\n if (permanent.length > 0) {\n hints.push(`Not worth retrying — these sites refuse automated readers: ${permanent.join(\", \")}.`);\n }\n }\n\n if (health.studyingPages > 0) {\n hints.push(\n `${health.studyingPages} saved ${health.studyingPages === 1 ? \"page is\" : \"pages are\"} still being studied and will be searchable in a few minutes. Carry on; do not wait on them.`,\n );\n }\n\n if (resultCount === 0 && health.failedPages === 0 && health.studyingPages === 0) {\n hints.push(\n `Nothing in this company's ${health.usablePages} readable saved pages matches. The saved set is healthy, so this is the query, not the library — loosen the filters or search everything with --scope all.`,\n );\n }\n\n return hints;\n}\n\n/** Warn when the extracted markup is known not to match what the screenshot shows. */\nexport function fidelityHint(fidelity: number | null | undefined): string | null {\n if (fidelity == null) return null;\n if (fidelity >= 0.9) return null;\n if (fidelity >= 0.75) {\n return `Reproduction fidelity ${fidelity.toFixed(2)} — the markup is close but not exact. Trust the screenshot over the code.`;\n }\n return (\n `Reproduction fidelity ${fidelity.toFixed(2)} — this section is scroll- or JS-driven and the extracted markup ` +\n `does NOT render like the original. Use the screenshot and the notes; treat the code as a hint only.`\n );\n}\n\nconst STALE_COPY_AFTER_MS = 30 * 24 * 60 * 60 * 1000;\n\n/**\n * Tell the agent a page's copy is old, before it builds from it.\n *\n * The library refreshes itself about monthly, but a site can redesign the day\n * after its read, and an agent copying last quarter's hero is building from\n * something the client can see is wrong.\n */\n/** `filedUrl`, never the address the capture landed on: after a redirect, refreshing that one files a second copy. */\nexport function staleCopyHint(studiedAt: number | null | undefined, filedUrl: string, now = Date.now()): string | null {\n if (!studiedAt || now - studiedAt < STALE_COPY_AFTER_MS) return null;\n const date = new Date(studiedAt).toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\", timeZone: \"UTC\" });\n return `This copy of the page was read on ${date}. If the user says the live page looks different, run: baker landing inspiration add ${filedUrl} --refresh`;\n}\n\nexport function reportError(error: unknown): never {\n if (error instanceof ApiError) {\n writeJson({ ok: false, error: { code: error.code, message: error.message } });\n } else {\n writeJson({\n ok: false,\n error: { code: \"UNKNOWN\", message: error instanceof Error ? error.message : String(error) },\n });\n }\n process.exit(1);\n}\n\nexport function splitList(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const parts = value\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n return parts.length > 0 ? parts : undefined;\n}\n\nexport function parseNumber(value: string | undefined): number | undefined {\n if (value === undefined || value === \"\") return undefined;\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n"],"mappings":";;;;;;;;AAYO,IAAM,oBAAoB;AAAA,EAC/B,OACE;AAAA,EAEF,kBACE;AAEJ;AAsBO,SAAS,oBAAoB,QAAgD,aAA+B;AACjH,MAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,QAAM,QAAkB,CAAC;AAEzB,MAAI,OAAO,eAAe,GAAG;AAC3B,UAAM;AAAA,MACJ;AAAA,IAEF;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,cAAc,GAAG;AAC1B,UAAM,YAAY,OAAO,eAAe,OAAO,CAAC,YAAY,QAAQ,SAAS,EAAE,IAAI,CAAC,YAAY,QAAQ,GAAG;AAC3G,UAAM,YAAY,OAAO,eAAe,OAAO,CAAC,YAAY,CAAC,QAAQ,SAAS,EAAE,IAAI,CAAC,YAAY,QAAQ,GAAG;AAC5G,UAAM;AAAA,MACJ,GAAG,OAAO,WAAW,sBAAsB,OAAO,UAAU,wEAClD,OAAO,WAAW;AAAA,IAC9B;AACA,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM;AAAA,QACJ,qBAAqB,UAAU,KAAK,IAAI,CAAC;AAAA,MAC3C;AAAA,IACF;AACA,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,KAAK,mEAA8D,UAAU,KAAK,IAAI,CAAC,GAAG;AAAA,IAClG;AAAA,EACF;AAEA,MAAI,OAAO,gBAAgB,GAAG;AAC5B,UAAM;AAAA,MACJ,GAAG,OAAO,aAAa,UAAU,OAAO,kBAAkB,IAAI,YAAY,WAAW;AAAA,IACvF;AAAA,EACF;AAEA,MAAI,gBAAgB,KAAK,OAAO,gBAAgB,KAAK,OAAO,kBAAkB,GAAG;AAC/E,UAAM;AAAA,MACJ,6BAA6B,OAAO,WAAW;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,aAAa,UAAoD;AAC/E,MAAI,YAAY,KAAM,QAAO;AAC7B,MAAI,YAAY,IAAK,QAAO;AAC5B,MAAI,YAAY,MAAM;AACpB,WAAO,yBAAyB,SAAS,QAAQ,CAAC,CAAC;AAAA,EACrD;AACA,SACE,yBAAyB,SAAS,QAAQ,CAAC,CAAC;AAGhD;AAEA,IAAM,sBAAsB,KAAK,KAAK,KAAK,KAAK;AAUzC,SAAS,cAAc,WAAsC,UAAkB,MAAM,KAAK,IAAI,GAAkB;AACrH,MAAI,CAAC,aAAa,MAAM,YAAY,oBAAqB,QAAO;AAChE,QAAM,OAAO,IAAI,KAAK,SAAS,EAAE,mBAAmB,SAAS,EAAE,OAAO,SAAS,KAAK,WAAW,UAAU,MAAM,CAAC;AAChH,SAAO,qCAAqC,IAAI,wFAAwF,QAAQ;AAClJ;AAEO,SAAS,YAAY,OAAuB;AACjD,MAAI,iBAAiB,UAAU;AAC7B,cAAU,EAAE,IAAI,OAAO,OAAO,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,QAAQ,EAAE,CAAC;AAAA,EAC9E,OAAO;AACL,cAAU;AAAA,MACR,IAAI;AAAA,MACJ,OAAO,EAAE,MAAM,WAAW,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AAAA,IAC5F,CAAC;AAAA,EACH;AACA,UAAQ,KAAK,CAAC;AAChB;AAEO,SAAS,UAAU,OAAiD;AACzE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,MACX,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO;AACjB,SAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;AAEO,SAAS,YAAY,OAA+C;AACzE,MAAI,UAAU,UAAa,UAAU,GAAI,QAAO;AAChD,QAAM,SAAS,OAAO,KAAK;AAC3B,SAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAC5C;","names":[]}