@koda-sl/baker-cli 0.450.0-dev.b454c3dd2 → 0.450.0-dev.d6701597d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -11
- package/dist/{account-XQXC7BR6.js → account-AL2ZDSR7.js} +4 -5
- package/dist/{account-XQXC7BR6.js.map → account-AL2ZDSR7.js.map} +1 -1
- package/dist/{accounts-722UY53A.js → accounts-HAFCLSR5.js} +3 -4
- package/dist/{accounts-722UY53A.js.map → accounts-HAFCLSR5.js.map} +1 -1
- package/dist/{accounts-E67BMK7T.js → accounts-O5MFO3QQ.js} +5 -6
- package/dist/{accounts-E67BMK7T.js.map → accounts-O5MFO3QQ.js.map} +1 -1
- package/dist/{actions-6TQMSVWD.js → actions-P35MEMGN.js} +18 -18
- package/dist/{add-2BEGRHUX.js → add-5GAN6CVO.js} +5 -28
- package/dist/add-5GAN6CVO.js.map +1 -0
- package/dist/{add-LEMKEOPO.js → add-6DTC6X5G.js} +2 -3
- package/dist/{add-LEMKEOPO.js.map → add-6DTC6X5G.js.map} +1 -1
- package/dist/{ads-AGYCVD62.js → ads-73PGA4YC.js} +4 -4
- package/dist/{advertisers-2VQKAYKG.js → advertisers-AE75CGVE.js} +3 -4
- package/dist/{advertisers-2VQKAYKG.js.map → advertisers-AE75CGVE.js.map} +1 -1
- package/dist/{analytics-IFELDWLL.js → analytics-FKCXIMPO.js} +20 -24
- package/dist/analytics-FKCXIMPO.js.map +1 -0
- package/dist/{analytics-OH5QEH7F.js → analytics-FPWQQGRM.js} +3 -4
- package/dist/{analytics-OH5QEH7F.js.map → analytics-FPWQQGRM.js.map} +1 -1
- package/dist/{assign-PTUJUCEL.js → assign-ABN2AQ4J.js} +3 -4
- package/dist/{assign-PTUJUCEL.js.map → assign-ABN2AQ4J.js.map} +1 -1
- package/dist/{audience-size-LRI6GJRT.js → audience-size-GNBJY35X.js} +3 -4
- package/dist/{audience-size-LRI6GJRT.js.map → audience-size-GNBJY35X.js.map} +1 -1
- package/dist/{audit-HWP7OPB7.js → audit-3VS63TBW.js} +3 -4
- package/dist/{audit-HWP7OPB7.js.map → audit-3VS63TBW.js.map} +1 -1
- package/dist/{autocomplete-J6DHU6MR.js → autocomplete-VS3XG3B7.js} +3 -4
- package/dist/{autocomplete-J6DHU6MR.js.map → autocomplete-VS3XG3B7.js.map} +1 -1
- package/dist/{avatars-467OSBD6.js → avatars-EKCKHCC3.js} +4 -4
- package/dist/{bid-pricing-EO5WLHGV.js → bid-pricing-Q72B65AY.js} +3 -4
- package/dist/{bid-pricing-EO5WLHGV.js.map → bid-pricing-Q72B65AY.js.map} +1 -1
- package/dist/{brand-YRTEPGBK.js → brand-C6PFGGQN.js} +2 -2
- package/dist/{brief-OSFJ2V7F.js → brief-YFJHQ5VQ.js} +7 -8
- package/dist/{brief-OSFJ2V7F.js.map → brief-YFJHQ5VQ.js.map} +1 -1
- package/dist/{campaign-groups-PQ6KSQJR.js → campaign-groups-KFFYQPU3.js} +8 -9
- package/dist/{campaign-groups-PQ6KSQJR.js.map → campaign-groups-KFFYQPU3.js.map} +1 -1
- package/dist/{campaign-writes-5OVLUD5E.js → campaign-writes-FHOS5XZY.js} +3 -4
- package/dist/{campaign-writes-5OVLUD5E.js.map → campaign-writes-FHOS5XZY.js.map} +1 -1
- package/dist/{campaigns-6T3NSUT2.js → campaigns-2NHWBF5C.js} +11 -12
- package/dist/{campaigns-6T3NSUT2.js.map → campaigns-2NHWBF5C.js.map} +1 -1
- package/dist/{campaigns-OYMXDGWX.js → campaigns-KZYZTXDS.js} +5 -5
- package/dist/{canvas-YQFG52IG.js → canvas-5NB27FX2.js} +13 -13
- package/dist/{capabilities-PXBKUN2G.js → capabilities-DJFTRJKS.js} +3 -4
- package/dist/{capabilities-PXBKUN2G.js.map → capabilities-DJFTRJKS.js.map} +1 -1
- package/dist/{catalog-XLXIM7IW.js → catalog-VSSY6FGI.js} +4 -4
- package/dist/{chats-UK47UE7C.js → chats-D2CSDX5Q.js} +3 -4
- package/dist/{chats-UK47UE7C.js.map → chats-D2CSDX5Q.js.map} +1 -1
- package/dist/{chunk-5ZNTADVR.js → chunk-3G3ZDLMI.js} +2 -2
- package/dist/{chunk-SJYEY5MV.js → chunk-3HJLHTWP.js} +3 -12
- package/dist/{chunk-SJYEY5MV.js.map → chunk-3HJLHTWP.js.map} +1 -1
- package/dist/{chunk-ZDMTXQ2Q.js → chunk-3IBYKLXR.js} +2 -2
- package/dist/{chunk-CWYAELVG.js → chunk-464O4MT2.js} +2 -2
- package/dist/{chunk-NA63BH7V.js → chunk-4AUMTNVB.js} +3 -3
- package/dist/{chunk-NDEE6G2J.js → chunk-4BQXAE7Z.js} +2 -2
- package/dist/{chunk-2AOE2MZQ.js → chunk-5ZDLTE5T.js} +3 -3
- package/dist/{chunk-ULG4QRTV.js → chunk-6NB47MRW.js} +2 -2
- package/dist/{chunk-24EB7EDR.js → chunk-7YCRFMXF.js} +3 -3
- package/dist/{chunk-WGUQHAJY.js → chunk-A4LOJ2VD.js} +2 -2
- package/dist/{chunk-6F7DVPOS.js → chunk-AEOSAVVL.js} +3 -3
- package/dist/{chunk-MACCF4JZ.js → chunk-CMPEUZOR.js} +22 -16
- package/dist/{chunk-MACCF4JZ.js.map → chunk-CMPEUZOR.js.map} +1 -1
- package/dist/{chunk-N4LAYIIN.js → chunk-CSYSX4D2.js} +2 -2
- package/dist/{chunk-RX2DKU3W.js → chunk-DGUNI37S.js} +2 -2
- package/dist/{chunk-QE7W555R.js → chunk-DWHIOO7E.js} +12 -163
- package/dist/chunk-DWHIOO7E.js.map +1 -0
- package/dist/{chunk-FPOGPFAG.js → chunk-EBWBG6YV.js} +51 -24
- package/dist/chunk-EBWBG6YV.js.map +1 -0
- package/dist/{chunk-NYIGXDUG.js → chunk-EDLZGTGN.js} +39 -1
- package/dist/chunk-EDLZGTGN.js.map +1 -0
- package/dist/{chunk-I3ZR655O.js → chunk-IR6D7K4H.js} +2 -2
- package/dist/{chunk-FUHN4MFY.js → chunk-JQJDXPCO.js} +2 -2
- package/dist/{chunk-7CTMH5AK.js → chunk-KAUOHQTF.js} +3 -3
- package/dist/{chunk-VYQ3QJ3C.js → chunk-KHRXPQID.js} +2 -2
- package/dist/{chunk-6Y7ZBENQ.js → chunk-LECGCWT5.js} +6 -6
- package/dist/{chunk-5WCSKQ7Z.js → chunk-LZ73CZGP.js} +6 -6
- package/dist/{chunk-R25YLW6H.js → chunk-MELOSESI.js} +2 -2
- package/dist/{chunk-DCRPXOJJ.js → chunk-MXYBTMKB.js} +2 -2
- package/dist/{chunk-54C6YDGJ.js → chunk-NPY4QUMQ.js} +2 -2
- package/dist/{chunk-LYQJ4PZW.js → chunk-OQ6663F4.js} +5 -5
- package/dist/{chunk-H3427GPU.js → chunk-OZRUJVIQ.js} +2 -2
- package/dist/{chunk-KMKEYI37.js → chunk-Q2V6E6SL.js} +3 -3
- package/dist/{chunk-VL43TNIP.js → chunk-QRP3PXWN.js} +2 -2
- package/dist/{chunk-HDLYPC6K.js → chunk-RPUSTYHL.js} +3 -5
- package/dist/{chunk-HDLYPC6K.js.map → chunk-RPUSTYHL.js.map} +1 -1
- package/dist/{chunk-C46GUI2S.js → chunk-RZBEK2VE.js} +2 -2
- package/dist/{chunk-2VPBIT65.js → chunk-S3A3YOKO.js} +8 -8
- package/dist/{chunk-FYGR3I2A.js → chunk-S77PZVYM.js} +3 -3
- package/dist/{chunk-VLMBTPXU.js → chunk-SHL7LOC3.js} +3 -3
- package/dist/{chunk-HR6IWNKE.js → chunk-SSJK7FEV.js} +1140 -1196
- package/dist/chunk-SSJK7FEV.js.map +1 -0
- package/dist/{chunk-KS2QY6MK.js → chunk-W3ZHJJVT.js} +4 -4
- package/dist/{chunk-7EPXVICM.js → chunk-XF4JUKVF.js} +5 -38
- package/dist/chunk-XF4JUKVF.js.map +1 -0
- package/dist/{chunk-RL5CP7N6.js → chunk-Y6O7EWYY.js} +5 -5
- package/dist/{chunk-6NY2GPR4.js → chunk-Y6ZQXUZ7.js} +3 -3
- package/dist/{chunk-HROZYQ5H.js → chunk-YRQYA2LR.js} +5 -63
- package/dist/chunk-YRQYA2LR.js.map +1 -0
- package/dist/{chunk-ASI4P6X2.js → chunk-YUCLMOEG.js} +6 -6
- package/dist/chunk-YUCLMOEG.js.map +1 -0
- package/dist/{chunk-WKQG6TER.js → chunk-ZEYEWPK6.js} +2 -2
- package/dist/{claim-W6G6VEG5.js → claim-FZ5OQLMU.js} +3 -4
- package/dist/{claim-W6G6VEG5.js.map → claim-FZ5OQLMU.js.map} +1 -1
- package/dist/cli.js +30 -30
- package/dist/{companies-TS6KBATJ.js → companies-DNI634RC.js} +3 -4
- package/dist/{companies-TS6KBATJ.js.map → companies-DNI634RC.js.map} +1 -1
- package/dist/{complete-LYR2HMQU.js → complete-2FZMGJV5.js} +3 -4
- package/dist/{complete-LYR2HMQU.js.map → complete-2FZMGJV5.js.map} +1 -1
- package/dist/{connect-FCXNVTXG.js → connect-QCOGEPP4.js} +6 -13
- package/dist/{conversation-6ZJGPCXM.js → conversation-6IOGV7B7.js} +3 -4
- package/dist/{conversation-6ZJGPCXM.js.map → conversation-6IOGV7B7.js.map} +1 -1
- package/dist/{conversions-UHB55MMQ.js → conversions-4SRZPBBX.js} +7 -8
- package/dist/{conversions-UHB55MMQ.js.map → conversions-4SRZPBBX.js.map} +1 -1
- package/dist/{create-EX6OWLNM.js → create-BJNMO6HT.js} +2 -3
- package/dist/{create-EX6OWLNM.js.map → create-BJNMO6HT.js.map} +1 -1
- package/dist/{create-JFSK4BOP.js → create-FX4OJ2XF.js} +3 -4
- package/dist/{create-JFSK4BOP.js.map → create-FX4OJ2XF.js.map} +1 -1
- package/dist/{create-JCA7JPLP.js → create-RM7HV77Y.js} +3 -4
- package/dist/{create-JCA7JPLP.js.map → create-RM7HV77Y.js.map} +1 -1
- package/dist/{create-WU22YYU2.js → create-VXM34ZWH.js} +3 -4
- package/dist/{create-WU22YYU2.js.map → create-VXM34ZWH.js.map} +1 -1
- package/dist/{creatives-FXUQ5WSD.js → creatives-B5NTXPUB.js} +10 -10
- package/dist/{creatives-KGXUOYPE.js → creatives-JSWBFQ5R.js} +8 -9
- package/dist/{creatives-KGXUOYPE.js.map → creatives-JSWBFQ5R.js.map} +1 -1
- package/dist/{credentials-MJC7PGKR.js → credentials-C33K6XCJ.js} +3 -4
- package/dist/{credentials-MJC7PGKR.js.map → credentials-C33K6XCJ.js.map} +1 -1
- package/dist/{critique-GS5VV5ZC.js → critique-4V5SKH7C.js} +6 -7
- package/dist/{critique-GS5VV5ZC.js.map → critique-4V5SKH7C.js.map} +1 -1
- package/dist/{critique-TPHR27KH.js → critique-ZS4ON3SU.js} +3 -4
- package/dist/{critique-TPHR27KH.js.map → critique-ZS4ON3SU.js.map} +1 -1
- package/dist/{crm-VK44O3ED.js → crm-52ROSWH5.js} +4 -5
- package/dist/{crm-VK44O3ED.js.map → crm-52ROSWH5.js.map} +1 -1
- package/dist/{crm-AVCM5D4G.js → crm-R5IXIFIV.js} +4 -5
- package/dist/{crm-AVCM5D4G.js.map → crm-R5IXIFIV.js.map} +1 -1
- package/dist/{customers-XH2DMTFH.js → customers-A36LOZOB.js} +5 -6
- package/dist/{delete-WI5E3DR3.js → delete-AIGE4Y4H.js} +3 -4
- package/dist/{delete-WI5E3DR3.js.map → delete-AIGE4Y4H.js.map} +1 -1
- package/dist/{delete-KRH2YMSZ.js → delete-HGHXY24R.js} +3 -4
- package/dist/{delete-KRH2YMSZ.js.map → delete-HGHXY24R.js.map} +1 -1
- package/dist/{delete-E3R3TKIL.js → delete-M2GDLPYN.js} +2 -3
- package/dist/{delete-E3R3TKIL.js.map → delete-M2GDLPYN.js.map} +1 -1
- package/dist/{demographics-XV5PBA77.js → demographics-NTWB2IMG.js} +3 -4
- package/dist/{demographics-XV5PBA77.js.map → demographics-NTWB2IMG.js.map} +1 -1
- package/dist/{discard-HTQUUHJR.js → discard-2WWQG6OU.js} +3 -4
- package/dist/{discard-HTQUUHJR.js.map → discard-2WWQG6OU.js.map} +1 -1
- package/dist/{domain-RECGZXJB.js → domain-Y2LT6JLT.js} +3 -4
- package/dist/{domain-RECGZXJB.js.map → domain-Y2LT6JLT.js.map} +1 -1
- package/dist/{draft-Q546QPPU.js → draft-EJXNNJ3Y.js} +4 -5
- package/dist/{draft-Q546QPPU.js.map → draft-EJXNNJ3Y.js.map} +1 -1
- package/dist/{draft-PVTX6QT6.js → draft-FJ7WHIXW.js} +3 -4
- package/dist/{draft-PVTX6QT6.js.map → draft-FJ7WHIXW.js.map} +1 -1
- package/dist/{draft-2IBSJEKC.js → draft-SLHAKJ2A.js} +3 -4
- package/dist/{draft-2IBSJEKC.js.map → draft-SLHAKJ2A.js.map} +1 -1
- package/dist/engine/index.js +3 -3
- package/dist/{facets-7EVPJMKS.js → facets-U7AQC4H6.js} +3 -4
- package/dist/{facets-7EVPJMKS.js.map → facets-U7AQC4H6.js.map} +1 -1
- package/dist/{feedback-EIZKS4JU.js → feedback-OLTCHE6C.js} +2 -2
- package/dist/{feedback-record-TKO54BOE.js → feedback-record-7WZ4H7EP.js} +8 -9
- package/dist/{feedback-record-TKO54BOE.js.map → feedback-record-7WZ4H7EP.js.map} +1 -1
- package/dist/{fetch-4BY6HYUM.js → fetch-W7NULDEO.js} +3 -4
- package/dist/{fetch-4BY6HYUM.js.map → fetch-W7NULDEO.js.map} +1 -1
- package/dist/{find-FRRHAPWX.js → find-OTDIX6V4.js} +4 -4
- package/dist/{flows-KTFAML22.js → flows-KABCBS3S.js} +17 -21
- package/dist/flows-KABCBS3S.js.map +1 -0
- package/dist/{fonts-MXR3ZKDX.js → fonts-EMMX3KII.js} +5 -6
- package/dist/{forecast-3QTJYVND.js → forecast-GNODEIIC.js} +3 -4
- package/dist/{forecast-3QTJYVND.js.map → forecast-GNODEIIC.js.map} +1 -1
- package/dist/{funnel-I6XIAEHG.js → funnel-AAX27NH4.js} +455 -11
- package/dist/funnel-AAX27NH4.js.map +1 -0
- package/dist/{ga4-DV2AXCSL.js → ga4-UDQ2HA2J.js} +1 -1
- package/dist/{get-5PKNKJ5S.js → get-QEYJRLV3.js} +4 -7
- package/dist/get-QEYJRLV3.js.map +1 -0
- package/dist/{get-72YPHJGV.js → get-RTVUZM6E.js} +3 -4
- package/dist/{get-72YPHJGV.js.map → get-RTVUZM6E.js.map} +1 -1
- package/dist/{google-QYYYSSXI.js → google-KTO3PLEU.js} +5 -5
- package/dist/{google-6OGZX47I.js → google-M7KEXVK5.js} +2 -2
- package/dist/{google-ads-QGMQKZQD.js → google-ads-OK6IG3UV.js} +3 -4
- package/dist/{google-ads-QGMQKZQD.js.map → google-ads-OK6IG3UV.js.map} +1 -1
- package/dist/{gsc-TAKOF7J5.js → gsc-P3QYGDV2.js} +1 -1
- package/dist/{history-6AVQX2OQ.js → history-PQUJKK26.js} +3 -4
- package/dist/{history-6AVQX2OQ.js.map → history-PQUJKK26.js.map} +1 -1
- package/dist/{hubspot-SVEMFK5S.js → hubspot-Y77VLY6Y.js} +8 -9
- package/dist/{hubspot-SVEMFK5S.js.map → hubspot-Y77VLY6Y.js.map} +1 -1
- package/dist/{icon-L4RSS6PZ.js → icon-I43F77FV.js} +4 -4
- package/dist/{ideas-NFOW3HKJ.js → ideas-MIDU7YOA.js} +2 -3
- package/dist/{images-2EFFUNNV.js → images-S254MS6O.js} +9 -9
- package/dist/{ingest-2SO62RRI.js → ingest-J4I3HKM3.js} +2 -3
- package/dist/{ingest-2SO62RRI.js.map → ingest-J4I3HKM3.js.map} +1 -1
- package/dist/{ingest-2EIKN4QC.js → ingest-YV2NLDBE.js} +3 -4
- package/dist/{inspect-4OOS4APT.js → inspect-Q5NHBBHX.js} +3 -4
- package/dist/{inspect-4OOS4APT.js.map → inspect-Q5NHBBHX.js.map} +1 -1
- package/dist/{inspiration-S3DU4CMQ.js → inspiration-P265QJ2H.js} +1 -1
- package/dist/{keyword-metrics-SF4CSNZ2.js → keyword-metrics-PDY4ZXSP.js} +3 -4
- package/dist/{keyword-metrics-SF4CSNZ2.js.map → keyword-metrics-PDY4ZXSP.js.map} +1 -1
- package/dist/{keywords-for-site-WDAOPNKC.js → keywords-for-site-GALSCV77.js} +3 -4
- package/dist/{keywords-for-site-WDAOPNKC.js.map → keywords-for-site-GALSCV77.js.map} +1 -1
- package/dist/{landing-2ZB46LXH.js → landing-CJYGWCK4.js} +3 -3
- package/dist/{leads-A4W5KTWB.js → leads-PHKG6CP3.js} +3 -4
- package/dist/{leads-A4W5KTWB.js.map → leads-PHKG6CP3.js.map} +1 -1
- package/dist/{learn-IPULBCOD.js → learn-FUQSY7DN.js} +4 -5
- package/dist/{learn-IPULBCOD.js.map → learn-FUQSY7DN.js.map} +1 -1
- package/dist/{line-item-writes-EMYSOJKM.js → line-item-writes-E6MZPIZZ.js} +3 -4
- package/dist/{line-item-writes-EMYSOJKM.js.map → line-item-writes-E6MZPIZZ.js.map} +1 -1
- package/dist/{line-items-5NECXUZT.js → line-items-7ZGIKEF2.js} +5 -5
- package/dist/{link-CI45HWFN.js → link-QYAW6A2W.js} +3 -4
- package/dist/{link-CI45HWFN.js.map → link-QYAW6A2W.js.map} +1 -1
- package/dist/{linkedin-B7SYR75X.js → linkedin-FFSDSGGS.js} +26 -27
- package/dist/{linkedin-B7SYR75X.js.map → linkedin-FFSDSGGS.js.map} +1 -1
- package/dist/{list-ZBT3EBVZ.js → list-5IC6KIKO.js} +3 -4
- package/dist/{list-ZBT3EBVZ.js.map → list-5IC6KIKO.js.map} +1 -1
- package/dist/{list-2BARXOT5.js → list-NVQC5SNY.js} +2 -3
- package/dist/{list-2BARXOT5.js.map → list-NVQC5SNY.js.map} +1 -1
- package/dist/{list-BIEVLEHS.js → list-SAV3LQHY.js} +3 -4
- package/dist/{list-BIEVLEHS.js.map → list-SAV3LQHY.js.map} +1 -1
- package/dist/{log-C23OOAJZ.js → log-XZPVOALD.js} +3 -4
- package/dist/{log-C23OOAJZ.js.map → log-XZPVOALD.js.map} +1 -1
- package/dist/{logo-Q5D7PZY6.js → logo-2IP663QO.js} +3 -3
- package/dist/{lookup-ETWY47F7.js → lookup-XK45W2SH.js} +5 -6
- package/dist/{make-TPKKJXGL.js → make-BMWRKIIY.js} +20 -18
- package/dist/{make-TPKKJXGL.js.map → make-BMWRKIIY.js.map} +1 -1
- package/dist/{map-SYZMPHLL.js → map-4J5WIWIG.js} +4 -5
- package/dist/{map-SYZMPHLL.js.map → map-4J5WIWIG.js.map} +1 -1
- package/dist/{mcp-6FQBVJ6F.js → mcp-XXD7ZQCP.js} +2 -3
- package/dist/{mcp-6FQBVJ6F.js.map → mcp-XXD7ZQCP.js.map} +1 -1
- package/dist/{media-sources-ZXHEEP6T.js → media-sources-O6ZRUA3N.js} +2 -2
- package/dist/{members-UDY4OOJW.js → members-D5ZYLS4Y.js} +3 -4
- package/dist/{members-UDY4OOJW.js.map → members-D5ZYLS4Y.js.map} +1 -1
- package/dist/{normalize-DAKHYS3V.js → normalize-PCNC6E2N.js} +3 -7
- package/dist/{normalize-DAKHYS3V.js.map → normalize-PCNC6E2N.js.map} +1 -1
- package/dist/{options-QL3ULED5.js → options-MQ65VEVD.js} +6 -7
- package/dist/{options-QL3ULED5.js.map → options-MQ65VEVD.js.map} +1 -1
- package/dist/{performance-UF5VTY2U.js → performance-6QW2KEEQ.js} +4 -5
- package/dist/{promoted-tweet-writes-7HGESJ46.js → promoted-tweet-writes-JPLHY3GM.js} +3 -4
- package/dist/{promoted-tweet-writes-7HGESJ46.js.map → promoted-tweet-writes-JPLHY3GM.js.map} +1 -1
- package/dist/{promoted-tweets-LZKS5JIF.js → promoted-tweets-SURKMHFI.js} +3 -3
- package/dist/{publish-NPD3SMZL.js → publish-HCQ6MXLB.js} +3 -4
- package/dist/{publish-NPD3SMZL.js.map → publish-HCQ6MXLB.js.map} +1 -1
- package/dist/{reddit-NU2N3LZD.js → reddit-GIP3ADMS.js} +4 -5
- package/dist/{refresh-EBVJ2C6L.js → refresh-UXQSLCR3.js} +2 -3
- package/dist/{refresh-EBVJ2C6L.js.map → refresh-UXQSLCR3.js.map} +1 -1
- package/dist/{release-V43YB2PY.js → release-5KVLXNP6.js} +3 -4
- package/dist/{release-V43YB2PY.js.map → release-5KVLXNP6.js.map} +1 -1
- package/dist/{remove-QPSWLFI4.js → remove-6FIVKCJI.js} +2 -3
- package/dist/{remove-QPSWLFI4.js.map → remove-6FIVKCJI.js.map} +1 -1
- package/dist/{reopen-GQ66NMWF.js → reopen-YM5LNOLB.js} +3 -4
- package/dist/{reopen-GQ66NMWF.js.map → reopen-YM5LNOLB.js.map} +1 -1
- package/dist/{rerun-PZK275DY.js → rerun-6XZG7BGK.js} +17 -18
- package/dist/{rerun-PZK275DY.js.map → rerun-6XZG7BGK.js.map} +1 -1
- package/dist/{research-FMM6AWZC.js → research-2BLEISBG.js} +10 -10
- package/dist/{research-GEOCUBXB.js → research-YOGE7GT2.js} +2 -3
- package/dist/{research-GEOCUBXB.js.map → research-YOGE7GT2.js.map} +1 -1
- package/dist/{reset-REXJ6AUK.js → reset-C4UHQ3EU.js} +2 -3
- package/dist/{reset-REXJ6AUK.js.map → reset-C4UHQ3EU.js.map} +1 -1
- package/dist/{reset-Y72IVESB.js → reset-OLVB6AE6.js} +2 -3
- package/dist/{reset-Y72IVESB.js.map → reset-OLVB6AE6.js.map} +1 -1
- package/dist/{resolve-OGX7C4TV.js → resolve-XYH2GDAE.js} +3 -4
- package/dist/{resolve-OGX7C4TV.js.map → resolve-XYH2GDAE.js.map} +1 -1
- package/dist/{retry-TCUBBFR5.js → retry-726GKI6V.js} +2 -3
- package/dist/{retry-TCUBBFR5.js.map → retry-726GKI6V.js.map} +1 -1
- package/dist/{retry-CD6JAQ3F.js → retry-7EELDEQP.js} +2 -3
- package/dist/{retry-CD6JAQ3F.js.map → retry-7EELDEQP.js.map} +1 -1
- package/dist/{run-EUO34T2J.js → run-MMEDKJDB.js} +17 -18
- package/dist/{run-A5ZDXTOI.js → run-P4KR2MXC.js} +3 -4
- package/dist/{run-A5ZDXTOI.js.map → run-P4KR2MXC.js.map} +1 -1
- package/dist/{scaffold-ad-SW2HEWM3.js → scaffold-ad-PBTEWDAC.js} +12 -13
- package/dist/{scaffold-ad-SW2HEWM3.js.map → scaffold-ad-PBTEWDAC.js.map} +1 -1
- package/dist/{scaffold-static-ad-ECTJL54Y.js → scaffold-static-ad-RM4M4X5U.js} +36 -37
- package/dist/scaffold-static-ad-RM4M4X5U.js.map +1 -0
- package/dist/{scaffold-video-EI7U7RBK.js → scaffold-video-O2TTKZIE.js} +11 -12
- package/dist/{scaffold-video-EI7U7RBK.js.map → scaffold-video-O2TTKZIE.js.map} +1 -1
- package/dist/{schedule-S5YZJZ5U.js → schedule-RDK4GEPI.js} +2 -3
- package/dist/{schedule-S5YZJZ5U.js.map → schedule-RDK4GEPI.js.map} +1 -1
- package/dist/{scheduled-agents-N4LJRM4C.js → scheduled-agents-6U44QE76.js} +11 -11
- package/dist/{schema-R7JWWOF4.js → schema-CHJDC7GQ.js} +4 -8
- package/dist/{schema-R7JWWOF4.js.map → schema-CHJDC7GQ.js.map} +1 -1
- package/dist/{search-KHMQH3AT.js → search-PMJRU3C4.js} +2 -3
- package/dist/{search-KHMQH3AT.js.map → search-PMJRU3C4.js.map} +1 -1
- package/dist/{select-O2FN2JEQ.js → select-OEUKOVZ5.js} +8 -9
- package/dist/{select-O2FN2JEQ.js.map → select-OEUKOVZ5.js.map} +1 -1
- package/dist/{sends-BQZM5PLS.js → sends-WGJVQUMF.js} +4 -5
- package/dist/{sends-BQZM5PLS.js.map → sends-WGJVQUMF.js.map} +1 -1
- package/dist/{set-prompt-2HASHGWC.js → set-prompt-5E5I7QAZ.js} +8 -9
- package/dist/{set-prompt-2HASHGWC.js.map → set-prompt-5E5I7QAZ.js.map} +1 -1
- package/dist/{setup-links-GYSE56GX.js → setup-links-REPREN3C.js} +3 -4
- package/dist/{setup-links-GYSE56GX.js.map → setup-links-REPREN3C.js.map} +1 -1
- package/dist/{site-4SKM7RKG.js → site-WFSWIA3S.js} +4 -5
- package/dist/{site-4SKM7RKG.js.map → site-WFSWIA3S.js.map} +1 -1
- package/dist/{sources-R2NKNC6J.js → sources-AMI2AWKZ.js} +9 -10
- package/dist/{sources-R2NKNC6J.js.map → sources-AMI2AWKZ.js.map} +1 -1
- package/dist/{sources-FQ2UZTHL.js → sources-YBQ6KPFM.js} +6 -6
- package/dist/{stale-W756ACKC.js → stale-IGFUKEN2.js} +7 -8
- package/dist/{stale-W756ACKC.js.map → stale-IGFUKEN2.js.map} +1 -1
- package/dist/{status-SE2VZJJB.js → status-7F2KHFGA.js} +3 -4
- package/dist/{status-SE2VZJJB.js.map → status-7F2KHFGA.js.map} +1 -1
- package/dist/{stock-KXJ26BY4.js → stock-2YCDN3N6.js} +5 -5
- package/dist/{studio-SYKOSNDB.js → studio-RA7QQH4O.js} +1 -1
- package/dist/{sync-LJGSODK3.js → sync-GWTLKZTU.js} +2 -3
- package/dist/{sync-LJGSODK3.js.map → sync-GWTLKZTU.js.map} +1 -1
- package/dist/{sync-definition-QR2N233R.js → sync-definition-UGSDX2SZ.js} +11 -12
- package/dist/{tags-PYWFSBTR.js → tags-3WPW6PTV.js} +4 -4
- package/dist/{tags-QQU3OKMZ.js → tags-6342FQEB.js} +3 -4
- package/dist/{tags-QQU3OKMZ.js.map → tags-6342FQEB.js.map} +1 -1
- package/dist/{tags-5SBMRC2A.js → tags-ABHSX6M5.js} +3 -4
- package/dist/{tags-5SBMRC2A.js.map → tags-ABHSX6M5.js.map} +1 -1
- package/dist/{tags-YYLNF3PK.js → tags-FJIBBBRG.js} +3 -4
- package/dist/{tags-YYLNF3PK.js.map → tags-FJIBBBRG.js.map} +1 -1
- package/dist/{tags-4BAVFH4S.js → tags-KFYLZLB3.js} +2 -3
- package/dist/{tags-4BAVFH4S.js.map → tags-KFYLZLB3.js.map} +1 -1
- package/dist/{targeting-criteria-RJFLFICN.js → targeting-criteria-NR47AF5C.js} +3 -3
- package/dist/{targets-S2MT2PNB.js → targets-L56KOVQE.js} +3 -4
- package/dist/{targets-S2MT2PNB.js.map → targets-L56KOVQE.js.map} +1 -1
- package/dist/{templates-ZE5TOGRT.js → templates-B6XGDYUF.js} +3 -4
- package/dist/{templates-ZE5TOGRT.js.map → templates-B6XGDYUF.js.map} +1 -1
- package/dist/{testimonials-DII5DYLR.js → testimonials-CVC4YIXO.js} +6 -6
- package/dist/{top-companies-PGIAEHDF.js → top-companies-45X3DT7Z.js} +3 -4
- package/dist/{top-companies-PGIAEHDF.js.map → top-companies-45X3DT7Z.js.map} +1 -1
- package/dist/{translate-GXTS633J.js → translate-VP5R67PL.js} +11 -12
- package/dist/{translate-GXTS633J.js.map → translate-VP5R67PL.js.map} +1 -1
- package/dist/{triggers-2PTONXRU.js → triggers-22EMIVFD.js} +3 -4
- package/dist/{triggers-2PTONXRU.js.map → triggers-22EMIVFD.js.map} +1 -1
- package/dist/{unlink-XRMYJ6DB.js → unlink-65KUN6ID.js} +3 -4
- package/dist/{unlink-XRMYJ6DB.js.map → unlink-65KUN6ID.js.map} +1 -1
- package/dist/{unstage-FY7A3YFF.js → unstage-2E3I5SWF.js} +3 -4
- package/dist/{unstage-FY7A3YFF.js.map → unstage-2E3I5SWF.js.map} +1 -1
- package/dist/{unstage-RM2RLXKD.js → unstage-4ZEULXEQ.js} +4 -5
- package/dist/{unstage-RM2RLXKD.js.map → unstage-4ZEULXEQ.js.map} +1 -1
- package/dist/{update-S4562V3O.js → update-2S7CSEAW.js} +3 -4
- package/dist/{update-S4562V3O.js.map → update-2S7CSEAW.js.map} +1 -1
- package/dist/{update-V6YVEUI2.js → update-7NCOTAQZ.js} +3 -4
- package/dist/{update-V6YVEUI2.js.map → update-7NCOTAQZ.js.map} +1 -1
- package/dist/{update-PJ67D2OG.js → update-D6DJC6T7.js} +2 -3
- package/dist/{update-PJ67D2OG.js.map → update-D6DJC6T7.js.map} +1 -1
- package/dist/{update-E5SRBXQR.js → update-KREBPGBH.js} +3 -4
- package/dist/{update-E5SRBXQR.js.map → update-KREBPGBH.js.map} +1 -1
- package/dist/{upload-R6CQVLKF.js → upload-O6NHRPS7.js} +3 -4
- package/dist/{upload-R6CQVLKF.js.map → upload-O6NHRPS7.js.map} +1 -1
- package/dist/{url-options-JOKU46F2.js → url-options-GGXAL3J4.js} +3 -4
- package/dist/{url-options-JOKU46F2.js.map → url-options-GGXAL3J4.js.map} +1 -1
- package/dist/{url-params-7U2XMOWF.js → url-params-3EFGVTZZ.js} +3 -4
- package/dist/{url-params-7U2XMOWF.js.map → url-params-3EFGVTZZ.js.map} +1 -1
- package/dist/{validate-7YPOUKPB.js → validate-CSJM7XZM.js} +9 -10
- package/dist/{validate-7YPOUKPB.js.map → validate-CSJM7XZM.js.map} +1 -1
- package/dist/{videos-LICG6ACJ.js → videos-YSXYGTBM.js} +5 -5
- package/dist/{web-BA2PGTWU.js → web-IGIGVEKS.js} +3 -4
- package/dist/{web-BA2PGTWU.js.map → web-IGIGVEKS.js.map} +1 -1
- package/dist/{winning-ads-C6S2C5VP.js → winning-ads-2WS7FI4E.js} +2 -2
- package/dist/{write-commands-7SJ3BOW5.js → write-commands-5C7FUOVN.js} +4 -5
- package/dist/{write-commands-7SJ3BOW5.js.map → write-commands-5C7FUOVN.js.map} +1 -1
- package/dist/{x-CZHRC6U7.js → x-BFSKFCZD.js} +6 -6
- package/package.json +1 -1
- package/dist/add-2BEGRHUX.js.map +0 -1
- package/dist/analytics-IFELDWLL.js.map +0 -1
- package/dist/chunk-4PDHHHUJ.js +0 -537
- package/dist/chunk-4PDHHHUJ.js.map +0 -1
- package/dist/chunk-7EPXVICM.js.map +0 -1
- package/dist/chunk-ASI4P6X2.js.map +0 -1
- package/dist/chunk-FPOGPFAG.js.map +0 -1
- package/dist/chunk-HR6IWNKE.js.map +0 -1
- package/dist/chunk-HROZYQ5H.js.map +0 -1
- package/dist/chunk-NYIGXDUG.js.map +0 -1
- package/dist/chunk-QE7W555R.js.map +0 -1
- package/dist/flows-KTFAML22.js.map +0 -1
- package/dist/funnel-I6XIAEHG.js.map +0 -1
- package/dist/get-5PKNKJ5S.js.map +0 -1
- package/dist/plan-FT632COT.js +0 -51
- package/dist/plan-FT632COT.js.map +0 -1
- package/dist/questionnaire-JNGYJTAY.js +0 -37
- package/dist/questionnaire-JNGYJTAY.js.map +0 -1
- package/dist/scaffold-static-ad-ECTJL54Y.js.map +0 -1
- /package/dist/{actions-6TQMSVWD.js.map → actions-P35MEMGN.js.map} +0 -0
- /package/dist/{ads-AGYCVD62.js.map → ads-73PGA4YC.js.map} +0 -0
- /package/dist/{avatars-467OSBD6.js.map → avatars-EKCKHCC3.js.map} +0 -0
- /package/dist/{brand-YRTEPGBK.js.map → brand-C6PFGGQN.js.map} +0 -0
- /package/dist/{campaigns-OYMXDGWX.js.map → campaigns-KZYZTXDS.js.map} +0 -0
- /package/dist/{canvas-YQFG52IG.js.map → canvas-5NB27FX2.js.map} +0 -0
- /package/dist/{catalog-XLXIM7IW.js.map → catalog-VSSY6FGI.js.map} +0 -0
- /package/dist/{chunk-5ZNTADVR.js.map → chunk-3G3ZDLMI.js.map} +0 -0
- /package/dist/{chunk-ZDMTXQ2Q.js.map → chunk-3IBYKLXR.js.map} +0 -0
- /package/dist/{chunk-CWYAELVG.js.map → chunk-464O4MT2.js.map} +0 -0
- /package/dist/{chunk-NA63BH7V.js.map → chunk-4AUMTNVB.js.map} +0 -0
- /package/dist/{chunk-NDEE6G2J.js.map → chunk-4BQXAE7Z.js.map} +0 -0
- /package/dist/{chunk-2AOE2MZQ.js.map → chunk-5ZDLTE5T.js.map} +0 -0
- /package/dist/{chunk-ULG4QRTV.js.map → chunk-6NB47MRW.js.map} +0 -0
- /package/dist/{chunk-24EB7EDR.js.map → chunk-7YCRFMXF.js.map} +0 -0
- /package/dist/{chunk-WGUQHAJY.js.map → chunk-A4LOJ2VD.js.map} +0 -0
- /package/dist/{chunk-6F7DVPOS.js.map → chunk-AEOSAVVL.js.map} +0 -0
- /package/dist/{chunk-N4LAYIIN.js.map → chunk-CSYSX4D2.js.map} +0 -0
- /package/dist/{chunk-RX2DKU3W.js.map → chunk-DGUNI37S.js.map} +0 -0
- /package/dist/{chunk-I3ZR655O.js.map → chunk-IR6D7K4H.js.map} +0 -0
- /package/dist/{chunk-FUHN4MFY.js.map → chunk-JQJDXPCO.js.map} +0 -0
- /package/dist/{chunk-7CTMH5AK.js.map → chunk-KAUOHQTF.js.map} +0 -0
- /package/dist/{chunk-VYQ3QJ3C.js.map → chunk-KHRXPQID.js.map} +0 -0
- /package/dist/{chunk-6Y7ZBENQ.js.map → chunk-LECGCWT5.js.map} +0 -0
- /package/dist/{chunk-5WCSKQ7Z.js.map → chunk-LZ73CZGP.js.map} +0 -0
- /package/dist/{chunk-R25YLW6H.js.map → chunk-MELOSESI.js.map} +0 -0
- /package/dist/{chunk-DCRPXOJJ.js.map → chunk-MXYBTMKB.js.map} +0 -0
- /package/dist/{chunk-54C6YDGJ.js.map → chunk-NPY4QUMQ.js.map} +0 -0
- /package/dist/{chunk-LYQJ4PZW.js.map → chunk-OQ6663F4.js.map} +0 -0
- /package/dist/{chunk-H3427GPU.js.map → chunk-OZRUJVIQ.js.map} +0 -0
- /package/dist/{chunk-KMKEYI37.js.map → chunk-Q2V6E6SL.js.map} +0 -0
- /package/dist/{chunk-VL43TNIP.js.map → chunk-QRP3PXWN.js.map} +0 -0
- /package/dist/{chunk-C46GUI2S.js.map → chunk-RZBEK2VE.js.map} +0 -0
- /package/dist/{chunk-2VPBIT65.js.map → chunk-S3A3YOKO.js.map} +0 -0
- /package/dist/{chunk-FYGR3I2A.js.map → chunk-S77PZVYM.js.map} +0 -0
- /package/dist/{chunk-VLMBTPXU.js.map → chunk-SHL7LOC3.js.map} +0 -0
- /package/dist/{chunk-KS2QY6MK.js.map → chunk-W3ZHJJVT.js.map} +0 -0
- /package/dist/{chunk-RL5CP7N6.js.map → chunk-Y6O7EWYY.js.map} +0 -0
- /package/dist/{chunk-6NY2GPR4.js.map → chunk-Y6ZQXUZ7.js.map} +0 -0
- /package/dist/{chunk-WKQG6TER.js.map → chunk-ZEYEWPK6.js.map} +0 -0
- /package/dist/{connect-FCXNVTXG.js.map → connect-QCOGEPP4.js.map} +0 -0
- /package/dist/{creatives-FXUQ5WSD.js.map → creatives-B5NTXPUB.js.map} +0 -0
- /package/dist/{customers-XH2DMTFH.js.map → customers-A36LOZOB.js.map} +0 -0
- /package/dist/{feedback-EIZKS4JU.js.map → feedback-OLTCHE6C.js.map} +0 -0
- /package/dist/{find-FRRHAPWX.js.map → find-OTDIX6V4.js.map} +0 -0
- /package/dist/{fonts-MXR3ZKDX.js.map → fonts-EMMX3KII.js.map} +0 -0
- /package/dist/{ga4-DV2AXCSL.js.map → ga4-UDQ2HA2J.js.map} +0 -0
- /package/dist/{google-QYYYSSXI.js.map → google-KTO3PLEU.js.map} +0 -0
- /package/dist/{google-6OGZX47I.js.map → google-M7KEXVK5.js.map} +0 -0
- /package/dist/{gsc-TAKOF7J5.js.map → gsc-P3QYGDV2.js.map} +0 -0
- /package/dist/{icon-L4RSS6PZ.js.map → icon-I43F77FV.js.map} +0 -0
- /package/dist/{ideas-NFOW3HKJ.js.map → ideas-MIDU7YOA.js.map} +0 -0
- /package/dist/{images-2EFFUNNV.js.map → images-S254MS6O.js.map} +0 -0
- /package/dist/{ingest-2EIKN4QC.js.map → ingest-YV2NLDBE.js.map} +0 -0
- /package/dist/{inspiration-S3DU4CMQ.js.map → inspiration-P265QJ2H.js.map} +0 -0
- /package/dist/{landing-2ZB46LXH.js.map → landing-CJYGWCK4.js.map} +0 -0
- /package/dist/{line-items-5NECXUZT.js.map → line-items-7ZGIKEF2.js.map} +0 -0
- /package/dist/{logo-Q5D7PZY6.js.map → logo-2IP663QO.js.map} +0 -0
- /package/dist/{lookup-ETWY47F7.js.map → lookup-XK45W2SH.js.map} +0 -0
- /package/dist/{media-sources-ZXHEEP6T.js.map → media-sources-O6ZRUA3N.js.map} +0 -0
- /package/dist/{performance-UF5VTY2U.js.map → performance-6QW2KEEQ.js.map} +0 -0
- /package/dist/{promoted-tweets-LZKS5JIF.js.map → promoted-tweets-SURKMHFI.js.map} +0 -0
- /package/dist/{reddit-NU2N3LZD.js.map → reddit-GIP3ADMS.js.map} +0 -0
- /package/dist/{research-FMM6AWZC.js.map → research-2BLEISBG.js.map} +0 -0
- /package/dist/{run-EUO34T2J.js.map → run-MMEDKJDB.js.map} +0 -0
- /package/dist/{scheduled-agents-N4LJRM4C.js.map → scheduled-agents-6U44QE76.js.map} +0 -0
- /package/dist/{sources-FQ2UZTHL.js.map → sources-YBQ6KPFM.js.map} +0 -0
- /package/dist/{stock-KXJ26BY4.js.map → stock-2YCDN3N6.js.map} +0 -0
- /package/dist/{studio-SYKOSNDB.js.map → studio-RA7QQH4O.js.map} +0 -0
- /package/dist/{sync-definition-QR2N233R.js.map → sync-definition-UGSDX2SZ.js.map} +0 -0
- /package/dist/{tags-PYWFSBTR.js.map → tags-3WPW6PTV.js.map} +0 -0
- /package/dist/{targeting-criteria-RJFLFICN.js.map → targeting-criteria-NR47AF5C.js.map} +0 -0
- /package/dist/{testimonials-DII5DYLR.js.map → testimonials-CVC4YIXO.js.map} +0 -0
- /package/dist/{videos-LICG6ACJ.js.map → videos-YSXYGTBM.js.map} +0 -0
- /package/dist/{winning-ads-C6S2C5VP.js.map → winning-ads-2WS7FI4E.js.map} +0 -0
- /package/dist/{x-CZHRC6U7.js.map → x-BFSKFCZD.js.map} +0 -0
|
@@ -6,11 +6,10 @@ import {
|
|
|
6
6
|
} from "./chunk-Q6ULQMWG.js";
|
|
7
7
|
import {
|
|
8
8
|
testimonialSourceTypeSchema
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-XF4JUKVF.js";
|
|
10
10
|
import "./chunk-GXDLWBOY.js";
|
|
11
11
|
import "./chunk-TEINLN64.js";
|
|
12
12
|
import "./chunk-ZJWUBJYQ.js";
|
|
13
|
-
import "./chunk-HR6IWNKE.js";
|
|
14
13
|
import "./chunk-NE4F3FHN.js";
|
|
15
14
|
import {
|
|
16
15
|
ApiError,
|
|
@@ -172,4 +171,4 @@ var searchCommand = defineCommand({
|
|
|
172
171
|
export {
|
|
173
172
|
searchCommand
|
|
174
173
|
};
|
|
175
|
-
//# sourceMappingURL=search-
|
|
174
|
+
//# sourceMappingURL=search-PMJRU3C4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/testimonials/search.ts"],"sourcesContent":["import {\n type TestimonialsSearchRequest,\n type TestimonialsSearchResponse,\n testimonialSourceTypeSchema,\n} from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { ApiError, apiPost } from \"../../client.ts\";\nimport { type OutputFormat, testimonialNormalizer, writeJson, writeOutput } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { activeFilterFlags } from \"../images/searchHints.ts\";\nimport { measureEmptyCorpus } from \"./emptyCorpusHints.ts\";\n\nconst FILTER_FLAGS = [\"source\", \"rating-min\", \"rating-max\", \"status\", \"sentiment\", \"language\", \"tags\"];\n\n/**\n * Hybrid search reranks over this company's whole corpus with no language\n * awareness, so a corpus seeded in one language returns that language even for\n * an English query. When the caller didn't pin a `--language` and the results\n * clearly skew to one, nudge them to scope by the target market's language —\n * otherwise a Spanish/French-heavy corpus silently starves a market-specific ad\n * of on-language quotes.\n */\nfunction languageBiasHint(results: TestimonialsSearchResponse, requestedLanguage: string | undefined): string | null {\n if (requestedLanguage) {\n return null;\n }\n const withLang = results.filter((r) => typeof r.language === \"string\" && r.language.length > 0);\n if (withLang.length < 3) {\n return null;\n }\n const counts = new Map<string, number>();\n for (const r of withLang) {\n const lang = r.language as string;\n counts.set(lang, (counts.get(lang) ?? 0) + 1);\n }\n const [topLang, topCount] = [...counts.entries()].sort((a, b) => b[1] - a[1])[0] ?? [\"\", 0];\n if (topLang && topCount / withLang.length >= 0.8) {\n return `Results skew ${topLang} (${topCount}/${withLang.length}). If you're sourcing quotes for a specific market, pass --language <code> (e.g. --language en) so the ad's language matches its audience.`;\n }\n return null;\n}\n\nregisterSchema({\n command: \"testimonials.search\",\n description: \"Search testimonials by text query. Uses hybrid BM25 + vector + reranking.\",\n args: {\n query: { type: \"string\", description: \"Search query text\", required: true },\n limit: { type: \"number\", description: \"Maximum results to return\", required: false, default: 10 },\n source: {\n type: \"string\",\n description: `Filter by source: ${testimonialSourceTypeSchema.options.join(\"|\")}`,\n required: false,\n enum: [...testimonialSourceTypeSchema.options],\n },\n \"rating-min\": { type: \"number\", description: \"Minimum star rating (1-5)\", required: false },\n \"rating-max\": { type: \"number\", description: \"Maximum star rating (1-5)\", required: false },\n status: {\n type: \"string\",\n description: \"Filter by status: pending|processing|ready|error\",\n required: false,\n enum: [\"pending\", \"processing\", \"ready\", \"error\"],\n },\n sentiment: {\n type: \"string\",\n description: \"Filter: positive|neutral|negative\",\n required: false,\n enum: [\"positive\", \"neutral\", \"negative\"],\n },\n language: { type: \"string\", description: \"Filter by language code (e.g. en, es)\", required: false },\n tags: { type: \"string\", description: \"Comma-separated tags to filter by\", required: false },\n },\n});\n\n/** Assemble the search request body from CLI args, applying only the flags that were provided. */\nfunction buildSearchRequest(query: string, args: Record<string, unknown>): TestimonialsSearchRequest {\n const body: TestimonialsSearchRequest = { query };\n if (args.limit !== undefined) {\n body.limit = Number(args.limit);\n }\n if (args.source) {\n body.source = args.source as TestimonialsSearchRequest[\"source\"];\n }\n if (args[\"rating-min\"] !== undefined) {\n body.rating_min = Number(args[\"rating-min\"]);\n }\n if (args[\"rating-max\"] !== undefined) {\n body.rating_max = Number(args[\"rating-max\"]);\n }\n if (args.status) {\n body.status = args.status as TestimonialsSearchRequest[\"status\"];\n }\n if (args.sentiment) {\n body.sentiment = args.sentiment as TestimonialsSearchRequest[\"sentiment\"];\n }\n if (args.language) {\n body.language = args.language as string;\n }\n if (args.tags) {\n body.tags = (args.tags as string).split(\",\").filter(Boolean);\n }\n return body;\n}\n\nexport const searchCommand = defineCommand({\n meta: {\n name: \"search\",\n description:\n \"Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4\",\n },\n args: {\n query: { type: \"positional\", description: \"Search query text\", required: false },\n limit: { type: \"string\", description: \"Max results (default 10)\", required: false },\n source: {\n type: \"string\",\n description: `Filter by source: ${testimonialSourceTypeSchema.options.join(\"|\")}`,\n required: false,\n },\n \"rating-min\": { type: \"string\", description: \"Minimum star rating (1-5)\", required: false },\n \"rating-max\": { type: \"string\", description: \"Maximum star rating (1-5)\", required: false },\n status: { type: \"string\", description: \"Filter by status: pending|processing|ready|error\", required: false },\n sentiment: { type: \"string\", description: \"Filter: positive|neutral|negative\", required: false },\n language: { type: \"string\", description: \"Filter by language code (e.g. en, es)\", required: false },\n tags: { type: \"string\", description: \"Comma-separated tags to filter by\", required: false },\n output: { type: \"string\", description: \"Output format: json|files|md\", required: false, default: \"json\" },\n fields: { type: \"string\", description: \"Comma-separated field names to include\", required: false },\n full: { type: \"boolean\", description: \"Include full metadata\", required: false, default: false },\n },\n run: async ({ args }) => {\n try {\n const query = args.query as string | undefined;\n if (!query) {\n writeJson({ ok: false, error: { code: \"VALIDATION_ERROR\", message: \"Search query is required\" } });\n process.exit(1);\n }\n\n const body = buildSearchRequest(query, args);\n const data = await apiPost<TestimonialsSearchResponse>(\"/api/testimonials/search\", body);\n const languageHint = languageBiasHint(data, body.language);\n const { hints: emptyHints, empty } = await measureEmptyCorpus({\n command: \"search\",\n resultCount: data.length,\n activeFilters: activeFilterFlags(args, FILTER_FLAGS),\n });\n const hints = [...emptyHints, ...(languageHint ? [languageHint] : [])];\n const outputFormat = (args.output as OutputFormat) || \"json\";\n writeOutput(\n { ok: true, data, ...(empty ? { meta: { empty } } : {}), ...(hints.length > 0 ? { hints } : {}) },\n outputFormat,\n args.fields ? args.fields.split(\",\") : undefined,\n args.full as boolean,\n testimonialNormalizer,\n );\n // md/files render only the table, so hints (which never reach the table)\n // go to stderr — otherwise `--output md` hides the language skew, and an\n // empty result prints a header row and nothing else.\n if (outputFormat !== \"json\") {\n for (const hint of hints) {\n process.stderr.write(`${hint}\\n`);\n }\n }\n } catch (err) {\n if (err instanceof ApiError) {\n writeJson({ ok: false, error: { code: err.code, message: err.message } });\n process.exit(1);\n }\n writeJson({ ok: false, error: { code: \"INTERNAL_ERROR\", message: \"Unexpected error\" } });\n process.exit(1);\n }\n },\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/commands/testimonials/search.ts"],"sourcesContent":["import {\n type TestimonialsSearchRequest,\n type TestimonialsSearchResponse,\n testimonialSourceTypeSchema,\n} from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { ApiError, apiPost } from \"../../client.ts\";\nimport { type OutputFormat, testimonialNormalizer, writeJson, writeOutput } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { activeFilterFlags } from \"../images/searchHints.ts\";\nimport { measureEmptyCorpus } from \"./emptyCorpusHints.ts\";\n\nconst FILTER_FLAGS = [\"source\", \"rating-min\", \"rating-max\", \"status\", \"sentiment\", \"language\", \"tags\"];\n\n/**\n * Hybrid search reranks over this company's whole corpus with no language\n * awareness, so a corpus seeded in one language returns that language even for\n * an English query. When the caller didn't pin a `--language` and the results\n * clearly skew to one, nudge them to scope by the target market's language —\n * otherwise a Spanish/French-heavy corpus silently starves a market-specific ad\n * of on-language quotes.\n */\nfunction languageBiasHint(results: TestimonialsSearchResponse, requestedLanguage: string | undefined): string | null {\n if (requestedLanguage) {\n return null;\n }\n const withLang = results.filter((r) => typeof r.language === \"string\" && r.language.length > 0);\n if (withLang.length < 3) {\n return null;\n }\n const counts = new Map<string, number>();\n for (const r of withLang) {\n const lang = r.language as string;\n counts.set(lang, (counts.get(lang) ?? 0) + 1);\n }\n const [topLang, topCount] = [...counts.entries()].sort((a, b) => b[1] - a[1])[0] ?? [\"\", 0];\n if (topLang && topCount / withLang.length >= 0.8) {\n return `Results skew ${topLang} (${topCount}/${withLang.length}). If you're sourcing quotes for a specific market, pass --language <code> (e.g. --language en) so the ad's language matches its audience.`;\n }\n return null;\n}\n\nregisterSchema({\n command: \"testimonials.search\",\n description: \"Search testimonials by text query. Uses hybrid BM25 + vector + reranking.\",\n args: {\n query: { type: \"string\", description: \"Search query text\", required: true },\n limit: { type: \"number\", description: \"Maximum results to return\", required: false, default: 10 },\n source: {\n type: \"string\",\n description: `Filter by source: ${testimonialSourceTypeSchema.options.join(\"|\")}`,\n required: false,\n enum: [...testimonialSourceTypeSchema.options],\n },\n \"rating-min\": { type: \"number\", description: \"Minimum star rating (1-5)\", required: false },\n \"rating-max\": { type: \"number\", description: \"Maximum star rating (1-5)\", required: false },\n status: {\n type: \"string\",\n description: \"Filter by status: pending|processing|ready|error\",\n required: false,\n enum: [\"pending\", \"processing\", \"ready\", \"error\"],\n },\n sentiment: {\n type: \"string\",\n description: \"Filter: positive|neutral|negative\",\n required: false,\n enum: [\"positive\", \"neutral\", \"negative\"],\n },\n language: { type: \"string\", description: \"Filter by language code (e.g. en, es)\", required: false },\n tags: { type: \"string\", description: \"Comma-separated tags to filter by\", required: false },\n },\n});\n\n/** Assemble the search request body from CLI args, applying only the flags that were provided. */\nfunction buildSearchRequest(query: string, args: Record<string, unknown>): TestimonialsSearchRequest {\n const body: TestimonialsSearchRequest = { query };\n if (args.limit !== undefined) {\n body.limit = Number(args.limit);\n }\n if (args.source) {\n body.source = args.source as TestimonialsSearchRequest[\"source\"];\n }\n if (args[\"rating-min\"] !== undefined) {\n body.rating_min = Number(args[\"rating-min\"]);\n }\n if (args[\"rating-max\"] !== undefined) {\n body.rating_max = Number(args[\"rating-max\"]);\n }\n if (args.status) {\n body.status = args.status as TestimonialsSearchRequest[\"status\"];\n }\n if (args.sentiment) {\n body.sentiment = args.sentiment as TestimonialsSearchRequest[\"sentiment\"];\n }\n if (args.language) {\n body.language = args.language as string;\n }\n if (args.tags) {\n body.tags = (args.tags as string).split(\",\").filter(Boolean);\n }\n return body;\n}\n\nexport const searchCommand = defineCommand({\n meta: {\n name: \"search\",\n description:\n \"Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4\",\n },\n args: {\n query: { type: \"positional\", description: \"Search query text\", required: false },\n limit: { type: \"string\", description: \"Max results (default 10)\", required: false },\n source: {\n type: \"string\",\n description: `Filter by source: ${testimonialSourceTypeSchema.options.join(\"|\")}`,\n required: false,\n },\n \"rating-min\": { type: \"string\", description: \"Minimum star rating (1-5)\", required: false },\n \"rating-max\": { type: \"string\", description: \"Maximum star rating (1-5)\", required: false },\n status: { type: \"string\", description: \"Filter by status: pending|processing|ready|error\", required: false },\n sentiment: { type: \"string\", description: \"Filter: positive|neutral|negative\", required: false },\n language: { type: \"string\", description: \"Filter by language code (e.g. en, es)\", required: false },\n tags: { type: \"string\", description: \"Comma-separated tags to filter by\", required: false },\n output: { type: \"string\", description: \"Output format: json|files|md\", required: false, default: \"json\" },\n fields: { type: \"string\", description: \"Comma-separated field names to include\", required: false },\n full: { type: \"boolean\", description: \"Include full metadata\", required: false, default: false },\n },\n run: async ({ args }) => {\n try {\n const query = args.query as string | undefined;\n if (!query) {\n writeJson({ ok: false, error: { code: \"VALIDATION_ERROR\", message: \"Search query is required\" } });\n process.exit(1);\n }\n\n const body = buildSearchRequest(query, args);\n const data = await apiPost<TestimonialsSearchResponse>(\"/api/testimonials/search\", body);\n const languageHint = languageBiasHint(data, body.language);\n const { hints: emptyHints, empty } = await measureEmptyCorpus({\n command: \"search\",\n resultCount: data.length,\n activeFilters: activeFilterFlags(args, FILTER_FLAGS),\n });\n const hints = [...emptyHints, ...(languageHint ? [languageHint] : [])];\n const outputFormat = (args.output as OutputFormat) || \"json\";\n writeOutput(\n { ok: true, data, ...(empty ? { meta: { empty } } : {}), ...(hints.length > 0 ? { hints } : {}) },\n outputFormat,\n args.fields ? args.fields.split(\",\") : undefined,\n args.full as boolean,\n testimonialNormalizer,\n );\n // md/files render only the table, so hints (which never reach the table)\n // go to stderr — otherwise `--output md` hides the language skew, and an\n // empty result prints a header row and nothing else.\n if (outputFormat !== \"json\") {\n for (const hint of hints) {\n process.stderr.write(`${hint}\\n`);\n }\n }\n } catch (err) {\n if (err instanceof ApiError) {\n writeJson({ ok: false, error: { code: err.code, message: err.message } });\n process.exit(1);\n }\n writeJson({ ok: false, error: { code: \"INTERNAL_ERROR\", message: \"Unexpected error\" } });\n process.exit(1);\n }\n },\n});\n"],"mappings":"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","names":[]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
versionOf
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-RZBEK2VE.js";
|
|
4
|
+
import "./chunk-KAUOHQTF.js";
|
|
5
|
+
import "./chunk-YUCLMOEG.js";
|
|
6
6
|
import "./chunk-4QEY2L6U.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-QRP3PXWN.js";
|
|
8
|
+
import "./chunk-3IBYKLXR.js";
|
|
9
9
|
import "./chunk-F2S5BLPE.js";
|
|
10
10
|
import "./chunk-WTOYCUKH.js";
|
|
11
11
|
import "./chunk-DZSIUEGH.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-EBWBG6YV.js";
|
|
13
13
|
import "./chunk-NCWCZY5P.js";
|
|
14
14
|
import "./chunk-DGCUPJZD.js";
|
|
15
15
|
import "./chunk-PZXCWSKV.js";
|
|
@@ -23,11 +23,10 @@ import "./chunk-VVZBBKRC.js";
|
|
|
23
23
|
import "./chunk-YBMVHGY3.js";
|
|
24
24
|
import {
|
|
25
25
|
creativesSelectRequestSchema
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-XF4JUKVF.js";
|
|
27
27
|
import "./chunk-GXDLWBOY.js";
|
|
28
28
|
import "./chunk-TEINLN64.js";
|
|
29
29
|
import "./chunk-ZJWUBJYQ.js";
|
|
30
|
-
import "./chunk-HR6IWNKE.js";
|
|
31
30
|
import "./chunk-NE4F3FHN.js";
|
|
32
31
|
import {
|
|
33
32
|
ApiError,
|
|
@@ -92,4 +91,4 @@ var selectCommand = defineCommand({
|
|
|
92
91
|
export {
|
|
93
92
|
selectCommand
|
|
94
93
|
};
|
|
95
|
-
//# sourceMappingURL=select-
|
|
94
|
+
//# sourceMappingURL=select-OEUKOVZ5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/creatives/select.ts"],"sourcesContent":["import { type CreativesSelectResponse, creativesSelectRequestSchema } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { ApiError, apiPost } from \"../../client.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { versionOf } from \"./version-of.ts\";\n\nconst DESCRIPTION = `Choose the version of a creative to keep, and optionally which of its options, only when the user says to keep this version in this chat. The creative shows that version as the chosen one, and the choice counts as the user's approval. A version you render after it replaces it when the chat is published (the user saw that one last). It does not save the image to their library (that is baker creatives publish) and puts nothing into an ad.\nStart here: baker creatives select --slug spring-offer\nOnly some options of a version that made several: --options \"ugc,2\" (labels or numbers). Naming options again replaces the earlier pick.`;\n\nconst ARGS = {\n slug: { type: \"string\", description: \"The creative: its folder name under src/creatives/.\", required: true },\n run: {\n type: \"string\",\n description:\n \"The version to keep: its canvas run id (r_…) Left out, the version the creative shows now (its last render).\",\n required: false,\n },\n options: {\n type: \"string\",\n description:\n 'Keep only these options of the version, comma-separated: labels (\"ugc\"), numbers (\"2\") or slots. Left out, the whole version.',\n required: false,\n },\n} as const;\n\nregisterSchema({ command: \"creatives.select\", description: DESCRIPTION, args: ARGS });\n\nfunction fail(code: string, message: string): never {\n writeJson({ ok: false, error: { code, message } });\n process.exit(1);\n}\n\nexport const selectCommand = defineCommand({\n meta: { name: \"select\", description: DESCRIPTION },\n args: ARGS,\n run: async ({ args }) => {\n const options =\n typeof args.options === \"string\"\n ? args.options\n .split(\",\")\n .map((option) => option.trim())\n .filter((option) => option.length > 0)\n : [];\n const parsed = creativesSelectRequestSchema.safeParse({\n slug: args.slug,\n runId: await versionOf(String(args.slug), args.run).then(\n (run) => run ?? fail(\"VALIDATION_ERROR\", \"--run: this creative has no rendered version here; name one (r_…).\"),\n ),\n ...(options.length > 0 ? { options } : {}),\n });\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n fail(\"VALIDATION_ERROR\", `--${String(issue?.path[0] ?? \"args\")}: ${issue?.message ?? \"invalid\"}`);\n }\n try {\n const response = await apiPost<CreativesSelectResponse>(\"/api/creatives/select\", parsed.data);\n writeJson(response);\n } catch (err) {\n if (err instanceof ApiError) fail(err.code, err.message);\n fail(\"INTERNAL_ERROR\", \"Unexpected error\");\n }\n },\n});\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/commands/creatives/select.ts"],"sourcesContent":["import { type CreativesSelectResponse, creativesSelectRequestSchema } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { ApiError, apiPost } from \"../../client.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { versionOf } from \"./version-of.ts\";\n\nconst DESCRIPTION = `Choose the version of a creative to keep, and optionally which of its options, only when the user says to keep this version in this chat. The creative shows that version as the chosen one, and the choice counts as the user's approval. A version you render after it replaces it when the chat is published (the user saw that one last). It does not save the image to their library (that is baker creatives publish) and puts nothing into an ad.\nStart here: baker creatives select --slug spring-offer\nOnly some options of a version that made several: --options \"ugc,2\" (labels or numbers). Naming options again replaces the earlier pick.`;\n\nconst ARGS = {\n slug: { type: \"string\", description: \"The creative: its folder name under src/creatives/.\", required: true },\n run: {\n type: \"string\",\n description:\n \"The version to keep: its canvas run id (r_…) Left out, the version the creative shows now (its last render).\",\n required: false,\n },\n options: {\n type: \"string\",\n description:\n 'Keep only these options of the version, comma-separated: labels (\"ugc\"), numbers (\"2\") or slots. Left out, the whole version.',\n required: false,\n },\n} as const;\n\nregisterSchema({ command: \"creatives.select\", description: DESCRIPTION, args: ARGS });\n\nfunction fail(code: string, message: string): never {\n writeJson({ ok: false, error: { code, message } });\n process.exit(1);\n}\n\nexport const selectCommand = defineCommand({\n meta: { name: \"select\", description: DESCRIPTION },\n args: ARGS,\n run: async ({ args }) => {\n const options =\n typeof args.options === \"string\"\n ? args.options\n .split(\",\")\n .map((option) => option.trim())\n .filter((option) => option.length > 0)\n : [];\n const parsed = creativesSelectRequestSchema.safeParse({\n slug: args.slug,\n runId: await versionOf(String(args.slug), args.run).then(\n (run) => run ?? fail(\"VALIDATION_ERROR\", \"--run: this creative has no rendered version here; name one (r_…).\"),\n ),\n ...(options.length > 0 ? { options } : {}),\n });\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n fail(\"VALIDATION_ERROR\", `--${String(issue?.path[0] ?? \"args\")}: ${issue?.message ?? \"invalid\"}`);\n }\n try {\n const response = await apiPost<CreativesSelectResponse>(\"/api/creatives/select\", parsed.data);\n writeJson(response);\n } catch (err) {\n if (err instanceof ApiError) fail(err.code, err.message);\n fail(\"INTERNAL_ERROR\", \"Unexpected error\");\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,qBAAqB;AAM9B,IAAM,cAAc;AAAA;AAAA;AAIpB,IAAM,OAAO;AAAA,EACX,MAAM,EAAE,MAAM,UAAU,aAAa,uDAAuD,UAAU,KAAK;AAAA,EAC3G,KAAK;AAAA,IACH,MAAM;AAAA,IACN,aACE;AAAA,IACF,UAAU;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,aACE;AAAA,IACF,UAAU;AAAA,EACZ;AACF;AAEA,eAAe,EAAE,SAAS,oBAAoB,aAAa,aAAa,MAAM,KAAK,CAAC;AAEpF,SAAS,KAAK,MAAc,SAAwB;AAClD,YAAU,EAAE,IAAI,OAAO,OAAO,EAAE,MAAM,QAAQ,EAAE,CAAC;AACjD,UAAQ,KAAK,CAAC;AAChB;AAEO,IAAM,gBAAgB,cAAc;AAAA,EACzC,MAAM,EAAE,MAAM,UAAU,aAAa,YAAY;AAAA,EACjD,MAAM;AAAA,EACN,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,UACJ,OAAO,KAAK,YAAY,WACpB,KAAK,QACF,MAAM,GAAG,EACT,IAAI,CAAC,WAAW,OAAO,KAAK,CAAC,EAC7B,OAAO,CAAC,WAAW,OAAO,SAAS,CAAC,IACvC,CAAC;AACP,UAAM,SAAS,6BAA6B,UAAU;AAAA,MACpD,MAAM,KAAK;AAAA,MACX,OAAO,MAAM,UAAU,OAAO,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE;AAAA,QAClD,CAAC,QAAQ,OAAO,KAAK,oBAAoB,yEAAoE;AAAA,MAC/G;AAAA,MACA,GAAI,QAAQ,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC1C,CAAC;AACD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,QAAQ,OAAO,MAAM,OAAO,CAAC;AACnC,WAAK,oBAAoB,KAAK,OAAO,OAAO,KAAK,CAAC,KAAK,MAAM,CAAC,KAAK,OAAO,WAAW,SAAS,EAAE;AAAA,IAClG;AACA,QAAI;AACF,YAAM,WAAW,MAAM,QAAiC,yBAAyB,OAAO,IAAI;AAC5F,gBAAU,QAAQ;AAAA,IACpB,SAAS,KAAK;AACZ,UAAI,eAAe,SAAU,MAAK,IAAI,MAAM,IAAI,OAAO;AACvD,WAAK,kBAAkB,kBAAkB;AAAA,IAC3C;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ConversionArgsError,
|
|
3
3
|
onlyOnce
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RPUSTYHL.js";
|
|
5
5
|
import {
|
|
6
6
|
SEND_PLATFORMS,
|
|
7
7
|
isSendPlatform,
|
|
8
8
|
sendEventProblem,
|
|
9
9
|
sendsRequestSchema
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-SSJK7FEV.js";
|
|
11
|
+
import "./chunk-EDLZGTGN.js";
|
|
12
12
|
import {
|
|
13
13
|
writeJsonEnvelope
|
|
14
14
|
} from "./chunk-VFIOJD5M.js";
|
|
15
|
-
import "./chunk-HR6IWNKE.js";
|
|
16
15
|
import {
|
|
17
16
|
ApiError,
|
|
18
17
|
apiPost
|
|
@@ -307,4 +306,4 @@ export {
|
|
|
307
306
|
sendsView,
|
|
308
307
|
sendsWrite
|
|
309
308
|
};
|
|
310
|
-
//# sourceMappingURL=sends-
|
|
309
|
+
//# sourceMappingURL=sends-WGJVQUMF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/analytics/sends.ts"],"sourcesContent":["/**\n * `baker analytics sends` — where this company's system events are sent, and\n * changing it.\n *\n * A send hangs off an event one of the client's own systems raises, by its\n * key: `page:deal_won` from HubSpot → Meta Purchase. Every such event is\n * uploaded to the platform with who the person is, the click that brought\n * them and the amount forwarded automatically. Nothing is mapped. What happens\n * on a page or in a Form is not sendable here: the page's own pixels and the\n * Form's own side effects already send those.\n *\n * A write STAGES: it lands when the chat is published, and from then on it\n * spends ad budget on every event under the key. The dashboard's Sources page\n * applies at once because the person clicking is the review; an agent's\n * proposal gets its review at Publish.\n */\n\nimport {\n isSendPlatform,\n SEND_PLATFORMS,\n type SendsRequest,\n type SendsResponse,\n sendEventProblem,\n sendsRequestSchema,\n} from \"@baker/api/analytics\";\nimport { defineCommand } from \"citty\";\nimport { ApiError, apiPost } from \"../../client.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { writeJsonEnvelope } from \"../ads/output.ts\";\nimport { ConversionArgsError, onlyOnce } from \"./conversionArgs.ts\";\n\nexport interface SendsArgs {\n set?: {\n id: string;\n eventKey: string;\n platform: string;\n tagId: string;\n event: string;\n account?: string;\n parameters?: Record<string, string>;\n };\n remove?: string;\n days?: number;\n /** One send's uploads, by id, and whether only the refused ones. */\n uploads?: string;\n failedOnly?: boolean;\n /** With `uploads`: only the events it skipped, for want of anything to match. */\n skippedOnly?: boolean;\n full: boolean;\n}\n\nconst SET_FLAGS = [\"--source-event\", \"--platform\", \"--tag\", \"--event\"] as const;\n\n/**\n * The flags, checked for the shapes that would otherwise stage the wrong\n * send in silence. Pure, so the refusals are tier-1 tested.\n */\nexport function parseSendsArgs(raw: Record<string, unknown>, argv: readonly string[], now = Date.now()): SendsArgs {\n const set = parseSetFlags(raw, argv, now);\n const remove = onlyOnce(raw.remove, \"--remove\", argv);\n\n const days = raw.days === undefined ? undefined : Number(raw.days);\n if (days !== undefined && (!Number.isInteger(days) || days <= 0 || days > 400)) {\n throw new ConversionArgsError(\"--days must be a whole number of days, from 1 to 400.\");\n }\n\n const uploads = onlyOnce(raw.uploads, \"--uploads\", argv);\n if (raw.failed === true && uploads === undefined) {\n throw new ConversionArgsError(\"--failed narrows --uploads <sendId> to the refused ones; name the send.\");\n }\n if (raw.skipped === true && uploads === undefined) {\n throw new ConversionArgsError(\n \"--skipped narrows --uploads <sendId> to the events it never uploaded; name the send.\",\n );\n }\n\n return {\n ...(set === undefined ? {} : { set }),\n ...(remove === undefined ? {} : { remove }),\n ...(days === undefined ? {} : { days }),\n ...(uploads === undefined ? {} : { uploads }),\n ...(raw.failed === true ? { failedOnly: true } : {}),\n ...(raw.skipped === true ? { skippedOnly: true } : {}),\n full: raw.full === true,\n };\n}\n\n/** The value a repeated flag carries at this position, in either spelling, or nothing. */\nfunction flagValueAt(argv: readonly string[], flag: string, index: number): string | undefined {\n const arg = argv[index] ?? \"\";\n if (arg === flag) return argv[index + 1];\n return arg.startsWith(`${flag}=`) ? arg.slice(flag.length + 1) : undefined;\n}\n\n/**\n * Every `--parameter name=template` on the command line, in order. Read off\n * argv rather than the parsed args because citty keeps only the last value\n * of a repeated flag — the defect that once staged one of three UTMs.\n */\nexport function parseParameterArgs(argv: readonly string[]): Record<string, string> | undefined {\n const parameters: Record<string, string> = {};\n for (let index = 0; index < argv.length; index += 1) {\n const pair = flagValueAt(argv, \"--parameter\", index);\n if (pair === undefined) continue;\n const eq = pair.indexOf(\"=\");\n const name = (eq === -1 ? pair : pair.slice(0, eq)).trim();\n const template = eq === -1 ? \"\" : pair.slice(eq + 1).trim();\n if (name === \"\" || template === \"\") {\n throw new ConversionArgsError(\n `--parameter needs <name>=<template>, like --parameter content_name={{properties.plan}}; got \"${pair}\".`,\n );\n }\n parameters[name] = template;\n }\n return Object.keys(parameters).length === 0 ? undefined : parameters;\n}\n\n/**\n * The send `--set` describes, or nothing on a read.\n *\n * The four flags are only meaningful together and only under `--set`: a send\n * described without it would answer ok and stage nothing, and a `--set` with\n * a piece missing would be refused by the server with the field named but not\n * the flag.\n */\nfunction parseSetFlags(raw: Record<string, unknown>, argv: readonly string[], now: number): SendsArgs[\"set\"] {\n if (raw.conversion !== undefined) {\n throw new ConversionArgsError(\n \"--conversion is gone: a send is on a system's EVENT, not a conversion. Pass --source-event <key> — one of events[].eventKey from a plain `baker analytics sends` (page:<name>).\",\n );\n }\n const values = {\n \"--source-event\": onlyOnce(raw[\"source-event\"] ?? raw.sourceEvent, \"--source-event\", argv),\n \"--platform\": onlyOnce(raw.platform, \"--platform\", argv),\n \"--tag\": onlyOnce(raw.tag, \"--tag\", argv),\n \"--event\": onlyOnce(raw.event, \"--event\", argv),\n };\n const given = SET_FLAGS.filter((flag) => values[flag] !== undefined);\n const set = raw.set === true;\n\n if (!set) {\n if (given.length > 0) {\n throw new ConversionArgsError(\n `${given.join(\", \")} describe a send, so add --set to stage it. Without --set the command only reads.`,\n );\n }\n return undefined;\n }\n\n const missing = SET_FLAGS.filter((flag) => values[flag] === undefined);\n if (missing.length > 0) {\n throw new ConversionArgsError(\n `--set needs ${SET_FLAGS.join(\", \")}; missing ${missing.join(\", \")}. Copy --tag from platforms[].tags of a plain \\`baker analytics sends\\`, never from memory.`,\n );\n }\n const platform = values[\"--platform\"] ?? \"\";\n if (!isSendPlatform(platform)) {\n throw new ConversionArgsError(\n `\"${platform}\" is not somewhere a conversion can be sent — --platform is one of ${SEND_PLATFORMS.join(\", \")}.`,\n );\n }\n\n const event = values[\"--event\"] ?? \"\";\n const templated = sendEventProblem(platform, event);\n if (templated !== null) {\n throw new ConversionArgsError(`--event ${event} cannot be sent to ${platform}. ${templated}`);\n }\n\n const account = onlyOnce(raw.account, \"--account\", argv);\n const parameters = parseParameterArgs(argv);\n return {\n id: onlyOnce(raw.id, \"--id\", argv) ?? sendIdFor(now),\n eventKey: values[\"--source-event\"] ?? \"\",\n ...originFlag(raw, argv),\n platform,\n tagId: values[\"--tag\"] ?? \"\",\n event,\n ...(account === undefined ? {} : { account }),\n ...(parameters === undefined ? {} : { parameters }),\n };\n}\n\n/**\n * Which door's events `--set` uploads, as the send spells it: every door the\n * event arrives by (`origin: \"any\"`, the default — one event, one set of\n * destinations, uploaded once when the pixel and the API both report it under\n * one event id), or only the pixel's (`website`) or only the API's and the\n * integrations' (no field at all).\n */\nfunction originFlag(raw: Record<string, unknown>, argv: readonly string[]): { origin?: \"website\" | \"any\" } {\n const from = onlyOnce(raw.from, \"--from\", argv) ?? \"any\";\n if (from === \"any\") return { origin: \"any\" };\n if (from === \"api\") return {};\n if (from === \"pixel\") return { origin: \"website\" };\n throw new ConversionArgsError(\n `--from is any, pixel or api; got \"${from}\". any — the default — uploads the event whichever door it arrives by, once when the pixel and the API both report it with the same event id; pixel only what Baker's pixel sent from the client's website; api only what the API or an integration sent.`,\n );\n}\n\n/** A short id a person can type, when the caller did not choose one. */\nfunction sendIdFor(now: number): string {\n return `s${now.toString(36).slice(-5)}`;\n}\n\n/**\n * The request body, validated against the shared schema here rather than only\n * on the server, so a malformed send is named before a round trip.\n */\nexport function sendsWrite(args: SendsArgs): SendsRequest {\n const body = {\n ...(args.set === undefined ? {} : { set: [args.set] }),\n ...(args.remove === undefined ? {} : { remove: [args.remove] }),\n ...(args.days === undefined ? {} : { days: args.days }),\n ...(args.uploads === undefined ? {} : { uploads: args.uploads }),\n ...(args.failedOnly === undefined ? {} : { failedOnly: args.failedOnly }),\n ...(args.skippedOnly === undefined ? {} : { skippedOnly: args.skippedOnly }),\n };\n const parsed = sendsRequestSchema.safeParse(body);\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n throw new ConversionArgsError(\n `That send cannot be staged — ${issue?.path.join(\".\") || \"set\"}: ${issue?.message ?? \"invalid\"}. Run \\`baker schema analytics.sends\\` for the exact shape.`,\n );\n }\n return parsed.data;\n}\n\n/**\n * What to print. Compact by default: the sends with their outcomes, the\n * platforms with the tags that can send (where a `tagId` is copied from), and\n * the system events that can be sent. `carries` — every field a send forwards\n * — is the same list every time, so it is behind `--full`.\n */\nexport function sendsView(response: SendsResponse, full: boolean): Record<string, unknown> {\n const { carries, templateFields, ...rest } = response.data;\n return {\n ok: true,\n data: { ...rest, ...(full ? { carries, templateFields } : {}) },\n ...(response.hints && response.hints.length > 0 ? { hints: response.hints } : {}),\n };\n}\n\nconst args = {\n set: {\n type: \"boolean\",\n description:\n \"Stage a send, described by --source-event, --platform, --tag and --event. It applies when this chat is published, and from then on every event arriving under that key is uploaded to the platform and spends ad budget — say so to the client, never that it is a preview\",\n required: false,\n },\n \"source-event\": {\n type: \"string\",\n description:\n \"The event to send, by key — one of `events[].eventKey` from a plain `baker analytics sends`: a Source's own event (page:<source name>), or a named event the client's server posts. A Form's or a page's event is refused: the page's own pixels and the Form's side effects already send those\",\n required: false,\n },\n from: {\n type: \"string\",\n description:\n \"Which door's events the send uploads: `any` (default) — the event whichever door it arrives by, uploaded once when the pixel and the API both report it with the same event id; `pixel` — only what Baker's pixel sent from the client's own website (an `events[]` row with origin `website`); `api` — only what the client's server posted or an integration like HubSpot sent\",\n required: false,\n },\n platform: {\n type: \"string\",\n description: `Where it goes: one of ${SEND_PLATFORMS.join(\", \")}`,\n required: false,\n },\n tag: {\n type: \"string\",\n description:\n \"The tag on Tracking that sends it. COPY the id from `platforms[].tags[].tagId` in the response — it is only listed there when the tag holds its server credential, and one typed from memory is refused\",\n required: false,\n },\n event: {\n type: \"string\",\n description:\n 'What the platform calls it — `platforms[].eventMeans` says what each one takes: a Meta or Google Analytics event name (Purchase, Lead, generate_lead), a Google Ads conversion action id copied from `platforms[].conversionActions`, or the conversion label the person gives you (staged as its id; never type an id: one the account does not hold is refused), a LinkedIn conversion rule id, an X event tag id. On Meta and Google Analytics it may be WRITTEN FROM THE EVENT with the same {{path}} mentions --parameter takes: --event {{properties.plan}} sends each event under the plan it carries, --event \"Purchase {{properties.tier}}\" mixes text and a field. An event carrying nothing there is not uploaded. Google Ads, LinkedIn and X take an id THEY issued, so a template is refused there — pass what varies as a --parameter instead. For a GOOGLE ADS id, list the account\\'s conversion actions first and pick by name — `baker ads google query \"SELECT conversion_action.id, conversion_action.name, conversion_action.primary_for_goal FROM conversion_action WHERE conversion_action.status = \\'ENABLED\\'\"` — never guess: Google accepts an upload against an id the account does not hold and files it against nothing',\n required: false,\n },\n account: {\n type: \"string\",\n description: \"LinkedIn only: the ad account the conversion rule belongs to\",\n required: false,\n },\n parameter: {\n type: \"string\",\n description:\n \"<name>=<template>, repeatable, with --set: an EXTRA parameter the platform receives with every upload, beyond who, the click and the amount — Meta's custom_data (content_name, content_category, or your own), a GA4 event parameter, a Google Ads custom variable (must exist in the account), X's contents (content_name, num_items…); LinkedIn takes none. The template is text with {{path}} mentions over the event: its own properties as {{properties.<key>}} (a HubSpot event's --field properties.<key> rows, a server event's `properties`), and the fields `templateFields` lists (--full): value, value_currency, event_name, page_path, city, country, gclid… Example: --parameter content_name={{properties.plan}} --parameter content_category=hubspot. `parameters[]` in the response says what each platform takes\",\n required: false,\n },\n uploads: {\n type: \"string\",\n description:\n \"The id of a send (`sends[].id`) whose uploads to list, newest first over --days: which event went, when, `outcome` (success | failed | pending | skipped) and in `error` the platform's refusal in its own words or what a skipped event was missing — the rows behind `sends[].outcome`. With --failed, only the refused ones; with --skipped, only the skipped ones\",\n required: false,\n },\n failed: {\n type: \"boolean\",\n description: \"With --uploads: only the uploads the platform refused\",\n required: false,\n },\n skipped: {\n type: \"boolean\",\n description:\n \"With --uploads: only the events the send never uploaded because they carried nothing the platform matches a person by — each `error` names what was missing (a Meta click id or cookie, an email, a gclid…)\",\n required: false,\n },\n id: {\n type: \"string\",\n description:\n \"The send's id, when changing one that exists (`sends[].id` for a live one, `staged.set[].id` for one staged in this chat, like s1). Left out, a new id is minted and a NEW send is staged — so re-running a --set you already ran is refused, naming the send it would duplicate\",\n required: false,\n },\n remove: {\n type: \"string\",\n description: \"The id of a send to stop, from `sends[].id`. Staged like a set: it stops when the chat is published\",\n required: false,\n },\n days: {\n type: \"string\",\n description: \"How many days the outcome beside each send covers (default 30, up to 400)\",\n required: false,\n },\n full: {\n type: \"boolean\",\n description: \"Also return `carries`: every field a send forwards, the same for every send\",\n required: false,\n },\n} as const;\n\nregisterSchema({\n command: \"analytics.sends\",\n description: \"Read where this company's system events are sent, or stage a change\",\n args,\n});\n\nexport const sendsCommand = defineCommand({\n meta: {\n name: \"sends\",\n description: `Where this company's SYSTEM EVENTS are sent — Meta, Google Ads, LinkedIn, X, Google Analytics — and what happened to each upload. A send belongs to an event one of the client's own systems raises, by key: page:deal_won from HubSpot → Meta Purchase means every \"deal_won\" HubSpot reports is uploaded to Meta with who the person is, the click that brought them and the amount forwarded automatically. There is nothing to map. What happens on a page or in a Form is never sent from here — the page's pixels and the Form's own side effects do that — and a send is never set on a funnel step: the step reads the sends of the events behind its ways in.\n\nStart here:\n baker analytics sends — the sends in effect, each with its outcome; the platforms and the tags that can send; the system events (events[]) that can be sent\n baker analytics sends --set --source-event page:deal_won --platform meta --tag <tagId> --event Purchase\n baker analytics sends --set --source-event page:deal_won --platform googleAds --tag <tagId> --event 987654321\n baker analytics sends --set --source-event page:deal_won --platform meta --tag <tagId> --event Purchase --parameter content_name={{properties.plan}}\n baker analytics sends --set --source-event page:lead_completed_step_2 --platform meta --tag <tagId> --event Lead — an event the pixel and/or the API send; uploaded once per event id\n baker analytics sends --set --source-event page:deal_won --platform meta --tag <tagId> --event {{properties.plan}} — a Meta event named after what each one carries\n baker analytics sends --remove s1 — stop one\n baker analytics sends --days 7 — outcomes over the last week\n baker analytics sends --uploads s1 --failed — the uploads Meta refused, each with the event and Meta's own words\n baker analytics sends --uploads s1 --skipped — the events never uploaded, each with what the platform needed and they lacked\n\nThree things to hold on to:\n it is STAGED — a set or a remove lands when this chat is published, and from then on it SPENDS AD BUDGET on every \"<event>\" that arrives. Tell the client that plainly; never call a published send a preview.\n the tagId is COPIED — from \\`platforms[].tags\\` in the response, which lists only the tags on Tracking that hold their server credential. One typed from memory is refused; a platform with no tag listed says what to add on Tracking (\\`platforms[].setupHint\\`).\n the outcome is what happened — \\`sends[].outcome\\` counts what was sent, what failed and why (\\`lastError\\`, in the platform's words), and what was SKIPPED: an event carrying nothing the platform matches a person by is never uploaded (Meta: a Meta click id or cookie, an email or your own customer id; Google Ads: gclid, wbraid, gbraid, an email or a phone; LinkedIn: li_fat_id or an email; X: twclid or an email; Google Analytics: nothing), counted in \\`skipped\\` with \\`lastSkipReason\\`.\n check the MATCH before staging — \\`events[].match\\` says, for the last 30 days of each event, how many arrived and how many each platform could match. A send to a platform matching 0 of 14 skips all 14: say so to the client, and ask for the click id or the email to be sent with the event instead. \"Nothing sent yet\" means no event under that name has fired since the send was set. \\`--uploads <id>\\` lists the rows behind the count, \\`--failed\\` only the refused ones — read it before telling a client a send \"failed\".\n a Meta or GA4 event name can be WRITTEN FROM THE EVENT — \\`--event {{properties.plan}}\\` sends each event under its own plan, so one Source covers every value instead of one Source, one send and one conversion action per value. Only where the platform takes a name of your own: Google Ads, LinkedIn and X take an id they issued and refuse a template.\n extra parameters are optional — \\`--parameter <name>=<template>\\` adds what the platform receives beyond who, the click and the amount: \\`{{properties.<key>}}\\` reads a property the event carries (a HubSpot event's \\`--field properties.<key>\\` rows), \\`{{value}}\\`, \\`{{page_path}}\\`, \\`{{city}}\\`… read the event's fields. \\`parameters[]\\` in the response says what each platform takes and the names it knows; LinkedIn takes none.\n\nAn empty \\`events[]\\` means none of the client's systems sends an event yet and there is nothing to send: make a Source with \\`baker analytics sources\\` (a HubSpot event, or the server's address), then send its event.`,\n },\n args,\n run: async ({ args: raw }) => {\n try {\n const parsed = parseSendsArgs(raw as Record<string, unknown>, process.argv);\n const response = await apiPost<SendsResponse>(\"/api/analytics/sends\", sendsWrite(parsed));\n writeJsonEnvelope(sendsView(response, parsed.full));\n } catch (err) {\n handleError(err);\n }\n },\n});\n\nfunction handleError(err: unknown): never {\n if (err instanceof ConversionArgsError) {\n writeJsonEnvelope({ ok: false, error: { code: \"VALIDATION_ERROR\", message: err.message } });\n process.exit(1);\n }\n if (err instanceof ApiError) {\n writeJsonEnvelope({ ok: false, error: { code: err.code, message: err.message } });\n process.exit(1);\n }\n writeJsonEnvelope({\n ok: false,\n error: { code: \"NETWORK_ERROR\", message: err instanceof Error ? err.message : \"Unexpected error\" },\n });\n process.exit(1);\n}\n"],"mappings":"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","names":["args"]}
|
|
1
|
+
{"version":3,"sources":["../src/commands/analytics/sends.ts"],"sourcesContent":["/**\n * `baker analytics sends` — where this company's system events are sent, and\n * changing it.\n *\n * A send hangs off an event one of the client's own systems raises, by its\n * key: `page:deal_won` from HubSpot → Meta Purchase. Every such event is\n * uploaded to the platform with who the person is, the click that brought\n * them and the amount forwarded automatically. Nothing is mapped. What happens\n * on a page or in a Form is not sendable here: the page's own pixels and the\n * Form's own side effects already send those.\n *\n * A write STAGES: it lands when the chat is published, and from then on it\n * spends ad budget on every event under the key. The dashboard's Sources page\n * applies at once because the person clicking is the review; an agent's\n * proposal gets its review at Publish.\n */\n\nimport {\n isSendPlatform,\n SEND_PLATFORMS,\n type SendsRequest,\n type SendsResponse,\n sendEventProblem,\n sendsRequestSchema,\n} from \"@baker/api/analytics\";\nimport { defineCommand } from \"citty\";\nimport { ApiError, apiPost } from \"../../client.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { writeJsonEnvelope } from \"../ads/output.ts\";\nimport { ConversionArgsError, onlyOnce } from \"./conversionArgs.ts\";\n\nexport interface SendsArgs {\n set?: {\n id: string;\n eventKey: string;\n platform: string;\n tagId: string;\n event: string;\n account?: string;\n parameters?: Record<string, string>;\n };\n remove?: string;\n days?: number;\n /** One send's uploads, by id, and whether only the refused ones. */\n uploads?: string;\n failedOnly?: boolean;\n /** With `uploads`: only the events it skipped, for want of anything to match. */\n skippedOnly?: boolean;\n full: boolean;\n}\n\nconst SET_FLAGS = [\"--source-event\", \"--platform\", \"--tag\", \"--event\"] as const;\n\n/**\n * The flags, checked for the shapes that would otherwise stage the wrong\n * send in silence. Pure, so the refusals are tier-1 tested.\n */\nexport function parseSendsArgs(raw: Record<string, unknown>, argv: readonly string[], now = Date.now()): SendsArgs {\n const set = parseSetFlags(raw, argv, now);\n const remove = onlyOnce(raw.remove, \"--remove\", argv);\n\n const days = raw.days === undefined ? undefined : Number(raw.days);\n if (days !== undefined && (!Number.isInteger(days) || days <= 0 || days > 400)) {\n throw new ConversionArgsError(\"--days must be a whole number of days, from 1 to 400.\");\n }\n\n const uploads = onlyOnce(raw.uploads, \"--uploads\", argv);\n if (raw.failed === true && uploads === undefined) {\n throw new ConversionArgsError(\"--failed narrows --uploads <sendId> to the refused ones; name the send.\");\n }\n if (raw.skipped === true && uploads === undefined) {\n throw new ConversionArgsError(\n \"--skipped narrows --uploads <sendId> to the events it never uploaded; name the send.\",\n );\n }\n\n return {\n ...(set === undefined ? {} : { set }),\n ...(remove === undefined ? {} : { remove }),\n ...(days === undefined ? {} : { days }),\n ...(uploads === undefined ? {} : { uploads }),\n ...(raw.failed === true ? { failedOnly: true } : {}),\n ...(raw.skipped === true ? { skippedOnly: true } : {}),\n full: raw.full === true,\n };\n}\n\n/** The value a repeated flag carries at this position, in either spelling, or nothing. */\nfunction flagValueAt(argv: readonly string[], flag: string, index: number): string | undefined {\n const arg = argv[index] ?? \"\";\n if (arg === flag) return argv[index + 1];\n return arg.startsWith(`${flag}=`) ? arg.slice(flag.length + 1) : undefined;\n}\n\n/**\n * Every `--parameter name=template` on the command line, in order. Read off\n * argv rather than the parsed args because citty keeps only the last value\n * of a repeated flag — the defect that once staged one of three UTMs.\n */\nexport function parseParameterArgs(argv: readonly string[]): Record<string, string> | undefined {\n const parameters: Record<string, string> = {};\n for (let index = 0; index < argv.length; index += 1) {\n const pair = flagValueAt(argv, \"--parameter\", index);\n if (pair === undefined) continue;\n const eq = pair.indexOf(\"=\");\n const name = (eq === -1 ? pair : pair.slice(0, eq)).trim();\n const template = eq === -1 ? \"\" : pair.slice(eq + 1).trim();\n if (name === \"\" || template === \"\") {\n throw new ConversionArgsError(\n `--parameter needs <name>=<template>, like --parameter content_name={{properties.plan}}; got \"${pair}\".`,\n );\n }\n parameters[name] = template;\n }\n return Object.keys(parameters).length === 0 ? undefined : parameters;\n}\n\n/**\n * The send `--set` describes, or nothing on a read.\n *\n * The four flags are only meaningful together and only under `--set`: a send\n * described without it would answer ok and stage nothing, and a `--set` with\n * a piece missing would be refused by the server with the field named but not\n * the flag.\n */\nfunction parseSetFlags(raw: Record<string, unknown>, argv: readonly string[], now: number): SendsArgs[\"set\"] {\n if (raw.conversion !== undefined) {\n throw new ConversionArgsError(\n \"--conversion is gone: a send is on a system's EVENT, not a conversion. Pass --source-event <key> — one of events[].eventKey from a plain `baker analytics sends` (page:<name>).\",\n );\n }\n const values = {\n \"--source-event\": onlyOnce(raw[\"source-event\"] ?? raw.sourceEvent, \"--source-event\", argv),\n \"--platform\": onlyOnce(raw.platform, \"--platform\", argv),\n \"--tag\": onlyOnce(raw.tag, \"--tag\", argv),\n \"--event\": onlyOnce(raw.event, \"--event\", argv),\n };\n const given = SET_FLAGS.filter((flag) => values[flag] !== undefined);\n const set = raw.set === true;\n\n if (!set) {\n if (given.length > 0) {\n throw new ConversionArgsError(\n `${given.join(\", \")} describe a send, so add --set to stage it. Without --set the command only reads.`,\n );\n }\n return undefined;\n }\n\n const missing = SET_FLAGS.filter((flag) => values[flag] === undefined);\n if (missing.length > 0) {\n throw new ConversionArgsError(\n `--set needs ${SET_FLAGS.join(\", \")}; missing ${missing.join(\", \")}. Copy --tag from platforms[].tags of a plain \\`baker analytics sends\\`, never from memory.`,\n );\n }\n const platform = values[\"--platform\"] ?? \"\";\n if (!isSendPlatform(platform)) {\n throw new ConversionArgsError(\n `\"${platform}\" is not somewhere a conversion can be sent — --platform is one of ${SEND_PLATFORMS.join(\", \")}.`,\n );\n }\n\n const event = values[\"--event\"] ?? \"\";\n const templated = sendEventProblem(platform, event);\n if (templated !== null) {\n throw new ConversionArgsError(`--event ${event} cannot be sent to ${platform}. ${templated}`);\n }\n\n const account = onlyOnce(raw.account, \"--account\", argv);\n const parameters = parseParameterArgs(argv);\n return {\n id: onlyOnce(raw.id, \"--id\", argv) ?? sendIdFor(now),\n eventKey: values[\"--source-event\"] ?? \"\",\n ...originFlag(raw, argv),\n platform,\n tagId: values[\"--tag\"] ?? \"\",\n event,\n ...(account === undefined ? {} : { account }),\n ...(parameters === undefined ? {} : { parameters }),\n };\n}\n\n/**\n * Which door's events `--set` uploads, as the send spells it: every door the\n * event arrives by (`origin: \"any\"`, the default — one event, one set of\n * destinations, uploaded once when the pixel and the API both report it under\n * one event id), or only the pixel's (`website`) or only the API's and the\n * integrations' (no field at all).\n */\nfunction originFlag(raw: Record<string, unknown>, argv: readonly string[]): { origin?: \"website\" | \"any\" } {\n const from = onlyOnce(raw.from, \"--from\", argv) ?? \"any\";\n if (from === \"any\") return { origin: \"any\" };\n if (from === \"api\") return {};\n if (from === \"pixel\") return { origin: \"website\" };\n throw new ConversionArgsError(\n `--from is any, pixel or api; got \"${from}\". any — the default — uploads the event whichever door it arrives by, once when the pixel and the API both report it with the same event id; pixel only what Baker's pixel sent from the client's website; api only what the API or an integration sent.`,\n );\n}\n\n/** A short id a person can type, when the caller did not choose one. */\nfunction sendIdFor(now: number): string {\n return `s${now.toString(36).slice(-5)}`;\n}\n\n/**\n * The request body, validated against the shared schema here rather than only\n * on the server, so a malformed send is named before a round trip.\n */\nexport function sendsWrite(args: SendsArgs): SendsRequest {\n const body = {\n ...(args.set === undefined ? {} : { set: [args.set] }),\n ...(args.remove === undefined ? {} : { remove: [args.remove] }),\n ...(args.days === undefined ? {} : { days: args.days }),\n ...(args.uploads === undefined ? {} : { uploads: args.uploads }),\n ...(args.failedOnly === undefined ? {} : { failedOnly: args.failedOnly }),\n ...(args.skippedOnly === undefined ? {} : { skippedOnly: args.skippedOnly }),\n };\n const parsed = sendsRequestSchema.safeParse(body);\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n throw new ConversionArgsError(\n `That send cannot be staged — ${issue?.path.join(\".\") || \"set\"}: ${issue?.message ?? \"invalid\"}. Run \\`baker schema analytics.sends\\` for the exact shape.`,\n );\n }\n return parsed.data;\n}\n\n/**\n * What to print. Compact by default: the sends with their outcomes, the\n * platforms with the tags that can send (where a `tagId` is copied from), and\n * the system events that can be sent. `carries` — every field a send forwards\n * — is the same list every time, so it is behind `--full`.\n */\nexport function sendsView(response: SendsResponse, full: boolean): Record<string, unknown> {\n const { carries, templateFields, ...rest } = response.data;\n return {\n ok: true,\n data: { ...rest, ...(full ? { carries, templateFields } : {}) },\n ...(response.hints && response.hints.length > 0 ? { hints: response.hints } : {}),\n };\n}\n\nconst args = {\n set: {\n type: \"boolean\",\n description:\n \"Stage a send, described by --source-event, --platform, --tag and --event. It applies when this chat is published, and from then on every event arriving under that key is uploaded to the platform and spends ad budget — say so to the client, never that it is a preview\",\n required: false,\n },\n \"source-event\": {\n type: \"string\",\n description:\n \"The event to send, by key — one of `events[].eventKey` from a plain `baker analytics sends`: a Source's own event (page:<source name>), or a named event the client's server posts. A Form's or a page's event is refused: the page's own pixels and the Form's side effects already send those\",\n required: false,\n },\n from: {\n type: \"string\",\n description:\n \"Which door's events the send uploads: `any` (default) — the event whichever door it arrives by, uploaded once when the pixel and the API both report it with the same event id; `pixel` — only what Baker's pixel sent from the client's own website (an `events[]` row with origin `website`); `api` — only what the client's server posted or an integration like HubSpot sent\",\n required: false,\n },\n platform: {\n type: \"string\",\n description: `Where it goes: one of ${SEND_PLATFORMS.join(\", \")}`,\n required: false,\n },\n tag: {\n type: \"string\",\n description:\n \"The tag on Tracking that sends it. COPY the id from `platforms[].tags[].tagId` in the response — it is only listed there when the tag holds its server credential, and one typed from memory is refused\",\n required: false,\n },\n event: {\n type: \"string\",\n description:\n 'What the platform calls it — `platforms[].eventMeans` says what each one takes: a Meta or Google Analytics event name (Purchase, Lead, generate_lead), a Google Ads conversion action id copied from `platforms[].conversionActions`, or the conversion label the person gives you (staged as its id; never type an id: one the account does not hold is refused), a LinkedIn conversion rule id, an X event tag id. On Meta and Google Analytics it may be WRITTEN FROM THE EVENT with the same {{path}} mentions --parameter takes: --event {{properties.plan}} sends each event under the plan it carries, --event \"Purchase {{properties.tier}}\" mixes text and a field. An event carrying nothing there is not uploaded. Google Ads, LinkedIn and X take an id THEY issued, so a template is refused there — pass what varies as a --parameter instead. For a GOOGLE ADS id, list the account\\'s conversion actions first and pick by name — `baker ads google query \"SELECT conversion_action.id, conversion_action.name, conversion_action.primary_for_goal FROM conversion_action WHERE conversion_action.status = \\'ENABLED\\'\"` — never guess: Google accepts an upload against an id the account does not hold and files it against nothing',\n required: false,\n },\n account: {\n type: \"string\",\n description: \"LinkedIn only: the ad account the conversion rule belongs to\",\n required: false,\n },\n parameter: {\n type: \"string\",\n description:\n \"<name>=<template>, repeatable, with --set: an EXTRA parameter the platform receives with every upload, beyond who, the click and the amount — Meta's custom_data (content_name, content_category, or your own), a GA4 event parameter, a Google Ads custom variable (must exist in the account), X's contents (content_name, num_items…); LinkedIn takes none. The template is text with {{path}} mentions over the event: its own properties as {{properties.<key>}} (a HubSpot event's --field properties.<key> rows, a server event's `properties`), and the fields `templateFields` lists (--full): value, value_currency, event_name, page_path, city, country, gclid… Example: --parameter content_name={{properties.plan}} --parameter content_category=hubspot. `parameters[]` in the response says what each platform takes\",\n required: false,\n },\n uploads: {\n type: \"string\",\n description:\n \"The id of a send (`sends[].id`) whose uploads to list, newest first over --days: which event went, when, `outcome` (success | failed | pending | skipped) and in `error` the platform's refusal in its own words or what a skipped event was missing — the rows behind `sends[].outcome`. With --failed, only the refused ones; with --skipped, only the skipped ones\",\n required: false,\n },\n failed: {\n type: \"boolean\",\n description: \"With --uploads: only the uploads the platform refused\",\n required: false,\n },\n skipped: {\n type: \"boolean\",\n description:\n \"With --uploads: only the events the send never uploaded because they carried nothing the platform matches a person by — each `error` names what was missing (a Meta click id or cookie, an email, a gclid…)\",\n required: false,\n },\n id: {\n type: \"string\",\n description:\n \"The send's id, when changing one that exists (`sends[].id` for a live one, `staged.set[].id` for one staged in this chat, like s1). Left out, a new id is minted and a NEW send is staged — so re-running a --set you already ran is refused, naming the send it would duplicate\",\n required: false,\n },\n remove: {\n type: \"string\",\n description: \"The id of a send to stop, from `sends[].id`. Staged like a set: it stops when the chat is published\",\n required: false,\n },\n days: {\n type: \"string\",\n description: \"How many days the outcome beside each send covers (default 30, up to 400)\",\n required: false,\n },\n full: {\n type: \"boolean\",\n description: \"Also return `carries`: every field a send forwards, the same for every send\",\n required: false,\n },\n} as const;\n\nregisterSchema({\n command: \"analytics.sends\",\n description: \"Read where this company's system events are sent, or stage a change\",\n args,\n});\n\nexport const sendsCommand = defineCommand({\n meta: {\n name: \"sends\",\n description: `Where this company's SYSTEM EVENTS are sent — Meta, Google Ads, LinkedIn, X, Google Analytics — and what happened to each upload. A send belongs to an event one of the client's own systems raises, by key: page:deal_won from HubSpot → Meta Purchase means every \"deal_won\" HubSpot reports is uploaded to Meta with who the person is, the click that brought them and the amount forwarded automatically. There is nothing to map. What happens on a page or in a Form is never sent from here — the page's pixels and the Form's own side effects do that — and a send is never set on a funnel step: the step reads the sends of the events behind its ways in.\n\nStart here:\n baker analytics sends — the sends in effect, each with its outcome; the platforms and the tags that can send; the system events (events[]) that can be sent\n baker analytics sends --set --source-event page:deal_won --platform meta --tag <tagId> --event Purchase\n baker analytics sends --set --source-event page:deal_won --platform googleAds --tag <tagId> --event 987654321\n baker analytics sends --set --source-event page:deal_won --platform meta --tag <tagId> --event Purchase --parameter content_name={{properties.plan}}\n baker analytics sends --set --source-event page:lead_completed_step_2 --platform meta --tag <tagId> --event Lead — an event the pixel and/or the API send; uploaded once per event id\n baker analytics sends --set --source-event page:deal_won --platform meta --tag <tagId> --event {{properties.plan}} — a Meta event named after what each one carries\n baker analytics sends --remove s1 — stop one\n baker analytics sends --days 7 — outcomes over the last week\n baker analytics sends --uploads s1 --failed — the uploads Meta refused, each with the event and Meta's own words\n baker analytics sends --uploads s1 --skipped — the events never uploaded, each with what the platform needed and they lacked\n\nThree things to hold on to:\n it is STAGED — a set or a remove lands when this chat is published, and from then on it SPENDS AD BUDGET on every \"<event>\" that arrives. Tell the client that plainly; never call a published send a preview.\n the tagId is COPIED — from \\`platforms[].tags\\` in the response, which lists only the tags on Tracking that hold their server credential. One typed from memory is refused; a platform with no tag listed says what to add on Tracking (\\`platforms[].setupHint\\`).\n the outcome is what happened — \\`sends[].outcome\\` counts what was sent, what failed and why (\\`lastError\\`, in the platform's words), and what was SKIPPED: an event carrying nothing the platform matches a person by is never uploaded (Meta: a Meta click id or cookie, an email or your own customer id; Google Ads: gclid, wbraid, gbraid, an email or a phone; LinkedIn: li_fat_id or an email; X: twclid or an email; Google Analytics: nothing), counted in \\`skipped\\` with \\`lastSkipReason\\`.\n check the MATCH before staging — \\`events[].match\\` says, for the last 30 days of each event, how many arrived and how many each platform could match. A send to a platform matching 0 of 14 skips all 14: say so to the client, and ask for the click id or the email to be sent with the event instead. \"Nothing sent yet\" means no event under that name has fired since the send was set. \\`--uploads <id>\\` lists the rows behind the count, \\`--failed\\` only the refused ones — read it before telling a client a send \"failed\".\n a Meta or GA4 event name can be WRITTEN FROM THE EVENT — \\`--event {{properties.plan}}\\` sends each event under its own plan, so one Source covers every value instead of one Source, one send and one conversion action per value. Only where the platform takes a name of your own: Google Ads, LinkedIn and X take an id they issued and refuse a template.\n extra parameters are optional — \\`--parameter <name>=<template>\\` adds what the platform receives beyond who, the click and the amount: \\`{{properties.<key>}}\\` reads a property the event carries (a HubSpot event's \\`--field properties.<key>\\` rows), \\`{{value}}\\`, \\`{{page_path}}\\`, \\`{{city}}\\`… read the event's fields. \\`parameters[]\\` in the response says what each platform takes and the names it knows; LinkedIn takes none.\n\nAn empty \\`events[]\\` means none of the client's systems sends an event yet and there is nothing to send: make a Source with \\`baker analytics sources\\` (a HubSpot event, or the server's address), then send its event.`,\n },\n args,\n run: async ({ args: raw }) => {\n try {\n const parsed = parseSendsArgs(raw as Record<string, unknown>, process.argv);\n const response = await apiPost<SendsResponse>(\"/api/analytics/sends\", sendsWrite(parsed));\n writeJsonEnvelope(sendsView(response, parsed.full));\n } catch (err) {\n handleError(err);\n }\n },\n});\n\nfunction handleError(err: unknown): never {\n if (err instanceof ConversionArgsError) {\n writeJsonEnvelope({ ok: false, error: { code: \"VALIDATION_ERROR\", message: err.message } });\n process.exit(1);\n }\n if (err instanceof ApiError) {\n writeJsonEnvelope({ ok: false, error: { code: err.code, message: err.message } });\n process.exit(1);\n }\n writeJsonEnvelope({\n ok: false,\n error: { code: \"NETWORK_ERROR\", message: err instanceof Error ? err.message : \"Unexpected error\" },\n });\n process.exit(1);\n}\n"],"mappings":"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","names":["args"]}
|
|
@@ -4,21 +4,21 @@ import {
|
|
|
4
4
|
compiledPromptNodeIds,
|
|
5
5
|
prepareCanvas,
|
|
6
6
|
sceneOwnedPrompts
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YUCLMOEG.js";
|
|
8
8
|
import "./chunk-4QEY2L6U.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-QRP3PXWN.js";
|
|
10
|
+
import "./chunk-3IBYKLXR.js";
|
|
11
11
|
import "./chunk-F2S5BLPE.js";
|
|
12
12
|
import "./chunk-WTOYCUKH.js";
|
|
13
13
|
import "./chunk-DZSIUEGH.js";
|
|
14
14
|
import {
|
|
15
15
|
defaultRegistry,
|
|
16
16
|
validateCanvasDeep
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-OQ6663F4.js";
|
|
18
|
+
import "./chunk-EBWBG6YV.js";
|
|
19
|
+
import "./chunk-W3B4BHQU.js";
|
|
19
20
|
import "./chunk-NCWCZY5P.js";
|
|
20
21
|
import "./chunk-DGCUPJZD.js";
|
|
21
|
-
import "./chunk-W3B4BHQU.js";
|
|
22
22
|
import {
|
|
23
23
|
COPY_DIRECTIVE_HEADER
|
|
24
24
|
} from "./chunk-PZXCWSKV.js";
|
|
@@ -30,11 +30,10 @@ import "./chunk-VAJBWA2U.js";
|
|
|
30
30
|
import "./chunk-HRYOZUSK.js";
|
|
31
31
|
import "./chunk-VVZBBKRC.js";
|
|
32
32
|
import "./chunk-YBMVHGY3.js";
|
|
33
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-XF4JUKVF.js";
|
|
34
34
|
import "./chunk-GXDLWBOY.js";
|
|
35
35
|
import "./chunk-TEINLN64.js";
|
|
36
36
|
import "./chunk-ZJWUBJYQ.js";
|
|
37
|
-
import "./chunk-HR6IWNKE.js";
|
|
38
37
|
import "./chunk-NE4F3FHN.js";
|
|
39
38
|
import "./chunk-IFWP3ZDO.js";
|
|
40
39
|
import "./chunk-NAWWC5I3.js";
|
|
@@ -184,4 +183,4 @@ export {
|
|
|
184
183
|
setPromptCommand,
|
|
185
184
|
setPromptInCanvasFile
|
|
186
185
|
};
|
|
187
|
-
//# sourceMappingURL=set-prompt-
|
|
186
|
+
//# sourceMappingURL=set-prompt-5E5I7QAZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/canvas/set-prompt.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { defineCommand } from \"citty\";\nimport { defaultRegistry, validateCanvasDeep } from \"../../engine/index.ts\";\nimport { COPY_DIRECTIVE_HEADER } from \"../../engine/scaffold/static-copy.ts\";\nimport { adaptNodes } from \"../../engine/scaffold/static-adapt-briefs.ts\";\nimport { compiledPromptNodeIds } from \"../../engine/scaffold/static-render-briefs.ts\";\nimport { CanvasPrepareError, prepareCanvas } from \"./prepare-canvas.ts\";\nimport { sceneOwnedPrompts } from \"./scene-projection.ts\";\n\n/**\n * Set one node's `params.prompt` in a parsed canvas, returning a NEW canvas. The\n * structured alternative to hand-editing a 133 KB machine JSON with jq/sed — which\n * is where `\"prompt\": null` pollution (a global `gsub` writing prompt onto every\n * node) and the French-accent corruption (shell `''` eating apostrophes) came from.\n * Throws when the node id is unknown. Pure — unit-tested without the filesystem.\n */\nexport function setNodePrompt(canvas: unknown, nodeId: string, text: string): unknown {\n const nodes = (canvas as { nodes?: unknown })?.nodes;\n if (!Array.isArray(nodes)) throw new Error(\"canvas has no nodes array\");\n const idx = nodes.findIndex((n) => (n as { id?: unknown })?.id === nodeId);\n if (idx < 0) {\n const ids = nodes.map((n) => (n as { id?: unknown })?.id).filter((id): id is string => typeof id === \"string\");\n throw new Error(`node \"${nodeId}\" not found. Known nodes: ${ids.join(\", \")}`);\n }\n const node = nodes[idx] as { params?: Record<string, unknown> };\n const newNode = { ...node, params: { ...(node.params ?? {}), prompt: text } };\n const newNodes = [...nodes];\n newNodes[idx] = newNode;\n return { ...(canvas as object), nodes: newNodes };\n}\n\n/** Why `set-prompt` did not write: the node's prompt is owned elsewhere, or the edit does not validate. */\nexport class SetPromptError extends Error {\n readonly code: string;\n readonly fix: string | undefined;\n readonly details: Record<string, unknown> | undefined;\n constructor(code: string, message: string, opts: { fix?: string; details?: Record<string, unknown> } = {}) {\n super(message);\n this.name = \"SetPromptError\";\n this.code = code;\n this.fix = opts.fix;\n this.details = opts.details;\n }\n}\n\n/**\n * Set a node's prompt in the canvas FILE, where it will survive.\n *\n * The canvas is a projection of its blueprint, and `prepareCanvas` rewrites the projected\n * parts on every validate and run. So:\n * - a frame or clip prompt a scene file rebuilds is refused, naming the scene file to edit\n * (writing it here would be silently overwritten by the next preflight);\n * - a static ad's scaffolded render prompt (a take, a re-lay, the judge) is refused, naming\n * prompt.json: it is compiled from the ad spec there on every run;\n * - a hand-written static render prompt keeps its copy block: the text replaces the scene\n * description, and the \"render these exact strings\" block after it is re-read from\n * prompt.json, as always;\n * - anything else is the canvas's own, and is written.\n * The result is validated; an edit that does not validate is undone.\n */\nexport async function setPromptInCanvasFile(canvasPath: string, nodeId: string, text: string): Promise<void> {\n const filePath = path.resolve(canvasPath);\n const original = await readFile(filePath, \"utf8\");\n let canvas: unknown;\n try {\n canvas = JSON.parse(original);\n } catch (e) {\n throw new SetPromptError(\"parse\", `${filePath}: JSON parse error: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n const sceneFile = (await sceneOwnedPrompts(filePath)).get(nodeId);\n if (sceneFile) {\n throw new SetPromptError(\n \"projected_prompt\",\n `The prompt of \"${nodeId}\" is rebuilt from ${sceneFile} on every validate and run, so setting it in the canvas would be overwritten.`,\n {\n fix: `Edit the scene's description in ${sceneFile} (its frame and motion fields, e.g. start_frame_prompt, end_frame_prompt, frame_prompt, motion_prompt), then run \\`baker canvas validate\\` to see the rebuilt prompt.`,\n },\n );\n }\n\n if (compiledPromptNodeIds(canvas).has(nodeId) || adaptNodes(canvas).some((a) => a.node.id === nodeId)) {\n throw new SetPromptError(\n \"projected_prompt\",\n `The prompt of \"${nodeId}\" is compiled from prompt.json on every validate and run, so setting it in the canvas would be overwritten.`,\n {\n fix: `Edit the ad in ${path.join(path.dirname(filePath), \"prompt.json\")} (its scene, copy, references or direction), then run \\`baker canvas validate\\` to see the compiled prompt on the node.`,\n },\n );\n }\n\n let updated: unknown;\n try {\n updated = setNodePrompt(canvas, nodeId, withCopyBlock(canvas, nodeId, text));\n } catch (e) {\n throw new SetPromptError(\"node_not_found\", e instanceof Error ? e.message : String(e));\n }\n\n await writeFile(filePath, `${JSON.stringify(updated, null, 2)}\\n`, \"utf8\");\n const restore = () => writeFile(filePath, original, \"utf8\");\n try {\n const prepared = await prepareCanvas(filePath);\n const validation = await validateCanvasDeep(prepared.canvas, defaultRegistry());\n if (!validation.ok) {\n await restore();\n throw new SetPromptError(\"validation\", \"The edited canvas does not validate; nothing was changed.\", {\n details: { issues: validation.issues },\n });\n }\n } catch (e) {\n if (e instanceof SetPromptError) throw e;\n await restore();\n if (e instanceof CanvasPrepareError) {\n throw new SetPromptError(e.code, e.message, { ...(e.fix ? { fix: e.fix } : {}), ...(e.details ? { details: e.details } : {}) });\n }\n throw e;\n }\n}\n\n/**\n * A static ad's render prompt ends with the copy block the preflight fills from prompt.json.\n * New text that leaves it out keeps it, so replacing the scene description never drops the\n * words the ad must show.\n */\nfunction withCopyBlock(canvas: unknown, nodeId: string, text: string): string {\n const nodes = (canvas as { nodes?: unknown })?.nodes;\n const current = Array.isArray(nodes)\n ? (nodes as Array<{ id?: unknown; params?: { prompt?: unknown } }>).find((n) => n?.id === nodeId)?.params?.prompt\n : undefined;\n if (typeof current !== \"string\" || !current.includes(COPY_DIRECTIVE_HEADER) || text.includes(COPY_DIRECTIVE_HEADER)) {\n return text;\n }\n return `${text.trimEnd()}\\n\\n${COPY_DIRECTIVE_HEADER}`;\n}\n\nexport const setPromptCommand = defineCommand({\n meta: {\n name: \"set-prompt\",\n description:\n \"Safely set a node's params.prompt (a frame description, motion prompt, etc.) without hand-editing the JSON. Prefer --text-file for multi-line/accented copy — it preserves UTF-8 exactly, unlike shell-quoted jq. A prompt rebuilt from a scene file (scenes/sNN.json), or compiled from a static ad's prompt.json, is refused with the file to edit instead.\",\n },\n args: {\n file: { type: \"positional\", required: true, description: \"Path to canvas JSON\" },\n node: { type: \"positional\", required: true, description: \"Node id to edit (e.g. s0_start)\" },\n text: { type: \"string\", description: \"New prompt text (inline)\" },\n \"text-file\": { type: \"string\", description: \"Read the new prompt from a UTF-8 file (preserves accents/newlines)\" },\n },\n async run({ args }) {\n let text: string;\n if (args[\"text-file\"]) text = await readFile(path.resolve(String(args[\"text-file\"])), \"utf8\");\n else if (args.text !== undefined) text = String(args.text);\n else {\n process.stderr.write(\n `${JSON.stringify({ ok: false, error: { code: \"no_text\", message: \"pass --text or --text-file\" } }, null, 2)}\\n`,\n );\n process.exit(2);\n return;\n }\n\n try {\n await setPromptInCanvasFile(String(args.file), String(args.node), text);\n } catch (e) {\n if (!(e instanceof SetPromptError)) throw e;\n process.stderr.write(\n `${JSON.stringify(\n { ok: false, error: { code: e.code, message: e.message, ...(e.fix ? { fix: e.fix } : {}), ...(e.details ?? {}) } },\n null,\n 2,\n )}\\n`,\n );\n process.exit(2);\n return;\n }\n process.stdout.write(`${JSON.stringify({ ok: true, node: String(args.node), bytes: text.length }, null, 2)}\\n`);\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,UAAU,iBAAiB;AACpC,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAevB,SAAS,cAAc,QAAiB,QAAgB,MAAuB;AACpF,QAAM,QAAS,QAAgC;AAC/C,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,OAAM,IAAI,MAAM,2BAA2B;AACtE,QAAM,MAAM,MAAM,UAAU,CAAC,MAAO,GAAwB,OAAO,MAAM;AACzE,MAAI,MAAM,GAAG;AACX,UAAM,MAAM,MAAM,IAAI,CAAC,MAAO,GAAwB,EAAE,EAAE,OAAO,CAAC,OAAqB,OAAO,OAAO,QAAQ;AAC7G,UAAM,IAAI,MAAM,SAAS,MAAM,6BAA6B,IAAI,KAAK,IAAI,CAAC,EAAE;AAAA,EAC9E;AACA,QAAM,OAAO,MAAM,GAAG;AACtB,QAAM,UAAU,EAAE,GAAG,MAAM,QAAQ,EAAE,GAAI,KAAK,UAAU,CAAC,GAAI,QAAQ,KAAK,EAAE;AAC5E,QAAM,WAAW,CAAC,GAAG,KAAK;AAC1B,WAAS,GAAG,IAAI;AAChB,SAAO,EAAE,GAAI,QAAmB,OAAO,SAAS;AAClD;AAGO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACT,YAAY,MAAc,SAAiB,OAA4D,CAAC,GAAG;AACzG,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,MAAM,KAAK;AAChB,SAAK,UAAU,KAAK;AAAA,EACtB;AACF;AAiBA,eAAsB,sBAAsB,YAAoB,QAAgB,MAA6B;AAC3G,QAAM,WAAW,KAAK,QAAQ,UAAU;AACxC,QAAM,WAAW,MAAM,SAAS,UAAU,MAAM;AAChD,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,QAAQ;AAAA,EAC9B,SAAS,GAAG;AACV,UAAM,IAAI,eAAe,SAAS,GAAG,QAAQ,uBAAuB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,EAClH;AAEA,QAAM,aAAa,MAAM,kBAAkB,QAAQ,GAAG,IAAI,MAAM;AAChE,MAAI,WAAW;AACb,UAAM,IAAI;AAAA,MACR;AAAA,MACA,kBAAkB,MAAM,qBAAqB,SAAS;AAAA,MACtD;AAAA,QACE,KAAK,mCAAmC,SAAS;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,sBAAsB,MAAM,EAAE,IAAI,MAAM,KAAK,WAAW,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,OAAO,MAAM,GAAG;AACrG,UAAM,IAAI;AAAA,MACR;AAAA,MACA,kBAAkB,MAAM;AAAA,MACxB;AAAA,QACE,KAAK,kBAAkB,KAAK,KAAK,KAAK,QAAQ,QAAQ,GAAG,aAAa,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,cAAU,cAAc,QAAQ,QAAQ,cAAc,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC7E,SAAS,GAAG;AACV,UAAM,IAAI,eAAe,kBAAkB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,EACvF;AAEA,QAAM,UAAU,UAAU,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AACzE,QAAM,UAAU,MAAM,UAAU,UAAU,UAAU,MAAM;AAC1D,MAAI;AACF,UAAM,WAAW,MAAM,cAAc,QAAQ;AAC7C,UAAM,aAAa,MAAM,mBAAmB,SAAS,QAAQ,gBAAgB,CAAC;AAC9E,QAAI,CAAC,WAAW,IAAI;AAClB,YAAM,QAAQ;AACd,YAAM,IAAI,eAAe,cAAc,6DAA6D;AAAA,QAClG,SAAS,EAAE,QAAQ,WAAW,OAAO;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF,SAAS,GAAG;AACV,QAAI,aAAa,eAAgB,OAAM;AACvC,UAAM,QAAQ;AACd,QAAI,aAAa,oBAAoB;AACnC,YAAM,IAAI,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,GAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,GAAI,GAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC,EAAG,CAAC;AAAA,IAChI;AACA,UAAM;AAAA,EACR;AACF;AAOA,SAAS,cAAc,QAAiB,QAAgB,MAAsB;AAC5E,QAAM,QAAS,QAAgC;AAC/C,QAAM,UAAU,MAAM,QAAQ,KAAK,IAC9B,MAAiE,KAAK,CAAC,MAAM,GAAG,OAAO,MAAM,GAAG,QAAQ,SACzG;AACJ,MAAI,OAAO,YAAY,YAAY,CAAC,QAAQ,SAAS,qBAAqB,KAAK,KAAK,SAAS,qBAAqB,GAAG;AACnH,WAAO;AAAA,EACT;AACA,SAAO,GAAG,KAAK,QAAQ,CAAC;AAAA;AAAA,EAAO,qBAAqB;AACtD;AAEO,IAAM,mBAAmB,cAAc;AAAA,EAC5C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,EAAE,MAAM,cAAc,UAAU,MAAM,aAAa,sBAAsB;AAAA,IAC/E,MAAM,EAAE,MAAM,cAAc,UAAU,MAAM,aAAa,kCAAkC;AAAA,IAC3F,MAAM,EAAE,MAAM,UAAU,aAAa,2BAA2B;AAAA,IAChE,aAAa,EAAE,MAAM,UAAU,aAAa,qEAAqE;AAAA,EACnH;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,QAAI;AACJ,QAAI,KAAK,WAAW,EAAG,QAAO,MAAM,SAAS,KAAK,QAAQ,OAAO,KAAK,WAAW,CAAC,CAAC,GAAG,MAAM;AAAA,aACnF,KAAK,SAAS,OAAW,QAAO,OAAO,KAAK,IAAI;AAAA,SACpD;AACH,cAAQ,OAAO;AAAA,QACb,GAAG,KAAK,UAAU,EAAE,IAAI,OAAO,OAAO,EAAE,MAAM,WAAW,SAAS,6BAA6B,EAAE,GAAG,MAAM,CAAC,CAAC;AAAA;AAAA,MAC9G;AACA,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AAEA,QAAI;AACF,YAAM,sBAAsB,OAAO,KAAK,IAAI,GAAG,OAAO,KAAK,IAAI,GAAG,IAAI;AAAA,IACxE,SAAS,GAAG;AACV,UAAI,EAAE,aAAa,gBAAiB,OAAM;AAC1C,cAAQ,OAAO;AAAA,QACb,GAAG,KAAK;AAAA,UACN,EAAE,IAAI,OAAO,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,SAAS,GAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,GAAI,GAAI,EAAE,WAAW,CAAC,EAAG,EAAE;AAAA,UACjH;AAAA,UACA;AAAA,QACF,CAAC;AAAA;AAAA,MACH;AACA,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,YAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK,IAAI,GAAG,OAAO,KAAK,OAAO,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EAChH;AACF,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/commands/canvas/set-prompt.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { defineCommand } from \"citty\";\nimport { defaultRegistry, validateCanvasDeep } from \"../../engine/index.ts\";\nimport { COPY_DIRECTIVE_HEADER } from \"../../engine/scaffold/static-copy.ts\";\nimport { adaptNodes } from \"../../engine/scaffold/static-adapt-briefs.ts\";\nimport { compiledPromptNodeIds } from \"../../engine/scaffold/static-render-briefs.ts\";\nimport { CanvasPrepareError, prepareCanvas } from \"./prepare-canvas.ts\";\nimport { sceneOwnedPrompts } from \"./scene-projection.ts\";\n\n/**\n * Set one node's `params.prompt` in a parsed canvas, returning a NEW canvas. The\n * structured alternative to hand-editing a 133 KB machine JSON with jq/sed — which\n * is where `\"prompt\": null` pollution (a global `gsub` writing prompt onto every\n * node) and the French-accent corruption (shell `''` eating apostrophes) came from.\n * Throws when the node id is unknown. Pure — unit-tested without the filesystem.\n */\nexport function setNodePrompt(canvas: unknown, nodeId: string, text: string): unknown {\n const nodes = (canvas as { nodes?: unknown })?.nodes;\n if (!Array.isArray(nodes)) throw new Error(\"canvas has no nodes array\");\n const idx = nodes.findIndex((n) => (n as { id?: unknown })?.id === nodeId);\n if (idx < 0) {\n const ids = nodes.map((n) => (n as { id?: unknown })?.id).filter((id): id is string => typeof id === \"string\");\n throw new Error(`node \"${nodeId}\" not found. Known nodes: ${ids.join(\", \")}`);\n }\n const node = nodes[idx] as { params?: Record<string, unknown> };\n const newNode = { ...node, params: { ...(node.params ?? {}), prompt: text } };\n const newNodes = [...nodes];\n newNodes[idx] = newNode;\n return { ...(canvas as object), nodes: newNodes };\n}\n\n/** Why `set-prompt` did not write: the node's prompt is owned elsewhere, or the edit does not validate. */\nexport class SetPromptError extends Error {\n readonly code: string;\n readonly fix: string | undefined;\n readonly details: Record<string, unknown> | undefined;\n constructor(code: string, message: string, opts: { fix?: string; details?: Record<string, unknown> } = {}) {\n super(message);\n this.name = \"SetPromptError\";\n this.code = code;\n this.fix = opts.fix;\n this.details = opts.details;\n }\n}\n\n/**\n * Set a node's prompt in the canvas FILE, where it will survive.\n *\n * The canvas is a projection of its blueprint, and `prepareCanvas` rewrites the projected\n * parts on every validate and run. So:\n * - a frame or clip prompt a scene file rebuilds is refused, naming the scene file to edit\n * (writing it here would be silently overwritten by the next preflight);\n * - a static ad's scaffolded render prompt (a take, a re-lay, the judge) is refused, naming\n * prompt.json: it is compiled from the ad spec there on every run;\n * - a hand-written static render prompt keeps its copy block: the text replaces the scene\n * description, and the \"render these exact strings\" block after it is re-read from\n * prompt.json, as always;\n * - anything else is the canvas's own, and is written.\n * The result is validated; an edit that does not validate is undone.\n */\nexport async function setPromptInCanvasFile(canvasPath: string, nodeId: string, text: string): Promise<void> {\n const filePath = path.resolve(canvasPath);\n const original = await readFile(filePath, \"utf8\");\n let canvas: unknown;\n try {\n canvas = JSON.parse(original);\n } catch (e) {\n throw new SetPromptError(\"parse\", `${filePath}: JSON parse error: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n const sceneFile = (await sceneOwnedPrompts(filePath)).get(nodeId);\n if (sceneFile) {\n throw new SetPromptError(\n \"projected_prompt\",\n `The prompt of \"${nodeId}\" is rebuilt from ${sceneFile} on every validate and run, so setting it in the canvas would be overwritten.`,\n {\n fix: `Edit the scene's description in ${sceneFile} (its frame and motion fields, e.g. start_frame_prompt, end_frame_prompt, frame_prompt, motion_prompt), then run \\`baker canvas validate\\` to see the rebuilt prompt.`,\n },\n );\n }\n\n if (compiledPromptNodeIds(canvas).has(nodeId) || adaptNodes(canvas).some((a) => a.node.id === nodeId)) {\n throw new SetPromptError(\n \"projected_prompt\",\n `The prompt of \"${nodeId}\" is compiled from prompt.json on every validate and run, so setting it in the canvas would be overwritten.`,\n {\n fix: `Edit the ad in ${path.join(path.dirname(filePath), \"prompt.json\")} (its scene, copy, references or direction), then run \\`baker canvas validate\\` to see the compiled prompt on the node.`,\n },\n );\n }\n\n let updated: unknown;\n try {\n updated = setNodePrompt(canvas, nodeId, withCopyBlock(canvas, nodeId, text));\n } catch (e) {\n throw new SetPromptError(\"node_not_found\", e instanceof Error ? e.message : String(e));\n }\n\n await writeFile(filePath, `${JSON.stringify(updated, null, 2)}\\n`, \"utf8\");\n const restore = () => writeFile(filePath, original, \"utf8\");\n try {\n const prepared = await prepareCanvas(filePath);\n const validation = await validateCanvasDeep(prepared.canvas, defaultRegistry());\n if (!validation.ok) {\n await restore();\n throw new SetPromptError(\"validation\", \"The edited canvas does not validate; nothing was changed.\", {\n details: { issues: validation.issues },\n });\n }\n } catch (e) {\n if (e instanceof SetPromptError) throw e;\n await restore();\n if (e instanceof CanvasPrepareError) {\n throw new SetPromptError(e.code, e.message, { ...(e.fix ? { fix: e.fix } : {}), ...(e.details ? { details: e.details } : {}) });\n }\n throw e;\n }\n}\n\n/**\n * A static ad's render prompt ends with the copy block the preflight fills from prompt.json.\n * New text that leaves it out keeps it, so replacing the scene description never drops the\n * words the ad must show.\n */\nfunction withCopyBlock(canvas: unknown, nodeId: string, text: string): string {\n const nodes = (canvas as { nodes?: unknown })?.nodes;\n const current = Array.isArray(nodes)\n ? (nodes as Array<{ id?: unknown; params?: { prompt?: unknown } }>).find((n) => n?.id === nodeId)?.params?.prompt\n : undefined;\n if (typeof current !== \"string\" || !current.includes(COPY_DIRECTIVE_HEADER) || text.includes(COPY_DIRECTIVE_HEADER)) {\n return text;\n }\n return `${text.trimEnd()}\\n\\n${COPY_DIRECTIVE_HEADER}`;\n}\n\nexport const setPromptCommand = defineCommand({\n meta: {\n name: \"set-prompt\",\n description:\n \"Safely set a node's params.prompt (a frame description, motion prompt, etc.) without hand-editing the JSON. Prefer --text-file for multi-line/accented copy — it preserves UTF-8 exactly, unlike shell-quoted jq. A prompt rebuilt from a scene file (scenes/sNN.json), or compiled from a static ad's prompt.json, is refused with the file to edit instead.\",\n },\n args: {\n file: { type: \"positional\", required: true, description: \"Path to canvas JSON\" },\n node: { type: \"positional\", required: true, description: \"Node id to edit (e.g. s0_start)\" },\n text: { type: \"string\", description: \"New prompt text (inline)\" },\n \"text-file\": { type: \"string\", description: \"Read the new prompt from a UTF-8 file (preserves accents/newlines)\" },\n },\n async run({ args }) {\n let text: string;\n if (args[\"text-file\"]) text = await readFile(path.resolve(String(args[\"text-file\"])), \"utf8\");\n else if (args.text !== undefined) text = String(args.text);\n else {\n process.stderr.write(\n `${JSON.stringify({ ok: false, error: { code: \"no_text\", message: \"pass --text or --text-file\" } }, null, 2)}\\n`,\n );\n process.exit(2);\n return;\n }\n\n try {\n await setPromptInCanvasFile(String(args.file), String(args.node), text);\n } catch (e) {\n if (!(e instanceof SetPromptError)) throw e;\n process.stderr.write(\n `${JSON.stringify(\n { ok: false, error: { code: e.code, message: e.message, ...(e.fix ? { fix: e.fix } : {}), ...(e.details ?? {}) } },\n null,\n 2,\n )}\\n`,\n );\n process.exit(2);\n return;\n }\n process.stdout.write(`${JSON.stringify({ ok: true, node: String(args.node), bytes: text.length }, null, 2)}\\n`);\n },\n});\n"],"mappings":"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","names":[]}
|
|
@@ -4,12 +4,11 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
failApi,
|
|
6
6
|
failValidation
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-3HJLHTWP.js";
|
|
8
|
+
import "./chunk-XF4JUKVF.js";
|
|
9
9
|
import "./chunk-GXDLWBOY.js";
|
|
10
10
|
import "./chunk-TEINLN64.js";
|
|
11
11
|
import "./chunk-ZJWUBJYQ.js";
|
|
12
|
-
import "./chunk-HR6IWNKE.js";
|
|
13
12
|
import "./chunk-NE4F3FHN.js";
|
|
14
13
|
import {
|
|
15
14
|
apiPost
|
|
@@ -139,4 +138,4 @@ export {
|
|
|
139
138
|
createBody,
|
|
140
139
|
setupLinksCommand
|
|
141
140
|
};
|
|
142
|
-
//# sourceMappingURL=setup-links-
|
|
141
|
+
//# sourceMappingURL=setup-links-REPREN3C.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/setup-links/index.ts"],"sourcesContent":["import type { SetupLinksCreateRequest, SetupLinksCreateResponse, SetupLinksListResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { repeatedFlagValues } from \"../../lib/repeatedFlags.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi, failValidation } from \"../actions/shared.ts\";\n\nconst DOC = \"__tooling__/docs/tools/baker/setup-links.md\";\n\nconst CREATE_HINT =\n \"Send this link to whoever owns the accounts; it works without a Baker login and expires in 30 days. Revoke it in Settings → Setup links.\";\n\nconst LIST_FLAGS = [\"tags\", \"connect\", \"keys\", \"apps\", \"domains\"] as const;\n\nconst FLAG_HELP = {\n tags: \"Tracking tags to add (repeatable or comma-separated): meta, googleAds, googleAnalytics, linkedinInsightTag, tiktok, …\",\n connect:\n \"Accounts to connect by signing in (repeatable or comma-separated): google-ads, meta, google-analytics, google-tag-manager, google-search-console, linkedin, x-ads, hubspot, …\",\n keys: \"Accounts connected by pasting a key (repeatable or comma-separated): chatgpt-ads\",\n apps: \"Apps from the app catalog, by slug or exact name (repeatable or comma-separated): slack, notion, … Find one with `baker mcp catalog <search>`.\",\n mcp: \"An MCP server to connect, as name=https://address (repeatable). The recipient types any key into the link, never you.\",\n domains:\n \"The company's own domain whose DNS record the recipient sets, by hostname (repeatable or comma-separated). It must already be added to Baker.\",\n} as const;\n\nregisterSchema({\n command: \"setup-links.create\",\n description:\n \"Start here: make a setup link for whoever holds the company's accounts (an agency, the client's IT) — they open it, no Baker login needed, and connect what it asks for. Example: baker setup-links create --connect google-ads --tags meta. Made at once and returned now with its url: send it back to the user in this reply. Unknown names are refused: tags, connections and keys with the list of valid ones, apps with a pointer to `baker mcp catalog`.\",\n args: {\n tags: { type: \"string\", description: FLAG_HELP.tags, required: false },\n connect: { type: \"string\", description: FLAG_HELP.connect, required: false },\n keys: { type: \"string\", description: FLAG_HELP.keys, required: false },\n apps: { type: \"string\", description: FLAG_HELP.apps, required: false },\n mcp: { type: \"string\", description: FLAG_HELP.mcp, required: false },\n domains: { type: \"string\", description: FLAG_HELP.domains, required: false },\n },\n});\n\nregisterSchema({\n command: \"setup-links.list\",\n description:\n \"The company's setup links that still work: what each asks for (in the same words `create` takes), how much of it is done, its url and when it expires. Check it before making a link that already exists.\",\n args: {},\n});\n\n/** Every value of a repeatable, comma-separated flag. */\nfunction listFlag(rawArgs: readonly string[], flag: string): string[] {\n return repeatedFlagValues(rawArgs, flag)\n .flatMap((value) => value.split(\",\"))\n .map((value) => value.trim())\n .filter((value) => value !== \"\");\n}\n\n/** The request one `create` line asks for, or why it cannot be sent. */\nexport function createBody(\n rawArgs: readonly string[],\n): { ok: true; body: SetupLinksCreateRequest } | { ok: false; error: string } {\n const body: SetupLinksCreateRequest = {};\n for (const flag of LIST_FLAGS) {\n const values = listFlag(rawArgs, flag);\n if (values.length > 0) body[flag] = values;\n }\n const mcp: NonNullable<SetupLinksCreateRequest[\"mcp\"]> = [];\n for (const raw of repeatedFlagValues(rawArgs, \"mcp\")) {\n const separator = raw.indexOf(\"=\");\n const name = raw.slice(0, separator).trim();\n const url = raw.slice(separator + 1).trim();\n if (separator < 0 || name === \"\" || !/^https:\\/\\//.test(url)) {\n return { ok: false, error: `--mcp takes name=https://address, got \"${raw}\".` };\n }\n mcp.push({ name, url });\n }\n if (mcp.length > 0) body.mcp = mcp;\n if (Object.keys(body).length === 0) {\n return {\n ok: false,\n error: \"A setup link has to ask for something: pass --tags, --connect, --keys, --apps, --mcp or --domains.\",\n };\n }\n return { ok: true, body };\n}\n\nconst createCommand = defineCommand({\n meta: {\n name: \"create\",\n description: `Make a setup link for whoever holds the company's accounts; returns its url now.\nStart here: baker setup-links create --connect google-ads --tags meta`,\n },\n args: {\n tags: { type: \"string\", description: FLAG_HELP.tags, required: false },\n connect: { type: \"string\", description: FLAG_HELP.connect, required: false },\n keys: { type: \"string\", description: FLAG_HELP.keys, required: false },\n apps: { type: \"string\", description: FLAG_HELP.apps, required: false },\n mcp: { type: \"string\", description: FLAG_HELP.mcp, required: false },\n domains: { type: \"string\", description: FLAG_HELP.domains, required: false },\n },\n run: async ({ rawArgs }) => {\n const parsed = createBody(rawArgs);\n if (!parsed.ok) {\n failValidation(parsed.error);\n }\n try {\n const response = await apiPost<SetupLinksCreateResponse>(\"/api/setup-links/create\", parsed.body);\n writeJson({ ok: true, data: response.data, hints: [CREATE_HINT] });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nconst listCommand = defineCommand({\n meta: {\n name: \"list\",\n description: \"The company's setup links that still work: what each asks for, progress, url and expiry.\",\n },\n args: {},\n run: async () => {\n try {\n const response = await apiPost<SetupLinksListResponse>(\"/api/setup-links/list\", {});\n writeJson({\n ok: true,\n data: response.data,\n meta: { count: response.data.links.length },\n ...(response.data.links.length === 0\n ? { hints: [\"No setup links are out. Make one with baker setup-links create.\"] }\n : {}),\n });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nexport const setupLinksCommand = defineCommand({\n meta: {\n name: \"setup-links\",\n description: `Setup links: one link that lets whoever holds the company's accounts connect them, without a Baker login. Subcommands: create, list.\nFull guide: ${DOC}`,\n },\n subCommands: { create: createCommand, list: listCommand },\n});\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/commands/setup-links/index.ts"],"sourcesContent":["import type { SetupLinksCreateRequest, SetupLinksCreateResponse, SetupLinksListResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { repeatedFlagValues } from \"../../lib/repeatedFlags.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi, failValidation } from \"../actions/shared.ts\";\n\nconst DOC = \"__tooling__/docs/tools/baker/setup-links.md\";\n\nconst CREATE_HINT =\n \"Send this link to whoever owns the accounts; it works without a Baker login and expires in 30 days. Revoke it in Settings → Setup links.\";\n\nconst LIST_FLAGS = [\"tags\", \"connect\", \"keys\", \"apps\", \"domains\"] as const;\n\nconst FLAG_HELP = {\n tags: \"Tracking tags to add (repeatable or comma-separated): meta, googleAds, googleAnalytics, linkedinInsightTag, tiktok, …\",\n connect:\n \"Accounts to connect by signing in (repeatable or comma-separated): google-ads, meta, google-analytics, google-tag-manager, google-search-console, linkedin, x-ads, hubspot, …\",\n keys: \"Accounts connected by pasting a key (repeatable or comma-separated): chatgpt-ads\",\n apps: \"Apps from the app catalog, by slug or exact name (repeatable or comma-separated): slack, notion, … Find one with `baker mcp catalog <search>`.\",\n mcp: \"An MCP server to connect, as name=https://address (repeatable). The recipient types any key into the link, never you.\",\n domains:\n \"The company's own domain whose DNS record the recipient sets, by hostname (repeatable or comma-separated). It must already be added to Baker.\",\n} as const;\n\nregisterSchema({\n command: \"setup-links.create\",\n description:\n \"Start here: make a setup link for whoever holds the company's accounts (an agency, the client's IT) — they open it, no Baker login needed, and connect what it asks for. Example: baker setup-links create --connect google-ads --tags meta. Made at once and returned now with its url: send it back to the user in this reply. Unknown names are refused: tags, connections and keys with the list of valid ones, apps with a pointer to `baker mcp catalog`.\",\n args: {\n tags: { type: \"string\", description: FLAG_HELP.tags, required: false },\n connect: { type: \"string\", description: FLAG_HELP.connect, required: false },\n keys: { type: \"string\", description: FLAG_HELP.keys, required: false },\n apps: { type: \"string\", description: FLAG_HELP.apps, required: false },\n mcp: { type: \"string\", description: FLAG_HELP.mcp, required: false },\n domains: { type: \"string\", description: FLAG_HELP.domains, required: false },\n },\n});\n\nregisterSchema({\n command: \"setup-links.list\",\n description:\n \"The company's setup links that still work: what each asks for (in the same words `create` takes), how much of it is done, its url and when it expires. Check it before making a link that already exists.\",\n args: {},\n});\n\n/** Every value of a repeatable, comma-separated flag. */\nfunction listFlag(rawArgs: readonly string[], flag: string): string[] {\n return repeatedFlagValues(rawArgs, flag)\n .flatMap((value) => value.split(\",\"))\n .map((value) => value.trim())\n .filter((value) => value !== \"\");\n}\n\n/** The request one `create` line asks for, or why it cannot be sent. */\nexport function createBody(\n rawArgs: readonly string[],\n): { ok: true; body: SetupLinksCreateRequest } | { ok: false; error: string } {\n const body: SetupLinksCreateRequest = {};\n for (const flag of LIST_FLAGS) {\n const values = listFlag(rawArgs, flag);\n if (values.length > 0) body[flag] = values;\n }\n const mcp: NonNullable<SetupLinksCreateRequest[\"mcp\"]> = [];\n for (const raw of repeatedFlagValues(rawArgs, \"mcp\")) {\n const separator = raw.indexOf(\"=\");\n const name = raw.slice(0, separator).trim();\n const url = raw.slice(separator + 1).trim();\n if (separator < 0 || name === \"\" || !/^https:\\/\\//.test(url)) {\n return { ok: false, error: `--mcp takes name=https://address, got \"${raw}\".` };\n }\n mcp.push({ name, url });\n }\n if (mcp.length > 0) body.mcp = mcp;\n if (Object.keys(body).length === 0) {\n return {\n ok: false,\n error: \"A setup link has to ask for something: pass --tags, --connect, --keys, --apps, --mcp or --domains.\",\n };\n }\n return { ok: true, body };\n}\n\nconst createCommand = defineCommand({\n meta: {\n name: \"create\",\n description: `Make a setup link for whoever holds the company's accounts; returns its url now.\nStart here: baker setup-links create --connect google-ads --tags meta`,\n },\n args: {\n tags: { type: \"string\", description: FLAG_HELP.tags, required: false },\n connect: { type: \"string\", description: FLAG_HELP.connect, required: false },\n keys: { type: \"string\", description: FLAG_HELP.keys, required: false },\n apps: { type: \"string\", description: FLAG_HELP.apps, required: false },\n mcp: { type: \"string\", description: FLAG_HELP.mcp, required: false },\n domains: { type: \"string\", description: FLAG_HELP.domains, required: false },\n },\n run: async ({ rawArgs }) => {\n const parsed = createBody(rawArgs);\n if (!parsed.ok) {\n failValidation(parsed.error);\n }\n try {\n const response = await apiPost<SetupLinksCreateResponse>(\"/api/setup-links/create\", parsed.body);\n writeJson({ ok: true, data: response.data, hints: [CREATE_HINT] });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nconst listCommand = defineCommand({\n meta: {\n name: \"list\",\n description: \"The company's setup links that still work: what each asks for, progress, url and expiry.\",\n },\n args: {},\n run: async () => {\n try {\n const response = await apiPost<SetupLinksListResponse>(\"/api/setup-links/list\", {});\n writeJson({\n ok: true,\n data: response.data,\n meta: { count: response.data.links.length },\n ...(response.data.links.length === 0\n ? { hints: [\"No setup links are out. Make one with baker setup-links create.\"] }\n : {}),\n });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nexport const setupLinksCommand = defineCommand({\n meta: {\n name: \"setup-links\",\n description: `Setup links: one link that lets whoever holds the company's accounts connect them, without a Baker login. Subcommands: create, list.\nFull guide: ${DOC}`,\n },\n subCommands: { create: createCommand, list: listCommand },\n});\n"],"mappings":"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","names":[]}
|
|
@@ -2,12 +2,11 @@ import {
|
|
|
2
2
|
SiteArgsError,
|
|
3
3
|
failSite,
|
|
4
4
|
parseSetArgs
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-JQJDXPCO.js";
|
|
6
|
+
import "./chunk-XF4JUKVF.js";
|
|
7
7
|
import "./chunk-GXDLWBOY.js";
|
|
8
8
|
import "./chunk-TEINLN64.js";
|
|
9
9
|
import "./chunk-ZJWUBJYQ.js";
|
|
10
|
-
import "./chunk-HR6IWNKE.js";
|
|
11
10
|
import "./chunk-NE4F3FHN.js";
|
|
12
11
|
import {
|
|
13
12
|
apiGet,
|
|
@@ -169,10 +168,10 @@ Full guide: __tooling__/docs/tools/baker/site.md`
|
|
|
169
168
|
show: showCommand,
|
|
170
169
|
set: setCommand,
|
|
171
170
|
unstage: unstageCommand,
|
|
172
|
-
domain: () => import("./domain-
|
|
171
|
+
domain: () => import("./domain-Y2LT6JLT.js").then((m) => m.domainCommand)
|
|
173
172
|
}
|
|
174
173
|
});
|
|
175
174
|
export {
|
|
176
175
|
siteCommand
|
|
177
176
|
};
|
|
178
|
-
//# sourceMappingURL=site-
|
|
177
|
+
//# sourceMappingURL=site-WFSWIA3S.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/site/index.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport type { SiteShowResponse, SiteStageRequest, SiteStageResponse, SiteUnstageResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiGet, apiPost } from \"../../client.ts\";\nimport { optionalChatId, requireChatId } from \"../../env.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { parseSetArgs, SiteArgsError } from \"./setArgs.ts\";\nimport { failSite } from \"./shared.ts\";\n\n/**\n * `baker site` — the company's site settings: cookie consent, what Baker\n * records, whether search engines show the site, the home page, the time zone,\n * the landing download format, and custom domains. Every change stages on this\n * chat and applies when the chat is published; discarding the chat drops it.\n */\n\nregisterSchema({\n command: \"site.show\",\n description:\n \"Start here: the company's site settings as they will be after this chat publishes — cookie consent (consent), what Baker records (analyticsCollection), search engines (indexing), the home page (homePage, null = the first published landing), time zone, download format (exportProfile, null = default) and custom domains with their status — plus `staged`: what this chat changed, each with before/after. Hints name other open chats that already staged a site setting. Read-only.\",\n args: {\n chat: {\n type: \"string\",\n description: \"Read another chat's staged settings instead of this chat's (a chat id from `baker chats list`)\",\n required: false,\n },\n },\n});\n\nregisterSchema({\n command: \"site.set\",\n description:\n \"Stage one or more site settings in one call; all apply when the chat is published, none mid-chat. Combine flags freely: `baker site set --consent recovery --indexing on`. Restaging a setting replaces what this chat staged before. Any member's chat may change these — the person who publishes is the review. --consent: bypass (no banner, maximum tracking), recovery (banner; declines still send anonymized pings — the usual EU choice), strict (banner; declines send nothing), external (the site's own consent tool). --collection: full, aggregate (counts only, nobody identifiable), off (Baker records nothing). --home takes a published landing slug (or one this chat is building); \\\"none\\\" restores the default. Always ask the user before hiding the site from search engines or reducing what Baker records.\",\n args: {\n consent: { type: \"string\", description: \"bypass | recovery | strict | external\", required: false },\n collection: { type: \"string\", description: \"full | aggregate | off\", required: false },\n payloads: {\n type: \"string\",\n description: \"on | off — keep a copy of each lead (only with --collection full)\",\n required: false,\n },\n indexing: { type: \"string\", description: \"on | off — show the site in search engines\", required: false },\n home: { type: \"string\", description: \"Landing slug to serve at the site root, or none\", required: false },\n \"home-mode\": {\n type: \"string\",\n description: \"rewrite (default; the root shows the landing) | redirect (the root sends visitors to /<slug>)\",\n required: false,\n },\n timezone: { type: \"string\", description: \"IANA time zone, e.g. Europe/Madrid\", required: false },\n \"export-profile\": {\n type: \"string\",\n description:\n 'Only the download-format fields to change, as JSON (e.g. {\"htmlOutput\":\"fragment\"}) or @path/to/profile.json. A second call adds to the first; Publish lays them over the format saved then',\n required: false,\n },\n },\n});\n\nregisterSchema({\n command: \"site.unstage\",\n description:\n \"Take back a site setting this chat staged, before publish — the same as discarding its row in the chat's Settings review. The key is the setting (consent, analyticsCollection, indexing, homePage, timezone, exportProfile) or customDomain:<hostname>; --all takes back every one. Never touches what is already live.\",\n args: {\n key: { type: \"string\", description: \"A `key` from `baker site show` → staged\", required: false },\n all: { type: \"boolean\", description: \"Take back every staged site setting\", required: false },\n },\n});\n\nconst showCommand = defineCommand({\n meta: {\n name: \"show\",\n description:\n \"Show the site settings as they will be after this chat publishes, and what this chat staged.\\n\\nExample: baker site show\",\n },\n args: {\n chat: { type: \"string\", description: \"Another chat's id, to read what it staged\", required: false },\n },\n run: async ({ args }) => {\n try {\n const chatId = typeof args.chat === \"string\" && args.chat.length > 0 ? args.chat : optionalChatId();\n writeJson(await apiGet<SiteShowResponse>(\"/api/site\", chatId ? { chatId } : undefined));\n } catch (err) {\n failSite(err);\n }\n },\n});\n\nconst setCommand = defineCommand({\n meta: {\n name: \"set\",\n description:\n \"Stage site settings; they apply when the chat is published.\\n\\nExamples:\\n baker site set --consent recovery\\n baker site set --collection aggregate\\n baker site set --indexing off\\n baker site set --home oferta --home-mode redirect\\n baker site set --home none\\n baker site set --timezone Europe/Madrid\\n baker site set --export-profile @profile.json\",\n },\n args: {\n consent: { type: \"string\", description: \"bypass | recovery | strict | external\", required: false },\n collection: { type: \"string\", description: \"full | aggregate | off\", required: false },\n payloads: { type: \"string\", description: \"on | off (with --collection full)\", required: false },\n indexing: { type: \"string\", description: \"on | off\", required: false },\n home: { type: \"string\", description: \"Landing slug, or none\", required: false },\n \"home-mode\": { type: \"string\", description: \"rewrite | redirect\", required: false },\n timezone: { type: \"string\", description: \"IANA time zone\", required: false },\n \"export-profile\": {\n type: \"string\",\n description:\n \"Fields to change, as JSON or @path; added to any staged earlier, laid over the saved format at Publish\",\n required: false,\n },\n },\n run: async ({ args }) => {\n try {\n const inputs = parseSetArgs(\n {\n consent: args.consent as string | undefined,\n collection: args.collection as string | undefined,\n payloads: args.payloads as string | undefined,\n indexing: args.indexing as string | undefined,\n home: args.home as string | undefined,\n \"home-mode\": args[\"home-mode\"] as string | undefined,\n timezone: args.timezone as string | undefined,\n \"export-profile\": args[\"export-profile\"] as string | undefined,\n },\n (path) => readFileSync(path, \"utf8\"),\n );\n const body: SiteStageRequest = { chatId: requireChatId(), inputs };\n writeJson(await apiPost<SiteStageResponse>(\"/api/site/stage\", body));\n } catch (err) {\n failSite(err);\n }\n },\n});\n\nconst unstageCommand = defineCommand({\n meta: {\n name: \"unstage\",\n description:\n \"Take back a staged site setting before publish.\\n\\nExamples:\\n baker site unstage consent\\n baker site unstage customDomain:shop.acme.com\\n baker site unstage --all\",\n },\n args: {\n key: { type: \"positional\", description: \"The setting key from `baker site show` → staged\", required: false },\n all: { type: \"boolean\", description: \"Take back every staged site setting\", required: false },\n },\n run: async ({ args }) => {\n try {\n const key = typeof args.key === \"string\" && args.key.length > 0 ? args.key : undefined;\n if ((key === undefined) === (args.all !== true)) {\n throw new SiteArgsError(\"Pass one setting key (see `baker site show` → staged) or --all.\");\n }\n const body = { chatId: requireChatId(), ...(key ? { key } : { all: true }) };\n writeJson(await apiPost<SiteUnstageResponse>(\"/api/site/draft-op/remove\", body));\n } catch (err) {\n failSite(err);\n }\n },\n});\n\nexport const siteCommand = defineCommand({\n meta: {\n name: \"site\",\n description: `The company's site settings: cookie consent, what Baker records, search engines, home page, time zone, landing download format, custom domains. Every change stages on this chat and applies when it is published. Subcommands: show, set, unstage, domain.\n\nExamples:\n baker site show\n baker site set --consent recovery --indexing on\n baker site set --home oferta\n baker site domain add shop.acme.com\n baker site unstage homePage\nFull guide: __tooling__/docs/tools/baker/site.md`,\n },\n subCommands: {\n show: showCommand,\n set: setCommand,\n unstage: unstageCommand,\n domain: () => import(\"./domain.ts\").then((m) => m.domainCommand),\n },\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/commands/site/index.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport type { SiteShowResponse, SiteStageRequest, SiteStageResponse, SiteUnstageResponse } from \"@baker/api\";\nimport { defineCommand } from \"citty\";\nimport { apiGet, apiPost } from \"../../client.ts\";\nimport { optionalChatId, requireChatId } from \"../../env.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { parseSetArgs, SiteArgsError } from \"./setArgs.ts\";\nimport { failSite } from \"./shared.ts\";\n\n/**\n * `baker site` — the company's site settings: cookie consent, what Baker\n * records, whether search engines show the site, the home page, the time zone,\n * the landing download format, and custom domains. Every change stages on this\n * chat and applies when the chat is published; discarding the chat drops it.\n */\n\nregisterSchema({\n command: \"site.show\",\n description:\n \"Start here: the company's site settings as they will be after this chat publishes — cookie consent (consent), what Baker records (analyticsCollection), search engines (indexing), the home page (homePage, null = the first published landing), time zone, download format (exportProfile, null = default) and custom domains with their status — plus `staged`: what this chat changed, each with before/after. Hints name other open chats that already staged a site setting. Read-only.\",\n args: {\n chat: {\n type: \"string\",\n description: \"Read another chat's staged settings instead of this chat's (a chat id from `baker chats list`)\",\n required: false,\n },\n },\n});\n\nregisterSchema({\n command: \"site.set\",\n description:\n \"Stage one or more site settings in one call; all apply when the chat is published, none mid-chat. Combine flags freely: `baker site set --consent recovery --indexing on`. Restaging a setting replaces what this chat staged before. Any member's chat may change these — the person who publishes is the review. --consent: bypass (no banner, maximum tracking), recovery (banner; declines still send anonymized pings — the usual EU choice), strict (banner; declines send nothing), external (the site's own consent tool). --collection: full, aggregate (counts only, nobody identifiable), off (Baker records nothing). --home takes a published landing slug (or one this chat is building); \\\"none\\\" restores the default. Always ask the user before hiding the site from search engines or reducing what Baker records.\",\n args: {\n consent: { type: \"string\", description: \"bypass | recovery | strict | external\", required: false },\n collection: { type: \"string\", description: \"full | aggregate | off\", required: false },\n payloads: {\n type: \"string\",\n description: \"on | off — keep a copy of each lead (only with --collection full)\",\n required: false,\n },\n indexing: { type: \"string\", description: \"on | off — show the site in search engines\", required: false },\n home: { type: \"string\", description: \"Landing slug to serve at the site root, or none\", required: false },\n \"home-mode\": {\n type: \"string\",\n description: \"rewrite (default; the root shows the landing) | redirect (the root sends visitors to /<slug>)\",\n required: false,\n },\n timezone: { type: \"string\", description: \"IANA time zone, e.g. Europe/Madrid\", required: false },\n \"export-profile\": {\n type: \"string\",\n description:\n 'Only the download-format fields to change, as JSON (e.g. {\"htmlOutput\":\"fragment\"}) or @path/to/profile.json. A second call adds to the first; Publish lays them over the format saved then',\n required: false,\n },\n },\n});\n\nregisterSchema({\n command: \"site.unstage\",\n description:\n \"Take back a site setting this chat staged, before publish — the same as discarding its row in the chat's Settings review. The key is the setting (consent, analyticsCollection, indexing, homePage, timezone, exportProfile) or customDomain:<hostname>; --all takes back every one. Never touches what is already live.\",\n args: {\n key: { type: \"string\", description: \"A `key` from `baker site show` → staged\", required: false },\n all: { type: \"boolean\", description: \"Take back every staged site setting\", required: false },\n },\n});\n\nconst showCommand = defineCommand({\n meta: {\n name: \"show\",\n description:\n \"Show the site settings as they will be after this chat publishes, and what this chat staged.\\n\\nExample: baker site show\",\n },\n args: {\n chat: { type: \"string\", description: \"Another chat's id, to read what it staged\", required: false },\n },\n run: async ({ args }) => {\n try {\n const chatId = typeof args.chat === \"string\" && args.chat.length > 0 ? args.chat : optionalChatId();\n writeJson(await apiGet<SiteShowResponse>(\"/api/site\", chatId ? { chatId } : undefined));\n } catch (err) {\n failSite(err);\n }\n },\n});\n\nconst setCommand = defineCommand({\n meta: {\n name: \"set\",\n description:\n \"Stage site settings; they apply when the chat is published.\\n\\nExamples:\\n baker site set --consent recovery\\n baker site set --collection aggregate\\n baker site set --indexing off\\n baker site set --home oferta --home-mode redirect\\n baker site set --home none\\n baker site set --timezone Europe/Madrid\\n baker site set --export-profile @profile.json\",\n },\n args: {\n consent: { type: \"string\", description: \"bypass | recovery | strict | external\", required: false },\n collection: { type: \"string\", description: \"full | aggregate | off\", required: false },\n payloads: { type: \"string\", description: \"on | off (with --collection full)\", required: false },\n indexing: { type: \"string\", description: \"on | off\", required: false },\n home: { type: \"string\", description: \"Landing slug, or none\", required: false },\n \"home-mode\": { type: \"string\", description: \"rewrite | redirect\", required: false },\n timezone: { type: \"string\", description: \"IANA time zone\", required: false },\n \"export-profile\": {\n type: \"string\",\n description:\n \"Fields to change, as JSON or @path; added to any staged earlier, laid over the saved format at Publish\",\n required: false,\n },\n },\n run: async ({ args }) => {\n try {\n const inputs = parseSetArgs(\n {\n consent: args.consent as string | undefined,\n collection: args.collection as string | undefined,\n payloads: args.payloads as string | undefined,\n indexing: args.indexing as string | undefined,\n home: args.home as string | undefined,\n \"home-mode\": args[\"home-mode\"] as string | undefined,\n timezone: args.timezone as string | undefined,\n \"export-profile\": args[\"export-profile\"] as string | undefined,\n },\n (path) => readFileSync(path, \"utf8\"),\n );\n const body: SiteStageRequest = { chatId: requireChatId(), inputs };\n writeJson(await apiPost<SiteStageResponse>(\"/api/site/stage\", body));\n } catch (err) {\n failSite(err);\n }\n },\n});\n\nconst unstageCommand = defineCommand({\n meta: {\n name: \"unstage\",\n description:\n \"Take back a staged site setting before publish.\\n\\nExamples:\\n baker site unstage consent\\n baker site unstage customDomain:shop.acme.com\\n baker site unstage --all\",\n },\n args: {\n key: { type: \"positional\", description: \"The setting key from `baker site show` → staged\", required: false },\n all: { type: \"boolean\", description: \"Take back every staged site setting\", required: false },\n },\n run: async ({ args }) => {\n try {\n const key = typeof args.key === \"string\" && args.key.length > 0 ? args.key : undefined;\n if ((key === undefined) === (args.all !== true)) {\n throw new SiteArgsError(\"Pass one setting key (see `baker site show` → staged) or --all.\");\n }\n const body = { chatId: requireChatId(), ...(key ? { key } : { all: true }) };\n writeJson(await apiPost<SiteUnstageResponse>(\"/api/site/draft-op/remove\", body));\n } catch (err) {\n failSite(err);\n }\n },\n});\n\nexport const siteCommand = defineCommand({\n meta: {\n name: \"site\",\n description: `The company's site settings: cookie consent, what Baker records, search engines, home page, time zone, landing download format, custom domains. Every change stages on this chat and applies when it is published. Subcommands: show, set, unstage, domain.\n\nExamples:\n baker site show\n baker site set --consent recovery --indexing on\n baker site set --home oferta\n baker site domain add shop.acme.com\n baker site unstage homePage\nFull guide: __tooling__/docs/tools/baker/site.md`,\n },\n subCommands: {\n show: showCommand,\n set: setCommand,\n unstage: unstageCommand,\n domain: () => import(\"./domain.ts\").then((m) => m.domainCommand),\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,oBAAoB;AAE7B,SAAS,qBAAqB;AAe9B,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,EACF;AACF,CAAC;AAED,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,UAAU,aAAa,yCAAyC,UAAU,MAAM;AAAA,IACjG,YAAY,EAAE,MAAM,UAAU,aAAa,0BAA0B,UAAU,MAAM;AAAA,IACrF,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,UAAU,EAAE,MAAM,UAAU,aAAa,mDAA8C,UAAU,MAAM;AAAA,IACvG,MAAM,EAAE,MAAM,UAAU,aAAa,mDAAmD,UAAU,MAAM;AAAA,IACxG,aAAa;AAAA,MACX,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,UAAU,EAAE,MAAM,UAAU,aAAa,sCAAsC,UAAU,MAAM;AAAA,IAC/F,kBAAkB;AAAA,MAChB,MAAM;AAAA,MACN,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,EACF;AACF,CAAC;AAED,eAAe;AAAA,EACb,SAAS;AAAA,EACT,aACE;AAAA,EACF,MAAM;AAAA,IACJ,KAAK,EAAE,MAAM,UAAU,aAAa,gDAA2C,UAAU,MAAM;AAAA,IAC/F,KAAK,EAAE,MAAM,WAAW,aAAa,uCAAuC,UAAU,MAAM;AAAA,EAC9F;AACF,CAAC;AAED,IAAM,cAAc,cAAc;AAAA,EAChC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,EAAE,MAAM,UAAU,aAAa,6CAA6C,UAAU,MAAM;AAAA,EACpG;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,QAAI;AACF,YAAM,SAAS,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,SAAS,IAAI,KAAK,OAAO,eAAe;AAClG,gBAAU,MAAM,OAAyB,aAAa,SAAS,EAAE,OAAO,IAAI,MAAS,CAAC;AAAA,IACxF,SAAS,KAAK;AACZ,eAAS,GAAG;AAAA,IACd;AAAA,EACF;AACF,CAAC;AAED,IAAM,aAAa,cAAc;AAAA,EAC/B,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,UAAU,aAAa,yCAAyC,UAAU,MAAM;AAAA,IACjG,YAAY,EAAE,MAAM,UAAU,aAAa,0BAA0B,UAAU,MAAM;AAAA,IACrF,UAAU,EAAE,MAAM,UAAU,aAAa,qCAAqC,UAAU,MAAM;AAAA,IAC9F,UAAU,EAAE,MAAM,UAAU,aAAa,YAAY,UAAU,MAAM;AAAA,IACrE,MAAM,EAAE,MAAM,UAAU,aAAa,yBAAyB,UAAU,MAAM;AAAA,IAC9E,aAAa,EAAE,MAAM,UAAU,aAAa,sBAAsB,UAAU,MAAM;AAAA,IAClF,UAAU,EAAE,MAAM,UAAU,aAAa,kBAAkB,UAAU,MAAM;AAAA,IAC3E,kBAAkB;AAAA,MAChB,MAAM;AAAA,MACN,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,QAAI;AACF,YAAM,SAAS;AAAA,QACb;AAAA,UACE,SAAS,KAAK;AAAA,UACd,YAAY,KAAK;AAAA,UACjB,UAAU,KAAK;AAAA,UACf,UAAU,KAAK;AAAA,UACf,MAAM,KAAK;AAAA,UACX,aAAa,KAAK,WAAW;AAAA,UAC7B,UAAU,KAAK;AAAA,UACf,kBAAkB,KAAK,gBAAgB;AAAA,QACzC;AAAA,QACA,CAAC,SAAS,aAAa,MAAM,MAAM;AAAA,MACrC;AACA,YAAM,OAAyB,EAAE,QAAQ,cAAc,GAAG,OAAO;AACjE,gBAAU,MAAM,QAA2B,mBAAmB,IAAI,CAAC;AAAA,IACrE,SAAS,KAAK;AACZ,eAAS,GAAG;AAAA,IACd;AAAA,EACF;AACF,CAAC;AAED,IAAM,iBAAiB,cAAc;AAAA,EACnC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACJ,KAAK,EAAE,MAAM,cAAc,aAAa,wDAAmD,UAAU,MAAM;AAAA,IAC3G,KAAK,EAAE,MAAM,WAAW,aAAa,uCAAuC,UAAU,MAAM;AAAA,EAC9F;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,QAAI;AACF,YAAM,MAAM,OAAO,KAAK,QAAQ,YAAY,KAAK,IAAI,SAAS,IAAI,KAAK,MAAM;AAC7E,UAAK,QAAQ,YAAgB,KAAK,QAAQ,OAAO;AAC/C,cAAM,IAAI,cAAc,sEAAiE;AAAA,MAC3F;AACA,YAAM,OAAO,EAAE,QAAQ,cAAc,GAAG,GAAI,MAAM,EAAE,IAAI,IAAI,EAAE,KAAK,KAAK,EAAG;AAC3E,gBAAU,MAAM,QAA6B,6BAA6B,IAAI,CAAC;AAAA,IACjF,SAAS,KAAK;AACZ,eAAS,GAAG;AAAA,IACd;AAAA,EACF;AACF,CAAC;AAEM,IAAM,cAAc,cAAc;AAAA,EACvC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASf;AAAA,EACA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,KAAK;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,MAAM,OAAO,sBAAa,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa;AAAA,EACjE;AACF,CAAC;","names":[]}
|