@koda-sl/baker-cli 0.386.0 → 0.387.0-dev.3bafd569e
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.
- package/README.md +1090 -211
- package/canvas/tiktok-captions-composition/index.html +5 -6
- package/canvas/tiktok-captions-composition/meta.json +5 -0
- package/dist/account-CLOKMTTC.js +49 -0
- package/dist/account-CLOKMTTC.js.map +1 -0
- package/dist/account-V5Y2QHAK.js +79 -0
- package/dist/account-V5Y2QHAK.js.map +1 -0
- package/dist/account-XFK6VX2R.js +80 -0
- package/dist/account-XFK6VX2R.js.map +1 -0
- package/dist/account-reads-S5VXX2QU.js +218 -0
- package/dist/account-reads-S5VXX2QU.js.map +1 -0
- package/dist/account-writes-Y7EQXDXF.js +66 -0
- package/dist/account-writes-Y7EQXDXF.js.map +1 -0
- package/dist/accounts-7YD457YN.js +114 -0
- package/dist/accounts-7YD457YN.js.map +1 -0
- package/dist/accounts-BJ3X5JQT.js +115 -0
- package/dist/accounts-BJ3X5JQT.js.map +1 -0
- package/dist/accounts-LOJ4WLIX.js +77 -0
- package/dist/accounts-LOJ4WLIX.js.map +1 -0
- package/dist/accounts-RYBDLQ6H.js +75 -0
- package/dist/accounts-RYBDLQ6H.js.map +1 -0
- package/dist/accounts-UO4XBWM2.js +611 -0
- package/dist/accounts-UO4XBWM2.js.map +1 -0
- package/dist/actions-3AW3R63U.js +55 -0
- package/dist/actions-3AW3R63U.js.map +1 -0
- package/dist/active-entities-R6GZIO6Z.js +103 -0
- package/dist/active-entities-R6GZIO6Z.js.map +1 -0
- package/dist/activities-ESBF3GFS.js +74 -0
- package/dist/activities-ESBF3GFS.js.map +1 -0
- package/dist/ad-group-writes-I225OYDZ.js +170 -0
- package/dist/ad-group-writes-I225OYDZ.js.map +1 -0
- package/dist/ad-groups-O35MWNF6.js +68 -0
- package/dist/ad-groups-O35MWNF6.js.map +1 -0
- package/dist/ad-writes-SS5YZO5W.js +174 -0
- package/dist/ad-writes-SS5YZO5W.js.map +1 -0
- package/dist/add-43DUOVNR.js +104 -0
- package/dist/add-43DUOVNR.js.map +1 -0
- package/dist/add-IE5WDELB.js +302 -0
- package/dist/add-IE5WDELB.js.map +1 -0
- package/dist/add-QZHAWUBA.js +97 -0
- package/dist/add-QZHAWUBA.js.map +1 -0
- package/dist/add-TGQIVVXH.js +105 -0
- package/dist/add-TGQIVVXH.js.map +1 -0
- package/dist/add-accounts-6QYPOPR2.js +91 -0
- package/dist/add-accounts-6QYPOPR2.js.map +1 -0
- package/dist/ads-AUSRB4GU.js +128 -0
- package/dist/ads-AUSRB4GU.js.map +1 -0
- package/dist/ads-COYOTEKE.js +77 -0
- package/dist/ads-COYOTEKE.js.map +1 -0
- package/dist/ads-DZ4N5INZ.js +40 -0
- package/dist/ads-DZ4N5INZ.js.map +1 -0
- package/dist/ads-XZCMSPM5.js +113 -0
- package/dist/ads-XZCMSPM5.js.map +1 -0
- package/dist/adsets-AKR75THA.js +176 -0
- package/dist/adsets-AKR75THA.js.map +1 -0
- package/dist/advertisers-52FMMBTQ.js +120 -0
- package/dist/advertisers-52FMMBTQ.js.map +1 -0
- package/dist/advertisers-BCGKUMEH.js +125 -0
- package/dist/advertisers-BCGKUMEH.js.map +1 -0
- package/dist/analytics-JPDBKETM.js +1980 -0
- package/dist/analytics-JPDBKETM.js.map +1 -0
- package/dist/analytics-YVQ6H4BG.js +433 -0
- package/dist/analytics-YVQ6H4BG.js.map +1 -0
- package/dist/animate-JXIT77Y5.js +480 -0
- package/dist/animate-JXIT77Y5.js.map +1 -0
- package/dist/assign-66NTWTR2.js +77 -0
- package/dist/assign-66NTWTR2.js.map +1 -0
- package/dist/audience-size-LVQJWQAS.js +94 -0
- package/dist/audience-size-LVQJWQAS.js.map +1 -0
- package/dist/audiences-DC3IOG34.js +85 -0
- package/dist/audiences-DC3IOG34.js.map +1 -0
- package/dist/audiences-NEW3LLQR.js +268 -0
- package/dist/audiences-NEW3LLQR.js.map +1 -0
- package/dist/audiences-NYGMBGQ3.js +79 -0
- package/dist/audiences-NYGMBGQ3.js.map +1 -0
- package/dist/audit-UIPMTI5C.js +88 -0
- package/dist/audit-UIPMTI5C.js.map +1 -0
- package/dist/audit-XGN2OFLN.js +151 -0
- package/dist/audit-XGN2OFLN.js.map +1 -0
- package/dist/autocomplete-LVPDV3JE.js +111 -0
- package/dist/autocomplete-LVPDV3JE.js.map +1 -0
- package/dist/avatars-S6NSLMJK.js +38 -0
- package/dist/avatars-S6NSLMJK.js.map +1 -0
- package/dist/bid-pricing-2LYULXU2.js +99 -0
- package/dist/bid-pricing-2LYULXU2.js.map +1 -0
- package/dist/brand-WWHUZ72R.js +22 -0
- package/dist/brand-WWHUZ72R.js.map +1 -0
- package/dist/brief-K3FILESK.js +492 -0
- package/dist/brief-K3FILESK.js.map +1 -0
- package/dist/businesses-J7OP7MSK.js +53 -0
- package/dist/businesses-J7OP7MSK.js.map +1 -0
- package/dist/campaign-groups-N4TZ2F3L.js +95 -0
- package/dist/campaign-groups-N4TZ2F3L.js.map +1 -0
- package/dist/campaign-writes-5XA727KI.js +170 -0
- package/dist/campaign-writes-5XA727KI.js.map +1 -0
- package/dist/campaign-writes-7YFRQIQT.js +165 -0
- package/dist/campaign-writes-7YFRQIQT.js.map +1 -0
- package/dist/campaigns-JPYNVFQI.js +76 -0
- package/dist/campaigns-JPYNVFQI.js.map +1 -0
- package/dist/campaigns-L43ZUKAI.js +107 -0
- package/dist/campaigns-L43ZUKAI.js.map +1 -0
- package/dist/campaigns-OD7Z332M.js +109 -0
- package/dist/campaigns-OD7Z332M.js.map +1 -0
- package/dist/campaigns-R4DXIR2Q.js +110 -0
- package/dist/campaigns-R4DXIR2Q.js.map +1 -0
- package/dist/canvas-57K7AGAP.js +46 -0
- package/dist/canvas-57K7AGAP.js.map +1 -0
- package/dist/capabilities-FVTZAFPV.js +144 -0
- package/dist/capabilities-FVTZAFPV.js.map +1 -0
- package/dist/cards-7H32TNMO.js +85 -0
- package/dist/cards-7H32TNMO.js.map +1 -0
- package/dist/catalog-OTICZPJA.js +64 -0
- package/dist/catalog-OTICZPJA.js.map +1 -0
- package/dist/catalogs-ABCQLCDU.js +128 -0
- package/dist/catalogs-ABCQLCDU.js.map +1 -0
- package/dist/changes-7ZIGNUW6.js +135 -0
- package/dist/changes-7ZIGNUW6.js.map +1 -0
- package/dist/chatgpt-B3NHRJUE.js +47 -0
- package/dist/chatgpt-B3NHRJUE.js.map +1 -0
- package/dist/chats-E7DBRHBF.js +262 -0
- package/dist/chats-E7DBRHBF.js.map +1 -0
- package/dist/chunk-2CV7LX23.js +474 -0
- package/dist/chunk-2CV7LX23.js.map +1 -0
- package/dist/chunk-2HCI5BXB.js +479 -0
- package/dist/chunk-2HCI5BXB.js.map +1 -0
- package/dist/chunk-2SQJL7ZN.js +56 -0
- package/dist/chunk-2SQJL7ZN.js.map +1 -0
- package/dist/chunk-2Y5V23PU.js +29 -0
- package/dist/chunk-2Y5V23PU.js.map +1 -0
- package/dist/chunk-32CPGJPL.js +149 -0
- package/dist/chunk-32CPGJPL.js.map +1 -0
- package/dist/chunk-3ACMDRSE.js +39 -0
- package/dist/chunk-3ACMDRSE.js.map +1 -0
- package/dist/chunk-3N4PZIIV.js +304 -0
- package/dist/chunk-3N4PZIIV.js.map +1 -0
- package/dist/chunk-3U7TDBIB.js +275 -0
- package/dist/chunk-3U7TDBIB.js.map +1 -0
- package/dist/chunk-3UDSYYND.js +42 -0
- package/dist/chunk-3UDSYYND.js.map +1 -0
- package/dist/chunk-3ZWWXAQZ.js +150 -0
- package/dist/chunk-3ZWWXAQZ.js.map +1 -0
- package/dist/chunk-4MH6LONO.js +274 -0
- package/dist/chunk-4MH6LONO.js.map +1 -0
- package/dist/chunk-4NZ47VXO.js +137 -0
- package/dist/chunk-4NZ47VXO.js.map +1 -0
- package/dist/chunk-564AEU2Q.js +541 -0
- package/dist/chunk-564AEU2Q.js.map +1 -0
- package/dist/chunk-5HYSKH77.js +315 -0
- package/dist/chunk-5HYSKH77.js.map +1 -0
- package/dist/chunk-5MBPIONY.js +29 -0
- package/dist/chunk-5MBPIONY.js.map +1 -0
- package/dist/chunk-5OVOLYY3.js +74 -0
- package/dist/chunk-5OVOLYY3.js.map +1 -0
- package/dist/chunk-5SJ3JNNY.js +6683 -0
- package/dist/chunk-5SJ3JNNY.js.map +1 -0
- package/dist/chunk-66USKCVY.js +4410 -0
- package/dist/chunk-66USKCVY.js.map +1 -0
- package/dist/chunk-6I7SYEYN.js +166 -0
- package/dist/chunk-6I7SYEYN.js.map +1 -0
- package/dist/chunk-6O7ISBC7.js +65 -0
- package/dist/chunk-6O7ISBC7.js.map +1 -0
- package/dist/chunk-752S7JF6.js +35 -0
- package/dist/chunk-752S7JF6.js.map +1 -0
- package/dist/chunk-77DN7R35.js +228 -0
- package/dist/chunk-77DN7R35.js.map +1 -0
- package/dist/chunk-7F7MFMLI.js +175 -0
- package/dist/chunk-7F7MFMLI.js.map +1 -0
- package/dist/chunk-7THBBTJJ.js +183 -0
- package/dist/chunk-7THBBTJJ.js.map +1 -0
- package/dist/chunk-7XU3HKMX.js +1599 -0
- package/dist/chunk-7XU3HKMX.js.map +1 -0
- package/dist/chunk-AEA5JV2X.js +92 -0
- package/dist/chunk-AEA5JV2X.js.map +1 -0
- package/dist/chunk-AFJGYJ7Z.js +45 -0
- package/dist/chunk-AFJGYJ7Z.js.map +1 -0
- package/dist/chunk-AR7PU7BB.js +76 -0
- package/dist/chunk-AR7PU7BB.js.map +1 -0
- package/dist/chunk-ASL7JFBD.js +96 -0
- package/dist/chunk-ASL7JFBD.js.map +1 -0
- package/dist/chunk-AUSKKFVH.js +84 -0
- package/dist/chunk-AUSKKFVH.js.map +1 -0
- package/dist/chunk-B52DCYL2.js +159 -0
- package/dist/chunk-B52DCYL2.js.map +1 -0
- package/dist/{chunk-XHC4LMK4.js → chunk-BVM5IRZW.js} +16 -8
- package/dist/chunk-BVM5IRZW.js.map +1 -0
- package/dist/chunk-CAMX6OHF.js +3182 -0
- package/dist/chunk-CAMX6OHF.js.map +1 -0
- package/dist/chunk-CYBLKMXQ.js +310 -0
- package/dist/chunk-CYBLKMXQ.js.map +1 -0
- package/dist/chunk-CZENWCBS.js +333 -0
- package/dist/chunk-CZENWCBS.js.map +1 -0
- package/dist/chunk-D5FY4FAK.js +24 -0
- package/dist/chunk-D5FY4FAK.js.map +1 -0
- package/dist/chunk-DGCUPJZD.js +39 -0
- package/dist/chunk-DGCUPJZD.js.map +1 -0
- package/dist/chunk-DNCLWSHO.js +41 -0
- package/dist/chunk-DNCLWSHO.js.map +1 -0
- package/dist/chunk-DX4GIDO7.js +296 -0
- package/dist/chunk-DX4GIDO7.js.map +1 -0
- package/dist/chunk-EDLZGTGN.js +216 -0
- package/dist/chunk-EDLZGTGN.js.map +1 -0
- package/dist/chunk-EDNX3AOS.js +76 -0
- package/dist/chunk-EDNX3AOS.js.map +1 -0
- package/dist/chunk-EF5DP6EB.js +52 -0
- package/dist/chunk-EF5DP6EB.js.map +1 -0
- package/dist/chunk-ERSX3MKH.js +34 -0
- package/dist/chunk-ERSX3MKH.js.map +1 -0
- package/dist/chunk-F3IJSR7O.js +346 -0
- package/dist/chunk-F3IJSR7O.js.map +1 -0
- package/dist/chunk-FKOECEVC.js +126 -0
- package/dist/chunk-FKOECEVC.js.map +1 -0
- package/dist/chunk-FYWWTMXP.js +2902 -0
- package/dist/chunk-FYWWTMXP.js.map +1 -0
- package/dist/chunk-G7AFVTUS.js +106 -0
- package/dist/chunk-G7AFVTUS.js.map +1 -0
- package/dist/chunk-GIW7ABMM.js +74 -0
- package/dist/chunk-GIW7ABMM.js.map +1 -0
- package/dist/chunk-GIWHHCD6.js +145 -0
- package/dist/chunk-GIWHHCD6.js.map +1 -0
- package/dist/chunk-GPZH5ASB.js +3151 -0
- package/dist/chunk-GPZH5ASB.js.map +1 -0
- package/dist/chunk-GRQ2AXDX.js +9 -0
- package/dist/chunk-GRQ2AXDX.js.map +1 -0
- package/dist/chunk-GXDLWBOY.js +73 -0
- package/dist/chunk-GXDLWBOY.js.map +1 -0
- package/dist/chunk-GYABNLWW.js +629 -0
- package/dist/chunk-GYABNLWW.js.map +1 -0
- package/dist/chunk-H7MLHG2I.js +94 -0
- package/dist/chunk-H7MLHG2I.js.map +1 -0
- package/dist/chunk-H7XVKLIY.js +206 -0
- package/dist/chunk-H7XVKLIY.js.map +1 -0
- package/dist/chunk-HAE4WWFQ.js +455 -0
- package/dist/chunk-HAE4WWFQ.js.map +1 -0
- package/dist/chunk-HDHWIEJJ.js +136 -0
- package/dist/chunk-HDHWIEJJ.js.map +1 -0
- package/dist/chunk-HJTIBTF7.js +98 -0
- package/dist/chunk-HJTIBTF7.js.map +1 -0
- package/dist/{chunk-VZEDAFAR.js → chunk-HLXWKMTK.js} +47 -8
- package/dist/chunk-HLXWKMTK.js.map +1 -0
- package/dist/{chunk-MF7YA62W.js → chunk-HREWXNTO.js} +10 -5
- package/dist/chunk-HREWXNTO.js.map +1 -0
- package/dist/chunk-HYXKRNRV.js +176 -0
- package/dist/chunk-HYXKRNRV.js.map +1 -0
- package/dist/chunk-I3DIZWN5.js +97 -0
- package/dist/chunk-I3DIZWN5.js.map +1 -0
- package/dist/chunk-IJMWEO4P.js +57 -0
- package/dist/chunk-IJMWEO4P.js.map +1 -0
- package/dist/chunk-IOCSDFF2.js +23992 -0
- package/dist/chunk-IOCSDFF2.js.map +1 -0
- package/dist/chunk-IVIJJXXT.js +62 -0
- package/dist/chunk-IVIJJXXT.js.map +1 -0
- package/dist/chunk-J57GWTPK.js +106 -0
- package/dist/chunk-J57GWTPK.js.map +1 -0
- package/dist/chunk-JPK34QPS.js +134 -0
- package/dist/chunk-JPK34QPS.js.map +1 -0
- package/dist/chunk-JRCFCIE3.js +188 -0
- package/dist/chunk-JRCFCIE3.js.map +1 -0
- package/dist/chunk-JUAIGJ2A.js +76 -0
- package/dist/chunk-JUAIGJ2A.js.map +1 -0
- package/dist/chunk-K5OQES4V.js +58 -0
- package/dist/chunk-K5OQES4V.js.map +1 -0
- package/dist/chunk-KBS5GH4T.js +1626 -0
- package/dist/chunk-KBS5GH4T.js.map +1 -0
- package/dist/chunk-KIGGMKAE.js +66 -0
- package/dist/chunk-KIGGMKAE.js.map +1 -0
- package/dist/chunk-KKJ4KJCW.js +29 -0
- package/dist/chunk-KKJ4KJCW.js.map +1 -0
- package/dist/chunk-KLK6KQLQ.js +55 -0
- package/dist/chunk-KLK6KQLQ.js.map +1 -0
- package/dist/chunk-KUZFWMJN.js +207 -0
- package/dist/chunk-KUZFWMJN.js.map +1 -0
- package/dist/chunk-KXGG6EQM.js +382 -0
- package/dist/chunk-KXGG6EQM.js.map +1 -0
- package/dist/chunk-KXRKPZZY.js +169 -0
- package/dist/chunk-KXRKPZZY.js.map +1 -0
- package/dist/chunk-KZUHRZ2C.js +5187 -0
- package/dist/chunk-KZUHRZ2C.js.map +1 -0
- package/dist/chunk-L45A3IYV.js +1079 -0
- package/dist/chunk-L45A3IYV.js.map +1 -0
- package/dist/chunk-LA6PPSNA.js +65 -0
- package/dist/chunk-LA6PPSNA.js.map +1 -0
- package/dist/chunk-LEIQAHWF.js +25 -0
- package/dist/chunk-LEIQAHWF.js.map +1 -0
- package/dist/chunk-LERWCRY5.js +297 -0
- package/dist/chunk-LERWCRY5.js.map +1 -0
- package/dist/chunk-M6UNISGO.js +66 -0
- package/dist/chunk-M6UNISGO.js.map +1 -0
- package/dist/chunk-MGKHFGLV.js +75 -0
- package/dist/chunk-MGKHFGLV.js.map +1 -0
- package/dist/chunk-MZWC6HHA.js +455 -0
- package/dist/chunk-MZWC6HHA.js.map +1 -0
- package/dist/chunk-N3XJ434P.js +197 -0
- package/dist/chunk-N3XJ434P.js.map +1 -0
- package/dist/chunk-NFSLRRIE.js +77 -0
- package/dist/chunk-NFSLRRIE.js.map +1 -0
- package/dist/chunk-NHU33T2S.js +60 -0
- package/dist/chunk-NHU33T2S.js.map +1 -0
- package/dist/chunk-NJEZM4OB.js +51 -0
- package/dist/chunk-NJEZM4OB.js.map +1 -0
- package/dist/chunk-O6QKCJE4.js +455 -0
- package/dist/chunk-O6QKCJE4.js.map +1 -0
- package/dist/chunk-OFFAMC5H.js +225 -0
- package/dist/chunk-OFFAMC5H.js.map +1 -0
- package/dist/chunk-OHGTCFFE.js +57 -0
- package/dist/chunk-OHGTCFFE.js.map +1 -0
- package/dist/chunk-P4NSJS54.js +20 -0
- package/dist/chunk-P4NSJS54.js.map +1 -0
- package/dist/chunk-P5T7OZKV.js +26 -0
- package/dist/chunk-P5T7OZKV.js.map +1 -0
- package/dist/chunk-PFBQERWX.js +10 -0
- package/dist/chunk-PFBQERWX.js.map +1 -0
- package/dist/chunk-PKTLHYH4.js +509 -0
- package/dist/chunk-PKTLHYH4.js.map +1 -0
- package/dist/chunk-PUPEGICD.js +103 -0
- package/dist/chunk-PUPEGICD.js.map +1 -0
- package/dist/chunk-Q6ULQMWG.js +41 -0
- package/dist/chunk-Q6ULQMWG.js.map +1 -0
- package/dist/chunk-QO23YHLK.js +84 -0
- package/dist/chunk-QO23YHLK.js.map +1 -0
- package/dist/chunk-QSGIWV4P.js +337 -0
- package/dist/chunk-QSGIWV4P.js.map +1 -0
- package/dist/chunk-R5OQM7FF.js +179 -0
- package/dist/chunk-R5OQM7FF.js.map +1 -0
- package/dist/chunk-RFB6RYKA.js +111 -0
- package/dist/chunk-RFB6RYKA.js.map +1 -0
- package/dist/chunk-RGIXQEGJ.js +502 -0
- package/dist/chunk-RGIXQEGJ.js.map +1 -0
- package/dist/chunk-RODLBWIR.js +592 -0
- package/dist/chunk-RODLBWIR.js.map +1 -0
- package/dist/chunk-S4LZ7KTG.js +160 -0
- package/dist/chunk-S4LZ7KTG.js.map +1 -0
- package/dist/chunk-SHTESUB6.js +1442 -0
- package/dist/chunk-SHTESUB6.js.map +1 -0
- package/dist/chunk-SJH4EOZH.js +23 -0
- package/dist/chunk-SJH4EOZH.js.map +1 -0
- package/dist/chunk-SLB46MSS.js +64 -0
- package/dist/chunk-SLB46MSS.js.map +1 -0
- package/dist/chunk-SMIENBNX.js +6212 -0
- package/dist/chunk-SMIENBNX.js.map +1 -0
- package/dist/chunk-T7GT22KA.js +494 -0
- package/dist/chunk-T7GT22KA.js.map +1 -0
- package/dist/chunk-T7M4WFNV.js +172 -0
- package/dist/chunk-T7M4WFNV.js.map +1 -0
- package/dist/chunk-TLQ23DDW.js +19 -0
- package/dist/chunk-TLQ23DDW.js.map +1 -0
- package/dist/chunk-TMIDUSOR.js +665 -0
- package/dist/chunk-TMIDUSOR.js.map +1 -0
- package/dist/{chunk-WLDM2TRF.js → chunk-TPXI2GCW.js} +4 -4
- package/dist/chunk-U6VRBDNQ.js +1830 -0
- package/dist/chunk-U6VRBDNQ.js.map +1 -0
- package/dist/chunk-U7BBXM67.js +1743 -0
- package/dist/chunk-U7BBXM67.js.map +1 -0
- package/dist/chunk-UI6BKYQD.js +225 -0
- package/dist/chunk-UI6BKYQD.js.map +1 -0
- package/dist/chunk-UOI5S62H.js +846 -0
- package/dist/chunk-UOI5S62H.js.map +1 -0
- package/dist/chunk-USL5ARRE.js +26 -0
- package/dist/chunk-USL5ARRE.js.map +1 -0
- package/dist/chunk-UYC45JNS.js +139 -0
- package/dist/chunk-UYC45JNS.js.map +1 -0
- package/dist/chunk-VNKVBY54.js +363 -0
- package/dist/chunk-VNKVBY54.js.map +1 -0
- package/dist/chunk-VS4C7VAR.js +533 -0
- package/dist/chunk-VS4C7VAR.js.map +1 -0
- package/dist/chunk-W4W4ZRBP.js +191 -0
- package/dist/chunk-W4W4ZRBP.js.map +1 -0
- package/dist/chunk-WN4KX7GE.js +25 -0
- package/dist/chunk-WN4KX7GE.js.map +1 -0
- package/dist/chunk-WNFTXSGR.js +111 -0
- package/dist/chunk-WNFTXSGR.js.map +1 -0
- package/dist/chunk-WOTDHRNF.js +2109 -0
- package/dist/chunk-WOTDHRNF.js.map +1 -0
- package/dist/chunk-XGWKTYXQ.js +67 -0
- package/dist/chunk-XGWKTYXQ.js.map +1 -0
- package/dist/chunk-XIGIJJSF.js +66 -0
- package/dist/chunk-XIGIJJSF.js.map +1 -0
- package/dist/chunk-XNUXB63I.js +817 -0
- package/dist/chunk-XNUXB63I.js.map +1 -0
- package/dist/chunk-XQ3CCNJD.js +610 -0
- package/dist/chunk-XQ3CCNJD.js.map +1 -0
- package/dist/chunk-XX6ZMCY5.js +4227 -0
- package/dist/chunk-XX6ZMCY5.js.map +1 -0
- package/dist/chunk-Y362QH54.js +98 -0
- package/dist/chunk-Y362QH54.js.map +1 -0
- package/dist/chunk-Y4T6ATDQ.js +74 -0
- package/dist/chunk-Y4T6ATDQ.js.map +1 -0
- package/dist/chunk-YQSBHWOI.js +41 -0
- package/dist/chunk-YU26SDNT.js +46 -0
- package/dist/chunk-YU26SDNT.js.map +1 -0
- package/dist/chunk-YULENNA7.js +501 -0
- package/dist/chunk-YULENNA7.js.map +1 -0
- package/dist/chunk-YYSZYSAG.js +150 -0
- package/dist/chunk-YYSZYSAG.js.map +1 -0
- package/dist/chunk-Z3ENMCFE.js +94 -0
- package/dist/chunk-Z3ENMCFE.js.map +1 -0
- package/dist/chunk-ZH7ZM3ZM.js +125 -0
- package/dist/chunk-ZH7ZM3ZM.js.map +1 -0
- package/dist/chunk-ZIXHS6AM.js +42 -0
- package/dist/chunk-ZIXHS6AM.js.map +1 -0
- package/dist/chunk-ZLLJKSNS.js +96 -0
- package/dist/chunk-ZLLJKSNS.js.map +1 -0
- package/dist/claim-LF6VQ7OR.js +197 -0
- package/dist/claim-LF6VQ7OR.js.map +1 -0
- package/dist/cli.js +104 -70026
- package/dist/cli.js.map +1 -1
- package/dist/client-26SAJ46D.js +19 -0
- package/dist/code-MOWYJMDH.js +76 -0
- package/dist/code-MOWYJMDH.js.map +1 -0
- package/dist/companies-6HSK5BLK.js +195 -0
- package/dist/companies-6HSK5BLK.js.map +1 -0
- package/dist/complete-2PUAFQEC.js +81 -0
- package/dist/complete-2PUAFQEC.js.map +1 -0
- package/dist/config-X6GKOVQ6.js +88 -0
- package/dist/config-X6GKOVQ6.js.map +1 -0
- package/dist/connect-RXPMAJQI.js +42 -0
- package/dist/content-UYZC4AKN.js +85 -0
- package/dist/content-UYZC4AKN.js.map +1 -0
- package/dist/conversation-Y3NB2VDI.js +93 -0
- package/dist/conversation-Y3NB2VDI.js.map +1 -0
- package/dist/conversion-report-R4GJWWTK.js +125 -0
- package/dist/conversion-report-R4GJWWTK.js.map +1 -0
- package/dist/conversion-upload-command-YP4DGTPP.js +438 -0
- package/dist/conversion-upload-command-YP4DGTPP.js.map +1 -0
- package/dist/conversion-writes-WHFFUWWL.js +120 -0
- package/dist/conversion-writes-WHFFUWWL.js.map +1 -0
- package/dist/conversions-K7C32DPW.js +135 -0
- package/dist/conversions-K7C32DPW.js.map +1 -0
- package/dist/conversions-OXJAX5GB.js +76 -0
- package/dist/conversions-OXJAX5GB.js.map +1 -0
- package/dist/countries-PBXNB3BR.js +82 -0
- package/dist/countries-PBXNB3BR.js.map +1 -0
- package/dist/create-AJ4KPSJ4.js +59 -0
- package/dist/create-AJ4KPSJ4.js.map +1 -0
- package/dist/create-ALKOAD5J.js +138 -0
- package/dist/create-ALKOAD5J.js.map +1 -0
- package/dist/create-HTKZMXKB.js +207 -0
- package/dist/create-HTKZMXKB.js.map +1 -0
- package/dist/create-TZMAOFBR.js +236 -0
- package/dist/create-TZMAOFBR.js.map +1 -0
- package/dist/creatives-BJYJFVXJ.js +51 -0
- package/dist/creatives-BJYJFVXJ.js.map +1 -0
- package/dist/creatives-OZHVU4WB.js +182 -0
- package/dist/creatives-OZHVU4WB.js.map +1 -0
- package/dist/creatives-VMGY5SU4.js +87 -0
- package/dist/creatives-VMGY5SU4.js.map +1 -0
- package/dist/credentials-FY4UH6TF.js +287 -0
- package/dist/credentials-FY4UH6TF.js.map +1 -0
- package/dist/critique-B3H7QFM2.js +1449 -0
- package/dist/critique-B3H7QFM2.js.map +1 -0
- package/dist/critique-YZBOA27H.js +216 -0
- package/dist/critique-YZBOA27H.js.map +1 -0
- package/dist/crm-2IBLUHDB.js +318 -0
- package/dist/crm-2IBLUHDB.js.map +1 -0
- package/dist/crm-YMYO4U53.js +224 -0
- package/dist/crm-YMYO4U53.js.map +1 -0
- package/dist/crop-U3AD4DDR.js +113 -0
- package/dist/crop-U3AD4DDR.js.map +1 -0
- package/dist/currency-S6KWZSZ6.js +88 -0
- package/dist/currency-S6KWZSZ6.js.map +1 -0
- package/dist/custom-conversions-FABS6YVT.js +125 -0
- package/dist/custom-conversions-FABS6YVT.js.map +1 -0
- package/dist/customers-P6LLLJHK.js +56 -0
- package/dist/decide-YTHCBKM6.js +199 -0
- package/dist/decide-YTHCBKM6.js.map +1 -0
- package/dist/delete-B2TDEW7H.js +63 -0
- package/dist/delete-B2TDEW7H.js.map +1 -0
- package/dist/delete-DZUDLYPC.js +69 -0
- package/dist/delete-DZUDLYPC.js.map +1 -0
- package/dist/delete-NZGZP4YP.js +71 -0
- package/dist/delete-NZGZP4YP.js.map +1 -0
- package/dist/delete-SDOZNDWQ.js +54 -0
- package/dist/delete-SDOZNDWQ.js.map +1 -0
- package/dist/delete-VQMU56OH.js +71 -0
- package/dist/delete-VQMU56OH.js.map +1 -0
- package/dist/delete-WKQPMVAM.js +66 -0
- package/dist/delete-WKQPMVAM.js.map +1 -0
- package/dist/demographics-Q3DCXULY.js +138 -0
- package/dist/demographics-Q3DCXULY.js.map +1 -0
- package/dist/describe-JNTCQZNL.js +97 -0
- package/dist/describe-JNTCQZNL.js.map +1 -0
- package/dist/describe-MT4334NG.js +97 -0
- package/dist/describe-MT4334NG.js.map +1 -0
- package/dist/dimensions-FEZUJRAG.js +101 -0
- package/dist/dimensions-FEZUJRAG.js.map +1 -0
- package/dist/discard-NEZM5CHF.js +66 -0
- package/dist/discard-NEZM5CHF.js.map +1 -0
- package/dist/discover-4GD7QSF5.js +93 -0
- package/dist/discover-4GD7QSF5.js.map +1 -0
- package/dist/discover-6K3IOYXR.js +172 -0
- package/dist/discover-6K3IOYXR.js.map +1 -0
- package/dist/domain-7Y256IDR.js +98 -0
- package/dist/domain-7Y256IDR.js.map +1 -0
- package/dist/download-L27HWEOE.js +299 -0
- package/dist/download-L27HWEOE.js.map +1 -0
- package/dist/draft-25G2P2TE.js +281 -0
- package/dist/draft-25G2P2TE.js.map +1 -0
- package/dist/draft-F6TUGXAY.js +307 -0
- package/dist/draft-F6TUGXAY.js.map +1 -0
- package/dist/draft-KLULNBWP.js +233 -0
- package/dist/draft-KLULNBWP.js.map +1 -0
- package/dist/draft-LY5ZPF73.js +217 -0
- package/dist/draft-LY5ZPF73.js.map +1 -0
- package/dist/draft-M4ZHDQ46.js +306 -0
- package/dist/draft-M4ZHDQ46.js.map +1 -0
- package/dist/draft-MI7RWY2K.js +100 -0
- package/dist/draft-MI7RWY2K.js.map +1 -0
- package/dist/draft-P4IVYTY3.js +103 -0
- package/dist/draft-P4IVYTY3.js.map +1 -0
- package/dist/draft-QQMCVDDS.js +328 -0
- package/dist/draft-QQMCVDDS.js.map +1 -0
- package/dist/engine/index.d.ts +213 -127
- package/dist/engine/index.js +18 -4
- package/dist/{env-4P5HOGNA.js → env-FBTHZKGN.js} +12 -2
- package/dist/env-FBTHZKGN.js.map +1 -0
- package/dist/experiment-HDYTJPUY.js +1397 -0
- package/dist/experiment-HDYTJPUY.js.map +1 -0
- package/dist/export-TS5GYEMA.js +168 -0
- package/dist/export-TS5GYEMA.js.map +1 -0
- package/dist/extract-QVQFUOIK.js +113 -0
- package/dist/extract-QVQFUOIK.js.map +1 -0
- package/dist/facets-7MBSM7BP.js +114 -0
- package/dist/facets-7MBSM7BP.js.map +1 -0
- package/dist/favorites-7QP7BY5K.js +178 -0
- package/dist/favorites-7QP7BY5K.js.map +1 -0
- package/dist/feed-EETRO2FG.js +177 -0
- package/dist/feed-EETRO2FG.js.map +1 -0
- package/dist/feedback-ZOUL22TP.js +66 -0
- package/dist/feedback-ZOUL22TP.js.map +1 -0
- package/dist/feedback-record-XFFJRKS6.js +177 -0
- package/dist/feedback-record-XFFJRKS6.js.map +1 -0
- package/dist/fetch-QE3EB756.js +176 -0
- package/dist/fetch-QE3EB756.js.map +1 -0
- package/dist/fetch-Z7O3ZL4D.js +139 -0
- package/dist/fetch-Z7O3ZL4D.js.map +1 -0
- package/dist/find-KAQ6JDMO.js +134 -0
- package/dist/find-KAQ6JDMO.js.map +1 -0
- package/dist/fit-MY5GVZZZ.js +45 -0
- package/dist/fit-MY5GVZZZ.js.map +1 -0
- package/dist/flows-C67KEMDU.js +247 -0
- package/dist/flows-C67KEMDU.js.map +1 -0
- package/dist/follow-IX4XVK5Y.js +94 -0
- package/dist/follow-IX4XVK5Y.js.map +1 -0
- package/dist/follow-competitors-UZBUOYTH.js +112 -0
- package/dist/follow-competitors-UZBUOYTH.js.map +1 -0
- package/dist/following-VGOIUCIZ.js +113 -0
- package/dist/following-VGOIUCIZ.js.map +1 -0
- package/dist/fonts-UR7XZ5XZ.js +34 -0
- package/dist/fonts-UR7XZ5XZ.js.map +1 -0
- package/dist/forecast-3F4SZNAK.js +104 -0
- package/dist/forecast-3F4SZNAK.js.map +1 -0
- package/dist/forecast-K5E7CTKX.js +168 -0
- package/dist/forecast-K5E7CTKX.js.map +1 -0
- package/dist/funding-H5YO37OW.js +85 -0
- package/dist/funding-H5YO37OW.js.map +1 -0
- package/dist/funnel-2PPEPAMY.js +394 -0
- package/dist/funnel-2PPEPAMY.js.map +1 -0
- package/dist/ga4-YHJ2XMLC.js +55 -0
- package/dist/ga4-YHJ2XMLC.js.map +1 -0
- package/dist/generate-M2ZX5DMI.js +262 -0
- package/dist/generate-M2ZX5DMI.js.map +1 -0
- package/dist/get-4EYKCZ6F.js +59 -0
- package/dist/get-4EYKCZ6F.js.map +1 -0
- package/dist/get-637GALM2.js +63 -0
- package/dist/get-637GALM2.js.map +1 -0
- package/dist/get-AZARFR6O.js +61 -0
- package/dist/get-AZARFR6O.js.map +1 -0
- package/dist/get-BPMEHRUG.js +56 -0
- package/dist/get-BPMEHRUG.js.map +1 -0
- package/dist/get-MQ6MMIZ7.js +78 -0
- package/dist/get-MQ6MMIZ7.js.map +1 -0
- package/dist/get-N4BPOQCB.js +63 -0
- package/dist/get-N4BPOQCB.js.map +1 -0
- package/dist/get-RPZHLQ56.js +92 -0
- package/dist/get-RPZHLQ56.js.map +1 -0
- package/dist/gif-6PRTB2VR.js +94 -0
- package/dist/gif-6PRTB2VR.js.map +1 -0
- package/dist/google-4XAYE4OI.js +3190 -0
- package/dist/google-4XAYE4OI.js.map +1 -0
- package/dist/google-52JRH7X3.js +136 -0
- package/dist/google-52JRH7X3.js.map +1 -0
- package/dist/google-ads-PWX7OF5Z.js +195 -0
- package/dist/google-ads-PWX7OF5Z.js.map +1 -0
- package/dist/group-AAZ5QKC3.js +43 -0
- package/dist/group-AAZ5QKC3.js.map +1 -0
- package/dist/group-GSYCZORC.js +43 -0
- package/dist/group-GSYCZORC.js.map +1 -0
- package/dist/gsc-TS5T7ML2.js +30 -0
- package/dist/gsc-TS5T7ML2.js.map +1 -0
- package/dist/history-EW6LFFCX.js +67 -0
- package/dist/history-EW6LFFCX.js.map +1 -0
- package/dist/history-XI5ABCFO.js +133 -0
- package/dist/history-XI5ABCFO.js.map +1 -0
- package/dist/hubspot-AVUOILRE.js +779 -0
- package/dist/hubspot-AVUOILRE.js.map +1 -0
- package/dist/icon-K75KI6BV.js +137 -0
- package/dist/icon-K75KI6BV.js.map +1 -0
- package/dist/ideas-UCPV3KTM.js +35 -0
- package/dist/ideas-UCPV3KTM.js.map +1 -0
- package/dist/images-CD53I2W5.js +90 -0
- package/dist/images-CD53I2W5.js.map +1 -0
- package/dist/improve-L3BW4EQG.js +86 -0
- package/dist/improve-L3BW4EQG.js.map +1 -0
- package/dist/ingest-KRJOYTCQ.js +107 -0
- package/dist/ingest-KRJOYTCQ.js.map +1 -0
- package/dist/ingest-WE3SPPND.js +23 -0
- package/dist/ingest-WE3SPPND.js.map +1 -0
- package/dist/insights-PELVD4RY.js +122 -0
- package/dist/insights-PELVD4RY.js.map +1 -0
- package/dist/insights-XCA4BUJW.js +423 -0
- package/dist/insights-XCA4BUJW.js.map +1 -0
- package/dist/inspect-QKETG5UJ.js +189 -0
- package/dist/inspect-QKETG5UJ.js.map +1 -0
- package/dist/inspiration-Y2J2PUPC.js +53 -0
- package/dist/inspiration-Y2J2PUPC.js.map +1 -0
- package/dist/intent-YJOJGNVJ.js +95 -0
- package/dist/intent-YJOJGNVJ.js.map +1 -0
- package/dist/job-E2U4FS5P.js +202 -0
- package/dist/job-E2U4FS5P.js.map +1 -0
- package/dist/job-create-DFYCHVQ7.js +109 -0
- package/dist/job-create-DFYCHVQ7.js.map +1 -0
- package/dist/job-status-FFPMTSHB.js +74 -0
- package/dist/job-status-FFPMTSHB.js.map +1 -0
- package/dist/keep-GYZS2UTL.js +78 -0
- package/dist/keep-GYZS2UTL.js.map +1 -0
- package/dist/keyword-gap-QU7O7UKC.js +130 -0
- package/dist/keyword-gap-QU7O7UKC.js.map +1 -0
- package/dist/keyword-metrics-HLCM3QU7.js +197 -0
- package/dist/keyword-metrics-HLCM3QU7.js.map +1 -0
- package/dist/keywords-for-site-BDKPQKWB.js +128 -0
- package/dist/keywords-for-site-BDKPQKWB.js.map +1 -0
- package/dist/landing-4K6XYNFM.js +28 -0
- package/dist/landing-4K6XYNFM.js.map +1 -0
- package/dist/landings-F7LOAEJE.js +151 -0
- package/dist/landings-F7LOAEJE.js.map +1 -0
- package/dist/languages-P3ZM6R2A.js +40 -0
- package/dist/languages-P3ZM6R2A.js.map +1 -0
- package/dist/languages-XEJKTIFP.js +55 -0
- package/dist/languages-XEJKTIFP.js.map +1 -0
- package/dist/launches-TCFAYUA5.js +19 -0
- package/dist/launches-TCFAYUA5.js.map +1 -0
- package/dist/layerize-ZSKFIPZA.js +190 -0
- package/dist/layerize-ZSKFIPZA.js.map +1 -0
- package/dist/leads-GDF4S2AM.js +90 -0
- package/dist/leads-GDF4S2AM.js.map +1 -0
- package/dist/leads-TPB5OFSQ.js +293 -0
- package/dist/leads-TPB5OFSQ.js.map +1 -0
- package/dist/learn-NMFEA5H5.js +203 -0
- package/dist/learn-NMFEA5H5.js.map +1 -0
- package/dist/library-IP2UKNRU.js +109 -0
- package/dist/library-IP2UKNRU.js.map +1 -0
- package/dist/lighthouse-57XBJRCO.js +75 -0
- package/dist/lighthouse-57XBJRCO.js.map +1 -0
- package/dist/line-item-writes-O6SSS5NQ.js +208 -0
- package/dist/line-item-writes-O6SSS5NQ.js.map +1 -0
- package/dist/line-items-ZZAKH3YZ.js +103 -0
- package/dist/line-items-ZZAKH3YZ.js.map +1 -0
- package/dist/link-CRY57R3E.js +64 -0
- package/dist/link-CRY57R3E.js.map +1 -0
- package/dist/linkedin-WC7LGYPP.js +1008 -0
- package/dist/linkedin-WC7LGYPP.js.map +1 -0
- package/dist/list-6IKPWQGG.js +57 -0
- package/dist/list-6IKPWQGG.js.map +1 -0
- package/dist/list-CAUH3BMG.js +65 -0
- package/dist/list-CAUH3BMG.js.map +1 -0
- package/dist/list-CWAKX5TH.js +63 -0
- package/dist/list-CWAKX5TH.js.map +1 -0
- package/dist/list-FJ5FSVL6.js +151 -0
- package/dist/list-FJ5FSVL6.js.map +1 -0
- package/dist/list-GTOSN7DP.js +50 -0
- package/dist/list-GTOSN7DP.js.map +1 -0
- package/dist/list-HLJP4NVE.js +51 -0
- package/dist/list-HLJP4NVE.js.map +1 -0
- package/dist/list-LCUPF7EF.js +76 -0
- package/dist/list-LCUPF7EF.js.map +1 -0
- package/dist/list-NH4ZRZTL.js +303 -0
- package/dist/list-NH4ZRZTL.js.map +1 -0
- package/dist/locations-2BYWKIYA.js +67 -0
- package/dist/locations-2BYWKIYA.js.map +1 -0
- package/dist/locations-LVVDOSXO.js +40 -0
- package/dist/locations-LVVDOSXO.js.map +1 -0
- package/dist/log-6JOWOY5G.js +92 -0
- package/dist/log-6JOWOY5G.js.map +1 -0
- package/dist/logo-AJK2TDQU.js +18 -0
- package/dist/logo-AJK2TDQU.js.map +1 -0
- package/dist/lookup-H5GEM77H.js +22 -0
- package/dist/lookup-H5GEM77H.js.map +1 -0
- package/dist/make-Q2AMLCWE.js +640 -0
- package/dist/make-Q2AMLCWE.js.map +1 -0
- package/dist/map-4KOYFHAN.js +404 -0
- package/dist/map-4KOYFHAN.js.map +1 -0
- package/dist/mcp-LSS2DHYL.js +463 -0
- package/dist/mcp-LSS2DHYL.js.map +1 -0
- package/dist/media-JBCN6V4X.js +15 -0
- package/dist/media-JBCN6V4X.js.map +1 -0
- package/dist/media-RAGEJTZX.js +89 -0
- package/dist/media-RAGEJTZX.js.map +1 -0
- package/dist/media-sources-GSPAV7HT.js +32 -0
- package/dist/media-sources-GSPAV7HT.js.map +1 -0
- package/dist/members-GUUVEK2Y.js +44 -0
- package/dist/members-GUUVEK2Y.js.map +1 -0
- package/dist/meta-Z37ZR3PJ.js +69 -0
- package/dist/meta-Z37ZR3PJ.js.map +1 -0
- package/dist/metrics-KW6SDULI.js +152 -0
- package/dist/metrics-KW6SDULI.js.map +1 -0
- package/dist/models-5J4WFUD3.js +155 -0
- package/dist/models-5J4WFUD3.js.map +1 -0
- package/dist/normalize-DSFVTRXN.js +806 -0
- package/dist/normalize-DSFVTRXN.js.map +1 -0
- package/dist/normalize-EUDI5HEM.js +141 -0
- package/dist/normalize-EUDI5HEM.js.map +1 -0
- package/dist/options-P4PPJQH4.js +121 -0
- package/dist/options-P4PPJQH4.js.map +1 -0
- package/dist/output-DTCLVPUF.js +24 -0
- package/dist/output-DTCLVPUF.js.map +1 -0
- package/dist/page-N2ZO3O7F.js +105 -0
- package/dist/page-N2ZO3O7F.js.map +1 -0
- package/dist/pages-FQ4CBAJ2.js +66 -0
- package/dist/pages-FQ4CBAJ2.js.map +1 -0
- package/dist/performance-A66LYIZX.js +24 -0
- package/dist/performance-A66LYIZX.js.map +1 -0
- package/dist/pinterest-NV5XTNJE.js +96 -0
- package/dist/pinterest-NV5XTNJE.js.map +1 -0
- package/dist/pixels-CTJ43FZ4.js +108 -0
- package/dist/pixels-CTJ43FZ4.js.map +1 -0
- package/dist/pixels-HKINGZCH.js +60 -0
- package/dist/pixels-HKINGZCH.js.map +1 -0
- package/dist/plan-ZYTWLGWK.js +207 -0
- package/dist/plan-ZYTWLGWK.js.map +1 -0
- package/dist/preview-5ROBOQG7.js +169 -0
- package/dist/preview-5ROBOQG7.js.map +1 -0
- package/dist/profile-Q3PHR6FU.js +159 -0
- package/dist/profile-Q3PHR6FU.js.map +1 -0
- package/dist/promoted-tweet-writes-AEOUK2LK.js +180 -0
- package/dist/promoted-tweet-writes-AEOUK2LK.js.map +1 -0
- package/dist/promoted-tweets-L2CEC2BJ.js +119 -0
- package/dist/promoted-tweets-L2CEC2BJ.js.map +1 -0
- package/dist/properties-WLL6M2P6.js +101 -0
- package/dist/properties-WLL6M2P6.js.map +1 -0
- package/dist/publish-KHNR5ARF.js +322 -0
- package/dist/publish-KHNR5ARF.js.map +1 -0
- package/dist/query-A34J7BGX.js +61 -0
- package/dist/query-A34J7BGX.js.map +1 -0
- package/dist/query-IYZN5KHO.js +236 -0
- package/dist/query-IYZN5KHO.js.map +1 -0
- package/dist/query-UN2P6DBA.js +247 -0
- package/dist/query-UN2P6DBA.js.map +1 -0
- package/dist/questionnaire-Z2ZIKNBV.js +93 -0
- package/dist/questionnaire-Z2ZIKNBV.js.map +1 -0
- package/dist/read-GM7PQYJA.js +141 -0
- package/dist/read-GM7PQYJA.js.map +1 -0
- package/dist/reddit-5NPFULGD.js +26 -0
- package/dist/reddit-5NPFULGD.js.map +1 -0
- package/dist/refresh-FGXW4Y4X.js +94 -0
- package/dist/refresh-FGXW4Y4X.js.map +1 -0
- package/dist/release-OKZMC73N.js +60 -0
- package/dist/release-OKZMC73N.js.map +1 -0
- package/dist/relevant-pages-J76ZKNKF.js +99 -0
- package/dist/relevant-pages-J76ZKNKF.js.map +1 -0
- package/dist/remove-CA2J6ACH.js +50 -0
- package/dist/remove-CA2J6ACH.js.map +1 -0
- package/dist/remove-GOYW2G4R.js +48 -0
- package/dist/remove-GOYW2G4R.js.map +1 -0
- package/dist/reopen-XPKSOE6O.js +63 -0
- package/dist/reopen-XPKSOE6O.js.map +1 -0
- package/dist/rerun-2ERJV4WC.js +86 -0
- package/dist/rerun-2ERJV4WC.js.map +1 -0
- package/dist/research-FZ63UZTE.js +62 -0
- package/dist/research-FZ63UZTE.js.map +1 -0
- package/dist/research-YGQQ6CNG.js +262 -0
- package/dist/research-YGQQ6CNG.js.map +1 -0
- package/dist/reset-BGPZ4HMA.js +54 -0
- package/dist/reset-BGPZ4HMA.js.map +1 -0
- package/dist/reset-HTD6LCIT.js +54 -0
- package/dist/reset-HTD6LCIT.js.map +1 -0
- package/dist/resolve-NRDZ6N2B.js +121 -0
- package/dist/resolve-NRDZ6N2B.js.map +1 -0
- package/dist/retry-PF4BGKJV.js +60 -0
- package/dist/retry-PF4BGKJV.js.map +1 -0
- package/dist/retry-XL26JDAV.js +62 -0
- package/dist/retry-XL26JDAV.js.map +1 -0
- package/dist/retry-failed-BEFWRV4Z.js +45 -0
- package/dist/retry-failed-BEFWRV4Z.js.map +1 -0
- package/dist/run-EMJLI7LR.js +65 -0
- package/dist/run-EMJLI7LR.js.map +1 -0
- package/dist/run-L5K44UEA.js +61 -0
- package/dist/run-L5K44UEA.js.map +1 -0
- package/dist/scaffold-ad-AY2OL7RI.js +1550 -0
- package/dist/scaffold-ad-AY2OL7RI.js.map +1 -0
- package/dist/scaffold-static-ad-FXYE46MT.js +973 -0
- package/dist/scaffold-static-ad-FXYE46MT.js.map +1 -0
- package/dist/scaffold-video-533BT6RX.js +874 -0
- package/dist/scaffold-video-533BT6RX.js.map +1 -0
- package/dist/schedule-KQ7UIR3N.js +66 -0
- package/dist/schedule-KQ7UIR3N.js.map +1 -0
- package/dist/schedule-PKPNSISL.js +61 -0
- package/dist/schedule-PKPNSISL.js.map +1 -0
- package/dist/scheduled-agents-LP5LITA3.js +49 -0
- package/dist/scheduled-agents-LP5LITA3.js.map +1 -0
- package/dist/schema-B6J6VPTO.js +132 -0
- package/dist/schema-B6J6VPTO.js.map +1 -0
- package/dist/schema-QXTDLZVC.js +63 -0
- package/dist/schema-QXTDLZVC.js.map +1 -0
- package/dist/scrape-7YKJWFZE.js +2241 -0
- package/dist/scrape-7YKJWFZE.js.map +1 -0
- package/dist/screenshot-ZHBSG3SI.js +102 -0
- package/dist/screenshot-ZHBSG3SI.js.map +1 -0
- package/dist/search-332KFYZ6.js +224 -0
- package/dist/search-332KFYZ6.js.map +1 -0
- package/dist/search-4PBMXXUY.js +91 -0
- package/dist/search-4PBMXXUY.js.map +1 -0
- package/dist/search-6WNUKCMP.js +174 -0
- package/dist/search-6WNUKCMP.js.map +1 -0
- package/dist/search-AVNUU6TJ.js +26 -0
- package/dist/search-AVNUU6TJ.js.map +1 -0
- package/dist/search-F5INRFFK.js +92 -0
- package/dist/search-F5INRFFK.js.map +1 -0
- package/dist/search-copy-DZVBYG2B.js +168 -0
- package/dist/search-copy-DZVBYG2B.js.map +1 -0
- package/dist/seeds-5JTQN5WI.js +101 -0
- package/dist/seeds-5JTQN5WI.js.map +1 -0
- package/dist/select-RSGLDQ5Z.js +96 -0
- package/dist/select-RSGLDQ5Z.js.map +1 -0
- package/dist/sends-3L6QBS46.js +309 -0
- package/dist/sends-3L6QBS46.js.map +1 -0
- package/dist/sequences-YKFV7BDH.js +146 -0
- package/dist/sequences-YKFV7BDH.js.map +1 -0
- package/dist/set-prompt-7WWJI6XW.js +188 -0
- package/dist/set-prompt-7WWJI6XW.js.map +1 -0
- package/dist/setup-links-6H5ONDCQ.js +141 -0
- package/dist/setup-links-6H5ONDCQ.js.map +1 -0
- package/dist/{shared-6762QE6R.js → shared-QAMP7FZV.js} +8 -6
- package/dist/shared-QAMP7FZV.js.map +1 -0
- package/dist/shopify-2OY3J3OY.js +3692 -0
- package/dist/shopify-2OY3J3OY.js.map +1 -0
- package/dist/site-TBPERLY3.js +177 -0
- package/dist/site-TBPERLY3.js.map +1 -0
- package/dist/sitemaps-XPGLW24S.js +87 -0
- package/dist/sitemaps-XPGLW24S.js.map +1 -0
- package/dist/sites-WMBY2HJV.js +101 -0
- package/dist/sites-WMBY2HJV.js.map +1 -0
- package/dist/skills-3HEILQCU.js +47 -0
- package/dist/skills-3HEILQCU.js.map +1 -0
- package/dist/sources-JFQKTK2L.js +421 -0
- package/dist/sources-JFQKTK2L.js.map +1 -0
- package/dist/sources-Q3I6DDV7.js +30 -0
- package/dist/sources-Q3I6DDV7.js.map +1 -0
- package/dist/stale-CAXBLZKJ.js +66 -0
- package/dist/stale-CAXBLZKJ.js.map +1 -0
- package/dist/stats-GNILHSKK.js +34 -0
- package/dist/stats-GNILHSKK.js.map +1 -0
- package/dist/status-LIZWJYS4.js +62 -0
- package/dist/status-LIZWJYS4.js.map +1 -0
- package/dist/sticker-KCV3VZHY.js +94 -0
- package/dist/sticker-KCV3VZHY.js.map +1 -0
- package/dist/stock-VTORKR4C.js +179 -0
- package/dist/stock-VTORKR4C.js.map +1 -0
- package/dist/studio-QCRA6BY5.js +49 -0
- package/dist/studio-QCRA6BY5.js.map +1 -0
- package/dist/sync-455DB46Y.js +54 -0
- package/dist/sync-455DB46Y.js.map +1 -0
- package/dist/sync-A4KKQ3B6.js +265 -0
- package/dist/sync-A4KKQ3B6.js.map +1 -0
- package/dist/sync-ULKWDFXM.js +54 -0
- package/dist/sync-ULKWDFXM.js.map +1 -0
- package/dist/sync-definition-P6QTHJJ6.js +55 -0
- package/dist/sync-definition-P6QTHJJ6.js.map +1 -0
- package/dist/tag-manager-E7QTXBWQ.js +43 -0
- package/dist/tag-manager-E7QTXBWQ.js.map +1 -0
- package/dist/tags-4Q4I5GQJ.js +20 -0
- package/dist/tags-4Q4I5GQJ.js.map +1 -0
- package/dist/tags-AMEVAQZ4.js +26 -0
- package/dist/tags-AMEVAQZ4.js.map +1 -0
- package/dist/tags-DPLOLH3E.js +20 -0
- package/dist/tags-DPLOLH3E.js.map +1 -0
- package/dist/tags-LDHXONR3.js +224 -0
- package/dist/tags-LDHXONR3.js.map +1 -0
- package/dist/tags-UW3WJTAQ.js +20 -0
- package/dist/tags-UW3WJTAQ.js.map +1 -0
- package/dist/targeting-constants-D64YO3E7.js +118 -0
- package/dist/targeting-constants-D64YO3E7.js.map +1 -0
- package/dist/targeting-criteria-BP6VJA7X.js +113 -0
- package/dist/targeting-criteria-BP6VJA7X.js.map +1 -0
- package/dist/targets-CQWO2UXD.js +102 -0
- package/dist/targets-CQWO2UXD.js.map +1 -0
- package/dist/templates-WZSTNRNZ.js +178 -0
- package/dist/templates-WZSTNRNZ.js.map +1 -0
- package/dist/testimonials-ETHSNWUH.js +32 -0
- package/dist/testimonials-ETHSNWUH.js.map +1 -0
- package/dist/themes-YU663LQH.js +94 -0
- package/dist/themes-YU663LQH.js.map +1 -0
- package/dist/top-companies-KTXHS472.js +108 -0
- package/dist/top-companies-KTXHS472.js.map +1 -0
- package/dist/translate-A7LYHUW3.js +600 -0
- package/dist/translate-A7LYHUW3.js.map +1 -0
- package/dist/triggers-4EDFLNGH.js +141 -0
- package/dist/triggers-4EDFLNGH.js.map +1 -0
- package/dist/tweets-ZUKQAAUQ.js +123 -0
- package/dist/tweets-ZUKQAAUQ.js.map +1 -0
- package/dist/unfollow-A4JVCJBF.js +46 -0
- package/dist/unfollow-A4JVCJBF.js.map +1 -0
- package/dist/unlink-KY2OEKMD.js +67 -0
- package/dist/unlink-KY2OEKMD.js.map +1 -0
- package/dist/unstage-FHUG67RI.js +84 -0
- package/dist/unstage-FHUG67RI.js.map +1 -0
- package/dist/unstage-ZRLLCSQF.js +95 -0
- package/dist/unstage-ZRLLCSQF.js.map +1 -0
- package/dist/update-27LGM65V.js +63 -0
- package/dist/update-27LGM65V.js.map +1 -0
- package/dist/update-AIY46I2Q.js +155 -0
- package/dist/update-AIY46I2Q.js.map +1 -0
- package/dist/update-QYD2XZFM.js +142 -0
- package/dist/update-QYD2XZFM.js.map +1 -0
- package/dist/update-W2OSRNFO.js +98 -0
- package/dist/update-W2OSRNFO.js.map +1 -0
- package/dist/upload-JGBTSKGH.js +126 -0
- package/dist/upload-JGBTSKGH.js.map +1 -0
- package/dist/upload-XEHWYMJG.js +150 -0
- package/dist/upload-XEHWYMJG.js.map +1 -0
- package/dist/upscale-I5P2OHTN.js +109 -0
- package/dist/upscale-I5P2OHTN.js.map +1 -0
- package/dist/url-options-QHGA42RP.js +130 -0
- package/dist/url-options-QHGA42RP.js.map +1 -0
- package/dist/url-params-NWSUHWRE.js +98 -0
- package/dist/url-params-NWSUHWRE.js.map +1 -0
- package/dist/use-U4HG2NF3.js +95 -0
- package/dist/use-U4HG2NF3.js.map +1 -0
- package/dist/validate-VKL3XKQ2.js +91 -0
- package/dist/validate-VKL3XKQ2.js.map +1 -0
- package/dist/variant-FOVE6URJ.js +338 -0
- package/dist/variant-FOVE6URJ.js.map +1 -0
- package/dist/videos-DP3VCSYG.js +39 -0
- package/dist/videos-DP3VCSYG.js.map +1 -0
- package/dist/view-HRI3FHCH.js +121 -0
- package/dist/view-HRI3FHCH.js.map +1 -0
- package/dist/viewer-check-JYUE24M6.js +68 -0
- package/dist/viewer-check-JYUE24M6.js.map +1 -0
- package/dist/web-AFUIWPFU.js +140 -0
- package/dist/web-AFUIWPFU.js.map +1 -0
- package/dist/winners-SMMDN6LW.js +113 -0
- package/dist/winners-SMMDN6LW.js.map +1 -0
- package/dist/winning-ads-PCIJUYVA.js +84 -0
- package/dist/winning-ads-PCIJUYVA.js.map +1 -0
- package/dist/write-commands-7Z34WG2J.js +206 -0
- package/dist/write-commands-7Z34WG2J.js.map +1 -0
- package/dist/write-commands-BLT2SEC4.js +713 -0
- package/dist/write-commands-BLT2SEC4.js.map +1 -0
- package/dist/write-commands-N4FSGRVQ.js +743 -0
- package/dist/write-commands-N4FSGRVQ.js.map +1 -0
- package/dist/write-commands-Q4MQ3BGM.js +1015 -0
- package/dist/write-commands-Q4MQ3BGM.js.map +1 -0
- package/dist/x-AUOZJNWE.js +47 -0
- package/dist/x-AUOZJNWE.js.map +1 -0
- package/package.json +9 -2
- package/dist/chunk-FGHMWBUD.js +0 -9989
- package/dist/chunk-FGHMWBUD.js.map +0 -1
- package/dist/chunk-HJEMOSPH.js +0 -1292
- package/dist/chunk-HJEMOSPH.js.map +0 -1
- package/dist/chunk-MF7YA62W.js.map +0 -1
- package/dist/chunk-VZEDAFAR.js.map +0 -1
- package/dist/chunk-XHC4LMK4.js.map +0 -1
- package/dist/client-GR6YL3YX.js +0 -17
- package/dist/output-NMQXZF3Z.js +0 -18
- /package/dist/{chunk-WLDM2TRF.js.map → chunk-TPXI2GCW.js.map} +0 -0
- /package/dist/{client-GR6YL3YX.js.map → chunk-YQSBHWOI.js.map} +0 -0
- /package/dist/{env-4P5HOGNA.js.map → client-26SAJ46D.js.map} +0 -0
- /package/dist/{output-NMQXZF3Z.js.map → connect-RXPMAJQI.js.map} +0 -0
- /package/dist/{shared-6762QE6R.js.map → customers-P6LLLJHK.js.map} +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/commands/images/brandVerification.ts
|
|
2
|
+
function brandToken(domain) {
|
|
3
|
+
const bare = domain.trim().toLowerCase().replace(/^[a-z]+:\/\//, "").replace(/^www\./, "").split("/")[0];
|
|
4
|
+
const label = (bare ?? "").split(".")[0] ?? "";
|
|
5
|
+
return label;
|
|
6
|
+
}
|
|
7
|
+
function readBackHints(domain, ingested, token, recoverRoute) {
|
|
8
|
+
if (ingested.length === 0) {
|
|
9
|
+
return [
|
|
10
|
+
`Nothing was catalogued, so no described row exists to check the mark against. Re-run with \`--auto-ingest 1\` and read \`textInImage\` / \`subject\` back with \`baker images get <imageId>\`, or open the URL and confirm by eye that it is ${token || domain}'s mark and not another company's.`
|
|
11
|
+
];
|
|
12
|
+
}
|
|
13
|
+
const readBack = ingested.map((item) => `baker images get ${item.imageId}`).join(" && ");
|
|
14
|
+
return [
|
|
15
|
+
`Read the mark itself: run \`${readBack}\` and confirm \`textInImage\` / \`subject\` names ${token || domain}. If it names a different company, this is the wrong mark: discard it and use ${recoverRoute} instead.`,
|
|
16
|
+
"The catalogued row is described asynchronously, so `textInImage` may be empty on the first read \u2014 re-read once the row is `ready` rather than treating an empty field as a match."
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
function brandVerificationHints({
|
|
20
|
+
domain,
|
|
21
|
+
ingested,
|
|
22
|
+
hitCount = 0,
|
|
23
|
+
recover,
|
|
24
|
+
brandMatch
|
|
25
|
+
}) {
|
|
26
|
+
if (ingested.length === 0 && hitCount === 0) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const token = brandToken(domain);
|
|
30
|
+
const recoverRoute = recover ?? `\`baker images extract https://${domain}\` to pull the mark off the brand's own site`;
|
|
31
|
+
const readBack = readBackHints(domain, ingested, token, recoverRoute);
|
|
32
|
+
if (brandMatch?.verdict === "mismatch") {
|
|
33
|
+
const owner = brandMatch.name ?? "a different company";
|
|
34
|
+
const ownerDomain = brandMatch.domain ? ` (${brandMatch.domain})` : "";
|
|
35
|
+
return [
|
|
36
|
+
`WRONG BRAND \u2014 Brandfetch holds no record for "${domain}". The closest one it has is ${owner}${ownerDomain}, so the mark returned here is very likely ${owner}'s, not ${token || domain}'s. Do not place it. Use ${recoverRoute}, and if that fails, tell the user you could not find their logo rather than shipping this one.`,
|
|
37
|
+
...readBack
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
if (brandMatch?.verdict === "confirmed") {
|
|
41
|
+
const owner = brandMatch.name ?? (token || domain);
|
|
42
|
+
return [
|
|
43
|
+
`Brandfetch confirms "${domain}" is ${owner}, which verifies the record \u2014 not the artwork. Its ${owner} record is what the returned files come from, and a provider record can hold the wrong company's image: this is exactly how a domain confirmed as "Zernio" served ClickUp's logo into a client's page.`,
|
|
44
|
+
...readBack
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
if (brandMatch?.verdict === "unverified") {
|
|
48
|
+
return [
|
|
49
|
+
`This mark could not be checked \u2014 Brandfetch returned no record for "${domain}", so nothing confirms whose logo these files are. Treat it as unverified rather than as correct.`,
|
|
50
|
+
...readBack
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
return [
|
|
54
|
+
`VERIFY BRAND before placing any of these. This matched on the string "${domain}", not on what the image shows \u2014 a 200 from the provider's CDN only means bytes were served, so a wrong brand's mark comes back looking exactly like a right one.`,
|
|
55
|
+
...readBack
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
brandVerificationHints
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=chunk-IVIJJXXT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/images/brandVerification.ts"],"sourcesContent":["/**\n * Brandfetch matches on the domain string, not on what the mark depicts.\n *\n * Resolution is a constructed CDN URL probed with a GET whose bytes are thrown\n * away, so a 200 means \"the CDN served something\", never \"this is that brand's\n * logo\". In a real run `freepik.com` returned the Magnific wordmark and\n * `zernio.com` returned ClickUp — both shipped into a client's page and both\n * only noticed twenty minutes later, by eye.\n *\n * The response now carries `brandMatch`, Brandfetch's own answer to \"whose brand\n * is this domain\", so these hints no longer have to fire blind:\n *\n * - `mismatch` — Brandfetch has records and none is this brand. Loudest\n * warning available, naming the company whose mark this is.\n * - `unverified` — the check did not run. Say so; do not imply either verdict.\n * - `confirmed` — the metadata agrees. Says nothing about the artwork, and\n * the read-back check stays exactly where it was, because\n * `zernio.com` is `confirmed` and still serves ClickUp.\n *\n * The hits are never withheld. A warned-about wrong logo is recoverable; a\n * client whose real mark refuses to load is not.\n */\n\ninterface IngestedRef {\n imageId: string;\n}\n\n/** Brandfetch's verdict, as carried on the `logo` response. Absent for `icon`,\n * which has no brand record to consult, and for an older backend. */\ninterface BrandMatchRef {\n verdict: \"confirmed\" | \"mismatch\" | \"unverified\";\n requestedDomain?: string;\n name?: string;\n domain?: string;\n}\n\ninterface BrandVerificationInput {\n /** What was asked for — a domain for `logo`, an icon slug for `icon`. */\n domain: string;\n ingested: IngestedRef[];\n /** Hits returned by the provider. With `--no-auto-ingest` there are hits but\n * no library row, so the read-back check has nothing to read. */\n hitCount?: number;\n /** What to run when the mark turns out to be the wrong brand. Callers whose\n * subject is not a hostname must pass their own route — `https://<icon-slug>`\n * is not a page. */\n recover?: string;\n brandMatch?: BrandMatchRef;\n}\n\n/**\n * The brand's own word, as it would appear burned into its wordmark:\n * `www.zernio.com` → `zernio`, `linear.app` → `linear`.\n */\nexport function brandToken(domain: string): string {\n const bare = domain\n .trim()\n .toLowerCase()\n .replace(/^[a-z]+:\\/\\//, \"\")\n .replace(/^www\\./, \"\")\n .split(\"/\")[0];\n const label = (bare ?? \"\").split(\".\")[0] ?? \"\";\n return label;\n}\n\n/** How to read the mark back, or how to get into a position to. */\nfunction readBackHints(domain: string, ingested: IngestedRef[], token: string, recoverRoute: string): string[] {\n if (ingested.length === 0) {\n return [\n `Nothing was catalogued, so no described row exists to check the mark against. Re-run with \\`--auto-ingest 1\\` and read \\`textInImage\\` / \\`subject\\` back with \\`baker images get <imageId>\\`, or open the URL and confirm by eye that it is ${token || domain}'s mark and not another company's.`,\n ];\n }\n const readBack = ingested.map((item) => `baker images get ${item.imageId}`).join(\" && \");\n return [\n `Read the mark itself: run \\`${readBack}\\` and confirm \\`textInImage\\` / \\`subject\\` names ${token || domain}. If it names a different company, this is the wrong mark: discard it and use ${recoverRoute} instead.`,\n \"The catalogued row is described asynchronously, so `textInImage` may be empty on the first read — re-read once the row is `ready` rather than treating an empty field as a match.\",\n ];\n}\n\nexport function brandVerificationHints({\n domain,\n ingested,\n hitCount = 0,\n recover,\n brandMatch,\n}: BrandVerificationInput): string[] {\n if (ingested.length === 0 && hitCount === 0) {\n return [];\n }\n\n const token = brandToken(domain);\n const recoverRoute =\n recover ?? `\\`baker images extract https://${domain}\\` to pull the mark off the brand's own site`;\n const readBack = readBackHints(domain, ingested, token, recoverRoute);\n\n if (brandMatch?.verdict === \"mismatch\") {\n const owner = brandMatch.name ?? \"a different company\";\n const ownerDomain = brandMatch.domain ? ` (${brandMatch.domain})` : \"\";\n return [\n `WRONG BRAND — Brandfetch holds no record for \"${domain}\". The closest one it has is ${owner}${ownerDomain}, so the mark returned here is very likely ${owner}'s, not ${token || domain}'s. Do not place it. Use ${recoverRoute}, and if that fails, tell the user you could not find their logo rather than shipping this one.`,\n ...readBack,\n ];\n }\n\n if (brandMatch?.verdict === \"confirmed\") {\n const owner = brandMatch.name ?? (token || domain);\n return [\n `Brandfetch confirms \"${domain}\" is ${owner}, which verifies the record — not the artwork. Its ${owner} record is what the returned files come from, and a provider record can hold the wrong company's image: this is exactly how a domain confirmed as \"Zernio\" served ClickUp's logo into a client's page.`,\n ...readBack,\n ];\n }\n\n if (brandMatch?.verdict === \"unverified\") {\n return [\n `This mark could not be checked — Brandfetch returned no record for \"${domain}\", so nothing confirms whose logo these files are. Treat it as unverified rather than as correct.`,\n ...readBack,\n ];\n }\n\n // No verdict at all (an `icon` lookup, or a backend that predates the field):\n // fall back to warning unconditionally, since a wrong brand and a right one\n // are byte-identical in shape.\n return [\n `VERIFY BRAND before placing any of these. This matched on the string \"${domain}\", not on what the image shows — a 200 from the provider's CDN only means bytes were served, so a wrong brand's mark comes back looking exactly like a right one.`,\n ...readBack,\n ];\n}\n"],"mappings":";AAsDO,SAAS,WAAW,QAAwB;AACjD,QAAM,OAAO,OACV,KAAK,EACL,YAAY,EACZ,QAAQ,gBAAgB,EAAE,EAC1B,QAAQ,UAAU,EAAE,EACpB,MAAM,GAAG,EAAE,CAAC;AACf,QAAM,SAAS,QAAQ,IAAI,MAAM,GAAG,EAAE,CAAC,KAAK;AAC5C,SAAO;AACT;AAGA,SAAS,cAAc,QAAgB,UAAyB,OAAe,cAAgC;AAC7G,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,MACL,gPAAgP,SAAS,MAAM;AAAA,IACjQ;AAAA,EACF;AACA,QAAM,WAAW,SAAS,IAAI,CAAC,SAAS,oBAAoB,KAAK,OAAO,EAAE,EAAE,KAAK,MAAM;AACvF,SAAO;AAAA,IACL,+BAA+B,QAAQ,sDAAsD,SAAS,MAAM,iFAAiF,YAAY;AAAA,IACzM;AAAA,EACF;AACF;AAEO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AACF,GAAqC;AACnC,MAAI,SAAS,WAAW,KAAK,aAAa,GAAG;AAC3C,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,QAAQ,WAAW,MAAM;AAC/B,QAAM,eACJ,WAAW,kCAAkC,MAAM;AACrD,QAAM,WAAW,cAAc,QAAQ,UAAU,OAAO,YAAY;AAEpE,MAAI,YAAY,YAAY,YAAY;AACtC,UAAM,QAAQ,WAAW,QAAQ;AACjC,UAAM,cAAc,WAAW,SAAS,KAAK,WAAW,MAAM,MAAM;AACpE,WAAO;AAAA,MACL,sDAAiD,MAAM,gCAAgC,KAAK,GAAG,WAAW,8CAA8C,KAAK,WAAW,SAAS,MAAM,4BAA4B,YAAY;AAAA,MAC/N,GAAG;AAAA,IACL;AAAA,EACF;AAEA,MAAI,YAAY,YAAY,aAAa;AACvC,UAAM,QAAQ,WAAW,SAAS,SAAS;AAC3C,WAAO;AAAA,MACL,wBAAwB,MAAM,QAAQ,KAAK,2DAAsD,KAAK;AAAA,MACtG,GAAG;AAAA,IACL;AAAA,EACF;AAEA,MAAI,YAAY,YAAY,cAAc;AACxC,WAAO;AAAA,MACL,4EAAuE,MAAM;AAAA,MAC7E,GAAG;AAAA,IACL;AAAA,EACF;AAKA,SAAO;AAAA,IACL,yEAAyE,MAAM;AAAA,IAC/E,GAAG;AAAA,EACL;AACF;","names":[]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiGet
|
|
3
|
+
} from "./chunk-HREWXNTO.js";
|
|
4
|
+
|
|
5
|
+
// src/commands/testimonials/emptyCorpusHints.ts
|
|
6
|
+
function resolveEmptyReason({
|
|
7
|
+
resultCount,
|
|
8
|
+
activeFilters,
|
|
9
|
+
sourceCount
|
|
10
|
+
}) {
|
|
11
|
+
if (resultCount > 0) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
if (activeFilters.length > 0) {
|
|
15
|
+
return "filtered_out";
|
|
16
|
+
}
|
|
17
|
+
return sourceCount === 0 ? "no_corpus_connected" : "corpus_empty";
|
|
18
|
+
}
|
|
19
|
+
var NO_CORPUS_EXIT = "Testimonials are ingested from the client's public review pages \u2014 an agent cannot write one \u2014 so no rewording will find quotes. If the user named the client's own review page (Google Maps, Trustpilot, Yelp, Tripadvisor, G2, Capterra, Amazon, App Store, Google Play), add it with `baker testimonials sources add <link>` \u2014 its reviews arrive over the next minutes, not in this turn. Stop searching and source proof another way: a result or case study the client already published, a named-customer logo (`baker images logo`), or a founder claim attributed as a claim. Otherwise ship without a testimonial block and file the gap: `baker actions create --name \"Collect customer quotes for <page>\" --priority medium --tags <slug>`. Never invent, paraphrase-into-existence, or pad with unrelated praise.";
|
|
20
|
+
function emptyReasonDetail(reason, sourceCount, activeFilters) {
|
|
21
|
+
if (reason === "filtered_out") {
|
|
22
|
+
return `No rows matched, and ${activeFilters.join(", ")} narrowed this read. The corpus was not checked \u2014 drop every filter to see whether the library itself is empty.`;
|
|
23
|
+
}
|
|
24
|
+
if (reason === "no_corpus_connected") {
|
|
25
|
+
return "This company has no review source connected \u2014 checked against its source list, not inferred from the empty result.";
|
|
26
|
+
}
|
|
27
|
+
return `${sourceCount} review source${sourceCount === 1 ? " is" : "s are"} connected but hold no testimonials yet \u2014 the source is there, the rows are not. Ingestion may still be running.`;
|
|
28
|
+
}
|
|
29
|
+
function morePagesHint(resultCount, cursor) {
|
|
30
|
+
const found = resultCount === 0 ? "This page held no matches" : `This page held ${resultCount}`;
|
|
31
|
+
return `${found}, and the library continues past it \u2014 so this is one page, not the client's whole set. Do not report it as the corpus and do not conclude anything is missing from it. Read the next page with \`baker testimonials list --cursor ${cursor}\` (same filters), or go straight at the rows you want with \`baker testimonials search <query>\`.`;
|
|
32
|
+
}
|
|
33
|
+
function endOfWalkHint(command) {
|
|
34
|
+
const noun = command === "search" ? "results" : "rows";
|
|
35
|
+
return `That was the end of the library \u2014 no more ${noun} past the page before this one. Nothing here says the corpus is empty (the earlier pages held it), so answer from what those pages returned rather than re-reading.`;
|
|
36
|
+
}
|
|
37
|
+
async function measureEmptyCorpus({
|
|
38
|
+
command,
|
|
39
|
+
resultCount,
|
|
40
|
+
activeFilters,
|
|
41
|
+
nextCursor = null,
|
|
42
|
+
continued = false
|
|
43
|
+
}) {
|
|
44
|
+
if (nextCursor) {
|
|
45
|
+
return { hints: [morePagesHint(resultCount, nextCursor)] };
|
|
46
|
+
}
|
|
47
|
+
if (resultCount > 0) {
|
|
48
|
+
return { hints: [] };
|
|
49
|
+
}
|
|
50
|
+
if (continued) {
|
|
51
|
+
return { hints: [endOfWalkHint(command)] };
|
|
52
|
+
}
|
|
53
|
+
if (activeFilters.length > 0) {
|
|
54
|
+
const reason2 = "filtered_out";
|
|
55
|
+
return {
|
|
56
|
+
hints: emptyCorpusHints({ command, reason: reason2, sourceCount: 0, activeFilters }),
|
|
57
|
+
empty: { reason: reason2, detail: emptyReasonDetail(reason2, 0, activeFilters) }
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
let sourceCount;
|
|
61
|
+
try {
|
|
62
|
+
const sources = await apiGet("/api/testimonials/sources");
|
|
63
|
+
sourceCount = Array.isArray(sources) ? sources.length : 0;
|
|
64
|
+
} catch {
|
|
65
|
+
return {
|
|
66
|
+
hints: [
|
|
67
|
+
"No rows, and the check for connected review sources failed \u2014 so this is NOT evidence that the client has no reviews. Do not record an absence you could not verify. Re-run once; if it fails again, say the library could not be read rather than that it is empty."
|
|
68
|
+
]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const reason = resolveEmptyReason({ resultCount, activeFilters, sourceCount });
|
|
72
|
+
if (reason === null) {
|
|
73
|
+
return { hints: [] };
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
hints: emptyCorpusHints({ command, reason, sourceCount, activeFilters }),
|
|
77
|
+
empty: { reason, detail: emptyReasonDetail(reason, sourceCount, activeFilters) }
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function emptyCorpusHints({
|
|
81
|
+
command,
|
|
82
|
+
reason,
|
|
83
|
+
sourceCount,
|
|
84
|
+
activeFilters
|
|
85
|
+
}) {
|
|
86
|
+
if (reason === null) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
if (reason === "filtered_out") {
|
|
90
|
+
return [
|
|
91
|
+
`No rows \u2014 ${activeFilters.join(", ")} narrowed this. Drop every filter and re-run once before touching the query; a filter combination and an empty library look identical from here.`
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
const lead = command === "search" ? "No hits" : "No rows";
|
|
95
|
+
if (reason === "no_corpus_connected") {
|
|
96
|
+
return [`${lead}, and this company's source list is empty: there is no review corpus to search. ${NO_CORPUS_EXIT}`];
|
|
97
|
+
}
|
|
98
|
+
return [
|
|
99
|
+
`${lead}. ${sourceCount} review source${sourceCount === 1 ? " is" : "s are"} connected but no testimonials have landed yet \u2014 so this is a timing or ingestion gap, not a missing connection, and re-querying will not change it. Ingestion may still be running: say so rather than reporting the client has no reviews. ${NO_CORPUS_EXIT}`
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
measureEmptyCorpus
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=chunk-J57GWTPK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/testimonials/emptyCorpusHints.ts"],"sourcesContent":["/**\n * Zero-result steering for the testimonial corpus.\n *\n * A bare `[]` reads as \"my query missed\" and the agent re-queries — three calls\n * to prove the same thing, in an audited run. It almost never means that here:\n * testimonials are ingested from the client's Google/Trustpilot reviews and an\n * agent cannot create one, so an empty library is a dead end no rewording opens.\n *\n * This module used to *assert* which of those it was, from `resultCount === 0`\n * alone: an unfiltered browse returning nothing was declared \"proof\" that the\n * company had no review corpus connected. It was never checked, and a company\n * with a connected source that simply holds no rows yet got told, confidently,\n * that it had no source at all. An agent then wrote that into the client's\n * knowledge vault as fact.\n *\n * So the reason is now measured against `GET /api/testimonials/sources` before\n * anything is claimed. `resolveEmptyReason` is the whole of that judgement and\n * is kept pure so it can be tested without a backend.\n */\n\nimport { apiGet } from \"../../client.ts\";\nimport type { EmptyEvidence } from \"../../output.ts\";\n\nexport type TestimonialQuery = \"search\" | \"list\";\n\n/**\n * Why a read came back empty.\n *\n * - `filtered_out` — filters were applied; the corpus may be fine.\n * - `no_corpus_connected` — the company has no review source at all. Terminal.\n * - `corpus_empty` — a source exists but holds no rows yet (still\n * ingesting, or the source genuinely has no reviews).\n */\nexport type EmptyCorpusReason = \"no_corpus_connected\" | \"corpus_empty\" | \"filtered_out\";\n\ninterface ResolveInput {\n resultCount: number;\n activeFilters: string[];\n /** Rows from /api/testimonials/sources. */\n sourceCount: number;\n}\n\nexport function resolveEmptyReason({\n resultCount,\n activeFilters,\n sourceCount,\n}: ResolveInput): EmptyCorpusReason | null {\n if (resultCount > 0) {\n return null;\n }\n // Filters first: they explain the empty result without saying anything about\n // the corpus, and a filter combination and an empty library look identical\n // from the result set alone.\n if (activeFilters.length > 0) {\n return \"filtered_out\";\n }\n return sourceCount === 0 ? \"no_corpus_connected\" : \"corpus_empty\";\n}\n\nconst NO_CORPUS_EXIT =\n \"Testimonials are ingested from the client's public review pages — an agent cannot write one — so no \" +\n \"rewording will find quotes. If the user named the client's own review page (Google Maps, Trustpilot, Yelp, \" +\n \"Tripadvisor, G2, Capterra, Amazon, App Store, Google Play), add it with `baker testimonials sources add <link>` \" +\n \"— its reviews arrive over the next minutes, not in this turn. Stop searching and source proof another way: a result or case study the client \" +\n \"already published, a named-customer logo (`baker images logo`), or a founder claim attributed as a claim. \" +\n \"Otherwise ship without a testimonial block and file the gap: `baker actions create \" +\n '--name \"Collect customer quotes for <page>\" --priority medium --tags <slug>`. ' +\n \"Never invent, paraphrase-into-existence, or pad with unrelated praise.\";\n\n/**\n * `detail` is written to be quotable — it ends up in `meta.empty.detail`, and\n * an agent that repeats it verbatim should still be saying something true.\n */\nexport function emptyReasonDetail(reason: EmptyCorpusReason, sourceCount: number, activeFilters: string[]): string {\n if (reason === \"filtered_out\") {\n return `No rows matched, and ${activeFilters.join(\", \")} narrowed this read. The corpus was not checked — drop every filter to see whether the library itself is empty.`;\n }\n if (reason === \"no_corpus_connected\") {\n return \"This company has no review source connected — checked against its source list, not inferred from the empty result.\";\n }\n return `${sourceCount} review source${sourceCount === 1 ? \" is\" : \"s are\"} connected but hold no testimonials yet — the source is there, the rows are not. Ingestion may still be running.`;\n}\n\n/**\n * What to say when the library did not end where this page did.\n *\n * `GET /api/testimonials` is paged — a testimonial row carries a 3072-float\n * embedding, so a listing reads an index page at a time and returns\n * `X-Baker-Next-Cursor` when rows remain unexamined. Until that cursor comes\n * back absent, every conclusion this module otherwise draws is off the table: an\n * empty page proves nothing about the corpus, and a short one is not \"all there\n * is\". The next call is a `--cursor` away, so the hint says exactly that.\n */\nexport function morePagesHint(resultCount: number, cursor: string): string {\n const found = resultCount === 0 ? \"This page held no matches\" : `This page held ${resultCount}`;\n return (\n `${found}, and the library continues past it — so this is one page, not the client's whole set. ` +\n \"Do not report it as the corpus and do not conclude anything is missing from it. Read the next page with \" +\n `\\`baker testimonials list --cursor ${cursor}\\` (same filters), or go straight at the rows you want with ` +\n \"`baker testimonials search <query>`.\"\n );\n}\n\n/** The last page of a walk came back empty: the read is over, and it worked. */\nfunction endOfWalkHint(command: TestimonialQuery): string {\n const noun = command === \"search\" ? \"results\" : \"rows\";\n return (\n `That was the end of the library — no more ${noun} past the page before this one. Nothing here says the ` +\n \"corpus is empty (the earlier pages held it), so answer from what those pages returned rather than re-reading.\"\n );\n}\n\n/**\n * Establishes why a read was empty, by asking the backend rather than inferring.\n *\n * Costs one extra round trip and only on the zero-result path, which is the\n * cheap half of the trade: the call it replaces was the agent re-querying two or\n * three times to convince itself, and the claim it replaces was sometimes wrong.\n *\n * If the source check itself fails we return nothing at all. That is the point\n * of the change — a read that did not happen must never become a confident\n * statement about the client's account, which is exactly the failure this\n * module previously shipped.\n */\nexport async function measureEmptyCorpus({\n command,\n resultCount,\n activeFilters,\n nextCursor = null,\n continued = false,\n}: {\n command: TestimonialQuery;\n resultCount: number;\n activeFilters: string[];\n /** `X-Baker-Next-Cursor` from the response — see `morePagesHint`. */\n nextCursor?: string | null;\n /** This call passed a `--cursor`, so it is the tail of a walk, not a read. */\n continued?: boolean;\n}): Promise<{ hints: string[]; empty?: EmptyEvidence }> {\n // A page that is not the last page establishes nothing about the corpus, so\n // it gets a hint and no `empty` evidence — the same rule as a failed source\n // check below. It is also the one path that speaks when rows came back:\n // \"here are 4\" is the misleading half.\n if (nextCursor) {\n return { hints: [morePagesHint(resultCount, nextCursor)] };\n }\n if (resultCount > 0) {\n return { hints: [] };\n }\n // Zero rows at the end of a walk is the walk ending — the rows were on the\n // pages already read. Measuring the corpus here would answer a question\n // nobody asked and, worse, answer it wrongly: a page can end exactly on the\n // last row (the page cap closes it with `isDone` still false), so a library\n // that was fully read hands back one final empty page, and `corpus_empty`\n // would report a company with reviews as having none.\n if (continued) {\n return { hints: [endOfWalkHint(command)] };\n }\n if (activeFilters.length > 0) {\n // Filters alone explain it; no need to spend a call on the corpus.\n const reason = \"filtered_out\" as const;\n return {\n hints: emptyCorpusHints({ command, reason, sourceCount: 0, activeFilters }),\n empty: { reason, detail: emptyReasonDetail(reason, 0, activeFilters) },\n };\n }\n\n let sourceCount: number;\n try {\n const sources = await apiGet<unknown[]>(\"/api/testimonials/sources\");\n sourceCount = Array.isArray(sources) ? sources.length : 0;\n } catch {\n return {\n hints: [\n \"No rows, and the check for connected review sources failed — so this is NOT evidence that the client \" +\n \"has no reviews. Do not record an absence you could not verify. Re-run once; if it fails again, say \" +\n \"the library could not be read rather than that it is empty.\",\n ],\n };\n }\n\n const reason = resolveEmptyReason({ resultCount, activeFilters, sourceCount });\n if (reason === null) {\n return { hints: [] };\n }\n return {\n hints: emptyCorpusHints({ command, reason, sourceCount, activeFilters }),\n empty: { reason, detail: emptyReasonDetail(reason, sourceCount, activeFilters) },\n };\n}\n\nexport function emptyCorpusHints({\n command,\n reason,\n sourceCount,\n activeFilters,\n}: {\n command: TestimonialQuery;\n reason: EmptyCorpusReason | null;\n sourceCount: number;\n activeFilters: string[];\n}): string[] {\n if (reason === null) {\n return [];\n }\n if (reason === \"filtered_out\") {\n return [\n `No rows — ${activeFilters.join(\", \")} narrowed this. Drop every filter and re-run once before touching ` +\n \"the query; a filter combination and an empty library look identical from here.\",\n ];\n }\n const lead = command === \"search\" ? \"No hits\" : \"No rows\";\n if (reason === \"no_corpus_connected\") {\n // Terminal, and now actually verified — so it is safe to tell the agent to\n // stop, which is the whole point of saying it.\n return [`${lead}, and this company's source list is empty: there is no review corpus to search. ${NO_CORPUS_EXIT}`];\n }\n return [\n `${lead}. ${sourceCount} review source${sourceCount === 1 ? \" is\" : \"s are\"} connected but no testimonials ` +\n \"have landed yet — so this is a timing or ingestion gap, not a missing connection, and re-querying will not \" +\n `change it. Ingestion may still be running: say so rather than reporting the client has no reviews. ${NO_CORPUS_EXIT}`,\n ];\n}\n"],"mappings":";;;;;AA0CO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,GAA2C;AACzC,MAAI,cAAc,GAAG;AACnB,WAAO;AAAA,EACT;AAIA,MAAI,cAAc,SAAS,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,SAAO,gBAAgB,IAAI,wBAAwB;AACrD;AAEA,IAAM,iBACJ;AAaK,SAAS,kBAAkB,QAA2B,aAAqB,eAAiC;AACjH,MAAI,WAAW,gBAAgB;AAC7B,WAAO,wBAAwB,cAAc,KAAK,IAAI,CAAC;AAAA,EACzD;AACA,MAAI,WAAW,uBAAuB;AACpC,WAAO;AAAA,EACT;AACA,SAAO,GAAG,WAAW,iBAAiB,gBAAgB,IAAI,QAAQ,OAAO;AAC3E;AAYO,SAAS,cAAc,aAAqB,QAAwB;AACzE,QAAM,QAAQ,gBAAgB,IAAI,8BAA8B,kBAAkB,WAAW;AAC7F,SACE,GAAG,KAAK,0OAE8B,MAAM;AAGhD;AAGA,SAAS,cAAc,SAAmC;AACxD,QAAM,OAAO,YAAY,WAAW,YAAY;AAChD,SACE,kDAA6C,IAAI;AAGrD;AAcA,eAAsB,mBAAmB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,YAAY;AACd,GAQwD;AAKtD,MAAI,YAAY;AACd,WAAO,EAAE,OAAO,CAAC,cAAc,aAAa,UAAU,CAAC,EAAE;AAAA,EAC3D;AACA,MAAI,cAAc,GAAG;AACnB,WAAO,EAAE,OAAO,CAAC,EAAE;AAAA,EACrB;AAOA,MAAI,WAAW;AACb,WAAO,EAAE,OAAO,CAAC,cAAc,OAAO,CAAC,EAAE;AAAA,EAC3C;AACA,MAAI,cAAc,SAAS,GAAG;AAE5B,UAAMA,UAAS;AACf,WAAO;AAAA,MACL,OAAO,iBAAiB,EAAE,SAAS,QAAAA,SAAQ,aAAa,GAAG,cAAc,CAAC;AAAA,MAC1E,OAAO,EAAE,QAAAA,SAAQ,QAAQ,kBAAkBA,SAAQ,GAAG,aAAa,EAAE;AAAA,IACvE;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,UAAU,MAAM,OAAkB,2BAA2B;AACnE,kBAAc,MAAM,QAAQ,OAAO,IAAI,QAAQ,SAAS;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,MACL,OAAO;AAAA,QACL;AAAA,MAGF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,mBAAmB,EAAE,aAAa,eAAe,YAAY,CAAC;AAC7E,MAAI,WAAW,MAAM;AACnB,WAAO,EAAE,OAAO,CAAC,EAAE;AAAA,EACrB;AACA,SAAO;AAAA,IACL,OAAO,iBAAiB,EAAE,SAAS,QAAQ,aAAa,cAAc,CAAC;AAAA,IACvE,OAAO,EAAE,QAAQ,QAAQ,kBAAkB,QAAQ,aAAa,aAAa,EAAE;AAAA,EACjF;AACF;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKa;AACX,MAAI,WAAW,MAAM;AACnB,WAAO,CAAC;AAAA,EACV;AACA,MAAI,WAAW,gBAAgB;AAC7B,WAAO;AAAA,MACL,kBAAa,cAAc,KAAK,IAAI,CAAC;AAAA,IAEvC;AAAA,EACF;AACA,QAAM,OAAO,YAAY,WAAW,YAAY;AAChD,MAAI,WAAW,uBAAuB;AAGpC,WAAO,CAAC,GAAG,IAAI,mFAAmF,cAAc,EAAE;AAAA,EACpH;AACA,SAAO;AAAA,IACL,GAAG,IAAI,KAAK,WAAW,iBAAiB,gBAAgB,IAAI,QAAQ,OAAO,qPAE6B,cAAc;AAAA,EACxH;AACF;","names":["reason"]}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// src/commands/ads/field-descriptions.ts
|
|
2
|
+
var FIELD_DESCRIPTIONS = {
|
|
3
|
+
// Customer
|
|
4
|
+
"customer.id": "Google Ads account ID",
|
|
5
|
+
"customer.descriptive_name": "Account display name",
|
|
6
|
+
"customer.currency_code": "Account currency (e.g. USD, EUR)",
|
|
7
|
+
"customer.time_zone": "Account timezone (e.g. America/New_York)",
|
|
8
|
+
// Campaign
|
|
9
|
+
"campaign.id": "Unique campaign identifier",
|
|
10
|
+
"campaign.name": "Campaign display name",
|
|
11
|
+
"campaign.status": "ENABLED, PAUSED, or REMOVED",
|
|
12
|
+
"campaign.advertising_channel_type": "Campaign type: SEARCH, DISPLAY, SHOPPING, VIDEO, PERFORMANCE_MAX, DEMAND_GEN",
|
|
13
|
+
"campaign.bidding_strategy_type": "Bidding strategy (TARGET_CPA, TARGET_ROAS, MAXIMIZE_CONVERSIONS, etc.)",
|
|
14
|
+
"campaign.primary_status": "Whether the campaign can serve: ELIGIBLE, PAUSED, REMOVED, ENDED, PENDING, MISCONFIGURED, LIMITED, LEARNING, NOT_ELIGIBLE. Unlike the keyword equivalent, LIMITED is a real value here \u2014 but Google publishes no reason-to-status mapping, so decide 'Limited by budget' from primary_status_reasons, not from this field.",
|
|
15
|
+
"campaign.primary_status_reasons": "Why the campaign is limited or not serving (repeated field \u2014 an array). BUDGET_CONSTRAINED is 'Limited by budget'; BUDGET_MISCONFIGURED is a broken budget setting, not a cap. Since 17 Aug 2026 a budget-limited campaign on a target-based strategy delivers toward its target instead of toward its recent actual cost, so BUDGET_CONSTRAINED is the flag that says a target above actual now costs money. BIDDING_STRATEGY_LEARNING means the bidding system is still adjusting to a change.",
|
|
16
|
+
"campaign.target_cpa.target_cpa_micros": "Target CPA in micros on a standalone Target CPA strategy",
|
|
17
|
+
"campaign.maximize_conversions.target_cpa_micros": "Target CPA in micros when the target is held inside a Maximize Conversions strategy \u2014 the shape Google uses on Search",
|
|
18
|
+
"campaign.target_roas.target_roas": "Target ROAS as a ratio (2.5 = 250%) on a standalone Target ROAS strategy",
|
|
19
|
+
"campaign.maximize_conversion_value.target_roas": "Target ROAS as a ratio when held inside a Maximize Conversion Value strategy",
|
|
20
|
+
"campaign.target_cpc.target_cpc_micros": "Target CPC in micros on a Demand Gen Target CPC strategy. Governed by the same August 2026 change as Target CPA/ROAS: on a budget-limited campaign it is what delivery moves toward, not a ceiling.",
|
|
21
|
+
"ad_group.target_cpc_micros": "Ad-group override of the campaign's Demand Gen target CPC, in micros",
|
|
22
|
+
"campaign.start_date": "Campaign start date (YYYY-MM-DD)",
|
|
23
|
+
"campaign.end_date": "Campaign end date (YYYY-MM-DD), blank if ongoing",
|
|
24
|
+
// Campaign budget
|
|
25
|
+
"campaign_budget.amount_micros": "Daily budget in micros (\xF7 1,000,000 for actual currency)",
|
|
26
|
+
// Ad group
|
|
27
|
+
"ad_group.id": "Unique ad group identifier",
|
|
28
|
+
"ad_group.name": "Ad group display name",
|
|
29
|
+
"ad_group.status": "ENABLED, PAUSED, or REMOVED",
|
|
30
|
+
"ad_group.type": "Ad group type (SEARCH_STANDARD, DISPLAY_STANDARD, etc.)",
|
|
31
|
+
// Ad group ad
|
|
32
|
+
"ad_group_ad.ad.id": "Unique ad identifier",
|
|
33
|
+
"ad_group_ad.ad.final_urls": "Landing page URLs (array)",
|
|
34
|
+
"ad_group_ad.ad.type": "Ad format (RESPONSIVE_SEARCH_AD, etc.)",
|
|
35
|
+
"ad_group_ad.status": "ENABLED, PAUSED, or REMOVED",
|
|
36
|
+
"ad_group_ad.ad.responsive_search_ad.headlines": "Ad headline variations (array)",
|
|
37
|
+
"ad_group_ad.ad.responsive_search_ad.descriptions": "Ad description variations (array)",
|
|
38
|
+
// Keywords
|
|
39
|
+
"ad_group_criterion.criterion_id": "Keyword criterion id \u2014 derived from text + match type, so every copy of the same keyword across ad groups shares it. Pair with ad_group.id to identify one copy (writes take customers/<cid>/adGroupCriteria/<adGroupId>~<criterionId>)",
|
|
40
|
+
"ad_group_criterion.keyword.text": "The keyword text",
|
|
41
|
+
"ad_group_criterion.keyword.match_type": "EXACT, PHRASE, or BROAD",
|
|
42
|
+
"ad_group_criterion.status": "ENABLED, PAUSED, or REMOVED",
|
|
43
|
+
"ad_group_criterion.quality_info.quality_score": "Quality score 1-10 (higher is better)",
|
|
44
|
+
"ad_group_criterion.quality_info.creative_quality_score": "Ad relevance bucket: ABOVE_AVERAGE, AVERAGE, BELOW_AVERAGE",
|
|
45
|
+
"ad_group_criterion.quality_info.post_click_quality_score": "Landing page experience bucket: ABOVE_AVERAGE, AVERAGE, BELOW_AVERAGE",
|
|
46
|
+
"ad_group_criterion.quality_info.search_predicted_ctr": "Expected click-through rate bucket: ABOVE_AVERAGE, AVERAGE, BELOW_AVERAGE",
|
|
47
|
+
"ad_group_criterion.primary_status": "Whether the keyword can serve: ELIGIBLE, PAUSED, REMOVED, PENDING, NOT_ELIGIBLE. There is no LIMITED value \u2014 Google Ads' 'Eligible (Limited)' is ELIGIBLE plus a limiting entry in primary_status_reasons, so read both.",
|
|
48
|
+
"ad_group_criterion.primary_status_reasons": "Why the keyword is in that status (array). AD_GROUP_CRITERION_BELOW_FIRST_PAGE_BID and AD_GROUP_CRITERION_LOW_QUALITY are the two that render as '(Limited)'; the CAMPAIGN_*/AD_GROUP_* entries just restate a paused or removed parent.",
|
|
49
|
+
"ad_group_criterion.system_serving_status": "ELIGIBLE or RARELY_SERVED (too few searches to show)",
|
|
50
|
+
"ad_group_criterion.approval_status": "Ad-approval state: APPROVED, DISAPPROVED, PENDING_REVIEW, UNDER_REVIEW",
|
|
51
|
+
"ad_group_criterion.disapproval_reasons": "Policy reasons the keyword was disapproved (array)",
|
|
52
|
+
"ad_group_criterion.cpc_bid_micros": "Max CPC bid set on this keyword, in micros (\xF7 1,000,000)",
|
|
53
|
+
"ad_group_criterion.effective_cpc_bid_micros": "Max CPC actually in force, in micros (\xF7 1,000,000) \u2014 the keyword's own bid, or the ad group's when the keyword has none",
|
|
54
|
+
"ad_group_criterion.effective_cpc_bid_source": "Where the effective max CPC comes from: ADGROUP, CRITERION, or CAMPAIGN_BIDDING_STRATEGY",
|
|
55
|
+
"ad_group_criterion.position_estimates.first_page_cpc_micros": "Bid estimated to reach the first page of results, in micros (\xF7 1,000,000). The number in Google Ads' 'Below first page bid (\u20AC3.63)' label \u2014 compare it against effective_cpc_bid_micros.",
|
|
56
|
+
"ad_group_criterion.position_estimates.top_of_page_cpc_micros": "Bid estimated to reach the top of the first page, in micros (\xF7 1,000,000)",
|
|
57
|
+
"ad_group_criterion.position_estimates.first_position_cpc_micros": "Bid estimated to reach the first ad position, in micros (\xF7 1,000,000)",
|
|
58
|
+
// Search terms
|
|
59
|
+
"search_term_view.search_term": "Actual user search query that triggered the ad",
|
|
60
|
+
"search_term_view.status": "Whether the search term is added, excluded, or none",
|
|
61
|
+
// Metrics
|
|
62
|
+
"metrics.impressions": "Times ads were shown (integer)",
|
|
63
|
+
"metrics.clicks": "Total clicks (integer)",
|
|
64
|
+
"metrics.cost_micros": "Total cost in micros (\xF7 1,000,000 for actual currency). Use 'currency' command for account currency.",
|
|
65
|
+
"metrics.cost": "Total cost in actual currency (already converted from micros)",
|
|
66
|
+
"metrics.conversions": "Conversion count (can be fractional from attribution models)",
|
|
67
|
+
"metrics.conversions_value": "Revenue from conversions in actual currency",
|
|
68
|
+
"metrics.all_conversions": "All conversions including view-through",
|
|
69
|
+
"metrics.all_conversions_value": "Total attributed revenue including view-through",
|
|
70
|
+
"metrics.ctr": "Click-through rate as decimal (0.05 = 5%)",
|
|
71
|
+
"metrics.average_cpc": "Average cost per click in micros (\xF7 1,000,000)",
|
|
72
|
+
"metrics.average_cpm": "Average cost per 1000 impressions in micros (\xF7 1,000,000)",
|
|
73
|
+
"metrics.search_impression_share": "Impression share as decimal (0.0\u20131.0)",
|
|
74
|
+
"metrics.search_budget_lost_impression_share": "Share of impressions lost because the budget ran out, as a decimal (0.0\u20131.0). The corroborating signal for a 'Limited by budget' campaign \u2014 a high value here alongside a target above actual cost per conversion is the combination that now raises spend.",
|
|
75
|
+
"metrics.cost_per_conversion": "Actual cost per conversion in micros (\xF7 1,000,000) \u2014 compare against the campaign's target",
|
|
76
|
+
"metrics.interaction_rate": "Interaction rate as decimal",
|
|
77
|
+
"metrics.video_views": "Total video views (integer)",
|
|
78
|
+
"metrics.video_view_rate": "Video view rate as decimal",
|
|
79
|
+
// Segments
|
|
80
|
+
"segments.date": "Date (YYYY-MM-DD format)",
|
|
81
|
+
"segments.device": "DESKTOP, MOBILE, TABLET, or OTHER",
|
|
82
|
+
"segments.day_of_week": "Day of week (MONDAY, TUESDAY, etc.)",
|
|
83
|
+
"segments.ad_network_type": "Network: SEARCH, SEARCH_PARTNERS, CONTENT, YOUTUBE_SEARCH, etc.",
|
|
84
|
+
"segments.product_title": "Shopping product title",
|
|
85
|
+
"segments.product_item_id": "Shopping product ID",
|
|
86
|
+
"segments.product_brand": "Shopping product brand",
|
|
87
|
+
"segments.product_type_l1": "Shopping product type (level 1)",
|
|
88
|
+
// Assets
|
|
89
|
+
"asset.type": "Asset type: IMAGE, YOUTUBE_VIDEO, TEXT, LEAD_FORM, etc.",
|
|
90
|
+
"asset.text_asset.text": "Text asset content",
|
|
91
|
+
"asset.image_asset.full_size.url": "Full-size image URL",
|
|
92
|
+
"asset.youtube_video_asset.youtube_video_id": "YouTube video ID",
|
|
93
|
+
"asset.youtube_video_asset.youtube_video_title": "YouTube video title",
|
|
94
|
+
"asset_group.name": "Asset group display name",
|
|
95
|
+
"asset_group.status": "ENABLED, PAUSED, or REMOVED",
|
|
96
|
+
"asset_group_asset.field_type": "Where the asset is used (HEADLINE, DESCRIPTION, LOGO, etc.)",
|
|
97
|
+
"asset_group_asset.primary_status": "Whether the asset serves: ELIGIBLE, LIMITED, NOT_ELIGIBLE, PAUSED, REMOVED, PENDING",
|
|
98
|
+
"asset_group_asset.primary_status_reasons": "Why the asset is not fully serving (policy, pending review, paused parent \u2026)",
|
|
99
|
+
// Change events (field-level detail, last 30 days)
|
|
100
|
+
"change_event.change_date_time": "When the change occurred (ISO 8601)",
|
|
101
|
+
"change_event.change_resource_type": "What was changed: CAMPAIGN, AD_GROUP, AD, etc.",
|
|
102
|
+
"change_event.resource_change_operation": "CREATE, UPDATE, or REMOVE",
|
|
103
|
+
"change_event.user_email": "Email of user who made the change",
|
|
104
|
+
// Change status (which resources changed, last 90 days — no values, no user)
|
|
105
|
+
"change_status.last_change_date_time": "When this resource last changed (ISO 8601)",
|
|
106
|
+
"change_status.resource_type": "What changed: CAMPAIGN, AD_GROUP, AD_GROUP_AD, AD_GROUP_CRITERION, etc.",
|
|
107
|
+
"change_status.resource_status": "ADDED, CHANGED, or REMOVED \u2014 not the old or new value",
|
|
108
|
+
"change_status.resource_name": "Identifier of the changed resource; query it to read its current values",
|
|
109
|
+
"change_status.campaign": "Resource name of the campaign the change belongs to",
|
|
110
|
+
"change_status.ad_group": "Resource name of the ad group the change belongs to",
|
|
111
|
+
"change_status.ad_group_ad": "Resource name of the changed ad",
|
|
112
|
+
"change_status.ad_group_criterion": "Resource name of the changed keyword or criterion",
|
|
113
|
+
"change_status.campaign_criterion": "Resource name of the changed campaign-level criterion",
|
|
114
|
+
// Landing pages
|
|
115
|
+
"landing_page_view.unexpanded_final_url": "Landing page URL",
|
|
116
|
+
// Geo
|
|
117
|
+
"geo_target_constant.name": "Geographic location name",
|
|
118
|
+
"geo_target_constant.resource_name": "Geo target resource identifier"
|
|
119
|
+
};
|
|
120
|
+
function getFieldDescriptions(fields) {
|
|
121
|
+
const result = {};
|
|
122
|
+
for (const field of fields) {
|
|
123
|
+
const desc = FIELD_DESCRIPTIONS[field];
|
|
124
|
+
if (desc) {
|
|
125
|
+
result[field] = desc;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export {
|
|
132
|
+
getFieldDescriptions
|
|
133
|
+
};
|
|
134
|
+
//# sourceMappingURL=chunk-JPK34QPS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/ads/field-descriptions.ts"],"sourcesContent":["const FIELD_DESCRIPTIONS: Record<string, string> = {\n // Customer\n \"customer.id\": \"Google Ads account ID\",\n \"customer.descriptive_name\": \"Account display name\",\n \"customer.currency_code\": \"Account currency (e.g. USD, EUR)\",\n \"customer.time_zone\": \"Account timezone (e.g. America/New_York)\",\n\n // Campaign\n \"campaign.id\": \"Unique campaign identifier\",\n \"campaign.name\": \"Campaign display name\",\n \"campaign.status\": \"ENABLED, PAUSED, or REMOVED\",\n \"campaign.advertising_channel_type\": \"Campaign type: SEARCH, DISPLAY, SHOPPING, VIDEO, PERFORMANCE_MAX, DEMAND_GEN\",\n \"campaign.bidding_strategy_type\": \"Bidding strategy (TARGET_CPA, TARGET_ROAS, MAXIMIZE_CONVERSIONS, etc.)\",\n \"campaign.primary_status\":\n \"Whether the campaign can serve: ELIGIBLE, PAUSED, REMOVED, ENDED, PENDING, MISCONFIGURED, LIMITED, LEARNING, NOT_ELIGIBLE. Unlike the keyword equivalent, LIMITED is a real value here — but Google publishes no reason-to-status mapping, so decide 'Limited by budget' from primary_status_reasons, not from this field.\",\n \"campaign.primary_status_reasons\":\n \"Why the campaign is limited or not serving (repeated field — an array). BUDGET_CONSTRAINED is 'Limited by budget'; BUDGET_MISCONFIGURED is a broken budget setting, not a cap. Since 17 Aug 2026 a budget-limited campaign on a target-based strategy delivers toward its target instead of toward its recent actual cost, so BUDGET_CONSTRAINED is the flag that says a target above actual now costs money. BIDDING_STRATEGY_LEARNING means the bidding system is still adjusting to a change.\",\n \"campaign.target_cpa.target_cpa_micros\": \"Target CPA in micros on a standalone Target CPA strategy\",\n \"campaign.maximize_conversions.target_cpa_micros\":\n \"Target CPA in micros when the target is held inside a Maximize Conversions strategy — the shape Google uses on Search\",\n \"campaign.target_roas.target_roas\": \"Target ROAS as a ratio (2.5 = 250%) on a standalone Target ROAS strategy\",\n \"campaign.maximize_conversion_value.target_roas\":\n \"Target ROAS as a ratio when held inside a Maximize Conversion Value strategy\",\n \"campaign.target_cpc.target_cpc_micros\":\n \"Target CPC in micros on a Demand Gen Target CPC strategy. Governed by the same August 2026 change as Target CPA/ROAS: on a budget-limited campaign it is what delivery moves toward, not a ceiling.\",\n \"ad_group.target_cpc_micros\": \"Ad-group override of the campaign's Demand Gen target CPC, in micros\",\n \"campaign.start_date\": \"Campaign start date (YYYY-MM-DD)\",\n \"campaign.end_date\": \"Campaign end date (YYYY-MM-DD), blank if ongoing\",\n\n // Campaign budget\n \"campaign_budget.amount_micros\": \"Daily budget in micros (÷ 1,000,000 for actual currency)\",\n\n // Ad group\n \"ad_group.id\": \"Unique ad group identifier\",\n \"ad_group.name\": \"Ad group display name\",\n \"ad_group.status\": \"ENABLED, PAUSED, or REMOVED\",\n \"ad_group.type\": \"Ad group type (SEARCH_STANDARD, DISPLAY_STANDARD, etc.)\",\n\n // Ad group ad\n \"ad_group_ad.ad.id\": \"Unique ad identifier\",\n \"ad_group_ad.ad.final_urls\": \"Landing page URLs (array)\",\n \"ad_group_ad.ad.type\": \"Ad format (RESPONSIVE_SEARCH_AD, etc.)\",\n \"ad_group_ad.status\": \"ENABLED, PAUSED, or REMOVED\",\n \"ad_group_ad.ad.responsive_search_ad.headlines\": \"Ad headline variations (array)\",\n \"ad_group_ad.ad.responsive_search_ad.descriptions\": \"Ad description variations (array)\",\n\n // Keywords\n \"ad_group_criterion.criterion_id\":\n \"Keyword criterion id — derived from text + match type, so every copy of the same keyword across ad groups shares it. Pair with ad_group.id to identify one copy (writes take customers/<cid>/adGroupCriteria/<adGroupId>~<criterionId>)\",\n \"ad_group_criterion.keyword.text\": \"The keyword text\",\n \"ad_group_criterion.keyword.match_type\": \"EXACT, PHRASE, or BROAD\",\n \"ad_group_criterion.status\": \"ENABLED, PAUSED, or REMOVED\",\n \"ad_group_criterion.quality_info.quality_score\": \"Quality score 1-10 (higher is better)\",\n \"ad_group_criterion.quality_info.creative_quality_score\":\n \"Ad relevance bucket: ABOVE_AVERAGE, AVERAGE, BELOW_AVERAGE\",\n \"ad_group_criterion.quality_info.post_click_quality_score\":\n \"Landing page experience bucket: ABOVE_AVERAGE, AVERAGE, BELOW_AVERAGE\",\n \"ad_group_criterion.quality_info.search_predicted_ctr\":\n \"Expected click-through rate bucket: ABOVE_AVERAGE, AVERAGE, BELOW_AVERAGE\",\n \"ad_group_criterion.primary_status\":\n \"Whether the keyword can serve: ELIGIBLE, PAUSED, REMOVED, PENDING, NOT_ELIGIBLE. There is no LIMITED value — Google Ads' 'Eligible (Limited)' is ELIGIBLE plus a limiting entry in primary_status_reasons, so read both.\",\n \"ad_group_criterion.primary_status_reasons\":\n \"Why the keyword is in that status (array). AD_GROUP_CRITERION_BELOW_FIRST_PAGE_BID and AD_GROUP_CRITERION_LOW_QUALITY are the two that render as '(Limited)'; the CAMPAIGN_*/AD_GROUP_* entries just restate a paused or removed parent.\",\n \"ad_group_criterion.system_serving_status\": \"ELIGIBLE or RARELY_SERVED (too few searches to show)\",\n \"ad_group_criterion.approval_status\": \"Ad-approval state: APPROVED, DISAPPROVED, PENDING_REVIEW, UNDER_REVIEW\",\n \"ad_group_criterion.disapproval_reasons\": \"Policy reasons the keyword was disapproved (array)\",\n \"ad_group_criterion.cpc_bid_micros\": \"Max CPC bid set on this keyword, in micros (÷ 1,000,000)\",\n \"ad_group_criterion.effective_cpc_bid_micros\":\n \"Max CPC actually in force, in micros (÷ 1,000,000) — the keyword's own bid, or the ad group's when the keyword has none\",\n \"ad_group_criterion.effective_cpc_bid_source\":\n \"Where the effective max CPC comes from: ADGROUP, CRITERION, or CAMPAIGN_BIDDING_STRATEGY\",\n \"ad_group_criterion.position_estimates.first_page_cpc_micros\":\n \"Bid estimated to reach the first page of results, in micros (÷ 1,000,000). The number in Google Ads' 'Below first page bid (€3.63)' label — compare it against effective_cpc_bid_micros.\",\n \"ad_group_criterion.position_estimates.top_of_page_cpc_micros\":\n \"Bid estimated to reach the top of the first page, in micros (÷ 1,000,000)\",\n \"ad_group_criterion.position_estimates.first_position_cpc_micros\":\n \"Bid estimated to reach the first ad position, in micros (÷ 1,000,000)\",\n\n // Search terms\n \"search_term_view.search_term\": \"Actual user search query that triggered the ad\",\n \"search_term_view.status\": \"Whether the search term is added, excluded, or none\",\n\n // Metrics\n \"metrics.impressions\": \"Times ads were shown (integer)\",\n \"metrics.clicks\": \"Total clicks (integer)\",\n \"metrics.cost_micros\":\n \"Total cost in micros (÷ 1,000,000 for actual currency). Use 'currency' command for account currency.\",\n \"metrics.cost\": \"Total cost in actual currency (already converted from micros)\",\n \"metrics.conversions\": \"Conversion count (can be fractional from attribution models)\",\n \"metrics.conversions_value\": \"Revenue from conversions in actual currency\",\n \"metrics.all_conversions\": \"All conversions including view-through\",\n \"metrics.all_conversions_value\": \"Total attributed revenue including view-through\",\n \"metrics.ctr\": \"Click-through rate as decimal (0.05 = 5%)\",\n \"metrics.average_cpc\": \"Average cost per click in micros (÷ 1,000,000)\",\n \"metrics.average_cpm\": \"Average cost per 1000 impressions in micros (÷ 1,000,000)\",\n \"metrics.search_impression_share\": \"Impression share as decimal (0.0–1.0)\",\n \"metrics.search_budget_lost_impression_share\":\n \"Share of impressions lost because the budget ran out, as a decimal (0.0–1.0). The corroborating signal for a 'Limited by budget' campaign — a high value here alongside a target above actual cost per conversion is the combination that now raises spend.\",\n \"metrics.cost_per_conversion\":\n \"Actual cost per conversion in micros (÷ 1,000,000) — compare against the campaign's target\",\n \"metrics.interaction_rate\": \"Interaction rate as decimal\",\n \"metrics.video_views\": \"Total video views (integer)\",\n \"metrics.video_view_rate\": \"Video view rate as decimal\",\n\n // Segments\n \"segments.date\": \"Date (YYYY-MM-DD format)\",\n \"segments.device\": \"DESKTOP, MOBILE, TABLET, or OTHER\",\n \"segments.day_of_week\": \"Day of week (MONDAY, TUESDAY, etc.)\",\n \"segments.ad_network_type\": \"Network: SEARCH, SEARCH_PARTNERS, CONTENT, YOUTUBE_SEARCH, etc.\",\n \"segments.product_title\": \"Shopping product title\",\n \"segments.product_item_id\": \"Shopping product ID\",\n \"segments.product_brand\": \"Shopping product brand\",\n \"segments.product_type_l1\": \"Shopping product type (level 1)\",\n\n // Assets\n \"asset.type\": \"Asset type: IMAGE, YOUTUBE_VIDEO, TEXT, LEAD_FORM, etc.\",\n \"asset.text_asset.text\": \"Text asset content\",\n \"asset.image_asset.full_size.url\": \"Full-size image URL\",\n \"asset.youtube_video_asset.youtube_video_id\": \"YouTube video ID\",\n \"asset.youtube_video_asset.youtube_video_title\": \"YouTube video title\",\n \"asset_group.name\": \"Asset group display name\",\n \"asset_group.status\": \"ENABLED, PAUSED, or REMOVED\",\n \"asset_group_asset.field_type\": \"Where the asset is used (HEADLINE, DESCRIPTION, LOGO, etc.)\",\n \"asset_group_asset.primary_status\":\n \"Whether the asset serves: ELIGIBLE, LIMITED, NOT_ELIGIBLE, PAUSED, REMOVED, PENDING\",\n \"asset_group_asset.primary_status_reasons\":\n \"Why the asset is not fully serving (policy, pending review, paused parent …)\",\n\n // Change events (field-level detail, last 30 days)\n \"change_event.change_date_time\": \"When the change occurred (ISO 8601)\",\n \"change_event.change_resource_type\": \"What was changed: CAMPAIGN, AD_GROUP, AD, etc.\",\n \"change_event.resource_change_operation\": \"CREATE, UPDATE, or REMOVE\",\n \"change_event.user_email\": \"Email of user who made the change\",\n\n // Change status (which resources changed, last 90 days — no values, no user)\n \"change_status.last_change_date_time\": \"When this resource last changed (ISO 8601)\",\n \"change_status.resource_type\": \"What changed: CAMPAIGN, AD_GROUP, AD_GROUP_AD, AD_GROUP_CRITERION, etc.\",\n \"change_status.resource_status\": \"ADDED, CHANGED, or REMOVED — not the old or new value\",\n \"change_status.resource_name\": \"Identifier of the changed resource; query it to read its current values\",\n \"change_status.campaign\": \"Resource name of the campaign the change belongs to\",\n \"change_status.ad_group\": \"Resource name of the ad group the change belongs to\",\n \"change_status.ad_group_ad\": \"Resource name of the changed ad\",\n \"change_status.ad_group_criterion\": \"Resource name of the changed keyword or criterion\",\n \"change_status.campaign_criterion\": \"Resource name of the changed campaign-level criterion\",\n\n // Landing pages\n \"landing_page_view.unexpanded_final_url\": \"Landing page URL\",\n\n // Geo\n \"geo_target_constant.name\": \"Geographic location name\",\n \"geo_target_constant.resource_name\": \"Geo target resource identifier\",\n};\n\nexport function getFieldDescriptions(fields: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n for (const field of fields) {\n const desc = FIELD_DESCRIPTIONS[field];\n if (desc) {\n result[field] = desc;\n }\n }\n return result;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import {
|
|
2
|
+
analyticsErrorEnvelope
|
|
3
|
+
} from "./chunk-AFJGYJ7Z.js";
|
|
4
|
+
import {
|
|
5
|
+
PEOPLE_SEARCH_MAX_TERMS,
|
|
6
|
+
parsePeopleQuery,
|
|
7
|
+
peopleLookupRequestSchema
|
|
8
|
+
} from "./chunk-FYWWTMXP.js";
|
|
9
|
+
import {
|
|
10
|
+
writeJsonEnvelope
|
|
11
|
+
} from "./chunk-BVM5IRZW.js";
|
|
12
|
+
import {
|
|
13
|
+
apiPost
|
|
14
|
+
} from "./chunk-HREWXNTO.js";
|
|
15
|
+
import {
|
|
16
|
+
registerSchema
|
|
17
|
+
} from "./chunk-WOTDHRNF.js";
|
|
18
|
+
|
|
19
|
+
// src/commands/analytics/lookup.ts
|
|
20
|
+
import { readFileSync } from "fs";
|
|
21
|
+
import { defineCommand } from "citty";
|
|
22
|
+
function peopleArgs(args2) {
|
|
23
|
+
const parts = peopleParts(args2);
|
|
24
|
+
if (parts.length === 0) return {};
|
|
25
|
+
const people = parsePeopleQuery(parts).terms.map((term) => term.input);
|
|
26
|
+
return people.length === 0 ? {} : { people };
|
|
27
|
+
}
|
|
28
|
+
function peopleParts(args2) {
|
|
29
|
+
return [...args2.person ? [String(args2.person)] : [], ...args2["people-file"] ? [readPeopleFile(args2)] : []];
|
|
30
|
+
}
|
|
31
|
+
function readPeopleFile(args2) {
|
|
32
|
+
try {
|
|
33
|
+
return readFileSync(String(args2["people-file"]), "utf8");
|
|
34
|
+
} catch {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function unreadablePeopleFile(args2) {
|
|
39
|
+
if (!args2["people-file"]) return void 0;
|
|
40
|
+
const path = String(args2["people-file"]);
|
|
41
|
+
try {
|
|
42
|
+
readFileSync(path, "utf8");
|
|
43
|
+
return void 0;
|
|
44
|
+
} catch {
|
|
45
|
+
return `Couldn't read --people-file ${path}. Check the path, or pass the people inline with --person.`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function peopleLimitError(args2) {
|
|
49
|
+
const unreadable = unreadablePeopleFile(args2);
|
|
50
|
+
if (unreadable !== void 0) return unreadable;
|
|
51
|
+
const { terms, dropped } = parsePeopleQuery(peopleParts(args2));
|
|
52
|
+
if (dropped === 0) return void 0;
|
|
53
|
+
return `${terms.length + dropped} people named; one search takes up to ${PEOPLE_SEARCH_MAX_TERMS}. Split the list and run each part.`;
|
|
54
|
+
}
|
|
55
|
+
function compactRow(row) {
|
|
56
|
+
const clicks = [...row.googleClick ? ["google"] : [], ...row.metaClick ? ["meta"] : []];
|
|
57
|
+
const candidates = {
|
|
58
|
+
input: row.input,
|
|
59
|
+
readAs: row.kind,
|
|
60
|
+
found: row.found,
|
|
61
|
+
problem: row.problem,
|
|
62
|
+
contacts: row.contacts,
|
|
63
|
+
events: row.events,
|
|
64
|
+
firstSeen: row.firstSeen,
|
|
65
|
+
lastSeen: row.lastSeen,
|
|
66
|
+
pageViews: row.pageViews,
|
|
67
|
+
landings: row.landings,
|
|
68
|
+
visits: row.visits,
|
|
69
|
+
formSubmits: row.formSubmits,
|
|
70
|
+
firstSource: row.firstSource,
|
|
71
|
+
systemEvents: row.systemEvents,
|
|
72
|
+
pageEvents: row.pageEvents,
|
|
73
|
+
uploads: row.uploads,
|
|
74
|
+
uploadedTo: row.uploadedTo,
|
|
75
|
+
clicks,
|
|
76
|
+
knownBy: row.knownBy
|
|
77
|
+
};
|
|
78
|
+
return Object.fromEntries(
|
|
79
|
+
Object.entries(candidates).filter(
|
|
80
|
+
([key, value]) => key === "found" || !(value === 0 || value === "" || Array.isArray(value) && value.length === 0)
|
|
81
|
+
)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
function lookupHints(data) {
|
|
85
|
+
const hints = [];
|
|
86
|
+
if (data.dropped > 0) {
|
|
87
|
+
hints.push(
|
|
88
|
+
`${data.dropped} lines past the limit of ${PEOPLE_SEARCH_MAX_TERMS} were not looked up. Run the rest separately.`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const unseen = data.people.filter((row) => !row.found && row.problem === "");
|
|
92
|
+
if (unseen.length > 0) {
|
|
93
|
+
hints.push(
|
|
94
|
+
`Not seen by Baker: ${unseen.map((row) => row.input).join(", ")}. Baker knows a person by what its pages, Forms and connected systems recorded \u2014 a lead that came in through a form or site Baker does not measure, or a source not connected, is not here.`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
for (const row of data.people.filter((person) => person.problem !== "")) {
|
|
98
|
+
hints.push(`${row.input}: ${row.problem}`);
|
|
99
|
+
}
|
|
100
|
+
const found = data.people.filter((row) => row.found);
|
|
101
|
+
const neverVisited = found.filter((row) => row.pageViews === 0);
|
|
102
|
+
if (neverVisited.length > 0) {
|
|
103
|
+
hints.push(
|
|
104
|
+
`${neverVisited.length} of ${found.length} found never visited a page Baker publishes: Baker knows them only from what their systems reported, so no landing can be credited with them.`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (found.length > 0) {
|
|
108
|
+
hints.push(
|
|
109
|
+
`\`baker analytics feed --person '${found[0]?.input}' --days 90\` lists everything one of them did, in order \u2014 add more, comma-separated, to follow several.`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
return hints;
|
|
113
|
+
}
|
|
114
|
+
function lookupReport(data, full = false) {
|
|
115
|
+
const found = data.people.filter((row) => row.found);
|
|
116
|
+
return {
|
|
117
|
+
summary: {
|
|
118
|
+
searched: data.people.length,
|
|
119
|
+
found: found.length,
|
|
120
|
+
notFound: data.people.length - found.length,
|
|
121
|
+
visitedABakerPage: found.filter((row) => row.pageViews > 0).length
|
|
122
|
+
},
|
|
123
|
+
people: full ? data.people : data.people.map(compactRow),
|
|
124
|
+
hints: lookupHints(data)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
var NO_PEOPLE = "Name at least one person: --person 'ana@empresa.com, deal:40001234567' or --people-file leads.txt.";
|
|
128
|
+
var args = {
|
|
129
|
+
person: {
|
|
130
|
+
type: "string",
|
|
131
|
+
description: "The people, comma-separated: an email, a phone (+34\u2026), a HubSpot contact id, deal:<HubSpot deal id>, a gclid/fbclid, a browser id. Prefix to be exact: email:, phone:, hubspot:, deal:, gclid:, fbclid:, browser:",
|
|
132
|
+
required: false
|
|
133
|
+
},
|
|
134
|
+
"people-file": {
|
|
135
|
+
type: "string",
|
|
136
|
+
description: "A file with one person per line \u2014 a column pasted from a CRM export",
|
|
137
|
+
required: false
|
|
138
|
+
},
|
|
139
|
+
full: {
|
|
140
|
+
type: "boolean",
|
|
141
|
+
description: "Every field of every line, zeros included",
|
|
142
|
+
required: false
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
registerSchema({
|
|
146
|
+
command: "analytics.lookup",
|
|
147
|
+
description: "What Baker saw of each person in a list, by email, phone, CRM id, deal or click id",
|
|
148
|
+
args
|
|
149
|
+
});
|
|
150
|
+
var lookupCommand = defineCommand({
|
|
151
|
+
meta: {
|
|
152
|
+
name: "lookup",
|
|
153
|
+
description: `What Baker saw of each person in a list \u2014 all time, one line each \u2014 by whatever the client holds about them. The reconciliation question: "HubSpot says 26 leads yesterday, which of them does Baker have, and where did they come from".
|
|
154
|
+
|
|
155
|
+
Start here:
|
|
156
|
+
baker analytics lookup --person 'ana@empresa.com, +34600111222, 90001234567'
|
|
157
|
+
baker analytics lookup --person 'deal:40001234567, deal:40001234568' \u2014 HubSpot deal ids, looked up through the deal's contacts
|
|
158
|
+
baker analytics lookup --people-file leads.txt \u2014 one per line, up to ${PEOPLE_SEARCH_MAX_TERMS}
|
|
159
|
+
|
|
160
|
+
Each line says whether Baker has them, when it first and last saw them, the pages and Forms they touched, what their systems reported (systemEvents: CRM stages, orders), what Baker uploaded for them to ad platforms, which ad click they carried, and every kind of key they are linked by. A bare number is read as a HubSpot contact id or a phone; prefix it to be exact. Emails and phones are hashed by Baker \u2014 say them to the client as they gave them, never as a hash. Follow one with \`baker analytics feed --person <same value>\`.`
|
|
161
|
+
},
|
|
162
|
+
args,
|
|
163
|
+
run: async ({ args: raw }) => {
|
|
164
|
+
const { people } = peopleArgs(raw);
|
|
165
|
+
const parsed = peopleLookupRequestSchema.safeParse({ people: people ?? [] });
|
|
166
|
+
const invalid = peopleLimitError(raw) ?? (parsed.success ? void 0 : NO_PEOPLE);
|
|
167
|
+
if (invalid !== void 0 || !parsed.success) {
|
|
168
|
+
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message: invalid ?? NO_PEOPLE } });
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const response = await apiPost("/api/analytics/people", parsed.data);
|
|
173
|
+
const { hints, ...data } = lookupReport(response.data, raw.full === true);
|
|
174
|
+
writeJsonEnvelope({ ok: true, data, ...hints.length > 0 ? { hints } : {} });
|
|
175
|
+
} catch (error) {
|
|
176
|
+
writeJsonEnvelope({ ok: false, error: analyticsErrorEnvelope(error) });
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
export {
|
|
183
|
+
peopleArgs,
|
|
184
|
+
peopleLimitError,
|
|
185
|
+
lookupReport,
|
|
186
|
+
lookupCommand
|
|
187
|
+
};
|
|
188
|
+
//# sourceMappingURL=chunk-JRCFCIE3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/analytics/lookup.ts"],"sourcesContent":["/**\n * `baker analytics lookup` — what Baker saw of each person in a list.\n *\n * The question a CRM export puts to Baker: here are yesterday's leads, which\n * of them do you have and what did you see them do. One line per person, all\n * time, by whatever the reader holds — an email, a phone, a HubSpot contact or\n * deal id, a click id. The server hashes contact details and asks HubSpot whose\n * each deal is; nothing here does either.\n *\n * `baker analytics feed --person` is the same list as rows.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport {\n PEOPLE_SEARCH_MAX_TERMS,\n type PeopleLookupData,\n type PeopleLookupRow,\n parsePeopleQuery,\n peopleLookupRequestSchema,\n} from \"@baker/api/analytics\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { writeJsonEnvelope } from \"../ads/output.ts\";\nimport { analyticsErrorEnvelope } from \"./errorEnvelope.ts\";\n\n/**\n * The people `--person` and `--people-file` name, one per line of the search.\n *\n * Split here with the server's own reading of a list, so the fifty-line limit\n * is the same one on both sides and a long pasted list travels as lines, not\n * as one oversized string.\n */\nexport function peopleArgs(args: Record<string, unknown>): { people?: string[] } {\n const parts = peopleParts(args);\n if (parts.length === 0) return {};\n const people = parsePeopleQuery(parts).terms.map((term) => term.input);\n return people.length === 0 ? {} : { people };\n}\n\nfunction peopleParts(args: Record<string, unknown>): string[] {\n return [...(args.person ? [String(args.person)] : []), ...(args[\"people-file\"] ? [readPeopleFile(args)] : [])];\n}\n\n/** `--people-file`, or `\"\"` when it cannot be read — {@link peopleLimitError} is what reports that. */\nfunction readPeopleFile(args: Record<string, unknown>): string {\n try {\n return readFileSync(String(args[\"people-file\"]), \"utf8\");\n } catch {\n return \"\";\n }\n}\n\nfunction unreadablePeopleFile(args: Record<string, unknown>): string | undefined {\n if (!args[\"people-file\"]) return undefined;\n const path = String(args[\"people-file\"]);\n try {\n readFileSync(path, \"utf8\");\n return undefined;\n } catch {\n return `Couldn't read --people-file ${path}. Check the path, or pass the people inline with --person.`;\n }\n}\n\n/**\n * Why a list is refused, when it is longer than one search holds. Refused\n * rather than cut: fifty lines answered out of sixty read as the whole list,\n * and \"not seen by Baker\" is then silently wrong about the other ten.\n */\nexport function peopleLimitError(args: Record<string, unknown>): string | undefined {\n const unreadable = unreadablePeopleFile(args);\n if (unreadable !== undefined) return unreadable;\n const { terms, dropped } = parsePeopleQuery(peopleParts(args));\n if (dropped === 0) return undefined;\n return `${terms.length + dropped} people named; one search takes up to ${PEOPLE_SEARCH_MAX_TERMS}. Split the list and run each part.`;\n}\n\n/** One person as an agent reads them: what was seen, with every zero and empty list left out. */\nfunction compactRow(row: PeopleLookupRow): Record<string, unknown> {\n const clicks = [...(row.googleClick ? [\"google\"] : []), ...(row.metaClick ? [\"meta\"] : [])];\n const candidates: Record<string, unknown> = {\n input: row.input,\n readAs: row.kind,\n found: row.found,\n problem: row.problem,\n contacts: row.contacts,\n events: row.events,\n firstSeen: row.firstSeen,\n lastSeen: row.lastSeen,\n pageViews: row.pageViews,\n landings: row.landings,\n visits: row.visits,\n formSubmits: row.formSubmits,\n firstSource: row.firstSource,\n systemEvents: row.systemEvents,\n pageEvents: row.pageEvents,\n uploads: row.uploads,\n uploadedTo: row.uploadedTo,\n clicks,\n knownBy: row.knownBy,\n };\n return Object.fromEntries(\n Object.entries(candidates).filter(\n ([key, value]) =>\n key === \"found\" || !(value === 0 || value === \"\" || (Array.isArray(value) && value.length === 0)),\n ),\n );\n}\n\nfunction lookupHints(data: PeopleLookupData): string[] {\n const hints: string[] = [];\n if (data.dropped > 0) {\n hints.push(\n `${data.dropped} lines past the limit of ${PEOPLE_SEARCH_MAX_TERMS} were not looked up. Run the rest separately.`,\n );\n }\n const unseen = data.people.filter((row) => !row.found && row.problem === \"\");\n if (unseen.length > 0) {\n hints.push(\n `Not seen by Baker: ${unseen.map((row) => row.input).join(\", \")}. Baker knows a person by what its pages, Forms and connected systems recorded — a lead that came in through a form or site Baker does not measure, or a source not connected, is not here.`,\n );\n }\n for (const row of data.people.filter((person) => person.problem !== \"\")) {\n hints.push(`${row.input}: ${row.problem}`);\n }\n const found = data.people.filter((row) => row.found);\n const neverVisited = found.filter((row) => row.pageViews === 0);\n if (neverVisited.length > 0) {\n hints.push(\n `${neverVisited.length} of ${found.length} found never visited a page Baker publishes: Baker knows them only from what their systems reported, so no landing can be credited with them.`,\n );\n }\n if (found.length > 0) {\n hints.push(\n `\\`baker analytics feed --person '${found[0]?.input}' --days 90\\` lists everything one of them did, in order — add more, comma-separated, to follow several.`,\n );\n }\n return hints;\n}\n\n/** The envelope's data and hints. Pure, so what an agent reads is tested without a network. */\nexport function lookupReport(data: PeopleLookupData, full = false) {\n const found = data.people.filter((row) => row.found);\n return {\n summary: {\n searched: data.people.length,\n found: found.length,\n notFound: data.people.length - found.length,\n visitedABakerPage: found.filter((row) => row.pageViews > 0).length,\n },\n people: full ? data.people : data.people.map(compactRow),\n hints: lookupHints(data),\n };\n}\n\nconst NO_PEOPLE = \"Name at least one person: --person 'ana@empresa.com, deal:40001234567' or --people-file leads.txt.\";\n\nconst args = {\n person: {\n type: \"string\",\n description:\n \"The people, comma-separated: an email, a phone (+34…), a HubSpot contact id, deal:<HubSpot deal id>, a gclid/fbclid, a browser id. Prefix to be exact: email:, phone:, hubspot:, deal:, gclid:, fbclid:, browser:\",\n required: false,\n },\n \"people-file\": {\n type: \"string\",\n description: \"A file with one person per line — a column pasted from a CRM export\",\n required: false,\n },\n full: {\n type: \"boolean\",\n description: \"Every field of every line, zeros included\",\n required: false,\n },\n} as const;\n\nregisterSchema({\n command: \"analytics.lookup\",\n description: \"What Baker saw of each person in a list, by email, phone, CRM id, deal or click id\",\n args,\n});\n\nexport const lookupCommand = defineCommand({\n meta: {\n name: \"lookup\",\n description: `What Baker saw of each person in a list — all time, one line each — by whatever the client holds about them. The reconciliation question: \"HubSpot says 26 leads yesterday, which of them does Baker have, and where did they come from\".\n\nStart here:\n baker analytics lookup --person 'ana@empresa.com, +34600111222, 90001234567'\n baker analytics lookup --person 'deal:40001234567, deal:40001234568' — HubSpot deal ids, looked up through the deal's contacts\n baker analytics lookup --people-file leads.txt — one per line, up to ${PEOPLE_SEARCH_MAX_TERMS}\n\nEach line says whether Baker has them, when it first and last saw them, the pages and Forms they touched, what their systems reported (systemEvents: CRM stages, orders), what Baker uploaded for them to ad platforms, which ad click they carried, and every kind of key they are linked by. A bare number is read as a HubSpot contact id or a phone; prefix it to be exact. Emails and phones are hashed by Baker — say them to the client as they gave them, never as a hash. Follow one with \\`baker analytics feed --person <same value>\\`.`,\n },\n args,\n run: async ({ args: raw }) => {\n const { people } = peopleArgs(raw as Record<string, unknown>);\n const parsed = peopleLookupRequestSchema.safeParse({ people: people ?? [] });\n const invalid = peopleLimitError(raw as Record<string, unknown>) ?? (parsed.success ? undefined : NO_PEOPLE);\n if (invalid !== undefined || !parsed.success) {\n writeJsonEnvelope({ ok: false, error: { code: \"VALIDATION_ERROR\", message: invalid ?? NO_PEOPLE } });\n process.exit(1);\n }\n try {\n const response = await apiPost<{ ok: true; data: PeopleLookupData }>(\"/api/analytics/people\", parsed.data);\n const { hints, ...data } = lookupReport(response.data, raw.full === true);\n writeJsonEnvelope({ ok: true, data, ...(hints.length > 0 ? { hints } : {}) });\n } catch (error) {\n writeJsonEnvelope({ ok: false, error: analyticsErrorEnvelope(error) });\n process.exit(1);\n }\n },\n});\n"],"mappings":"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","names":["args"]}
|