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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (443) hide show
  1. package/README.md +10 -11
  2. package/dist/{account-XQXC7BR6.js → account-AL2ZDSR7.js} +4 -5
  3. package/dist/{account-XQXC7BR6.js.map → account-AL2ZDSR7.js.map} +1 -1
  4. package/dist/{accounts-722UY53A.js → accounts-HAFCLSR5.js} +3 -4
  5. package/dist/{accounts-722UY53A.js.map → accounts-HAFCLSR5.js.map} +1 -1
  6. package/dist/{accounts-E67BMK7T.js → accounts-O5MFO3QQ.js} +5 -6
  7. package/dist/{accounts-E67BMK7T.js.map → accounts-O5MFO3QQ.js.map} +1 -1
  8. package/dist/{actions-6TQMSVWD.js → actions-P35MEMGN.js} +18 -18
  9. package/dist/{add-2BEGRHUX.js → add-5GAN6CVO.js} +5 -28
  10. package/dist/add-5GAN6CVO.js.map +1 -0
  11. package/dist/{add-LEMKEOPO.js → add-6DTC6X5G.js} +2 -3
  12. package/dist/{add-LEMKEOPO.js.map → add-6DTC6X5G.js.map} +1 -1
  13. package/dist/{ads-AGYCVD62.js → ads-73PGA4YC.js} +4 -4
  14. package/dist/{advertisers-2VQKAYKG.js → advertisers-AE75CGVE.js} +3 -4
  15. package/dist/{advertisers-2VQKAYKG.js.map → advertisers-AE75CGVE.js.map} +1 -1
  16. package/dist/{analytics-IFELDWLL.js → analytics-FKCXIMPO.js} +20 -24
  17. package/dist/analytics-FKCXIMPO.js.map +1 -0
  18. package/dist/{analytics-OH5QEH7F.js → analytics-FPWQQGRM.js} +3 -4
  19. package/dist/{analytics-OH5QEH7F.js.map → analytics-FPWQQGRM.js.map} +1 -1
  20. package/dist/{assign-PTUJUCEL.js → assign-ABN2AQ4J.js} +3 -4
  21. package/dist/{assign-PTUJUCEL.js.map → assign-ABN2AQ4J.js.map} +1 -1
  22. package/dist/{audience-size-LRI6GJRT.js → audience-size-GNBJY35X.js} +3 -4
  23. package/dist/{audience-size-LRI6GJRT.js.map → audience-size-GNBJY35X.js.map} +1 -1
  24. package/dist/{audit-HWP7OPB7.js → audit-3VS63TBW.js} +3 -4
  25. package/dist/{audit-HWP7OPB7.js.map → audit-3VS63TBW.js.map} +1 -1
  26. package/dist/{autocomplete-J6DHU6MR.js → autocomplete-VS3XG3B7.js} +3 -4
  27. package/dist/{autocomplete-J6DHU6MR.js.map → autocomplete-VS3XG3B7.js.map} +1 -1
  28. package/dist/{avatars-467OSBD6.js → avatars-EKCKHCC3.js} +4 -4
  29. package/dist/{bid-pricing-EO5WLHGV.js → bid-pricing-Q72B65AY.js} +3 -4
  30. package/dist/{bid-pricing-EO5WLHGV.js.map → bid-pricing-Q72B65AY.js.map} +1 -1
  31. package/dist/{brand-YRTEPGBK.js → brand-C6PFGGQN.js} +2 -2
  32. package/dist/{brief-OSFJ2V7F.js → brief-YFJHQ5VQ.js} +7 -8
  33. package/dist/{brief-OSFJ2V7F.js.map → brief-YFJHQ5VQ.js.map} +1 -1
  34. package/dist/{campaign-groups-PQ6KSQJR.js → campaign-groups-KFFYQPU3.js} +8 -9
  35. package/dist/{campaign-groups-PQ6KSQJR.js.map → campaign-groups-KFFYQPU3.js.map} +1 -1
  36. package/dist/{campaign-writes-5OVLUD5E.js → campaign-writes-FHOS5XZY.js} +3 -4
  37. package/dist/{campaign-writes-5OVLUD5E.js.map → campaign-writes-FHOS5XZY.js.map} +1 -1
  38. package/dist/{campaigns-6T3NSUT2.js → campaigns-2NHWBF5C.js} +11 -12
  39. package/dist/{campaigns-6T3NSUT2.js.map → campaigns-2NHWBF5C.js.map} +1 -1
  40. package/dist/{campaigns-OYMXDGWX.js → campaigns-KZYZTXDS.js} +5 -5
  41. package/dist/{canvas-YQFG52IG.js → canvas-5NB27FX2.js} +13 -13
  42. package/dist/{capabilities-PXBKUN2G.js → capabilities-DJFTRJKS.js} +3 -4
  43. package/dist/{capabilities-PXBKUN2G.js.map → capabilities-DJFTRJKS.js.map} +1 -1
  44. package/dist/{catalog-XLXIM7IW.js → catalog-VSSY6FGI.js} +4 -4
  45. package/dist/{chats-UK47UE7C.js → chats-D2CSDX5Q.js} +3 -4
  46. package/dist/{chats-UK47UE7C.js.map → chats-D2CSDX5Q.js.map} +1 -1
  47. package/dist/{chunk-5ZNTADVR.js → chunk-3G3ZDLMI.js} +2 -2
  48. package/dist/{chunk-SJYEY5MV.js → chunk-3HJLHTWP.js} +3 -12
  49. package/dist/{chunk-SJYEY5MV.js.map → chunk-3HJLHTWP.js.map} +1 -1
  50. package/dist/{chunk-ZDMTXQ2Q.js → chunk-3IBYKLXR.js} +2 -2
  51. package/dist/{chunk-CWYAELVG.js → chunk-464O4MT2.js} +2 -2
  52. package/dist/{chunk-NA63BH7V.js → chunk-4AUMTNVB.js} +3 -3
  53. package/dist/{chunk-NDEE6G2J.js → chunk-4BQXAE7Z.js} +2 -2
  54. package/dist/{chunk-2AOE2MZQ.js → chunk-5ZDLTE5T.js} +3 -3
  55. package/dist/{chunk-ULG4QRTV.js → chunk-6NB47MRW.js} +2 -2
  56. package/dist/{chunk-24EB7EDR.js → chunk-7YCRFMXF.js} +3 -3
  57. package/dist/{chunk-WGUQHAJY.js → chunk-A4LOJ2VD.js} +2 -2
  58. package/dist/{chunk-6F7DVPOS.js → chunk-AEOSAVVL.js} +3 -3
  59. package/dist/{chunk-MACCF4JZ.js → chunk-CMPEUZOR.js} +22 -16
  60. package/dist/{chunk-MACCF4JZ.js.map → chunk-CMPEUZOR.js.map} +1 -1
  61. package/dist/{chunk-N4LAYIIN.js → chunk-CSYSX4D2.js} +2 -2
  62. package/dist/{chunk-RX2DKU3W.js → chunk-DGUNI37S.js} +2 -2
  63. package/dist/{chunk-QE7W555R.js → chunk-DWHIOO7E.js} +12 -163
  64. package/dist/chunk-DWHIOO7E.js.map +1 -0
  65. package/dist/{chunk-FPOGPFAG.js → chunk-EBWBG6YV.js} +51 -24
  66. package/dist/chunk-EBWBG6YV.js.map +1 -0
  67. package/dist/{chunk-NYIGXDUG.js → chunk-EDLZGTGN.js} +39 -1
  68. package/dist/chunk-EDLZGTGN.js.map +1 -0
  69. package/dist/{chunk-I3ZR655O.js → chunk-IR6D7K4H.js} +2 -2
  70. package/dist/{chunk-FUHN4MFY.js → chunk-JQJDXPCO.js} +2 -2
  71. package/dist/{chunk-7CTMH5AK.js → chunk-KAUOHQTF.js} +3 -3
  72. package/dist/{chunk-VYQ3QJ3C.js → chunk-KHRXPQID.js} +2 -2
  73. package/dist/{chunk-6Y7ZBENQ.js → chunk-LECGCWT5.js} +6 -6
  74. package/dist/{chunk-5WCSKQ7Z.js → chunk-LZ73CZGP.js} +6 -6
  75. package/dist/{chunk-R25YLW6H.js → chunk-MELOSESI.js} +2 -2
  76. package/dist/{chunk-DCRPXOJJ.js → chunk-MXYBTMKB.js} +2 -2
  77. package/dist/{chunk-54C6YDGJ.js → chunk-NPY4QUMQ.js} +2 -2
  78. package/dist/{chunk-LYQJ4PZW.js → chunk-OQ6663F4.js} +5 -5
  79. package/dist/{chunk-H3427GPU.js → chunk-OZRUJVIQ.js} +2 -2
  80. package/dist/{chunk-KMKEYI37.js → chunk-Q2V6E6SL.js} +3 -3
  81. package/dist/{chunk-VL43TNIP.js → chunk-QRP3PXWN.js} +2 -2
  82. package/dist/{chunk-HDLYPC6K.js → chunk-RPUSTYHL.js} +3 -5
  83. package/dist/{chunk-HDLYPC6K.js.map → chunk-RPUSTYHL.js.map} +1 -1
  84. package/dist/{chunk-C46GUI2S.js → chunk-RZBEK2VE.js} +2 -2
  85. package/dist/{chunk-2VPBIT65.js → chunk-S3A3YOKO.js} +8 -8
  86. package/dist/{chunk-FYGR3I2A.js → chunk-S77PZVYM.js} +3 -3
  87. package/dist/{chunk-VLMBTPXU.js → chunk-SHL7LOC3.js} +3 -3
  88. package/dist/{chunk-HR6IWNKE.js → chunk-SSJK7FEV.js} +1140 -1196
  89. package/dist/chunk-SSJK7FEV.js.map +1 -0
  90. package/dist/{chunk-KS2QY6MK.js → chunk-W3ZHJJVT.js} +4 -4
  91. package/dist/{chunk-7EPXVICM.js → chunk-XF4JUKVF.js} +5 -38
  92. package/dist/chunk-XF4JUKVF.js.map +1 -0
  93. package/dist/{chunk-RL5CP7N6.js → chunk-Y6O7EWYY.js} +5 -5
  94. package/dist/{chunk-6NY2GPR4.js → chunk-Y6ZQXUZ7.js} +3 -3
  95. package/dist/{chunk-HROZYQ5H.js → chunk-YRQYA2LR.js} +5 -63
  96. package/dist/chunk-YRQYA2LR.js.map +1 -0
  97. package/dist/{chunk-ASI4P6X2.js → chunk-YUCLMOEG.js} +6 -6
  98. package/dist/chunk-YUCLMOEG.js.map +1 -0
  99. package/dist/{chunk-WKQG6TER.js → chunk-ZEYEWPK6.js} +2 -2
  100. package/dist/{claim-W6G6VEG5.js → claim-FZ5OQLMU.js} +3 -4
  101. package/dist/{claim-W6G6VEG5.js.map → claim-FZ5OQLMU.js.map} +1 -1
  102. package/dist/cli.js +30 -30
  103. package/dist/{companies-TS6KBATJ.js → companies-DNI634RC.js} +3 -4
  104. package/dist/{companies-TS6KBATJ.js.map → companies-DNI634RC.js.map} +1 -1
  105. package/dist/{complete-LYR2HMQU.js → complete-2FZMGJV5.js} +3 -4
  106. package/dist/{complete-LYR2HMQU.js.map → complete-2FZMGJV5.js.map} +1 -1
  107. package/dist/{connect-FCXNVTXG.js → connect-QCOGEPP4.js} +6 -13
  108. package/dist/{conversation-6ZJGPCXM.js → conversation-6IOGV7B7.js} +3 -4
  109. package/dist/{conversation-6ZJGPCXM.js.map → conversation-6IOGV7B7.js.map} +1 -1
  110. package/dist/{conversions-UHB55MMQ.js → conversions-4SRZPBBX.js} +7 -8
  111. package/dist/{conversions-UHB55MMQ.js.map → conversions-4SRZPBBX.js.map} +1 -1
  112. package/dist/{create-EX6OWLNM.js → create-BJNMO6HT.js} +2 -3
  113. package/dist/{create-EX6OWLNM.js.map → create-BJNMO6HT.js.map} +1 -1
  114. package/dist/{create-JFSK4BOP.js → create-FX4OJ2XF.js} +3 -4
  115. package/dist/{create-JFSK4BOP.js.map → create-FX4OJ2XF.js.map} +1 -1
  116. package/dist/{create-JCA7JPLP.js → create-RM7HV77Y.js} +3 -4
  117. package/dist/{create-JCA7JPLP.js.map → create-RM7HV77Y.js.map} +1 -1
  118. package/dist/{create-WU22YYU2.js → create-VXM34ZWH.js} +3 -4
  119. package/dist/{create-WU22YYU2.js.map → create-VXM34ZWH.js.map} +1 -1
  120. package/dist/{creatives-FXUQ5WSD.js → creatives-B5NTXPUB.js} +10 -10
  121. package/dist/{creatives-KGXUOYPE.js → creatives-JSWBFQ5R.js} +8 -9
  122. package/dist/{creatives-KGXUOYPE.js.map → creatives-JSWBFQ5R.js.map} +1 -1
  123. package/dist/{credentials-MJC7PGKR.js → credentials-C33K6XCJ.js} +3 -4
  124. package/dist/{credentials-MJC7PGKR.js.map → credentials-C33K6XCJ.js.map} +1 -1
  125. package/dist/{critique-GS5VV5ZC.js → critique-4V5SKH7C.js} +6 -7
  126. package/dist/{critique-GS5VV5ZC.js.map → critique-4V5SKH7C.js.map} +1 -1
  127. package/dist/{critique-TPHR27KH.js → critique-ZS4ON3SU.js} +3 -4
  128. package/dist/{critique-TPHR27KH.js.map → critique-ZS4ON3SU.js.map} +1 -1
  129. package/dist/{crm-VK44O3ED.js → crm-52ROSWH5.js} +4 -5
  130. package/dist/{crm-VK44O3ED.js.map → crm-52ROSWH5.js.map} +1 -1
  131. package/dist/{crm-AVCM5D4G.js → crm-R5IXIFIV.js} +4 -5
  132. package/dist/{crm-AVCM5D4G.js.map → crm-R5IXIFIV.js.map} +1 -1
  133. package/dist/{customers-XH2DMTFH.js → customers-A36LOZOB.js} +5 -6
  134. package/dist/{delete-WI5E3DR3.js → delete-AIGE4Y4H.js} +3 -4
  135. package/dist/{delete-WI5E3DR3.js.map → delete-AIGE4Y4H.js.map} +1 -1
  136. package/dist/{delete-KRH2YMSZ.js → delete-HGHXY24R.js} +3 -4
  137. package/dist/{delete-KRH2YMSZ.js.map → delete-HGHXY24R.js.map} +1 -1
  138. package/dist/{delete-E3R3TKIL.js → delete-M2GDLPYN.js} +2 -3
  139. package/dist/{delete-E3R3TKIL.js.map → delete-M2GDLPYN.js.map} +1 -1
  140. package/dist/{demographics-XV5PBA77.js → demographics-NTWB2IMG.js} +3 -4
  141. package/dist/{demographics-XV5PBA77.js.map → demographics-NTWB2IMG.js.map} +1 -1
  142. package/dist/{discard-HTQUUHJR.js → discard-2WWQG6OU.js} +3 -4
  143. package/dist/{discard-HTQUUHJR.js.map → discard-2WWQG6OU.js.map} +1 -1
  144. package/dist/{domain-RECGZXJB.js → domain-Y2LT6JLT.js} +3 -4
  145. package/dist/{domain-RECGZXJB.js.map → domain-Y2LT6JLT.js.map} +1 -1
  146. package/dist/{draft-Q546QPPU.js → draft-EJXNNJ3Y.js} +4 -5
  147. package/dist/{draft-Q546QPPU.js.map → draft-EJXNNJ3Y.js.map} +1 -1
  148. package/dist/{draft-PVTX6QT6.js → draft-FJ7WHIXW.js} +3 -4
  149. package/dist/{draft-PVTX6QT6.js.map → draft-FJ7WHIXW.js.map} +1 -1
  150. package/dist/{draft-2IBSJEKC.js → draft-SLHAKJ2A.js} +3 -4
  151. package/dist/{draft-2IBSJEKC.js.map → draft-SLHAKJ2A.js.map} +1 -1
  152. package/dist/engine/index.js +3 -3
  153. package/dist/{facets-7EVPJMKS.js → facets-U7AQC4H6.js} +3 -4
  154. package/dist/{facets-7EVPJMKS.js.map → facets-U7AQC4H6.js.map} +1 -1
  155. package/dist/{feedback-EIZKS4JU.js → feedback-OLTCHE6C.js} +2 -2
  156. package/dist/{feedback-record-TKO54BOE.js → feedback-record-7WZ4H7EP.js} +8 -9
  157. package/dist/{feedback-record-TKO54BOE.js.map → feedback-record-7WZ4H7EP.js.map} +1 -1
  158. package/dist/{fetch-4BY6HYUM.js → fetch-W7NULDEO.js} +3 -4
  159. package/dist/{fetch-4BY6HYUM.js.map → fetch-W7NULDEO.js.map} +1 -1
  160. package/dist/{find-FRRHAPWX.js → find-OTDIX6V4.js} +4 -4
  161. package/dist/{flows-KTFAML22.js → flows-KABCBS3S.js} +17 -21
  162. package/dist/flows-KABCBS3S.js.map +1 -0
  163. package/dist/{fonts-MXR3ZKDX.js → fonts-EMMX3KII.js} +5 -6
  164. package/dist/{forecast-3QTJYVND.js → forecast-GNODEIIC.js} +3 -4
  165. package/dist/{forecast-3QTJYVND.js.map → forecast-GNODEIIC.js.map} +1 -1
  166. package/dist/{funnel-I6XIAEHG.js → funnel-AAX27NH4.js} +455 -11
  167. package/dist/funnel-AAX27NH4.js.map +1 -0
  168. package/dist/{ga4-DV2AXCSL.js → ga4-UDQ2HA2J.js} +1 -1
  169. package/dist/{get-5PKNKJ5S.js → get-QEYJRLV3.js} +4 -7
  170. package/dist/get-QEYJRLV3.js.map +1 -0
  171. package/dist/{get-72YPHJGV.js → get-RTVUZM6E.js} +3 -4
  172. package/dist/{get-72YPHJGV.js.map → get-RTVUZM6E.js.map} +1 -1
  173. package/dist/{google-QYYYSSXI.js → google-KTO3PLEU.js} +5 -5
  174. package/dist/{google-6OGZX47I.js → google-M7KEXVK5.js} +2 -2
  175. package/dist/{google-ads-QGMQKZQD.js → google-ads-OK6IG3UV.js} +3 -4
  176. package/dist/{google-ads-QGMQKZQD.js.map → google-ads-OK6IG3UV.js.map} +1 -1
  177. package/dist/{gsc-TAKOF7J5.js → gsc-P3QYGDV2.js} +1 -1
  178. package/dist/{history-6AVQX2OQ.js → history-PQUJKK26.js} +3 -4
  179. package/dist/{history-6AVQX2OQ.js.map → history-PQUJKK26.js.map} +1 -1
  180. package/dist/{hubspot-SVEMFK5S.js → hubspot-Y77VLY6Y.js} +8 -9
  181. package/dist/{hubspot-SVEMFK5S.js.map → hubspot-Y77VLY6Y.js.map} +1 -1
  182. package/dist/{icon-L4RSS6PZ.js → icon-I43F77FV.js} +4 -4
  183. package/dist/{ideas-NFOW3HKJ.js → ideas-MIDU7YOA.js} +2 -3
  184. package/dist/{images-2EFFUNNV.js → images-S254MS6O.js} +9 -9
  185. package/dist/{ingest-2SO62RRI.js → ingest-J4I3HKM3.js} +2 -3
  186. package/dist/{ingest-2SO62RRI.js.map → ingest-J4I3HKM3.js.map} +1 -1
  187. package/dist/{ingest-2EIKN4QC.js → ingest-YV2NLDBE.js} +3 -4
  188. package/dist/{inspect-4OOS4APT.js → inspect-Q5NHBBHX.js} +3 -4
  189. package/dist/{inspect-4OOS4APT.js.map → inspect-Q5NHBBHX.js.map} +1 -1
  190. package/dist/{inspiration-S3DU4CMQ.js → inspiration-P265QJ2H.js} +1 -1
  191. package/dist/{keyword-metrics-SF4CSNZ2.js → keyword-metrics-PDY4ZXSP.js} +3 -4
  192. package/dist/{keyword-metrics-SF4CSNZ2.js.map → keyword-metrics-PDY4ZXSP.js.map} +1 -1
  193. package/dist/{keywords-for-site-WDAOPNKC.js → keywords-for-site-GALSCV77.js} +3 -4
  194. package/dist/{keywords-for-site-WDAOPNKC.js.map → keywords-for-site-GALSCV77.js.map} +1 -1
  195. package/dist/{landing-2ZB46LXH.js → landing-CJYGWCK4.js} +3 -3
  196. package/dist/{leads-A4W5KTWB.js → leads-PHKG6CP3.js} +3 -4
  197. package/dist/{leads-A4W5KTWB.js.map → leads-PHKG6CP3.js.map} +1 -1
  198. package/dist/{learn-IPULBCOD.js → learn-FUQSY7DN.js} +4 -5
  199. package/dist/{learn-IPULBCOD.js.map → learn-FUQSY7DN.js.map} +1 -1
  200. package/dist/{line-item-writes-EMYSOJKM.js → line-item-writes-E6MZPIZZ.js} +3 -4
  201. package/dist/{line-item-writes-EMYSOJKM.js.map → line-item-writes-E6MZPIZZ.js.map} +1 -1
  202. package/dist/{line-items-5NECXUZT.js → line-items-7ZGIKEF2.js} +5 -5
  203. package/dist/{link-CI45HWFN.js → link-QYAW6A2W.js} +3 -4
  204. package/dist/{link-CI45HWFN.js.map → link-QYAW6A2W.js.map} +1 -1
  205. package/dist/{linkedin-B7SYR75X.js → linkedin-FFSDSGGS.js} +26 -27
  206. package/dist/{linkedin-B7SYR75X.js.map → linkedin-FFSDSGGS.js.map} +1 -1
  207. package/dist/{list-ZBT3EBVZ.js → list-5IC6KIKO.js} +3 -4
  208. package/dist/{list-ZBT3EBVZ.js.map → list-5IC6KIKO.js.map} +1 -1
  209. package/dist/{list-2BARXOT5.js → list-NVQC5SNY.js} +2 -3
  210. package/dist/{list-2BARXOT5.js.map → list-NVQC5SNY.js.map} +1 -1
  211. package/dist/{list-BIEVLEHS.js → list-SAV3LQHY.js} +3 -4
  212. package/dist/{list-BIEVLEHS.js.map → list-SAV3LQHY.js.map} +1 -1
  213. package/dist/{log-C23OOAJZ.js → log-XZPVOALD.js} +3 -4
  214. package/dist/{log-C23OOAJZ.js.map → log-XZPVOALD.js.map} +1 -1
  215. package/dist/{logo-Q5D7PZY6.js → logo-2IP663QO.js} +3 -3
  216. package/dist/{lookup-ETWY47F7.js → lookup-XK45W2SH.js} +5 -6
  217. package/dist/{make-TPKKJXGL.js → make-BMWRKIIY.js} +20 -18
  218. package/dist/{make-TPKKJXGL.js.map → make-BMWRKIIY.js.map} +1 -1
  219. package/dist/{map-SYZMPHLL.js → map-4J5WIWIG.js} +4 -5
  220. package/dist/{map-SYZMPHLL.js.map → map-4J5WIWIG.js.map} +1 -1
  221. package/dist/{mcp-6FQBVJ6F.js → mcp-XXD7ZQCP.js} +2 -3
  222. package/dist/{mcp-6FQBVJ6F.js.map → mcp-XXD7ZQCP.js.map} +1 -1
  223. package/dist/{media-sources-ZXHEEP6T.js → media-sources-O6ZRUA3N.js} +2 -2
  224. package/dist/{members-UDY4OOJW.js → members-D5ZYLS4Y.js} +3 -4
  225. package/dist/{members-UDY4OOJW.js.map → members-D5ZYLS4Y.js.map} +1 -1
  226. package/dist/{normalize-DAKHYS3V.js → normalize-PCNC6E2N.js} +3 -7
  227. package/dist/{normalize-DAKHYS3V.js.map → normalize-PCNC6E2N.js.map} +1 -1
  228. package/dist/{options-QL3ULED5.js → options-MQ65VEVD.js} +6 -7
  229. package/dist/{options-QL3ULED5.js.map → options-MQ65VEVD.js.map} +1 -1
  230. package/dist/{performance-UF5VTY2U.js → performance-6QW2KEEQ.js} +4 -5
  231. package/dist/{promoted-tweet-writes-7HGESJ46.js → promoted-tweet-writes-JPLHY3GM.js} +3 -4
  232. package/dist/{promoted-tweet-writes-7HGESJ46.js.map → promoted-tweet-writes-JPLHY3GM.js.map} +1 -1
  233. package/dist/{promoted-tweets-LZKS5JIF.js → promoted-tweets-SURKMHFI.js} +3 -3
  234. package/dist/{publish-NPD3SMZL.js → publish-HCQ6MXLB.js} +3 -4
  235. package/dist/{publish-NPD3SMZL.js.map → publish-HCQ6MXLB.js.map} +1 -1
  236. package/dist/{reddit-NU2N3LZD.js → reddit-GIP3ADMS.js} +4 -5
  237. package/dist/{refresh-EBVJ2C6L.js → refresh-UXQSLCR3.js} +2 -3
  238. package/dist/{refresh-EBVJ2C6L.js.map → refresh-UXQSLCR3.js.map} +1 -1
  239. package/dist/{release-V43YB2PY.js → release-5KVLXNP6.js} +3 -4
  240. package/dist/{release-V43YB2PY.js.map → release-5KVLXNP6.js.map} +1 -1
  241. package/dist/{remove-QPSWLFI4.js → remove-6FIVKCJI.js} +2 -3
  242. package/dist/{remove-QPSWLFI4.js.map → remove-6FIVKCJI.js.map} +1 -1
  243. package/dist/{reopen-GQ66NMWF.js → reopen-YM5LNOLB.js} +3 -4
  244. package/dist/{reopen-GQ66NMWF.js.map → reopen-YM5LNOLB.js.map} +1 -1
  245. package/dist/{rerun-PZK275DY.js → rerun-6XZG7BGK.js} +17 -18
  246. package/dist/{rerun-PZK275DY.js.map → rerun-6XZG7BGK.js.map} +1 -1
  247. package/dist/{research-FMM6AWZC.js → research-2BLEISBG.js} +10 -10
  248. package/dist/{research-GEOCUBXB.js → research-YOGE7GT2.js} +2 -3
  249. package/dist/{research-GEOCUBXB.js.map → research-YOGE7GT2.js.map} +1 -1
  250. package/dist/{reset-REXJ6AUK.js → reset-C4UHQ3EU.js} +2 -3
  251. package/dist/{reset-REXJ6AUK.js.map → reset-C4UHQ3EU.js.map} +1 -1
  252. package/dist/{reset-Y72IVESB.js → reset-OLVB6AE6.js} +2 -3
  253. package/dist/{reset-Y72IVESB.js.map → reset-OLVB6AE6.js.map} +1 -1
  254. package/dist/{resolve-OGX7C4TV.js → resolve-XYH2GDAE.js} +3 -4
  255. package/dist/{resolve-OGX7C4TV.js.map → resolve-XYH2GDAE.js.map} +1 -1
  256. package/dist/{retry-TCUBBFR5.js → retry-726GKI6V.js} +2 -3
  257. package/dist/{retry-TCUBBFR5.js.map → retry-726GKI6V.js.map} +1 -1
  258. package/dist/{retry-CD6JAQ3F.js → retry-7EELDEQP.js} +2 -3
  259. package/dist/{retry-CD6JAQ3F.js.map → retry-7EELDEQP.js.map} +1 -1
  260. package/dist/{run-EUO34T2J.js → run-MMEDKJDB.js} +17 -18
  261. package/dist/{run-A5ZDXTOI.js → run-P4KR2MXC.js} +3 -4
  262. package/dist/{run-A5ZDXTOI.js.map → run-P4KR2MXC.js.map} +1 -1
  263. package/dist/{scaffold-ad-SW2HEWM3.js → scaffold-ad-PBTEWDAC.js} +12 -13
  264. package/dist/{scaffold-ad-SW2HEWM3.js.map → scaffold-ad-PBTEWDAC.js.map} +1 -1
  265. package/dist/{scaffold-static-ad-ECTJL54Y.js → scaffold-static-ad-RM4M4X5U.js} +36 -37
  266. package/dist/scaffold-static-ad-RM4M4X5U.js.map +1 -0
  267. package/dist/{scaffold-video-EI7U7RBK.js → scaffold-video-O2TTKZIE.js} +11 -12
  268. package/dist/{scaffold-video-EI7U7RBK.js.map → scaffold-video-O2TTKZIE.js.map} +1 -1
  269. package/dist/{schedule-S5YZJZ5U.js → schedule-RDK4GEPI.js} +2 -3
  270. package/dist/{schedule-S5YZJZ5U.js.map → schedule-RDK4GEPI.js.map} +1 -1
  271. package/dist/{scheduled-agents-N4LJRM4C.js → scheduled-agents-6U44QE76.js} +11 -11
  272. package/dist/{schema-R7JWWOF4.js → schema-CHJDC7GQ.js} +4 -8
  273. package/dist/{schema-R7JWWOF4.js.map → schema-CHJDC7GQ.js.map} +1 -1
  274. package/dist/{search-KHMQH3AT.js → search-PMJRU3C4.js} +2 -3
  275. package/dist/{search-KHMQH3AT.js.map → search-PMJRU3C4.js.map} +1 -1
  276. package/dist/{select-O2FN2JEQ.js → select-OEUKOVZ5.js} +8 -9
  277. package/dist/{select-O2FN2JEQ.js.map → select-OEUKOVZ5.js.map} +1 -1
  278. package/dist/{sends-BQZM5PLS.js → sends-WGJVQUMF.js} +4 -5
  279. package/dist/{sends-BQZM5PLS.js.map → sends-WGJVQUMF.js.map} +1 -1
  280. package/dist/{set-prompt-2HASHGWC.js → set-prompt-5E5I7QAZ.js} +8 -9
  281. package/dist/{set-prompt-2HASHGWC.js.map → set-prompt-5E5I7QAZ.js.map} +1 -1
  282. package/dist/{setup-links-GYSE56GX.js → setup-links-REPREN3C.js} +3 -4
  283. package/dist/{setup-links-GYSE56GX.js.map → setup-links-REPREN3C.js.map} +1 -1
  284. package/dist/{site-4SKM7RKG.js → site-WFSWIA3S.js} +4 -5
  285. package/dist/{site-4SKM7RKG.js.map → site-WFSWIA3S.js.map} +1 -1
  286. package/dist/{sources-R2NKNC6J.js → sources-AMI2AWKZ.js} +9 -10
  287. package/dist/{sources-R2NKNC6J.js.map → sources-AMI2AWKZ.js.map} +1 -1
  288. package/dist/{sources-FQ2UZTHL.js → sources-YBQ6KPFM.js} +6 -6
  289. package/dist/{stale-W756ACKC.js → stale-IGFUKEN2.js} +7 -8
  290. package/dist/{stale-W756ACKC.js.map → stale-IGFUKEN2.js.map} +1 -1
  291. package/dist/{status-SE2VZJJB.js → status-7F2KHFGA.js} +3 -4
  292. package/dist/{status-SE2VZJJB.js.map → status-7F2KHFGA.js.map} +1 -1
  293. package/dist/{stock-KXJ26BY4.js → stock-2YCDN3N6.js} +5 -5
  294. package/dist/{studio-SYKOSNDB.js → studio-RA7QQH4O.js} +1 -1
  295. package/dist/{sync-LJGSODK3.js → sync-GWTLKZTU.js} +2 -3
  296. package/dist/{sync-LJGSODK3.js.map → sync-GWTLKZTU.js.map} +1 -1
  297. package/dist/{sync-definition-QR2N233R.js → sync-definition-UGSDX2SZ.js} +11 -12
  298. package/dist/{tags-PYWFSBTR.js → tags-3WPW6PTV.js} +4 -4
  299. package/dist/{tags-QQU3OKMZ.js → tags-6342FQEB.js} +3 -4
  300. package/dist/{tags-QQU3OKMZ.js.map → tags-6342FQEB.js.map} +1 -1
  301. package/dist/{tags-5SBMRC2A.js → tags-ABHSX6M5.js} +3 -4
  302. package/dist/{tags-5SBMRC2A.js.map → tags-ABHSX6M5.js.map} +1 -1
  303. package/dist/{tags-YYLNF3PK.js → tags-FJIBBBRG.js} +3 -4
  304. package/dist/{tags-YYLNF3PK.js.map → tags-FJIBBBRG.js.map} +1 -1
  305. package/dist/{tags-4BAVFH4S.js → tags-KFYLZLB3.js} +2 -3
  306. package/dist/{tags-4BAVFH4S.js.map → tags-KFYLZLB3.js.map} +1 -1
  307. package/dist/{targeting-criteria-RJFLFICN.js → targeting-criteria-NR47AF5C.js} +3 -3
  308. package/dist/{targets-S2MT2PNB.js → targets-L56KOVQE.js} +3 -4
  309. package/dist/{targets-S2MT2PNB.js.map → targets-L56KOVQE.js.map} +1 -1
  310. package/dist/{templates-ZE5TOGRT.js → templates-B6XGDYUF.js} +3 -4
  311. package/dist/{templates-ZE5TOGRT.js.map → templates-B6XGDYUF.js.map} +1 -1
  312. package/dist/{testimonials-DII5DYLR.js → testimonials-CVC4YIXO.js} +6 -6
  313. package/dist/{top-companies-PGIAEHDF.js → top-companies-45X3DT7Z.js} +3 -4
  314. package/dist/{top-companies-PGIAEHDF.js.map → top-companies-45X3DT7Z.js.map} +1 -1
  315. package/dist/{translate-GXTS633J.js → translate-VP5R67PL.js} +11 -12
  316. package/dist/{translate-GXTS633J.js.map → translate-VP5R67PL.js.map} +1 -1
  317. package/dist/{triggers-2PTONXRU.js → triggers-22EMIVFD.js} +3 -4
  318. package/dist/{triggers-2PTONXRU.js.map → triggers-22EMIVFD.js.map} +1 -1
  319. package/dist/{unlink-XRMYJ6DB.js → unlink-65KUN6ID.js} +3 -4
  320. package/dist/{unlink-XRMYJ6DB.js.map → unlink-65KUN6ID.js.map} +1 -1
  321. package/dist/{unstage-FY7A3YFF.js → unstage-2E3I5SWF.js} +3 -4
  322. package/dist/{unstage-FY7A3YFF.js.map → unstage-2E3I5SWF.js.map} +1 -1
  323. package/dist/{unstage-RM2RLXKD.js → unstage-4ZEULXEQ.js} +4 -5
  324. package/dist/{unstage-RM2RLXKD.js.map → unstage-4ZEULXEQ.js.map} +1 -1
  325. package/dist/{update-S4562V3O.js → update-2S7CSEAW.js} +3 -4
  326. package/dist/{update-S4562V3O.js.map → update-2S7CSEAW.js.map} +1 -1
  327. package/dist/{update-V6YVEUI2.js → update-7NCOTAQZ.js} +3 -4
  328. package/dist/{update-V6YVEUI2.js.map → update-7NCOTAQZ.js.map} +1 -1
  329. package/dist/{update-PJ67D2OG.js → update-D6DJC6T7.js} +2 -3
  330. package/dist/{update-PJ67D2OG.js.map → update-D6DJC6T7.js.map} +1 -1
  331. package/dist/{update-E5SRBXQR.js → update-KREBPGBH.js} +3 -4
  332. package/dist/{update-E5SRBXQR.js.map → update-KREBPGBH.js.map} +1 -1
  333. package/dist/{upload-R6CQVLKF.js → upload-O6NHRPS7.js} +3 -4
  334. package/dist/{upload-R6CQVLKF.js.map → upload-O6NHRPS7.js.map} +1 -1
  335. package/dist/{url-options-JOKU46F2.js → url-options-GGXAL3J4.js} +3 -4
  336. package/dist/{url-options-JOKU46F2.js.map → url-options-GGXAL3J4.js.map} +1 -1
  337. package/dist/{url-params-7U2XMOWF.js → url-params-3EFGVTZZ.js} +3 -4
  338. package/dist/{url-params-7U2XMOWF.js.map → url-params-3EFGVTZZ.js.map} +1 -1
  339. package/dist/{validate-7YPOUKPB.js → validate-CSJM7XZM.js} +9 -10
  340. package/dist/{validate-7YPOUKPB.js.map → validate-CSJM7XZM.js.map} +1 -1
  341. package/dist/{videos-LICG6ACJ.js → videos-YSXYGTBM.js} +5 -5
  342. package/dist/{web-BA2PGTWU.js → web-IGIGVEKS.js} +3 -4
  343. package/dist/{web-BA2PGTWU.js.map → web-IGIGVEKS.js.map} +1 -1
  344. package/dist/{winning-ads-C6S2C5VP.js → winning-ads-2WS7FI4E.js} +2 -2
  345. package/dist/{write-commands-7SJ3BOW5.js → write-commands-5C7FUOVN.js} +4 -5
  346. package/dist/{write-commands-7SJ3BOW5.js.map → write-commands-5C7FUOVN.js.map} +1 -1
  347. package/dist/{x-CZHRC6U7.js → x-BFSKFCZD.js} +6 -6
  348. package/package.json +1 -1
  349. package/dist/add-2BEGRHUX.js.map +0 -1
  350. package/dist/analytics-IFELDWLL.js.map +0 -1
  351. package/dist/chunk-4PDHHHUJ.js +0 -537
  352. package/dist/chunk-4PDHHHUJ.js.map +0 -1
  353. package/dist/chunk-7EPXVICM.js.map +0 -1
  354. package/dist/chunk-ASI4P6X2.js.map +0 -1
  355. package/dist/chunk-FPOGPFAG.js.map +0 -1
  356. package/dist/chunk-HR6IWNKE.js.map +0 -1
  357. package/dist/chunk-HROZYQ5H.js.map +0 -1
  358. package/dist/chunk-NYIGXDUG.js.map +0 -1
  359. package/dist/chunk-QE7W555R.js.map +0 -1
  360. package/dist/flows-KTFAML22.js.map +0 -1
  361. package/dist/funnel-I6XIAEHG.js.map +0 -1
  362. package/dist/get-5PKNKJ5S.js.map +0 -1
  363. package/dist/plan-FT632COT.js +0 -51
  364. package/dist/plan-FT632COT.js.map +0 -1
  365. package/dist/questionnaire-JNGYJTAY.js +0 -37
  366. package/dist/questionnaire-JNGYJTAY.js.map +0 -1
  367. package/dist/scaffold-static-ad-ECTJL54Y.js.map +0 -1
  368. /package/dist/{actions-6TQMSVWD.js.map → actions-P35MEMGN.js.map} +0 -0
  369. /package/dist/{ads-AGYCVD62.js.map → ads-73PGA4YC.js.map} +0 -0
  370. /package/dist/{avatars-467OSBD6.js.map → avatars-EKCKHCC3.js.map} +0 -0
  371. /package/dist/{brand-YRTEPGBK.js.map → brand-C6PFGGQN.js.map} +0 -0
  372. /package/dist/{campaigns-OYMXDGWX.js.map → campaigns-KZYZTXDS.js.map} +0 -0
  373. /package/dist/{canvas-YQFG52IG.js.map → canvas-5NB27FX2.js.map} +0 -0
  374. /package/dist/{catalog-XLXIM7IW.js.map → catalog-VSSY6FGI.js.map} +0 -0
  375. /package/dist/{chunk-5ZNTADVR.js.map → chunk-3G3ZDLMI.js.map} +0 -0
  376. /package/dist/{chunk-ZDMTXQ2Q.js.map → chunk-3IBYKLXR.js.map} +0 -0
  377. /package/dist/{chunk-CWYAELVG.js.map → chunk-464O4MT2.js.map} +0 -0
  378. /package/dist/{chunk-NA63BH7V.js.map → chunk-4AUMTNVB.js.map} +0 -0
  379. /package/dist/{chunk-NDEE6G2J.js.map → chunk-4BQXAE7Z.js.map} +0 -0
  380. /package/dist/{chunk-2AOE2MZQ.js.map → chunk-5ZDLTE5T.js.map} +0 -0
  381. /package/dist/{chunk-ULG4QRTV.js.map → chunk-6NB47MRW.js.map} +0 -0
  382. /package/dist/{chunk-24EB7EDR.js.map → chunk-7YCRFMXF.js.map} +0 -0
  383. /package/dist/{chunk-WGUQHAJY.js.map → chunk-A4LOJ2VD.js.map} +0 -0
  384. /package/dist/{chunk-6F7DVPOS.js.map → chunk-AEOSAVVL.js.map} +0 -0
  385. /package/dist/{chunk-N4LAYIIN.js.map → chunk-CSYSX4D2.js.map} +0 -0
  386. /package/dist/{chunk-RX2DKU3W.js.map → chunk-DGUNI37S.js.map} +0 -0
  387. /package/dist/{chunk-I3ZR655O.js.map → chunk-IR6D7K4H.js.map} +0 -0
  388. /package/dist/{chunk-FUHN4MFY.js.map → chunk-JQJDXPCO.js.map} +0 -0
  389. /package/dist/{chunk-7CTMH5AK.js.map → chunk-KAUOHQTF.js.map} +0 -0
  390. /package/dist/{chunk-VYQ3QJ3C.js.map → chunk-KHRXPQID.js.map} +0 -0
  391. /package/dist/{chunk-6Y7ZBENQ.js.map → chunk-LECGCWT5.js.map} +0 -0
  392. /package/dist/{chunk-5WCSKQ7Z.js.map → chunk-LZ73CZGP.js.map} +0 -0
  393. /package/dist/{chunk-R25YLW6H.js.map → chunk-MELOSESI.js.map} +0 -0
  394. /package/dist/{chunk-DCRPXOJJ.js.map → chunk-MXYBTMKB.js.map} +0 -0
  395. /package/dist/{chunk-54C6YDGJ.js.map → chunk-NPY4QUMQ.js.map} +0 -0
  396. /package/dist/{chunk-LYQJ4PZW.js.map → chunk-OQ6663F4.js.map} +0 -0
  397. /package/dist/{chunk-H3427GPU.js.map → chunk-OZRUJVIQ.js.map} +0 -0
  398. /package/dist/{chunk-KMKEYI37.js.map → chunk-Q2V6E6SL.js.map} +0 -0
  399. /package/dist/{chunk-VL43TNIP.js.map → chunk-QRP3PXWN.js.map} +0 -0
  400. /package/dist/{chunk-C46GUI2S.js.map → chunk-RZBEK2VE.js.map} +0 -0
  401. /package/dist/{chunk-2VPBIT65.js.map → chunk-S3A3YOKO.js.map} +0 -0
  402. /package/dist/{chunk-FYGR3I2A.js.map → chunk-S77PZVYM.js.map} +0 -0
  403. /package/dist/{chunk-VLMBTPXU.js.map → chunk-SHL7LOC3.js.map} +0 -0
  404. /package/dist/{chunk-KS2QY6MK.js.map → chunk-W3ZHJJVT.js.map} +0 -0
  405. /package/dist/{chunk-RL5CP7N6.js.map → chunk-Y6O7EWYY.js.map} +0 -0
  406. /package/dist/{chunk-6NY2GPR4.js.map → chunk-Y6ZQXUZ7.js.map} +0 -0
  407. /package/dist/{chunk-WKQG6TER.js.map → chunk-ZEYEWPK6.js.map} +0 -0
  408. /package/dist/{connect-FCXNVTXG.js.map → connect-QCOGEPP4.js.map} +0 -0
  409. /package/dist/{creatives-FXUQ5WSD.js.map → creatives-B5NTXPUB.js.map} +0 -0
  410. /package/dist/{customers-XH2DMTFH.js.map → customers-A36LOZOB.js.map} +0 -0
  411. /package/dist/{feedback-EIZKS4JU.js.map → feedback-OLTCHE6C.js.map} +0 -0
  412. /package/dist/{find-FRRHAPWX.js.map → find-OTDIX6V4.js.map} +0 -0
  413. /package/dist/{fonts-MXR3ZKDX.js.map → fonts-EMMX3KII.js.map} +0 -0
  414. /package/dist/{ga4-DV2AXCSL.js.map → ga4-UDQ2HA2J.js.map} +0 -0
  415. /package/dist/{google-QYYYSSXI.js.map → google-KTO3PLEU.js.map} +0 -0
  416. /package/dist/{google-6OGZX47I.js.map → google-M7KEXVK5.js.map} +0 -0
  417. /package/dist/{gsc-TAKOF7J5.js.map → gsc-P3QYGDV2.js.map} +0 -0
  418. /package/dist/{icon-L4RSS6PZ.js.map → icon-I43F77FV.js.map} +0 -0
  419. /package/dist/{ideas-NFOW3HKJ.js.map → ideas-MIDU7YOA.js.map} +0 -0
  420. /package/dist/{images-2EFFUNNV.js.map → images-S254MS6O.js.map} +0 -0
  421. /package/dist/{ingest-2EIKN4QC.js.map → ingest-YV2NLDBE.js.map} +0 -0
  422. /package/dist/{inspiration-S3DU4CMQ.js.map → inspiration-P265QJ2H.js.map} +0 -0
  423. /package/dist/{landing-2ZB46LXH.js.map → landing-CJYGWCK4.js.map} +0 -0
  424. /package/dist/{line-items-5NECXUZT.js.map → line-items-7ZGIKEF2.js.map} +0 -0
  425. /package/dist/{logo-Q5D7PZY6.js.map → logo-2IP663QO.js.map} +0 -0
  426. /package/dist/{lookup-ETWY47F7.js.map → lookup-XK45W2SH.js.map} +0 -0
  427. /package/dist/{media-sources-ZXHEEP6T.js.map → media-sources-O6ZRUA3N.js.map} +0 -0
  428. /package/dist/{performance-UF5VTY2U.js.map → performance-6QW2KEEQ.js.map} +0 -0
  429. /package/dist/{promoted-tweets-LZKS5JIF.js.map → promoted-tweets-SURKMHFI.js.map} +0 -0
  430. /package/dist/{reddit-NU2N3LZD.js.map → reddit-GIP3ADMS.js.map} +0 -0
  431. /package/dist/{research-FMM6AWZC.js.map → research-2BLEISBG.js.map} +0 -0
  432. /package/dist/{run-EUO34T2J.js.map → run-MMEDKJDB.js.map} +0 -0
  433. /package/dist/{scheduled-agents-N4LJRM4C.js.map → scheduled-agents-6U44QE76.js.map} +0 -0
  434. /package/dist/{sources-FQ2UZTHL.js.map → sources-YBQ6KPFM.js.map} +0 -0
  435. /package/dist/{stock-KXJ26BY4.js.map → stock-2YCDN3N6.js.map} +0 -0
  436. /package/dist/{studio-SYKOSNDB.js.map → studio-RA7QQH4O.js.map} +0 -0
  437. /package/dist/{sync-definition-QR2N233R.js.map → sync-definition-UGSDX2SZ.js.map} +0 -0
  438. /package/dist/{tags-PYWFSBTR.js.map → tags-3WPW6PTV.js.map} +0 -0
  439. /package/dist/{targeting-criteria-RJFLFICN.js.map → targeting-criteria-NR47AF5C.js.map} +0 -0
  440. /package/dist/{testimonials-DII5DYLR.js.map → testimonials-CVC4YIXO.js.map} +0 -0
  441. /package/dist/{videos-LICG6ACJ.js.map → videos-YSXYGTBM.js.map} +0 -0
  442. /package/dist/{winning-ads-C6S2C5VP.js.map → winning-ads-2WS7FI4E.js.map} +0 -0
  443. /package/dist/{x-CZHRC6U7.js.map → x-BFSKFCZD.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/research/keyword-metrics.ts","../src/commands/research/keyword-metrics-rows.ts"],"sourcesContent":["import { RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS, type ResearchKeywordMetricsRow } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { buildResearchQueryContext, warnDefaults } from \"../../geo-context.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { keywordMetricsHints } from \"./hints.ts\";\nimport { keywordMetricsFields, toOutputRow } from \"./keyword-metrics-rows.ts\";\nimport {\n handleResearchError,\n RESEARCH_DATA_NOTE,\n writeResearchHints,\n writeResearchJson,\n writeResearchOutput,\n} from \"./output.ts\";\n\nregisterSchema({\n command: \"research.keyword-metrics\",\n description:\n \"Search volume, CPC, top-of-page bids and competition for a list of keywords you name — no domain needed. This is the command for sizing a market you have keywords for; the domain-bound ones (keywords-for-site, keyword-gap) answer a different question and should not be used as a workaround for this one. The volume is Google's Keyword Planner figure resold by DataForSEO, so it is not a second opinion on `baker ads google keywords metrics` — for that, pass --clickstream. If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.\",\n args: {\n keywords: {\n type: \"string\",\n description: `Comma-separated keywords (max ${RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS}, 80 chars each)`,\n required: true,\n },\n location: {\n type: \"string\",\n description:\n \"Country code (us, mx, br, es...) or DataForSEO location code. Defaults to us (United States) if omitted — always set this for non-US markets\",\n required: false,\n },\n language: {\n type: \"string\",\n description:\n \"Language code or name. Defaults to en (English) if omitted — always set this for non-English markets\",\n required: false,\n },\n clickstream: {\n type: \"boolean\",\n description:\n \"Also return DataForSEO's own panel-derived volume (clickstream_search_volume), the only genuinely independent estimate of demand available here. Costs 2x.\",\n required: false,\n },\n full: {\n type: \"boolean\",\n description: \"Add keyword difficulty, search intent and the 12-month volume trend to each row\",\n required: false,\n },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n});\n\nexport const keywordMetricsCommand = defineCommand({\n meta: {\n name: \"keyword-metrics\",\n description: `Volume, CPC and competition for keywords you name. No domain required.\n\nNumbers are Keyword Planner ESTIMATES of total market volume, resold by DataForSEO — every column carrying one is named planner_. Pass --clickstream for DataForSEO's own independent estimate alongside.\n\nExamples:\n baker research keyword-metrics \"chatbot whatsapp,agente whatsapp ecommerce\" --location mx --language es\n baker research keyword-metrics \"chatbot whatsapp\" --location br --language pt --clickstream\n baker research keyword-metrics \"crm software,best crm\" --full --output md`,\n },\n args: {\n keywords: { type: \"positional\", description: \"Comma-separated keywords\", required: true },\n location: { type: \"string\", description: \"Country code or location code (default: us)\", required: false },\n language: { type: \"string\", description: \"Language code or name (default: en)\", required: false },\n clickstream: { type: \"boolean\", description: \"Add DataForSEO's own volume estimate (costs 2x)\", required: false },\n full: { type: \"boolean\", description: \"Add difficulty, intent and the 12-month trend\", required: false },\n output: { type: \"string\", description: \"Format: json|csv|md|jsonl\", required: false, default: \"json\" },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n run: async ({ args }) => {\n const keywords = (args.keywords as string)\n .split(\",\")\n .map((k) => k.trim())\n .filter(Boolean);\n\n if (keywords.length === 0) {\n writeResearchJson({\n ok: false,\n error: { code: \"VALIDATION_ERROR\", message: \"Provide at least one keyword\" },\n });\n process.exit(1);\n }\n if (keywords.length > RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS) {\n writeResearchJson({\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Maximum ${RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS} keywords per request`,\n fix: {\n action: \"retry_with_changes\",\n explanation: `You sent ${keywords.length}. Split the list into batches of ${RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS} and run the command once per batch — each batch is a separate charge, so batch by priority.`,\n },\n },\n });\n process.exit(1);\n }\n\n const location = (args.location as string) || undefined;\n const language = (args.language as string) || undefined;\n const clickstream = Boolean(args.clickstream);\n const full = Boolean(args.full);\n const queryContext = buildResearchQueryContext(location, language);\n\n try {\n const result = await apiPost<{ data: ResearchKeywordMetricsRow[] }>(\"/api/research/keyword-metrics\", {\n keywords,\n location,\n language,\n includeClickstream: clickstream,\n skipCache: args[\"no-cache\"] ? true : undefined,\n });\n\n const columns = { clickstream, full };\n const rows = result.data.map((row) => toOutputRow(row, columns));\n const hints = keywordMetricsHints({ rows: result.data, asked: keywords, clickstream, queryContext });\n\n warnDefaults(queryContext);\n const format = (args.output as string) || \"json\";\n if (format !== \"json\") {\n writeResearchOutput(rows, format);\n writeResearchHints([...hints, RESEARCH_DATA_NOTE], format);\n return;\n }\n writeResearchJson({\n ok: true,\n data: rows,\n fields: keywordMetricsFields(columns),\n note: RESEARCH_DATA_NOTE,\n hints,\n query_context: queryContext,\n });\n } catch (err) {\n handleResearchError(err);\n }\n },\n});\n","/**\n * Naming the rows of `baker research keyword-metrics` after where each number\n * came from.\n *\n * DataForSEO does not measure Google's search volume — it resells the Keyword\n * Planner figure, so `search_volume` here and `planner_avg_monthly_searches`\n * from `baker ads google keywords metrics` are one number with two names. A run\n * that did not know that presented the two side by side as agreeing sources and\n * reported the agreement as validation; they matched to the digit in all seven\n * rows because they are the same row. The only defence that survives a CSV in\n * /tmp is the column name, which is the same conclusion `ads/google/keywords/\n * provenance.ts` reached for the other half of the pair — so the same prefix is\n * used deliberately.\n *\n * The exception is clickstream: `clickstream_search_volume` is DataForSEO's own\n * panel-derived estimate and genuinely is a second opinion. It keeps its own\n * prefix so it can never be read as Google's, or Google's as it.\n */\nimport type { ResearchKeywordMetricsRow } from \"@baker/api\";\n\nexport const KEYWORD_METRICS_SOURCE = \"keyword_planner_estimate_via_dataforseo\";\n\nexport type KeywordMetricsOutputRow = Record<string, unknown>;\n\nexport interface KeywordMetricsColumnOptions {\n /** The request asked for DataForSEO's panel volume alongside Google's. */\n clickstream: boolean;\n /** Add difficulty, intent and the 12-month trend. */\n full: boolean;\n}\n\nexport function toOutputRow(\n row: ResearchKeywordMetricsRow,\n options: KeywordMetricsColumnOptions,\n): KeywordMetricsOutputRow {\n const out: KeywordMetricsOutputRow = {\n source: KEYWORD_METRICS_SOURCE,\n keyword: row.keyword,\n planner_search_volume: row.search_volume,\n planner_cpc: row.cpc,\n planner_low_top_of_page_bid: row.low_top_of_page_bid,\n planner_high_top_of_page_bid: row.high_top_of_page_bid,\n planner_competition: row.competition,\n planner_competition_index: row.competition_index,\n };\n if (options.clickstream) {\n out.clickstream_search_volume = row.clickstream_search_volume;\n }\n if (options.full) {\n out.keyword_difficulty = row.keyword_difficulty;\n out.main_intent = row.main_intent;\n out.planner_monthly_searches = row.monthly_searches;\n }\n return out;\n}\n\nexport function keywordMetricsFields(options: KeywordMetricsColumnOptions): Record<string, string> {\n const fields: Record<string, string> = {\n source: `Always \"${KEYWORD_METRICS_SOURCE}\". Every planner_ column below is Google's Keyword Planner ESTIMATE of total market volume, resold by DataForSEO — the same number \\`baker ads google keywords metrics\\` returns, not an independent measurement of it. Columns without the planner_ prefix are DataForSEO's own.`,\n keyword:\n \"The keyword asked for. A row with every metric null means DataForSEO holds no data on it — not that nobody searches it.\",\n planner_search_volume: \"ESTIMATE: average monthly searches across the whole market, last 12 months\",\n planner_cpc: \"ESTIMATE: average cost per click in USD (a single blended figure, not a top-of-page range)\",\n planner_low_top_of_page_bid: \"ESTIMATE: low-range top-of-page bid in USD\",\n planner_high_top_of_page_bid: \"ESTIMATE: high-range top-of-page bid in USD\",\n planner_competition: \"ESTIMATE: competition level — LOW, MEDIUM or HIGH\",\n planner_competition_index: \"ESTIMATE: competition index 0-100 (higher = more advertisers)\",\n };\n if (options.clickstream) {\n fields.clickstream_search_volume =\n \"DataForSEO's OWN volume estimate, from clickstream panels — not Google's, and the only number here that is a genuine second opinion on demand. Expect it to differ from planner_search_volume; that is the point.\";\n }\n if (options.full) {\n fields.keyword_difficulty = \"DataForSEO's 0-100 estimate of how hard ranking in the organic top 10 would be\";\n fields.main_intent = \"DataForSEO's intent classification: informational, navigational, commercial or transactional\";\n fields.planner_monthly_searches = \"ESTIMATE: 12-month volume breakdown ({year, month, search_volume})\";\n }\n return fields;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/commands/research/keyword-metrics.ts","../src/commands/research/keyword-metrics-rows.ts"],"sourcesContent":["import { RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS, type ResearchKeywordMetricsRow } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { buildResearchQueryContext, warnDefaults } from \"../../geo-context.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { keywordMetricsHints } from \"./hints.ts\";\nimport { keywordMetricsFields, toOutputRow } from \"./keyword-metrics-rows.ts\";\nimport {\n handleResearchError,\n RESEARCH_DATA_NOTE,\n writeResearchHints,\n writeResearchJson,\n writeResearchOutput,\n} from \"./output.ts\";\n\nregisterSchema({\n command: \"research.keyword-metrics\",\n description:\n \"Search volume, CPC, top-of-page bids and competition for a list of keywords you name — no domain needed. This is the command for sizing a market you have keywords for; the domain-bound ones (keywords-for-site, keyword-gap) answer a different question and should not be used as a workaround for this one. The volume is Google's Keyword Planner figure resold by DataForSEO, so it is not a second opinion on `baker ads google keywords metrics` — for that, pass --clickstream. If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.\",\n args: {\n keywords: {\n type: \"string\",\n description: `Comma-separated keywords (max ${RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS}, 80 chars each)`,\n required: true,\n },\n location: {\n type: \"string\",\n description:\n \"Country code (us, mx, br, es...) or DataForSEO location code. Defaults to us (United States) if omitted — always set this for non-US markets\",\n required: false,\n },\n language: {\n type: \"string\",\n description:\n \"Language code or name. Defaults to en (English) if omitted — always set this for non-English markets\",\n required: false,\n },\n clickstream: {\n type: \"boolean\",\n description:\n \"Also return DataForSEO's own panel-derived volume (clickstream_search_volume), the only genuinely independent estimate of demand available here. Costs 2x.\",\n required: false,\n },\n full: {\n type: \"boolean\",\n description: \"Add keyword difficulty, search intent and the 12-month volume trend to each row\",\n required: false,\n },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n});\n\nexport const keywordMetricsCommand = defineCommand({\n meta: {\n name: \"keyword-metrics\",\n description: `Volume, CPC and competition for keywords you name. No domain required.\n\nNumbers are Keyword Planner ESTIMATES of total market volume, resold by DataForSEO — every column carrying one is named planner_. Pass --clickstream for DataForSEO's own independent estimate alongside.\n\nExamples:\n baker research keyword-metrics \"chatbot whatsapp,agente whatsapp ecommerce\" --location mx --language es\n baker research keyword-metrics \"chatbot whatsapp\" --location br --language pt --clickstream\n baker research keyword-metrics \"crm software,best crm\" --full --output md`,\n },\n args: {\n keywords: { type: \"positional\", description: \"Comma-separated keywords\", required: true },\n location: { type: \"string\", description: \"Country code or location code (default: us)\", required: false },\n language: { type: \"string\", description: \"Language code or name (default: en)\", required: false },\n clickstream: { type: \"boolean\", description: \"Add DataForSEO's own volume estimate (costs 2x)\", required: false },\n full: { type: \"boolean\", description: \"Add difficulty, intent and the 12-month trend\", required: false },\n output: { type: \"string\", description: \"Format: json|csv|md|jsonl\", required: false, default: \"json\" },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n run: async ({ args }) => {\n const keywords = (args.keywords as string)\n .split(\",\")\n .map((k) => k.trim())\n .filter(Boolean);\n\n if (keywords.length === 0) {\n writeResearchJson({\n ok: false,\n error: { code: \"VALIDATION_ERROR\", message: \"Provide at least one keyword\" },\n });\n process.exit(1);\n }\n if (keywords.length > RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS) {\n writeResearchJson({\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Maximum ${RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS} keywords per request`,\n fix: {\n action: \"retry_with_changes\",\n explanation: `You sent ${keywords.length}. Split the list into batches of ${RESEARCH_KEYWORD_METRICS_MAX_KEYWORDS} and run the command once per batch — each batch is a separate charge, so batch by priority.`,\n },\n },\n });\n process.exit(1);\n }\n\n const location = (args.location as string) || undefined;\n const language = (args.language as string) || undefined;\n const clickstream = Boolean(args.clickstream);\n const full = Boolean(args.full);\n const queryContext = buildResearchQueryContext(location, language);\n\n try {\n const result = await apiPost<{ data: ResearchKeywordMetricsRow[] }>(\"/api/research/keyword-metrics\", {\n keywords,\n location,\n language,\n includeClickstream: clickstream,\n skipCache: args[\"no-cache\"] ? true : undefined,\n });\n\n const columns = { clickstream, full };\n const rows = result.data.map((row) => toOutputRow(row, columns));\n const hints = keywordMetricsHints({ rows: result.data, asked: keywords, clickstream, queryContext });\n\n warnDefaults(queryContext);\n const format = (args.output as string) || \"json\";\n if (format !== \"json\") {\n writeResearchOutput(rows, format);\n writeResearchHints([...hints, RESEARCH_DATA_NOTE], format);\n return;\n }\n writeResearchJson({\n ok: true,\n data: rows,\n fields: keywordMetricsFields(columns),\n note: RESEARCH_DATA_NOTE,\n hints,\n query_context: queryContext,\n });\n } catch (err) {\n handleResearchError(err);\n }\n },\n});\n","/**\n * Naming the rows of `baker research keyword-metrics` after where each number\n * came from.\n *\n * DataForSEO does not measure Google's search volume — it resells the Keyword\n * Planner figure, so `search_volume` here and `planner_avg_monthly_searches`\n * from `baker ads google keywords metrics` are one number with two names. A run\n * that did not know that presented the two side by side as agreeing sources and\n * reported the agreement as validation; they matched to the digit in all seven\n * rows because they are the same row. The only defence that survives a CSV in\n * /tmp is the column name, which is the same conclusion `ads/google/keywords/\n * provenance.ts` reached for the other half of the pair — so the same prefix is\n * used deliberately.\n *\n * The exception is clickstream: `clickstream_search_volume` is DataForSEO's own\n * panel-derived estimate and genuinely is a second opinion. It keeps its own\n * prefix so it can never be read as Google's, or Google's as it.\n */\nimport type { ResearchKeywordMetricsRow } from \"@baker/api\";\n\nexport const KEYWORD_METRICS_SOURCE = \"keyword_planner_estimate_via_dataforseo\";\n\nexport type KeywordMetricsOutputRow = Record<string, unknown>;\n\nexport interface KeywordMetricsColumnOptions {\n /** The request asked for DataForSEO's panel volume alongside Google's. */\n clickstream: boolean;\n /** Add difficulty, intent and the 12-month trend. */\n full: boolean;\n}\n\nexport function toOutputRow(\n row: ResearchKeywordMetricsRow,\n options: KeywordMetricsColumnOptions,\n): KeywordMetricsOutputRow {\n const out: KeywordMetricsOutputRow = {\n source: KEYWORD_METRICS_SOURCE,\n keyword: row.keyword,\n planner_search_volume: row.search_volume,\n planner_cpc: row.cpc,\n planner_low_top_of_page_bid: row.low_top_of_page_bid,\n planner_high_top_of_page_bid: row.high_top_of_page_bid,\n planner_competition: row.competition,\n planner_competition_index: row.competition_index,\n };\n if (options.clickstream) {\n out.clickstream_search_volume = row.clickstream_search_volume;\n }\n if (options.full) {\n out.keyword_difficulty = row.keyword_difficulty;\n out.main_intent = row.main_intent;\n out.planner_monthly_searches = row.monthly_searches;\n }\n return out;\n}\n\nexport function keywordMetricsFields(options: KeywordMetricsColumnOptions): Record<string, string> {\n const fields: Record<string, string> = {\n source: `Always \"${KEYWORD_METRICS_SOURCE}\". Every planner_ column below is Google's Keyword Planner ESTIMATE of total market volume, resold by DataForSEO — the same number \\`baker ads google keywords metrics\\` returns, not an independent measurement of it. Columns without the planner_ prefix are DataForSEO's own.`,\n keyword:\n \"The keyword asked for. A row with every metric null means DataForSEO holds no data on it — not that nobody searches it.\",\n planner_search_volume: \"ESTIMATE: average monthly searches across the whole market, last 12 months\",\n planner_cpc: \"ESTIMATE: average cost per click in USD (a single blended figure, not a top-of-page range)\",\n planner_low_top_of_page_bid: \"ESTIMATE: low-range top-of-page bid in USD\",\n planner_high_top_of_page_bid: \"ESTIMATE: high-range top-of-page bid in USD\",\n planner_competition: \"ESTIMATE: competition level — LOW, MEDIUM or HIGH\",\n planner_competition_index: \"ESTIMATE: competition index 0-100 (higher = more advertisers)\",\n };\n if (options.clickstream) {\n fields.clickstream_search_volume =\n \"DataForSEO's OWN volume estimate, from clickstream panels — not Google's, and the only number here that is a genuine second opinion on demand. Expect it to differ from planner_search_volume; that is the point.\";\n }\n if (options.full) {\n fields.keyword_difficulty = \"DataForSEO's 0-100 estimate of how hard ranking in the organic top 10 would be\";\n fields.main_intent = \"DataForSEO's intent classification: informational, navigational, commercial or transactional\";\n fields.planner_monthly_searches = \"ESTIMATE: 12-month volume breakdown ({year, month, search_volume})\";\n }\n return fields;\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  keywordsForSiteHints
3
- } from "./chunk-H3427GPU.js";
3
+ } from "./chunk-OZRUJVIQ.js";
4
4
  import {
5
5
  RESEARCH_DATA_NOTE,
6
6
  handleResearchError,
@@ -13,11 +13,10 @@ import {
13
13
  warnDefaults
14
14
  } from "./chunk-LIQ4SQ2T.js";
15
15
  import "./chunk-XCM6XWOB.js";
16
- import "./chunk-7EPXVICM.js";
16
+ import "./chunk-XF4JUKVF.js";
17
17
  import "./chunk-GXDLWBOY.js";
18
18
  import "./chunk-TEINLN64.js";
19
19
  import "./chunk-ZJWUBJYQ.js";
20
- import "./chunk-HR6IWNKE.js";
21
20
  import "./chunk-NE4F3FHN.js";
22
21
  import {
23
22
  apiPost
@@ -126,4 +125,4 @@ Examples:
126
125
  export {
127
126
  keywordsForSiteCommand
128
127
  };
129
- //# sourceMappingURL=keywords-for-site-WDAOPNKC.js.map
128
+ //# sourceMappingURL=keywords-for-site-GALSCV77.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/research/keywords-for-site.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { buildResearchQueryContext, warnDefaults } from \"../../geo-context.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { keywordsForSiteHints } from \"./hints.ts\";\nimport {\n handleResearchError,\n RESEARCH_DATA_NOTE,\n writeResearchHints,\n writeResearchJson,\n writeResearchOutput,\n} from \"./output.ts\";\n\nregisterSchema({\n command: \"research.keywords-for-site\",\n description:\n \"Get keywords a competitor targets in Google. Use --type paid to see only paid keywords, --type organic for organic only. If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.\",\n args: {\n target: { type: \"string\", description: \"Domain or URL to analyze (positional)\", required: true },\n location: {\n type: \"string\",\n description:\n \"Country code (us, uk, es, de...) or DataForSEO location code. Defaults to us (United States) if omitted — always set this for non-US markets\",\n required: false,\n },\n language: {\n type: \"string\",\n description:\n \"Language code or name. Defaults to en (English) if omitted — always set this for non-English markets\",\n required: false,\n },\n sort: {\n type: \"string\",\n description: \"Sort: search_volume, competition, cpc (default: search_volume)\",\n required: false,\n },\n type: { type: \"string\", description: \"Filter: paid, organic, all (default: all)\", required: false },\n limit: { type: \"string\", description: \"Max results (default: 50, max: 1000)\", required: false },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n});\n\ninterface KeywordForSite {\n keyword: string;\n search_volume: number;\n cpc: number;\n competition: string;\n competition_index: number;\n}\n\nconst FIELDS: Record<string, string> = {\n keyword: \"Keyword the site targets\",\n search_volume: \"Monthly search volume\",\n cpc: \"Cost per click in USD\",\n competition: \"LOW, MEDIUM, or HIGH\",\n competition_index: \"Competition score 0-100\",\n};\n\nexport const keywordsForSiteCommand = defineCommand({\n meta: {\n name: \"keywords-for-site\",\n description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.\n\nExamples:\n baker research keywords-for-site \"competitor.com\"\n baker research keywords-for-site \"competitor.com\" --type paid --limit 20\n baker research keywords-for-site \"competitor.com\" --type organic --location uk`,\n },\n args: {\n target: { type: \"positional\", description: \"Domain or URL to analyze\", required: true },\n location: { type: \"string\", description: \"Country code or location code (default: us)\", required: false },\n language: { type: \"string\", description: \"Language code or name (default: en)\", required: false },\n sort: { type: \"string\", description: \"Sort: search_volume, competition, cpc\", required: false },\n type: { type: \"string\", description: \"Filter: paid, organic, all (default: all)\", required: false },\n limit: { type: \"string\", description: \"Max results (default: 50, max: 1000)\", required: false },\n output: { type: \"string\", description: \"Format: json|csv|md|jsonl\", required: false, default: \"json\" },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n run: async ({ args }) => {\n const target = args.target as string;\n const location = (args.location as string) || undefined;\n const language = (args.language as string) || undefined;\n const sort = (args.sort as string) || undefined;\n const type = (args.type as string) || undefined;\n const limit = args.limit ? Number(args.limit) : undefined;\n const skipCache = args[\"no-cache\"] ? true : undefined;\n const queryContext = buildResearchQueryContext(location, language);\n\n try {\n const data = await apiPost<KeywordForSite[]>(\"/api/research/keywords-for-site\", {\n target,\n location,\n language,\n sort,\n type,\n limit,\n skipCache,\n });\n\n warnDefaults(queryContext);\n const format = (args.output as string) || \"json\";\n const hints = keywordsForSiteHints(data.length, queryContext, type);\n if (format !== \"json\") {\n writeResearchOutput(data as unknown as Array<Record<string, unknown>>, format);\n writeResearchHints(hints, format);\n return;\n }\n writeResearchJson({\n ok: true,\n data,\n fields: FIELDS,\n note: RESEARCH_DATA_NOTE,\n query_context: queryContext,\n hints,\n });\n } catch (err) {\n handleResearchError(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAa9B,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,QAAQ,EAAE,MAAM,UAAU,aAAa,yCAAyC,UAAU,KAAK;AAAA,IAC/F,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,MAAM,EAAE,MAAM,UAAU,aAAa,6CAA6C,UAAU,MAAM;AAAA,IAClG,OAAO,EAAE,MAAM,UAAU,aAAa,wCAAwC,UAAU,MAAM;AAAA,IAC9F,YAAY,EAAE,MAAM,WAAW,aAAa,uCAAuC,UAAU,MAAM;AAAA,EACrG;AACF,CAAC;AAUD,IAAM,SAAiC;AAAA,EACrC,SAAS;AAAA,EACT,eAAe;AAAA,EACf,KAAK;AAAA,EACL,aAAa;AAAA,EACb,mBAAmB;AACrB;AAEO,IAAM,yBAAyB,cAAc;AAAA,EAClD,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMf;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ,EAAE,MAAM,cAAc,aAAa,4BAA4B,UAAU,KAAK;AAAA,IACtF,UAAU,EAAE,MAAM,UAAU,aAAa,+CAA+C,UAAU,MAAM;AAAA,IACxG,UAAU,EAAE,MAAM,UAAU,aAAa,uCAAuC,UAAU,MAAM;AAAA,IAChG,MAAM,EAAE,MAAM,UAAU,aAAa,yCAAyC,UAAU,MAAM;AAAA,IAC9F,MAAM,EAAE,MAAM,UAAU,aAAa,6CAA6C,UAAU,MAAM;AAAA,IAClG,OAAO,EAAE,MAAM,UAAU,aAAa,wCAAwC,UAAU,MAAM;AAAA,IAC9F,QAAQ,EAAE,MAAM,UAAU,aAAa,6BAA6B,UAAU,OAAO,SAAS,OAAO;AAAA,IACrG,YAAY,EAAE,MAAM,WAAW,aAAa,uCAAuC,UAAU,MAAM;AAAA,EACrG;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,SAAS,KAAK;AACpB,UAAM,WAAY,KAAK,YAAuB;AAC9C,UAAM,WAAY,KAAK,YAAuB;AAC9C,UAAM,OAAQ,KAAK,QAAmB;AACtC,UAAM,OAAQ,KAAK,QAAmB;AACtC,UAAM,QAAQ,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAChD,UAAM,YAAY,KAAK,UAAU,IAAI,OAAO;AAC5C,UAAM,eAAe,0BAA0B,UAAU,QAAQ;AAEjE,QAAI;AACF,YAAM,OAAO,MAAM,QAA0B,mCAAmC;AAAA,QAC9E;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,mBAAa,YAAY;AACzB,YAAM,SAAU,KAAK,UAAqB;AAC1C,YAAM,QAAQ,qBAAqB,KAAK,QAAQ,cAAc,IAAI;AAClE,UAAI,WAAW,QAAQ;AACrB,4BAAoB,MAAmD,MAAM;AAC7E,2BAAmB,OAAO,MAAM;AAChC;AAAA,MACF;AACA,wBAAkB;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,QACA,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,eAAe;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,0BAAoB,GAAG;AAAA,IACzB;AAAA,EACF;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/commands/research/keywords-for-site.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { buildResearchQueryContext, warnDefaults } from \"../../geo-context.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { keywordsForSiteHints } from \"./hints.ts\";\nimport {\n handleResearchError,\n RESEARCH_DATA_NOTE,\n writeResearchHints,\n writeResearchJson,\n writeResearchOutput,\n} from \"./output.ts\";\n\nregisterSchema({\n command: \"research.keywords-for-site\",\n description:\n \"Get keywords a competitor targets in Google. Use --type paid to see only paid keywords, --type organic for organic only. If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.\",\n args: {\n target: { type: \"string\", description: \"Domain or URL to analyze (positional)\", required: true },\n location: {\n type: \"string\",\n description:\n \"Country code (us, uk, es, de...) or DataForSEO location code. Defaults to us (United States) if omitted — always set this for non-US markets\",\n required: false,\n },\n language: {\n type: \"string\",\n description:\n \"Language code or name. Defaults to en (English) if omitted — always set this for non-English markets\",\n required: false,\n },\n sort: {\n type: \"string\",\n description: \"Sort: search_volume, competition, cpc (default: search_volume)\",\n required: false,\n },\n type: { type: \"string\", description: \"Filter: paid, organic, all (default: all)\", required: false },\n limit: { type: \"string\", description: \"Max results (default: 50, max: 1000)\", required: false },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n});\n\ninterface KeywordForSite {\n keyword: string;\n search_volume: number;\n cpc: number;\n competition: string;\n competition_index: number;\n}\n\nconst FIELDS: Record<string, string> = {\n keyword: \"Keyword the site targets\",\n search_volume: \"Monthly search volume\",\n cpc: \"Cost per click in USD\",\n competition: \"LOW, MEDIUM, or HIGH\",\n competition_index: \"Competition score 0-100\",\n};\n\nexport const keywordsForSiteCommand = defineCommand({\n meta: {\n name: \"keywords-for-site\",\n description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.\n\nExamples:\n baker research keywords-for-site \"competitor.com\"\n baker research keywords-for-site \"competitor.com\" --type paid --limit 20\n baker research keywords-for-site \"competitor.com\" --type organic --location uk`,\n },\n args: {\n target: { type: \"positional\", description: \"Domain or URL to analyze\", required: true },\n location: { type: \"string\", description: \"Country code or location code (default: us)\", required: false },\n language: { type: \"string\", description: \"Language code or name (default: en)\", required: false },\n sort: { type: \"string\", description: \"Sort: search_volume, competition, cpc\", required: false },\n type: { type: \"string\", description: \"Filter: paid, organic, all (default: all)\", required: false },\n limit: { type: \"string\", description: \"Max results (default: 50, max: 1000)\", required: false },\n output: { type: \"string\", description: \"Format: json|csv|md|jsonl\", required: false, default: \"json\" },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n run: async ({ args }) => {\n const target = args.target as string;\n const location = (args.location as string) || undefined;\n const language = (args.language as string) || undefined;\n const sort = (args.sort as string) || undefined;\n const type = (args.type as string) || undefined;\n const limit = args.limit ? Number(args.limit) : undefined;\n const skipCache = args[\"no-cache\"] ? true : undefined;\n const queryContext = buildResearchQueryContext(location, language);\n\n try {\n const data = await apiPost<KeywordForSite[]>(\"/api/research/keywords-for-site\", {\n target,\n location,\n language,\n sort,\n type,\n limit,\n skipCache,\n });\n\n warnDefaults(queryContext);\n const format = (args.output as string) || \"json\";\n const hints = keywordsForSiteHints(data.length, queryContext, type);\n if (format !== \"json\") {\n writeResearchOutput(data as unknown as Array<Record<string, unknown>>, format);\n writeResearchHints(hints, format);\n return;\n }\n writeResearchJson({\n ok: true,\n data,\n fields: FIELDS,\n note: RESEARCH_DATA_NOTE,\n query_context: queryContext,\n hints,\n });\n } catch (err) {\n handleResearchError(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAa9B,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,QAAQ,EAAE,MAAM,UAAU,aAAa,yCAAyC,UAAU,KAAK;AAAA,IAC/F,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,MAAM,EAAE,MAAM,UAAU,aAAa,6CAA6C,UAAU,MAAM;AAAA,IAClG,OAAO,EAAE,MAAM,UAAU,aAAa,wCAAwC,UAAU,MAAM;AAAA,IAC9F,YAAY,EAAE,MAAM,WAAW,aAAa,uCAAuC,UAAU,MAAM;AAAA,EACrG;AACF,CAAC;AAUD,IAAM,SAAiC;AAAA,EACrC,SAAS;AAAA,EACT,eAAe;AAAA,EACf,KAAK;AAAA,EACL,aAAa;AAAA,EACb,mBAAmB;AACrB;AAEO,IAAM,yBAAyB,cAAc;AAAA,EAClD,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMf;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ,EAAE,MAAM,cAAc,aAAa,4BAA4B,UAAU,KAAK;AAAA,IACtF,UAAU,EAAE,MAAM,UAAU,aAAa,+CAA+C,UAAU,MAAM;AAAA,IACxG,UAAU,EAAE,MAAM,UAAU,aAAa,uCAAuC,UAAU,MAAM;AAAA,IAChG,MAAM,EAAE,MAAM,UAAU,aAAa,yCAAyC,UAAU,MAAM;AAAA,IAC9F,MAAM,EAAE,MAAM,UAAU,aAAa,6CAA6C,UAAU,MAAM;AAAA,IAClG,OAAO,EAAE,MAAM,UAAU,aAAa,wCAAwC,UAAU,MAAM;AAAA,IAC9F,QAAQ,EAAE,MAAM,UAAU,aAAa,6BAA6B,UAAU,OAAO,SAAS,OAAO;AAAA,IACrG,YAAY,EAAE,MAAM,WAAW,aAAa,uCAAuC,UAAU,MAAM;AAAA,EACrG;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,SAAS,KAAK;AACpB,UAAM,WAAY,KAAK,YAAuB;AAC9C,UAAM,WAAY,KAAK,YAAuB;AAC9C,UAAM,OAAQ,KAAK,QAAmB;AACtC,UAAM,OAAQ,KAAK,QAAmB;AACtC,UAAM,QAAQ,KAAK,QAAQ,OAAO,KAAK,KAAK,IAAI;AAChD,UAAM,YAAY,KAAK,UAAU,IAAI,OAAO;AAC5C,UAAM,eAAe,0BAA0B,UAAU,QAAQ;AAEjE,QAAI;AACF,YAAM,OAAO,MAAM,QAA0B,mCAAmC;AAAA,QAC9E;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,mBAAa,YAAY;AACzB,YAAM,SAAU,KAAK,UAAqB;AAC1C,YAAM,QAAQ,qBAAqB,KAAK,QAAQ,cAAc,IAAI;AAClE,UAAI,WAAW,QAAQ;AACrB,4BAAoB,MAAmD,MAAM;AAC7E,2BAAmB,OAAO,MAAM;AAChC;AAAA,MACF;AACA,wBAAkB;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,QACA,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,eAAe;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,0BAAoB,GAAG;AAAA,IACzB;AAAA,EACF;AACF,CAAC;","names":[]}
@@ -16,8 +16,8 @@ Subcommands:
16
16
  baker landing export start \u2014 download the PUBLISHED landings as a ZIP of plain HTML ("download my landings", "send me the HTML"); \`baker landing export status <id>\` gives the link.`
17
17
  },
18
18
  subCommands: {
19
- inspiration: () => import("./inspiration-S3DU4CMQ.js").then((m) => m.inspirationCommand),
20
- critique: () => import("./critique-TPHR27KH.js").then((m) => m.critiqueCommand),
19
+ inspiration: () => import("./inspiration-P265QJ2H.js").then((m) => m.inspirationCommand),
20
+ critique: () => import("./critique-ZS4ON3SU.js").then((m) => m.critiqueCommand),
21
21
  variant: () => import("./variant-FLZJYGYL.js").then((m) => m.variantCommand),
22
22
  export: () => import("./export-JQRMBJ7D.js").then((m) => m.exportCommand)
23
23
  }
@@ -25,4 +25,4 @@ Subcommands:
25
25
  export {
26
26
  landingCommand
27
27
  };
28
- //# sourceMappingURL=landing-2ZB46LXH.js.map
28
+ //# sourceMappingURL=landing-CJYGWCK4.js.map
@@ -2,7 +2,7 @@ import {
2
2
  csvOrJson,
3
3
  handleLinkedinError,
4
4
  resolveAccountIdArg
5
- } from "./chunk-N4LAYIIN.js";
5
+ } from "./chunk-CSYSX4D2.js";
6
6
  import {
7
7
  writeAdsJson,
8
8
  writeAdsOutput
@@ -10,11 +10,10 @@ import {
10
10
  import {
11
11
  NO_CACHE_ARG
12
12
  } from "./chunk-X7ZODEXJ.js";
13
- import "./chunk-7EPXVICM.js";
13
+ import "./chunk-XF4JUKVF.js";
14
14
  import "./chunk-GXDLWBOY.js";
15
15
  import "./chunk-TEINLN64.js";
16
16
  import "./chunk-ZJWUBJYQ.js";
17
- import "./chunk-HR6IWNKE.js";
18
17
  import "./chunk-NE4F3FHN.js";
19
18
  import {
20
19
  apiGet
@@ -88,4 +87,4 @@ Examples:
88
87
  export {
89
88
  leadsCommand
90
89
  };
91
- //# sourceMappingURL=leads-A4W5KTWB.js.map
90
+ //# sourceMappingURL=leads-PHKG6CP3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/ads/linkedin/leads.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiGet } from \"../../../client.ts\";\nimport { writeAdsJson, writeAdsOutput } from \"../output.ts\";\nimport { csvOrJson, handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\ninterface LeadResponseRow {\n id: string;\n formId: string;\n formUrn: string;\n campaignUrn?: string;\n submittedAt?: number;\n answers?: Array<{ questionId: string; question: string; answer: string }>;\n consentResponses?: Array<{ consentId: string; consentText?: string; agreed?: boolean }>;\n}\n\nconst DAY_MS = 86_400_000;\n\nexport const leadsCommand = defineCommand({\n meta: {\n name: \"leads\",\n description: `List Lead Gen Form responses (playbook §07).\n\nLinkedIn retains LGF responses for 90 days only — sync to your CRM via this\nendpoint or you'll lose them.\n\nExamples:\n baker ads linkedin leads --account-id 503001492\n baker ads linkedin leads --account-id 503001492 --campaign-id 1234\n baker ads linkedin leads --account-id 503001492 --form-id 5678 --since-days 7\n baker ads linkedin leads --account-id 503001492 --output csv`,\n },\n args: {\n \"account-id\": { type: \"string\", description: \"Numeric account ID or urn:li:sponsoredAccount:N\" },\n \"account-urn\": { type: \"string\", description: \"Alias for --account-id\" },\n \"form-id\": { type: \"string\", description: \"Filter by Lead Gen Form ID\" },\n \"campaign-id\": { type: \"string\", description: \"Filter by campaign ID\" },\n \"since-days\": { type: \"string\", description: \"Only responses submitted in the last N days\" },\n \"since-ms\": {\n type: \"string\",\n description: \"Only responses submitted at or after this epoch ms (alternative to --since-days)\",\n },\n limit: { type: \"string\", description: \"Max rows (default: 500)\" },\n \"no-cache\": NO_CACHE_ARG,\n output: { type: \"string\", description: \"json|csv|jsonl|md\", default: \"json\" },\n },\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n try {\n const params: Record<string, string> = { \"account-id\": accountId };\n if (args[\"form-id\"]) params[\"form-id\"] = String(args[\"form-id\"]);\n if (args[\"campaign-id\"]) params[\"campaign-id\"] = String(args[\"campaign-id\"]);\n const sinceDays = args[\"since-days\"] ? Number(args[\"since-days\"]) : undefined;\n const sinceMs = args[\"since-ms\"]\n ? Number(args[\"since-ms\"])\n : sinceDays\n ? Date.now() - sinceDays * DAY_MS\n : undefined;\n if (sinceMs) params[\"since-ms\"] = String(sinceMs);\n if (args.limit) params.limit = String(args.limit);\n if (args[\"no-cache\"]) params[\"skip-cache\"] = \"true\";\n\n const data = await apiGet<LeadResponseRow[]>(\"/api/ads/linkedin/leads\", params);\n const fmt = csvOrJson(args);\n if (fmt !== \"json\") {\n // Flatten the answers array for CSV/MD output.\n const flat = data.map((r) => ({\n id: r.id,\n formId: r.formId,\n campaignUrn: r.campaignUrn,\n submittedAt: r.submittedAt ? new Date(r.submittedAt).toISOString() : \"\",\n answers: (r.answers ?? []).map((a) => `${a.question}: ${a.answer}`).join(\" | \"),\n }));\n writeAdsOutput(flat as unknown as Array<Record<string, unknown>>, fmt);\n return;\n }\n writeAdsJson({ ok: true, data });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAgB9B,IAAM,SAAS;AAER,IAAM,eAAe,cAAc;AAAA,EACxC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUf;AAAA,EACA,MAAM;AAAA,IACJ,cAAc,EAAE,MAAM,UAAU,aAAa,kDAAkD;AAAA,IAC/F,eAAe,EAAE,MAAM,UAAU,aAAa,yBAAyB;AAAA,IACvE,WAAW,EAAE,MAAM,UAAU,aAAa,6BAA6B;AAAA,IACvE,eAAe,EAAE,MAAM,UAAU,aAAa,wBAAwB;AAAA,IACtE,cAAc,EAAE,MAAM,UAAU,aAAa,8CAA8C;AAAA,IAC3F,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,OAAO,EAAE,MAAM,UAAU,aAAa,0BAA0B;AAAA,IAChE,YAAY;AAAA,IACZ,QAAQ,EAAE,MAAM,UAAU,aAAa,qBAAqB,SAAS,OAAO;AAAA,EAC9E;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,YAAY,oBAAoB,IAAI;AAC1C,QAAI;AACF,YAAM,SAAiC,EAAE,cAAc,UAAU;AACjE,UAAI,KAAK,SAAS,EAAG,QAAO,SAAS,IAAI,OAAO,KAAK,SAAS,CAAC;AAC/D,UAAI,KAAK,aAAa,EAAG,QAAO,aAAa,IAAI,OAAO,KAAK,aAAa,CAAC;AAC3E,YAAM,YAAY,KAAK,YAAY,IAAI,OAAO,KAAK,YAAY,CAAC,IAAI;AACpE,YAAM,UAAU,KAAK,UAAU,IAC3B,OAAO,KAAK,UAAU,CAAC,IACvB,YACE,KAAK,IAAI,IAAI,YAAY,SACzB;AACN,UAAI,QAAS,QAAO,UAAU,IAAI,OAAO,OAAO;AAChD,UAAI,KAAK,MAAO,QAAO,QAAQ,OAAO,KAAK,KAAK;AAChD,UAAI,KAAK,UAAU,EAAG,QAAO,YAAY,IAAI;AAE7C,YAAM,OAAO,MAAM,OAA0B,2BAA2B,MAAM;AAC9E,YAAM,MAAM,UAAU,IAAI;AAC1B,UAAI,QAAQ,QAAQ;AAElB,cAAM,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,UAC5B,IAAI,EAAE;AAAA,UACN,QAAQ,EAAE;AAAA,UACV,aAAa,EAAE;AAAA,UACf,aAAa,EAAE,cAAc,IAAI,KAAK,EAAE,WAAW,EAAE,YAAY,IAAI;AAAA,UACrE,UAAU,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,KAAK;AAAA,QAChF,EAAE;AACF,uBAAe,MAAmD,GAAG;AACrE;AAAA,MACF;AACA,mBAAa,EAAE,IAAI,MAAM,KAAK,CAAC;AAAA,IACjC,SAAS,KAAK;AACZ,0BAAoB,GAAG;AAAA,IACzB;AAAA,EACF;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/commands/ads/linkedin/leads.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiGet } from \"../../../client.ts\";\nimport { writeAdsJson, writeAdsOutput } from \"../output.ts\";\nimport { csvOrJson, handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\ninterface LeadResponseRow {\n id: string;\n formId: string;\n formUrn: string;\n campaignUrn?: string;\n submittedAt?: number;\n answers?: Array<{ questionId: string; question: string; answer: string }>;\n consentResponses?: Array<{ consentId: string; consentText?: string; agreed?: boolean }>;\n}\n\nconst DAY_MS = 86_400_000;\n\nexport const leadsCommand = defineCommand({\n meta: {\n name: \"leads\",\n description: `List Lead Gen Form responses (playbook §07).\n\nLinkedIn retains LGF responses for 90 days only — sync to your CRM via this\nendpoint or you'll lose them.\n\nExamples:\n baker ads linkedin leads --account-id 503001492\n baker ads linkedin leads --account-id 503001492 --campaign-id 1234\n baker ads linkedin leads --account-id 503001492 --form-id 5678 --since-days 7\n baker ads linkedin leads --account-id 503001492 --output csv`,\n },\n args: {\n \"account-id\": { type: \"string\", description: \"Numeric account ID or urn:li:sponsoredAccount:N\" },\n \"account-urn\": { type: \"string\", description: \"Alias for --account-id\" },\n \"form-id\": { type: \"string\", description: \"Filter by Lead Gen Form ID\" },\n \"campaign-id\": { type: \"string\", description: \"Filter by campaign ID\" },\n \"since-days\": { type: \"string\", description: \"Only responses submitted in the last N days\" },\n \"since-ms\": {\n type: \"string\",\n description: \"Only responses submitted at or after this epoch ms (alternative to --since-days)\",\n },\n limit: { type: \"string\", description: \"Max rows (default: 500)\" },\n \"no-cache\": NO_CACHE_ARG,\n output: { type: \"string\", description: \"json|csv|jsonl|md\", default: \"json\" },\n },\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n try {\n const params: Record<string, string> = { \"account-id\": accountId };\n if (args[\"form-id\"]) params[\"form-id\"] = String(args[\"form-id\"]);\n if (args[\"campaign-id\"]) params[\"campaign-id\"] = String(args[\"campaign-id\"]);\n const sinceDays = args[\"since-days\"] ? Number(args[\"since-days\"]) : undefined;\n const sinceMs = args[\"since-ms\"]\n ? Number(args[\"since-ms\"])\n : sinceDays\n ? Date.now() - sinceDays * DAY_MS\n : undefined;\n if (sinceMs) params[\"since-ms\"] = String(sinceMs);\n if (args.limit) params.limit = String(args.limit);\n if (args[\"no-cache\"]) params[\"skip-cache\"] = \"true\";\n\n const data = await apiGet<LeadResponseRow[]>(\"/api/ads/linkedin/leads\", params);\n const fmt = csvOrJson(args);\n if (fmt !== \"json\") {\n // Flatten the answers array for CSV/MD output.\n const flat = data.map((r) => ({\n id: r.id,\n formId: r.formId,\n campaignUrn: r.campaignUrn,\n submittedAt: r.submittedAt ? new Date(r.submittedAt).toISOString() : \"\",\n answers: (r.answers ?? []).map((a) => `${a.question}: ${a.answer}`).join(\" | \"),\n }));\n writeAdsOutput(flat as unknown as Array<Record<string, unknown>>, fmt);\n return;\n }\n writeAdsJson({ ok: true, data });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAgB9B,IAAM,SAAS;AAER,IAAM,eAAe,cAAc;AAAA,EACxC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUf;AAAA,EACA,MAAM;AAAA,IACJ,cAAc,EAAE,MAAM,UAAU,aAAa,kDAAkD;AAAA,IAC/F,eAAe,EAAE,MAAM,UAAU,aAAa,yBAAyB;AAAA,IACvE,WAAW,EAAE,MAAM,UAAU,aAAa,6BAA6B;AAAA,IACvE,eAAe,EAAE,MAAM,UAAU,aAAa,wBAAwB;AAAA,IACtE,cAAc,EAAE,MAAM,UAAU,aAAa,8CAA8C;AAAA,IAC3F,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,OAAO,EAAE,MAAM,UAAU,aAAa,0BAA0B;AAAA,IAChE,YAAY;AAAA,IACZ,QAAQ,EAAE,MAAM,UAAU,aAAa,qBAAqB,SAAS,OAAO;AAAA,EAC9E;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,YAAY,oBAAoB,IAAI;AAC1C,QAAI;AACF,YAAM,SAAiC,EAAE,cAAc,UAAU;AACjE,UAAI,KAAK,SAAS,EAAG,QAAO,SAAS,IAAI,OAAO,KAAK,SAAS,CAAC;AAC/D,UAAI,KAAK,aAAa,EAAG,QAAO,aAAa,IAAI,OAAO,KAAK,aAAa,CAAC;AAC3E,YAAM,YAAY,KAAK,YAAY,IAAI,OAAO,KAAK,YAAY,CAAC,IAAI;AACpE,YAAM,UAAU,KAAK,UAAU,IAC3B,OAAO,KAAK,UAAU,CAAC,IACvB,YACE,KAAK,IAAI,IAAI,YAAY,SACzB;AACN,UAAI,QAAS,QAAO,UAAU,IAAI,OAAO,OAAO;AAChD,UAAI,KAAK,MAAO,QAAO,QAAQ,OAAO,KAAK,KAAK;AAChD,UAAI,KAAK,UAAU,EAAG,QAAO,YAAY,IAAI;AAE7C,YAAM,OAAO,MAAM,OAA0B,2BAA2B,MAAM;AAC9E,YAAM,MAAM,UAAU,IAAI;AAC1B,UAAI,QAAQ,QAAQ;AAElB,cAAM,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,UAC5B,IAAI,EAAE;AAAA,UACN,QAAQ,EAAE;AAAA,UACV,aAAa,EAAE;AAAA,UACf,aAAa,EAAE,cAAc,IAAI,KAAK,EAAE,WAAW,EAAE,YAAY,IAAI;AAAA,UACrE,UAAU,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,KAAK;AAAA,QAChF,EAAE;AACF,uBAAe,MAAmD,GAAG;AACrE;AAAA,MACF;AACA,mBAAa,EAAE,IAAI,MAAM,KAAK,CAAC;AAAA,IACjC,SAAS,KAAK;AACZ,0BAAoB,GAAG;AAAA,IACzB;AAAA,EACF;AACF,CAAC;","names":[]}
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  parseDays,
10
10
  withDefinitions
11
- } from "./chunk-2AOE2MZQ.js";
11
+ } from "./chunk-5ZDLTE5T.js";
12
12
  import "./chunk-F2S5BLPE.js";
13
13
  import "./chunk-WTOYCUKH.js";
14
14
  import {
@@ -22,12 +22,11 @@ import "./chunk-VVZBBKRC.js";
22
22
  import "./chunk-YBMVHGY3.js";
23
23
  import {
24
24
  failApi
25
- } from "./chunk-SJYEY5MV.js";
26
- import "./chunk-7EPXVICM.js";
25
+ } from "./chunk-3HJLHTWP.js";
26
+ import "./chunk-XF4JUKVF.js";
27
27
  import "./chunk-GXDLWBOY.js";
28
28
  import "./chunk-TEINLN64.js";
29
29
  import "./chunk-ZJWUBJYQ.js";
30
- import "./chunk-HR6IWNKE.js";
31
30
  import "./chunk-NE4F3FHN.js";
32
31
  import {
33
32
  apiPost
@@ -201,4 +200,4 @@ export {
201
200
  learnCommand,
202
201
  learnEnvelope
203
202
  };
204
- //# sourceMappingURL=learn-IPULBCOD.js.map
203
+ //# sourceMappingURL=learn-FUQSY7DN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/creatives/learn.ts","../src/commands/creatives/learn-model.ts"],"sourcesContent":["/**\n * `baker creatives learn`: what the ads each idea became did in the live account, written back\n * onto the idea (its `status` and a frozen `result`), so the next chat builds on winners and\n * never repeats a message that lost.\n */\nimport { readFileSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { CreativesPerformanceResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi } from \"../actions/shared.ts\";\nimport { findWorkspaceRoot } from \"../canvas/normalize-paths.ts\";\nimport { IDEAS_DIR, readIdeas } from \"./ideas-workspace.ts\";\nimport { type IdeaLearning, learnFromResults } from \"./learn-model.ts\";\nimport { setDefinitionFields } from \"./make-model.ts\";\nimport { parseDays, withDefinitions } from \"./performance.ts\";\n\nconst DESCRIPTION = `Write back what each built idea's ads did in the live Meta account: every creative of the idea pooled, judged against the rest of the account's cost per result, and the verdict (winner, failed, inconclusive, testing) and frozen numbers written onto src/creatives/_ideas/<idea>.md. Run it before writing new ideas, and weekly.\n\nStart here:\n baker creatives learn # last 30 days, written onto the ideas\n baker creatives learn --days 60\n baker creatives learn --dry-run # show the verdicts, write nothing\n\nA winner gets results at 0.8x the usual cost or less (3+ results); failed is 1.5x or more, or spend worth two usual results with none; under 1,000 impressions it is still testing.`;\n\nconst ARGS = {\n days: { type: \"string\", required: false, description: \"Reporting window in days (default 30)\" },\n \"dry-run\": { type: \"boolean\", required: false, default: false, description: \"Show the verdicts; write nothing\" },\n} as const;\n\nregisterSchema({ command: \"creatives.learn\", description: DESCRIPTION, args: ARGS });\n\n/** What the agent reads, and what to do with winners and losers. Pure. */\nexport function learnEnvelope(\n learnings: readonly IdeaLearning[],\n written: boolean,\n unreadable: readonly string[] = [],\n) {\n const winners = learnings.filter((l) => l.to === \"winner\").map((l) => l.idea);\n const failed = learnings.filter((l) => l.to === \"failed\").map((l) => l.idea);\n const hints: string[] = [];\n if (unreadable.length > 0) {\n hints.push(\n `Could not read ${unreadable.join(\", \")}, so their results were not written: fix what \\`baker creatives ideas\\` names, then run this again.`,\n );\n }\n if (learnings.length === 0) {\n hints.push(\n \"No built idea has ads delivering yet: nothing to learn. Ideas count once a published ad shows their creative.\",\n );\n }\n if (winners.length > 0) {\n hints.push(\n `Build on ${winners.join(\", \")}: keep the message and make it in a new format or for a new persona before any new idea.`,\n );\n }\n if (failed.length > 0) {\n hints.push(\n `${failed.join(\", \")} lost: never repeat their message; \\`baker creatives ideas\\` flags an idea that does.`,\n );\n }\n return {\n ok: true as const,\n data: {\n written,\n ideas: learnings.map((l) => ({\n idea: l.idea,\n status: l.from === l.to ? l.to : `${l.from} → ${l.to}`,\n ...l.result,\n })),\n },\n hints,\n };\n}\n\nasync function writeBack(root: string, learnings: readonly IdeaLearning[]): Promise<void> {\n for (const learning of learnings) {\n const file = path.join(root, IDEAS_DIR, `${learning.idea}.md`);\n const raw = await readFile(file, \"utf8\");\n await writeFile(file, setDefinitionFields(raw, { status: learning.to, result: learning.result }), \"utf8\");\n }\n}\n\nfunction readDefinition(root: string, slug: string): string | null {\n try {\n return readFileSync(path.join(root, \"src\", \"creatives\", slug, \"_definition.md\"), \"utf8\");\n } catch {\n return null;\n }\n}\n\nfunction today(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nexport const learnCommand = defineCommand({\n meta: { name: \"learn\", description: DESCRIPTION },\n args: ARGS,\n async run({ args }) {\n try {\n const root = findWorkspaceRoot(process.cwd()) ?? process.cwd();\n const days = parseDays(args.days as string | undefined);\n const performance = withDefinitions(\n await apiPost<CreativesPerformanceResponse>(\"/api/creatives/performance\", days ? { days } : {}),\n (slug) => readDefinition(root, slug),\n );\n const { ideas, unreadable } = await readIdeas(root);\n const learnings = learnFromResults(ideas, performance.data.creatives, today());\n const dryRun = args[\"dry-run\"] === true;\n if (!dryRun) await writeBack(root, learnings);\n writeJson(\n learnEnvelope(\n learnings,\n !dryRun && learnings.length > 0,\n unreadable.map((u) => u.id),\n ),\n );\n } catch (err) {\n failApi(err);\n }\n },\n});\n","/**\n * What the ads an idea became did, written back onto the idea: `baker creatives learn` turns\n * performance into a verdict per idea, so the next chat starts from what won and what lost\n * instead of from zero. Pure.\n */\nimport type { CreativePerformance } from \"@baker/api\";\nimport type { Idea, IdeaStatus } from \"./ideas-model.ts\";\n\n/** Below this many impressions an idea has not been seen enough to call. */\nconst MIN_IMPRESSIONS = 1000;\n/** Seen this much with no clear verdict, an idea is inconclusive rather than still testing. */\nconst SEEN_ENOUGH = 5000;\n/** At or under this share of the account's usual cost per result, with enough results: a winner. */\nconst WINNER_RATIO = 0.8;\nconst WINNER_MIN_RESULTS = 3;\n/** At or over this share of the usual cost per result: failed. */\nconst FAILED_RATIO = 1.5;\n/** Spending this many usual results' worth with none: failed. */\nconst SILENT_SPEND = 2;\n/** Verdicts a thin window never takes back: too little delivery says nothing new about them. */\nconst SETTLED: ReadonlySet<IdeaStatus> = new Set([\"winner\", \"failed\", \"inconclusive\"]);\n\nexport type IdeaResult = {\n asOf: string;\n creatives: number;\n currency?: string;\n spend: number;\n impressions: number;\n results: number;\n costPerResult: number | null;\n ctr: number | null;\n /** Cost per result over the rest of the account's: 0.5 is half the usual cost. */\n vsAccount: number | null;\n};\n\nexport type IdeaLearning = { idea: string; from: IdeaStatus; to: IdeaStatus; result: IdeaResult };\n\nconst round = (n: number) => Math.round(n * 100) / 100;\n\nfunction totals(creatives: readonly CreativePerformance[]) {\n const spend = creatives.reduce((sum, c) => sum + c.spend, 0);\n const impressions = creatives.reduce((sum, c) => sum + c.impressions, 0);\n const results = creatives.reduce((sum, c) => sum + (c.results ?? 0), 0);\n const clicks = creatives.reduce((sum, c) => sum + (c.ctr ?? 0) * c.impressions, 0);\n return { spend, impressions, results, ctr: impressions > 0 ? round(clicks / impressions) : null };\n}\n\nfunction verdict(result: IdeaResult, usual: number | null): IdeaStatus {\n if (result.impressions < MIN_IMPRESSIONS) return \"testing\";\n if (usual !== null) {\n if (result.results === 0 && result.spend >= SILENT_SPEND * usual) return \"failed\";\n const ratio = result.vsAccount;\n if (ratio !== null && result.results >= WINNER_MIN_RESULTS && ratio <= WINNER_RATIO) return \"winner\";\n if (ratio !== null && ratio >= FAILED_RATIO) return \"failed\";\n }\n return result.impressions >= SEEN_ENOUGH ? \"inconclusive\" : \"testing\";\n}\n\n/** One idea's ads pooled into the numbers frozen on it, against the account's usual cost per result. */\nfunction ideaResult(own: readonly CreativePerformance[], usual: number | null, asOf: string): IdeaResult {\n const mine = totals(own);\n const costPerResult = mine.results > 0 ? round(mine.spend / mine.results) : null;\n return {\n asOf,\n creatives: own.length,\n ...(own[0]?.currency ? { currency: own[0].currency } : {}),\n spend: round(mine.spend),\n impressions: mine.impressions,\n results: mine.results,\n costPerResult,\n ctr: mine.ctr,\n vsAccount: usual !== null && costPerResult !== null ? round(costPerResult / usual) : null,\n };\n}\n\n/**\n * Each built idea's ads, pooled and judged against the rest of the account: cheaper results than\n * usual win, far dearer ones (or spend with none) fail. Ideas still to build, retired, with no\n * ad delivering, or already judged and seen too little since, are left alone.\n */\nexport function learnFromResults(\n ideas: readonly Idea[],\n creatives: readonly CreativePerformance[],\n asOf: string,\n): IdeaLearning[] {\n const ideaOf = (c: CreativePerformance) => c.definition?.idea ?? null;\n return ideas.flatMap((idea): IdeaLearning[] => {\n if (idea.status === \"idea\" || idea.status === \"retired\") return [];\n const own = creatives.filter((c) => ideaOf(c) === idea.id);\n if (own.length === 0) return [];\n const rest = totals(creatives.filter((c) => ideaOf(c) !== idea.id));\n const usual = rest.results > 0 ? rest.spend / rest.results : null;\n const result = ideaResult(own, usual, asOf);\n const to = verdict(result, usual);\n if (to === \"testing\" && SETTLED.has(idea.status)) return [];\n return [{ idea: idea.id, from: idea.status, to, result }];\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,SAAS,oBAAoB;AAC7B,SAAS,UAAU,iBAAiB;AACpC,OAAO,UAAU;AAEjB,SAAS,qBAAqB;;;ACA9B,IAAM,kBAAkB;AAExB,IAAM,cAAc;AAEpB,IAAM,eAAe;AACrB,IAAM,qBAAqB;AAE3B,IAAM,eAAe;AAErB,IAAM,eAAe;AAErB,IAAM,UAAmC,oBAAI,IAAI,CAAC,UAAU,UAAU,cAAc,CAAC;AAiBrF,IAAM,QAAQ,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG,IAAI;AAEnD,SAAS,OAAO,WAA2C;AACzD,QAAM,QAAQ,UAAU,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AAC3D,QAAM,cAAc,UAAU,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC;AACvE,QAAM,UAAU,UAAU,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,WAAW,IAAI,CAAC;AACtE,QAAM,SAAS,UAAU,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,OAAO,KAAK,EAAE,aAAa,CAAC;AACjF,SAAO,EAAE,OAAO,aAAa,SAAS,KAAK,cAAc,IAAI,MAAM,SAAS,WAAW,IAAI,KAAK;AAClG;AAEA,SAAS,QAAQ,QAAoB,OAAkC;AACrE,MAAI,OAAO,cAAc,gBAAiB,QAAO;AACjD,MAAI,UAAU,MAAM;AAClB,QAAI,OAAO,YAAY,KAAK,OAAO,SAAS,eAAe,MAAO,QAAO;AACzE,UAAM,QAAQ,OAAO;AACrB,QAAI,UAAU,QAAQ,OAAO,WAAW,sBAAsB,SAAS,aAAc,QAAO;AAC5F,QAAI,UAAU,QAAQ,SAAS,aAAc,QAAO;AAAA,EACtD;AACA,SAAO,OAAO,eAAe,cAAc,iBAAiB;AAC9D;AAGA,SAAS,WAAW,KAAqC,OAAsB,MAA0B;AACvG,QAAM,OAAO,OAAO,GAAG;AACvB,QAAM,gBAAgB,KAAK,UAAU,IAAI,MAAM,KAAK,QAAQ,KAAK,OAAO,IAAI;AAC5E,SAAO;AAAA,IACL;AAAA,IACA,WAAW,IAAI;AAAA,IACf,GAAI,IAAI,CAAC,GAAG,WAAW,EAAE,UAAU,IAAI,CAAC,EAAE,SAAS,IAAI,CAAC;AAAA,IACxD,OAAO,MAAM,KAAK,KAAK;AAAA,IACvB,aAAa,KAAK;AAAA,IAClB,SAAS,KAAK;AAAA,IACd;AAAA,IACA,KAAK,KAAK;AAAA,IACV,WAAW,UAAU,QAAQ,kBAAkB,OAAO,MAAM,gBAAgB,KAAK,IAAI;AAAA,EACvF;AACF;AAOO,SAAS,iBACd,OACA,WACA,MACgB;AAChB,QAAM,SAAS,CAAC,MAA2B,EAAE,YAAY,QAAQ;AACjE,SAAO,MAAM,QAAQ,CAAC,SAAyB;AAC7C,QAAI,KAAK,WAAW,UAAU,KAAK,WAAW,UAAW,QAAO,CAAC;AACjE,UAAM,MAAM,UAAU,OAAO,CAAC,MAAM,OAAO,CAAC,MAAM,KAAK,EAAE;AACzD,QAAI,IAAI,WAAW,EAAG,QAAO,CAAC;AAC9B,UAAM,OAAO,OAAO,UAAU,OAAO,CAAC,MAAM,OAAO,CAAC,MAAM,KAAK,EAAE,CAAC;AAClE,UAAM,QAAQ,KAAK,UAAU,IAAI,KAAK,QAAQ,KAAK,UAAU;AAC7D,UAAM,SAAS,WAAW,KAAK,OAAO,IAAI;AAC1C,UAAM,KAAK,QAAQ,QAAQ,KAAK;AAChC,QAAI,OAAO,aAAa,QAAQ,IAAI,KAAK,MAAM,EAAG,QAAO,CAAC;AAC1D,WAAO,CAAC,EAAE,MAAM,KAAK,IAAI,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC;AAAA,EAC1D,CAAC;AACH;;;AD7EA,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpB,IAAM,OAAO;AAAA,EACX,MAAM,EAAE,MAAM,UAAU,UAAU,OAAO,aAAa,wCAAwC;AAAA,EAC9F,WAAW,EAAE,MAAM,WAAW,UAAU,OAAO,SAAS,OAAO,aAAa,mCAAmC;AACjH;AAEA,eAAe,EAAE,SAAS,mBAAmB,aAAa,aAAa,MAAM,KAAK,CAAC;AAG5E,SAAS,cACd,WACA,SACA,aAAgC,CAAC,GACjC;AACA,QAAM,UAAU,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAC5E,QAAM,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAC3E,QAAM,QAAkB,CAAC;AACzB,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM;AAAA,MACJ,kBAAkB,WAAW,KAAK,IAAI,CAAC;AAAA,IACzC;AAAA,EACF;AACA,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM;AAAA,MACJ,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,IAChC;AAAA,EACF;AACA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM;AAAA,MACJ,GAAG,OAAO,KAAK,IAAI,CAAC;AAAA,IACtB;AAAA,EACF;AACA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,MACJ;AAAA,MACA,OAAO,UAAU,IAAI,CAAC,OAAO;AAAA,QAC3B,MAAM,EAAE;AAAA,QACR,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,IAAI,WAAM,EAAE,EAAE;AAAA,QACpD,GAAG,EAAE;AAAA,MACP,EAAE;AAAA,IACJ;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,UAAU,MAAc,WAAmD;AACxF,aAAW,YAAY,WAAW;AAChC,UAAM,OAAO,KAAK,KAAK,MAAM,WAAW,GAAG,SAAS,IAAI,KAAK;AAC7D,UAAM,MAAM,MAAM,SAAS,MAAM,MAAM;AACvC,UAAM,UAAU,MAAM,oBAAoB,KAAK,EAAE,QAAQ,SAAS,IAAI,QAAQ,SAAS,OAAO,CAAC,GAAG,MAAM;AAAA,EAC1G;AACF;AAEA,SAAS,eAAe,MAAc,MAA6B;AACjE,MAAI;AACF,WAAO,aAAa,KAAK,KAAK,MAAM,OAAO,aAAa,MAAM,gBAAgB,GAAG,MAAM;AAAA,EACzF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,QAAgB;AACvB,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAC7C;AAEO,IAAM,eAAe,cAAc;AAAA,EACxC,MAAM,EAAE,MAAM,SAAS,aAAa,YAAY;AAAA,EAChD,MAAM;AAAA,EACN,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,QAAI;AACF,YAAM,OAAO,kBAAkB,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI;AAC7D,YAAM,OAAO,UAAU,KAAK,IAA0B;AACtD,YAAM,cAAc;AAAA,QAClB,MAAM,QAAsC,8BAA8B,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC;AAAA,QAC9F,CAAC,SAAS,eAAe,MAAM,IAAI;AAAA,MACrC;AACA,YAAM,EAAE,OAAO,WAAW,IAAI,MAAM,UAAU,IAAI;AAClD,YAAM,YAAY,iBAAiB,OAAO,YAAY,KAAK,WAAW,MAAM,CAAC;AAC7E,YAAM,SAAS,KAAK,SAAS,MAAM;AACnC,UAAI,CAAC,OAAQ,OAAM,UAAU,MAAM,SAAS;AAC5C;AAAA,QACE;AAAA,UACE;AAAA,UACA,CAAC,UAAU,UAAU,SAAS;AAAA,UAC9B,WAAW,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,QAC5B;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,GAAG;AAAA,IACb;AAAA,EACF;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/commands/creatives/learn.ts","../src/commands/creatives/learn-model.ts"],"sourcesContent":["/**\n * `baker creatives learn`: what the ads each idea became did in the live account, written back\n * onto the idea (its `status` and a frozen `result`), so the next chat builds on winners and\n * never repeats a message that lost.\n */\nimport { readFileSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { CreativesPerformanceResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi } from \"../actions/shared.ts\";\nimport { findWorkspaceRoot } from \"../canvas/normalize-paths.ts\";\nimport { IDEAS_DIR, readIdeas } from \"./ideas-workspace.ts\";\nimport { type IdeaLearning, learnFromResults } from \"./learn-model.ts\";\nimport { setDefinitionFields } from \"./make-model.ts\";\nimport { parseDays, withDefinitions } from \"./performance.ts\";\n\nconst DESCRIPTION = `Write back what each built idea's ads did in the live Meta account: every creative of the idea pooled, judged against the rest of the account's cost per result, and the verdict (winner, failed, inconclusive, testing) and frozen numbers written onto src/creatives/_ideas/<idea>.md. Run it before writing new ideas, and weekly.\n\nStart here:\n baker creatives learn # last 30 days, written onto the ideas\n baker creatives learn --days 60\n baker creatives learn --dry-run # show the verdicts, write nothing\n\nA winner gets results at 0.8x the usual cost or less (3+ results); failed is 1.5x or more, or spend worth two usual results with none; under 1,000 impressions it is still testing.`;\n\nconst ARGS = {\n days: { type: \"string\", required: false, description: \"Reporting window in days (default 30)\" },\n \"dry-run\": { type: \"boolean\", required: false, default: false, description: \"Show the verdicts; write nothing\" },\n} as const;\n\nregisterSchema({ command: \"creatives.learn\", description: DESCRIPTION, args: ARGS });\n\n/** What the agent reads, and what to do with winners and losers. Pure. */\nexport function learnEnvelope(\n learnings: readonly IdeaLearning[],\n written: boolean,\n unreadable: readonly string[] = [],\n) {\n const winners = learnings.filter((l) => l.to === \"winner\").map((l) => l.idea);\n const failed = learnings.filter((l) => l.to === \"failed\").map((l) => l.idea);\n const hints: string[] = [];\n if (unreadable.length > 0) {\n hints.push(\n `Could not read ${unreadable.join(\", \")}, so their results were not written: fix what \\`baker creatives ideas\\` names, then run this again.`,\n );\n }\n if (learnings.length === 0) {\n hints.push(\n \"No built idea has ads delivering yet: nothing to learn. Ideas count once a published ad shows their creative.\",\n );\n }\n if (winners.length > 0) {\n hints.push(\n `Build on ${winners.join(\", \")}: keep the message and make it in a new format or for a new persona before any new idea.`,\n );\n }\n if (failed.length > 0) {\n hints.push(\n `${failed.join(\", \")} lost: never repeat their message; \\`baker creatives ideas\\` flags an idea that does.`,\n );\n }\n return {\n ok: true as const,\n data: {\n written,\n ideas: learnings.map((l) => ({\n idea: l.idea,\n status: l.from === l.to ? l.to : `${l.from} → ${l.to}`,\n ...l.result,\n })),\n },\n hints,\n };\n}\n\nasync function writeBack(root: string, learnings: readonly IdeaLearning[]): Promise<void> {\n for (const learning of learnings) {\n const file = path.join(root, IDEAS_DIR, `${learning.idea}.md`);\n const raw = await readFile(file, \"utf8\");\n await writeFile(file, setDefinitionFields(raw, { status: learning.to, result: learning.result }), \"utf8\");\n }\n}\n\nfunction readDefinition(root: string, slug: string): string | null {\n try {\n return readFileSync(path.join(root, \"src\", \"creatives\", slug, \"_definition.md\"), \"utf8\");\n } catch {\n return null;\n }\n}\n\nfunction today(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nexport const learnCommand = defineCommand({\n meta: { name: \"learn\", description: DESCRIPTION },\n args: ARGS,\n async run({ args }) {\n try {\n const root = findWorkspaceRoot(process.cwd()) ?? process.cwd();\n const days = parseDays(args.days as string | undefined);\n const performance = withDefinitions(\n await apiPost<CreativesPerformanceResponse>(\"/api/creatives/performance\", days ? { days } : {}),\n (slug) => readDefinition(root, slug),\n );\n const { ideas, unreadable } = await readIdeas(root);\n const learnings = learnFromResults(ideas, performance.data.creatives, today());\n const dryRun = args[\"dry-run\"] === true;\n if (!dryRun) await writeBack(root, learnings);\n writeJson(\n learnEnvelope(\n learnings,\n !dryRun && learnings.length > 0,\n unreadable.map((u) => u.id),\n ),\n );\n } catch (err) {\n failApi(err);\n }\n },\n});\n","/**\n * What the ads an idea became did, written back onto the idea: `baker creatives learn` turns\n * performance into a verdict per idea, so the next chat starts from what won and what lost\n * instead of from zero. Pure.\n */\nimport type { CreativePerformance } from \"@baker/api\";\nimport type { Idea, IdeaStatus } from \"./ideas-model.ts\";\n\n/** Below this many impressions an idea has not been seen enough to call. */\nconst MIN_IMPRESSIONS = 1000;\n/** Seen this much with no clear verdict, an idea is inconclusive rather than still testing. */\nconst SEEN_ENOUGH = 5000;\n/** At or under this share of the account's usual cost per result, with enough results: a winner. */\nconst WINNER_RATIO = 0.8;\nconst WINNER_MIN_RESULTS = 3;\n/** At or over this share of the usual cost per result: failed. */\nconst FAILED_RATIO = 1.5;\n/** Spending this many usual results' worth with none: failed. */\nconst SILENT_SPEND = 2;\n/** Verdicts a thin window never takes back: too little delivery says nothing new about them. */\nconst SETTLED: ReadonlySet<IdeaStatus> = new Set([\"winner\", \"failed\", \"inconclusive\"]);\n\nexport type IdeaResult = {\n asOf: string;\n creatives: number;\n currency?: string;\n spend: number;\n impressions: number;\n results: number;\n costPerResult: number | null;\n ctr: number | null;\n /** Cost per result over the rest of the account's: 0.5 is half the usual cost. */\n vsAccount: number | null;\n};\n\nexport type IdeaLearning = { idea: string; from: IdeaStatus; to: IdeaStatus; result: IdeaResult };\n\nconst round = (n: number) => Math.round(n * 100) / 100;\n\nfunction totals(creatives: readonly CreativePerformance[]) {\n const spend = creatives.reduce((sum, c) => sum + c.spend, 0);\n const impressions = creatives.reduce((sum, c) => sum + c.impressions, 0);\n const results = creatives.reduce((sum, c) => sum + (c.results ?? 0), 0);\n const clicks = creatives.reduce((sum, c) => sum + (c.ctr ?? 0) * c.impressions, 0);\n return { spend, impressions, results, ctr: impressions > 0 ? round(clicks / impressions) : null };\n}\n\nfunction verdict(result: IdeaResult, usual: number | null): IdeaStatus {\n if (result.impressions < MIN_IMPRESSIONS) return \"testing\";\n if (usual !== null) {\n if (result.results === 0 && result.spend >= SILENT_SPEND * usual) return \"failed\";\n const ratio = result.vsAccount;\n if (ratio !== null && result.results >= WINNER_MIN_RESULTS && ratio <= WINNER_RATIO) return \"winner\";\n if (ratio !== null && ratio >= FAILED_RATIO) return \"failed\";\n }\n return result.impressions >= SEEN_ENOUGH ? \"inconclusive\" : \"testing\";\n}\n\n/** One idea's ads pooled into the numbers frozen on it, against the account's usual cost per result. */\nfunction ideaResult(own: readonly CreativePerformance[], usual: number | null, asOf: string): IdeaResult {\n const mine = totals(own);\n const costPerResult = mine.results > 0 ? round(mine.spend / mine.results) : null;\n return {\n asOf,\n creatives: own.length,\n ...(own[0]?.currency ? { currency: own[0].currency } : {}),\n spend: round(mine.spend),\n impressions: mine.impressions,\n results: mine.results,\n costPerResult,\n ctr: mine.ctr,\n vsAccount: usual !== null && costPerResult !== null ? round(costPerResult / usual) : null,\n };\n}\n\n/**\n * Each built idea's ads, pooled and judged against the rest of the account: cheaper results than\n * usual win, far dearer ones (or spend with none) fail. Ideas still to build, retired, with no\n * ad delivering, or already judged and seen too little since, are left alone.\n */\nexport function learnFromResults(\n ideas: readonly Idea[],\n creatives: readonly CreativePerformance[],\n asOf: string,\n): IdeaLearning[] {\n const ideaOf = (c: CreativePerformance) => c.definition?.idea ?? null;\n return ideas.flatMap((idea): IdeaLearning[] => {\n if (idea.status === \"idea\" || idea.status === \"retired\") return [];\n const own = creatives.filter((c) => ideaOf(c) === idea.id);\n if (own.length === 0) return [];\n const rest = totals(creatives.filter((c) => ideaOf(c) !== idea.id));\n const usual = rest.results > 0 ? rest.spend / rest.results : null;\n const result = ideaResult(own, usual, asOf);\n const to = verdict(result, usual);\n if (to === \"testing\" && SETTLED.has(idea.status)) return [];\n return [{ idea: idea.id, from: idea.status, to, result }];\n });\n}\n"],"mappings":"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","names":[]}
@@ -7,7 +7,7 @@ import {
7
7
  stageAccountId,
8
8
  stageXOp,
9
9
  stageXOps
10
- } from "./chunk-VYQ3QJ3C.js";
10
+ } from "./chunk-KHRXPQID.js";
11
11
  import "./chunk-M6UNISGO.js";
12
12
  import "./chunk-C6U6UDHJ.js";
13
13
  import "./chunk-VFIOJD5M.js";
@@ -15,11 +15,10 @@ import {
15
15
  OBJECTIVES,
16
16
  PLACEMENTS,
17
17
  PRODUCT_TYPES
18
- } from "./chunk-7EPXVICM.js";
18
+ } from "./chunk-XF4JUKVF.js";
19
19
  import "./chunk-GXDLWBOY.js";
20
20
  import "./chunk-TEINLN64.js";
21
21
  import "./chunk-ZJWUBJYQ.js";
22
- import "./chunk-HR6IWNKE.js";
23
22
  import "./chunk-NE4F3FHN.js";
24
23
  import "./chunk-XBOK23HI.js";
25
24
  import "./chunk-IFWP3ZDO.js";
@@ -206,4 +205,4 @@ export {
206
205
  lineItemsResumeCommand,
207
206
  lineItemsUpdateCommand
208
207
  };
209
- //# sourceMappingURL=line-item-writes-EMYSOJKM.js.map
208
+ //# sourceMappingURL=line-item-writes-E6MZPIZZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/ads/x/line-item-writes.ts"],"sourcesContent":["import { OBJECTIVES, PLACEMENTS, PRODUCT_TYPES } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { registerSchema } from \"../../../schemas.ts\";\nimport {\n compact,\n csvArg,\n microsFromArg,\n requireTarget,\n requireTargets,\n stageAccountId,\n stageXOp,\n stageXOps,\n} from \"./write-shared.ts\";\n\n/**\n * Staged ad-group (line item) writes. X calls them line items; X Ads Manager\n * and every marketer call them ad groups, so the help does too.\n */\n\nregisterSchema({\n command: \"ads.x.lineItems.create\",\n description: `Stage a new X ad group under a campaign. Objective, product type and campaign are fixed at create — X refuses to change any of them afterwards, so get them right here.\nObjectives: ${OBJECTIVES.join(\", \")}.`,\n args: {\n \"account-id\": { type: \"string\", description: \"X Ads account ID\", required: false },\n \"campaign-id\": {\n type: \"string\",\n description: \"Parent campaign id, or an x_temp_* ref staged in this draft\",\n required: true,\n },\n name: { type: \"string\", description: \"Ad group name\", required: true },\n objective: { type: \"string\", description: OBJECTIVES.join(\" | \"), required: true },\n \"product-type\": { type: \"string\", description: PRODUCT_TYPES.join(\" | \"), required: false },\n placements: { type: \"string\", description: `CSV of ${PLACEMENTS.join(\", \")}`, required: false },\n status: { type: \"string\", description: \"ACTIVE | PAUSED | DRAFT (default PAUSED)\", required: false },\n \"bid-strategy\": { type: \"string\", description: \"AUTO | MAX | TARGET\", required: false },\n bid: {\n type: \"string\",\n description: \"Bid in account currency — required for MAX/TARGET, refused for AUTO\",\n required: false,\n },\n \"daily-budget\": { type: \"string\", description: \"Daily budget in account currency\", required: false },\n \"total-budget\": { type: \"string\", description: \"Lifetime budget in account currency\", required: false },\n \"start-time\": { type: \"string\", description: \"ISO 8601 start\", required: false },\n \"end-time\": { type: \"string\", description: \"ISO 8601 end\", required: false },\n },\n});\n\nexport const lineItemsCreateCommand = defineCommand({\n meta: {\n name: \"create\",\n description: `Stage a new ad group (applies when the chat is published).\n\nExamples:\n baker ads x line-items create --campaign-id oilf0 --name \"Spain\" --objective WEBSITE_CLICKS\n baker ads x line-items create --campaign-id x_temp_abc --name \"Spain\" --objective REACH --bid-strategy MAX --bid 1.20`,\n },\n args: {\n \"account-id\": { type: \"string\", description: \"X Ads account ID\" },\n \"campaign-id\": { type: \"string\", description: \"Parent campaign id or x_temp_* ref\", required: true },\n name: { type: \"string\", description: \"Ad group name\", required: true },\n objective: { type: \"string\", description: OBJECTIVES.join(\" | \"), required: true },\n \"product-type\": { type: \"string\", description: PRODUCT_TYPES.join(\" | \") },\n placements: { type: \"string\", description: `CSV of ${PLACEMENTS.join(\", \")}` },\n status: { type: \"string\", description: \"ACTIVE | PAUSED | DRAFT (default PAUSED)\" },\n \"bid-strategy\": { type: \"string\", description: \"AUTO | MAX | TARGET\" },\n bid: { type: \"string\", description: \"Bid in account currency\" },\n \"daily-budget\": { type: \"string\", description: \"Daily budget in account currency\" },\n \"total-budget\": { type: \"string\", description: \"Lifetime budget in account currency\" },\n \"start-time\": { type: \"string\", description: \"ISO 8601 start\" },\n \"end-time\": { type: \"string\", description: \"ISO 8601 end\" },\n },\n run: async ({ args }) => {\n const accountId = await stageAccountId(args);\n await stageXOp({\n kind: \"lineItem.create\",\n accountId,\n payload: compact({\n campaignId: args[\"campaign-id\"],\n name: args.name,\n objective: args.objective,\n productType: args[\"product-type\"],\n placements: csvArg(args.placements),\n entityStatus: args.status,\n bidStrategy: args[\"bid-strategy\"],\n bidAmountLocalMicro: microsFromArg(args.bid, \"--bid\"),\n dailyBudgetAmountLocalMicro: microsFromArg(args[\"daily-budget\"], \"--daily-budget\"),\n totalBudgetAmountLocalMicro: microsFromArg(args[\"total-budget\"], \"--total-budget\"),\n startTime: args[\"start-time\"],\n endTime: args[\"end-time\"],\n }),\n });\n },\n});\n\nregisterSchema({\n command: \"ads.x.lineItems.update\",\n description:\n \"Stage a change to an existing X ad group. Objective, product type and campaign are absent on purpose — X treats all three as immutable after create.\",\n args: {\n id: { type: \"string\", description: \"Ad group id\", required: true },\n \"account-id\": { type: \"string\", description: \"X Ads account ID\", required: false },\n name: { type: \"string\", description: \"New name\", required: false },\n status: { type: \"string\", description: \"ACTIVE | PAUSED\", required: false },\n placements: { type: \"string\", description: \"CSV of placements\", required: false },\n \"bid-strategy\": { type: \"string\", description: \"AUTO | MAX | TARGET\", required: false },\n bid: { type: \"string\", description: \"Bid in account currency\", required: false },\n \"daily-budget\": { type: \"string\", description: \"Daily budget in account currency\", required: false },\n \"total-budget\": { type: \"string\", description: \"Lifetime budget in account currency\", required: false },\n \"start-time\": { type: \"string\", description: \"ISO 8601 start\", required: false },\n \"end-time\": { type: \"string\", description: \"ISO 8601 end\", required: false },\n },\n});\n\nexport const lineItemsUpdateCommand = defineCommand({\n meta: {\n name: \"update\",\n description: `Stage a change to an ad group.\n\nExamples:\n baker ads x line-items update wiee9 --bid 1.50\n baker ads x line-items update wiee9 --end-time 2026-12-31T00:00:00Z`,\n },\n args: {\n id: { type: \"positional\", description: \"Ad group id\", required: true },\n \"account-id\": { type: \"string\", description: \"X Ads account ID\" },\n name: { type: \"string\", description: \"New name\" },\n status: { type: \"string\", description: \"ACTIVE | PAUSED\" },\n placements: { type: \"string\", description: \"CSV of placements\" },\n \"bid-strategy\": { type: \"string\", description: \"AUTO | MAX | TARGET\" },\n bid: { type: \"string\", description: \"Bid in account currency\" },\n \"daily-budget\": { type: \"string\", description: \"Daily budget in account currency\" },\n \"total-budget\": { type: \"string\", description: \"Lifetime budget in account currency\" },\n \"start-time\": { type: \"string\", description: \"ISO 8601 start\" },\n \"end-time\": { type: \"string\", description: \"ISO 8601 end\" },\n },\n run: async ({ args }) => {\n const accountId = await stageAccountId(args);\n await stageXOp({\n kind: \"lineItem.update\",\n accountId,\n target: requireTarget(args, \"id\"),\n payload: compact({\n name: args.name,\n entityStatus: args.status,\n placements: csvArg(args.placements),\n bidStrategy: args[\"bid-strategy\"],\n bidAmountLocalMicro: microsFromArg(args.bid, \"--bid\"),\n dailyBudgetAmountLocalMicro: microsFromArg(args[\"daily-budget\"], \"--daily-budget\"),\n totalBudgetAmountLocalMicro: microsFromArg(args[\"total-budget\"], \"--total-budget\"),\n startTime: args[\"start-time\"],\n endTime: args[\"end-time\"],\n }),\n });\n },\n});\n\nfunction statusCommand(name: \"pause\" | \"resume\", status: \"PAUSED\" | \"ACTIVE\") {\n registerSchema({\n command: `ads.x.lineItems.${name}`,\n description: `Stage ${name === \"pause\" ? \"a pause\" : \"a resume\"} for one or more X ad groups. Pass every id in one call.`,\n args: {\n ids: { type: \"string\", description: \"Ad group ids, comma-separated\", required: true },\n \"account-id\": { type: \"string\", description: \"X Ads account ID\", required: false },\n },\n });\n return defineCommand({\n meta: {\n name,\n description: `Stage ${name === \"pause\" ? \"pausing\" : \"resuming\"} ad groups.\n\nExample:\n baker ads x line-items ${name} wiee9,wo2sr`,\n },\n args: {\n ids: { type: \"positional\", description: \"Ad group ids, comma-separated\", required: true },\n \"account-id\": { type: \"string\", description: \"X Ads account ID\" },\n },\n run: async ({ args }) => {\n const accountId = await stageAccountId(args);\n await stageXOps(\n requireTargets(args, \"ids\").map((id) => ({\n kind: \"lineItem.update\",\n accountId,\n target: id,\n payload: { entityStatus: status },\n })),\n );\n },\n });\n}\n\nexport const lineItemsPauseCommand = statusCommand(\"pause\", \"PAUSED\");\nexport const lineItemsResumeCommand = statusCommand(\"resume\", \"ACTIVE\");\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/commands/ads/x/line-item-writes.ts"],"sourcesContent":["import { OBJECTIVES, PLACEMENTS, PRODUCT_TYPES } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { registerSchema } from \"../../../schemas.ts\";\nimport {\n compact,\n csvArg,\n microsFromArg,\n requireTarget,\n requireTargets,\n stageAccountId,\n stageXOp,\n stageXOps,\n} from \"./write-shared.ts\";\n\n/**\n * Staged ad-group (line item) writes. X calls them line items; X Ads Manager\n * and every marketer call them ad groups, so the help does too.\n */\n\nregisterSchema({\n command: \"ads.x.lineItems.create\",\n description: `Stage a new X ad group under a campaign. Objective, product type and campaign are fixed at create — X refuses to change any of them afterwards, so get them right here.\nObjectives: ${OBJECTIVES.join(\", \")}.`,\n args: {\n \"account-id\": { type: \"string\", description: \"X Ads account ID\", required: false },\n \"campaign-id\": {\n type: \"string\",\n description: \"Parent campaign id, or an x_temp_* ref staged in this draft\",\n required: true,\n },\n name: { type: \"string\", description: \"Ad group name\", required: true },\n objective: { type: \"string\", description: OBJECTIVES.join(\" | \"), required: true },\n \"product-type\": { type: \"string\", description: PRODUCT_TYPES.join(\" | \"), required: false },\n placements: { type: \"string\", description: `CSV of ${PLACEMENTS.join(\", \")}`, required: false },\n status: { type: \"string\", description: \"ACTIVE | PAUSED | DRAFT (default PAUSED)\", required: false },\n \"bid-strategy\": { type: \"string\", description: \"AUTO | MAX | TARGET\", required: false },\n bid: {\n type: \"string\",\n description: \"Bid in account currency — required for MAX/TARGET, refused for AUTO\",\n required: false,\n },\n \"daily-budget\": { type: \"string\", description: \"Daily budget in account currency\", required: false },\n \"total-budget\": { type: \"string\", description: \"Lifetime budget in account currency\", required: false },\n \"start-time\": { type: \"string\", description: \"ISO 8601 start\", required: false },\n \"end-time\": { type: \"string\", description: \"ISO 8601 end\", required: false },\n },\n});\n\nexport const lineItemsCreateCommand = defineCommand({\n meta: {\n name: \"create\",\n description: `Stage a new ad group (applies when the chat is published).\n\nExamples:\n baker ads x line-items create --campaign-id oilf0 --name \"Spain\" --objective WEBSITE_CLICKS\n baker ads x line-items create --campaign-id x_temp_abc --name \"Spain\" --objective REACH --bid-strategy MAX --bid 1.20`,\n },\n args: {\n \"account-id\": { type: \"string\", description: \"X Ads account ID\" },\n \"campaign-id\": { type: \"string\", description: \"Parent campaign id or x_temp_* ref\", required: true },\n name: { type: \"string\", description: \"Ad group name\", required: true },\n objective: { type: \"string\", description: OBJECTIVES.join(\" | \"), required: true },\n \"product-type\": { type: \"string\", description: PRODUCT_TYPES.join(\" | \") },\n placements: { type: \"string\", description: `CSV of ${PLACEMENTS.join(\", \")}` },\n status: { type: \"string\", description: \"ACTIVE | PAUSED | DRAFT (default PAUSED)\" },\n \"bid-strategy\": { type: \"string\", description: \"AUTO | MAX | TARGET\" },\n bid: { type: \"string\", description: \"Bid in account currency\" },\n \"daily-budget\": { type: \"string\", description: \"Daily budget in account currency\" },\n \"total-budget\": { type: \"string\", description: \"Lifetime budget in account currency\" },\n \"start-time\": { type: \"string\", description: \"ISO 8601 start\" },\n \"end-time\": { type: \"string\", description: \"ISO 8601 end\" },\n },\n run: async ({ args }) => {\n const accountId = await stageAccountId(args);\n await stageXOp({\n kind: \"lineItem.create\",\n accountId,\n payload: compact({\n campaignId: args[\"campaign-id\"],\n name: args.name,\n objective: args.objective,\n productType: args[\"product-type\"],\n placements: csvArg(args.placements),\n entityStatus: args.status,\n bidStrategy: args[\"bid-strategy\"],\n bidAmountLocalMicro: microsFromArg(args.bid, \"--bid\"),\n dailyBudgetAmountLocalMicro: microsFromArg(args[\"daily-budget\"], \"--daily-budget\"),\n totalBudgetAmountLocalMicro: microsFromArg(args[\"total-budget\"], \"--total-budget\"),\n startTime: args[\"start-time\"],\n endTime: args[\"end-time\"],\n }),\n });\n },\n});\n\nregisterSchema({\n command: \"ads.x.lineItems.update\",\n description:\n \"Stage a change to an existing X ad group. Objective, product type and campaign are absent on purpose — X treats all three as immutable after create.\",\n args: {\n id: { type: \"string\", description: \"Ad group id\", required: true },\n \"account-id\": { type: \"string\", description: \"X Ads account ID\", required: false },\n name: { type: \"string\", description: \"New name\", required: false },\n status: { type: \"string\", description: \"ACTIVE | PAUSED\", required: false },\n placements: { type: \"string\", description: \"CSV of placements\", required: false },\n \"bid-strategy\": { type: \"string\", description: \"AUTO | MAX | TARGET\", required: false },\n bid: { type: \"string\", description: \"Bid in account currency\", required: false },\n \"daily-budget\": { type: \"string\", description: \"Daily budget in account currency\", required: false },\n \"total-budget\": { type: \"string\", description: \"Lifetime budget in account currency\", required: false },\n \"start-time\": { type: \"string\", description: \"ISO 8601 start\", required: false },\n \"end-time\": { type: \"string\", description: \"ISO 8601 end\", required: false },\n },\n});\n\nexport const lineItemsUpdateCommand = defineCommand({\n meta: {\n name: \"update\",\n description: `Stage a change to an ad group.\n\nExamples:\n baker ads x line-items update wiee9 --bid 1.50\n baker ads x line-items update wiee9 --end-time 2026-12-31T00:00:00Z`,\n },\n args: {\n id: { type: \"positional\", description: \"Ad group id\", required: true },\n \"account-id\": { type: \"string\", description: \"X Ads account ID\" },\n name: { type: \"string\", description: \"New name\" },\n status: { type: \"string\", description: \"ACTIVE | PAUSED\" },\n placements: { type: \"string\", description: \"CSV of placements\" },\n \"bid-strategy\": { type: \"string\", description: \"AUTO | MAX | TARGET\" },\n bid: { type: \"string\", description: \"Bid in account currency\" },\n \"daily-budget\": { type: \"string\", description: \"Daily budget in account currency\" },\n \"total-budget\": { type: \"string\", description: \"Lifetime budget in account currency\" },\n \"start-time\": { type: \"string\", description: \"ISO 8601 start\" },\n \"end-time\": { type: \"string\", description: \"ISO 8601 end\" },\n },\n run: async ({ args }) => {\n const accountId = await stageAccountId(args);\n await stageXOp({\n kind: \"lineItem.update\",\n accountId,\n target: requireTarget(args, \"id\"),\n payload: compact({\n name: args.name,\n entityStatus: args.status,\n placements: csvArg(args.placements),\n bidStrategy: args[\"bid-strategy\"],\n bidAmountLocalMicro: microsFromArg(args.bid, \"--bid\"),\n dailyBudgetAmountLocalMicro: microsFromArg(args[\"daily-budget\"], \"--daily-budget\"),\n totalBudgetAmountLocalMicro: microsFromArg(args[\"total-budget\"], \"--total-budget\"),\n startTime: args[\"start-time\"],\n endTime: args[\"end-time\"],\n }),\n });\n },\n});\n\nfunction statusCommand(name: \"pause\" | \"resume\", status: \"PAUSED\" | \"ACTIVE\") {\n registerSchema({\n command: `ads.x.lineItems.${name}`,\n description: `Stage ${name === \"pause\" ? \"a pause\" : \"a resume\"} for one or more X ad groups. Pass every id in one call.`,\n args: {\n ids: { type: \"string\", description: \"Ad group ids, comma-separated\", required: true },\n \"account-id\": { type: \"string\", description: \"X Ads account ID\", required: false },\n },\n });\n return defineCommand({\n meta: {\n name,\n description: `Stage ${name === \"pause\" ? \"pausing\" : \"resuming\"} ad groups.\n\nExample:\n baker ads x line-items ${name} wiee9,wo2sr`,\n },\n args: {\n ids: { type: \"positional\", description: \"Ad group ids, comma-separated\", required: true },\n \"account-id\": { type: \"string\", description: \"X Ads account ID\" },\n },\n run: async ({ args }) => {\n const accountId = await stageAccountId(args);\n await stageXOps(\n requireTargets(args, \"ids\").map((id) => ({\n kind: \"lineItem.update\",\n accountId,\n target: id,\n payload: { entityStatus: status },\n })),\n );\n },\n });\n}\n\nexport const lineItemsPauseCommand = statusCommand(\"pause\", \"PAUSED\");\nexport const lineItemsResumeCommand = statusCommand(\"resume\", \"ACTIVE\");\n"],"mappings":"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","names":[]}
@@ -82,10 +82,10 @@ Examples:
82
82
  },
83
83
  subCommands: {
84
84
  list: lineItemsListCommand,
85
- create: () => import("./line-item-writes-EMYSOJKM.js").then((m) => m.lineItemsCreateCommand),
86
- update: () => import("./line-item-writes-EMYSOJKM.js").then((m) => m.lineItemsUpdateCommand),
87
- pause: () => import("./line-item-writes-EMYSOJKM.js").then((m) => m.lineItemsPauseCommand),
88
- resume: () => import("./line-item-writes-EMYSOJKM.js").then((m) => m.lineItemsResumeCommand)
85
+ create: () => import("./line-item-writes-E6MZPIZZ.js").then((m) => m.lineItemsCreateCommand),
86
+ update: () => import("./line-item-writes-E6MZPIZZ.js").then((m) => m.lineItemsUpdateCommand),
87
+ pause: () => import("./line-item-writes-E6MZPIZZ.js").then((m) => m.lineItemsPauseCommand),
88
+ resume: () => import("./line-item-writes-E6MZPIZZ.js").then((m) => m.lineItemsResumeCommand)
89
89
  },
90
90
  args: {
91
91
  "account-id": { type: "string", description: "X Ads account ID" },
@@ -100,4 +100,4 @@ Examples:
100
100
  export {
101
101
  lineItemsCommand
102
102
  };
103
- //# sourceMappingURL=line-items-5NECXUZT.js.map
103
+ //# sourceMappingURL=line-items-7ZGIKEF2.js.map
@@ -2,12 +2,11 @@ import {
2
2
  failApi,
3
3
  failValidation,
4
4
  writeOk
5
- } from "./chunk-SJYEY5MV.js";
6
- import "./chunk-7EPXVICM.js";
5
+ } from "./chunk-3HJLHTWP.js";
6
+ import "./chunk-XF4JUKVF.js";
7
7
  import "./chunk-GXDLWBOY.js";
8
8
  import "./chunk-TEINLN64.js";
9
9
  import "./chunk-ZJWUBJYQ.js";
10
- import "./chunk-HR6IWNKE.js";
11
10
  import "./chunk-NE4F3FHN.js";
12
11
  import {
13
12
  apiPost
@@ -62,4 +61,4 @@ var linkCommand = defineCommand({
62
61
  export {
63
62
  linkCommand
64
63
  };
65
- //# sourceMappingURL=link-CI45HWFN.js.map
64
+ //# sourceMappingURL=link-QYAW6A2W.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/actions/link.ts"],"sourcesContent":["import type { ActionsLinkResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { requireChatId } from \"../../env.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi, failValidation, writeOk } from \"./shared.ts\";\n\nregisterSchema({\n command: \"actions.link\",\n description:\n \"Stage a 'blocker -> blocked' dependency. Refs can be either action IDs or tempIds from create ops in the same draft.\",\n args: {\n blocker: { type: \"string\", description: \"Blocker action ID or tempId\", required: true },\n blocked: { type: \"string\", description: \"Blocked action ID or tempId\", required: true },\n },\n});\n\nexport const linkCommand = defineCommand({\n meta: {\n name: \"link\",\n description: \"Stage a dependency link. Example: baker actions link --blocker <id> --blocked <id>\",\n },\n args: {\n blocker: { type: \"string\", description: \"Blocker ref\", required: false },\n blocked: { type: \"string\", description: \"Blocked ref\", required: false },\n },\n run: async ({ args }) => {\n try {\n const blocker = args.blocker as string | undefined;\n const blocked = args.blocked as string | undefined;\n if (!blocker || !blocked) {\n failValidation(\"--blocker and --blocked are required.\");\n }\n const chatId = requireChatId();\n await apiPost<ActionsLinkResponse>(\"/api/actions/link\", {\n chatId,\n blockerRef: blocker,\n blockedRef: blocked,\n });\n writeOk();\n } catch (err) {\n failApi(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,qBAAqB;AAM9B,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,UAAU,aAAa,+BAA+B,UAAU,KAAK;AAAA,IACtF,SAAS,EAAE,MAAM,UAAU,aAAa,+BAA+B,UAAU,KAAK;AAAA,EACxF;AACF,CAAC;AAEM,IAAM,cAAc,cAAc;AAAA,EACvC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,UAAU,aAAa,eAAe,UAAU,MAAM;AAAA,IACvE,SAAS,EAAE,MAAM,UAAU,aAAa,eAAe,UAAU,MAAM;AAAA,EACzE;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,QAAI;AACF,YAAM,UAAU,KAAK;AACrB,YAAM,UAAU,KAAK;AACrB,UAAI,CAAC,WAAW,CAAC,SAAS;AACxB,uBAAe,uCAAuC;AAAA,MACxD;AACA,YAAM,SAAS,cAAc;AAC7B,YAAM,QAA6B,qBAAqB;AAAA,QACtD;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA,MACd,CAAC;AACD,cAAQ;AAAA,IACV,SAAS,KAAK;AACZ,cAAQ,GAAG;AAAA,IACb;AAAA,EACF;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/commands/actions/link.ts"],"sourcesContent":["import type { ActionsLinkResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { requireChatId } from \"../../env.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi, failValidation, writeOk } from \"./shared.ts\";\n\nregisterSchema({\n command: \"actions.link\",\n description:\n \"Stage a 'blocker -> blocked' dependency. Refs can be either action IDs or tempIds from create ops in the same draft.\",\n args: {\n blocker: { type: \"string\", description: \"Blocker action ID or tempId\", required: true },\n blocked: { type: \"string\", description: \"Blocked action ID or tempId\", required: true },\n },\n});\n\nexport const linkCommand = defineCommand({\n meta: {\n name: \"link\",\n description: \"Stage a dependency link. Example: baker actions link --blocker <id> --blocked <id>\",\n },\n args: {\n blocker: { type: \"string\", description: \"Blocker ref\", required: false },\n blocked: { type: \"string\", description: \"Blocked ref\", required: false },\n },\n run: async ({ args }) => {\n try {\n const blocker = args.blocker as string | undefined;\n const blocked = args.blocked as string | undefined;\n if (!blocker || !blocked) {\n failValidation(\"--blocker and --blocked are required.\");\n }\n const chatId = requireChatId();\n await apiPost<ActionsLinkResponse>(\"/api/actions/link\", {\n chatId,\n blockerRef: blocker,\n blockedRef: blocked,\n });\n writeOk();\n } catch (err) {\n failApi(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,qBAAqB;AAM9B,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,UAAU,aAAa,+BAA+B,UAAU,KAAK;AAAA,IACtF,SAAS,EAAE,MAAM,UAAU,aAAa,+BAA+B,UAAU,KAAK;AAAA,EACxF;AACF,CAAC;AAEM,IAAM,cAAc,cAAc;AAAA,EACvC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,UAAU,aAAa,eAAe,UAAU,MAAM;AAAA,IACvE,SAAS,EAAE,MAAM,UAAU,aAAa,eAAe,UAAU,MAAM;AAAA,EACzE;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,QAAI;AACF,YAAM,UAAU,KAAK;AACrB,YAAM,UAAU,KAAK;AACrB,UAAI,CAAC,WAAW,CAAC,SAAS;AACxB,uBAAe,uCAAuC;AAAA,MACxD;AACA,YAAM,SAAS,cAAc;AAC7B,YAAM,QAA6B,qBAAqB;AAAA,QACtD;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA,MACd,CAAC;AACD,cAAQ;AAAA,IACV,SAAS,KAAK;AACZ,cAAQ,GAAG;AAAA,IACb;AAAA,EACF;AACF,CAAC;","names":[]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  TOTAL_BUDGET_HELP
3
- } from "./chunk-NA63BH7V.js";
3
+ } from "./chunk-4AUMTNVB.js";
4
4
  import {
5
5
  statusesArgDescription
6
- } from "./chunk-N4LAYIIN.js";
6
+ } from "./chunk-CSYSX4D2.js";
7
7
  import "./chunk-T4DD5YMP.js";
8
8
  import "./chunk-4NZ47VXO.js";
9
9
  import "./chunk-D5FY4FAK.js";
@@ -24,11 +24,10 @@ import "./chunk-YBMVHGY3.js";
24
24
  import {
25
25
  CHAT_READ_ARG
26
26
  } from "./chunk-PFBQERWX.js";
27
- import "./chunk-7EPXVICM.js";
27
+ import "./chunk-XF4JUKVF.js";
28
28
  import "./chunk-GXDLWBOY.js";
29
29
  import "./chunk-TEINLN64.js";
30
30
  import "./chunk-ZJWUBJYQ.js";
31
- import "./chunk-HR6IWNKE.js";
32
31
  import "./chunk-NE4F3FHN.js";
33
32
  import "./chunk-XBOK23HI.js";
34
33
  import "./chunk-IFWP3ZDO.js";
@@ -979,31 +978,31 @@ Account ID format:
979
978
  Full guide: __tooling__/docs/tools/baker/ads-linkedin.md`
980
979
  },
981
980
  subCommands: {
982
- accounts: () => import("./accounts-722UY53A.js").then((m) => m.accountsCommand),
983
- account: () => import("./account-XQXC7BR6.js").then((m) => m.accountCommand),
984
- "campaign-groups": () => import("./campaign-groups-PQ6KSQJR.js").then((m) => m.campaignGroupsCommand),
985
- campaigns: () => import("./campaigns-6T3NSUT2.js").then((m) => m.campaignsCommand),
986
- creatives: () => import("./creatives-KGXUOYPE.js").then((m) => m.creativesCommand),
987
- audiences: () => import("./write-commands-7SJ3BOW5.js").then((m) => m.audiencesCommand),
988
- "lead-forms": () => import("./write-commands-7SJ3BOW5.js").then((m) => m.leadFormsCommand),
989
- draft: () => import("./draft-Q546QPPU.js").then((m) => m.linkedinDraftCommand),
990
- analytics: () => import("./analytics-OH5QEH7F.js").then((m) => m.analyticsCommand),
991
- demographics: () => import("./demographics-XV5PBA77.js").then((m) => m.demographicsCommand),
992
- companies: () => import("./companies-TS6KBATJ.js").then((m) => m.companiesCommand),
993
- "top-companies": () => import("./top-companies-PGIAEHDF.js").then((m) => m.topCompaniesCommand),
994
- resolve: () => import("./resolve-OGX7C4TV.js").then((m) => m.resolveCommand),
995
- facets: () => import("./facets-7EVPJMKS.js").then((m) => m.facetsCommand),
996
- "audience-size": () => import("./audience-size-LRI6GJRT.js").then((m) => m.audienceSizeCommand),
997
- "bid-pricing": () => import("./bid-pricing-EO5WLHGV.js").then((m) => m.bidPricingCommand),
998
- forecast: () => import("./forecast-3QTJYVND.js").then((m) => m.forecastCommand),
999
- leads: () => import("./leads-A4W5KTWB.js").then((m) => m.leadsCommand),
1000
- conversions: () => import("./conversions-UHB55MMQ.js").then((m) => m.conversionsCommand),
1001
- conversation: () => import("./conversation-6ZJGPCXM.js").then((m) => m.conversationCommand),
1002
- audit: () => import("./audit-HWP7OPB7.js").then((m) => m.auditCommand),
1003
- "url-params": () => import("./url-params-7U2XMOWF.js").then((m) => m.urlParamsCommand)
981
+ accounts: () => import("./accounts-HAFCLSR5.js").then((m) => m.accountsCommand),
982
+ account: () => import("./account-AL2ZDSR7.js").then((m) => m.accountCommand),
983
+ "campaign-groups": () => import("./campaign-groups-KFFYQPU3.js").then((m) => m.campaignGroupsCommand),
984
+ campaigns: () => import("./campaigns-2NHWBF5C.js").then((m) => m.campaignsCommand),
985
+ creatives: () => import("./creatives-JSWBFQ5R.js").then((m) => m.creativesCommand),
986
+ audiences: () => import("./write-commands-5C7FUOVN.js").then((m) => m.audiencesCommand),
987
+ "lead-forms": () => import("./write-commands-5C7FUOVN.js").then((m) => m.leadFormsCommand),
988
+ draft: () => import("./draft-EJXNNJ3Y.js").then((m) => m.linkedinDraftCommand),
989
+ analytics: () => import("./analytics-FPWQQGRM.js").then((m) => m.analyticsCommand),
990
+ demographics: () => import("./demographics-NTWB2IMG.js").then((m) => m.demographicsCommand),
991
+ companies: () => import("./companies-DNI634RC.js").then((m) => m.companiesCommand),
992
+ "top-companies": () => import("./top-companies-45X3DT7Z.js").then((m) => m.topCompaniesCommand),
993
+ resolve: () => import("./resolve-XYH2GDAE.js").then((m) => m.resolveCommand),
994
+ facets: () => import("./facets-U7AQC4H6.js").then((m) => m.facetsCommand),
995
+ "audience-size": () => import("./audience-size-GNBJY35X.js").then((m) => m.audienceSizeCommand),
996
+ "bid-pricing": () => import("./bid-pricing-Q72B65AY.js").then((m) => m.bidPricingCommand),
997
+ forecast: () => import("./forecast-GNODEIIC.js").then((m) => m.forecastCommand),
998
+ leads: () => import("./leads-PHKG6CP3.js").then((m) => m.leadsCommand),
999
+ conversions: () => import("./conversions-4SRZPBBX.js").then((m) => m.conversionsCommand),
1000
+ conversation: () => import("./conversation-6IOGV7B7.js").then((m) => m.conversationCommand),
1001
+ audit: () => import("./audit-3VS63TBW.js").then((m) => m.auditCommand),
1002
+ "url-params": () => import("./url-params-3EFGVTZZ.js").then((m) => m.urlParamsCommand)
1004
1003
  }
1005
1004
  });
1006
1005
  export {
1007
1006
  linkedinCommand
1008
1007
  };
1009
- //# sourceMappingURL=linkedin-B7SYR75X.js.map
1008
+ //# sourceMappingURL=linkedin-FFSDSGGS.js.map