@koda-sl/baker-cli 0.384.0 → 0.385.0-dev.f7ef4c7e1
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 +1102 -218
- package/canvas/tiktok-captions-composition/index.html +5 -6
- package/canvas/tiktok-captions-composition/meta.json +5 -0
- package/dist/account-4UEZAY5T.js +49 -0
- package/dist/account-4UEZAY5T.js.map +1 -0
- package/dist/account-G6QK2VXQ.js +79 -0
- package/dist/account-G6QK2VXQ.js.map +1 -0
- package/dist/account-OINZG6UP.js +80 -0
- package/dist/account-OINZG6UP.js.map +1 -0
- package/dist/account-reads-ZKKDYHK5.js +218 -0
- package/dist/account-reads-ZKKDYHK5.js.map +1 -0
- package/dist/account-writes-N4JDIDRB.js +66 -0
- package/dist/account-writes-N4JDIDRB.js.map +1 -0
- package/dist/accounts-7KRRRVLB.js +611 -0
- package/dist/accounts-7KRRRVLB.js.map +1 -0
- package/dist/accounts-AEBQFCNH.js +114 -0
- package/dist/accounts-AEBQFCNH.js.map +1 -0
- package/dist/accounts-CNTOHRQ2.js +77 -0
- package/dist/accounts-CNTOHRQ2.js.map +1 -0
- package/dist/accounts-HP4BLKK5.js +75 -0
- package/dist/accounts-HP4BLKK5.js.map +1 -0
- package/dist/accounts-Z4CLGQXJ.js +115 -0
- package/dist/accounts-Z4CLGQXJ.js.map +1 -0
- package/dist/actions-QO7VQ6UV.js +55 -0
- package/dist/actions-QO7VQ6UV.js.map +1 -0
- package/dist/active-entities-YB46ADQN.js +103 -0
- package/dist/active-entities-YB46ADQN.js.map +1 -0
- package/dist/activities-DUAIQJLN.js +74 -0
- package/dist/activities-DUAIQJLN.js.map +1 -0
- package/dist/ad-group-writes-HL3EZ3BT.js +170 -0
- package/dist/ad-group-writes-HL3EZ3BT.js.map +1 -0
- package/dist/ad-groups-FGS5JJGN.js +68 -0
- package/dist/ad-groups-FGS5JJGN.js.map +1 -0
- package/dist/ad-writes-LX4ACUHB.js +174 -0
- package/dist/ad-writes-LX4ACUHB.js.map +1 -0
- package/dist/add-5CUXNOUM.js +97 -0
- package/dist/add-5CUXNOUM.js.map +1 -0
- package/dist/add-5JBMJHNW.js +302 -0
- package/dist/add-5JBMJHNW.js.map +1 -0
- package/dist/add-E66HBIZV.js +105 -0
- package/dist/add-E66HBIZV.js.map +1 -0
- package/dist/add-O76R2SPE.js +104 -0
- package/dist/add-O76R2SPE.js.map +1 -0
- package/dist/add-accounts-YME5SCXD.js +91 -0
- package/dist/add-accounts-YME5SCXD.js.map +1 -0
- package/dist/ads-65R3WMDU.js +128 -0
- package/dist/ads-65R3WMDU.js.map +1 -0
- package/dist/ads-O63J7BDF.js +113 -0
- package/dist/ads-O63J7BDF.js.map +1 -0
- package/dist/ads-T5JWNFSA.js +40 -0
- package/dist/ads-T5JWNFSA.js.map +1 -0
- package/dist/ads-TFZ5PXKS.js +77 -0
- package/dist/ads-TFZ5PXKS.js.map +1 -0
- package/dist/adsets-Y62JOOTV.js +176 -0
- package/dist/adsets-Y62JOOTV.js.map +1 -0
- package/dist/advertisers-LJ2HKJ4W.js +125 -0
- package/dist/advertisers-LJ2HKJ4W.js.map +1 -0
- package/dist/advertisers-WJW5DK3Q.js +120 -0
- package/dist/advertisers-WJW5DK3Q.js.map +1 -0
- package/dist/analytics-HIOC3TUK.js +1976 -0
- package/dist/analytics-HIOC3TUK.js.map +1 -0
- package/dist/analytics-U2NLDV2V.js +433 -0
- package/dist/analytics-U2NLDV2V.js.map +1 -0
- package/dist/animate-E3SKQ6SI.js +480 -0
- package/dist/animate-E3SKQ6SI.js.map +1 -0
- package/dist/assign-V7EAR7VD.js +77 -0
- package/dist/assign-V7EAR7VD.js.map +1 -0
- package/dist/audience-size-GS7EDBDP.js +94 -0
- package/dist/audience-size-GS7EDBDP.js.map +1 -0
- package/dist/audiences-5A6BCWSA.js +268 -0
- package/dist/audiences-5A6BCWSA.js.map +1 -0
- package/dist/audiences-6QOCASVV.js +78 -0
- package/dist/audiences-6QOCASVV.js.map +1 -0
- package/dist/audiences-O67NGIP5.js +85 -0
- package/dist/audiences-O67NGIP5.js.map +1 -0
- package/dist/audit-HWK24VXI.js +88 -0
- package/dist/audit-HWK24VXI.js.map +1 -0
- package/dist/audit-WMZERUAA.js +151 -0
- package/dist/audit-WMZERUAA.js.map +1 -0
- package/dist/autocomplete-KQSTLQFS.js +111 -0
- package/dist/autocomplete-KQSTLQFS.js.map +1 -0
- package/dist/avatars-HAFQZD63.js +38 -0
- package/dist/avatars-HAFQZD63.js.map +1 -0
- package/dist/bid-pricing-5SORFAPE.js +99 -0
- package/dist/bid-pricing-5SORFAPE.js.map +1 -0
- package/dist/brand-EBG436YV.js +22 -0
- package/dist/brand-EBG436YV.js.map +1 -0
- package/dist/brief-AYXXPTHC.js +490 -0
- package/dist/brief-AYXXPTHC.js.map +1 -0
- package/dist/businesses-65EWTK5E.js +53 -0
- package/dist/businesses-65EWTK5E.js.map +1 -0
- package/dist/campaign-groups-U7723BBE.js +95 -0
- package/dist/campaign-groups-U7723BBE.js.map +1 -0
- package/dist/campaign-writes-CXS4KYB5.js +165 -0
- package/dist/campaign-writes-CXS4KYB5.js.map +1 -0
- package/dist/campaign-writes-M6JLF5AC.js +170 -0
- package/dist/campaign-writes-M6JLF5AC.js.map +1 -0
- package/dist/campaigns-6SM2ZSIH.js +76 -0
- package/dist/campaigns-6SM2ZSIH.js.map +1 -0
- package/dist/campaigns-7DWD2A5U.js +109 -0
- package/dist/campaigns-7DWD2A5U.js.map +1 -0
- package/dist/campaigns-F66OYA6N.js +107 -0
- package/dist/campaigns-F66OYA6N.js.map +1 -0
- package/dist/campaigns-TD7ZB5DG.js +110 -0
- package/dist/campaigns-TD7ZB5DG.js.map +1 -0
- package/dist/canvas-3NYM5Y7G.js +46 -0
- package/dist/canvas-3NYM5Y7G.js.map +1 -0
- package/dist/capabilities-JNFYSGRD.js +144 -0
- package/dist/capabilities-JNFYSGRD.js.map +1 -0
- package/dist/cards-7HRC4UQQ.js +85 -0
- package/dist/cards-7HRC4UQQ.js.map +1 -0
- package/dist/catalog-N6MDMIVL.js +64 -0
- package/dist/catalog-N6MDMIVL.js.map +1 -0
- package/dist/catalogs-PB46L7FH.js +128 -0
- package/dist/catalogs-PB46L7FH.js.map +1 -0
- package/dist/changes-SASUQK62.js +135 -0
- package/dist/changes-SASUQK62.js.map +1 -0
- package/dist/chatgpt-JKBSAG25.js +47 -0
- package/dist/chatgpt-JKBSAG25.js.map +1 -0
- package/dist/chats-TUZANLQH.js +262 -0
- package/dist/chats-TUZANLQH.js.map +1 -0
- package/dist/chunk-25E6SC3F.js +363 -0
- package/dist/chunk-25E6SC3F.js.map +1 -0
- package/dist/chunk-2GVXNKAE.js +42 -0
- package/dist/chunk-2GVXNKAE.js.map +1 -0
- package/dist/{chunk-VLUGGVJL.js → chunk-2UFRHW3T.js} +12 -4
- package/dist/chunk-2UFRHW3T.js.map +1 -0
- package/dist/chunk-2Y5V23PU.js +29 -0
- package/dist/chunk-2Y5V23PU.js.map +1 -0
- package/dist/chunk-35NYNRRB.js +111 -0
- package/dist/chunk-35NYNRRB.js.map +1 -0
- package/dist/chunk-3ACMDRSE.js +39 -0
- package/dist/chunk-3ACMDRSE.js.map +1 -0
- package/dist/chunk-3M6RNCDD.js +26 -0
- package/dist/chunk-3M6RNCDD.js.map +1 -0
- package/dist/chunk-3VXQYDJN.js +1743 -0
- package/dist/chunk-3VXQYDJN.js.map +1 -0
- package/dist/chunk-42DF5DF3.js +304 -0
- package/dist/chunk-42DF5DF3.js.map +1 -0
- package/dist/chunk-44VXKO65.js +106 -0
- package/dist/chunk-44VXKO65.js.map +1 -0
- package/dist/chunk-4NZ47VXO.js +137 -0
- package/dist/chunk-4NZ47VXO.js.map +1 -0
- package/dist/chunk-4X3UR372.js +225 -0
- package/dist/chunk-4X3UR372.js.map +1 -0
- package/dist/chunk-5FEBUCJU.js +25 -0
- package/dist/chunk-5FEBUCJU.js.map +1 -0
- package/dist/chunk-5HYSKH77.js +315 -0
- package/dist/chunk-5HYSKH77.js.map +1 -0
- package/dist/chunk-5LBGFQWF.js +310 -0
- package/dist/chunk-5LBGFQWF.js.map +1 -0
- package/dist/chunk-5MBPIONY.js +29 -0
- package/dist/chunk-5MBPIONY.js.map +1 -0
- package/dist/chunk-6YMHGIHP.js +346 -0
- package/dist/chunk-6YMHGIHP.js.map +1 -0
- package/dist/{chunk-VZEDAFAR.js → chunk-6YYSUISH.js} +47 -8
- package/dist/chunk-6YYSUISH.js.map +1 -0
- package/dist/chunk-7GNU3P7X.js +175 -0
- package/dist/chunk-7GNU3P7X.js.map +1 -0
- package/dist/chunk-7OHWEF3I.js +98 -0
- package/dist/chunk-7OHWEF3I.js.map +1 -0
- package/dist/chunk-7TR3QVWM.js +57 -0
- package/dist/chunk-7TR3QVWM.js.map +1 -0
- package/dist/chunk-AADVCEL4.js +817 -0
- package/dist/chunk-AADVCEL4.js.map +1 -0
- package/dist/chunk-AG62YO7C.js +96 -0
- package/dist/chunk-AG62YO7C.js.map +1 -0
- package/dist/chunk-AIRIT4GF.js +75 -0
- package/dist/chunk-AIRIT4GF.js.map +1 -0
- package/dist/chunk-AP3TP6VG.js +139 -0
- package/dist/chunk-AP3TP6VG.js.map +1 -0
- package/dist/chunk-APP475IQ.js +474 -0
- package/dist/chunk-APP475IQ.js.map +1 -0
- package/dist/chunk-AR7PU7BB.js +76 -0
- package/dist/chunk-AR7PU7BB.js.map +1 -0
- package/dist/chunk-B4S72KSS.js +172 -0
- package/dist/chunk-B4S72KSS.js.map +1 -0
- package/dist/chunk-BIPIL4QA.js +486 -0
- package/dist/chunk-BIPIL4QA.js.map +1 -0
- package/dist/chunk-BPUSL5Y2.js +58 -0
- package/dist/chunk-BPUSL5Y2.js.map +1 -0
- package/dist/chunk-BR32GHYD.js +65 -0
- package/dist/chunk-BR32GHYD.js.map +1 -0
- package/dist/chunk-CAMX6OHF.js +3182 -0
- package/dist/chunk-CAMX6OHF.js.map +1 -0
- package/dist/chunk-CE7RTOX6.js +494 -0
- package/dist/chunk-CE7RTOX6.js.map +1 -0
- package/dist/{chunk-MF7YA62W.js → chunk-CUL3VB4L.js} +10 -5
- package/dist/chunk-CUL3VB4L.js.map +1 -0
- package/dist/chunk-CVEY353K.js +66 -0
- package/dist/chunk-CVEY353K.js.map +1 -0
- package/dist/chunk-CWXADUKL.js +1599 -0
- package/dist/chunk-CWXADUKL.js.map +1 -0
- package/dist/chunk-D46NOXRY.js +6212 -0
- package/dist/chunk-D46NOXRY.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-DUPURL26.js +97 -0
- package/dist/chunk-DUPURL26.js.map +1 -0
- package/dist/chunk-DXJYQ5P2.js +625 -0
- package/dist/chunk-DXJYQ5P2.js.map +1 -0
- package/dist/chunk-E2ZOSNF5.js +96 -0
- package/dist/chunk-E2ZOSNF5.js.map +1 -0
- package/dist/chunk-E3HYHT7C.js +274 -0
- package/dist/chunk-E3HYHT7C.js.map +1 -0
- package/dist/chunk-EDLZGTGN.js +216 -0
- package/dist/chunk-EDLZGTGN.js.map +1 -0
- package/dist/{chunk-XHC4LMK4.js → chunk-EIGXX6KI.js} +16 -8
- package/dist/chunk-EIGXX6KI.js.map +1 -0
- package/dist/chunk-EPDE7ZRU.js +174 -0
- package/dist/chunk-EPDE7ZRU.js.map +1 -0
- package/dist/chunk-ERSX3MKH.js +34 -0
- package/dist/chunk-ERSX3MKH.js.map +1 -0
- package/dist/chunk-F7HRLPR5.js +67 -0
- package/dist/chunk-F7HRLPR5.js.map +1 -0
- package/dist/chunk-FEG6MN4H.js +84 -0
- package/dist/chunk-FEG6MN4H.js.map +1 -0
- package/dist/chunk-FKOECEVC.js +126 -0
- package/dist/chunk-FKOECEVC.js.map +1 -0
- package/dist/chunk-FMGW2NZI.js +106 -0
- package/dist/chunk-FMGW2NZI.js.map +1 -0
- package/dist/chunk-FPZKKNDK.js +98 -0
- package/dist/chunk-FPZKKNDK.js.map +1 -0
- package/dist/chunk-G3ZDLPNZ.js +206 -0
- package/dist/chunk-G3ZDLPNZ.js.map +1 -0
- package/dist/chunk-GIWHHCD6.js +145 -0
- package/dist/chunk-GIWHHCD6.js.map +1 -0
- package/dist/chunk-GOJXKIFQ.js +1605 -0
- package/dist/chunk-GOJXKIFQ.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-HAE4WWFQ.js +455 -0
- package/dist/chunk-HAE4WWFQ.js.map +1 -0
- package/dist/chunk-HEEAC2YG.js +541 -0
- package/dist/chunk-HEEAC2YG.js.map +1 -0
- package/dist/chunk-I2DNBEV6.js +4227 -0
- package/dist/chunk-I2DNBEV6.js.map +1 -0
- package/dist/chunk-I4FTS5EE.js +455 -0
- package/dist/chunk-I4FTS5EE.js.map +1 -0
- package/dist/chunk-IA4KJU7O.js +3151 -0
- package/dist/chunk-IA4KJU7O.js.map +1 -0
- package/dist/chunk-IELPT4K2.js +74 -0
- package/dist/chunk-IELPT4K2.js.map +1 -0
- package/dist/chunk-IJMWEO4P.js +57 -0
- package/dist/chunk-IJMWEO4P.js.map +1 -0
- package/dist/chunk-IVIJJXXT.js +62 -0
- package/dist/chunk-IVIJJXXT.js.map +1 -0
- package/dist/chunk-JAU6OAFK.js +455 -0
- package/dist/chunk-JAU6OAFK.js.map +1 -0
- package/dist/chunk-JD3W3ON7.js +188 -0
- package/dist/chunk-JD3W3ON7.js.map +1 -0
- package/dist/chunk-JLWBK3VC.js +5187 -0
- package/dist/chunk-JLWBK3VC.js.map +1 -0
- package/dist/chunk-JPK34QPS.js +134 -0
- package/dist/chunk-JPK34QPS.js.map +1 -0
- package/dist/chunk-JXJD6RC5.js +169 -0
- package/dist/chunk-JXJD6RC5.js.map +1 -0
- package/dist/chunk-JXMZEOHV.js +333 -0
- package/dist/chunk-JXMZEOHV.js.map +1 -0
- package/dist/chunk-K6TDB2KV.js +1442 -0
- package/dist/chunk-K6TDB2KV.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-KONA5PSR.js +55 -0
- package/dist/chunk-KONA5PSR.js.map +1 -0
- package/dist/chunk-KVHRW7KO.js +60 -0
- package/dist/chunk-KVHRW7KO.js.map +1 -0
- package/dist/chunk-LA6PPSNA.js +65 -0
- package/dist/chunk-LA6PPSNA.js.map +1 -0
- package/dist/chunk-LKPJADL2.js +74 -0
- package/dist/chunk-LKPJADL2.js.map +1 -0
- package/dist/chunk-LM7N7IQR.js +297 -0
- package/dist/chunk-LM7N7IQR.js.map +1 -0
- package/dist/chunk-LWAEHLKV.js +74 -0
- package/dist/chunk-LWAEHLKV.js.map +1 -0
- package/dist/chunk-M6UNISGO.js +66 -0
- package/dist/chunk-M6UNISGO.js.map +1 -0
- package/dist/chunk-MFSIACRB.js +207 -0
- package/dist/chunk-MFSIACRB.js.map +1 -0
- package/dist/chunk-MIJAGBEP.js +23992 -0
- package/dist/chunk-MIJAGBEP.js.map +1 -0
- package/dist/chunk-MYTDK3AL.js +2102 -0
- package/dist/chunk-MYTDK3AL.js.map +1 -0
- package/dist/chunk-MYURCD23.js +6667 -0
- package/dist/chunk-MYURCD23.js.map +1 -0
- package/dist/chunk-MZQ5DX6S.js +125 -0
- package/dist/chunk-MZQ5DX6S.js.map +1 -0
- package/dist/chunk-NFSLRRIE.js +77 -0
- package/dist/chunk-NFSLRRIE.js.map +1 -0
- package/dist/chunk-NMDP7FZP.js +479 -0
- package/dist/chunk-NMDP7FZP.js.map +1 -0
- package/dist/chunk-NMGELUIA.js +183 -0
- package/dist/chunk-NMGELUIA.js.map +1 -0
- package/dist/chunk-NOK7MSVJ.js +533 -0
- package/dist/chunk-NOK7MSVJ.js.map +1 -0
- package/dist/chunk-O2EVJALZ.js +133 -0
- package/dist/chunk-O2EVJALZ.js.map +1 -0
- package/dist/chunk-OIL6PU5W.js +35 -0
- package/dist/chunk-OIL6PU5W.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-PSWVSLJU.js +56 -0
- package/dist/chunk-PSWVSLJU.js.map +1 -0
- package/dist/chunk-PY2NJ6XZ.js +191 -0
- package/dist/chunk-PY2NJ6XZ.js.map +1 -0
- package/dist/chunk-PZ4OM2LK.js +45 -0
- package/dist/chunk-PZ4OM2LK.js.map +1 -0
- package/dist/chunk-Q2EKN7NI.js +1079 -0
- package/dist/chunk-Q2EKN7NI.js.map +1 -0
- package/dist/chunk-Q6ULQMWG.js +41 -0
- package/dist/chunk-Q6ULQMWG.js.map +1 -0
- package/dist/chunk-QMLGJ5OW.js +2891 -0
- package/dist/chunk-QMLGJ5OW.js.map +1 -0
- package/dist/chunk-R7QV5N2S.js +846 -0
- package/dist/chunk-R7QV5N2S.js.map +1 -0
- package/dist/chunk-RCS4JKUD.js +23 -0
- package/dist/chunk-RCS4JKUD.js.map +1 -0
- package/dist/chunk-RR3KT2E7.js +665 -0
- package/dist/chunk-RR3KT2E7.js.map +1 -0
- package/dist/chunk-SEPPFM5S.js +228 -0
- package/dist/chunk-SEPPFM5S.js.map +1 -0
- package/dist/chunk-SQ7DRYCC.js +150 -0
- package/dist/chunk-SQ7DRYCC.js.map +1 -0
- package/dist/chunk-SYULM665.js +610 -0
- package/dist/chunk-SYULM665.js.map +1 -0
- package/dist/chunk-TKT3OHZ6.js +170 -0
- package/dist/chunk-TKT3OHZ6.js.map +1 -0
- package/dist/chunk-TNOSX3PJ.js +136 -0
- package/dist/chunk-TNOSX3PJ.js.map +1 -0
- package/dist/chunk-TTVKI54A.js +160 -0
- package/dist/chunk-TTVKI54A.js.map +1 -0
- package/dist/chunk-U55UZRIB.js +592 -0
- package/dist/chunk-U55UZRIB.js.map +1 -0
- package/dist/chunk-UI6BKYQD.js +225 -0
- package/dist/chunk-UI6BKYQD.js.map +1 -0
- package/dist/chunk-UKE4IZSA.js +337 -0
- package/dist/chunk-UKE4IZSA.js.map +1 -0
- package/dist/chunk-UKLDW4UW.js +46 -0
- package/dist/chunk-UKLDW4UW.js.map +1 -0
- package/dist/chunk-V6XXXEXZ.js +76 -0
- package/dist/chunk-V6XXXEXZ.js.map +1 -0
- package/dist/chunk-VCZSZCXY.js +197 -0
- package/dist/chunk-VCZSZCXY.js.map +1 -0
- package/dist/chunk-VJQWUF66.js +92 -0
- package/dist/chunk-VJQWUF66.js.map +1 -0
- package/dist/chunk-VSU5R34H.js +76 -0
- package/dist/chunk-VSU5R34H.js.map +1 -0
- package/dist/chunk-W4SA4CMR.js +296 -0
- package/dist/chunk-W4SA4CMR.js.map +1 -0
- package/dist/chunk-WFUMNDCE.js +111 -0
- package/dist/chunk-WFUMNDCE.js.map +1 -0
- package/dist/chunk-WGCGKU3M.js +51 -0
- package/dist/chunk-WGCGKU3M.js.map +1 -0
- package/dist/chunk-WHWNXLTD.js +166 -0
- package/dist/chunk-WHWNXLTD.js.map +1 -0
- package/dist/chunk-WN42X2OE.js +509 -0
- package/dist/chunk-WN42X2OE.js.map +1 -0
- package/dist/chunk-WN4KX7GE.js +25 -0
- package/dist/chunk-WN4KX7GE.js.map +1 -0
- package/dist/chunk-XIY7P54H.js +84 -0
- package/dist/chunk-XIY7P54H.js.map +1 -0
- package/dist/chunk-XPLTWUMN.js +103 -0
- package/dist/chunk-XPLTWUMN.js.map +1 -0
- package/dist/chunk-Y6T5ZKBK.js +19 -0
- package/dist/chunk-Y6T5ZKBK.js.map +1 -0
- package/dist/chunk-YGGRQXDP.js +382 -0
- package/dist/chunk-YGGRQXDP.js.map +1 -0
- package/dist/chunk-YMBB4JBD.js +1830 -0
- package/dist/chunk-YMBB4JBD.js.map +1 -0
- package/dist/chunk-YNWM426O.js +159 -0
- package/dist/chunk-YNWM426O.js.map +1 -0
- package/dist/chunk-YQSBHWOI.js +41 -0
- package/dist/chunk-YTF3IVMF.js +149 -0
- package/dist/chunk-YTF3IVMF.js.map +1 -0
- package/dist/chunk-Z3ENMCFE.js +94 -0
- package/dist/chunk-Z3ENMCFE.js.map +1 -0
- package/dist/chunk-Z7MWSXLG.js +94 -0
- package/dist/chunk-Z7MWSXLG.js.map +1 -0
- package/dist/chunk-ZIXHS6AM.js +42 -0
- package/dist/chunk-ZIXHS6AM.js.map +1 -0
- package/dist/chunk-ZJ7TQUCU.js +4410 -0
- package/dist/chunk-ZJ7TQUCU.js.map +1 -0
- package/dist/chunk-ZNQRDLSS.js +52 -0
- package/dist/chunk-ZNQRDLSS.js.map +1 -0
- package/dist/chunk-ZPGGSXU3.js +275 -0
- package/dist/chunk-ZPGGSXU3.js.map +1 -0
- package/dist/claim-NXYQZEMC.js +197 -0
- package/dist/claim-NXYQZEMC.js.map +1 -0
- package/dist/cli.js +104 -69952
- package/dist/cli.js.map +1 -1
- package/dist/client-EURRWXPW.js +19 -0
- package/dist/code-FKQW7V7N.js +76 -0
- package/dist/code-FKQW7V7N.js.map +1 -0
- package/dist/companies-5ZH47E4H.js +195 -0
- package/dist/companies-5ZH47E4H.js.map +1 -0
- package/dist/complete-62OQPRHW.js +81 -0
- package/dist/complete-62OQPRHW.js.map +1 -0
- package/dist/config-OZOHIAOJ.js +88 -0
- package/dist/config-OZOHIAOJ.js.map +1 -0
- package/dist/connect-6DQFYKGN.js +42 -0
- package/dist/content-PCGSX2QU.js +85 -0
- package/dist/content-PCGSX2QU.js.map +1 -0
- package/dist/conversation-NS7JHTPK.js +93 -0
- package/dist/conversation-NS7JHTPK.js.map +1 -0
- package/dist/conversion-report-7QSWB2FY.js +125 -0
- package/dist/conversion-report-7QSWB2FY.js.map +1 -0
- package/dist/conversion-upload-command-XESIAQPU.js +438 -0
- package/dist/conversion-upload-command-XESIAQPU.js.map +1 -0
- package/dist/conversion-writes-BGOVLBS5.js +120 -0
- package/dist/conversion-writes-BGOVLBS5.js.map +1 -0
- package/dist/conversions-46MI57VC.js +135 -0
- package/dist/conversions-46MI57VC.js.map +1 -0
- package/dist/conversions-IYIWW4O7.js +76 -0
- package/dist/conversions-IYIWW4O7.js.map +1 -0
- package/dist/countries-5OBUVLLD.js +82 -0
- package/dist/countries-5OBUVLLD.js.map +1 -0
- package/dist/create-BEDPXUB7.js +236 -0
- package/dist/create-BEDPXUB7.js.map +1 -0
- package/dist/create-LLTMBBGV.js +207 -0
- package/dist/create-LLTMBBGV.js.map +1 -0
- package/dist/create-VNJ2VH3A.js +59 -0
- package/dist/create-VNJ2VH3A.js.map +1 -0
- package/dist/create-ZYKG2XOP.js +138 -0
- package/dist/create-ZYKG2XOP.js.map +1 -0
- package/dist/creatives-2LL66X4E.js +51 -0
- package/dist/creatives-2LL66X4E.js.map +1 -0
- package/dist/creatives-3MEMSUKJ.js +182 -0
- package/dist/creatives-3MEMSUKJ.js.map +1 -0
- package/dist/creatives-XI2DGQUZ.js +87 -0
- package/dist/creatives-XI2DGQUZ.js.map +1 -0
- package/dist/credentials-63PRTM3K.js +287 -0
- package/dist/credentials-63PRTM3K.js.map +1 -0
- package/dist/critique-IQI7CCTT.js +213 -0
- package/dist/critique-IQI7CCTT.js.map +1 -0
- package/dist/critique-UV7FPG45.js +1449 -0
- package/dist/critique-UV7FPG45.js.map +1 -0
- package/dist/crm-OERYUOBS.js +224 -0
- package/dist/crm-OERYUOBS.js.map +1 -0
- package/dist/crm-VNO3QTQG.js +318 -0
- package/dist/crm-VNO3QTQG.js.map +1 -0
- package/dist/crop-B52KIQ4O.js +113 -0
- package/dist/crop-B52KIQ4O.js.map +1 -0
- package/dist/currency-GGWF5DMU.js +88 -0
- package/dist/currency-GGWF5DMU.js.map +1 -0
- package/dist/custom-conversions-7WDBTC4X.js +125 -0
- package/dist/custom-conversions-7WDBTC4X.js.map +1 -0
- package/dist/customers-FOPXEGCB.js +56 -0
- package/dist/decide-PK7WNSQ2.js +199 -0
- package/dist/decide-PK7WNSQ2.js.map +1 -0
- package/dist/delete-56LKNEGA.js +71 -0
- package/dist/delete-56LKNEGA.js.map +1 -0
- package/dist/delete-EZ7HHOOD.js +69 -0
- package/dist/delete-EZ7HHOOD.js.map +1 -0
- package/dist/delete-JSYM7QKN.js +54 -0
- package/dist/delete-JSYM7QKN.js.map +1 -0
- package/dist/delete-NOUWBNZM.js +66 -0
- package/dist/delete-NOUWBNZM.js.map +1 -0
- package/dist/delete-T33AWV63.js +63 -0
- package/dist/delete-T33AWV63.js.map +1 -0
- package/dist/delete-YSYVFL6W.js +71 -0
- package/dist/delete-YSYVFL6W.js.map +1 -0
- package/dist/demographics-LQGFUS4F.js +138 -0
- package/dist/demographics-LQGFUS4F.js.map +1 -0
- package/dist/describe-AAVYIFE3.js +97 -0
- package/dist/describe-AAVYIFE3.js.map +1 -0
- package/dist/describe-UQFLWVFR.js +97 -0
- package/dist/describe-UQFLWVFR.js.map +1 -0
- package/dist/dimensions-QDXBG2XC.js +101 -0
- package/dist/dimensions-QDXBG2XC.js.map +1 -0
- package/dist/discard-V4LQ7ZGA.js +66 -0
- package/dist/discard-V4LQ7ZGA.js.map +1 -0
- package/dist/discover-6TEBPVNC.js +93 -0
- package/dist/discover-6TEBPVNC.js.map +1 -0
- package/dist/discover-SBZPB7T2.js +172 -0
- package/dist/discover-SBZPB7T2.js.map +1 -0
- package/dist/domain-65J2DEDB.js +98 -0
- package/dist/domain-65J2DEDB.js.map +1 -0
- package/dist/download-LV3GPOWV.js +299 -0
- package/dist/download-LV3GPOWV.js.map +1 -0
- package/dist/draft-DDFFTZ43.js +233 -0
- package/dist/draft-DDFFTZ43.js.map +1 -0
- package/dist/draft-FIKJXNIQ.js +281 -0
- package/dist/draft-FIKJXNIQ.js.map +1 -0
- package/dist/draft-GYGWTMBU.js +307 -0
- package/dist/draft-GYGWTMBU.js.map +1 -0
- package/dist/draft-KNXVZAZV.js +217 -0
- package/dist/draft-KNXVZAZV.js.map +1 -0
- package/dist/draft-N4LFPKTA.js +100 -0
- package/dist/draft-N4LFPKTA.js.map +1 -0
- package/dist/draft-NG2DPL2X.js +306 -0
- package/dist/draft-NG2DPL2X.js.map +1 -0
- package/dist/draft-QILZ7M7N.js +328 -0
- package/dist/draft-QILZ7M7N.js.map +1 -0
- package/dist/draft-XPO5RWST.js +103 -0
- package/dist/draft-XPO5RWST.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-TQ2XS2KY.js} +12 -2
- package/dist/env-TQ2XS2KY.js.map +1 -0
- package/dist/experiment-FQNKMORZ.js +1397 -0
- package/dist/experiment-FQNKMORZ.js.map +1 -0
- package/dist/export-4IZQZAPF.js +168 -0
- package/dist/export-4IZQZAPF.js.map +1 -0
- package/dist/extract-DZMGVQ7D.js +113 -0
- package/dist/extract-DZMGVQ7D.js.map +1 -0
- package/dist/facets-FAAOFHBF.js +114 -0
- package/dist/facets-FAAOFHBF.js.map +1 -0
- package/dist/favorites-DD2LNSTG.js +178 -0
- package/dist/favorites-DD2LNSTG.js.map +1 -0
- package/dist/feed-TUVFNX2U.js +177 -0
- package/dist/feed-TUVFNX2U.js.map +1 -0
- package/dist/feedback-NWOOZOFW.js +66 -0
- package/dist/feedback-NWOOZOFW.js.map +1 -0
- package/dist/feedback-record-CFPUKLMY.js +175 -0
- package/dist/feedback-record-CFPUKLMY.js.map +1 -0
- package/dist/fetch-LEY77E7V.js +176 -0
- package/dist/fetch-LEY77E7V.js.map +1 -0
- package/dist/fetch-O6UHNXWB.js +139 -0
- package/dist/fetch-O6UHNXWB.js.map +1 -0
- package/dist/find-4XKIBF4D.js +134 -0
- package/dist/find-4XKIBF4D.js.map +1 -0
- package/dist/fit-ODVVXV2Q.js +45 -0
- package/dist/fit-ODVVXV2Q.js.map +1 -0
- package/dist/flows-QKPC63AF.js +247 -0
- package/dist/flows-QKPC63AF.js.map +1 -0
- package/dist/follow-RCOXTZGY.js +94 -0
- package/dist/follow-RCOXTZGY.js.map +1 -0
- package/dist/follow-competitors-SQ5XBFTK.js +112 -0
- package/dist/follow-competitors-SQ5XBFTK.js.map +1 -0
- package/dist/following-VDU3BHC4.js +113 -0
- package/dist/following-VDU3BHC4.js.map +1 -0
- package/dist/fonts-WM2MJDVJ.js +34 -0
- package/dist/fonts-WM2MJDVJ.js.map +1 -0
- package/dist/forecast-2GJKBNBM.js +168 -0
- package/dist/forecast-2GJKBNBM.js.map +1 -0
- package/dist/forecast-7K3TAHDL.js +104 -0
- package/dist/forecast-7K3TAHDL.js.map +1 -0
- package/dist/funding-HTFVZLLG.js +85 -0
- package/dist/funding-HTFVZLLG.js.map +1 -0
- package/dist/funnel-CSPK5SPZ.js +394 -0
- package/dist/funnel-CSPK5SPZ.js.map +1 -0
- package/dist/ga4-2RC4EH7V.js +55 -0
- package/dist/ga4-2RC4EH7V.js.map +1 -0
- package/dist/generate-TPDOBCKQ.js +262 -0
- package/dist/generate-TPDOBCKQ.js.map +1 -0
- package/dist/get-4YZ4PI3B.js +56 -0
- package/dist/get-4YZ4PI3B.js.map +1 -0
- package/dist/get-FH2LIEYL.js +63 -0
- package/dist/get-FH2LIEYL.js.map +1 -0
- package/dist/get-GZLCDXXW.js +61 -0
- package/dist/get-GZLCDXXW.js.map +1 -0
- package/dist/get-HFU6ZJPX.js +78 -0
- package/dist/get-HFU6ZJPX.js.map +1 -0
- package/dist/get-TSPQYEKC.js +59 -0
- package/dist/get-TSPQYEKC.js.map +1 -0
- package/dist/get-TY3RXYNZ.js +63 -0
- package/dist/get-TY3RXYNZ.js.map +1 -0
- package/dist/get-VPW33XTN.js +92 -0
- package/dist/get-VPW33XTN.js.map +1 -0
- package/dist/gif-JFEYPFFI.js +94 -0
- package/dist/gif-JFEYPFFI.js.map +1 -0
- package/dist/google-R6RD4L6Z.js +136 -0
- package/dist/google-R6RD4L6Z.js.map +1 -0
- package/dist/google-VPQNRVIB.js +3190 -0
- package/dist/google-VPQNRVIB.js.map +1 -0
- package/dist/google-ads-WWM5KIRS.js +195 -0
- package/dist/google-ads-WWM5KIRS.js.map +1 -0
- package/dist/group-7AV6UL26.js +43 -0
- package/dist/group-7AV6UL26.js.map +1 -0
- package/dist/group-BVQZEZIC.js +43 -0
- package/dist/group-BVQZEZIC.js.map +1 -0
- package/dist/gsc-SQ42WAQE.js +30 -0
- package/dist/gsc-SQ42WAQE.js.map +1 -0
- package/dist/history-BNNHFURR.js +67 -0
- package/dist/history-BNNHFURR.js.map +1 -0
- package/dist/history-KBK5TP65.js +133 -0
- package/dist/history-KBK5TP65.js.map +1 -0
- package/dist/hubspot-GAAWWVLL.js +779 -0
- package/dist/hubspot-GAAWWVLL.js.map +1 -0
- package/dist/icon-OYTTSNSL.js +137 -0
- package/dist/icon-OYTTSNSL.js.map +1 -0
- package/dist/ideas-CELMD3BL.js +32 -0
- package/dist/ideas-CELMD3BL.js.map +1 -0
- package/dist/images-QHV4ECAP.js +90 -0
- package/dist/images-QHV4ECAP.js.map +1 -0
- package/dist/improve-W6GZNT2A.js +86 -0
- package/dist/improve-W6GZNT2A.js.map +1 -0
- package/dist/ingest-SH35YX6X.js +23 -0
- package/dist/ingest-SH35YX6X.js.map +1 -0
- package/dist/ingest-UWCGJZXV.js +107 -0
- package/dist/ingest-UWCGJZXV.js.map +1 -0
- package/dist/insights-IW7LGAWU.js +423 -0
- package/dist/insights-IW7LGAWU.js.map +1 -0
- package/dist/insights-QH54F56A.js +122 -0
- package/dist/insights-QH54F56A.js.map +1 -0
- package/dist/inspect-6Z6HEMBI.js +189 -0
- package/dist/inspect-6Z6HEMBI.js.map +1 -0
- package/dist/inspiration-RDQ3Y3N3.js +53 -0
- package/dist/inspiration-RDQ3Y3N3.js.map +1 -0
- package/dist/intent-5GSSCFZ2.js +95 -0
- package/dist/intent-5GSSCFZ2.js.map +1 -0
- package/dist/job-URVXJP75.js +202 -0
- package/dist/job-URVXJP75.js.map +1 -0
- package/dist/job-create-S4SECUVF.js +109 -0
- package/dist/job-create-S4SECUVF.js.map +1 -0
- package/dist/job-status-253SUCTJ.js +74 -0
- package/dist/job-status-253SUCTJ.js.map +1 -0
- package/dist/keep-GPSYDIGJ.js +78 -0
- package/dist/keep-GPSYDIGJ.js.map +1 -0
- package/dist/keyword-gap-NTFDX43B.js +130 -0
- package/dist/keyword-gap-NTFDX43B.js.map +1 -0
- package/dist/keyword-metrics-NKZRCF4L.js +197 -0
- package/dist/keyword-metrics-NKZRCF4L.js.map +1 -0
- package/dist/keywords-for-site-NQUPJNUR.js +128 -0
- package/dist/keywords-for-site-NQUPJNUR.js.map +1 -0
- package/dist/landing-AHNZSZHY.js +28 -0
- package/dist/landing-AHNZSZHY.js.map +1 -0
- package/dist/landings-NEF4PQL2.js +151 -0
- package/dist/landings-NEF4PQL2.js.map +1 -0
- package/dist/languages-3RDPPPTE.js +55 -0
- package/dist/languages-3RDPPPTE.js.map +1 -0
- package/dist/languages-CQX3YOIT.js +40 -0
- package/dist/languages-CQX3YOIT.js.map +1 -0
- package/dist/launches-GBHLJH5S.js +19 -0
- package/dist/launches-GBHLJH5S.js.map +1 -0
- package/dist/layerize-Q56C6LFG.js +190 -0
- package/dist/layerize-Q56C6LFG.js.map +1 -0
- package/dist/leads-5MUVPXA2.js +90 -0
- package/dist/leads-5MUVPXA2.js.map +1 -0
- package/dist/leads-JHUM6FYR.js +293 -0
- package/dist/leads-JHUM6FYR.js.map +1 -0
- package/dist/learn-EMV7RWTB.js +203 -0
- package/dist/learn-EMV7RWTB.js.map +1 -0
- package/dist/library-6VUFHTEK.js +109 -0
- package/dist/library-6VUFHTEK.js.map +1 -0
- package/dist/lighthouse-57U2GMPV.js +75 -0
- package/dist/lighthouse-57U2GMPV.js.map +1 -0
- package/dist/line-item-writes-GMIZYHLB.js +208 -0
- package/dist/line-item-writes-GMIZYHLB.js.map +1 -0
- package/dist/line-items-B5HAC47U.js +103 -0
- package/dist/line-items-B5HAC47U.js.map +1 -0
- package/dist/link-B6ZJFGFE.js +64 -0
- package/dist/link-B6ZJFGFE.js.map +1 -0
- package/dist/linkedin-FJ3OUYT2.js +1008 -0
- package/dist/linkedin-FJ3OUYT2.js.map +1 -0
- package/dist/list-2MBSU4ZX.js +63 -0
- package/dist/list-2MBSU4ZX.js.map +1 -0
- package/dist/list-EFUPHLG3.js +303 -0
- package/dist/list-EFUPHLG3.js.map +1 -0
- package/dist/list-G57ZO4PG.js +50 -0
- package/dist/list-G57ZO4PG.js.map +1 -0
- package/dist/list-JCSWZWDI.js +57 -0
- package/dist/list-JCSWZWDI.js.map +1 -0
- package/dist/list-QOSPRCH4.js +151 -0
- package/dist/list-QOSPRCH4.js.map +1 -0
- package/dist/list-RINCJOAC.js +76 -0
- package/dist/list-RINCJOAC.js.map +1 -0
- package/dist/list-SRNXHS6L.js +51 -0
- package/dist/list-SRNXHS6L.js.map +1 -0
- package/dist/list-YJSO4M5Q.js +65 -0
- package/dist/list-YJSO4M5Q.js.map +1 -0
- package/dist/locations-HW2Y5OJO.js +67 -0
- package/dist/locations-HW2Y5OJO.js.map +1 -0
- package/dist/locations-XOHI3VWI.js +40 -0
- package/dist/locations-XOHI3VWI.js.map +1 -0
- package/dist/log-SZDYUMM3.js +92 -0
- package/dist/log-SZDYUMM3.js.map +1 -0
- package/dist/logo-KXTGIYBI.js +18 -0
- package/dist/logo-KXTGIYBI.js.map +1 -0
- package/dist/lookup-X6O5UNJH.js +22 -0
- package/dist/lookup-X6O5UNJH.js.map +1 -0
- package/dist/make-SGCBJTRR.js +633 -0
- package/dist/make-SGCBJTRR.js.map +1 -0
- package/dist/map-ZK46VVL3.js +404 -0
- package/dist/map-ZK46VVL3.js.map +1 -0
- package/dist/mcp-NCM5TQUG.js +463 -0
- package/dist/mcp-NCM5TQUG.js.map +1 -0
- package/dist/media-MI4EE7L4.js +89 -0
- package/dist/media-MI4EE7L4.js.map +1 -0
- package/dist/media-QUTQOBA7.js +15 -0
- package/dist/media-QUTQOBA7.js.map +1 -0
- package/dist/media-sources-MS3RMQ6A.js +32 -0
- package/dist/media-sources-MS3RMQ6A.js.map +1 -0
- package/dist/members-IGHLTQKW.js +44 -0
- package/dist/members-IGHLTQKW.js.map +1 -0
- package/dist/meta-E3JOUOSS.js +69 -0
- package/dist/meta-E3JOUOSS.js.map +1 -0
- package/dist/metrics-HQ7XJAYQ.js +152 -0
- package/dist/metrics-HQ7XJAYQ.js.map +1 -0
- package/dist/models-PGX3FBHU.js +155 -0
- package/dist/models-PGX3FBHU.js.map +1 -0
- package/dist/normalize-FPJ6GSOY.js +806 -0
- package/dist/normalize-FPJ6GSOY.js.map +1 -0
- package/dist/normalize-LHD5LVFK.js +141 -0
- package/dist/normalize-LHD5LVFK.js.map +1 -0
- package/dist/options-CPHN3RMO.js +121 -0
- package/dist/options-CPHN3RMO.js.map +1 -0
- package/dist/output-GQFJ2T5B.js +24 -0
- package/dist/output-GQFJ2T5B.js.map +1 -0
- package/dist/page-VTTSBC6Y.js +105 -0
- package/dist/page-VTTSBC6Y.js.map +1 -0
- package/dist/pages-PMZVNVQM.js +66 -0
- package/dist/pages-PMZVNVQM.js.map +1 -0
- package/dist/performance-ECIJJEFV.js +24 -0
- package/dist/performance-ECIJJEFV.js.map +1 -0
- package/dist/pinterest-UDNGOWDM.js +96 -0
- package/dist/pinterest-UDNGOWDM.js.map +1 -0
- package/dist/pixels-OYZDGCH3.js +108 -0
- package/dist/pixels-OYZDGCH3.js.map +1 -0
- package/dist/pixels-XKGNTCFX.js +60 -0
- package/dist/pixels-XKGNTCFX.js.map +1 -0
- package/dist/plan-DZS3TVIJ.js +207 -0
- package/dist/plan-DZS3TVIJ.js.map +1 -0
- package/dist/preview-DR6MXOGI.js +169 -0
- package/dist/preview-DR6MXOGI.js.map +1 -0
- package/dist/profile-VOVZG44G.js +159 -0
- package/dist/profile-VOVZG44G.js.map +1 -0
- package/dist/promoted-tweet-writes-UJJI5SQL.js +180 -0
- package/dist/promoted-tweet-writes-UJJI5SQL.js.map +1 -0
- package/dist/promoted-tweets-O5RCETPX.js +119 -0
- package/dist/promoted-tweets-O5RCETPX.js.map +1 -0
- package/dist/properties-MKVF7MUK.js +101 -0
- package/dist/properties-MKVF7MUK.js.map +1 -0
- package/dist/publish-RRYU3NNX.js +322 -0
- package/dist/publish-RRYU3NNX.js.map +1 -0
- package/dist/query-CNWQ6STR.js +61 -0
- package/dist/query-CNWQ6STR.js.map +1 -0
- package/dist/query-DBSBZ73C.js +247 -0
- package/dist/query-DBSBZ73C.js.map +1 -0
- package/dist/query-QK4U4TEL.js +236 -0
- package/dist/query-QK4U4TEL.js.map +1 -0
- package/dist/questionnaire-OVJWNUVV.js +93 -0
- package/dist/questionnaire-OVJWNUVV.js.map +1 -0
- package/dist/read-L2QIVJTL.js +141 -0
- package/dist/read-L2QIVJTL.js.map +1 -0
- package/dist/reddit-K6CKJZRF.js +26 -0
- package/dist/reddit-K6CKJZRF.js.map +1 -0
- package/dist/refresh-IF4P57JJ.js +94 -0
- package/dist/refresh-IF4P57JJ.js.map +1 -0
- package/dist/release-H4EL3J6R.js +60 -0
- package/dist/release-H4EL3J6R.js.map +1 -0
- package/dist/relevant-pages-CRI2NLWG.js +99 -0
- package/dist/relevant-pages-CRI2NLWG.js.map +1 -0
- package/dist/remove-DKSHQRNS.js +50 -0
- package/dist/remove-DKSHQRNS.js.map +1 -0
- package/dist/remove-JKSCGKQG.js +48 -0
- package/dist/remove-JKSCGKQG.js.map +1 -0
- package/dist/reopen-B26V2GEJ.js +63 -0
- package/dist/reopen-B26V2GEJ.js.map +1 -0
- package/dist/rerun-6WKE4MPY.js +84 -0
- package/dist/rerun-6WKE4MPY.js.map +1 -0
- package/dist/research-O3IVF3MM.js +62 -0
- package/dist/research-O3IVF3MM.js.map +1 -0
- package/dist/research-SC7S6IPV.js +262 -0
- package/dist/research-SC7S6IPV.js.map +1 -0
- package/dist/reset-7HMOB2KE.js +54 -0
- package/dist/reset-7HMOB2KE.js.map +1 -0
- package/dist/reset-THPEXZDK.js +54 -0
- package/dist/reset-THPEXZDK.js.map +1 -0
- package/dist/resolve-HX5R52A3.js +121 -0
- package/dist/resolve-HX5R52A3.js.map +1 -0
- package/dist/retry-4ENRUJOJ.js +62 -0
- package/dist/retry-4ENRUJOJ.js.map +1 -0
- package/dist/retry-ELIMI7U5.js +60 -0
- package/dist/retry-ELIMI7U5.js.map +1 -0
- package/dist/retry-failed-2OYMCB55.js +45 -0
- package/dist/retry-failed-2OYMCB55.js.map +1 -0
- package/dist/run-CY4BAIQI.js +65 -0
- package/dist/run-CY4BAIQI.js.map +1 -0
- package/dist/run-GXPPPDGI.js +59 -0
- package/dist/run-GXPPPDGI.js.map +1 -0
- package/dist/scaffold-ad-X6VPBVTB.js +1548 -0
- package/dist/scaffold-ad-X6VPBVTB.js.map +1 -0
- package/dist/scaffold-static-ad-LKOOZSDP.js +971 -0
- package/dist/scaffold-static-ad-LKOOZSDP.js.map +1 -0
- package/dist/scaffold-video-NAOIFIM4.js +872 -0
- package/dist/scaffold-video-NAOIFIM4.js.map +1 -0
- package/dist/schedule-TLYT5UXM.js +66 -0
- package/dist/schedule-TLYT5UXM.js.map +1 -0
- package/dist/schedule-V654LLZ2.js +61 -0
- package/dist/schedule-V654LLZ2.js.map +1 -0
- package/dist/scheduled-agents-MJNUZYEK.js +49 -0
- package/dist/scheduled-agents-MJNUZYEK.js.map +1 -0
- package/dist/schema-DN4WKWUM.js +132 -0
- package/dist/schema-DN4WKWUM.js.map +1 -0
- package/dist/schema-MZTVCNP4.js +63 -0
- package/dist/schema-MZTVCNP4.js.map +1 -0
- package/dist/scrape-T3DA7ER7.js +2241 -0
- package/dist/scrape-T3DA7ER7.js.map +1 -0
- package/dist/screenshot-EIGC6SZB.js +102 -0
- package/dist/screenshot-EIGC6SZB.js.map +1 -0
- package/dist/search-2SVUDZIX.js +224 -0
- package/dist/search-2SVUDZIX.js.map +1 -0
- package/dist/search-34NFJ5F6.js +26 -0
- package/dist/search-34NFJ5F6.js.map +1 -0
- package/dist/search-BWE3OPOY.js +91 -0
- package/dist/search-BWE3OPOY.js.map +1 -0
- package/dist/search-EYYAOZND.js +92 -0
- package/dist/search-EYYAOZND.js.map +1 -0
- package/dist/search-EZZMYU4Y.js +174 -0
- package/dist/search-EZZMYU4Y.js.map +1 -0
- package/dist/search-copy-VKQ2OOBM.js +168 -0
- package/dist/search-copy-VKQ2OOBM.js.map +1 -0
- package/dist/seeds-HQYSVFIX.js +101 -0
- package/dist/seeds-HQYSVFIX.js.map +1 -0
- package/dist/select-3SIBANY6.js +94 -0
- package/dist/select-3SIBANY6.js.map +1 -0
- package/dist/sends-I7VQFE4S.js +309 -0
- package/dist/sends-I7VQFE4S.js.map +1 -0
- package/dist/sequences-JHSEJJGN.js +146 -0
- package/dist/sequences-JHSEJJGN.js.map +1 -0
- package/dist/set-prompt-RAG7RJOD.js +185 -0
- package/dist/set-prompt-RAG7RJOD.js.map +1 -0
- package/dist/setup-links-TNRBFS5Z.js +141 -0
- package/dist/setup-links-TNRBFS5Z.js.map +1 -0
- package/dist/{shared-J7DQZ2ED.js → shared-AT3FXPAG.js} +8 -6
- package/dist/shared-AT3FXPAG.js.map +1 -0
- package/dist/shopify-LUETQ5NT.js +3819 -0
- package/dist/shopify-LUETQ5NT.js.map +1 -0
- package/dist/site-SDL6LF6D.js +177 -0
- package/dist/site-SDL6LF6D.js.map +1 -0
- package/dist/sitemaps-FG37N5EB.js +87 -0
- package/dist/sitemaps-FG37N5EB.js.map +1 -0
- package/dist/sites-FIXK4Y3O.js +101 -0
- package/dist/sites-FIXK4Y3O.js.map +1 -0
- package/dist/skills-OKVCVQVD.js +47 -0
- package/dist/skills-OKVCVQVD.js.map +1 -0
- package/dist/sources-ISAUZFRN.js +30 -0
- package/dist/sources-ISAUZFRN.js.map +1 -0
- package/dist/sources-LQTJXAJG.js +421 -0
- package/dist/sources-LQTJXAJG.js.map +1 -0
- package/dist/stale-2L7NTLC6.js +63 -0
- package/dist/stale-2L7NTLC6.js.map +1 -0
- package/dist/stats-ZWZ7BAHV.js +34 -0
- package/dist/stats-ZWZ7BAHV.js.map +1 -0
- package/dist/status-4QBSIHO7.js +62 -0
- package/dist/status-4QBSIHO7.js.map +1 -0
- package/dist/sticker-FLRZM3BI.js +94 -0
- package/dist/sticker-FLRZM3BI.js.map +1 -0
- package/dist/stock-2CSMWRWV.js +179 -0
- package/dist/stock-2CSMWRWV.js.map +1 -0
- package/dist/studio-TTTR6N7D.js +49 -0
- package/dist/studio-TTTR6N7D.js.map +1 -0
- package/dist/sync-DH7FTPGG.js +54 -0
- package/dist/sync-DH7FTPGG.js.map +1 -0
- package/dist/sync-G5CS2RYV.js +54 -0
- package/dist/sync-G5CS2RYV.js.map +1 -0
- package/dist/sync-UADA6M33.js +265 -0
- package/dist/sync-UADA6M33.js.map +1 -0
- package/dist/sync-definition-ATMMOJ37.js +52 -0
- package/dist/sync-definition-ATMMOJ37.js.map +1 -0
- package/dist/tag-manager-NK3ZHSJB.js +43 -0
- package/dist/tag-manager-NK3ZHSJB.js.map +1 -0
- package/dist/tags-4RBZWDHS.js +20 -0
- package/dist/tags-4RBZWDHS.js.map +1 -0
- package/dist/tags-M7ATU2R7.js +26 -0
- package/dist/tags-M7ATU2R7.js.map +1 -0
- package/dist/tags-MXJKIBL4.js +20 -0
- package/dist/tags-MXJKIBL4.js.map +1 -0
- package/dist/tags-YG5EGPBW.js +20 -0
- package/dist/tags-YG5EGPBW.js.map +1 -0
- package/dist/tags-ZP4O3I2F.js +224 -0
- package/dist/tags-ZP4O3I2F.js.map +1 -0
- package/dist/targeting-constants-ZGBX3VWU.js +118 -0
- package/dist/targeting-constants-ZGBX3VWU.js.map +1 -0
- package/dist/targeting-criteria-BTB2RVI4.js +113 -0
- package/dist/targeting-criteria-BTB2RVI4.js.map +1 -0
- package/dist/targets-DEGJD2N6.js +102 -0
- package/dist/targets-DEGJD2N6.js.map +1 -0
- package/dist/templates-FZDWQSTV.js +178 -0
- package/dist/templates-FZDWQSTV.js.map +1 -0
- package/dist/testimonials-TI5EDABS.js +32 -0
- package/dist/testimonials-TI5EDABS.js.map +1 -0
- package/dist/themes-3RV3HNNE.js +94 -0
- package/dist/themes-3RV3HNNE.js.map +1 -0
- package/dist/top-companies-OKH7UNKX.js +108 -0
- package/dist/top-companies-OKH7UNKX.js.map +1 -0
- package/dist/translate-IUQBBVE6.js +598 -0
- package/dist/translate-IUQBBVE6.js.map +1 -0
- package/dist/triggers-2NWMXQ5P.js +141 -0
- package/dist/triggers-2NWMXQ5P.js.map +1 -0
- package/dist/tweets-X64YDEAA.js +123 -0
- package/dist/tweets-X64YDEAA.js.map +1 -0
- package/dist/unfollow-PIONCSBL.js +46 -0
- package/dist/unfollow-PIONCSBL.js.map +1 -0
- package/dist/unlink-UAPLQMK6.js +67 -0
- package/dist/unlink-UAPLQMK6.js.map +1 -0
- package/dist/unstage-BJJ5M7MK.js +95 -0
- package/dist/unstage-BJJ5M7MK.js.map +1 -0
- package/dist/unstage-X2BYGH2S.js +84 -0
- package/dist/unstage-X2BYGH2S.js.map +1 -0
- package/dist/update-7YK3VSOK.js +142 -0
- package/dist/update-7YK3VSOK.js.map +1 -0
- package/dist/update-BHG7BTK3.js +155 -0
- package/dist/update-BHG7BTK3.js.map +1 -0
- package/dist/update-CDJXKEVA.js +63 -0
- package/dist/update-CDJXKEVA.js.map +1 -0
- package/dist/update-RZXDAMAG.js +98 -0
- package/dist/update-RZXDAMAG.js.map +1 -0
- package/dist/upload-DSZEXNHH.js +126 -0
- package/dist/upload-DSZEXNHH.js.map +1 -0
- package/dist/upload-IWFYKD7A.js +150 -0
- package/dist/upload-IWFYKD7A.js.map +1 -0
- package/dist/upscale-EYCEYRWE.js +109 -0
- package/dist/upscale-EYCEYRWE.js.map +1 -0
- package/dist/url-options-RA3XISLN.js +130 -0
- package/dist/url-options-RA3XISLN.js.map +1 -0
- package/dist/url-params-OGZXF6MT.js +98 -0
- package/dist/url-params-OGZXF6MT.js.map +1 -0
- package/dist/use-E2TA2K6J.js +95 -0
- package/dist/use-E2TA2K6J.js.map +1 -0
- package/dist/validate-C6HWDI6K.js +88 -0
- package/dist/validate-C6HWDI6K.js.map +1 -0
- package/dist/variant-ETHB6XUM.js +338 -0
- package/dist/variant-ETHB6XUM.js.map +1 -0
- package/dist/videos-A2X5AARB.js +39 -0
- package/dist/videos-A2X5AARB.js.map +1 -0
- package/dist/view-BVEZRRV2.js +121 -0
- package/dist/view-BVEZRRV2.js.map +1 -0
- package/dist/viewer-check-W4ICSBHO.js +68 -0
- package/dist/viewer-check-W4ICSBHO.js.map +1 -0
- package/dist/web-GJSFDBBE.js +140 -0
- package/dist/web-GJSFDBBE.js.map +1 -0
- package/dist/winners-MJDKCGEZ.js +113 -0
- package/dist/winners-MJDKCGEZ.js.map +1 -0
- package/dist/winning-ads-NNU5MM75.js +84 -0
- package/dist/winning-ads-NNU5MM75.js.map +1 -0
- package/dist/write-commands-5I5KY6ZS.js +1015 -0
- package/dist/write-commands-5I5KY6ZS.js.map +1 -0
- package/dist/write-commands-DA6FIFAO.js +737 -0
- package/dist/write-commands-DA6FIFAO.js.map +1 -0
- package/dist/write-commands-KTPISQRE.js +206 -0
- package/dist/write-commands-KTPISQRE.js.map +1 -0
- package/dist/write-commands-QBGIWU27.js +713 -0
- package/dist/write-commands-QBGIWU27.js.map +1 -0
- package/dist/x-VCL5VRXC.js +47 -0
- package/dist/x-VCL5VRXC.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-VLUGGVJL.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/{client-GR6YL3YX.js.map → chunk-YQSBHWOI.js.map} +0 -0
- /package/dist/{env-4P5HOGNA.js.map → client-EURRWXPW.js.map} +0 -0
- /package/dist/{output-NMQXZF3Z.js.map → connect-6DQFYKGN.js.map} +0 -0
- /package/dist/{shared-J7DQZ2ED.js.map → customers-FOPXEGCB.js.map} +0 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import {
|
|
2
|
+
languageTag
|
|
3
|
+
} from "./chunk-MYURCD23.js";
|
|
4
|
+
import {
|
|
5
|
+
parseRefExpr
|
|
6
|
+
} from "./chunk-ZJ7TQUCU.js";
|
|
7
|
+
import {
|
|
8
|
+
AWARENESS_VALUES
|
|
9
|
+
} from "./chunk-5HYSKH77.js";
|
|
10
|
+
import {
|
|
11
|
+
collectAssetRefLikes,
|
|
12
|
+
isPersistedAssetRef
|
|
13
|
+
} from "./chunk-3VXQYDJN.js";
|
|
14
|
+
|
|
15
|
+
// src/commands/canvas/creative-definition.ts
|
|
16
|
+
import { parseDocument } from "yaml";
|
|
17
|
+
var PLATFORM_VALUES = ["meta", "google", "linkedin", "tiktok", "youtube", "x", "other"];
|
|
18
|
+
var FORMAT_VALUES = ["1:1", "4:5", "9:16", "16:9", "1.91:1"];
|
|
19
|
+
var EVIDENCE_VALUES = ["observed", "interpreted", "hypothesized", "generated"];
|
|
20
|
+
function titleFromSlug(slug) {
|
|
21
|
+
const title = slug.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
22
|
+
return title || slug;
|
|
23
|
+
}
|
|
24
|
+
function resolvePlatform(platform) {
|
|
25
|
+
const value = platform?.trim();
|
|
26
|
+
return value && PLATFORM_VALUES.includes(value) ? value : "meta";
|
|
27
|
+
}
|
|
28
|
+
function resolveFormats(aspect) {
|
|
29
|
+
const value = aspect?.trim();
|
|
30
|
+
return value && FORMAT_VALUES.includes(value) ? [value] : ["4:5"];
|
|
31
|
+
}
|
|
32
|
+
function resolveFormatList(formats) {
|
|
33
|
+
const valid = [...new Set(formats.map((f) => f.trim()))].filter(
|
|
34
|
+
(f) => FORMAT_VALUES.includes(f)
|
|
35
|
+
);
|
|
36
|
+
return valid.length > 0 ? valid : ["4:5"];
|
|
37
|
+
}
|
|
38
|
+
function describeBlueprintIntent(blueprint) {
|
|
39
|
+
const intent = blueprint?.ad_intent;
|
|
40
|
+
if (typeof intent === "string" && intent.trim()) return intent.trim();
|
|
41
|
+
if (intent && typeof intent === "object") {
|
|
42
|
+
const summary = intent.summary ?? intent.feeling;
|
|
43
|
+
if (typeof summary === "string" && summary.trim()) return summary.trim();
|
|
44
|
+
}
|
|
45
|
+
return void 0;
|
|
46
|
+
}
|
|
47
|
+
function yamlScalar(value) {
|
|
48
|
+
return JSON.stringify(value);
|
|
49
|
+
}
|
|
50
|
+
function buildCreativeDefinition(input) {
|
|
51
|
+
const lines = ["---", `title: ${yamlScalar(input.title)}`, `kind: ${input.kind}`, `platform: ${input.platform}`];
|
|
52
|
+
lines.push(`formats: [${input.formats.map(yamlScalar).join(", ")}]`);
|
|
53
|
+
lines.push(`status: ${input.status ?? "draft"}`);
|
|
54
|
+
if (input.sourceReferenceUrl) lines.push(`sourceReferenceUrl: ${yamlScalar(input.sourceReferenceUrl)}`);
|
|
55
|
+
if (input.sourceAdvertiser) lines.push(`sourceAdvertiser: ${yamlScalar(input.sourceAdvertiser)}`);
|
|
56
|
+
if (input.sourceAdvertiserId) lines.push(`sourceAdvertiserId: ${yamlScalar(input.sourceAdvertiserId)}`);
|
|
57
|
+
if (input.sourceAdId) lines.push(`sourceAdId: ${yamlScalar(input.sourceAdId)}`);
|
|
58
|
+
if (input.sourcePlatform) lines.push(`sourcePlatform: ${input.sourcePlatform}`);
|
|
59
|
+
if (input.sourceKind) lines.push(`sourceKind: ${input.sourceKind}`);
|
|
60
|
+
if (input.sourcePath) lines.push(`sourcePath: ${yamlScalar(input.sourcePath)}`);
|
|
61
|
+
if (input.targetAdSet) lines.push(`targetAdSet: ${yamlScalar(input.targetAdSet)}`);
|
|
62
|
+
if (input.viewer) lines.push(`viewer: ${JSON.stringify(input.viewer)}`);
|
|
63
|
+
lines.push("---", "");
|
|
64
|
+
lines.push(input.description?.trim() || `${input.title} \u2014 canvas-built ${input.kind} ad for ${input.platform}.`);
|
|
65
|
+
lines.push("");
|
|
66
|
+
return lines.join("\n");
|
|
67
|
+
}
|
|
68
|
+
var SOURCE_FIELD_KEYS = ["sourceAdId", "sourcePlatform", "sourceAdvertiserId"];
|
|
69
|
+
function parseDefinitionSourceFields(raw) {
|
|
70
|
+
const match = raw.match(/^---\r?\n([\s\S]*?\r?\n)?---/);
|
|
71
|
+
if (!match) return {};
|
|
72
|
+
const doc = parseDocument(match[1] ?? "");
|
|
73
|
+
if (doc.errors.length > 0) return {};
|
|
74
|
+
const fields = {};
|
|
75
|
+
for (const key of SOURCE_FIELD_KEYS) {
|
|
76
|
+
const value = doc.get(key);
|
|
77
|
+
if (typeof value === "string" && value.trim()) fields[key] = value.trim();
|
|
78
|
+
}
|
|
79
|
+
return fields;
|
|
80
|
+
}
|
|
81
|
+
function oneOf(values, value) {
|
|
82
|
+
return values.find((allowed) => allowed === value);
|
|
83
|
+
}
|
|
84
|
+
function parseDefinitionStrategyFields(raw) {
|
|
85
|
+
const match = raw.match(/^---\r?\n([\s\S]*?\r?\n)?---/);
|
|
86
|
+
if (!match) return {};
|
|
87
|
+
const doc = parseDocument(match[1] ?? "");
|
|
88
|
+
if (doc.errors.length > 0) return {};
|
|
89
|
+
const text = (key) => {
|
|
90
|
+
const value = doc.get(key);
|
|
91
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
92
|
+
};
|
|
93
|
+
const ideaSlug = text("idea");
|
|
94
|
+
const message = text("message");
|
|
95
|
+
const evidence = oneOf(EVIDENCE_VALUES, text("evidence"));
|
|
96
|
+
const angle = text("angle");
|
|
97
|
+
const persona = text("persona");
|
|
98
|
+
const awareness = oneOf(AWARENESS_VALUES, text("awareness"));
|
|
99
|
+
const hypothesis = text("hypothesis");
|
|
100
|
+
const seriesLead = text("series");
|
|
101
|
+
const language = languageTag(text("language") ?? "");
|
|
102
|
+
return {
|
|
103
|
+
...seriesLead ? { seriesLead } : {},
|
|
104
|
+
...language ? { language } : {},
|
|
105
|
+
...ideaSlug ? { ideaSlug } : {},
|
|
106
|
+
...message ? { message } : {},
|
|
107
|
+
...evidence ? { evidence } : {},
|
|
108
|
+
...angle ? { angle } : {},
|
|
109
|
+
...persona ? { persona } : {},
|
|
110
|
+
...awareness ? { awareness } : {},
|
|
111
|
+
...hypothesis ? { hypothesis } : {}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function parseDefinitionSeriesPlace(raw) {
|
|
115
|
+
const match = raw.match(/^---\r?\n([\s\S]*?\r?\n)?---/);
|
|
116
|
+
if (!match || parseDocument(match[1] ?? "").errors.length > 0) return null;
|
|
117
|
+
const { seriesLead, language } = parseDefinitionStrategyFields(raw);
|
|
118
|
+
return { seriesLead: seriesLead ?? null, language: language ?? null };
|
|
119
|
+
}
|
|
120
|
+
function parseDefinitionViewerFields(raw) {
|
|
121
|
+
const match = raw.match(/^---\r?\n([\s\S]*?\r?\n)?---/);
|
|
122
|
+
if (!match) return {};
|
|
123
|
+
const doc = parseDocument(match[1] ?? "");
|
|
124
|
+
if (doc.errors.length > 0) return {};
|
|
125
|
+
const data = doc.toJS();
|
|
126
|
+
const adSet = data?.targetAdSet;
|
|
127
|
+
const targetAdSet = typeof adSet === "string" || typeof adSet === "number" ? String(adSet).trim() : "";
|
|
128
|
+
return {
|
|
129
|
+
...targetAdSet ? { targetAdSet } : {},
|
|
130
|
+
...data?.viewer !== void 0 ? { viewer: data.viewer } : {}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function setDefinitionViewer(raw, fields) {
|
|
134
|
+
const match = raw.match(/^---\r?\n([\s\S]*?\r?\n)?---/);
|
|
135
|
+
if (!match) return raw;
|
|
136
|
+
const doc = parseDocument(match[1] ?? "");
|
|
137
|
+
if (doc.errors.length > 0) return raw;
|
|
138
|
+
if (fields.targetAdSet) doc.set("targetAdSet", fields.targetAdSet);
|
|
139
|
+
if (fields.viewer) doc.set("viewer", doc.createNode(fields.viewer, { flow: true }));
|
|
140
|
+
return `---
|
|
141
|
+
${doc.toString()}---${raw.slice(match[0].length)}`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/commands/canvas/run-record.ts
|
|
145
|
+
import path from "path";
|
|
146
|
+
var MAX_RUN_NODES = 200;
|
|
147
|
+
var MAX_OUTPUTS_PER_NODE = 10;
|
|
148
|
+
var MAX_FINAL_OUTPUTS = 10;
|
|
149
|
+
var MAX_CREATIVE_SLUG_LENGTH = 100;
|
|
150
|
+
function creativeSlugFromCanvasPath(filePath) {
|
|
151
|
+
const normalized = filePath.split(path.sep).join("/");
|
|
152
|
+
const match = normalized.match(/(?:^|\/)src\/creatives\/([a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\//);
|
|
153
|
+
const slug = match?.[1] ?? null;
|
|
154
|
+
return slug && slug.length <= MAX_CREATIVE_SLUG_LENGTH ? slug : null;
|
|
155
|
+
}
|
|
156
|
+
function finalOutputLabelsFromCanvas(parsed) {
|
|
157
|
+
const canvas = parsed;
|
|
158
|
+
const outputNodeId = canvas?.output?.node;
|
|
159
|
+
if (typeof outputNodeId !== "string" || !Array.isArray(canvas?.nodes)) return null;
|
|
160
|
+
const node = canvas.nodes.find((n) => n?.id === outputNodeId);
|
|
161
|
+
if (node?.type !== "collect") return null;
|
|
162
|
+
const explicit = node.params?.labels;
|
|
163
|
+
if (Array.isArray(explicit) && explicit.every((l) => typeof l === "string")) {
|
|
164
|
+
return { nodeId: outputNodeId, labels: explicit };
|
|
165
|
+
}
|
|
166
|
+
const images = node.inputs?.images;
|
|
167
|
+
if (!Array.isArray(images)) return null;
|
|
168
|
+
const labels = images.map((entry) => {
|
|
169
|
+
if (typeof entry !== "string") return void 0;
|
|
170
|
+
return parseRefExpr(entry)?.nodeId;
|
|
171
|
+
});
|
|
172
|
+
return { nodeId: outputNodeId, labels };
|
|
173
|
+
}
|
|
174
|
+
var OUTPUT_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
|
|
175
|
+
function toRecordOutput(slot, value, label) {
|
|
176
|
+
const refs = collectAssetRefLikes(value);
|
|
177
|
+
const ref = refs.length === 1 ? refs[0] : null;
|
|
178
|
+
if (!ref || !isPersistedAssetRef(ref)) return null;
|
|
179
|
+
const kind = typeof ref.kind === "string" && OUTPUT_KINDS.has(ref.kind) ? ref.kind : null;
|
|
180
|
+
if (!kind) return null;
|
|
181
|
+
return {
|
|
182
|
+
slot,
|
|
183
|
+
label,
|
|
184
|
+
kind,
|
|
185
|
+
sha256: ref.sha256,
|
|
186
|
+
url: ref.url,
|
|
187
|
+
mime: ref.mime,
|
|
188
|
+
width: typeof ref.width === "number" ? ref.width : void 0,
|
|
189
|
+
height: typeof ref.height === "number" ? ref.height : void 0,
|
|
190
|
+
durationMs: typeof ref.duration_ms === "number" ? ref.duration_ms : void 0
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function nodeOutputsToRecord(nodeOutputs, labels) {
|
|
194
|
+
const out = [];
|
|
195
|
+
for (const [slot, value] of Object.entries(nodeOutputs)) {
|
|
196
|
+
if (Array.isArray(value)) {
|
|
197
|
+
value.forEach((item, i) => {
|
|
198
|
+
const rec = toRecordOutput(`${slot}#${i}`, item, labels?.[i]);
|
|
199
|
+
if (rec) out.push(rec);
|
|
200
|
+
});
|
|
201
|
+
} else {
|
|
202
|
+
const rec = toRecordOutput(slot, value);
|
|
203
|
+
if (rec) out.push(rec);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return out.slice(0, MAX_OUTPUTS_PER_NODE);
|
|
207
|
+
}
|
|
208
|
+
function finalOutputsToRecord(output, labels) {
|
|
209
|
+
if (Array.isArray(output)) {
|
|
210
|
+
return output.map((item, i) => toRecordOutput(`final#${i}`, item, labels?.[i])).filter((rec2) => rec2 !== null).slice(0, MAX_FINAL_OUTPUTS);
|
|
211
|
+
}
|
|
212
|
+
const rec = toRecordOutput("final", output);
|
|
213
|
+
return rec ? [rec] : [];
|
|
214
|
+
}
|
|
215
|
+
function finalFiles(output, labels) {
|
|
216
|
+
const items = Array.isArray(output) ? output : [output];
|
|
217
|
+
const files = {};
|
|
218
|
+
items.forEach((item, i) => {
|
|
219
|
+
const ref = collectAssetRefLikes(item)[0];
|
|
220
|
+
if (ref && typeof ref.path === "string") files[labels?.[i] ?? `final#${i}`] = ref.path;
|
|
221
|
+
});
|
|
222
|
+
return files;
|
|
223
|
+
}
|
|
224
|
+
function buildRunRecord(result, meta, plan, finalLabels) {
|
|
225
|
+
const nodes = result.node_runs.slice(0, MAX_RUN_NODES).map((run) => {
|
|
226
|
+
const planned = plan?.get(run.node_id);
|
|
227
|
+
return {
|
|
228
|
+
nodeId: run.node_id,
|
|
229
|
+
nodeType: run.node_type,
|
|
230
|
+
cached: run.cached,
|
|
231
|
+
credits: run.credits,
|
|
232
|
+
durationMs: run.duration_ms,
|
|
233
|
+
outputs: nodeOutputsToRecord(
|
|
234
|
+
result.outputs_by_node[run.node_id] ?? {},
|
|
235
|
+
run.node_id === finalLabels?.nodeId ? finalLabels.labels : void 0
|
|
236
|
+
),
|
|
237
|
+
deps: planned?.deps,
|
|
238
|
+
status: plan ? "completed" : void 0,
|
|
239
|
+
paramsPreview: planned?.paramsPreview,
|
|
240
|
+
...planned?.role !== void 0 ? { role: planned.role } : {}
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
const finalOutputs = finalOutputsToRecord(result.output, finalLabels?.labels);
|
|
244
|
+
return {
|
|
245
|
+
runId: result.run_id,
|
|
246
|
+
...meta,
|
|
247
|
+
status: "completed",
|
|
248
|
+
stats: {
|
|
249
|
+
totalNodes: result.stats.total_nodes,
|
|
250
|
+
cachedNodes: result.stats.cached_nodes,
|
|
251
|
+
totalCredits: result.stats.total_credits,
|
|
252
|
+
durationMs: result.stats.duration_ms
|
|
253
|
+
},
|
|
254
|
+
nodes,
|
|
255
|
+
finalOutputs: finalOutputs.length > 0 ? finalOutputs : void 0,
|
|
256
|
+
// Sent whenever the review RAN, empty list included. Sending it only when there
|
|
257
|
+
// were findings makes a clean render and an unreviewed one look identical in the
|
|
258
|
+
// record — which is the exact ambiguity this field was added to remove: proving a
|
|
259
|
+
// review had happened once meant re-running a cached canvas and reading raw JSON.
|
|
260
|
+
// Only the fields the backend keeps: a static review's typed fields (`kind`) stay in the CLI.
|
|
261
|
+
...meta.review ? { review: meta.review.slice(0, 40).map(({ severity, what, scene }) => ({ severity, what, ...scene ? { scene } : {} })) } : {}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function buildInitialRunRecord(runId, meta) {
|
|
265
|
+
return {
|
|
266
|
+
runId,
|
|
267
|
+
...meta,
|
|
268
|
+
status: "running",
|
|
269
|
+
stats: { totalNodes: 0, cachedNodes: 0, totalCredits: 0, durationMs: 0 },
|
|
270
|
+
nodes: []
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function buildFailedRunRecord(runId, errorMessage, meta) {
|
|
274
|
+
return {
|
|
275
|
+
runId,
|
|
276
|
+
...meta,
|
|
277
|
+
status: "failed",
|
|
278
|
+
errorMessage: errorMessage.slice(0, 2e3),
|
|
279
|
+
stats: { totalNodes: 0, cachedNodes: 0, totalCredits: 0, durationMs: 0 },
|
|
280
|
+
nodes: []
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export {
|
|
285
|
+
titleFromSlug,
|
|
286
|
+
resolvePlatform,
|
|
287
|
+
resolveFormats,
|
|
288
|
+
resolveFormatList,
|
|
289
|
+
describeBlueprintIntent,
|
|
290
|
+
buildCreativeDefinition,
|
|
291
|
+
parseDefinitionSourceFields,
|
|
292
|
+
parseDefinitionStrategyFields,
|
|
293
|
+
parseDefinitionSeriesPlace,
|
|
294
|
+
parseDefinitionViewerFields,
|
|
295
|
+
setDefinitionViewer,
|
|
296
|
+
creativeSlugFromCanvasPath,
|
|
297
|
+
finalOutputLabelsFromCanvas,
|
|
298
|
+
nodeOutputsToRecord,
|
|
299
|
+
finalFiles,
|
|
300
|
+
buildRunRecord,
|
|
301
|
+
buildInitialRunRecord,
|
|
302
|
+
buildFailedRunRecord
|
|
303
|
+
};
|
|
304
|
+
//# sourceMappingURL=chunk-42DF5DF3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/canvas/creative-definition.ts","../src/commands/canvas/run-record.ts"],"sourcesContent":["import { parseDocument } from \"yaml\";\nimport { AWARENESS_VALUES, type ViewerProfile } from \"../../viewer-profile.ts\";\nimport { languageTag } from \"../../language.ts\";\n\n// The scaffold's `creatives` collection (src/collections/creatives.ts) accepts exactly these;\n// `creative-definition.parity.test.ts` fails when the two lists drift. An unknown platform or\n// format degrades to the default rather than emitting a definition the collection would reject.\nexport const PLATFORM_VALUES = [\"meta\", \"google\", \"linkedin\", \"tiktok\", \"youtube\", \"x\", \"other\"] as const;\nexport const FORMAT_VALUES = [\"1:1\", \"4:5\", \"9:16\", \"16:9\", \"1.91:1\"] as const;\nexport const CREATIVE_KIND_VALUES = [\"static\", \"video\"] as const;\nexport const CREATIVE_STATUS_VALUES = [\"draft\", \"rendered\", \"published\", \"archived\"] as const;\nexport const SOURCE_KIND_VALUES = [\"image\", \"video\"] as const;\nexport const EVIDENCE_VALUES = [\"observed\", \"interpreted\", \"hypothesized\", \"generated\"] as const;\n\n/** Frontmatter + body for a creative's `_definition.md`, mirroring the scaffold `creatives` collection schema. */\nexport type CreativeSourceKind = (typeof SOURCE_KIND_VALUES)[number];\n\nexport type CreativeDefinitionInput = {\n title: string;\n kind: (typeof CREATIVE_KIND_VALUES)[number];\n platform: string;\n formats: string[];\n status?: (typeof CREATIVE_STATUS_VALUES)[number];\n sourceReferenceUrl?: string;\n sourceAdvertiser?: string;\n /** The library ad it adapted (`baker winning-ads` ids): what `baker_uses` in reference search counts. */\n sourceAdId?: string;\n sourcePlatform?: string;\n sourceAdvertiserId?: string;\n sourceKind?: CreativeSourceKind;\n /** Repo-relative path to the committed source asset (e.g. \"references/original.jpg\"). */\n sourcePath?: string;\n /** The Meta ad set the ad is made for (`baker ads meta adsets`). */\n targetAdSet?: string;\n /** Who that ad set reaches (`baker ads meta adsets --audience`), or the viewer read from the Knowledge. */\n viewer?: ViewerProfile;\n description?: string;\n};\n\n/** Title-case a slug: \"factorial-hr-4x5\" -> \"Factorial Hr 4x5\". Falls back to the slug when empty. */\nexport function titleFromSlug(slug: string): string {\n const title = slug\n .split(\"-\")\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n return title || slug;\n}\n\n/** Coerce a platform flag to a collection-valid value (default \"meta\"). */\nexport function resolvePlatform(platform: string | undefined): string {\n const value = platform?.trim();\n return value && (PLATFORM_VALUES as readonly string[]).includes(value) ? value : \"meta\";\n}\n\n/** A single-format array from the resolved aspect ratio (default [\"4:5\"] when unknown). */\nexport function resolveFormats(aspect: string | undefined): string[] {\n const value = aspect?.trim();\n return value && (FORMAT_VALUES as readonly string[]).includes(value) ? [value] : [\"4:5\"];\n}\n\n/** A deduped list of collection-valid formats (default [\"4:5\"] when none are recognized). */\nexport function resolveFormatList(formats: readonly string[]): string[] {\n const valid = [...new Set(formats.map((f) => f.trim()))].filter((f) =>\n (FORMAT_VALUES as readonly string[]).includes(f),\n );\n return valid.length > 0 ? valid : [\"4:5\"];\n}\n\n/** Best-effort human summary from an image_describe blueprint's ad_intent (for the definition body). */\nexport function describeBlueprintIntent(blueprint: unknown): string | undefined {\n const intent = (blueprint as { ad_intent?: unknown } | null)?.ad_intent;\n if (typeof intent === \"string\" && intent.trim()) return intent.trim();\n if (intent && typeof intent === \"object\") {\n const summary = (intent as { summary?: unknown }).summary ?? (intent as { feeling?: unknown }).feeling;\n if (typeof summary === \"string\" && summary.trim()) return summary.trim();\n }\n return undefined;\n}\n\n// Double-quoted YAML scalar via JSON.stringify — valid YAML that survives colons, quotes, and unicode.\nfunction yamlScalar(value: string): string {\n return JSON.stringify(value);\n}\n\n/** Render `_definition.md` (YAML frontmatter + body) for a creative. */\nexport function buildCreativeDefinition(input: CreativeDefinitionInput): string {\n const lines = [\"---\", `title: ${yamlScalar(input.title)}`, `kind: ${input.kind}`, `platform: ${input.platform}`];\n lines.push(`formats: [${input.formats.map(yamlScalar).join(\", \")}]`);\n lines.push(`status: ${input.status ?? \"draft\"}`);\n if (input.sourceReferenceUrl) lines.push(`sourceReferenceUrl: ${yamlScalar(input.sourceReferenceUrl)}`);\n if (input.sourceAdvertiser) lines.push(`sourceAdvertiser: ${yamlScalar(input.sourceAdvertiser)}`);\n if (input.sourceAdvertiserId) lines.push(`sourceAdvertiserId: ${yamlScalar(input.sourceAdvertiserId)}`);\n if (input.sourceAdId) lines.push(`sourceAdId: ${yamlScalar(input.sourceAdId)}`);\n if (input.sourcePlatform) lines.push(`sourcePlatform: ${input.sourcePlatform}`);\n if (input.sourceKind) lines.push(`sourceKind: ${input.sourceKind}`);\n if (input.sourcePath) lines.push(`sourcePath: ${yamlScalar(input.sourcePath)}`);\n if (input.targetAdSet) lines.push(`targetAdSet: ${yamlScalar(input.targetAdSet)}`);\n // A JSON object is a YAML flow mapping: one line, and every string in it quoted.\n if (input.viewer) lines.push(`viewer: ${JSON.stringify(input.viewer)}`);\n lines.push(\"---\", \"\");\n lines.push(input.description?.trim() || `${input.title} — canvas-built ${input.kind} ad for ${input.platform}.`);\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n/** The library ids a `_definition.md` names, as `DefinitionSourceFields`. */\nexport type DefinitionSourceFields = {\n sourceAdId?: string;\n sourcePlatform?: string;\n sourceAdvertiserId?: string;\n};\n\nconst SOURCE_FIELD_KEYS = [\"sourceAdId\", \"sourcePlatform\", \"sourceAdvertiserId\"] as const;\n\n/**\n * Read the library ids back out of a `_definition.md`, so a sync after the agent edited the\n * file still carries them. Tolerant: no frontmatter, a mid-edit parse error, or a non-string\n * value yields nothing for that field rather than a failed sync.\n */\nexport function parseDefinitionSourceFields(raw: string): DefinitionSourceFields {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?\\r?\\n)?---/);\n if (!match) return {};\n const doc = parseDocument(match[1] ?? \"\");\n if (doc.errors.length > 0) return {};\n const fields: DefinitionSourceFields = {};\n for (const key of SOURCE_FIELD_KEYS) {\n const value = doc.get(key);\n if (typeof value === \"string\" && value.trim()) fields[key] = value.trim();\n }\n return fields;\n}\n\n/** Why the creative exists, as a `_definition.md` states it (its `idea` sent as `ideaSlug`). */\nexport type DefinitionStrategyFields = {\n ideaSlug?: string;\n message?: string;\n evidence?: (typeof EVIDENCE_VALUES)[number];\n angle?: string;\n persona?: string;\n awareness?: (typeof AWARENESS_VALUES)[number];\n hypothesis?: string;\n /** The lead ad of the series this creative is one of (`series`): its picture is the lead's with other words. */\n seriesLead?: string;\n /** The language its words are in (`language`), as a canonical BCP-47 tag (`es-MX`): a translation's. */\n language?: string;\n};\n\nfunction oneOf<T extends string>(values: readonly T[], value: string | undefined): T | undefined {\n return values.find((allowed) => allowed === value);\n}\n\n/**\n * Read the creative's strategy back out of a `_definition.md`, so the dashboard holds it from the\n * first sync rather than from Publish. Tolerant like `parseDefinitionSourceFields`; an `evidence`\n * or `awareness` the collection would reject is dropped rather than sent.\n */\nexport function parseDefinitionStrategyFields(raw: string): DefinitionStrategyFields {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?\\r?\\n)?---/);\n if (!match) return {};\n const doc = parseDocument(match[1] ?? \"\");\n if (doc.errors.length > 0) return {};\n const text = (key: string): string | undefined => {\n const value = doc.get(key);\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n };\n const ideaSlug = text(\"idea\");\n const message = text(\"message\");\n const evidence = oneOf(EVIDENCE_VALUES, text(\"evidence\"));\n const angle = text(\"angle\");\n const persona = text(\"persona\");\n const awareness = oneOf(AWARENESS_VALUES, text(\"awareness\"));\n const hypothesis = text(\"hypothesis\");\n const seriesLead = text(\"series\");\n const language = languageTag(text(\"language\") ?? \"\");\n return {\n ...(seriesLead ? { seriesLead } : {}),\n ...(language ? { language } : {}),\n ...(ideaSlug ? { ideaSlug } : {}),\n ...(message ? { message } : {}),\n ...(evidence ? { evidence } : {}),\n ...(angle ? { angle } : {}),\n ...(persona ? { persona } : {}),\n ...(awareness ? { awareness } : {}),\n ...(hypothesis ? { hypothesis } : {}),\n };\n}\n\n/** Where a definition places its creative in a series: null for a field it does not name. */\nexport type DefinitionSeriesPlace = { seriesLead: string | null; language: string | null };\n\n/**\n * The series lead and language a `_definition.md` names, each null when it names none, so a\n * sync can tell the backend the creative left its series. Null when the front matter cannot be\n * read (none, or mid-edit invalid YAML): the sync then says nothing and the backend keeps what it has.\n */\nexport function parseDefinitionSeriesPlace(raw: string): DefinitionSeriesPlace | null {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?\\r?\\n)?---/);\n if (!match || parseDocument(match[1] ?? \"\").errors.length > 0) return null;\n const { seriesLead, language } = parseDefinitionStrategyFields(raw);\n return { seriesLead: seriesLead ?? null, language: language ?? null };\n}\n\n/** Who a `_definition.md` says the ad is for: its `targetAdSet` and its recorded `viewer`, unchecked. */\nexport type DefinitionViewerFields = { targetAdSet?: string; viewer?: unknown };\n\n/** Read `targetAdSet` and `viewer` back out of a `_definition.md`; tolerant like `parseDefinitionSourceFields`. */\nexport function parseDefinitionViewerFields(raw: string): DefinitionViewerFields {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?\\r?\\n)?---/);\n if (!match) return {};\n const doc = parseDocument(match[1] ?? \"\");\n if (doc.errors.length > 0) return {};\n const data = doc.toJS() as { targetAdSet?: unknown; viewer?: unknown } | null;\n const adSet = data?.targetAdSet;\n const targetAdSet = typeof adSet === \"string\" || typeof adSet === \"number\" ? String(adSet).trim() : \"\";\n return {\n ...(targetAdSet ? { targetAdSet } : {}),\n ...(data?.viewer !== undefined ? { viewer: data.viewer } : {}),\n };\n}\n\n/**\n * Record the ad set an ad is for and the viewer it reaches in an existing `_definition.md`,\n * keeping every other field and the body. A file without frontmatter, or one mid-edit, is\n * returned as it is: the viewer is then read again from the ad set on the next run.\n */\nexport function setDefinitionViewer(raw: string, fields: { targetAdSet?: string; viewer?: ViewerProfile }): string {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?\\r?\\n)?---/);\n if (!match) return raw;\n const doc = parseDocument(match[1] ?? \"\");\n if (doc.errors.length > 0) return raw;\n if (fields.targetAdSet) doc.set(\"targetAdSet\", fields.targetAdSet);\n if (fields.viewer) doc.set(\"viewer\", doc.createNode(fields.viewer, { flow: true }));\n return `---\\n${doc.toString()}---${raw.slice(match[0].length)}`;\n}\n","import path from \"node:path\";\nimport type { CanvasRunVerdict } from \"@baker/api\";\nimport type { NodeRunRecord, RunResult } from \"../../engine/engine/executor.ts\";\nimport { parseRefExpr } from \"../../engine/schema/canvas.ts\";\nimport { collectAssetRefLikes, isPersistedAssetRef } from \"../../engine/storage/remote-cache-store.ts\";\n\n// Mirrors of the backend intake caps (canvas/runRecords.ts) so an in-bounds\n// payload is sent even for pathological runs; the server re-caps defensively.\nconst MAX_RUN_NODES = 200;\nconst MAX_OUTPUTS_PER_NODE = 10;\nconst MAX_FINAL_OUTPUTS = 10;\n\nexport type RunRecordOutput = {\n slot: string;\n /** Variant identity from the collect terminal (branch/scene name) — slot stays the stable key. */\n label?: string;\n kind: \"image\" | \"video\" | \"audio\" | \"json\" | \"text\" | \"font\";\n sha256: string;\n url: string;\n mime: string;\n width?: number;\n height?: number;\n durationMs?: number;\n};\n\n/** Labels for a collect-terminated canvas: the collector's node id + one label per collected image. */\nexport type FinalOutputLabels = { nodeId: string; labels: (string | undefined)[] };\n\nexport type RunNodeStatus = \"pending\" | \"running\" | \"completed\" | \"failed\";\n\nexport type RunRecordNode = {\n nodeId: string;\n nodeType: string;\n cached: boolean;\n credits: number;\n durationMs: number;\n outputs: RunRecordOutput[];\n /** Upstream node ids ($ref edges) — lets the dashboard render the workflow graph. */\n deps?: string[];\n status?: RunNodeStatus;\n /** Compact params excerpt (prompt text preferred) for graph-node legibility. */\n paramsPreview?: string;\n /** Why this node failed — the real upstream status/provider — set only on `status: \"failed\"`. */\n error?: RunNodeError;\n /** The node's job, from its `tags.role` (e.g. `static_variants`), so readers never parse node ids. */\n role?: string;\n};\n\n/** Display-ready per-node failure detail. Mirrors the engine's `NodeFailureDetail`. */\nexport type RunNodeError = {\n message: string;\n code?: string;\n provider?: string;\n retryable?: boolean;\n};\n\n/** Run attribution stamped on every record post (progress, terminal, initial). */\nexport type RunRecordMeta = {\n creativeSlug?: string;\n canvasPath?: string;\n canvasSha?: string;\n /** Content sha of the rendered source (canvas.json + prompt.json) — powers the dashboard staleness signal. */\n sourceSha?: string;\n chatId?: string;\n /** R2 manifest of the executed canvas + its local file refs — first-write-wins server-side. */\n canvasSnapshotUrl?: string;\n /** R2 copy of the graph this run executes (every node's declaration): what a correction elsewhere grows on. */\n graphUrl?: string;\n /** What the render review found, so it outlives the terminal it was printed to. */\n review?: { severity: \"blocking\" | \"warning\"; what: string; scene?: string }[];\n /**\n * What the review's own model calls cost, as the gateway reported them.\n *\n * The review calls OpenRouter from the Runtime — that is where the finished video is,\n * and shipping 60MB through Convex to reach the same gateway would buy nothing — so\n * this record is what carries the spend back to where it is billed. `costUsd` is\n * OpenRouter's own `usage.cost`, relayed rather than computed: the sandbox never\n * prices anything, which is what makes it safe for the model id to float.\n */\n reviewUsage?: { model: string; inputTokens: number; outputTokens: number; costUsd: number }[];\n /** What the render review said (`@baker/api` CANVAS_RUN_VERDICTS), and whether the run may be shown as a version. */\n verdict?: CanvasRunVerdict;\n presentable?: boolean;\n /** An ad of a series made again from a new version of its lead: a new version of the ad, not a retry. */\n newAsk?: boolean;\n};\n\nexport type RunRecordPayload = {\n runId: string;\n /** `awaiting_approval`: stopped on purpose at a `--until` checkpoint, resumable with the same run id. */\n status: \"running\" | \"completed\" | \"failed\" | \"awaiting_approval\";\n errorMessage?: string;\n stats: { totalNodes: number; cachedNodes: number; totalCredits: number; durationMs: number };\n nodes: RunRecordNode[];\n finalOutputs?: RunRecordOutput[];\n /**\n * What the render review found, sent with the run that produced it.\n *\n * Without this the findings existed only in the CLI's stdout — visible to the agent\n * for one turn and to nobody afterwards. A check whose result leaves no trace cannot\n * be read back, compared between runs, or shown to the person the ad is for, and is\n * indistinguishable from a check that never ran.\n */\n review?: { severity: \"blocking\" | \"warning\"; what: string; scene?: string }[];\n /** Graceful-abort flush (SIGINT/SIGTERM): terminal but resumable — the backend keeps the row adoptable. */\n interrupted?: boolean;\n} & RunRecordMeta;\n\n/** Per-node plan facts (edges + params preview) captured from the engine's plan event. */\nexport type RunPlanInfo = Map<string, { deps: string[]; paramsPreview?: string; role?: string }>;\n\n// Mirrors the backend's CREATIVE_SLUG_MAX_LENGTH — an over-long slug would\n// 400 the whole run record, so attribution is dropped instead.\nconst MAX_CREATIVE_SLUG_LENGTH = 100;\n\n/**\n * A canvas under the repo convention `src/creatives/{slug}/` belongs to that\n * creative; its runs become the creative's generation history. Returns null\n * for canvases anywhere else (and for slugs the backend would reject).\n */\nexport function creativeSlugFromCanvasPath(filePath: string): string | null {\n const normalized = filePath.split(path.sep).join(\"/\");\n const match = normalized.match(/(?:^|\\/)src\\/creatives\\/([a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\\//);\n const slug = match?.[1] ?? null;\n return slug && slug.length <= MAX_CREATIVE_SLUG_LENGTH ? slug : null;\n}\n\n/**\n * Best-effort variant labels from a not-yet-validated canvas: when the declared\n * output is a `collect` node, each final inherits the node's explicit\n * `params.labels[i]`, else the producer node id parsed from the raw `$ref` it\n * collects (`$ref:gen_billboard_03.images#0` → `gen_billboard_03`). Null for\n * every other canvas shape — single-output runs stay unlabeled.\n */\nexport function finalOutputLabelsFromCanvas(parsed: unknown): FinalOutputLabels | null {\n const canvas = parsed as { nodes?: unknown; output?: { node?: unknown } } | null;\n const outputNodeId = canvas?.output?.node;\n if (typeof outputNodeId !== \"string\" || !Array.isArray(canvas?.nodes)) return null;\n const node = canvas.nodes.find((n) => (n as { id?: unknown })?.id === outputNodeId) as\n | { type?: unknown; inputs?: { images?: unknown }; params?: { labels?: unknown } }\n | undefined;\n if (node?.type !== \"collect\") return null;\n const explicit = node.params?.labels;\n if (Array.isArray(explicit) && explicit.every((l) => typeof l === \"string\")) {\n return { nodeId: outputNodeId, labels: explicit };\n }\n const images = node.inputs?.images;\n if (!Array.isArray(images)) return null;\n const labels = images.map((entry) => {\n if (typeof entry !== \"string\") return undefined;\n return parseRefExpr(entry)?.nodeId;\n });\n return { nodeId: outputNodeId, labels };\n}\n\nconst OUTPUT_KINDS = new Set([\"image\", \"video\", \"audio\", \"json\", \"text\", \"font\"]);\n\nfunction toRecordOutput(slot: string, value: unknown, label?: string): RunRecordOutput | null {\n const refs = collectAssetRefLikes(value);\n const ref = refs.length === 1 ? refs[0] : null;\n if (!ref || !isPersistedAssetRef(ref)) return null;\n const kind = typeof ref.kind === \"string\" && OUTPUT_KINDS.has(ref.kind) ? ref.kind : null;\n if (!kind) return null;\n return {\n slot,\n label,\n kind: kind as RunRecordOutput[\"kind\"],\n sha256: ref.sha256,\n url: ref.url,\n mime: ref.mime,\n width: typeof ref.width === \"number\" ? ref.width : undefined,\n height: typeof ref.height === \"number\" ? ref.height : undefined,\n durationMs: typeof ref.duration_ms === \"number\" ? ref.duration_ms : undefined,\n };\n}\n\n/**\n * Flatten one node's outputs into record entries. Single refs keep their slot\n * name; arrays become `slot#i`. Values without a persisted ref (plain JSON\n * manifests, refs whose upload failed) are dropped — every stored output must\n * be renderable from R2.\n */\nexport function nodeOutputsToRecord(\n nodeOutputs: Record<string, unknown>,\n labels?: (string | undefined)[],\n): RunRecordOutput[] {\n const out: RunRecordOutput[] = [];\n for (const [slot, value] of Object.entries(nodeOutputs)) {\n if (Array.isArray(value)) {\n value.forEach((item, i) => {\n const rec = toRecordOutput(`${slot}#${i}`, item, labels?.[i]);\n if (rec) out.push(rec);\n });\n } else {\n const rec = toRecordOutput(slot, value);\n if (rec) out.push(rec);\n }\n }\n return out.slice(0, MAX_OUTPUTS_PER_NODE);\n}\n\nfunction finalOutputsToRecord(output: unknown, labels?: (string | undefined)[]): RunRecordOutput[] {\n if (Array.isArray(output)) {\n return output\n .map((item, i) => toRecordOutput(`final#${i}`, item, labels?.[i]))\n .filter((rec): rec is RunRecordOutput => rec !== null)\n .slice(0, MAX_FINAL_OUTPUTS);\n }\n const rec = toRecordOutput(\"final\", output);\n return rec ? [rec] : [];\n}\n\n/** Each delivered size's local file, keyed by its label (or `final#i`), so the agent opens it with Read. */\nexport function finalFiles(output: unknown, labels?: (string | undefined)[]): Record<string, string> {\n const items = Array.isArray(output) ? output : [output];\n const files: Record<string, string> = {};\n items.forEach((item, i) => {\n const ref = collectAssetRefLikes(item)[0];\n if (ref && typeof ref.path === \"string\") files[labels?.[i] ?? `final#${i}`] = ref.path;\n });\n return files;\n}\n\nexport function buildRunRecord(\n result: Pick<RunResult, \"run_id\" | \"output\" | \"outputs_by_node\" | \"stats\"> & { node_runs: NodeRunRecord[] },\n meta: RunRecordMeta,\n plan?: RunPlanInfo,\n finalLabels?: FinalOutputLabels,\n): RunRecordPayload {\n const nodes = result.node_runs.slice(0, MAX_RUN_NODES).map((run): RunRecordNode => {\n const planned = plan?.get(run.node_id);\n return {\n nodeId: run.node_id,\n nodeType: run.node_type,\n cached: run.cached,\n credits: run.credits,\n durationMs: run.duration_ms,\n outputs: nodeOutputsToRecord(\n result.outputs_by_node[run.node_id] ?? {},\n run.node_id === finalLabels?.nodeId ? finalLabels.labels : undefined,\n ),\n deps: planned?.deps,\n status: plan ? \"completed\" : undefined,\n paramsPreview: planned?.paramsPreview,\n ...(planned?.role !== undefined ? { role: planned.role } : {}),\n };\n });\n const finalOutputs = finalOutputsToRecord(result.output, finalLabels?.labels);\n return {\n runId: result.run_id,\n ...meta,\n status: \"completed\",\n stats: {\n totalNodes: result.stats.total_nodes,\n cachedNodes: result.stats.cached_nodes,\n totalCredits: result.stats.total_credits,\n durationMs: result.stats.duration_ms,\n },\n nodes,\n finalOutputs: finalOutputs.length > 0 ? finalOutputs : undefined,\n // Sent whenever the review RAN, empty list included. Sending it only when there\n // were findings makes a clean render and an unreviewed one look identical in the\n // record — which is the exact ambiguity this field was added to remove: proving a\n // review had happened once meant re-running a cached canvas and reading raw JSON.\n // Only the fields the backend keeps: a static review's typed fields (`kind`) stay in the CLI.\n ...(meta.review\n ? { review: meta.review.slice(0, 40).map(({ severity, what, scene }) => ({ severity, what, ...(scene ? { scene } : {}) })) }\n : {}),\n };\n}\n\n/**\n * The empty `running` record posted BEFORE layer 1 executes. This row is the\n * Convex-side in-flight marker: the reconciliation sweep and cross-sandbox\n * resume both key off it, so unlike the fire-and-forget progress stream it is\n * posted synchronously (with retries) at run start.\n */\nexport function buildInitialRunRecord(runId: string, meta: RunRecordMeta): RunRecordPayload {\n return {\n runId,\n ...meta,\n status: \"running\",\n stats: { totalNodes: 0, cachedNodes: 0, totalCredits: 0, durationMs: 0 },\n nodes: [],\n };\n}\n\nexport function buildFailedRunRecord(runId: string, errorMessage: string, meta: RunRecordMeta): RunRecordPayload {\n return {\n runId,\n ...meta,\n status: \"failed\",\n errorMessage: errorMessage.slice(0, 2000),\n stats: { totalNodes: 0, cachedNodes: 0, totalCredits: 0, durationMs: 0 },\n nodes: [],\n };\n}\n"],"mappings":"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","names":["rec"]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiGet
|
|
3
|
+
} from "./chunk-CUL3VB4L.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-44VXKO65.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,137 @@
|
|
|
1
|
+
// src/engine/copy-tells/questions.ts
|
|
2
|
+
var ANY_LANGUAGE = "The copy may be in any language; judge the construction, not the words.";
|
|
3
|
+
var TELL_QUESTIONS = [
|
|
4
|
+
{
|
|
5
|
+
id: "rhetorical-opener",
|
|
6
|
+
question: `Does \`sentence\` open with a fake-candid pause before an ordinary claim, such as "Honestly?", "Here's the thing:", "Look,", "Let's be real", "La verdad es que", "Seamos sinceros"? A sentence that simply starts with its claim does not count. ${ANY_LANGUAGE}`,
|
|
7
|
+
threshold: 0.75
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
id: "negation-pivot",
|
|
11
|
+
question: `Is \`sentence\` built as a negative parallelism that denies a smaller framing to assert a bigger one, such as "It's not just a CRM, it's a growth engine", "Not only X but also Y", "No se trata solo de X, sino de Y", or a short "Not a tool." answered by "A partner." (\`before\` is the sentence before it, for that two-sentence form)? A plain negative fact ("No setup fee", "We don't sell your data") does not count. ${ANY_LANGUAGE}`,
|
|
12
|
+
threshold: 0.5
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: "participle-tail",
|
|
16
|
+
question: `Does \`sentence\` end with a participle or gerund phrase hung off a comma to add vague significance, such as ", ensuring nothing slips through", ", fostering growth", ", permitiendo cerrar el mes antes"? A sentence that opens with such a word does not count. ${ANY_LANGUAGE}`,
|
|
17
|
+
threshold: 0.5
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "copula-avoidance",
|
|
21
|
+
question: `Does \`sentence\` use an inflated verb where a plain "is" or "has" would do, such as "serves as", "stands as", "boasts", "se erige como", "cuenta con"? ${ANY_LANGUAGE}`,
|
|
22
|
+
threshold: 0.6
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "authority-trope",
|
|
26
|
+
question: `Does \`sentence\` claim to reveal what is "really" at stake, with a phrase like "The real question is", "At its core", "What really matters is", "The heart of the matter", "En el fondo", "Lo que realmente importa"? Candid openers ("Honestly", "To be fair"), contrasts ("not just X, but Y") and filler words are other tells and do not count here. ${ANY_LANGUAGE}`,
|
|
27
|
+
threshold: 0.5
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "signposting",
|
|
31
|
+
question: `Does \`sentence\` announce what the text is about to explain instead of saying it, such as "Let's dive in", "Here's what you need to know", "Let's break it down", "Vamos a ver c\xF3mo funciona"? Presenting the offer itself ("Here is a plan for every team size", "Aqu\xED tienes nuestras tarifas") and an assistant handing over a summary are not this. ${ANY_LANGUAGE}`,
|
|
32
|
+
threshold: 0.5
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "chat-artifact",
|
|
36
|
+
question: `Is \`sentence\` an AI assistant talking to the person who asked it for the text, pasted into the page by mistake, such as "I hope this helps!", "Let me know if you want changes", "Here is an overview of the plan", "Would you like me to", "Aqu\xED tienes el resumen"? Copy that speaks to the page's own visitor ("Here are our three plans", "Tell us what you need") does not count. ${ANY_LANGUAGE}`,
|
|
37
|
+
threshold: 0.62
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: "vague-attribution",
|
|
41
|
+
question: `Does \`sentence\` credit a claim to unnamed authorities, such as "Experts agree", "Studies show", "Research shows", "Los expertos coinciden", without naming who? ${ANY_LANGUAGE}`,
|
|
42
|
+
threshold: 0.5
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "hollow-conclusion",
|
|
46
|
+
question: `Is \`sentence\` a vague upbeat ending that asserts nothing, such as "The future looks bright", "The possibilities are endless", "El cielo es el l\xEDmite"? ${ANY_LANGUAGE}`,
|
|
47
|
+
threshold: 0.65
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "filler-phrase",
|
|
51
|
+
question: `Does \`sentence\` contain a wordy filler phrase that carries no meaning, such as "in order to", "due to the fact that", "it is worth noting that", "cabe destacar"? ${ANY_LANGUAGE}`,
|
|
52
|
+
threshold: 0.75
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "aphorism-formula",
|
|
56
|
+
question: `Is \`sentence\` an aphorism of the form "X is the <abstract noun> of Y", such as "Trust is the currency of every deal", "Data is the language of growth", "Los datos son la columna vertebral de tu negocio"? Other contrasts and slogans do not count. ${ANY_LANGUAGE}`,
|
|
57
|
+
threshold: 0.7
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "false-range",
|
|
61
|
+
question: `Does \`sentence\` use a "from X to Y" range whose two ends are not points on one scale, such as "from onboarding to retention", "from startups to enterprises", "desde la captaci\xF3n hasta la fidelizaci\xF3n"? A real range of numbers, prices or dates ("from $9 to $99") does not count. ${ANY_LANGUAGE}`,
|
|
62
|
+
threshold: 0.5
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
function tellQuestionsFor(sentence) {
|
|
66
|
+
return TELL_QUESTIONS.map((t) => ({
|
|
67
|
+
instructions: {
|
|
68
|
+
sentence: sentence.text,
|
|
69
|
+
...t.id === "negation-pivot" && sentence.before ? { before: sentence.before } : {},
|
|
70
|
+
question: t.question
|
|
71
|
+
}
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
var SAME_CLAIM_QUESTION = `\`a\` and \`b\` are two headlines of the same ad. Are they the same claim reworded, a synonym or a swapped verb apart ("Boost Your Sales Fast" and "Increase Your Sales Fast"), rather than two different claims (a price, a guarantee, a delivery time, a rating)? ${ANY_LANGUAGE}`;
|
|
75
|
+
var SAME_CLAIM_HELD = 0.5;
|
|
76
|
+
function sameClaimQuestion(a, b) {
|
|
77
|
+
return { instructions: { a, b, question: SAME_CLAIM_QUESTION } };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/engine/copy-tells/sentences.ts
|
|
81
|
+
var SENTENCES = new Intl.Segmenter(void 0, { granularity: "sentence" });
|
|
82
|
+
var WORDS = new Intl.Segmenter(void 0, { granularity: "word" });
|
|
83
|
+
function wordCount(text) {
|
|
84
|
+
let n = 0;
|
|
85
|
+
for (const s of WORDS.segment(text)) if (s.isWordLike) n++;
|
|
86
|
+
return n;
|
|
87
|
+
}
|
|
88
|
+
function rawSentences(text) {
|
|
89
|
+
return [...SENTENCES.segment(text)].map((s) => s.segment.trim()).filter(Boolean);
|
|
90
|
+
}
|
|
91
|
+
function blockSentences(block, offset) {
|
|
92
|
+
const out = [];
|
|
93
|
+
let pending = null;
|
|
94
|
+
for (const segment of SENTENCES.segment(block)) {
|
|
95
|
+
const trimmed = segment.segment.trim().replace(/\s+/g, " ");
|
|
96
|
+
if (!trimmed) continue;
|
|
97
|
+
const start = offset + segment.index + (segment.segment.length - segment.segment.trimStart().length);
|
|
98
|
+
const joined = pending ? { text: `${pending.text} ${trimmed}`, start: pending.start } : { text: trimmed, start };
|
|
99
|
+
pending = wordCount(joined.text) < 2 ? joined : null;
|
|
100
|
+
if (!pending) out.push(joined);
|
|
101
|
+
}
|
|
102
|
+
if (pending && wordCount(pending.text) > 0) out.push(pending);
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
105
|
+
var BLOCK_END = /\n[^\S\n]*\n/g;
|
|
106
|
+
function copySentences(copy) {
|
|
107
|
+
const out = [];
|
|
108
|
+
let offset = 0;
|
|
109
|
+
for (const end of [...copy.matchAll(BLOCK_END), null]) {
|
|
110
|
+
const to = end ? end.index : copy.length;
|
|
111
|
+
blockSentences(copy.slice(offset, to).replaceAll("\n", " "), offset).forEach((s, i, all) => {
|
|
112
|
+
const before = all[i - 1]?.text;
|
|
113
|
+
out.push({ ...s, ...before ? { before } : {} });
|
|
114
|
+
});
|
|
115
|
+
if (end) offset = end.index + end[0].length;
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/engine/copy-tells/patterns.ts
|
|
121
|
+
var STACCATO_MAX_WORDS = 4;
|
|
122
|
+
var STACCATO_RUN = 3;
|
|
123
|
+
var HEADLINE_SET_FLOOR = 3;
|
|
124
|
+
|
|
125
|
+
export {
|
|
126
|
+
STACCATO_MAX_WORDS,
|
|
127
|
+
STACCATO_RUN,
|
|
128
|
+
HEADLINE_SET_FLOOR,
|
|
129
|
+
TELL_QUESTIONS,
|
|
130
|
+
tellQuestionsFor,
|
|
131
|
+
SAME_CLAIM_HELD,
|
|
132
|
+
sameClaimQuestion,
|
|
133
|
+
wordCount,
|
|
134
|
+
rawSentences,
|
|
135
|
+
copySentences
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=chunk-4NZ47VXO.js.map
|