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

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 +11 -6
  2. package/dist/{account-AL2ZDSR7.js → account-XQXC7BR6.js} +5 -4
  3. package/dist/{account-AL2ZDSR7.js.map → account-XQXC7BR6.js.map} +1 -1
  4. package/dist/{accounts-HAFCLSR5.js → accounts-722UY53A.js} +4 -3
  5. package/dist/{accounts-HAFCLSR5.js.map → accounts-722UY53A.js.map} +1 -1
  6. package/dist/{accounts-O5MFO3QQ.js → accounts-E67BMK7T.js} +6 -5
  7. package/dist/{accounts-O5MFO3QQ.js.map → accounts-E67BMK7T.js.map} +1 -1
  8. package/dist/{actions-P35MEMGN.js → actions-6TQMSVWD.js} +18 -18
  9. package/dist/{add-5GAN6CVO.js → add-2BEGRHUX.js} +28 -5
  10. package/dist/add-2BEGRHUX.js.map +1 -0
  11. package/dist/{add-6DTC6X5G.js → add-LEMKEOPO.js} +3 -2
  12. package/dist/{add-6DTC6X5G.js.map → add-LEMKEOPO.js.map} +1 -1
  13. package/dist/{ads-73PGA4YC.js → ads-AGYCVD62.js} +4 -4
  14. package/dist/{advertisers-AE75CGVE.js → advertisers-2VQKAYKG.js} +4 -3
  15. package/dist/{advertisers-AE75CGVE.js.map → advertisers-2VQKAYKG.js.map} +1 -1
  16. package/dist/{analytics-FKCXIMPO.js → analytics-IFELDWLL.js} +24 -20
  17. package/dist/analytics-IFELDWLL.js.map +1 -0
  18. package/dist/{analytics-FPWQQGRM.js → analytics-OH5QEH7F.js} +4 -3
  19. package/dist/{analytics-FPWQQGRM.js.map → analytics-OH5QEH7F.js.map} +1 -1
  20. package/dist/{assign-ABN2AQ4J.js → assign-PTUJUCEL.js} +4 -3
  21. package/dist/{assign-ABN2AQ4J.js.map → assign-PTUJUCEL.js.map} +1 -1
  22. package/dist/{audience-size-GNBJY35X.js → audience-size-LRI6GJRT.js} +4 -3
  23. package/dist/{audience-size-GNBJY35X.js.map → audience-size-LRI6GJRT.js.map} +1 -1
  24. package/dist/{audit-3VS63TBW.js → audit-HWP7OPB7.js} +4 -3
  25. package/dist/{audit-3VS63TBW.js.map → audit-HWP7OPB7.js.map} +1 -1
  26. package/dist/{autocomplete-VS3XG3B7.js → autocomplete-J6DHU6MR.js} +4 -3
  27. package/dist/{autocomplete-VS3XG3B7.js.map → autocomplete-J6DHU6MR.js.map} +1 -1
  28. package/dist/{avatars-EKCKHCC3.js → avatars-467OSBD6.js} +4 -4
  29. package/dist/{bid-pricing-Q72B65AY.js → bid-pricing-EO5WLHGV.js} +4 -3
  30. package/dist/{bid-pricing-Q72B65AY.js.map → bid-pricing-EO5WLHGV.js.map} +1 -1
  31. package/dist/{brand-C6PFGGQN.js → brand-YRTEPGBK.js} +2 -2
  32. package/dist/{brief-YFJHQ5VQ.js → brief-OSFJ2V7F.js} +8 -7
  33. package/dist/{brief-YFJHQ5VQ.js.map → brief-OSFJ2V7F.js.map} +1 -1
  34. package/dist/{campaign-groups-KFFYQPU3.js → campaign-groups-PQ6KSQJR.js} +9 -8
  35. package/dist/{campaign-groups-KFFYQPU3.js.map → campaign-groups-PQ6KSQJR.js.map} +1 -1
  36. package/dist/{campaign-writes-FHOS5XZY.js → campaign-writes-5OVLUD5E.js} +4 -3
  37. package/dist/{campaign-writes-FHOS5XZY.js.map → campaign-writes-5OVLUD5E.js.map} +1 -1
  38. package/dist/{campaigns-2NHWBF5C.js → campaigns-6T3NSUT2.js} +12 -11
  39. package/dist/{campaigns-2NHWBF5C.js.map → campaigns-6T3NSUT2.js.map} +1 -1
  40. package/dist/{campaigns-KZYZTXDS.js → campaigns-OYMXDGWX.js} +5 -5
  41. package/dist/{canvas-UJNSHD3B.js → canvas-YQFG52IG.js} +13 -13
  42. package/dist/{capabilities-DJFTRJKS.js → capabilities-PXBKUN2G.js} +4 -3
  43. package/dist/{capabilities-DJFTRJKS.js.map → capabilities-PXBKUN2G.js.map} +1 -1
  44. package/dist/{catalog-ZQX6BGXS.js → catalog-XLXIM7IW.js} +4 -4
  45. package/dist/{chats-D2CSDX5Q.js → chats-UK47UE7C.js} +4 -3
  46. package/dist/{chats-D2CSDX5Q.js.map → chats-UK47UE7C.js.map} +1 -1
  47. package/dist/{chunk-7YCRFMXF.js → chunk-24EB7EDR.js} +3 -3
  48. package/dist/{chunk-5ZDLTE5T.js → chunk-2AOE2MZQ.js} +3 -3
  49. package/dist/{chunk-4SG4RW2P.js → chunk-2VPBIT65.js} +8 -8
  50. package/dist/chunk-4PDHHHUJ.js +537 -0
  51. package/dist/chunk-4PDHHHUJ.js.map +1 -0
  52. package/dist/{chunk-NPY4QUMQ.js → chunk-54C6YDGJ.js} +2 -2
  53. package/dist/{chunk-LZ73CZGP.js → chunk-5WCSKQ7Z.js} +6 -6
  54. package/dist/{chunk-3G3ZDLMI.js → chunk-5ZNTADVR.js} +2 -2
  55. package/dist/{chunk-AEOSAVVL.js → chunk-6F7DVPOS.js} +3 -3
  56. package/dist/{chunk-CJCVIEJ5.js → chunk-6NY2GPR4.js} +3 -3
  57. package/dist/{chunk-CXWFX2AM.js → chunk-6Y7ZBENQ.js} +6 -6
  58. package/dist/{chunk-M242LHLX.js → chunk-7CTMH5AK.js} +3 -3
  59. package/dist/{chunk-XF4JUKVF.js → chunk-7EPXVICM.js} +38 -5
  60. package/dist/chunk-7EPXVICM.js.map +1 -0
  61. package/dist/{chunk-T2PC5AVH.js → chunk-ASI4P6X2.js} +6 -6
  62. package/dist/chunk-ASI4P6X2.js.map +1 -0
  63. package/dist/{chunk-QD7ESRLN.js → chunk-C46GUI2S.js} +2 -2
  64. package/dist/{chunk-6N6WKAJM.js → chunk-CWYAELVG.js} +2 -2
  65. package/dist/{chunk-MXYBTMKB.js → chunk-DCRPXOJJ.js} +2 -2
  66. package/dist/{chunk-GKZ2WU75.js → chunk-FPOGPFAG.js} +3 -14
  67. package/dist/chunk-FPOGPFAG.js.map +1 -0
  68. package/dist/{chunk-JQJDXPCO.js → chunk-FUHN4MFY.js} +2 -2
  69. package/dist/{chunk-S77PZVYM.js → chunk-FYGR3I2A.js} +3 -3
  70. package/dist/{chunk-OZRUJVIQ.js → chunk-H3427GPU.js} +2 -2
  71. package/dist/{chunk-RPUSTYHL.js → chunk-HDLYPC6K.js} +5 -3
  72. package/dist/{chunk-RPUSTYHL.js.map → chunk-HDLYPC6K.js.map} +1 -1
  73. package/dist/{chunk-SSJK7FEV.js → chunk-HR6IWNKE.js} +1196 -1140
  74. package/dist/chunk-HR6IWNKE.js.map +1 -0
  75. package/dist/{chunk-YRQYA2LR.js → chunk-HROZYQ5H.js} +63 -5
  76. package/dist/chunk-HROZYQ5H.js.map +1 -0
  77. package/dist/{chunk-IR6D7K4H.js → chunk-I3ZR655O.js} +2 -2
  78. package/dist/{chunk-YK32GUBN.js → chunk-KMKEYI37.js} +3 -3
  79. package/dist/{chunk-W3ZHJJVT.js → chunk-KS2QY6MK.js} +4 -4
  80. package/dist/{chunk-WNRV4QH7.js → chunk-LYQJ4PZW.js} +5 -5
  81. package/dist/{chunk-B5SCU7MJ.js → chunk-MACCF4JZ.js} +16 -22
  82. package/dist/{chunk-B5SCU7MJ.js.map → chunk-MACCF4JZ.js.map} +1 -1
  83. package/dist/{chunk-CSYSX4D2.js → chunk-N4LAYIIN.js} +2 -2
  84. package/dist/{chunk-4AUMTNVB.js → chunk-NA63BH7V.js} +3 -3
  85. package/dist/{chunk-4BQXAE7Z.js → chunk-NDEE6G2J.js} +2 -2
  86. package/dist/{chunk-EDLZGTGN.js → chunk-NYIGXDUG.js} +1 -39
  87. package/dist/chunk-NYIGXDUG.js.map +1 -0
  88. package/dist/{chunk-DWHIOO7E.js → chunk-QE7W555R.js} +163 -12
  89. package/dist/chunk-QE7W555R.js.map +1 -0
  90. package/dist/{chunk-MELOSESI.js → chunk-R25YLW6H.js} +2 -2
  91. package/dist/{chunk-Y6O7EWYY.js → chunk-RL5CP7N6.js} +5 -5
  92. package/dist/{chunk-DGUNI37S.js → chunk-RX2DKU3W.js} +2 -2
  93. package/dist/{chunk-3HJLHTWP.js → chunk-SJYEY5MV.js} +12 -3
  94. package/dist/{chunk-3HJLHTWP.js.map → chunk-SJYEY5MV.js.map} +1 -1
  95. package/dist/{chunk-VTDMKARH.js → chunk-ULG4QRTV.js} +2 -2
  96. package/dist/{chunk-QRP3PXWN.js → chunk-VL43TNIP.js} +2 -2
  97. package/dist/{chunk-SHL7LOC3.js → chunk-VLMBTPXU.js} +3 -3
  98. package/dist/{chunk-KHRXPQID.js → chunk-VYQ3QJ3C.js} +2 -2
  99. package/dist/{chunk-A4LOJ2VD.js → chunk-WGUQHAJY.js} +2 -2
  100. package/dist/{chunk-ZEYEWPK6.js → chunk-WKQG6TER.js} +2 -2
  101. package/dist/{chunk-3IBYKLXR.js → chunk-ZDMTXQ2Q.js} +2 -2
  102. package/dist/{claim-FZ5OQLMU.js → claim-W6G6VEG5.js} +4 -3
  103. package/dist/{claim-FZ5OQLMU.js.map → claim-W6G6VEG5.js.map} +1 -1
  104. package/dist/cli.js +30 -30
  105. package/dist/{companies-DNI634RC.js → companies-TS6KBATJ.js} +4 -3
  106. package/dist/{companies-DNI634RC.js.map → companies-TS6KBATJ.js.map} +1 -1
  107. package/dist/{complete-2FZMGJV5.js → complete-LYR2HMQU.js} +4 -3
  108. package/dist/{complete-2FZMGJV5.js.map → complete-LYR2HMQU.js.map} +1 -1
  109. package/dist/{connect-QCOGEPP4.js → connect-FCXNVTXG.js} +13 -6
  110. package/dist/{conversation-6IOGV7B7.js → conversation-6ZJGPCXM.js} +4 -3
  111. package/dist/{conversation-6IOGV7B7.js.map → conversation-6ZJGPCXM.js.map} +1 -1
  112. package/dist/{conversions-4SRZPBBX.js → conversions-UHB55MMQ.js} +8 -7
  113. package/dist/{conversions-4SRZPBBX.js.map → conversions-UHB55MMQ.js.map} +1 -1
  114. package/dist/{create-BJNMO6HT.js → create-EX6OWLNM.js} +3 -2
  115. package/dist/{create-BJNMO6HT.js.map → create-EX6OWLNM.js.map} +1 -1
  116. package/dist/{create-RM7HV77Y.js → create-JCA7JPLP.js} +4 -3
  117. package/dist/{create-RM7HV77Y.js.map → create-JCA7JPLP.js.map} +1 -1
  118. package/dist/{create-FX4OJ2XF.js → create-JFSK4BOP.js} +4 -3
  119. package/dist/{create-FX4OJ2XF.js.map → create-JFSK4BOP.js.map} +1 -1
  120. package/dist/{create-VXM34ZWH.js → create-WU22YYU2.js} +4 -3
  121. package/dist/{create-VXM34ZWH.js.map → create-WU22YYU2.js.map} +1 -1
  122. package/dist/{creatives-NJF2U763.js → creatives-FXUQ5WSD.js} +10 -10
  123. package/dist/{creatives-JSWBFQ5R.js → creatives-KGXUOYPE.js} +9 -8
  124. package/dist/{creatives-JSWBFQ5R.js.map → creatives-KGXUOYPE.js.map} +1 -1
  125. package/dist/{credentials-C33K6XCJ.js → credentials-MJC7PGKR.js} +4 -3
  126. package/dist/{credentials-C33K6XCJ.js.map → credentials-MJC7PGKR.js.map} +1 -1
  127. package/dist/{critique-YDKPYZLD.js → critique-GS5VV5ZC.js} +7 -6
  128. package/dist/{critique-YDKPYZLD.js.map → critique-GS5VV5ZC.js.map} +1 -1
  129. package/dist/{critique-ZS4ON3SU.js → critique-TPHR27KH.js} +4 -3
  130. package/dist/{critique-ZS4ON3SU.js.map → critique-TPHR27KH.js.map} +1 -1
  131. package/dist/{crm-R5IXIFIV.js → crm-AVCM5D4G.js} +5 -4
  132. package/dist/{crm-R5IXIFIV.js.map → crm-AVCM5D4G.js.map} +1 -1
  133. package/dist/{crm-52ROSWH5.js → crm-VK44O3ED.js} +5 -4
  134. package/dist/{crm-52ROSWH5.js.map → crm-VK44O3ED.js.map} +1 -1
  135. package/dist/{customers-A36LOZOB.js → customers-XH2DMTFH.js} +6 -5
  136. package/dist/{delete-M2GDLPYN.js → delete-E3R3TKIL.js} +3 -2
  137. package/dist/{delete-M2GDLPYN.js.map → delete-E3R3TKIL.js.map} +1 -1
  138. package/dist/{delete-HGHXY24R.js → delete-KRH2YMSZ.js} +4 -3
  139. package/dist/{delete-HGHXY24R.js.map → delete-KRH2YMSZ.js.map} +1 -1
  140. package/dist/{delete-AIGE4Y4H.js → delete-WI5E3DR3.js} +4 -3
  141. package/dist/{delete-AIGE4Y4H.js.map → delete-WI5E3DR3.js.map} +1 -1
  142. package/dist/{demographics-NTWB2IMG.js → demographics-XV5PBA77.js} +4 -3
  143. package/dist/{demographics-NTWB2IMG.js.map → demographics-XV5PBA77.js.map} +1 -1
  144. package/dist/{discard-2WWQG6OU.js → discard-HTQUUHJR.js} +4 -3
  145. package/dist/{discard-2WWQG6OU.js.map → discard-HTQUUHJR.js.map} +1 -1
  146. package/dist/{domain-Y2LT6JLT.js → domain-RECGZXJB.js} +4 -3
  147. package/dist/{domain-Y2LT6JLT.js.map → domain-RECGZXJB.js.map} +1 -1
  148. package/dist/{draft-SLHAKJ2A.js → draft-2IBSJEKC.js} +4 -3
  149. package/dist/{draft-SLHAKJ2A.js.map → draft-2IBSJEKC.js.map} +1 -1
  150. package/dist/{draft-FJ7WHIXW.js → draft-PVTX6QT6.js} +4 -3
  151. package/dist/{draft-FJ7WHIXW.js.map → draft-PVTX6QT6.js.map} +1 -1
  152. package/dist/{draft-EJXNNJ3Y.js → draft-Q546QPPU.js} +5 -4
  153. package/dist/{draft-EJXNNJ3Y.js.map → draft-Q546QPPU.js.map} +1 -1
  154. package/dist/engine/index.js +3 -3
  155. package/dist/{facets-U7AQC4H6.js → facets-7EVPJMKS.js} +4 -3
  156. package/dist/{facets-U7AQC4H6.js.map → facets-7EVPJMKS.js.map} +1 -1
  157. package/dist/{feedback-PPQMOQ46.js → feedback-EIZKS4JU.js} +2 -2
  158. package/dist/{feedback-record-V66HWVRR.js → feedback-record-TKO54BOE.js} +9 -8
  159. package/dist/{feedback-record-V66HWVRR.js.map → feedback-record-TKO54BOE.js.map} +1 -1
  160. package/dist/{fetch-W7NULDEO.js → fetch-4BY6HYUM.js} +4 -3
  161. package/dist/{fetch-W7NULDEO.js.map → fetch-4BY6HYUM.js.map} +1 -1
  162. package/dist/{find-OTDIX6V4.js → find-FRRHAPWX.js} +4 -4
  163. package/dist/{flows-KABCBS3S.js → flows-KTFAML22.js} +21 -17
  164. package/dist/flows-KTFAML22.js.map +1 -0
  165. package/dist/{fonts-EMMX3KII.js → fonts-MXR3ZKDX.js} +6 -5
  166. package/dist/{forecast-GNODEIIC.js → forecast-3QTJYVND.js} +4 -3
  167. package/dist/{forecast-GNODEIIC.js.map → forecast-3QTJYVND.js.map} +1 -1
  168. package/dist/{funnel-AAX27NH4.js → funnel-I6XIAEHG.js} +11 -455
  169. package/dist/funnel-I6XIAEHG.js.map +1 -0
  170. package/dist/{ga4-UDQ2HA2J.js → ga4-DV2AXCSL.js} +1 -1
  171. package/dist/{get-QEYJRLV3.js → get-5PKNKJ5S.js} +7 -4
  172. package/dist/get-5PKNKJ5S.js.map +1 -0
  173. package/dist/{get-RTVUZM6E.js → get-72YPHJGV.js} +4 -3
  174. package/dist/{get-RTVUZM6E.js.map → get-72YPHJGV.js.map} +1 -1
  175. package/dist/{google-M7KEXVK5.js → google-6OGZX47I.js} +2 -2
  176. package/dist/{google-KTO3PLEU.js → google-QYYYSSXI.js} +5 -5
  177. package/dist/{google-ads-OK6IG3UV.js → google-ads-QGMQKZQD.js} +4 -3
  178. package/dist/{google-ads-OK6IG3UV.js.map → google-ads-QGMQKZQD.js.map} +1 -1
  179. package/dist/{gsc-P3QYGDV2.js → gsc-TAKOF7J5.js} +1 -1
  180. package/dist/{history-PQUJKK26.js → history-6AVQX2OQ.js} +4 -3
  181. package/dist/{history-PQUJKK26.js.map → history-6AVQX2OQ.js.map} +1 -1
  182. package/dist/{hubspot-Y77VLY6Y.js → hubspot-SVEMFK5S.js} +9 -8
  183. package/dist/{hubspot-Y77VLY6Y.js.map → hubspot-SVEMFK5S.js.map} +1 -1
  184. package/dist/{icon-I43F77FV.js → icon-L4RSS6PZ.js} +4 -4
  185. package/dist/{ideas-MIDU7YOA.js → ideas-NFOW3HKJ.js} +3 -2
  186. package/dist/{images-S254MS6O.js → images-2EFFUNNV.js} +9 -9
  187. package/dist/{ingest-YV2NLDBE.js → ingest-2EIKN4QC.js} +4 -3
  188. package/dist/{ingest-J4I3HKM3.js → ingest-2SO62RRI.js} +3 -2
  189. package/dist/{ingest-J4I3HKM3.js.map → ingest-2SO62RRI.js.map} +1 -1
  190. package/dist/{inspect-Q5NHBBHX.js → inspect-4OOS4APT.js} +4 -3
  191. package/dist/{inspect-Q5NHBBHX.js.map → inspect-4OOS4APT.js.map} +1 -1
  192. package/dist/{inspiration-P265QJ2H.js → inspiration-S3DU4CMQ.js} +1 -1
  193. package/dist/{keyword-metrics-PDY4ZXSP.js → keyword-metrics-SF4CSNZ2.js} +4 -3
  194. package/dist/{keyword-metrics-PDY4ZXSP.js.map → keyword-metrics-SF4CSNZ2.js.map} +1 -1
  195. package/dist/{keywords-for-site-GALSCV77.js → keywords-for-site-WDAOPNKC.js} +4 -3
  196. package/dist/{keywords-for-site-GALSCV77.js.map → keywords-for-site-WDAOPNKC.js.map} +1 -1
  197. package/dist/{landing-CJYGWCK4.js → landing-2ZB46LXH.js} +3 -3
  198. package/dist/{leads-PHKG6CP3.js → leads-A4W5KTWB.js} +4 -3
  199. package/dist/{leads-PHKG6CP3.js.map → leads-A4W5KTWB.js.map} +1 -1
  200. package/dist/{learn-FUQSY7DN.js → learn-IPULBCOD.js} +5 -4
  201. package/dist/{learn-FUQSY7DN.js.map → learn-IPULBCOD.js.map} +1 -1
  202. package/dist/{line-item-writes-E6MZPIZZ.js → line-item-writes-EMYSOJKM.js} +4 -3
  203. package/dist/{line-item-writes-E6MZPIZZ.js.map → line-item-writes-EMYSOJKM.js.map} +1 -1
  204. package/dist/{line-items-7ZGIKEF2.js → line-items-5NECXUZT.js} +5 -5
  205. package/dist/{link-QYAW6A2W.js → link-CI45HWFN.js} +4 -3
  206. package/dist/{link-QYAW6A2W.js.map → link-CI45HWFN.js.map} +1 -1
  207. package/dist/{linkedin-FFSDSGGS.js → linkedin-B7SYR75X.js} +27 -26
  208. package/dist/{linkedin-FFSDSGGS.js.map → linkedin-B7SYR75X.js.map} +1 -1
  209. package/dist/{list-NVQC5SNY.js → list-2BARXOT5.js} +3 -2
  210. package/dist/{list-NVQC5SNY.js.map → list-2BARXOT5.js.map} +1 -1
  211. package/dist/{list-SAV3LQHY.js → list-BIEVLEHS.js} +4 -3
  212. package/dist/{list-SAV3LQHY.js.map → list-BIEVLEHS.js.map} +1 -1
  213. package/dist/{list-5IC6KIKO.js → list-ZBT3EBVZ.js} +4 -3
  214. package/dist/{list-5IC6KIKO.js.map → list-ZBT3EBVZ.js.map} +1 -1
  215. package/dist/{log-XZPVOALD.js → log-C23OOAJZ.js} +4 -3
  216. package/dist/{log-XZPVOALD.js.map → log-C23OOAJZ.js.map} +1 -1
  217. package/dist/{logo-2IP663QO.js → logo-Q5D7PZY6.js} +3 -3
  218. package/dist/{lookup-XK45W2SH.js → lookup-ETWY47F7.js} +6 -5
  219. package/dist/{make-J3WBO62B.js → make-TPKKJXGL.js} +18 -17
  220. package/dist/{make-J3WBO62B.js.map → make-TPKKJXGL.js.map} +1 -1
  221. package/dist/{map-4J5WIWIG.js → map-SYZMPHLL.js} +5 -4
  222. package/dist/{map-4J5WIWIG.js.map → map-SYZMPHLL.js.map} +1 -1
  223. package/dist/{mcp-XXD7ZQCP.js → mcp-6FQBVJ6F.js} +3 -2
  224. package/dist/{mcp-XXD7ZQCP.js.map → mcp-6FQBVJ6F.js.map} +1 -1
  225. package/dist/{media-sources-O6ZRUA3N.js → media-sources-ZXHEEP6T.js} +2 -2
  226. package/dist/{members-D5ZYLS4Y.js → members-UDY4OOJW.js} +4 -3
  227. package/dist/{members-D5ZYLS4Y.js.map → members-UDY4OOJW.js.map} +1 -1
  228. package/dist/{normalize-PCNC6E2N.js → normalize-DAKHYS3V.js} +7 -3
  229. package/dist/{normalize-PCNC6E2N.js.map → normalize-DAKHYS3V.js.map} +1 -1
  230. package/dist/{options-MQ65VEVD.js → options-QL3ULED5.js} +7 -6
  231. package/dist/{options-MQ65VEVD.js.map → options-QL3ULED5.js.map} +1 -1
  232. package/dist/{performance-6QW2KEEQ.js → performance-UF5VTY2U.js} +5 -4
  233. package/dist/plan-FT632COT.js +51 -0
  234. package/dist/plan-FT632COT.js.map +1 -0
  235. package/dist/{promoted-tweet-writes-JPLHY3GM.js → promoted-tweet-writes-7HGESJ46.js} +4 -3
  236. package/dist/{promoted-tweet-writes-JPLHY3GM.js.map → promoted-tweet-writes-7HGESJ46.js.map} +1 -1
  237. package/dist/{promoted-tweets-SURKMHFI.js → promoted-tweets-LZKS5JIF.js} +3 -3
  238. package/dist/{publish-HCQ6MXLB.js → publish-NPD3SMZL.js} +4 -3
  239. package/dist/{publish-HCQ6MXLB.js.map → publish-NPD3SMZL.js.map} +1 -1
  240. package/dist/questionnaire-JNGYJTAY.js +37 -0
  241. package/dist/questionnaire-JNGYJTAY.js.map +1 -0
  242. package/dist/{reddit-GIP3ADMS.js → reddit-NU2N3LZD.js} +5 -4
  243. package/dist/{refresh-UXQSLCR3.js → refresh-EBVJ2C6L.js} +3 -2
  244. package/dist/{refresh-UXQSLCR3.js.map → refresh-EBVJ2C6L.js.map} +1 -1
  245. package/dist/{release-5KVLXNP6.js → release-V43YB2PY.js} +4 -3
  246. package/dist/{release-5KVLXNP6.js.map → release-V43YB2PY.js.map} +1 -1
  247. package/dist/{remove-6FIVKCJI.js → remove-QPSWLFI4.js} +3 -2
  248. package/dist/{remove-6FIVKCJI.js.map → remove-QPSWLFI4.js.map} +1 -1
  249. package/dist/{reopen-YM5LNOLB.js → reopen-GQ66NMWF.js} +4 -3
  250. package/dist/{reopen-YM5LNOLB.js.map → reopen-GQ66NMWF.js.map} +1 -1
  251. package/dist/{rerun-WYDRHIUJ.js → rerun-PZK275DY.js} +18 -17
  252. package/dist/{rerun-WYDRHIUJ.js.map → rerun-PZK275DY.js.map} +1 -1
  253. package/dist/{research-2BLEISBG.js → research-FMM6AWZC.js} +10 -10
  254. package/dist/{research-YOGE7GT2.js → research-GEOCUBXB.js} +3 -2
  255. package/dist/{research-YOGE7GT2.js.map → research-GEOCUBXB.js.map} +1 -1
  256. package/dist/{reset-C4UHQ3EU.js → reset-REXJ6AUK.js} +3 -2
  257. package/dist/{reset-C4UHQ3EU.js.map → reset-REXJ6AUK.js.map} +1 -1
  258. package/dist/{reset-OLVB6AE6.js → reset-Y72IVESB.js} +3 -2
  259. package/dist/{reset-OLVB6AE6.js.map → reset-Y72IVESB.js.map} +1 -1
  260. package/dist/{resolve-XYH2GDAE.js → resolve-OGX7C4TV.js} +4 -3
  261. package/dist/{resolve-XYH2GDAE.js.map → resolve-OGX7C4TV.js.map} +1 -1
  262. package/dist/{retry-7EELDEQP.js → retry-CD6JAQ3F.js} +3 -2
  263. package/dist/{retry-7EELDEQP.js.map → retry-CD6JAQ3F.js.map} +1 -1
  264. package/dist/{retry-726GKI6V.js → retry-TCUBBFR5.js} +3 -2
  265. package/dist/{retry-726GKI6V.js.map → retry-TCUBBFR5.js.map} +1 -1
  266. package/dist/{run-P4KR2MXC.js → run-A5ZDXTOI.js} +4 -3
  267. package/dist/{run-P4KR2MXC.js.map → run-A5ZDXTOI.js.map} +1 -1
  268. package/dist/{run-MODGUNGT.js → run-EUO34T2J.js} +18 -17
  269. package/dist/{scaffold-ad-5ZE7KE62.js → scaffold-ad-SW2HEWM3.js} +13 -12
  270. package/dist/{scaffold-ad-5ZE7KE62.js.map → scaffold-ad-SW2HEWM3.js.map} +1 -1
  271. package/dist/{scaffold-static-ad-HJY5HFDL.js → scaffold-static-ad-ECTJL54Y.js} +37 -36
  272. package/dist/scaffold-static-ad-ECTJL54Y.js.map +1 -0
  273. package/dist/{scaffold-video-P2PYPWG2.js → scaffold-video-EI7U7RBK.js} +12 -11
  274. package/dist/{scaffold-video-P2PYPWG2.js.map → scaffold-video-EI7U7RBK.js.map} +1 -1
  275. package/dist/{schedule-RDK4GEPI.js → schedule-S5YZJZ5U.js} +3 -2
  276. package/dist/{schedule-RDK4GEPI.js.map → schedule-S5YZJZ5U.js.map} +1 -1
  277. package/dist/{scheduled-agents-6U44QE76.js → scheduled-agents-N4LJRM4C.js} +11 -11
  278. package/dist/{schema-CHJDC7GQ.js → schema-R7JWWOF4.js} +8 -4
  279. package/dist/{schema-CHJDC7GQ.js.map → schema-R7JWWOF4.js.map} +1 -1
  280. package/dist/{search-PMJRU3C4.js → search-KHMQH3AT.js} +3 -2
  281. package/dist/{search-PMJRU3C4.js.map → search-KHMQH3AT.js.map} +1 -1
  282. package/dist/{select-AB2L4GAA.js → select-O2FN2JEQ.js} +9 -8
  283. package/dist/{select-AB2L4GAA.js.map → select-O2FN2JEQ.js.map} +1 -1
  284. package/dist/{sends-WGJVQUMF.js → sends-BQZM5PLS.js} +5 -4
  285. package/dist/{sends-WGJVQUMF.js.map → sends-BQZM5PLS.js.map} +1 -1
  286. package/dist/{set-prompt-DU2G2WTB.js → set-prompt-2HASHGWC.js} +9 -8
  287. package/dist/{set-prompt-DU2G2WTB.js.map → set-prompt-2HASHGWC.js.map} +1 -1
  288. package/dist/{setup-links-REPREN3C.js → setup-links-GYSE56GX.js} +4 -3
  289. package/dist/{setup-links-REPREN3C.js.map → setup-links-GYSE56GX.js.map} +1 -1
  290. package/dist/{site-WFSWIA3S.js → site-4SKM7RKG.js} +5 -4
  291. package/dist/{site-WFSWIA3S.js.map → site-4SKM7RKG.js.map} +1 -1
  292. package/dist/{sources-YBQ6KPFM.js → sources-FQ2UZTHL.js} +6 -6
  293. package/dist/{sources-AMI2AWKZ.js → sources-R2NKNC6J.js} +10 -9
  294. package/dist/{sources-AMI2AWKZ.js.map → sources-R2NKNC6J.js.map} +1 -1
  295. package/dist/{stale-6MJHVEG4.js → stale-W756ACKC.js} +8 -7
  296. package/dist/{stale-6MJHVEG4.js.map → stale-W756ACKC.js.map} +1 -1
  297. package/dist/{status-7F2KHFGA.js → status-SE2VZJJB.js} +4 -3
  298. package/dist/{status-7F2KHFGA.js.map → status-SE2VZJJB.js.map} +1 -1
  299. package/dist/{stock-2YCDN3N6.js → stock-KXJ26BY4.js} +5 -5
  300. package/dist/{studio-RA7QQH4O.js → studio-SYKOSNDB.js} +1 -1
  301. package/dist/{sync-GWTLKZTU.js → sync-LJGSODK3.js} +3 -2
  302. package/dist/{sync-GWTLKZTU.js.map → sync-LJGSODK3.js.map} +1 -1
  303. package/dist/{sync-definition-IPUFS5XS.js → sync-definition-QR2N233R.js} +12 -11
  304. package/dist/{tags-KFYLZLB3.js → tags-4BAVFH4S.js} +3 -2
  305. package/dist/{tags-KFYLZLB3.js.map → tags-4BAVFH4S.js.map} +1 -1
  306. package/dist/{tags-ABHSX6M5.js → tags-5SBMRC2A.js} +4 -3
  307. package/dist/{tags-ABHSX6M5.js.map → tags-5SBMRC2A.js.map} +1 -1
  308. package/dist/{tags-3WPW6PTV.js → tags-PYWFSBTR.js} +4 -4
  309. package/dist/{tags-6342FQEB.js → tags-QQU3OKMZ.js} +4 -3
  310. package/dist/{tags-6342FQEB.js.map → tags-QQU3OKMZ.js.map} +1 -1
  311. package/dist/{tags-FJIBBBRG.js → tags-YYLNF3PK.js} +4 -3
  312. package/dist/{tags-FJIBBBRG.js.map → tags-YYLNF3PK.js.map} +1 -1
  313. package/dist/{targeting-criteria-NR47AF5C.js → targeting-criteria-RJFLFICN.js} +3 -3
  314. package/dist/{targets-L56KOVQE.js → targets-S2MT2PNB.js} +4 -3
  315. package/dist/{targets-L56KOVQE.js.map → targets-S2MT2PNB.js.map} +1 -1
  316. package/dist/{templates-B6XGDYUF.js → templates-ZE5TOGRT.js} +4 -3
  317. package/dist/{templates-B6XGDYUF.js.map → templates-ZE5TOGRT.js.map} +1 -1
  318. package/dist/{testimonials-CVC4YIXO.js → testimonials-DII5DYLR.js} +6 -6
  319. package/dist/{top-companies-45X3DT7Z.js → top-companies-PGIAEHDF.js} +4 -3
  320. package/dist/{top-companies-45X3DT7Z.js.map → top-companies-PGIAEHDF.js.map} +1 -1
  321. package/dist/{translate-Z66FDB4K.js → translate-GXTS633J.js} +12 -11
  322. package/dist/{translate-Z66FDB4K.js.map → translate-GXTS633J.js.map} +1 -1
  323. package/dist/{triggers-22EMIVFD.js → triggers-2PTONXRU.js} +4 -3
  324. package/dist/{triggers-22EMIVFD.js.map → triggers-2PTONXRU.js.map} +1 -1
  325. package/dist/{unlink-65KUN6ID.js → unlink-XRMYJ6DB.js} +4 -3
  326. package/dist/{unlink-65KUN6ID.js.map → unlink-XRMYJ6DB.js.map} +1 -1
  327. package/dist/{unstage-2E3I5SWF.js → unstage-FY7A3YFF.js} +4 -3
  328. package/dist/{unstage-2E3I5SWF.js.map → unstage-FY7A3YFF.js.map} +1 -1
  329. package/dist/{unstage-4ZEULXEQ.js → unstage-RM2RLXKD.js} +5 -4
  330. package/dist/{unstage-4ZEULXEQ.js.map → unstage-RM2RLXKD.js.map} +1 -1
  331. package/dist/{update-KREBPGBH.js → update-E5SRBXQR.js} +4 -3
  332. package/dist/{update-KREBPGBH.js.map → update-E5SRBXQR.js.map} +1 -1
  333. package/dist/{update-D6DJC6T7.js → update-PJ67D2OG.js} +3 -2
  334. package/dist/{update-D6DJC6T7.js.map → update-PJ67D2OG.js.map} +1 -1
  335. package/dist/{update-2S7CSEAW.js → update-S4562V3O.js} +4 -3
  336. package/dist/{update-2S7CSEAW.js.map → update-S4562V3O.js.map} +1 -1
  337. package/dist/{update-7NCOTAQZ.js → update-V6YVEUI2.js} +4 -3
  338. package/dist/{update-7NCOTAQZ.js.map → update-V6YVEUI2.js.map} +1 -1
  339. package/dist/{upload-O6NHRPS7.js → upload-R6CQVLKF.js} +4 -3
  340. package/dist/{upload-O6NHRPS7.js.map → upload-R6CQVLKF.js.map} +1 -1
  341. package/dist/{url-options-GGXAL3J4.js → url-options-JOKU46F2.js} +4 -3
  342. package/dist/{url-options-GGXAL3J4.js.map → url-options-JOKU46F2.js.map} +1 -1
  343. package/dist/{url-params-3EFGVTZZ.js → url-params-7U2XMOWF.js} +4 -3
  344. package/dist/{url-params-3EFGVTZZ.js.map → url-params-7U2XMOWF.js.map} +1 -1
  345. package/dist/{validate-UMHHNTVU.js → validate-7YPOUKPB.js} +10 -9
  346. package/dist/{validate-UMHHNTVU.js.map → validate-7YPOUKPB.js.map} +1 -1
  347. package/dist/{videos-YSXYGTBM.js → videos-LICG6ACJ.js} +5 -5
  348. package/dist/{web-IGIGVEKS.js → web-BA2PGTWU.js} +4 -3
  349. package/dist/{web-IGIGVEKS.js.map → web-BA2PGTWU.js.map} +1 -1
  350. package/dist/{winning-ads-2WS7FI4E.js → winning-ads-C6S2C5VP.js} +2 -2
  351. package/dist/{write-commands-5C7FUOVN.js → write-commands-7SJ3BOW5.js} +5 -4
  352. package/dist/{write-commands-5C7FUOVN.js.map → write-commands-7SJ3BOW5.js.map} +1 -1
  353. package/dist/{x-BFSKFCZD.js → x-CZHRC6U7.js} +6 -6
  354. package/package.json +1 -1
  355. package/dist/add-5GAN6CVO.js.map +0 -1
  356. package/dist/analytics-FKCXIMPO.js.map +0 -1
  357. package/dist/chunk-DWHIOO7E.js.map +0 -1
  358. package/dist/chunk-EDLZGTGN.js.map +0 -1
  359. package/dist/chunk-GKZ2WU75.js.map +0 -1
  360. package/dist/chunk-SSJK7FEV.js.map +0 -1
  361. package/dist/chunk-T2PC5AVH.js.map +0 -1
  362. package/dist/chunk-XF4JUKVF.js.map +0 -1
  363. package/dist/chunk-YRQYA2LR.js.map +0 -1
  364. package/dist/flows-KABCBS3S.js.map +0 -1
  365. package/dist/funnel-AAX27NH4.js.map +0 -1
  366. package/dist/get-QEYJRLV3.js.map +0 -1
  367. package/dist/scaffold-static-ad-HJY5HFDL.js.map +0 -1
  368. /package/dist/{actions-P35MEMGN.js.map → actions-6TQMSVWD.js.map} +0 -0
  369. /package/dist/{ads-73PGA4YC.js.map → ads-AGYCVD62.js.map} +0 -0
  370. /package/dist/{avatars-EKCKHCC3.js.map → avatars-467OSBD6.js.map} +0 -0
  371. /package/dist/{brand-C6PFGGQN.js.map → brand-YRTEPGBK.js.map} +0 -0
  372. /package/dist/{campaigns-KZYZTXDS.js.map → campaigns-OYMXDGWX.js.map} +0 -0
  373. /package/dist/{canvas-UJNSHD3B.js.map → canvas-YQFG52IG.js.map} +0 -0
  374. /package/dist/{catalog-ZQX6BGXS.js.map → catalog-XLXIM7IW.js.map} +0 -0
  375. /package/dist/{chunk-7YCRFMXF.js.map → chunk-24EB7EDR.js.map} +0 -0
  376. /package/dist/{chunk-5ZDLTE5T.js.map → chunk-2AOE2MZQ.js.map} +0 -0
  377. /package/dist/{chunk-4SG4RW2P.js.map → chunk-2VPBIT65.js.map} +0 -0
  378. /package/dist/{chunk-NPY4QUMQ.js.map → chunk-54C6YDGJ.js.map} +0 -0
  379. /package/dist/{chunk-LZ73CZGP.js.map → chunk-5WCSKQ7Z.js.map} +0 -0
  380. /package/dist/{chunk-3G3ZDLMI.js.map → chunk-5ZNTADVR.js.map} +0 -0
  381. /package/dist/{chunk-AEOSAVVL.js.map → chunk-6F7DVPOS.js.map} +0 -0
  382. /package/dist/{chunk-CJCVIEJ5.js.map → chunk-6NY2GPR4.js.map} +0 -0
  383. /package/dist/{chunk-CXWFX2AM.js.map → chunk-6Y7ZBENQ.js.map} +0 -0
  384. /package/dist/{chunk-M242LHLX.js.map → chunk-7CTMH5AK.js.map} +0 -0
  385. /package/dist/{chunk-QD7ESRLN.js.map → chunk-C46GUI2S.js.map} +0 -0
  386. /package/dist/{chunk-6N6WKAJM.js.map → chunk-CWYAELVG.js.map} +0 -0
  387. /package/dist/{chunk-MXYBTMKB.js.map → chunk-DCRPXOJJ.js.map} +0 -0
  388. /package/dist/{chunk-JQJDXPCO.js.map → chunk-FUHN4MFY.js.map} +0 -0
  389. /package/dist/{chunk-S77PZVYM.js.map → chunk-FYGR3I2A.js.map} +0 -0
  390. /package/dist/{chunk-OZRUJVIQ.js.map → chunk-H3427GPU.js.map} +0 -0
  391. /package/dist/{chunk-IR6D7K4H.js.map → chunk-I3ZR655O.js.map} +0 -0
  392. /package/dist/{chunk-YK32GUBN.js.map → chunk-KMKEYI37.js.map} +0 -0
  393. /package/dist/{chunk-W3ZHJJVT.js.map → chunk-KS2QY6MK.js.map} +0 -0
  394. /package/dist/{chunk-WNRV4QH7.js.map → chunk-LYQJ4PZW.js.map} +0 -0
  395. /package/dist/{chunk-CSYSX4D2.js.map → chunk-N4LAYIIN.js.map} +0 -0
  396. /package/dist/{chunk-4AUMTNVB.js.map → chunk-NA63BH7V.js.map} +0 -0
  397. /package/dist/{chunk-4BQXAE7Z.js.map → chunk-NDEE6G2J.js.map} +0 -0
  398. /package/dist/{chunk-MELOSESI.js.map → chunk-R25YLW6H.js.map} +0 -0
  399. /package/dist/{chunk-Y6O7EWYY.js.map → chunk-RL5CP7N6.js.map} +0 -0
  400. /package/dist/{chunk-DGUNI37S.js.map → chunk-RX2DKU3W.js.map} +0 -0
  401. /package/dist/{chunk-VTDMKARH.js.map → chunk-ULG4QRTV.js.map} +0 -0
  402. /package/dist/{chunk-QRP3PXWN.js.map → chunk-VL43TNIP.js.map} +0 -0
  403. /package/dist/{chunk-SHL7LOC3.js.map → chunk-VLMBTPXU.js.map} +0 -0
  404. /package/dist/{chunk-KHRXPQID.js.map → chunk-VYQ3QJ3C.js.map} +0 -0
  405. /package/dist/{chunk-A4LOJ2VD.js.map → chunk-WGUQHAJY.js.map} +0 -0
  406. /package/dist/{chunk-ZEYEWPK6.js.map → chunk-WKQG6TER.js.map} +0 -0
  407. /package/dist/{chunk-3IBYKLXR.js.map → chunk-ZDMTXQ2Q.js.map} +0 -0
  408. /package/dist/{connect-QCOGEPP4.js.map → connect-FCXNVTXG.js.map} +0 -0
  409. /package/dist/{creatives-NJF2U763.js.map → creatives-FXUQ5WSD.js.map} +0 -0
  410. /package/dist/{customers-A36LOZOB.js.map → customers-XH2DMTFH.js.map} +0 -0
  411. /package/dist/{feedback-PPQMOQ46.js.map → feedback-EIZKS4JU.js.map} +0 -0
  412. /package/dist/{find-OTDIX6V4.js.map → find-FRRHAPWX.js.map} +0 -0
  413. /package/dist/{fonts-EMMX3KII.js.map → fonts-MXR3ZKDX.js.map} +0 -0
  414. /package/dist/{ga4-UDQ2HA2J.js.map → ga4-DV2AXCSL.js.map} +0 -0
  415. /package/dist/{google-M7KEXVK5.js.map → google-6OGZX47I.js.map} +0 -0
  416. /package/dist/{google-KTO3PLEU.js.map → google-QYYYSSXI.js.map} +0 -0
  417. /package/dist/{gsc-P3QYGDV2.js.map → gsc-TAKOF7J5.js.map} +0 -0
  418. /package/dist/{icon-I43F77FV.js.map → icon-L4RSS6PZ.js.map} +0 -0
  419. /package/dist/{ideas-MIDU7YOA.js.map → ideas-NFOW3HKJ.js.map} +0 -0
  420. /package/dist/{images-S254MS6O.js.map → images-2EFFUNNV.js.map} +0 -0
  421. /package/dist/{ingest-YV2NLDBE.js.map → ingest-2EIKN4QC.js.map} +0 -0
  422. /package/dist/{inspiration-P265QJ2H.js.map → inspiration-S3DU4CMQ.js.map} +0 -0
  423. /package/dist/{landing-CJYGWCK4.js.map → landing-2ZB46LXH.js.map} +0 -0
  424. /package/dist/{line-items-7ZGIKEF2.js.map → line-items-5NECXUZT.js.map} +0 -0
  425. /package/dist/{logo-2IP663QO.js.map → logo-Q5D7PZY6.js.map} +0 -0
  426. /package/dist/{lookup-XK45W2SH.js.map → lookup-ETWY47F7.js.map} +0 -0
  427. /package/dist/{media-sources-O6ZRUA3N.js.map → media-sources-ZXHEEP6T.js.map} +0 -0
  428. /package/dist/{performance-6QW2KEEQ.js.map → performance-UF5VTY2U.js.map} +0 -0
  429. /package/dist/{promoted-tweets-SURKMHFI.js.map → promoted-tweets-LZKS5JIF.js.map} +0 -0
  430. /package/dist/{reddit-GIP3ADMS.js.map → reddit-NU2N3LZD.js.map} +0 -0
  431. /package/dist/{research-2BLEISBG.js.map → research-FMM6AWZC.js.map} +0 -0
  432. /package/dist/{run-MODGUNGT.js.map → run-EUO34T2J.js.map} +0 -0
  433. /package/dist/{scheduled-agents-6U44QE76.js.map → scheduled-agents-N4LJRM4C.js.map} +0 -0
  434. /package/dist/{sources-YBQ6KPFM.js.map → sources-FQ2UZTHL.js.map} +0 -0
  435. /package/dist/{stock-2YCDN3N6.js.map → stock-KXJ26BY4.js.map} +0 -0
  436. /package/dist/{studio-RA7QQH4O.js.map → studio-SYKOSNDB.js.map} +0 -0
  437. /package/dist/{sync-definition-IPUFS5XS.js.map → sync-definition-QR2N233R.js.map} +0 -0
  438. /package/dist/{tags-3WPW6PTV.js.map → tags-PYWFSBTR.js.map} +0 -0
  439. /package/dist/{targeting-criteria-NR47AF5C.js.map → targeting-criteria-RJFLFICN.js.map} +0 -0
  440. /package/dist/{testimonials-CVC4YIXO.js.map → testimonials-DII5DYLR.js.map} +0 -0
  441. /package/dist/{videos-YSXYGTBM.js.map → videos-LICG6ACJ.js.map} +0 -0
  442. /package/dist/{winning-ads-2WS7FI4E.js.map → winning-ads-C6S2C5VP.js.map} +0 -0
  443. /package/dist/{x-BFSKFCZD.js.map → x-CZHRC6U7.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/ads/linkedin/analytics.ts","../src/commands/ads/linkedin/presets.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiPost } from \"../../../client.ts\";\nimport { writeAdsJson, writeAdsOutput } from \"../output.ts\";\nimport {\n ALL_LEVELS,\n ALL_PIVOTS,\n composeFields,\n type IntentName,\n isLevel,\n isPivot,\n type LevelName,\n listIntents,\n MEMBER_PIVOTS,\n type PivotSlug,\n} from \"./presets.ts\";\nimport { csvOrJson, daysAgoIso, handleLinkedinError, resolveAccountIdArg, todayIso } from \"./shared.ts\";\n\ntype Granularity = \"DAILY\" | \"MONTHLY\" | \"YEARLY\" | \"ALL\";\n\ninterface AnalyticsRequest {\n level: LevelName;\n ids: string[];\n intent: IntentName;\n pivot: PivotSlug;\n metrics?: string[];\n start: string;\n end?: string;\n granularity: Granularity;\n limit?: number;\n}\n\ninterface AnalyticsResponse {\n rows: Array<Record<string, unknown>>;\n fields: string[];\n warnings: Array<{ code: string; message: string }>;\n query: AnalyticsRequest & { metrics: string[] };\n}\n\nfunction commaSplit(input: string | undefined): string[] | undefined {\n if (!input) return undefined;\n return input\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nfunction parseGranularity(raw: string | undefined): Granularity {\n const v = (raw ?? \"DAILY\").toUpperCase();\n if (v === \"DAILY\" || v === \"MONTHLY\" || v === \"YEARLY\" || v === \"ALL\") {\n return v;\n }\n handleLinkedinError(new Error(`Invalid --granularity \"${raw}\". Use DAILY | MONTHLY | YEARLY | ALL.`));\n}\n\nfunction parseLevel(raw: string | undefined): LevelName {\n const v = raw ?? \"account\";\n if (!isLevel(v)) {\n handleLinkedinError(new Error(`Invalid --level \"${raw}\". Use one of: ${ALL_LEVELS.join(\", \")}.`));\n }\n return v;\n}\n\nfunction parsePivot(raw: string | undefined): PivotSlug {\n const v = raw ?? \"none\";\n if (!isPivot(v)) {\n handleLinkedinError(new Error(`Invalid --pivot \"${raw}\". Use one of: ${ALL_PIVOTS.join(\", \")}.`));\n }\n return v;\n}\n\nfunction parseIntent(raw: string | undefined): IntentName {\n const v = (raw ?? \"baseline\") as IntentName;\n const known: IntentName[] = [\n \"baseline\",\n \"revenue\",\n \"funnel\",\n \"engagement\",\n \"video\",\n \"lead-gen\",\n \"inmail\",\n \"document\",\n \"ranking\",\n \"identity\",\n ];\n if (!known.includes(v)) {\n handleLinkedinError(new Error(`Invalid --intent \"${raw}\". Run --list-intents to see options.`));\n }\n return v;\n}\n\n/**\n * Resolve start/end dates. Precedence:\n * 1. --start + --end (explicit window)\n * 2. --last-days N → end=today, start=today-N\n * 3. default: last 7 days\n */\nfunction resolveDateRange(args: Record<string, unknown>): { start: string; end?: string } {\n const start = args.start as string | undefined;\n const end = args.end as string | undefined;\n if (start) {\n return { start, end };\n }\n const lastDaysRaw = args[\"last-days\"] as string | undefined;\n const days = lastDaysRaw ? Number(lastDaysRaw) : 7;\n if (!Number.isFinite(days) || days < 1 || days > 730) {\n handleLinkedinError(new Error(`Invalid --last-days \"${lastDaysRaw}\". Use a positive number ≤ 730.`));\n }\n return { start: daysAgoIso(days), end: todayIso() };\n}\n\n/**\n * Resolve scope IDs. Each level expects a different flag — but we accept\n * --account-id at every level when level=account, and --campaign-id /\n * --campaign-group-id / --creative-id otherwise. CSV-encoded for multi-id.\n */\nfunction resolveScopeIds(args: Record<string, unknown>, level: LevelName): string[] {\n if (level === \"account\") {\n const id = resolveAccountIdArg(args);\n return [id];\n }\n if (level === \"campaign-group\") {\n const raw = (args[\"campaign-group-id\"] as string | undefined) ?? (args.ids as string | undefined);\n if (!raw) {\n handleLinkedinError(new Error(\"Pass --campaign-group-id (CSV for multi) when --level campaign-group.\"));\n }\n return commaSplit(raw) ?? [];\n }\n if (level === \"campaign\") {\n const raw = (args[\"campaign-id\"] as string | undefined) ?? (args.ids as string | undefined);\n if (!raw) {\n handleLinkedinError(new Error(\"Pass --campaign-id (CSV for multi) when --level campaign.\"));\n }\n return commaSplit(raw) ?? [];\n }\n // creative\n const raw = (args[\"creative-id\"] as string | undefined) ?? (args.ids as string | undefined);\n if (!raw) {\n handleLinkedinError(new Error(\"Pass --creative-id (CSV for multi) when --level creative.\"));\n }\n return commaSplit(raw) ?? [];\n}\n\n/** Sort rows by spend desc when present, otherwise by impressions desc. */\nfunction sortRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n return [...rows].sort((a, b) => {\n const cs = numberOf(b.costInUsd) - numberOf(a.costInUsd);\n if (cs !== 0) return cs;\n return numberOf(b.impressions) - numberOf(a.impressions);\n });\n}\n\nfunction numberOf(v: unknown): number {\n if (typeof v === \"number\") return Number.isFinite(v) ? v : 0;\n if (typeof v === \"string\") {\n const n = Number(v);\n return Number.isFinite(n) ? n : 0;\n }\n return 0;\n}\n\nexport const analyticsCommand = defineCommand({\n meta: {\n name: \"analytics\",\n description: `Performance reporting — the workhorse for AI agents.\n\nThree-axis design (LinkedIn's superpower over Meta/Google):\n --level account | campaign-group | campaign | creative\n --intent baseline | revenue | funnel | engagement | video | lead-gen | inmail | document | ranking | identity\n --pivot none | job-title | company | industry | seniority | function | company-size | country | region | dma\n | device | placement | serving-location | card-index | objective\n | conversation-node | conversation-node-button\n\nSmart defaults:\n --level account, --intent baseline, --pivot none, --granularity DAILY, last 7 days\n Pivot on a MEMBER_* dim → granularity auto-forced to ALL (LinkedIn rejects DAILY+demographic)\n Demographic data delayed 12-24h with ≥3-event privacy floor — the CLI flags this in warnings.\n --pivot dma → US Nielsen DMA® regions, names resolved. Any report built from it must write \"DMA®\"\n and carry Nielsen's notice (returned as the DMA_ATTRIBUTION_REQUIRED warning).\n Derived metrics injected client-side: ctr, cpc, cpm, frequency, leadCompletionRate\n\nExamples — common AI questions:\n # \"How is this account doing this week?\"\n baker ads linkedin analytics\n\n # \"Who are we reaching, by job title?\" (the LinkedIn killer)\n baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot job-title --intent baseline --last-days 30\n\n # \"Top companies seeing my ads\" (ABM feedback loop)\n baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot company --last-days 30\n\n # \"Revenue by campaign over Q1\"\n baker ads linkedin analytics --level campaign --campaign-id 1,2,3 --intent revenue --start 2026-01-01 --end 2026-03-31 --granularity MONTHLY\n\n # \"How is the lead form converting?\"\n baker ads linkedin analytics --level campaign --campaign-id 1234 --intent lead-gen\n\n # Custom field set (escape hatch)\n baker ads linkedin analytics --metrics impressions,clicks,oneClickLeads --intent identity`,\n },\n args: {\n level: { type: \"string\", description: \"Object scope (default: account)\" },\n \"account-id\": { type: \"string\", description: \"Account ID — numeric or urn:li:sponsoredAccount:N (level=account)\" },\n \"account-urn\": { type: \"string\", description: \"Alias for --account-id (URN form)\" },\n \"campaign-group-id\": { type: \"string\", description: \"Comma-separated IDs (level=campaign-group)\" },\n \"campaign-id\": { type: \"string\", description: \"Comma-separated IDs (level=campaign)\" },\n \"creative-id\": { type: \"string\", description: \"Comma-separated IDs (level=creative)\" },\n ids: { type: \"string\", description: \"Generic CSV of IDs at the chosen level (alternative to per-level flags)\" },\n intent: {\n type: \"string\",\n description: \"baseline|revenue|funnel|engagement|video|lead-gen|inmail|document|ranking|identity\",\n },\n pivot: { type: \"string\", description: \"Pivot dim. Default: none. See `--list-pivots`.\" },\n metrics: { type: \"string\", description: \"CSV metric override — bypass --intent's bundle\" },\n \"list-intents\": { type: \"boolean\", description: \"Print intent definitions and exit\" },\n \"list-pivots\": { type: \"boolean\", description: \"Print pivot slugs and exit\" },\n start: { type: \"string\", description: \"Start date YYYY-MM-DD (overrides --last-days)\" },\n end: { type: \"string\", description: \"End date YYYY-MM-DD\" },\n \"last-days\": { type: \"string\", description: \"Window relative to today (default: 7)\" },\n granularity: { type: \"string\", description: \"DAILY|MONTHLY|YEARLY|ALL (default: DAILY)\" },\n limit: { type: \"string\", description: \"Max rows (default: 1000)\" },\n \"no-sort\": { type: \"boolean\", description: \"Skip default sort by costInUsd desc\" },\n \"no-cache\": NO_CACHE_ARG,\n output: { type: \"string\", description: \"Output format json|csv|jsonl|md\", default: \"json\" },\n },\n run: async ({ args }) => {\n if (args[\"list-intents\"]) {\n writeAdsJson({ ok: true, data: listIntents() });\n return;\n }\n if (args[\"list-pivots\"]) {\n writeAdsJson({ ok: true, data: ALL_PIVOTS });\n return;\n }\n\n const level = parseLevel(args.level as string | undefined);\n const intent = parseIntent(args.intent as string | undefined);\n const pivot = parsePivot(args.pivot as string | undefined);\n let granularity = parseGranularity(args.granularity as string | undefined);\n\n // CLI-side mirror of the backend's pivot/granularity guard. Backend will\n // also enforce — this lets us echo the auto-correction in stderr early.\n if (MEMBER_PIVOTS.has(pivot) && granularity === \"DAILY\") {\n process.stderr.write(`note: pivot=${pivot} forces --granularity ALL (LinkedIn rejects DAILY + demographic).\\n`);\n granularity = \"ALL\";\n }\n\n const ids = resolveScopeIds(args, level);\n if (ids.length === 0) {\n handleLinkedinError(new Error(`No IDs resolved for --level ${level}`));\n }\n\n const range = resolveDateRange(args);\n const metrics = commaSplit(args.metrics as string | undefined);\n const limit = args.limit ? Number(args.limit) : 1000;\n\n const request: AnalyticsRequest = {\n level,\n ids,\n intent,\n pivot,\n metrics,\n start: range.start,\n end: range.end,\n granularity,\n limit,\n };\n\n try {\n const data = await apiPost<AnalyticsResponse>(\"/api/ads/linkedin/analytics\", {\n request,\n skipCache: Boolean(args[\"no-cache\"]),\n });\n const rows = args[\"no-sort\"] ? data.rows : sortRows(data.rows);\n const fmt = csvOrJson(args);\n if (fmt !== \"json\") {\n writeAdsOutput(rows, fmt, data.fields);\n return;\n }\n writeAdsJson({\n ok: true,\n data: {\n rows,\n fields: data.fields,\n warnings: data.warnings,\n query: data.query,\n // Echo composed fields so an offline agent can pre-flight w/o this network call.\n composedFields: composeFields(intent, level, metrics),\n },\n });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n","/**\n * LinkedIn analytics field bundles. Three-axis design:\n * --intent → metric bundle (baseline | revenue | funnel | engagement | video |\n * lead-gen | inmail | document | ranking | identity)\n * --level → object scope (account | campaign-group | campaign | creative)\n * --pivot → demographic / firmographic breakdown\n * (none | job-title | company | industry | seniority | function |\n * company-size | country | region | dma | device | placement | …)\n *\n * Backend recomputes the field list itself (single source of truth in\n * `packages/backend/convex/ads/linkedin/constants.ts`). The CLI keeps a\n * mirror copy so `--list-intents` / `--list-pivots` work offline.\n */\n\nexport type IntentName =\n | \"baseline\"\n | \"revenue\"\n | \"funnel\"\n | \"engagement\"\n | \"video\"\n | \"lead-gen\"\n | \"inmail\"\n | \"document\"\n | \"ranking\"\n | \"identity\";\n\nexport type LevelName = \"account\" | \"campaign-group\" | \"campaign\" | \"creative\";\n\nexport type PivotSlug =\n | \"none\"\n | \"campaign\"\n | \"campaign-group\"\n | \"creative\"\n | \"company\"\n | \"account\"\n | \"conversion\"\n | \"job-title\"\n | \"job-function\"\n | \"seniority\"\n | \"industry\"\n | \"company-size\"\n | \"country\"\n | \"region\"\n | \"dma\"\n | \"device\"\n | \"placement\"\n | \"serving-location\"\n | \"card-index\"\n | \"objective\"\n | \"conversation-node\"\n | \"conversation-node-button\";\n\ninterface IntentDefinition {\n name: IntentName;\n description: string;\n metrics: string[];\n /** Derived (CLI-side) metrics this bundle materializes. Documentation only. */\n derived?: string[];\n}\n\nexport const INTENTS: Record<IntentName, IntentDefinition> = {\n baseline: {\n name: \"baseline\",\n description: \"Spend, impressions, clicks. The default 'how is delivery?' question. Derives CTR, CPC, CPM.\",\n metrics: [\"impressions\", \"clicks\", \"costInUsd\", \"costInLocalCurrency\", \"approximateUniqueImpressions\"],\n derived: [\"ctr\", \"cpc\", \"cpm\", \"frequency\"],\n },\n revenue: {\n name: \"revenue\",\n description: \"Spend, conversions, conversion value. 'How much money are we making?'\",\n metrics: [\n \"costInUsd\",\n \"externalWebsiteConversions\",\n \"externalWebsitePostClickConversions\",\n \"externalWebsitePostViewConversions\",\n \"conversionValueInLocalCurrency\",\n \"oneClickLeads\",\n ],\n },\n funnel: {\n name: \"funnel\",\n description: \"Impression → click → landing → form open → lead → conversion. 'Where do users drop off?'\",\n metrics: [\n \"impressions\",\n \"clicks\",\n \"landingPageClicks\",\n \"oneClickLeadFormOpens\",\n \"oneClickLeads\",\n \"externalWebsiteConversions\",\n \"costInUsd\",\n ],\n derived: [\"ctr\", \"leadCompletionRate\"],\n },\n engagement: {\n name: \"engagement\",\n description: \"Likes, comments, shares, follows + viral spillover. TLA-aware — measures organic reach effect.\",\n metrics: [\n \"impressions\",\n \"likes\",\n \"comments\",\n \"shares\",\n \"reactions\",\n \"follows\",\n \"totalEngagements\",\n \"viralImpressions\",\n \"viralLikes\",\n \"viralShares\",\n \"viralOneClickLeads\",\n \"costInUsd\",\n ],\n },\n video: {\n name: \"video\",\n description: \"Video watch quartiles + cost. 'How are video creatives holding attention?'\",\n metrics: [\n \"videoStarts\",\n \"videoFirstQuartileCompletions\",\n \"videoMidpointCompletions\",\n \"videoThirdQuartileCompletions\",\n \"videoCompletions\",\n \"videoViews\",\n \"fullScreenPlays\",\n \"costInUsd\",\n \"impressions\",\n ],\n },\n \"lead-gen\": {\n name: \"lead-gen\",\n description: \"Lead Gen Form opens + completions. CLI derives form-completion-rate.\",\n metrics: [\n \"oneClickLeadFormOpens\",\n \"oneClickLeads\",\n \"viralOneClickLeads\",\n \"viralOneClickLeadFormOpens\",\n \"costInUsd\",\n ],\n derived: [\"leadCompletionRate\"],\n },\n inmail: {\n name: \"inmail\",\n description: \"Sponsored Message / Conversation Ads — sends, opens, clicks, lead-gen taps.\",\n metrics: [\n \"sends\",\n \"opens\",\n \"clicks\",\n \"costInUsd\",\n \"leadGenerationMailContactInfoShares\",\n \"leadGenerationMailInterestedClicks\",\n ],\n },\n document: {\n name: \"document\",\n description: \"Document Ads — quartile read-through, completion, downloads.\",\n metrics: [\n \"documentFirstQuartileCompletions\",\n \"documentMidpointCompletions\",\n \"documentThirdQuartileCompletions\",\n \"documentCompletions\",\n \"downloadClicks\",\n \"costInUsd\",\n \"impressions\",\n ],\n },\n ranking: {\n name: \"ranking\",\n description:\n \"Frequency + reach metrics for fatigue detection. CLI derives frequency = impressions/uniqueImpressions.\",\n metrics: [\"impressions\", \"clicks\", \"costInUsd\", \"approximateUniqueImpressions\"],\n derived: [\"frequency\", \"ctr\"],\n },\n identity: {\n name: \"identity\",\n description: \"Just spend + impressions. Cheap roll-up.\",\n metrics: [\"costInUsd\", \"impressions\"],\n },\n};\n\n/** Pivots that LinkedIn rejects with DAILY granularity — CLI auto-forces ALL. */\nexport const MEMBER_PIVOTS = new Set<PivotSlug>([\n \"company\",\n \"job-title\",\n \"job-function\",\n \"seniority\",\n \"industry\",\n \"company-size\",\n \"country\",\n \"region\",\n \"dma\",\n]);\n\nexport const ALL_PIVOTS: PivotSlug[] = [\n \"none\",\n \"campaign\",\n \"campaign-group\",\n \"creative\",\n \"company\",\n \"account\",\n \"conversion\",\n \"job-title\",\n \"job-function\",\n \"seniority\",\n \"industry\",\n \"company-size\",\n \"country\",\n \"region\",\n \"dma\",\n \"device\",\n \"placement\",\n \"serving-location\",\n \"card-index\",\n \"objective\",\n \"conversation-node\",\n \"conversation-node-button\",\n];\n\nexport const ALL_LEVELS: LevelName[] = [\"account\", \"campaign-group\", \"campaign\", \"creative\"];\n\nexport function getIntent(name: string): IntentDefinition | undefined {\n return INTENTS[name as IntentName];\n}\n\nexport function listIntents(): IntentDefinition[] {\n return Object.values(INTENTS);\n}\n\nexport function isPivot(slug: string): slug is PivotSlug {\n return (ALL_PIVOTS as string[]).includes(slug);\n}\n\nexport function isLevel(slug: string): slug is LevelName {\n return (ALL_LEVELS as string[]).includes(slug);\n}\n\n/**\n * Compose final field list — intent bundle + identity columns + pivotValues +\n * dateRange. Backend re-validates and recomposes; this is just for offline\n * preview (`baker ads linkedin analytics --list-intents`).\n */\nexport function composeFields(intent: IntentName, _level: LevelName, metricsOverride?: string[]): string[] {\n const base = metricsOverride && metricsOverride.length > 0 ? metricsOverride : INTENTS[intent].metrics;\n const seen = new Set<string>();\n const out: string[] = [];\n for (const f of [\"pivotValues\", \"dateRange\", ...base]) {\n if (!seen.has(f)) {\n seen.add(f);\n out.push(f);\n }\n }\n return out;\n}\n"],"mappings":"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","names":["raw"]}
1
+ {"version":3,"sources":["../src/commands/ads/linkedin/analytics.ts","../src/commands/ads/linkedin/presets.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiPost } from \"../../../client.ts\";\nimport { writeAdsJson, writeAdsOutput } from \"../output.ts\";\nimport {\n ALL_LEVELS,\n ALL_PIVOTS,\n composeFields,\n type IntentName,\n isLevel,\n isPivot,\n type LevelName,\n listIntents,\n MEMBER_PIVOTS,\n type PivotSlug,\n} from \"./presets.ts\";\nimport { csvOrJson, daysAgoIso, handleLinkedinError, resolveAccountIdArg, todayIso } from \"./shared.ts\";\n\ntype Granularity = \"DAILY\" | \"MONTHLY\" | \"YEARLY\" | \"ALL\";\n\ninterface AnalyticsRequest {\n level: LevelName;\n ids: string[];\n intent: IntentName;\n pivot: PivotSlug;\n metrics?: string[];\n start: string;\n end?: string;\n granularity: Granularity;\n limit?: number;\n}\n\ninterface AnalyticsResponse {\n rows: Array<Record<string, unknown>>;\n fields: string[];\n warnings: Array<{ code: string; message: string }>;\n query: AnalyticsRequest & { metrics: string[] };\n}\n\nfunction commaSplit(input: string | undefined): string[] | undefined {\n if (!input) return undefined;\n return input\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nfunction parseGranularity(raw: string | undefined): Granularity {\n const v = (raw ?? \"DAILY\").toUpperCase();\n if (v === \"DAILY\" || v === \"MONTHLY\" || v === \"YEARLY\" || v === \"ALL\") {\n return v;\n }\n handleLinkedinError(new Error(`Invalid --granularity \"${raw}\". Use DAILY | MONTHLY | YEARLY | ALL.`));\n}\n\nfunction parseLevel(raw: string | undefined): LevelName {\n const v = raw ?? \"account\";\n if (!isLevel(v)) {\n handleLinkedinError(new Error(`Invalid --level \"${raw}\". Use one of: ${ALL_LEVELS.join(\", \")}.`));\n }\n return v;\n}\n\nfunction parsePivot(raw: string | undefined): PivotSlug {\n const v = raw ?? \"none\";\n if (!isPivot(v)) {\n handleLinkedinError(new Error(`Invalid --pivot \"${raw}\". Use one of: ${ALL_PIVOTS.join(\", \")}.`));\n }\n return v;\n}\n\nfunction parseIntent(raw: string | undefined): IntentName {\n const v = (raw ?? \"baseline\") as IntentName;\n const known: IntentName[] = [\n \"baseline\",\n \"revenue\",\n \"funnel\",\n \"engagement\",\n \"video\",\n \"lead-gen\",\n \"inmail\",\n \"document\",\n \"ranking\",\n \"identity\",\n ];\n if (!known.includes(v)) {\n handleLinkedinError(new Error(`Invalid --intent \"${raw}\". Run --list-intents to see options.`));\n }\n return v;\n}\n\n/**\n * Resolve start/end dates. Precedence:\n * 1. --start + --end (explicit window)\n * 2. --last-days N → end=today, start=today-N\n * 3. default: last 7 days\n */\nfunction resolveDateRange(args: Record<string, unknown>): { start: string; end?: string } {\n const start = args.start as string | undefined;\n const end = args.end as string | undefined;\n if (start) {\n return { start, end };\n }\n const lastDaysRaw = args[\"last-days\"] as string | undefined;\n const days = lastDaysRaw ? Number(lastDaysRaw) : 7;\n if (!Number.isFinite(days) || days < 1 || days > 730) {\n handleLinkedinError(new Error(`Invalid --last-days \"${lastDaysRaw}\". Use a positive number ≤ 730.`));\n }\n return { start: daysAgoIso(days), end: todayIso() };\n}\n\n/**\n * Resolve scope IDs. Each level expects a different flag — but we accept\n * --account-id at every level when level=account, and --campaign-id /\n * --campaign-group-id / --creative-id otherwise. CSV-encoded for multi-id.\n */\nfunction resolveScopeIds(args: Record<string, unknown>, level: LevelName): string[] {\n if (level === \"account\") {\n const id = resolveAccountIdArg(args);\n return [id];\n }\n if (level === \"campaign-group\") {\n const raw = (args[\"campaign-group-id\"] as string | undefined) ?? (args.ids as string | undefined);\n if (!raw) {\n handleLinkedinError(new Error(\"Pass --campaign-group-id (CSV for multi) when --level campaign-group.\"));\n }\n return commaSplit(raw) ?? [];\n }\n if (level === \"campaign\") {\n const raw = (args[\"campaign-id\"] as string | undefined) ?? (args.ids as string | undefined);\n if (!raw) {\n handleLinkedinError(new Error(\"Pass --campaign-id (CSV for multi) when --level campaign.\"));\n }\n return commaSplit(raw) ?? [];\n }\n // creative\n const raw = (args[\"creative-id\"] as string | undefined) ?? (args.ids as string | undefined);\n if (!raw) {\n handleLinkedinError(new Error(\"Pass --creative-id (CSV for multi) when --level creative.\"));\n }\n return commaSplit(raw) ?? [];\n}\n\n/** Sort rows by spend desc when present, otherwise by impressions desc. */\nfunction sortRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n return [...rows].sort((a, b) => {\n const cs = numberOf(b.costInUsd) - numberOf(a.costInUsd);\n if (cs !== 0) return cs;\n return numberOf(b.impressions) - numberOf(a.impressions);\n });\n}\n\nfunction numberOf(v: unknown): number {\n if (typeof v === \"number\") return Number.isFinite(v) ? v : 0;\n if (typeof v === \"string\") {\n const n = Number(v);\n return Number.isFinite(n) ? n : 0;\n }\n return 0;\n}\n\nexport const analyticsCommand = defineCommand({\n meta: {\n name: \"analytics\",\n description: `Performance reporting — the workhorse for AI agents.\n\nThree-axis design (LinkedIn's superpower over Meta/Google):\n --level account | campaign-group | campaign | creative\n --intent baseline | revenue | funnel | engagement | video | lead-gen | inmail | document | ranking | identity\n --pivot none | job-title | company | industry | seniority | function | company-size | country | region | dma\n | device | placement | serving-location | card-index | objective\n | conversation-node | conversation-node-button\n\nSmart defaults:\n --level account, --intent baseline, --pivot none, --granularity DAILY, last 7 days\n Pivot on a MEMBER_* dim → granularity auto-forced to ALL (LinkedIn rejects DAILY+demographic)\n Demographic data delayed 12-24h with ≥3-event privacy floor — the CLI flags this in warnings.\n --pivot dma → US Nielsen DMA® regions, names resolved. Any report built from it must write \"DMA®\"\n and carry Nielsen's notice (returned as the DMA_ATTRIBUTION_REQUIRED warning).\n Derived metrics injected client-side: ctr, cpc, cpm, frequency, leadCompletionRate\n\nExamples — common AI questions:\n # \"How is this account doing this week?\"\n baker ads linkedin analytics\n\n # \"Who are we reaching, by job title?\" (the LinkedIn killer)\n baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot job-title --intent baseline --last-days 30\n\n # \"Top companies seeing my ads\" (ABM feedback loop)\n baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot company --last-days 30\n\n # \"Revenue by campaign over Q1\"\n baker ads linkedin analytics --level campaign --campaign-id 1,2,3 --intent revenue --start 2026-01-01 --end 2026-03-31 --granularity MONTHLY\n\n # \"How is the lead form converting?\"\n baker ads linkedin analytics --level campaign --campaign-id 1234 --intent lead-gen\n\n # Custom field set (escape hatch)\n baker ads linkedin analytics --metrics impressions,clicks,oneClickLeads --intent identity`,\n },\n args: {\n level: { type: \"string\", description: \"Object scope (default: account)\" },\n \"account-id\": { type: \"string\", description: \"Account ID — numeric or urn:li:sponsoredAccount:N (level=account)\" },\n \"account-urn\": { type: \"string\", description: \"Alias for --account-id (URN form)\" },\n \"campaign-group-id\": { type: \"string\", description: \"Comma-separated IDs (level=campaign-group)\" },\n \"campaign-id\": { type: \"string\", description: \"Comma-separated IDs (level=campaign)\" },\n \"creative-id\": { type: \"string\", description: \"Comma-separated IDs (level=creative)\" },\n ids: { type: \"string\", description: \"Generic CSV of IDs at the chosen level (alternative to per-level flags)\" },\n intent: {\n type: \"string\",\n description: \"baseline|revenue|funnel|engagement|video|lead-gen|inmail|document|ranking|identity\",\n },\n pivot: { type: \"string\", description: \"Pivot dim. Default: none. See `--list-pivots`.\" },\n metrics: { type: \"string\", description: \"CSV metric override — bypass --intent's bundle\" },\n \"list-intents\": { type: \"boolean\", description: \"Print intent definitions and exit\" },\n \"list-pivots\": { type: \"boolean\", description: \"Print pivot slugs and exit\" },\n start: { type: \"string\", description: \"Start date YYYY-MM-DD (overrides --last-days)\" },\n end: { type: \"string\", description: \"End date YYYY-MM-DD\" },\n \"last-days\": { type: \"string\", description: \"Window relative to today (default: 7)\" },\n granularity: { type: \"string\", description: \"DAILY|MONTHLY|YEARLY|ALL (default: DAILY)\" },\n limit: { type: \"string\", description: \"Max rows (default: 1000)\" },\n \"no-sort\": { type: \"boolean\", description: \"Skip default sort by costInUsd desc\" },\n \"no-cache\": NO_CACHE_ARG,\n output: { type: \"string\", description: \"Output format json|csv|jsonl|md\", default: \"json\" },\n },\n run: async ({ args }) => {\n if (args[\"list-intents\"]) {\n writeAdsJson({ ok: true, data: listIntents() });\n return;\n }\n if (args[\"list-pivots\"]) {\n writeAdsJson({ ok: true, data: ALL_PIVOTS });\n return;\n }\n\n const level = parseLevel(args.level as string | undefined);\n const intent = parseIntent(args.intent as string | undefined);\n const pivot = parsePivot(args.pivot as string | undefined);\n let granularity = parseGranularity(args.granularity as string | undefined);\n\n // CLI-side mirror of the backend's pivot/granularity guard. Backend will\n // also enforce — this lets us echo the auto-correction in stderr early.\n if (MEMBER_PIVOTS.has(pivot) && granularity === \"DAILY\") {\n process.stderr.write(`note: pivot=${pivot} forces --granularity ALL (LinkedIn rejects DAILY + demographic).\\n`);\n granularity = \"ALL\";\n }\n\n const ids = resolveScopeIds(args, level);\n if (ids.length === 0) {\n handleLinkedinError(new Error(`No IDs resolved for --level ${level}`));\n }\n\n const range = resolveDateRange(args);\n const metrics = commaSplit(args.metrics as string | undefined);\n const limit = args.limit ? Number(args.limit) : 1000;\n\n const request: AnalyticsRequest = {\n level,\n ids,\n intent,\n pivot,\n metrics,\n start: range.start,\n end: range.end,\n granularity,\n limit,\n };\n\n try {\n const data = await apiPost<AnalyticsResponse>(\"/api/ads/linkedin/analytics\", {\n request,\n skipCache: Boolean(args[\"no-cache\"]),\n });\n const rows = args[\"no-sort\"] ? data.rows : sortRows(data.rows);\n const fmt = csvOrJson(args);\n if (fmt !== \"json\") {\n writeAdsOutput(rows, fmt, data.fields);\n return;\n }\n writeAdsJson({\n ok: true,\n data: {\n rows,\n fields: data.fields,\n warnings: data.warnings,\n query: data.query,\n // Echo composed fields so an offline agent can pre-flight w/o this network call.\n composedFields: composeFields(intent, level, metrics),\n },\n });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n","/**\n * LinkedIn analytics field bundles. Three-axis design:\n * --intent → metric bundle (baseline | revenue | funnel | engagement | video |\n * lead-gen | inmail | document | ranking | identity)\n * --level → object scope (account | campaign-group | campaign | creative)\n * --pivot → demographic / firmographic breakdown\n * (none | job-title | company | industry | seniority | function |\n * company-size | country | region | dma | device | placement | …)\n *\n * Backend recomputes the field list itself (single source of truth in\n * `packages/backend/convex/ads/linkedin/constants.ts`). The CLI keeps a\n * mirror copy so `--list-intents` / `--list-pivots` work offline.\n */\n\nexport type IntentName =\n | \"baseline\"\n | \"revenue\"\n | \"funnel\"\n | \"engagement\"\n | \"video\"\n | \"lead-gen\"\n | \"inmail\"\n | \"document\"\n | \"ranking\"\n | \"identity\";\n\nexport type LevelName = \"account\" | \"campaign-group\" | \"campaign\" | \"creative\";\n\nexport type PivotSlug =\n | \"none\"\n | \"campaign\"\n | \"campaign-group\"\n | \"creative\"\n | \"company\"\n | \"account\"\n | \"conversion\"\n | \"job-title\"\n | \"job-function\"\n | \"seniority\"\n | \"industry\"\n | \"company-size\"\n | \"country\"\n | \"region\"\n | \"dma\"\n | \"device\"\n | \"placement\"\n | \"serving-location\"\n | \"card-index\"\n | \"objective\"\n | \"conversation-node\"\n | \"conversation-node-button\";\n\ninterface IntentDefinition {\n name: IntentName;\n description: string;\n metrics: string[];\n /** Derived (CLI-side) metrics this bundle materializes. Documentation only. */\n derived?: string[];\n}\n\nexport const INTENTS: Record<IntentName, IntentDefinition> = {\n baseline: {\n name: \"baseline\",\n description: \"Spend, impressions, clicks. The default 'how is delivery?' question. Derives CTR, CPC, CPM.\",\n metrics: [\"impressions\", \"clicks\", \"costInUsd\", \"costInLocalCurrency\", \"approximateUniqueImpressions\"],\n derived: [\"ctr\", \"cpc\", \"cpm\", \"frequency\"],\n },\n revenue: {\n name: \"revenue\",\n description: \"Spend, conversions, conversion value. 'How much money are we making?'\",\n metrics: [\n \"costInUsd\",\n \"externalWebsiteConversions\",\n \"externalWebsitePostClickConversions\",\n \"externalWebsitePostViewConversions\",\n \"conversionValueInLocalCurrency\",\n \"oneClickLeads\",\n ],\n },\n funnel: {\n name: \"funnel\",\n description: \"Impression → click → landing → form open → lead → conversion. 'Where do users drop off?'\",\n metrics: [\n \"impressions\",\n \"clicks\",\n \"landingPageClicks\",\n \"oneClickLeadFormOpens\",\n \"oneClickLeads\",\n \"externalWebsiteConversions\",\n \"costInUsd\",\n ],\n derived: [\"ctr\", \"leadCompletionRate\"],\n },\n engagement: {\n name: \"engagement\",\n description: \"Likes, comments, shares, follows + viral spillover. TLA-aware — measures organic reach effect.\",\n metrics: [\n \"impressions\",\n \"likes\",\n \"comments\",\n \"shares\",\n \"reactions\",\n \"follows\",\n \"totalEngagements\",\n \"viralImpressions\",\n \"viralLikes\",\n \"viralShares\",\n \"viralOneClickLeads\",\n \"costInUsd\",\n ],\n },\n video: {\n name: \"video\",\n description: \"Video watch quartiles + cost. 'How are video creatives holding attention?'\",\n metrics: [\n \"videoStarts\",\n \"videoFirstQuartileCompletions\",\n \"videoMidpointCompletions\",\n \"videoThirdQuartileCompletions\",\n \"videoCompletions\",\n \"videoViews\",\n \"fullScreenPlays\",\n \"costInUsd\",\n \"impressions\",\n ],\n },\n \"lead-gen\": {\n name: \"lead-gen\",\n description: \"Lead Gen Form opens + completions. CLI derives form-completion-rate.\",\n metrics: [\n \"oneClickLeadFormOpens\",\n \"oneClickLeads\",\n \"viralOneClickLeads\",\n \"viralOneClickLeadFormOpens\",\n \"costInUsd\",\n ],\n derived: [\"leadCompletionRate\"],\n },\n inmail: {\n name: \"inmail\",\n description: \"Sponsored Message / Conversation Ads — sends, opens, clicks, lead-gen taps.\",\n metrics: [\n \"sends\",\n \"opens\",\n \"clicks\",\n \"costInUsd\",\n \"leadGenerationMailContactInfoShares\",\n \"leadGenerationMailInterestedClicks\",\n ],\n },\n document: {\n name: \"document\",\n description: \"Document Ads — quartile read-through, completion, downloads.\",\n metrics: [\n \"documentFirstQuartileCompletions\",\n \"documentMidpointCompletions\",\n \"documentThirdQuartileCompletions\",\n \"documentCompletions\",\n \"downloadClicks\",\n \"costInUsd\",\n \"impressions\",\n ],\n },\n ranking: {\n name: \"ranking\",\n description:\n \"Frequency + reach metrics for fatigue detection. CLI derives frequency = impressions/uniqueImpressions.\",\n metrics: [\"impressions\", \"clicks\", \"costInUsd\", \"approximateUniqueImpressions\"],\n derived: [\"frequency\", \"ctr\"],\n },\n identity: {\n name: \"identity\",\n description: \"Just spend + impressions. Cheap roll-up.\",\n metrics: [\"costInUsd\", \"impressions\"],\n },\n};\n\n/** Pivots that LinkedIn rejects with DAILY granularity — CLI auto-forces ALL. */\nexport const MEMBER_PIVOTS = new Set<PivotSlug>([\n \"company\",\n \"job-title\",\n \"job-function\",\n \"seniority\",\n \"industry\",\n \"company-size\",\n \"country\",\n \"region\",\n \"dma\",\n]);\n\nexport const ALL_PIVOTS: PivotSlug[] = [\n \"none\",\n \"campaign\",\n \"campaign-group\",\n \"creative\",\n \"company\",\n \"account\",\n \"conversion\",\n \"job-title\",\n \"job-function\",\n \"seniority\",\n \"industry\",\n \"company-size\",\n \"country\",\n \"region\",\n \"dma\",\n \"device\",\n \"placement\",\n \"serving-location\",\n \"card-index\",\n \"objective\",\n \"conversation-node\",\n \"conversation-node-button\",\n];\n\nexport const ALL_LEVELS: LevelName[] = [\"account\", \"campaign-group\", \"campaign\", \"creative\"];\n\nexport function getIntent(name: string): IntentDefinition | undefined {\n return INTENTS[name as IntentName];\n}\n\nexport function listIntents(): IntentDefinition[] {\n return Object.values(INTENTS);\n}\n\nexport function isPivot(slug: string): slug is PivotSlug {\n return (ALL_PIVOTS as string[]).includes(slug);\n}\n\nexport function isLevel(slug: string): slug is LevelName {\n return (ALL_LEVELS as string[]).includes(slug);\n}\n\n/**\n * Compose final field list — intent bundle + identity columns + pivotValues +\n * dateRange. Backend re-validates and recomposes; this is just for offline\n * preview (`baker ads linkedin analytics --list-intents`).\n */\nexport function composeFields(intent: IntentName, _level: LevelName, metricsOverride?: string[]): string[] {\n const base = metricsOverride && metricsOverride.length > 0 ? metricsOverride : INTENTS[intent].metrics;\n const seen = new Set<string>();\n const out: string[] = [];\n for (const f of [\"pivotValues\", \"dateRange\", ...base]) {\n if (!seen.has(f)) {\n seen.add(f);\n out.push(f);\n }\n }\n return out;\n}\n"],"mappings":"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","names":["raw"]}
@@ -2,11 +2,12 @@ import {
2
2
  failApi,
3
3
  failValidation,
4
4
  isTempId
5
- } from "./chunk-3HJLHTWP.js";
6
- import "./chunk-XF4JUKVF.js";
5
+ } from "./chunk-SJYEY5MV.js";
6
+ import "./chunk-7EPXVICM.js";
7
7
  import "./chunk-GXDLWBOY.js";
8
8
  import "./chunk-TEINLN64.js";
9
9
  import "./chunk-ZJWUBJYQ.js";
10
+ import "./chunk-HR6IWNKE.js";
10
11
  import "./chunk-NE4F3FHN.js";
11
12
  import {
12
13
  apiPost,
@@ -74,4 +75,4 @@ export {
74
75
  assignBody,
75
76
  assignCommand
76
77
  };
77
- //# sourceMappingURL=assign-ABN2AQ4J.js.map
78
+ //# sourceMappingURL=assign-PTUJUCEL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/actions/assign.ts"],"sourcesContent":["import type { ActionsAssignRequest, ActionsAssignResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost, validateConvexId } from \"../../client.ts\";\nimport { requireChatId } from \"../../env.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi, failValidation, isTempId } from \"./shared.ts\";\n\nregisterSchema({\n command: \"actions.assign\",\n description:\n \"Stage who a Task is assigned to — applies when the chat is published, like every other Task change. --to takes a userId or email from `baker actions members` (only those teammates can be named), or `none` to unassign. Works on a published Task by id or on one this chat is creating by its tempId. Restaging replaces the earlier assignment; drop it with `baker actions draft remove <id> --op assign`. No claim needed; blocked only while another chat has the Task claimed.\",\n args: {\n id: { type: \"string\", description: \"Action ID, or tempId (temp_*) of a Task staged in this chat\", required: true },\n to: {\n type: \"string\",\n description: \"userId or email from `baker actions members`, or `none` to unassign\",\n required: true,\n },\n },\n});\n\n/** The request for one assignment, checked before the round trip. */\nexport function assignBody(args: { ref: string; to?: string }, chatId: string): ActionsAssignRequest {\n const to = args.to?.trim();\n if (!to) {\n failValidation(\"--to is required: a userId or email from `baker actions members`, or `none` to unassign the Task.\");\n }\n if (!isTempId(args.ref)) {\n validateConvexId(args.ref);\n }\n return { chatId, actionRef: args.ref, to };\n}\n\nexport const assignCommand = defineCommand({\n meta: {\n name: \"assign\",\n description:\n \"Stage who a Task is assigned to (applies on publish). Examples: baker actions assign <id> --to maria@empresa.com | baker actions assign temp_brief --to <userId> | baker actions assign <id> --to none\",\n },\n args: {\n id: { type: \"positional\", description: \"Action ID or tempId (temp_*)\", required: false },\n \"action-id\": { type: \"string\", description: \"Action ID or tempId (temp_*)\", required: false },\n to: { type: \"string\", description: \"userId or email from `baker actions members`, or none\", required: false },\n },\n run: async ({ args }) => {\n try {\n const ref = (args.id as string | undefined) || (args[\"action-id\"] as string | undefined);\n if (!ref) {\n failValidation(\"Action ID is required.\");\n }\n const body = assignBody({ ref, ...(typeof args.to === \"string\" ? { to: args.to } : {}) }, requireChatId());\n const response = await apiPost<ActionsAssignResponse>(\"/api/actions/assign\", body);\n writeJson({ ...response, hints: [\"Staged: the Task changes hands when the chat is published.\"] });\n } catch (err) {\n failApi(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,qBAAqB;AAO9B,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,IAAI,EAAE,MAAM,UAAU,aAAa,+DAA+D,UAAU,KAAK;AAAA,IACjH,IAAI;AAAA,MACF,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,EACF;AACF,CAAC;AAGM,SAAS,WAAW,MAAoC,QAAsC;AACnG,QAAM,KAAK,KAAK,IAAI,KAAK;AACzB,MAAI,CAAC,IAAI;AACP,mBAAe,mGAAmG;AAAA,EACpH;AACA,MAAI,CAAC,SAAS,KAAK,GAAG,GAAG;AACvB,qBAAiB,KAAK,GAAG;AAAA,EAC3B;AACA,SAAO,EAAE,QAAQ,WAAW,KAAK,KAAK,GAAG;AAC3C;AAEO,IAAM,gBAAgB,cAAc;AAAA,EACzC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACJ,IAAI,EAAE,MAAM,cAAc,aAAa,gCAAgC,UAAU,MAAM;AAAA,IACvF,aAAa,EAAE,MAAM,UAAU,aAAa,gCAAgC,UAAU,MAAM;AAAA,IAC5F,IAAI,EAAE,MAAM,UAAU,aAAa,yDAAyD,UAAU,MAAM;AAAA,EAC9G;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,QAAI;AACF,YAAM,MAAO,KAAK,MAA8B,KAAK,WAAW;AAChE,UAAI,CAAC,KAAK;AACR,uBAAe,wBAAwB;AAAA,MACzC;AACA,YAAM,OAAO,WAAW,EAAE,KAAK,GAAI,OAAO,KAAK,OAAO,WAAW,EAAE,IAAI,KAAK,GAAG,IAAI,CAAC,EAAG,GAAG,cAAc,CAAC;AACzG,YAAM,WAAW,MAAM,QAA+B,uBAAuB,IAAI;AACjF,gBAAU,EAAE,GAAG,UAAU,OAAO,CAAC,4DAA4D,EAAE,CAAC;AAAA,IAClG,SAAS,KAAK;AACZ,cAAQ,GAAG;AAAA,IACb;AAAA,EACF;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/commands/actions/assign.ts"],"sourcesContent":["import type { ActionsAssignRequest, ActionsAssignResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost, validateConvexId } from \"../../client.ts\";\nimport { requireChatId } from \"../../env.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi, failValidation, isTempId } from \"./shared.ts\";\n\nregisterSchema({\n command: \"actions.assign\",\n description:\n \"Stage who a Task is assigned to — applies when the chat is published, like every other Task change. --to takes a userId or email from `baker actions members` (only those teammates can be named), or `none` to unassign. Works on a published Task by id or on one this chat is creating by its tempId. Restaging replaces the earlier assignment; drop it with `baker actions draft remove <id> --op assign`. No claim needed; blocked only while another chat has the Task claimed.\",\n args: {\n id: { type: \"string\", description: \"Action ID, or tempId (temp_*) of a Task staged in this chat\", required: true },\n to: {\n type: \"string\",\n description: \"userId or email from `baker actions members`, or `none` to unassign\",\n required: true,\n },\n },\n});\n\n/** The request for one assignment, checked before the round trip. */\nexport function assignBody(args: { ref: string; to?: string }, chatId: string): ActionsAssignRequest {\n const to = args.to?.trim();\n if (!to) {\n failValidation(\"--to is required: a userId or email from `baker actions members`, or `none` to unassign the Task.\");\n }\n if (!isTempId(args.ref)) {\n validateConvexId(args.ref);\n }\n return { chatId, actionRef: args.ref, to };\n}\n\nexport const assignCommand = defineCommand({\n meta: {\n name: \"assign\",\n description:\n \"Stage who a Task is assigned to (applies on publish). Examples: baker actions assign <id> --to maria@empresa.com | baker actions assign temp_brief --to <userId> | baker actions assign <id> --to none\",\n },\n args: {\n id: { type: \"positional\", description: \"Action ID or tempId (temp_*)\", required: false },\n \"action-id\": { type: \"string\", description: \"Action ID or tempId (temp_*)\", required: false },\n to: { type: \"string\", description: \"userId or email from `baker actions members`, or none\", required: false },\n },\n run: async ({ args }) => {\n try {\n const ref = (args.id as string | undefined) || (args[\"action-id\"] as string | undefined);\n if (!ref) {\n failValidation(\"Action ID is required.\");\n }\n const body = assignBody({ ref, ...(typeof args.to === \"string\" ? { to: args.to } : {}) }, requireChatId());\n const response = await apiPost<ActionsAssignResponse>(\"/api/actions/assign\", body);\n writeJson({ ...response, hints: [\"Staged: the Task changes hands when the chat is published.\"] });\n } catch (err) {\n failApi(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,qBAAqB;AAO9B,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,IAAI,EAAE,MAAM,UAAU,aAAa,+DAA+D,UAAU,KAAK;AAAA,IACjH,IAAI;AAAA,MACF,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,EACF;AACF,CAAC;AAGM,SAAS,WAAW,MAAoC,QAAsC;AACnG,QAAM,KAAK,KAAK,IAAI,KAAK;AACzB,MAAI,CAAC,IAAI;AACP,mBAAe,mGAAmG;AAAA,EACpH;AACA,MAAI,CAAC,SAAS,KAAK,GAAG,GAAG;AACvB,qBAAiB,KAAK,GAAG;AAAA,EAC3B;AACA,SAAO,EAAE,QAAQ,WAAW,KAAK,KAAK,GAAG;AAC3C;AAEO,IAAM,gBAAgB,cAAc;AAAA,EACzC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACJ,IAAI,EAAE,MAAM,cAAc,aAAa,gCAAgC,UAAU,MAAM;AAAA,IACvF,aAAa,EAAE,MAAM,UAAU,aAAa,gCAAgC,UAAU,MAAM;AAAA,IAC5F,IAAI,EAAE,MAAM,UAAU,aAAa,yDAAyD,UAAU,MAAM;AAAA,EAC9G;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,QAAI;AACF,YAAM,MAAO,KAAK,MAA8B,KAAK,WAAW;AAChE,UAAI,CAAC,KAAK;AACR,uBAAe,wBAAwB;AAAA,MACzC;AACA,YAAM,OAAO,WAAW,EAAE,KAAK,GAAI,OAAO,KAAK,OAAO,WAAW,EAAE,IAAI,KAAK,GAAG,IAAI,CAAC,EAAG,GAAG,cAAc,CAAC;AACzG,YAAM,WAAW,MAAM,QAA+B,uBAAuB,IAAI;AACjF,gBAAU,EAAE,GAAG,UAAU,OAAO,CAAC,4DAA4D,EAAE,CAAC;AAAA,IAClG,SAAS,KAAK;AACZ,cAAQ,GAAG;AAAA,IACb;AAAA,EACF;AACF,CAAC;","names":[]}
@@ -1,17 +1,18 @@
1
1
  import {
2
2
  handleLinkedinError,
3
3
  resolveAccountIdArg
4
- } from "./chunk-CSYSX4D2.js";
4
+ } from "./chunk-N4LAYIIN.js";
5
5
  import {
6
6
  writeAdsJson
7
7
  } from "./chunk-VFIOJD5M.js";
8
8
  import {
9
9
  NO_CACHE_ARG
10
10
  } from "./chunk-X7ZODEXJ.js";
11
- import "./chunk-XF4JUKVF.js";
11
+ import "./chunk-7EPXVICM.js";
12
12
  import "./chunk-GXDLWBOY.js";
13
13
  import "./chunk-TEINLN64.js";
14
14
  import "./chunk-ZJWUBJYQ.js";
15
+ import "./chunk-HR6IWNKE.js";
15
16
  import "./chunk-NE4F3FHN.js";
16
17
  import {
17
18
  apiPost
@@ -91,4 +92,4 @@ Examples:
91
92
  export {
92
93
  audienceSizeCommand
93
94
  };
94
- //# sourceMappingURL=audience-size-GNBJY35X.js.map
95
+ //# sourceMappingURL=audience-size-LRI6GJRT.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/ads/linkedin/audience-size.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiPost } from \"../../../client.ts\";\nimport { writeAdsJson } from \"../output.ts\";\nimport { handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\ninterface AudienceSizeResult {\n total: number;\n active: number;\n warnings: string[];\n}\n\n/**\n * Read targeting JSON from --targeting-file, --targeting (inline JSON), or\n * stdin. Returns the parsed object — failure exits via handleLinkedinError.\n */\nfunction loadTargeting(args: Record<string, unknown>): unknown {\n const inline = args.targeting as string | undefined;\n if (inline) {\n try {\n return JSON.parse(inline);\n } catch {\n handleLinkedinError(new Error(\"--targeting must be valid JSON. See LinkedIn 'targetingCriteria' shape.\"));\n }\n }\n const file = args[\"targeting-file\"] as string | undefined;\n if (file) {\n try {\n return JSON.parse(readFileSync(file, \"utf-8\"));\n } catch (e) {\n handleLinkedinError(\n new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : \"I/O error\"}`),\n );\n }\n }\n handleLinkedinError(new Error(\"Pass --targeting-file <path> or --targeting '{...JSON...}'\"));\n}\n\nexport const audienceSizeCommand = defineCommand({\n meta: {\n name: \"audience-size\",\n description: `Estimate audience size for a targeting payload — pre-launch sanity check.\n\nReturns total + active counts plus playbook §04 warnings:\n size <20K → too narrow (will not deliver)\n size <50K → outside the 50K–500K sweet spot\n size >500K → outside the sweet spot\n size >1M → too broad, refine ICP\n\nThe targeting payload must follow LinkedIn's 'targetingCriteria' shape — an\ninclude/exclude tree of and/or boolean operators with adTargetingFacet keys.\nThe simplest form:\n { \"include\": { \"and\": [{ \"or\": { \"urn:li:adTargetingFacet:locations\": [\"urn:li:geo:103644278\"] }}]}}\n\nExamples:\n baker ads linkedin audience-size --account-id 503001492 --targeting-file targeting.json\n baker ads linkedin audience-size --account-id 503001492 --targeting '{\"include\":{\"and\":[]}}'`,\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 targeting: { type: \"string\", description: \"Inline JSON targetingCriteria payload\" },\n \"targeting-file\": { type: \"string\", description: \"Path to JSON file with targetingCriteria\" },\n \"no-cache\": NO_CACHE_ARG,\n output: { type: \"string\", description: \"json\", default: \"json\" },\n },\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n const targetingCriteria = loadTargeting(args);\n try {\n const data = await apiPost<AudienceSizeResult>(\"/api/ads/linkedin/audience-size\", {\n accountId,\n targetingCriteria,\n skipCache: Boolean(args[\"no-cache\"]),\n });\n writeAdsJson({ ok: true, data });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAgB9B,SAAS,cAAc,MAAwC;AAC7D,QAAM,SAAS,KAAK;AACpB,MAAI,QAAQ;AACV,QAAI;AACF,aAAO,KAAK,MAAM,MAAM;AAAA,IAC1B,QAAQ;AACN,0BAAoB,IAAI,MAAM,yEAAyE,CAAC;AAAA,IAC1G;AAAA,EACF;AACA,QAAM,OAAO,KAAK,gBAAgB;AAClC,MAAI,MAAM;AACR,QAAI;AACF,aAAO,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,IAC/C,SAAS,GAAG;AACV;AAAA,QACE,IAAI,MAAM,oCAAoC,aAAa,QAAQ,EAAE,UAAU,WAAW,EAAE;AAAA,MAC9F;AAAA,IACF;AAAA,EACF;AACA,sBAAoB,IAAI,MAAM,4DAA4D,CAAC;AAC7F;AAEO,IAAM,sBAAsB,cAAc;AAAA,EAC/C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBf;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,wCAAwC;AAAA,IAClF,kBAAkB,EAAE,MAAM,UAAU,aAAa,2CAA2C;AAAA,IAC5F,YAAY;AAAA,IACZ,QAAQ,EAAE,MAAM,UAAU,aAAa,QAAQ,SAAS,OAAO;AAAA,EACjE;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,YAAY,oBAAoB,IAAI;AAC1C,UAAM,oBAAoB,cAAc,IAAI;AAC5C,QAAI;AACF,YAAM,OAAO,MAAM,QAA4B,mCAAmC;AAAA,QAChF;AAAA,QACA;AAAA,QACA,WAAW,QAAQ,KAAK,UAAU,CAAC;AAAA,MACrC,CAAC;AACD,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/audience-size.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiPost } from \"../../../client.ts\";\nimport { writeAdsJson } from \"../output.ts\";\nimport { handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\ninterface AudienceSizeResult {\n total: number;\n active: number;\n warnings: string[];\n}\n\n/**\n * Read targeting JSON from --targeting-file, --targeting (inline JSON), or\n * stdin. Returns the parsed object — failure exits via handleLinkedinError.\n */\nfunction loadTargeting(args: Record<string, unknown>): unknown {\n const inline = args.targeting as string | undefined;\n if (inline) {\n try {\n return JSON.parse(inline);\n } catch {\n handleLinkedinError(new Error(\"--targeting must be valid JSON. See LinkedIn 'targetingCriteria' shape.\"));\n }\n }\n const file = args[\"targeting-file\"] as string | undefined;\n if (file) {\n try {\n return JSON.parse(readFileSync(file, \"utf-8\"));\n } catch (e) {\n handleLinkedinError(\n new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : \"I/O error\"}`),\n );\n }\n }\n handleLinkedinError(new Error(\"Pass --targeting-file <path> or --targeting '{...JSON...}'\"));\n}\n\nexport const audienceSizeCommand = defineCommand({\n meta: {\n name: \"audience-size\",\n description: `Estimate audience size for a targeting payload — pre-launch sanity check.\n\nReturns total + active counts plus playbook §04 warnings:\n size <20K → too narrow (will not deliver)\n size <50K → outside the 50K–500K sweet spot\n size >500K → outside the sweet spot\n size >1M → too broad, refine ICP\n\nThe targeting payload must follow LinkedIn's 'targetingCriteria' shape — an\ninclude/exclude tree of and/or boolean operators with adTargetingFacet keys.\nThe simplest form:\n { \"include\": { \"and\": [{ \"or\": { \"urn:li:adTargetingFacet:locations\": [\"urn:li:geo:103644278\"] }}]}}\n\nExamples:\n baker ads linkedin audience-size --account-id 503001492 --targeting-file targeting.json\n baker ads linkedin audience-size --account-id 503001492 --targeting '{\"include\":{\"and\":[]}}'`,\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 targeting: { type: \"string\", description: \"Inline JSON targetingCriteria payload\" },\n \"targeting-file\": { type: \"string\", description: \"Path to JSON file with targetingCriteria\" },\n \"no-cache\": NO_CACHE_ARG,\n output: { type: \"string\", description: \"json\", default: \"json\" },\n },\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n const targetingCriteria = loadTargeting(args);\n try {\n const data = await apiPost<AudienceSizeResult>(\"/api/ads/linkedin/audience-size\", {\n accountId,\n targetingCriteria,\n skipCache: Boolean(args[\"no-cache\"]),\n });\n writeAdsJson({ ok: true, data });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAgB9B,SAAS,cAAc,MAAwC;AAC7D,QAAM,SAAS,KAAK;AACpB,MAAI,QAAQ;AACV,QAAI;AACF,aAAO,KAAK,MAAM,MAAM;AAAA,IAC1B,QAAQ;AACN,0BAAoB,IAAI,MAAM,yEAAyE,CAAC;AAAA,IAC1G;AAAA,EACF;AACA,QAAM,OAAO,KAAK,gBAAgB;AAClC,MAAI,MAAM;AACR,QAAI;AACF,aAAO,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,IAC/C,SAAS,GAAG;AACV;AAAA,QACE,IAAI,MAAM,oCAAoC,aAAa,QAAQ,EAAE,UAAU,WAAW,EAAE;AAAA,MAC9F;AAAA,IACF;AAAA,EACF;AACA,sBAAoB,IAAI,MAAM,4DAA4D,CAAC;AAC7F;AAEO,IAAM,sBAAsB,cAAc;AAAA,EAC/C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBf;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,wCAAwC;AAAA,IAClF,kBAAkB,EAAE,MAAM,UAAU,aAAa,2CAA2C;AAAA,IAC5F,YAAY;AAAA,IACZ,QAAQ,EAAE,MAAM,UAAU,aAAa,QAAQ,SAAS,OAAO;AAAA,EACjE;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,YAAY,oBAAoB,IAAI;AAC1C,UAAM,oBAAoB,cAAc,IAAI;AAC5C,QAAI;AACF,YAAM,OAAO,MAAM,QAA4B,mCAAmC;AAAA,QAChF;AAAA,QACA;AAAA,QACA,WAAW,QAAQ,KAAK,UAAU,CAAC;AAAA,MACrC,CAAC;AACD,mBAAa,EAAE,IAAI,MAAM,KAAK,CAAC;AAAA,IACjC,SAAS,KAAK;AACZ,0BAAoB,GAAG;AAAA,IACzB;AAAA,EACF;AACF,CAAC;","names":[]}
@@ -1,17 +1,18 @@
1
1
  import {
2
2
  handleLinkedinError,
3
3
  resolveAccountIdArg
4
- } from "./chunk-CSYSX4D2.js";
4
+ } from "./chunk-N4LAYIIN.js";
5
5
  import {
6
6
  writeAdsJson
7
7
  } from "./chunk-VFIOJD5M.js";
8
8
  import {
9
9
  NO_CACHE_ARG
10
10
  } from "./chunk-X7ZODEXJ.js";
11
- import "./chunk-XF4JUKVF.js";
11
+ import "./chunk-7EPXVICM.js";
12
12
  import "./chunk-GXDLWBOY.js";
13
13
  import "./chunk-TEINLN64.js";
14
14
  import "./chunk-ZJWUBJYQ.js";
15
+ import "./chunk-HR6IWNKE.js";
15
16
  import "./chunk-NE4F3FHN.js";
16
17
  import {
17
18
  apiPost
@@ -148,4 +149,4 @@ Examples:
148
149
  export {
149
150
  auditCommand
150
151
  };
151
- //# sourceMappingURL=audit-3VS63TBW.js.map
152
+ //# sourceMappingURL=audit-HWP7OPB7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/ads/linkedin/audit.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiPost } from \"../../../client.ts\";\nimport { writeAdsJson } from \"../output.ts\";\nimport { handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\ninterface AuditFinding {\n id: string;\n area: string;\n check: string;\n status: \"pass\" | \"fail\" | \"partial\" | \"warn\" | \"n_a\";\n severity: \"critical\" | \"high\" | \"medium\" | \"low\";\n evidence?: Record<string, unknown>;\n fix?: { explanation: string; playbookRef?: string; correctedCommand?: string };\n}\n\ninterface AuditResult {\n account: { urn: string; id: string; name: string };\n scope: { campaigns: number; creatives: number; windowDays: number };\n summary: {\n critical: number;\n high: number;\n medium: number;\n low: number;\n pass: number;\n n_a: number;\n totalChecks: number;\n };\n findings: AuditFinding[];\n}\n\nconst SEVERITY_RANK: Record<AuditFinding[\"severity\"], number> = {\n critical: 0,\n high: 1,\n medium: 2,\n low: 3,\n};\n\nconst STATUS_RANK: Record<AuditFinding[\"status\"], number> = {\n fail: 0,\n warn: 1,\n partial: 2,\n pass: 3,\n n_a: 4,\n};\n\nfunction filterFindings(\n findings: AuditFinding[],\n severity: string[] | undefined,\n area: string[] | undefined,\n): AuditFinding[] {\n return findings.filter((f) => {\n if (severity && !severity.includes(f.severity)) return false;\n if (area && !area.includes(f.area)) return false;\n return true;\n });\n}\n\nfunction sortFindings(findings: AuditFinding[]): AuditFinding[] {\n return [...findings].sort((a, b) => {\n const sa = STATUS_RANK[a.status] - STATUS_RANK[b.status];\n if (sa !== 0) return sa;\n return SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity];\n });\n}\n\n/**\n * Render the audit as a markdown table that mirrors\n * google-ads-playbook/10-audit-summary.md so the agent can drop it into a\n * client deliverable as-is.\n */\nfunction renderMarkdown(result: AuditResult): string {\n const lines: string[] = [];\n lines.push(`# LinkedIn Ads Audit — ${result.account.name} (${result.account.id})`);\n lines.push(\"\");\n lines.push(\n `**Scope:** ${result.scope.campaigns} campaigns, ${result.scope.creatives} creatives, last ${result.scope.windowDays}d`,\n );\n lines.push(\"\");\n lines.push(\n `**Summary:** ${result.summary.pass} pass • ${result.summary.critical} critical • ${result.summary.high} high • ${result.summary.medium} medium • ${result.summary.low} low • ${result.summary.n_a} n/a (${result.summary.totalChecks} total)`,\n );\n lines.push(\"\");\n lines.push(\"| # | Area | Check | Status | Severity | Notes |\");\n lines.push(\"|---|------|-------|--------|----------|-------|\");\n result.findings.forEach((f, idx) => {\n const note = noteOf(f);\n lines.push(\n `| ${idx + 1} | ${f.area} | ${escapeMd(f.check)} | ${f.status.toUpperCase()} | ${f.severity} | ${escapeMd(note)} |`,\n );\n });\n return lines.join(\"\\n\");\n}\n\nfunction escapeMd(text: string): string {\n return text.replace(/\\|/g, \"\\\\|\").replace(/\\n/g, \" \");\n}\n\nfunction noteOf(f: AuditFinding): string {\n if (f.status === \"pass\") return \"\";\n const ev = f.evidence ? JSON.stringify(f.evidence) : \"\";\n const fix = f.fix?.explanation ?? \"\";\n return [fix, ev].filter(Boolean).join(\" — \");\n}\n\nexport const auditCommand = defineCommand({\n meta: {\n name: \"audit\",\n description: `Run a LinkedIn Ads playbook audit — 30+ checks across Settings, Tracking,\nAudience, Campaigns, Creative, Performance, Bidding, and Compliance.\n\nEach finding has {id, area, check, status, severity, evidence, fix} fields with\nplaybook citations. The default JSON output is agent-friendly; --format md\nrenders a deliverable-ready table that mirrors the google-ads-playbook\n10-audit-summary.md style.\n\nExit code 0 always. Use the JSON 'summary' counts to decide if action is needed.\n\nExamples:\n baker ads linkedin audit --account-id 503001492\n baker ads linkedin audit --account-id 503001492 --campaign-id 1234 # narrow scope\n baker ads linkedin audit --account-id 503001492 --window-days 90\n baker ads linkedin audit --account-id 503001492 --severity critical,high\n baker ads linkedin audit --account-id 503001492 --area Settings,Tracking\n baker ads linkedin audit --account-id 503001492 --format md`,\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 \"campaign-id\": { type: \"string\", description: \"Narrow scope to a single campaign\" },\n \"window-days\": { type: \"string\", description: \"Lookback window for performance checks (default: 30)\" },\n severity: { type: \"string\", description: \"CSV severity filter: critical,high,medium,low\" },\n area: {\n type: \"string\",\n description:\n \"CSV area filter: Settings,Tracking,Audience,Campaigns,Creative,Performance,Bidding,Compliance,Hygiene\",\n },\n format: { type: \"string\", description: \"Output format: json | md (default: json)\" },\n \"no-cache\": NO_CACHE_ARG,\n },\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n const windowDays = args[\"window-days\"] ? Number(args[\"window-days\"]) : 30;\n if (!Number.isFinite(windowDays) || windowDays < 1 || windowDays > 365) {\n handleLinkedinError(new Error(\"--window-days must be 1..365\"));\n }\n try {\n const data = await apiPost<AuditResult>(\"/api/ads/linkedin/audit\", {\n accountId,\n campaignId: args[\"campaign-id\"] ? String(args[\"campaign-id\"]) : undefined,\n windowDays,\n skipCache: Boolean(args[\"no-cache\"]),\n });\n\n const severityFilter = (args.severity as string | undefined)\n ?.split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean);\n const areaFilter = (args.area as string | undefined)\n ?.split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n const filtered = filterFindings(data.findings, severityFilter, areaFilter);\n const sorted = sortFindings(filtered);\n const result: AuditResult = { ...data, findings: sorted };\n\n const fmt = (args.format as string | undefined) ?? \"json\";\n if (fmt === \"md\") {\n process.stdout.write(`${renderMarkdown(result)}\\n`);\n return;\n }\n writeAdsJson({ ok: true, data: result });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/commands/ads/linkedin/audit.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiPost } from \"../../../client.ts\";\nimport { writeAdsJson } from \"../output.ts\";\nimport { handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\ninterface AuditFinding {\n id: string;\n area: string;\n check: string;\n status: \"pass\" | \"fail\" | \"partial\" | \"warn\" | \"n_a\";\n severity: \"critical\" | \"high\" | \"medium\" | \"low\";\n evidence?: Record<string, unknown>;\n fix?: { explanation: string; playbookRef?: string; correctedCommand?: string };\n}\n\ninterface AuditResult {\n account: { urn: string; id: string; name: string };\n scope: { campaigns: number; creatives: number; windowDays: number };\n summary: {\n critical: number;\n high: number;\n medium: number;\n low: number;\n pass: number;\n n_a: number;\n totalChecks: number;\n };\n findings: AuditFinding[];\n}\n\nconst SEVERITY_RANK: Record<AuditFinding[\"severity\"], number> = {\n critical: 0,\n high: 1,\n medium: 2,\n low: 3,\n};\n\nconst STATUS_RANK: Record<AuditFinding[\"status\"], number> = {\n fail: 0,\n warn: 1,\n partial: 2,\n pass: 3,\n n_a: 4,\n};\n\nfunction filterFindings(\n findings: AuditFinding[],\n severity: string[] | undefined,\n area: string[] | undefined,\n): AuditFinding[] {\n return findings.filter((f) => {\n if (severity && !severity.includes(f.severity)) return false;\n if (area && !area.includes(f.area)) return false;\n return true;\n });\n}\n\nfunction sortFindings(findings: AuditFinding[]): AuditFinding[] {\n return [...findings].sort((a, b) => {\n const sa = STATUS_RANK[a.status] - STATUS_RANK[b.status];\n if (sa !== 0) return sa;\n return SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity];\n });\n}\n\n/**\n * Render the audit as a markdown table that mirrors\n * google-ads-playbook/10-audit-summary.md so the agent can drop it into a\n * client deliverable as-is.\n */\nfunction renderMarkdown(result: AuditResult): string {\n const lines: string[] = [];\n lines.push(`# LinkedIn Ads Audit — ${result.account.name} (${result.account.id})`);\n lines.push(\"\");\n lines.push(\n `**Scope:** ${result.scope.campaigns} campaigns, ${result.scope.creatives} creatives, last ${result.scope.windowDays}d`,\n );\n lines.push(\"\");\n lines.push(\n `**Summary:** ${result.summary.pass} pass • ${result.summary.critical} critical • ${result.summary.high} high • ${result.summary.medium} medium • ${result.summary.low} low • ${result.summary.n_a} n/a (${result.summary.totalChecks} total)`,\n );\n lines.push(\"\");\n lines.push(\"| # | Area | Check | Status | Severity | Notes |\");\n lines.push(\"|---|------|-------|--------|----------|-------|\");\n result.findings.forEach((f, idx) => {\n const note = noteOf(f);\n lines.push(\n `| ${idx + 1} | ${f.area} | ${escapeMd(f.check)} | ${f.status.toUpperCase()} | ${f.severity} | ${escapeMd(note)} |`,\n );\n });\n return lines.join(\"\\n\");\n}\n\nfunction escapeMd(text: string): string {\n return text.replace(/\\|/g, \"\\\\|\").replace(/\\n/g, \" \");\n}\n\nfunction noteOf(f: AuditFinding): string {\n if (f.status === \"pass\") return \"\";\n const ev = f.evidence ? JSON.stringify(f.evidence) : \"\";\n const fix = f.fix?.explanation ?? \"\";\n return [fix, ev].filter(Boolean).join(\" — \");\n}\n\nexport const auditCommand = defineCommand({\n meta: {\n name: \"audit\",\n description: `Run a LinkedIn Ads playbook audit — 30+ checks across Settings, Tracking,\nAudience, Campaigns, Creative, Performance, Bidding, and Compliance.\n\nEach finding has {id, area, check, status, severity, evidence, fix} fields with\nplaybook citations. The default JSON output is agent-friendly; --format md\nrenders a deliverable-ready table that mirrors the google-ads-playbook\n10-audit-summary.md style.\n\nExit code 0 always. Use the JSON 'summary' counts to decide if action is needed.\n\nExamples:\n baker ads linkedin audit --account-id 503001492\n baker ads linkedin audit --account-id 503001492 --campaign-id 1234 # narrow scope\n baker ads linkedin audit --account-id 503001492 --window-days 90\n baker ads linkedin audit --account-id 503001492 --severity critical,high\n baker ads linkedin audit --account-id 503001492 --area Settings,Tracking\n baker ads linkedin audit --account-id 503001492 --format md`,\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 \"campaign-id\": { type: \"string\", description: \"Narrow scope to a single campaign\" },\n \"window-days\": { type: \"string\", description: \"Lookback window for performance checks (default: 30)\" },\n severity: { type: \"string\", description: \"CSV severity filter: critical,high,medium,low\" },\n area: {\n type: \"string\",\n description:\n \"CSV area filter: Settings,Tracking,Audience,Campaigns,Creative,Performance,Bidding,Compliance,Hygiene\",\n },\n format: { type: \"string\", description: \"Output format: json | md (default: json)\" },\n \"no-cache\": NO_CACHE_ARG,\n },\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n const windowDays = args[\"window-days\"] ? Number(args[\"window-days\"]) : 30;\n if (!Number.isFinite(windowDays) || windowDays < 1 || windowDays > 365) {\n handleLinkedinError(new Error(\"--window-days must be 1..365\"));\n }\n try {\n const data = await apiPost<AuditResult>(\"/api/ads/linkedin/audit\", {\n accountId,\n campaignId: args[\"campaign-id\"] ? String(args[\"campaign-id\"]) : undefined,\n windowDays,\n skipCache: Boolean(args[\"no-cache\"]),\n });\n\n const severityFilter = (args.severity as string | undefined)\n ?.split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean);\n const areaFilter = (args.area as string | undefined)\n ?.split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n const filtered = filterFindings(data.findings, severityFilter, areaFilter);\n const sorted = sortFindings(filtered);\n const result: AuditResult = { ...data, findings: sorted };\n\n const fmt = (args.format as string | undefined) ?? \"json\";\n if (fmt === \"md\") {\n process.stdout.write(`${renderMarkdown(result)}\\n`);\n return;\n }\n writeAdsJson({ ok: true, data: result });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  noSerpRowsHints
3
- } from "./chunk-OZRUJVIQ.js";
3
+ } from "./chunk-H3427GPU.js";
4
4
  import {
5
5
  RESEARCH_DATA_NOTE,
6
6
  handleResearchError,
@@ -13,10 +13,11 @@ import {
13
13
  warnDefaults
14
14
  } from "./chunk-LIQ4SQ2T.js";
15
15
  import "./chunk-XCM6XWOB.js";
16
- import "./chunk-XF4JUKVF.js";
16
+ import "./chunk-7EPXVICM.js";
17
17
  import "./chunk-GXDLWBOY.js";
18
18
  import "./chunk-TEINLN64.js";
19
19
  import "./chunk-ZJWUBJYQ.js";
20
+ import "./chunk-HR6IWNKE.js";
20
21
  import "./chunk-NE4F3FHN.js";
21
22
  import {
22
23
  apiPost
@@ -108,4 +109,4 @@ Examples:
108
109
  export {
109
110
  autocompleteCommand
110
111
  };
111
- //# sourceMappingURL=autocomplete-VS3XG3B7.js.map
112
+ //# sourceMappingURL=autocomplete-J6DHU6MR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/research/autocomplete.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { buildResearchQueryContext, warnDefaults } from \"../../geo-context.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { noSerpRowsHints } 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.autocomplete\",\n description:\n \"Get Google Autocomplete suggestions for a seed keyword. Useful for keyword expansion and discovering what people actually search for. If --location and --language are omitted, defaults to United States (us) and English (en).\",\n args: {\n keyword: { type: \"string\", description: \"Seed keyword (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\",\n required: false,\n },\n language: {\n type: \"string\",\n description: \"Language code or name. Defaults to en (English) if omitted\",\n required: false,\n },\n limit: { type: \"string\", description: \"Max suggestions (default: 10, max: 20)\", required: false },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n});\n\ninterface AutocompleteResult {\n suggestion: string;\n}\n\nconst FIELDS: Record<string, string> = {\n suggestion: \"Autocomplete suggestion from Google\",\n};\n\nexport const autocompleteCommand = defineCommand({\n meta: {\n name: \"autocomplete\",\n description: `Get Google Autocomplete suggestions for keyword expansion.\n\nExamples:\n baker research autocomplete \"running shoes\"\n baker research autocomplete \"crm\" --location uk --limit 5`,\n },\n args: {\n keyword: { type: \"positional\", description: \"Seed keyword\", 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 limit: { type: \"string\", description: \"Max suggestions (default: 10, max: 20)\", 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 keyword = args.keyword as string;\n const location = (args.location as string) || undefined;\n const language = (args.language 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<AutocompleteResult[]>(\"/api/research/autocomplete\", {\n keyword,\n location,\n language,\n limit,\n skipCache,\n });\n\n warnDefaults(queryContext);\n const format = (args.output as string) || \"json\";\n const hints = noSerpRowsHints(data.length, queryContext);\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,SAAS,EAAE,MAAM,UAAU,aAAa,6BAA6B,UAAU,KAAK;AAAA,IACpF,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,EAAE,MAAM,UAAU,aAAa,0CAA0C,UAAU,MAAM;AAAA,IAChG,YAAY,EAAE,MAAM,WAAW,aAAa,uCAAuC,UAAU,MAAM;AAAA,EACrG;AACF,CAAC;AAMD,IAAM,SAAiC;AAAA,EACrC,YAAY;AACd;AAEO,IAAM,sBAAsB,cAAc;AAAA,EAC/C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf;AAAA,EACA,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,cAAc,aAAa,gBAAgB,UAAU,KAAK;AAAA,IAC3E,UAAU,EAAE,MAAM,UAAU,aAAa,+CAA+C,UAAU,MAAM;AAAA,IACxG,UAAU,EAAE,MAAM,UAAU,aAAa,uCAAuC,UAAU,MAAM;AAAA,IAChG,OAAO,EAAE,MAAM,UAAU,aAAa,0CAA0C,UAAU,MAAM;AAAA,IAChG,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,UAAU,KAAK;AACrB,UAAM,WAAY,KAAK,YAAuB;AAC9C,UAAM,WAAY,KAAK,YAAuB;AAC9C,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,QAA8B,8BAA8B;AAAA,QAC7E;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,mBAAa,YAAY;AACzB,YAAM,SAAU,KAAK,UAAqB;AAC1C,YAAM,QAAQ,gBAAgB,KAAK,QAAQ,YAAY;AACvD,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/autocomplete.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { buildResearchQueryContext, warnDefaults } from \"../../geo-context.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { noSerpRowsHints } 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.autocomplete\",\n description:\n \"Get Google Autocomplete suggestions for a seed keyword. Useful for keyword expansion and discovering what people actually search for. If --location and --language are omitted, defaults to United States (us) and English (en).\",\n args: {\n keyword: { type: \"string\", description: \"Seed keyword (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\",\n required: false,\n },\n language: {\n type: \"string\",\n description: \"Language code or name. Defaults to en (English) if omitted\",\n required: false,\n },\n limit: { type: \"string\", description: \"Max suggestions (default: 10, max: 20)\", required: false },\n \"no-cache\": { type: \"boolean\", description: \"Skip server cache, hit API directly\", required: false },\n },\n});\n\ninterface AutocompleteResult {\n suggestion: string;\n}\n\nconst FIELDS: Record<string, string> = {\n suggestion: \"Autocomplete suggestion from Google\",\n};\n\nexport const autocompleteCommand = defineCommand({\n meta: {\n name: \"autocomplete\",\n description: `Get Google Autocomplete suggestions for keyword expansion.\n\nExamples:\n baker research autocomplete \"running shoes\"\n baker research autocomplete \"crm\" --location uk --limit 5`,\n },\n args: {\n keyword: { type: \"positional\", description: \"Seed keyword\", 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 limit: { type: \"string\", description: \"Max suggestions (default: 10, max: 20)\", 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 keyword = args.keyword as string;\n const location = (args.location as string) || undefined;\n const language = (args.language 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<AutocompleteResult[]>(\"/api/research/autocomplete\", {\n keyword,\n location,\n language,\n limit,\n skipCache,\n });\n\n warnDefaults(queryContext);\n const format = (args.output as string) || \"json\";\n const hints = noSerpRowsHints(data.length, queryContext);\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,SAAS,EAAE,MAAM,UAAU,aAAa,6BAA6B,UAAU,KAAK;AAAA,IACpF,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,EAAE,MAAM,UAAU,aAAa,0CAA0C,UAAU,MAAM;AAAA,IAChG,YAAY,EAAE,MAAM,WAAW,aAAa,uCAAuC,UAAU,MAAM;AAAA,EACrG;AACF,CAAC;AAMD,IAAM,SAAiC;AAAA,EACrC,YAAY;AACd;AAEO,IAAM,sBAAsB,cAAc;AAAA,EAC/C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf;AAAA,EACA,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,cAAc,aAAa,gBAAgB,UAAU,KAAK;AAAA,IAC3E,UAAU,EAAE,MAAM,UAAU,aAAa,+CAA+C,UAAU,MAAM;AAAA,IACxG,UAAU,EAAE,MAAM,UAAU,aAAa,uCAAuC,UAAU,MAAM;AAAA,IAChG,OAAO,EAAE,MAAM,UAAU,aAAa,0CAA0C,UAAU,MAAM;AAAA,IAChG,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,UAAU,KAAK;AACrB,UAAM,WAAY,KAAK,YAAuB;AAC9C,UAAM,WAAY,KAAK,YAAuB;AAC9C,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,QAA8B,8BAA8B;AAAA,QAC7E;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,mBAAa,YAAY;AACzB,YAAM,SAAU,KAAK,UAAqB;AAC1C,YAAM,QAAQ,gBAAgB,KAAK,QAAQ,YAAY;AACvD,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":[]}
@@ -26,13 +26,13 @@ Full guide: __tooling__/docs/tools/baker/avatars.md`
26
26
  subCommands: {
27
27
  list: () => import("./list-P7NAFN6J.js").then((m) => m.listCommand),
28
28
  get: () => import("./get-YIHTAMRT.js").then((m) => m.getCommand),
29
- create: () => import("./create-BJNMO6HT.js").then((m) => m.createCommand),
30
- research: () => import("./research-YOGE7GT2.js").then((m) => m.researchCommand),
31
- update: () => import("./update-D6DJC6T7.js").then((m) => m.updateCommand),
29
+ create: () => import("./create-EX6OWLNM.js").then((m) => m.createCommand),
30
+ research: () => import("./research-GEOCUBXB.js").then((m) => m.researchCommand),
31
+ update: () => import("./update-PJ67D2OG.js").then((m) => m.updateCommand),
32
32
  delete: () => import("./delete-A5XD52K4.js").then((m) => m.deleteCommand)
33
33
  }
34
34
  });
35
35
  export {
36
36
  avatarsCommand
37
37
  };
38
- //# sourceMappingURL=avatars-EKCKHCC3.js.map
38
+ //# sourceMappingURL=avatars-467OSBD6.js.map
@@ -1,17 +1,18 @@
1
1
  import {
2
2
  handleLinkedinError,
3
3
  resolveAccountIdArg
4
- } from "./chunk-CSYSX4D2.js";
4
+ } from "./chunk-N4LAYIIN.js";
5
5
  import {
6
6
  writeAdsJson
7
7
  } from "./chunk-VFIOJD5M.js";
8
8
  import {
9
9
  NO_CACHE_ARG
10
10
  } from "./chunk-X7ZODEXJ.js";
11
- import "./chunk-XF4JUKVF.js";
11
+ import "./chunk-7EPXVICM.js";
12
12
  import "./chunk-GXDLWBOY.js";
13
13
  import "./chunk-TEINLN64.js";
14
14
  import "./chunk-ZJWUBJYQ.js";
15
+ import "./chunk-HR6IWNKE.js";
15
16
  import "./chunk-NE4F3FHN.js";
16
17
  import {
17
18
  apiPost
@@ -96,4 +97,4 @@ Examples:
96
97
  export {
97
98
  bidPricingCommand
98
99
  };
99
- //# sourceMappingURL=bid-pricing-Q72B65AY.js.map
100
+ //# sourceMappingURL=bid-pricing-EO5WLHGV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/ads/linkedin/bid-pricing.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiPost } from \"../../../client.ts\";\nimport { writeAdsJson } from \"../output.ts\";\nimport { handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\ninterface BidPricingResult {\n bidLimits?: { min?: { amount?: string; currencyCode?: string }; max?: { amount?: string; currencyCode?: string } };\n suggestedBid?: {\n default?: { amount?: string; currencyCode?: string };\n min?: { amount?: string; currencyCode?: string };\n max?: { amount?: string; currencyCode?: string };\n };\n costType: string;\n objectiveType: string;\n playbookFloor?: { amount: string; currencyCode: string };\n playbookNote: string;\n}\n\nfunction loadTargeting(args: Record<string, unknown>): unknown {\n const inline = args.targeting as string | undefined;\n if (inline) {\n try {\n return JSON.parse(inline);\n } catch {\n handleLinkedinError(new Error(\"--targeting must be valid JSON. See LinkedIn 'targetingCriteria' shape.\"));\n }\n }\n const file = args[\"targeting-file\"] as string | undefined;\n if (file) {\n try {\n return JSON.parse(readFileSync(file, \"utf-8\"));\n } catch (e) {\n handleLinkedinError(\n new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : \"I/O error\"}`),\n );\n }\n }\n handleLinkedinError(new Error(\"Pass --targeting-file <path> or --targeting '{...JSON...}'\"));\n}\n\nexport const bidPricingCommand = defineCommand({\n meta: {\n name: \"bid-pricing\",\n description: `Get LinkedIn's suggested bid range for a targeting + objective + cost type.\n\nReturns LinkedIn's min / suggested / max bid plus the playbook §06 floor\n(2/3 of suggested — the recommended manual CPC starting point).\n\nObjective types: BRAND_AWARENESS | WEBSITE_TRAFFIC | WEBSITE_VISIT |\n ENGAGEMENT | WEBSITE_CONVERSION | LEAD_GENERATION |\n JOB_APPLICANT | VIDEO_VIEW\nCost types: CPC | CPM | CPV | CPS\n\nExamples:\n baker ads linkedin bid-pricing --account-id 503001492 --objective WEBSITE_CONVERSION --cost-type CPC --targeting-file targeting.json\n baker ads linkedin bid-pricing --account-id 503001492 --objective LEAD_GENERATION --cost-type CPM --targeting '{\"include\":...}'`,\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 objective: {\n type: \"string\",\n description: \"Objective type (e.g. WEBSITE_CONVERSION, LEAD_GENERATION)\",\n required: true,\n },\n \"cost-type\": { type: \"string\", description: \"CPC | CPM | CPV | CPS\", required: true },\n targeting: { type: \"string\", description: \"Inline JSON targetingCriteria\" },\n \"targeting-file\": { type: \"string\", description: \"Path to JSON file with targetingCriteria\" },\n \"no-cache\": NO_CACHE_ARG,\n output: { type: \"string\", description: \"json\", default: \"json\" },\n },\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n const targetingCriteria = loadTargeting(args);\n try {\n const data = await apiPost<BidPricingResult>(\"/api/ads/linkedin/bid-pricing\", {\n accountId,\n objectiveType: String(args.objective),\n costType: String(args[\"cost-type\"]).toUpperCase(),\n targetingCriteria,\n skipCache: Boolean(args[\"no-cache\"]),\n });\n writeAdsJson({ ok: true, data });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAmB9B,SAAS,cAAc,MAAwC;AAC7D,QAAM,SAAS,KAAK;AACpB,MAAI,QAAQ;AACV,QAAI;AACF,aAAO,KAAK,MAAM,MAAM;AAAA,IAC1B,QAAQ;AACN,0BAAoB,IAAI,MAAM,yEAAyE,CAAC;AAAA,IAC1G;AAAA,EACF;AACA,QAAM,OAAO,KAAK,gBAAgB;AAClC,MAAI,MAAM;AACR,QAAI;AACF,aAAO,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,IAC/C,SAAS,GAAG;AACV;AAAA,QACE,IAAI,MAAM,oCAAoC,aAAa,QAAQ,EAAE,UAAU,WAAW,EAAE;AAAA,MAC9F;AAAA,IACF;AAAA,EACF;AACA,sBAAoB,IAAI,MAAM,4DAA4D,CAAC;AAC7F;AAEO,IAAM,oBAAoB,cAAc;AAAA,EAC7C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaf;AAAA,EACA,MAAM;AAAA,IACJ,cAAc,EAAE,MAAM,UAAU,aAAa,kDAAkD;AAAA,IAC/F,eAAe,EAAE,MAAM,UAAU,aAAa,yBAAyB;AAAA,IACvE,WAAW;AAAA,MACT,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,aAAa,EAAE,MAAM,UAAU,aAAa,yBAAyB,UAAU,KAAK;AAAA,IACpF,WAAW,EAAE,MAAM,UAAU,aAAa,gCAAgC;AAAA,IAC1E,kBAAkB,EAAE,MAAM,UAAU,aAAa,2CAA2C;AAAA,IAC5F,YAAY;AAAA,IACZ,QAAQ,EAAE,MAAM,UAAU,aAAa,QAAQ,SAAS,OAAO;AAAA,EACjE;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,YAAY,oBAAoB,IAAI;AAC1C,UAAM,oBAAoB,cAAc,IAAI;AAC5C,QAAI;AACF,YAAM,OAAO,MAAM,QAA0B,iCAAiC;AAAA,QAC5E;AAAA,QACA,eAAe,OAAO,KAAK,SAAS;AAAA,QACpC,UAAU,OAAO,KAAK,WAAW,CAAC,EAAE,YAAY;AAAA,QAChD;AAAA,QACA,WAAW,QAAQ,KAAK,UAAU,CAAC;AAAA,MACrC,CAAC;AACD,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/bid-pricing.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiPost } from \"../../../client.ts\";\nimport { writeAdsJson } from \"../output.ts\";\nimport { handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\ninterface BidPricingResult {\n bidLimits?: { min?: { amount?: string; currencyCode?: string }; max?: { amount?: string; currencyCode?: string } };\n suggestedBid?: {\n default?: { amount?: string; currencyCode?: string };\n min?: { amount?: string; currencyCode?: string };\n max?: { amount?: string; currencyCode?: string };\n };\n costType: string;\n objectiveType: string;\n playbookFloor?: { amount: string; currencyCode: string };\n playbookNote: string;\n}\n\nfunction loadTargeting(args: Record<string, unknown>): unknown {\n const inline = args.targeting as string | undefined;\n if (inline) {\n try {\n return JSON.parse(inline);\n } catch {\n handleLinkedinError(new Error(\"--targeting must be valid JSON. See LinkedIn 'targetingCriteria' shape.\"));\n }\n }\n const file = args[\"targeting-file\"] as string | undefined;\n if (file) {\n try {\n return JSON.parse(readFileSync(file, \"utf-8\"));\n } catch (e) {\n handleLinkedinError(\n new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : \"I/O error\"}`),\n );\n }\n }\n handleLinkedinError(new Error(\"Pass --targeting-file <path> or --targeting '{...JSON...}'\"));\n}\n\nexport const bidPricingCommand = defineCommand({\n meta: {\n name: \"bid-pricing\",\n description: `Get LinkedIn's suggested bid range for a targeting + objective + cost type.\n\nReturns LinkedIn's min / suggested / max bid plus the playbook §06 floor\n(2/3 of suggested — the recommended manual CPC starting point).\n\nObjective types: BRAND_AWARENESS | WEBSITE_TRAFFIC | WEBSITE_VISIT |\n ENGAGEMENT | WEBSITE_CONVERSION | LEAD_GENERATION |\n JOB_APPLICANT | VIDEO_VIEW\nCost types: CPC | CPM | CPV | CPS\n\nExamples:\n baker ads linkedin bid-pricing --account-id 503001492 --objective WEBSITE_CONVERSION --cost-type CPC --targeting-file targeting.json\n baker ads linkedin bid-pricing --account-id 503001492 --objective LEAD_GENERATION --cost-type CPM --targeting '{\"include\":...}'`,\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 objective: {\n type: \"string\",\n description: \"Objective type (e.g. WEBSITE_CONVERSION, LEAD_GENERATION)\",\n required: true,\n },\n \"cost-type\": { type: \"string\", description: \"CPC | CPM | CPV | CPS\", required: true },\n targeting: { type: \"string\", description: \"Inline JSON targetingCriteria\" },\n \"targeting-file\": { type: \"string\", description: \"Path to JSON file with targetingCriteria\" },\n \"no-cache\": NO_CACHE_ARG,\n output: { type: \"string\", description: \"json\", default: \"json\" },\n },\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n const targetingCriteria = loadTargeting(args);\n try {\n const data = await apiPost<BidPricingResult>(\"/api/ads/linkedin/bid-pricing\", {\n accountId,\n objectiveType: String(args.objective),\n costType: String(args[\"cost-type\"]).toUpperCase(),\n targetingCriteria,\n skipCache: Boolean(args[\"no-cache\"]),\n });\n writeAdsJson({ ok: true, data });\n } catch (err) {\n handleLinkedinError(err);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAmB9B,SAAS,cAAc,MAAwC;AAC7D,QAAM,SAAS,KAAK;AACpB,MAAI,QAAQ;AACV,QAAI;AACF,aAAO,KAAK,MAAM,MAAM;AAAA,IAC1B,QAAQ;AACN,0BAAoB,IAAI,MAAM,yEAAyE,CAAC;AAAA,IAC1G;AAAA,EACF;AACA,QAAM,OAAO,KAAK,gBAAgB;AAClC,MAAI,MAAM;AACR,QAAI;AACF,aAAO,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,IAC/C,SAAS,GAAG;AACV;AAAA,QACE,IAAI,MAAM,oCAAoC,aAAa,QAAQ,EAAE,UAAU,WAAW,EAAE;AAAA,MAC9F;AAAA,IACF;AAAA,EACF;AACA,sBAAoB,IAAI,MAAM,4DAA4D,CAAC;AAC7F;AAEO,IAAM,oBAAoB,cAAc;AAAA,EAC7C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaf;AAAA,EACA,MAAM;AAAA,IACJ,cAAc,EAAE,MAAM,UAAU,aAAa,kDAAkD;AAAA,IAC/F,eAAe,EAAE,MAAM,UAAU,aAAa,yBAAyB;AAAA,IACvE,WAAW;AAAA,MACT,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,aAAa,EAAE,MAAM,UAAU,aAAa,yBAAyB,UAAU,KAAK;AAAA,IACpF,WAAW,EAAE,MAAM,UAAU,aAAa,gCAAgC;AAAA,IAC1E,kBAAkB,EAAE,MAAM,UAAU,aAAa,2CAA2C;AAAA,IAC5F,YAAY;AAAA,IACZ,QAAQ,EAAE,MAAM,UAAU,aAAa,QAAQ,SAAS,OAAO;AAAA,EACjE;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,YAAY,oBAAoB,IAAI;AAC1C,UAAM,oBAAoB,cAAc,IAAI;AAC5C,QAAI;AACF,YAAM,OAAO,MAAM,QAA0B,iCAAiC;AAAA,QAC5E;AAAA,QACA,eAAe,OAAO,KAAK,SAAS;AAAA,QACpC,UAAU,OAAO,KAAK,WAAW,CAAC,EAAE,YAAY;AAAA,QAChD;AAAA,QACA,WAAW,QAAQ,KAAK,UAAU,CAAC;AAAA,MACrC,CAAC;AACD,mBAAa,EAAE,IAAI,MAAM,KAAK,CAAC;AAAA,IACjC,SAAS,KAAK;AACZ,0BAAoB,GAAG;AAAA,IACzB;AAAA,EACF;AACF,CAAC;","names":[]}
@@ -13,10 +13,10 @@ Subcommands:
13
13
  baker brand fonts \u2014 verify the brand's typefaces really load, and self-host them into src/brand/fonts/`
14
14
  },
15
15
  subCommands: {
16
- fonts: () => import("./fonts-EMMX3KII.js").then((m) => m.fontsCommand)
16
+ fonts: () => import("./fonts-MXR3ZKDX.js").then((m) => m.fontsCommand)
17
17
  }
18
18
  });
19
19
  export {
20
20
  brandCommand
21
21
  };
22
- //# sourceMappingURL=brand-C6PFGGQN.js.map
22
+ //# sourceMappingURL=brand-YRTEPGBK.js.map
@@ -18,12 +18,12 @@ import {
18
18
  } from "./chunk-4QEY2L6U.js";
19
19
  import {
20
20
  withDefinitions
21
- } from "./chunk-5ZDLTE5T.js";
21
+ } from "./chunk-2AOE2MZQ.js";
22
22
  import {
23
23
  researchCustomers
24
- } from "./chunk-DGUNI37S.js";
25
- import "./chunk-S77PZVYM.js";
26
- import "./chunk-OZRUJVIQ.js";
24
+ } from "./chunk-RX2DKU3W.js";
25
+ import "./chunk-FYGR3I2A.js";
26
+ import "./chunk-H3427GPU.js";
27
27
  import "./chunk-WNFIJAUO.js";
28
28
  import "./chunk-NFSLRRIE.js";
29
29
  import "./chunk-ERSX3MKH.js";
@@ -44,11 +44,12 @@ import "./chunk-VAJBWA2U.js";
44
44
  import "./chunk-HRYOZUSK.js";
45
45
  import "./chunk-VVZBBKRC.js";
46
46
  import "./chunk-YBMVHGY3.js";
47
- import "./chunk-3HJLHTWP.js";
48
- import "./chunk-XF4JUKVF.js";
47
+ import "./chunk-SJYEY5MV.js";
48
+ import "./chunk-7EPXVICM.js";
49
49
  import "./chunk-GXDLWBOY.js";
50
50
  import "./chunk-TEINLN64.js";
51
51
  import "./chunk-ZJWUBJYQ.js";
52
+ import "./chunk-HR6IWNKE.js";
52
53
  import "./chunk-NE4F3FHN.js";
53
54
  import {
54
55
  ApiError,
@@ -474,4 +475,4 @@ export {
474
475
  briefHints,
475
476
  whatWorks
476
477
  };
477
- //# sourceMappingURL=brief-YFJHQ5VQ.js.map
478
+ //# sourceMappingURL=brief-OSFJ2V7F.js.map