@maycombhq/atticus 2.0.0-beta.22 → 2.0.0-beta.24
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/dist/bin.js +12 -7
- package/dist/{chunk-J2JAKCIW.js → chunk-25CUJJTP.js} +511 -291
- package/dist/chunk-26AB2WNW.js +62 -0
- package/dist/{chunk-VBTP56CE.js → chunk-2ITYURTR.js} +9 -8
- package/dist/{chunk-6ZJ5A7AF.js → chunk-2JHE75RW.js} +13 -11
- package/dist/{chunk-QFWA2DPH.js → chunk-37UTWGU4.js} +8 -6
- package/dist/{chunk-VW62D6QE.js → chunk-3BEGKSDW.js} +14 -12
- package/dist/{chunk-3RM4UK6W.js → chunk-3FGQFDS4.js} +20 -18
- package/dist/{chunk-23XVSEV5.js → chunk-3NS4RS3C.js} +20 -18
- package/dist/{chunk-FSMSFDLD.js → chunk-3TGX4SJ3.js} +10 -7
- package/dist/{chunk-7JITZFJC.js → chunk-3UMKLB6P.js} +7 -5
- package/dist/chunk-3VS7RNEB.js +96 -0
- package/dist/{chunk-AJYXNTNZ.js → chunk-3XCCT2GR.js} +167 -42
- package/dist/{chunk-XERYFDB5.js → chunk-3XZRYQWU.js} +38 -34
- package/dist/{chunk-FUJM6RTF.js → chunk-432FGEVB.js} +9 -7
- package/dist/{chunk-SFUP7TTO.js → chunk-44QUCNPH.js} +7 -5
- package/dist/{chunk-O5PXQR67.js → chunk-4CS3PMIM.js} +15 -13
- package/dist/{chunk-RGERPOIV.js → chunk-4DCIUKIE.js} +22 -12
- package/dist/{chunk-RLDGWLQ7.js → chunk-4DX4DIND.js} +9 -7
- package/dist/chunk-4MNMOUU7.js +108 -0
- package/dist/{chunk-SLXZOMA6.js → chunk-4RKIOUPA.js} +9 -7
- package/dist/{chunk-AJQ72EBM.js → chunk-532HDXMM.js} +9 -7
- package/dist/{chunk-CADWLE2T.js → chunk-5EIKOU7L.js} +6 -4
- package/dist/{chunk-CQDGOPGH.js → chunk-5FPAKAGE.js} +7 -5
- package/dist/{chunk-IVBOQAGB.js → chunk-5FUFVNXB.js} +27 -3
- package/dist/{chunk-UUU4CLJG.js → chunk-5MKV4TV6.js} +5 -1
- package/dist/{chunk-ZQXZ2SES.js → chunk-5ORLKITZ.js} +23 -21
- package/dist/{chunk-OHVTTOPS.js → chunk-5PSKLTBR.js} +3 -3
- package/dist/{chunk-RUGXBPWI.js → chunk-5QF5W5P2.js} +10 -10
- package/dist/{chunk-BPK5P77O.js → chunk-5Z7L2TSR.js} +3 -3
- package/dist/{chunk-L27SV425.js → chunk-66DWUSNY.js} +22 -20
- package/dist/{chunk-JAVI7JSP.js → chunk-6FIYEB7M.js} +25 -22
- package/dist/{chunk-VY72R2XZ.js → chunk-6OZAQPU5.js} +532 -358
- package/dist/{chunk-AFWUDXEM.js → chunk-6TNQO76I.js} +34 -17
- package/dist/{chunk-WF7B67YE.js → chunk-6UTD5RQH.js} +18 -16
- package/dist/{chunk-HNM2YQT2.js → chunk-775FMPUB.js} +7 -7
- package/dist/{chunk-7ASNL4Q4.js → chunk-77AZRGWE.js} +19 -16
- package/dist/{chunk-WKUJ3KPV.js → chunk-7HWCEDPX.js} +7 -5
- package/dist/{chunk-G6X77UJZ.js → chunk-7U46TCRZ.js} +25 -22
- package/dist/{chunk-O45HFTFS.js → chunk-A3NUZJFI.js} +4 -2
- package/dist/{chunk-UPOY4YSQ.js → chunk-A4VDFIMR.js} +14 -12
- package/dist/{chunk-EMRIQUND.js → chunk-A53IYUCR.js} +87 -29
- package/dist/{chunk-S4PMJU6H.js → chunk-A6ZG3UOS.js} +108 -50
- package/dist/{chunk-PMUAJGLI.js → chunk-AAY6VPPO.js} +18 -16
- package/dist/{chunk-MG4ZL5RW.js → chunk-ABDE5IRC.js} +18 -16
- package/dist/{chunk-T6DQR5TV.js → chunk-AM7PYKVP.js} +15 -13
- package/dist/{chunk-SFSPGFCV.js → chunk-ANUMIPF6.js} +22 -20
- package/dist/{chunk-VTZMAJ3W.js → chunk-ASFRT33J.js} +11 -9
- package/dist/{chunk-7FTTA3HD.js → chunk-AWDCVZYO.js} +9 -7
- package/dist/{chunk-KFAVQZSX.js → chunk-B63NWU3P.js} +14 -12
- package/dist/{chunk-YYY3AZFE.js → chunk-BBZ6UKN3.js} +16 -5
- package/dist/{chunk-Q4K5WB2W.js → chunk-BFQ5IKQA.js} +12 -10
- package/dist/{chunk-ZFL7NY4F.js → chunk-BLVFHN3C.js} +73 -42
- package/dist/{chunk-MO6P2JZH.js → chunk-BQXAHIZ6.js} +10 -8
- package/dist/{chunk-Y2EQNWKV.js → chunk-BTS56NV7.js} +91 -41
- package/dist/{chunk-UGUP3ZM6.js → chunk-BWYW533C.js} +18 -16
- package/dist/{chunk-O7FDLW7L.js → chunk-BYKWWSXL.js} +14 -12
- package/dist/chunk-C7BB6IQT.js +147 -0
- package/dist/{chunk-JLUCKAEL.js → chunk-CCQWQFOT.js} +19 -17
- package/dist/{chunk-SYV5LHML.js → chunk-CCQZN6W3.js} +35 -33
- package/dist/{chunk-UCROWG2D.js → chunk-CFSBBLDD.js} +28 -25
- package/dist/{chunk-EIPTLPFC.js → chunk-CFSHLQPK.js} +26 -24
- package/dist/{chunk-2IIMFOPM.js → chunk-CI4D6VSU.js} +20 -18
- package/dist/{chunk-66PPNOON.js → chunk-CKRPMRFQ.js} +28 -25
- package/dist/{chunk-IUPG3UKI.js → chunk-CNF2EZ6S.js} +191 -125
- package/dist/chunk-CTJHEG6A.js +97 -0
- package/dist/{chunk-DOBQKHIF.js → chunk-CU7ZK7KP.js} +30 -29
- package/dist/{chunk-745DAZ4L.js → chunk-CZ75S2EZ.js} +886 -313
- package/dist/{chunk-LGFL54FP.js → chunk-D5CJEKZI.js} +11 -4
- package/dist/{chunk-PBPBMP2B.js → chunk-D5ZC7IMC.js} +5 -3
- package/dist/{chunk-LZ7NUC62.js → chunk-D63NU53X.js} +20 -18
- package/dist/{chunk-BO4KX37X.js → chunk-DCQSPSXU.js} +28 -23
- package/dist/{chunk-WXFLMQSR.js → chunk-DCRZ3OQ7.js} +8 -6
- package/dist/chunk-DD2AXECF.js +41 -0
- package/dist/{chunk-4EURQWQD.js → chunk-DF6DPCW2.js} +16 -14
- package/dist/{chunk-53T4O55J.js → chunk-DH3EQMIA.js} +5 -3
- package/dist/{chunk-ZX57KSEQ.js → chunk-DIXA74N7.js} +5 -3
- package/dist/{chunk-6ZGLAACW.js → chunk-DIYNRYXW.js} +2 -2
- package/dist/chunk-DYDNW4O6.js +52 -0
- package/dist/{chunk-P2V7QW4D.js → chunk-E7YDJH6B.js} +16 -14
- package/dist/chunk-EEKQI3U4.js +45 -0
- package/dist/{chunk-GZY6RUZ6.js → chunk-EHF2MBGR.js} +9 -4
- package/dist/chunk-EHXDB3SA.js +25 -0
- package/dist/{chunk-PJSJPMJI.js → chunk-ENZ3PI7L.js} +3 -3
- package/dist/{chunk-E3ISYXO3.js → chunk-EPQQ2XVM.js} +16 -14
- package/dist/{chunk-7IGKHZ4Z.js → chunk-ESJALLOK.js} +222 -213
- package/dist/chunk-ETQSQ2EC.js +33 -0
- package/dist/{chunk-MFR5OPBD.js → chunk-EUMXLSW5.js} +14 -6
- package/dist/{chunk-BTY3HZBO.js → chunk-F63F4NKT.js} +18 -16
- package/dist/{chunk-ZFFYNRIO.js → chunk-FDL2JOLB.js} +26 -22
- package/dist/{chunk-5SJZW52K.js → chunk-FFDVAV56.js} +24 -22
- package/dist/chunk-FFYOZ7PF.js +27 -0
- package/dist/{chunk-RXPJMEOW.js → chunk-FGW5TLGM.js} +24 -19
- package/dist/{chunk-UPS2DGFC.js → chunk-FL53R4SW.js} +1 -1
- package/dist/chunk-FYWLB7PO.js +38 -0
- package/dist/{chunk-FFLNS6VP.js → chunk-G3W7GNEP.js} +24 -18
- package/dist/chunk-G3ZFEHCX.js +925 -0
- package/dist/{chunk-YHCMZC2J.js → chunk-G67GOK4S.js} +10 -8
- package/dist/{chunk-2F4CYZKJ.js → chunk-GCMDDVIE.js} +14 -9
- package/dist/{chunk-QKUJMING.js → chunk-GFYVVTKH.js} +10 -8
- package/dist/chunk-GJVCBTSO.js +20722 -0
- package/dist/{chunk-VCTWPLAO.js → chunk-GKZDHXC2.js} +8 -8
- package/dist/{chunk-5BD2KYLE.js → chunk-GQFUEUC7.js} +18 -16
- package/dist/chunk-GQPP4P2E.js +33 -0
- package/dist/{chunk-42SIDKEU.js → chunk-GS7N3RFG.js} +51 -32
- package/dist/{chunk-LJXMYKZJ.js → chunk-GXQYEIYM.js} +7 -5
- package/dist/{chunk-VNU26RCO.js → chunk-H5EQOSTC.js} +43 -33
- package/dist/{chunk-W7VWI2YH.js → chunk-H7KERB6Q.js} +7 -5
- package/dist/{chunk-OUBGGKDU.js → chunk-HGDBM3A5.js} +5 -3
- package/dist/{chunk-JENSEMXF.js → chunk-HI7ADE4E.js} +1 -1
- package/dist/{chunk-CXJ6FUKN.js → chunk-HNPKCRCE.js} +1010 -330
- package/dist/{chunk-FPJPLKDW.js → chunk-HRHXTLUM.js} +40 -16
- package/dist/{chunk-57TDNMI3.js → chunk-HRYI22QU.js} +17 -15
- package/dist/{chunk-LO6P2VYG.js → chunk-HWNFFCGB.js} +5 -3
- package/dist/{chunk-XI2LCCYQ.js → chunk-HXFZX2BI.js} +12 -8
- package/dist/{chunk-H7KM7LZE.js → chunk-HYHV2P3G.js} +16 -13
- package/dist/{chunk-X3WY6MN3.js → chunk-IB66ZLDN.js} +10 -8
- package/dist/{chunk-3NFFJL5D.js → chunk-IJQHBK76.js} +1 -1
- package/dist/{chunk-LQJPN536.js → chunk-IK6LHW3E.js} +6 -4
- package/dist/{chunk-DCZWQLYT.js → chunk-IOHRX4KF.js} +26 -21
- package/dist/{chunk-2GF7OLF3.js → chunk-IRXZKKCG.js} +21 -15
- package/dist/{chunk-Z5IA3WDR.js → chunk-IUBBEU6O.js} +160 -81
- package/dist/{chunk-W62H2XSO.js → chunk-IWPO5AUT.js} +29 -26
- package/dist/{chunk-BEVTIBRH.js → chunk-J4K4C4T5.js} +31 -15
- package/dist/{chunk-WERM6KPJ.js → chunk-JCEYOSST.js} +14 -6
- package/dist/{chunk-HYU5VLGA.js → chunk-JCG2EBNB.js} +1 -1
- package/dist/{chunk-UNAGJYET.js → chunk-JFBVIMGY.js} +14 -12
- package/dist/chunk-JJ4SCGRJ.js +43 -0
- package/dist/{chunk-2Q5EDGEO.js → chunk-JLYH2QOE.js} +7 -5
- package/dist/{chunk-X4CXA2IL.js → chunk-JMH6TCZJ.js} +23 -21
- package/dist/{chunk-6PPOWY5E.js → chunk-JUHZBZPZ.js} +17 -13
- package/dist/{chunk-GUX3PTYM.js → chunk-JVMNEI7B.js} +3 -3
- package/dist/chunk-JYJMIAFS.js +44 -0
- package/dist/{chunk-34S2WGOB.js → chunk-KIY2WCN7.js} +7 -3
- package/dist/chunk-KVVNAUIG.js +66 -0
- package/dist/{chunk-M32BLWDH.js → chunk-KYO5HT4G.js} +14 -12
- package/dist/chunk-L27KUL5B.js +38 -0
- package/dist/chunk-L3PIN47C.js +18 -0
- package/dist/{chunk-IH2XURVQ.js → chunk-L6Z6TMIK.js} +5 -5
- package/dist/{chunk-E6ZIEVOI.js → chunk-LAGZBQHK.js} +16 -13
- package/dist/chunk-LBG4GMOR.js +68 -0
- package/dist/{chunk-UF4GLFBX.js → chunk-LDKP7OWQ.js} +33 -24
- package/dist/{chunk-ZQ7SKESZ.js → chunk-LELM7X5H.js} +13 -11
- package/dist/{chunk-INQHESFB.js → chunk-LIB6AUZS.js} +6 -4
- package/dist/{chunk-H5HBGNXU.js → chunk-LIQWFDOZ.js} +6 -4
- package/dist/{chunk-TYQBFTBR.js → chunk-LKUTBQ2Y.js} +8 -6
- package/dist/{chunk-7BR7IPOH.js → chunk-LOCJHNZI.js} +10 -8
- package/dist/{chunk-SQV37XO2.js → chunk-LTIXFLYE.js} +6 -6
- package/dist/{chunk-3NWDLGG6.js → chunk-M3RWF7MC.js} +33 -29
- package/dist/chunk-MA6UK7GX.js +42 -0
- package/dist/{chunk-ISUAAMGS.js → chunk-MCE74XMF.js} +25 -16
- package/dist/{chunk-EGQRREQH.js → chunk-MDTAZ6NE.js} +37 -24
- package/dist/{chunk-ZZK56BLP.js → chunk-MMOMKHAX.js} +6 -4
- package/dist/{chunk-P32RUW3B.js → chunk-MOWUP33K.js} +49 -15
- package/dist/{chunk-UOR2DTHH.js → chunk-MPATOMY5.js} +18 -14
- package/dist/{chunk-LNBQOP7D.js → chunk-MQFSEGTU.js} +23 -21
- package/dist/{chunk-2Q56PQPS.js → chunk-MT3FNSXO.js} +4 -4
- package/dist/{chunk-FZOJFH7Q.js → chunk-MUY5MAGM.js} +15 -12
- package/dist/{chunk-7DOR27HL.js → chunk-MVXMISNA.js} +9 -7
- package/dist/{chunk-CX4RZ2KS.js → chunk-MWN7CBVL.js} +5 -3
- package/dist/{chunk-BXYMYEJ4.js → chunk-MZWM73S2.js} +18 -17
- package/dist/chunk-NBZ7RKX3.js +46 -0
- package/dist/{chunk-EPCJQQWD.js → chunk-NC56V6KQ.js} +6 -4
- package/dist/{chunk-7UOMVMFG.js → chunk-NN6AXKFX.js} +17 -15
- package/dist/{chunk-BIGDQDHD.js → chunk-NOU5IBLM.js} +6 -4
- package/dist/{chunk-LFGTYX5U.js → chunk-NQDHRT2H.js} +20 -18
- package/dist/{chunk-KDNTAPLX.js → chunk-NTEPBOAF.js} +6 -4
- package/dist/{chunk-LYBNHMVZ.js → chunk-NTOPAOBY.js} +3 -3
- package/dist/{chunk-R44CYFPV.js → chunk-NX5IPHI3.js} +19 -16
- package/dist/{chunk-GCWRWSU7.js → chunk-O4ZWZZZT.js} +6 -4
- package/dist/chunk-OCU5S2XG.js +36 -0
- package/dist/{chunk-SU74NDMQ.js → chunk-OKSRK2LJ.js} +19 -17
- package/dist/{chunk-XD75VZIH.js → chunk-OSWOIFRQ.js} +9 -7
- package/dist/{chunk-PKBHS4AA.js → chunk-OSZTENIA.js} +54 -21
- package/dist/{chunk-NDCF4R6S.js → chunk-OTUBMKSG.js} +10 -8
- package/dist/{chunk-THDMSZ3R.js → chunk-OYKNPZCV.js} +2837 -693
- package/dist/{chunk-ZQ3ON2VQ.js → chunk-OYTSRNSZ.js} +8 -6
- package/dist/chunk-OYZ64UMQ.js +67 -0
- package/dist/{chunk-UF4AZOZB.js → chunk-PB3NCPRF.js} +10 -8
- package/dist/chunk-PIPJZIJE.js +47 -0
- package/dist/{chunk-2RLKFUUL.js → chunk-PIPYJTIL.js} +27 -24
- package/dist/{chunk-MZCGSXVR.js → chunk-PUMNCWHJ.js} +15 -13
- package/dist/{chunk-X5F3Q5LV.js → chunk-PZBNDFZ7.js} +35 -25
- package/dist/chunk-Q2ULHBCJ.js +59 -0
- package/dist/{chunk-ZJFRMSJT.js → chunk-Q5QSWV2R.js} +14 -12
- package/dist/{chunk-Q2TECDIT.js → chunk-QFDPX6C4.js} +2886 -20703
- package/dist/{chunk-WG5U3F5V.js → chunk-QGBS4GMS.js} +14 -12
- package/dist/{chunk-BTGPE6CR.js → chunk-QIDSEHJA.js} +17 -15
- package/dist/{chunk-Q6DFNVRJ.js → chunk-QJ3AYXVO.js} +14 -12
- package/dist/{chunk-EBL2R3YG.js → chunk-QK6CGRKK.js} +6 -4
- package/dist/{chunk-S7FCV7S5.js → chunk-QOC3Q4UU.js} +1 -1
- package/dist/{chunk-JJF6HALY.js → chunk-QPLNB2BM.js} +5 -3
- package/dist/chunk-QVF4KYIO.js +71 -0
- package/dist/{chunk-6OJQOPUN.js → chunk-QXXEO4TF.js} +5 -3
- package/dist/{chunk-F3P7N7SF.js → chunk-QYFNVQLK.js} +1 -1
- package/dist/{chunk-6MUGR4LS.js → chunk-R6CJOMPC.js} +106 -29
- package/dist/{chunk-BDKC6H5P.js → chunk-ROWZYQOI.js} +9 -7
- package/dist/{chunk-2MMCFP5C.js → chunk-RQAMZVWW.js} +10 -8
- package/dist/chunk-RQSUFGU2.js +55 -0
- package/dist/{chunk-SDKLKB6I.js → chunk-RRKM3GJA.js} +38 -28
- package/dist/{chunk-OHNCWBKF.js → chunk-RSHVSXPJ.js} +7 -5
- package/dist/chunk-RSKMV3VC.js +22 -0
- package/dist/{chunk-U76OWS3Q.js → chunk-RU5W7JJQ.js} +25 -23
- package/dist/{chunk-63YRMR6J.js → chunk-RYY554OA.js} +7 -5
- package/dist/{chunk-5NMKONLP.js → chunk-SGYQORAD.js} +7 -3
- package/dist/{chunk-JA5FI3QV.js → chunk-SLGUSFOD.js} +3 -3
- package/dist/{chunk-M3NANSDZ.js → chunk-SUAHNYNQ.js} +17 -15
- package/dist/{chunk-QAXW2N3B.js → chunk-SUYC5NP6.js} +34 -34
- package/dist/{chunk-FFTRTL6R.js → chunk-SWSGRRNO.js} +6 -4
- package/dist/{chunk-UWOJLHFT.js → chunk-SYLXQNPC.js} +38 -24
- package/dist/chunk-T24TBI7F.js +54 -0
- package/dist/chunk-T2HXLDY3.js +55 -0
- package/dist/{chunk-O4GXGGBX.js → chunk-T5NH5L7A.js} +16 -13
- package/dist/{chunk-KXITGYLF.js → chunk-TAR6T2RE.js} +4 -2
- package/dist/chunk-TBQHBOFF.js +324 -0
- package/dist/{chunk-LKOR5UET.js → chunk-TKE6ZJMM.js} +26 -24
- package/dist/chunk-TKEXS74L.js +52 -0
- package/dist/{chunk-J3IOLXWM.js → chunk-TXYMNKGM.js} +16 -14
- package/dist/{chunk-IDKCWSM5.js → chunk-U2JTTRKS.js} +401 -115
- package/dist/{chunk-TNR75OXT.js → chunk-U37ZOYJJ.js} +11 -8
- package/dist/{chunk-7MJSQTL5.js → chunk-U57VLY6X.js} +23 -21
- package/dist/{chunk-BHT7QK4G.js → chunk-U66RQUFC.js} +6 -4
- package/dist/chunk-UCFNHK5L.js +50 -0
- package/dist/{chunk-IFKEI4SA.js → chunk-UI6KNLSO.js} +31 -11
- package/dist/{chunk-7GJS6DNX.js → chunk-UKRJ2ISN.js} +13 -3
- package/dist/chunk-UWJOM457.js +232 -0
- package/dist/{chunk-D73UEXYW.js → chunk-UXO25YBN.js} +3 -3
- package/dist/chunk-VE2T5URA.js +51 -0
- package/dist/{chunk-C3RY6KU6.js → chunk-W4EG25TI.js} +513 -172
- package/dist/{chunk-O66DM6DJ.js → chunk-WAAPMZWO.js} +6 -4
- package/dist/{chunk-R7NYHMUU.js → chunk-WECCLSYY.js} +4884 -3669
- package/dist/chunk-WQDJGNJQ.js +45 -0
- package/dist/{chunk-UWMJKX5U.js → chunk-WWSCJBF6.js} +14 -12
- package/dist/{chunk-N3XIYPU3.js → chunk-X7HFXXTZ.js} +16 -13
- package/dist/chunk-X7XVMYIL.js +5 -0
- package/dist/{chunk-NR2UJWOC.js → chunk-XERIHPBF.js} +12 -9
- package/dist/{chunk-JRBFANFE.js → chunk-XKNISZ6N.js} +21 -18
- package/dist/{chunk-PPD7HTDP.js → chunk-XNH5ZWIA.js} +20 -18
- package/dist/{chunk-7IOWA5D5.js → chunk-XNW3EDCY.js} +13 -3
- package/dist/{chunk-2LGRMVCA.js → chunk-XPXOKHNZ.js} +13 -11
- package/dist/{chunk-ZJXLNDH4.js → chunk-XXRBAJ36.js} +14 -12
- package/dist/{chunk-EHA7RMZ3.js → chunk-YA2IJJ6N.js} +8 -6
- package/dist/{chunk-LGBMTVNT.js → chunk-YB5AKYVQ.js} +7 -5
- package/dist/{chunk-JB5LINEM.js → chunk-YDDLVBQ4.js} +3 -3
- package/dist/{chunk-PAQ2AS5E.js → chunk-YF6N45QN.js} +1 -1
- package/dist/{chunk-WMTRHUI5.js → chunk-YHWX5LPT.js} +23 -21
- package/dist/{chunk-KQGURXFU.js → chunk-YLZNTVZR.js} +36 -13
- package/dist/{chunk-NY2XSR5K.js → chunk-YUJTOALL.js} +118 -18
- package/dist/{chunk-VZALIKIF.js → chunk-Z5YDTIWQ.js} +19 -16
- package/dist/{chunk-LDLL7LB3.js → chunk-ZCU2UY47.js} +24 -22
- package/dist/{chunk-OWNCM4ZN.js → chunk-ZIAYNHHE.js} +197 -17
- package/dist/{chunk-WJF2CS6M.js → chunk-ZJ2W2RDE.js} +7 -5
- package/dist/{chunk-REWWDVQB.js → chunk-ZRQHSMPK.js} +6 -4
- package/dist/{chunk-O7XLYEFA.js → chunk-ZSD75FYI.js} +57 -23
- package/dist/chunk-ZSNNF26J.js +220 -0
- package/dist/{chunk-BQ4SQQC6.js → chunk-ZX6RAGE6.js} +11 -9
- package/dist/files.json +583 -515
- package/dist/packages/sdk/npm/index.js +6428 -4882
- package/dist/packages/ui/dist/assets/{elk-api-CIf-0gz5.js → elk-api--rH6Kdl4.js} +2 -2
- package/dist/packages/ui/dist/assets/index-Bf2immpE.css +1 -0
- package/dist/packages/ui/dist/assets/index-CH4nGIW3.js +62 -0
- package/dist/packages/ui/dist/index.html +2 -2
- package/package.json +6 -6
- package/dist/chunk-2SKB4O2E.js +0 -59
- package/dist/chunk-4U276ICE.js +0 -39
- package/dist/chunk-6H3Z5JHH.js +0 -64
- package/dist/chunk-AFZ3QA6W.js +0 -47
- package/dist/chunk-AVTBS4OW.js +0 -49
- package/dist/chunk-C4R4JLHE.js +0 -40
- package/dist/chunk-CBGGOQWU.js +0 -82
- package/dist/chunk-CMDXGQTS.js +0 -47
- package/dist/chunk-DLOBCJL6.js +0 -48
- package/dist/chunk-GIW4ZVDB.js +0 -39
- package/dist/chunk-IP74LCOQ.js +0 -57
- package/dist/chunk-IPHHDDC6.js +0 -45
- package/dist/chunk-KJXD4PNL.js +0 -50
- package/dist/chunk-KN5BXMWN.js +0 -44
- package/dist/chunk-MFHL5URL.js +0 -31
- package/dist/chunk-NXJ5URP6.js +0 -51
- package/dist/chunk-OMI6FPPN.js +0 -43
- package/dist/chunk-ONUPY3H6.js +0 -53
- package/dist/chunk-OTLDSZDV.js +0 -69
- package/dist/chunk-PSOFBQWB.js +0 -42
- package/dist/chunk-T4YPZIQN.js +0 -36
- package/dist/chunk-TUULXQRW.js +0 -420
- package/dist/chunk-WNKPRSGI.js +0 -36
- package/dist/packages/ui/dist/assets/index-CoK_Dl0D.js +0 -47
- package/dist/packages/ui/dist/assets/index-Dw20IRhQ.css +0 -1
- package/dist/{chunk-24XLDU72.js → chunk-PXMV2LLY.js} +3 -3
|
@@ -3,23 +3,23 @@ import { fileURLToPath as __atticusFileURLToPath } from "node:url";
|
|
|
3
3
|
var require = __atticusCreateRequire(import.meta.url);
|
|
4
4
|
var __atticusUrl = (p) => new URL("./" + p, import.meta.url).href;
|
|
5
5
|
var __atticusPath = (p) => __atticusFileURLToPath(__atticusUrl(p));
|
|
6
|
-
import {
|
|
7
|
-
featuresForScan,
|
|
8
|
-
namingHint,
|
|
9
|
-
syncSources
|
|
10
|
-
} from "./chunk-745DAZ4L.js";
|
|
11
6
|
import {
|
|
12
7
|
dirSource,
|
|
13
8
|
rereadPlan,
|
|
14
9
|
sameCommit,
|
|
15
10
|
verifyFacts
|
|
16
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-HNPKCRCE.js";
|
|
12
|
+
import {
|
|
13
|
+
featuresForScan,
|
|
14
|
+
namingHint,
|
|
15
|
+
syncSources
|
|
16
|
+
} from "./chunk-CZ75S2EZ.js";
|
|
17
17
|
import {
|
|
18
18
|
scanInputs
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-GFYVVTKH.js";
|
|
20
20
|
import {
|
|
21
21
|
listIngestors
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-DIYNRYXW.js";
|
|
23
23
|
import {
|
|
24
24
|
BUILT_IN_EXTRACTORS,
|
|
25
25
|
MODEL_READERS,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
runDialectTests,
|
|
35
35
|
runFrameworkTests,
|
|
36
36
|
unmodelledFrameworks
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-5FPAKAGE.js";
|
|
38
38
|
import {
|
|
39
39
|
DEFAULT_IGNORES,
|
|
40
40
|
configHash,
|
|
@@ -46,31 +46,24 @@ import {
|
|
|
46
46
|
sandboxedExtractor,
|
|
47
47
|
scanRepo,
|
|
48
48
|
withParseCache
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-IJQHBK76.js";
|
|
50
|
+
import {
|
|
51
|
+
buildContextPack,
|
|
52
|
+
toRunSummary
|
|
53
|
+
} from "./chunk-MOWUP33K.js";
|
|
50
54
|
import {
|
|
51
55
|
baseClonePath,
|
|
52
56
|
changesSince,
|
|
53
57
|
checkoutState,
|
|
54
58
|
inPlaceDir
|
|
55
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-OSZTENIA.js";
|
|
56
60
|
import {
|
|
57
|
-
buildContextPack,
|
|
58
|
-
toRunSummary
|
|
59
|
-
} from "./chunk-P32RUW3B.js";
|
|
60
|
-
import {
|
|
61
|
-
AgentDefinition,
|
|
62
61
|
DECLARED_CALLER,
|
|
63
|
-
DEFAULT_SPEC_TEMPLATE,
|
|
64
62
|
HOSTS_NONE,
|
|
65
63
|
HOSTS_OUTSIDE_INTERNAL,
|
|
66
64
|
HOSTS_OUTSIDE_VENDOR,
|
|
67
|
-
|
|
68
|
-
NEVER_CHECKED_STEPS,
|
|
65
|
+
HOSTS_STEP,
|
|
69
66
|
NO_TARGET,
|
|
70
|
-
PluginExpected,
|
|
71
|
-
REPO_TYPE_SCHEMA_VERSION,
|
|
72
|
-
RecordId,
|
|
73
|
-
SCAN_SETTINGS_SCHEMA_VERSION,
|
|
74
67
|
TARGETS_ANOTHER_LABEL,
|
|
75
68
|
TARGETS_SPLIT_LABEL,
|
|
76
69
|
TARGETS_STEP_ID,
|
|
@@ -83,31 +76,26 @@ import {
|
|
|
83
76
|
callTargetQuestion,
|
|
84
77
|
callerRecords,
|
|
85
78
|
catalogDirOf,
|
|
86
|
-
cmpNatural,
|
|
87
|
-
cmpText,
|
|
88
|
-
conventionsOf,
|
|
89
79
|
declaredCallsOf,
|
|
90
80
|
deserializeRecord,
|
|
91
|
-
effectiveComponentTypes,
|
|
92
|
-
external_exports,
|
|
93
81
|
factIdPart,
|
|
94
82
|
factsDirOf,
|
|
95
83
|
factsRelOf,
|
|
96
84
|
fieldKey,
|
|
97
85
|
flowFiles,
|
|
98
86
|
helperOn,
|
|
99
|
-
|
|
87
|
+
hostOfQuestion,
|
|
100
88
|
hostQuestionText,
|
|
101
89
|
identifierWords,
|
|
102
|
-
|
|
90
|
+
ignoreOption,
|
|
91
|
+
ignoredAnswer,
|
|
103
92
|
isGuessedJoin,
|
|
104
|
-
isPathMatch,
|
|
105
93
|
isPrototypeType,
|
|
106
94
|
joinCallers,
|
|
107
|
-
joinConventions,
|
|
108
95
|
joinFacts,
|
|
109
96
|
joinFlagsOf,
|
|
110
97
|
joinGuessesOf,
|
|
98
|
+
joinHostOfQuestion,
|
|
111
99
|
joinRecords,
|
|
112
100
|
joinSharedMaps,
|
|
113
101
|
joinTerms,
|
|
@@ -116,15 +104,16 @@ import {
|
|
|
116
104
|
lineNamesWord,
|
|
117
105
|
linkEvidenceOf,
|
|
118
106
|
listQuestions,
|
|
119
|
-
loadOrgPack,
|
|
120
107
|
mergeCatalog,
|
|
121
|
-
normalizePath,
|
|
122
108
|
orgPackDirOf,
|
|
109
|
+
outsideBoundaryOf,
|
|
123
110
|
outsideSystemOf,
|
|
111
|
+
outsideSystemOfJoinHost,
|
|
124
112
|
pairsFromCorrections,
|
|
125
113
|
parseCorrections,
|
|
126
114
|
parseFacts,
|
|
127
115
|
parseRecord,
|
|
116
|
+
placeholderIn,
|
|
128
117
|
projectFacts,
|
|
129
118
|
questionId,
|
|
130
119
|
readParsedFiles,
|
|
@@ -132,7 +121,6 @@ import {
|
|
|
132
121
|
serializeRecord,
|
|
133
122
|
sharedJoinAbout,
|
|
134
123
|
singularNoun,
|
|
135
|
-
slugify,
|
|
136
124
|
specFileHash,
|
|
137
125
|
specFindingFingerprint,
|
|
138
126
|
stackHelpersOff,
|
|
@@ -142,13 +130,38 @@ import {
|
|
|
142
130
|
throwIfCancelled,
|
|
143
131
|
toCanonicalYaml,
|
|
144
132
|
topicOfQuestion,
|
|
145
|
-
topicQuestionText
|
|
133
|
+
topicQuestionText
|
|
134
|
+
} from "./chunk-GJVCBTSO.js";
|
|
135
|
+
import {
|
|
136
|
+
writeFileAtomic
|
|
137
|
+
} from "./chunk-G3ZFEHCX.js";
|
|
138
|
+
import {
|
|
139
|
+
AgentDefinition,
|
|
140
|
+
DEFAULT_SPEC_TEMPLATE,
|
|
141
|
+
IsoDateTime,
|
|
142
|
+
NEVER_CHECKED_STEPS,
|
|
143
|
+
PluginExpected,
|
|
144
|
+
REPO_TYPE_SCHEMA_VERSION,
|
|
145
|
+
RecordId,
|
|
146
|
+
SCAN_SETTINGS_SCHEMA_VERSION,
|
|
147
|
+
cmpNatural,
|
|
148
|
+
cmpText,
|
|
149
|
+
conventionsOf,
|
|
150
|
+
effectiveComponentTypes,
|
|
151
|
+
external_exports,
|
|
152
|
+
hostMatches,
|
|
153
|
+
isAiBy,
|
|
154
|
+
isPathMatch,
|
|
155
|
+
joinConventions,
|
|
156
|
+
loadOrgPack,
|
|
157
|
+
normalizePath,
|
|
158
|
+
slugify,
|
|
146
159
|
urlHostPort
|
|
147
|
-
} from "./chunk-
|
|
160
|
+
} from "./chunk-QFDPX6C4.js";
|
|
148
161
|
import {
|
|
149
162
|
SCHEMA_VERSION,
|
|
150
|
-
|
|
151
|
-
} from "./chunk-
|
|
163
|
+
keptParse
|
|
164
|
+
} from "./chunk-CTJHEG6A.js";
|
|
152
165
|
import {
|
|
153
166
|
require_dist
|
|
154
167
|
} from "./chunk-BQGDB6ZL.js";
|
|
@@ -1481,17 +1494,401 @@ function estateMergeInput(op, repos, records, modulesOf = (id) => repos.find((r)
|
|
|
1481
1494
|
function mergeEstate(op, repos, records, modulesOf, read) {
|
|
1482
1495
|
return mergeCatalog(estateMergeInput(op, repos, records, modulesOf, read));
|
|
1483
1496
|
}
|
|
1484
|
-
function curatedDirOf(root, op) {
|
|
1485
|
-
return join5(root, ...op.sources.layout.catalog.split("/"), "curated");
|
|
1497
|
+
function curatedDirOf(root, op) {
|
|
1498
|
+
return join5(root, ...op.sources.layout.catalog.split("/"), "curated");
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
// packages/scanner/dist/facts-scan.js
|
|
1502
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
1503
|
+
import { join as join6 } from "node:path";
|
|
1504
|
+
|
|
1505
|
+
// packages/scanner/dist/facts-catalog.js
|
|
1506
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
1507
|
+
|
|
1508
|
+
// packages/scanner/dist/hosts-asked.js
|
|
1509
|
+
var segs = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$]/.test(x) ? "{}" : x);
|
|
1510
|
+
var underPath = (path, base2) => {
|
|
1511
|
+
const b = segs(base2);
|
|
1512
|
+
const c = segs(path);
|
|
1513
|
+
return b.length > 0 && b.length <= c.length && b.every((x, i) => x === c[i]);
|
|
1514
|
+
};
|
|
1515
|
+
var servesPath = (entry, path) => {
|
|
1516
|
+
const e = segs(entry);
|
|
1517
|
+
const c = segs(path);
|
|
1518
|
+
return e.length === c.length && e.every((x, i) => x === "{}" || c[i] === "{}" || x === c[i]);
|
|
1519
|
+
};
|
|
1520
|
+
var HTTP_TYPES = /* @__PURE__ */ new Set(["rest", "graphql", "soap", "websocket", "sse", "webhook"]);
|
|
1521
|
+
var CONFIG_FILES = [
|
|
1522
|
+
"**/application*.properties",
|
|
1523
|
+
"**/application*.yml",
|
|
1524
|
+
"**/application*.yaml",
|
|
1525
|
+
"**/bootstrap*.properties",
|
|
1526
|
+
"**/bootstrap*.yml",
|
|
1527
|
+
"**/bootstrap*.yaml",
|
|
1528
|
+
"**/.env",
|
|
1529
|
+
"**/.env.*",
|
|
1530
|
+
"**/Dockerfile",
|
|
1531
|
+
"**/docker-compose*.yml",
|
|
1532
|
+
"**/docker-compose*.yaml",
|
|
1533
|
+
"**/compose*.yml",
|
|
1534
|
+
"**/compose*.yaml",
|
|
1535
|
+
"**/package.json"
|
|
1536
|
+
];
|
|
1537
|
+
function lineSetsPort(line, port) {
|
|
1538
|
+
const p = String(port);
|
|
1539
|
+
const end = "(?![0-9])";
|
|
1540
|
+
return [
|
|
1541
|
+
new RegExp(`port["']?\\s*[:=]\\s*["']?${p}${end}`, "i"),
|
|
1542
|
+
new RegExp(`^\\s*EXPOSE\\s+(?:[0-9]+(?:/[a-z]+)?\\s+)*${p}${end}`, "i"),
|
|
1543
|
+
new RegExp(`--port[=\\s]+${p}${end}`, "i"),
|
|
1544
|
+
new RegExp(`(?:^|[\\s"'-])${p}:[0-9]+`)
|
|
1545
|
+
].some((re) => re.test(line));
|
|
1546
|
+
}
|
|
1547
|
+
function callHost(url) {
|
|
1548
|
+
if (url.includes("${"))
|
|
1549
|
+
return void 0;
|
|
1550
|
+
if (tokenHost(url))
|
|
1551
|
+
return void 0;
|
|
1552
|
+
const hp = urlHostPort(url);
|
|
1553
|
+
if (!hp || !hp.host)
|
|
1554
|
+
return void 0;
|
|
1555
|
+
const explicit = /^[a-z][a-z0-9+.-]*:\/\/(?:[^/@?#]*@)?[^/:?#]+:(\d+)/i.exec(url);
|
|
1556
|
+
return {
|
|
1557
|
+
label: explicit ? `${hp.host}:${explicit[1]}` : hp.host,
|
|
1558
|
+
host: hp.host,
|
|
1559
|
+
...hp.port !== void 0 ? { port: hp.port } : {}
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
function tokenHost(url) {
|
|
1563
|
+
const authority = /^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)/i.exec(url)?.[1] ?? url;
|
|
1564
|
+
return !!placeholderIn(authority);
|
|
1565
|
+
}
|
|
1566
|
+
var callHostLabel = (url) => callHost(url)?.label;
|
|
1567
|
+
async function unknownHosts(o) {
|
|
1568
|
+
const patterns = o.repos.flatMap((r) => [
|
|
1569
|
+
...r.hosts,
|
|
1570
|
+
...(r.modules ?? []).flatMap((m) => m.hosts)
|
|
1571
|
+
]);
|
|
1572
|
+
const byHost = /* @__PURE__ */ new Map();
|
|
1573
|
+
for (const r of o.records) {
|
|
1574
|
+
if (r.kind !== "Unresolved" || r.unresolvedKind !== "http-call")
|
|
1575
|
+
continue;
|
|
1576
|
+
const url = r.raw.slice(r.raw.indexOf(" ") + 1);
|
|
1577
|
+
const h = callHost(url);
|
|
1578
|
+
if (!h)
|
|
1579
|
+
continue;
|
|
1580
|
+
if (patterns.some((p) => hostMatches(p, h.host, h.port)))
|
|
1581
|
+
continue;
|
|
1582
|
+
const e = r.evidence[0];
|
|
1583
|
+
const repo = e?.repo ?? r.owner;
|
|
1584
|
+
if (!e?.path || e.line === void 0 || !repo)
|
|
1585
|
+
continue;
|
|
1586
|
+
const entry = byHost.get(h.label) ?? {
|
|
1587
|
+
...h.port !== void 0 ? { port: h.port } : {},
|
|
1588
|
+
explicit: h.label !== h.host,
|
|
1589
|
+
calls: [],
|
|
1590
|
+
paths: /* @__PURE__ */ new Set()
|
|
1591
|
+
};
|
|
1592
|
+
const path = /^[a-z][a-z0-9+.-]*:\/\/[^/?#]*(\/[^?#]*)?/i.exec(url)?.[1];
|
|
1593
|
+
if (path)
|
|
1594
|
+
entry.paths.add(path);
|
|
1595
|
+
const at3 = `${e.path}:${e.line}`;
|
|
1596
|
+
if (!entry.calls.some((c) => c.repo === repo && c.at === at3))
|
|
1597
|
+
entry.calls.push({ repo, at: at3 });
|
|
1598
|
+
byHost.set(h.label, entry);
|
|
1599
|
+
}
|
|
1600
|
+
if (byHost.size === 0)
|
|
1601
|
+
return [];
|
|
1602
|
+
const compRepo = /* @__PURE__ */ new Map();
|
|
1603
|
+
for (const r of o.repos) {
|
|
1604
|
+
compRepo.set(r.component ?? r.id, r.id);
|
|
1605
|
+
for (const m of r.modules ?? [])
|
|
1606
|
+
compRepo.set(m.component, r.id);
|
|
1607
|
+
}
|
|
1608
|
+
const serving = /* @__PURE__ */ new Set();
|
|
1609
|
+
for (const r of o.records)
|
|
1610
|
+
if (r.kind === "Endpoint" && HTTP_TYPES.has(r.endpointType)) {
|
|
1611
|
+
const repo = compRepo.get(r.component);
|
|
1612
|
+
if (repo)
|
|
1613
|
+
serving.add(repo);
|
|
1614
|
+
}
|
|
1615
|
+
const servers = [...serving].sort();
|
|
1616
|
+
const configs = /* @__PURE__ */ new Map();
|
|
1617
|
+
const configOf = async (repo) => {
|
|
1618
|
+
if (configs.has(repo))
|
|
1619
|
+
return configs.get(repo);
|
|
1620
|
+
const h = o.handle(repo);
|
|
1621
|
+
const out = [];
|
|
1622
|
+
if (h)
|
|
1623
|
+
for await (const path of h.listFiles(CONFIG_FILES)) {
|
|
1624
|
+
const t = await h.readText(path).catch(() => void 0);
|
|
1625
|
+
if (t !== void 0)
|
|
1626
|
+
out.push({ path, lines: t.replace(/\r\n?/g, "\n").split("\n") });
|
|
1627
|
+
}
|
|
1628
|
+
configs.set(repo, out);
|
|
1629
|
+
return out;
|
|
1630
|
+
};
|
|
1631
|
+
const asks = [];
|
|
1632
|
+
for (const [host, entry] of [...byHost.entries()].sort(([a], [b]) => cmpText(a, b))) {
|
|
1633
|
+
if (servers.length === 0)
|
|
1634
|
+
continue;
|
|
1635
|
+
const hits = [];
|
|
1636
|
+
if (entry.explicit && entry.port !== void 0)
|
|
1637
|
+
for (const repo of servers) {
|
|
1638
|
+
hit: for (const f of await configOf(repo))
|
|
1639
|
+
for (const [i, l] of f.lines.entries())
|
|
1640
|
+
if (lineSetsPort(l, entry.port)) {
|
|
1641
|
+
hits.push({ repo, at: `${f.path}:${i + 1}`, line: l.trim() });
|
|
1642
|
+
break hit;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
const suggest = hits.length === 1 ? hits[0] : void 0;
|
|
1646
|
+
const calls = entry.calls.sort((a, b) => cmpText(a.repo, b.repo) || cmpNatural(a.at, b.at));
|
|
1647
|
+
const byPath = [];
|
|
1648
|
+
for (const g of o.records) {
|
|
1649
|
+
if (g.kind !== "GatewayRoute")
|
|
1650
|
+
continue;
|
|
1651
|
+
const repo = g.evidence.find((e) => e.repo)?.repo;
|
|
1652
|
+
if (!repo || byPath.some((b) => b.repo === repo))
|
|
1653
|
+
continue;
|
|
1654
|
+
const under2 = [...entry.paths].filter((p) => underPath(p, g.basepath));
|
|
1655
|
+
if (!under2.length)
|
|
1656
|
+
continue;
|
|
1657
|
+
const comps = new Set([...compRepo].filter(([, r]) => r === repo).map(([c]) => c));
|
|
1658
|
+
const hit = o.records.find((r) => r.kind === "Endpoint" && comps.has(r.component) && under2.some((p) => servesPath(r.pathOrTopic, p)));
|
|
1659
|
+
byPath.push({
|
|
1660
|
+
repo,
|
|
1661
|
+
serves: hit ? [hit.method?.toUpperCase(), hit.pathOrTopic].filter(Boolean).join(" ") : `the routes under ${g.basepath}`
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
byPath.sort((a, b) => cmpText(a.repo, b.repo));
|
|
1665
|
+
const first = suggest ? [suggest.repo] : byPath.map((b) => b.repo).filter((x) => servers.includes(x));
|
|
1666
|
+
const about = Object.fromEntries(servers.flatMap((s) => {
|
|
1667
|
+
const d = o.repos.find((r) => r.id === s)?.description;
|
|
1668
|
+
return d ? [[s, { text: d.text, trust: d.trust }]] : [];
|
|
1669
|
+
}));
|
|
1670
|
+
asks.push({
|
|
1671
|
+
host,
|
|
1672
|
+
calls,
|
|
1673
|
+
servers: [...first, ...servers.filter((s) => !first.includes(s))],
|
|
1674
|
+
...suggest ? { suggest } : {},
|
|
1675
|
+
...Object.keys(about).length ? { about } : {},
|
|
1676
|
+
...byPath.length ? { byPath } : {}
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
return asks;
|
|
1680
|
+
}
|
|
1681
|
+
function aboutOf(a, repo) {
|
|
1682
|
+
const d = a.about?.[repo];
|
|
1683
|
+
if (!d)
|
|
1684
|
+
return "";
|
|
1685
|
+
return d.trust === "suggested" ? `. What it is, as your assistant drafted it (unconfirmed): ${d.text}` : `. What it is: ${d.text}`;
|
|
1686
|
+
}
|
|
1687
|
+
function gatewayHostFix(host, byPath) {
|
|
1688
|
+
const repos = byPath.map((b) => b.repo);
|
|
1689
|
+
return `${repos.length === 1 ? `${repos[0]}'s routes serve` : `The routes of ${repos.join(", ")} serve`} the paths the calls to ${host} make, and no repo lists ${host}: it looks like a shared gateway's host. Once, not per call: list ${host} under hosts: on each proxy repo in repos.manifest.yaml (${repos.join(", ")}, and any other proxy on it); the path then picks the proxy, and this question retires itself`;
|
|
1690
|
+
}
|
|
1691
|
+
function hostQuestionDrafts(asks) {
|
|
1692
|
+
return asks.map((a) => {
|
|
1693
|
+
const repo = a.calls[0].repo;
|
|
1694
|
+
const byPath = new Map((a.byPath ?? []).map((b) => [b.repo, b.serves]));
|
|
1695
|
+
return {
|
|
1696
|
+
repo,
|
|
1697
|
+
...a.byPath?.length ? { byPath: a.byPath } : {},
|
|
1698
|
+
draft: {
|
|
1699
|
+
question: hostQuestionText(a.host),
|
|
1700
|
+
options: [
|
|
1701
|
+
...a.servers.map((s) => ({
|
|
1702
|
+
label: s,
|
|
1703
|
+
means: (a.suggest?.repo === s ? `${s} serves HTTP, and its ${a.suggest.at} sets the port ${a.host.split(":").pop()} (${a.suggest.line})` : byPath.has(s) ? `${s} serves ${byPath.get(s)}, a path the calls to ${a.host} make` : `${s} serves HTTP`) + aboutOf(a, s),
|
|
1704
|
+
changes: byPath.has(s) ? `${a.host} goes under hosts for ${s} in repos.manifest.yaml, and the calls to it join ${s} on the next scan; on a shared gateway host, list it on each proxy repo instead (${[...byPath.keys()].join(", ")}, and any other proxy on it), and the path picks the proxy` : `${a.host} goes under hosts for ${s} in repos.manifest.yaml, and the calls to it join ${s} on the next scan`
|
|
1705
|
+
})),
|
|
1706
|
+
// O1: a system outside the estate, declared in the profile with the host as its alias.
|
|
1707
|
+
...[
|
|
1708
|
+
[HOSTS_OUTSIDE_INTERNAL, "internal", "another team's system"],
|
|
1709
|
+
[HOSTS_OUTSIDE_VENDOR, "vendor", "a vendor's system"]
|
|
1710
|
+
].map(([label2, boundary, what2]) => ({
|
|
1711
|
+
label: label2,
|
|
1712
|
+
means: `${a.host} is ${what2}, outside this estate, that the org pack doesn't name yet`,
|
|
1713
|
+
changes: `A system ${outsideSystemOf(a.host).id} (boundary ${boundary}, alias ${a.host}) goes into the profile, and the calls to ${a.host} go to it on the next scan`
|
|
1714
|
+
})),
|
|
1715
|
+
{
|
|
1716
|
+
label: HOSTS_NONE,
|
|
1717
|
+
means: `Neither a repo of this estate nor a system to add to the org pack answers on ${a.host}`,
|
|
1718
|
+
changes: "Nothing is added to the manifest or the profile; the calls stay loose ends, and this isn't asked again"
|
|
1719
|
+
},
|
|
1720
|
+
// Beta.24 review: every join question offers Ignore from the start.
|
|
1721
|
+
ignoreOption()
|
|
1722
|
+
],
|
|
1723
|
+
evidence: a.calls.filter((c) => c.repo === repo).slice(0, 3).map((c) => c.at),
|
|
1724
|
+
scope: "repo"
|
|
1725
|
+
}
|
|
1726
|
+
};
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
// packages/scanner/dist/join-host-questions.js
|
|
1731
|
+
var HTTP_TYPES2 = /* @__PURE__ */ new Set(["rest", "graphql", "soap", "websocket", "sse", "webhook"]);
|
|
1732
|
+
var segs2 = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$*]/.test(x) ? "{}" : x);
|
|
1733
|
+
var servesPath2 = (entry, path) => {
|
|
1734
|
+
const e = segs2(entry);
|
|
1735
|
+
const c = segs2(path);
|
|
1736
|
+
if (!c.length || c.length > e.length)
|
|
1737
|
+
return false;
|
|
1738
|
+
const tail = e.slice(e.length - c.length);
|
|
1739
|
+
return tail.every((x, i) => x === "{}" || c[i] === "{}" || x === c[i]);
|
|
1740
|
+
};
|
|
1741
|
+
var isTokenHost = (host) => !!placeholderIn(host);
|
|
1742
|
+
function joinHostQuestionDrafts(input) {
|
|
1743
|
+
const byHost = /* @__PURE__ */ new Map();
|
|
1744
|
+
for (const a of input.asks) {
|
|
1745
|
+
if (a.reason !== "unknown-host" || !a.host || a.call.repo !== input.repo)
|
|
1746
|
+
continue;
|
|
1747
|
+
if (input.skip?.has(a.call.fact))
|
|
1748
|
+
continue;
|
|
1749
|
+
if (!isTokenHost(a.host) && input.hostsAsked?.has(a.host))
|
|
1750
|
+
continue;
|
|
1751
|
+
byHost.set(a.host, [...byHost.get(a.host) ?? [], a]);
|
|
1752
|
+
}
|
|
1753
|
+
if (!byHost.size)
|
|
1754
|
+
return [];
|
|
1755
|
+
const compRepo = /* @__PURE__ */ new Map();
|
|
1756
|
+
for (const r of input.repos) {
|
|
1757
|
+
compRepo.set(r.component ?? r.id, r.id);
|
|
1758
|
+
for (const m of r.modules ?? [])
|
|
1759
|
+
compRepo.set(m.component, r.id);
|
|
1760
|
+
}
|
|
1761
|
+
const endpoints = input.records.filter((r) => r.kind === "Endpoint" && HTTP_TYPES2.has(r.endpointType));
|
|
1762
|
+
const servers = [
|
|
1763
|
+
...new Set(endpoints.flatMap((e) => compRepo.has(e.component) ? [compRepo.get(e.component)] : []))
|
|
1764
|
+
].filter((r) => r !== input.repo).sort(cmpText);
|
|
1765
|
+
const factOf = new Map(input.facts.map((f) => [f.id, f]));
|
|
1766
|
+
const out = [];
|
|
1767
|
+
for (const [host, asks] of [...byHost].sort(([a], [b]) => cmpText(a, b))) {
|
|
1768
|
+
const calls = asks.map((a) => ({ id: a.call.fact, at: a.call.at, f: factOf.get(a.call.fact) })).sort((a, b) => cmpNatural(a.at, b.at) || cmpText(a.id, b.id));
|
|
1769
|
+
const paths = calls.flatMap((c) => c.f?.kind === "call" ? [c.f.path] : []);
|
|
1770
|
+
const byPath = [];
|
|
1771
|
+
for (const r of servers) {
|
|
1772
|
+
const hit = endpoints.find((e) => compRepo.get(e.component) === r && paths.some((p) => servesPath2(e.pathOrTopic, p)));
|
|
1773
|
+
if (hit)
|
|
1774
|
+
byPath.push({
|
|
1775
|
+
repo: r,
|
|
1776
|
+
serves: [hit.method?.toUpperCase(), hit.pathOrTopic].filter(Boolean).join(" ")
|
|
1777
|
+
});
|
|
1778
|
+
}
|
|
1779
|
+
const evidence = [...new Set(calls.map((c) => c.at))].sort(cmpNatural);
|
|
1780
|
+
const factIds = [...new Set(calls.map((c) => c.id))].sort(cmpText);
|
|
1781
|
+
if (!isTokenHost(host)) {
|
|
1782
|
+
const first = byPath.map((b) => b.repo);
|
|
1783
|
+
const ask = {
|
|
1784
|
+
host,
|
|
1785
|
+
calls: evidence.map((at3) => ({ repo: input.repo, at: at3 })),
|
|
1786
|
+
servers: [...first, ...servers.filter((s) => !first.includes(s))],
|
|
1787
|
+
...byPath.length ? { byPath } : {}
|
|
1788
|
+
};
|
|
1789
|
+
const [d] = hostQuestionDrafts([ask]);
|
|
1790
|
+
if (d)
|
|
1791
|
+
out.push({ step: HOSTS_STEP, host, factIds, draft: d.draft });
|
|
1792
|
+
continue;
|
|
1793
|
+
}
|
|
1794
|
+
const n = factIds.length;
|
|
1795
|
+
const them = n === 1 ? "The call" : `The ${n} calls`;
|
|
1796
|
+
const system = outsideSystemOfJoinHost(host);
|
|
1797
|
+
const rerun = `atticus verify ${input.repo} --write`;
|
|
1798
|
+
const serves2 = new Map(byPath.map((b) => [b.repo, b.serves]));
|
|
1799
|
+
const ranked = [...byPath.map((b) => b.repo), ...servers.filter((s) => !serves2.has(s))];
|
|
1800
|
+
out.push({
|
|
1801
|
+
step: TARGETS_STEP_ID,
|
|
1802
|
+
host,
|
|
1803
|
+
factIds,
|
|
1804
|
+
draft: {
|
|
1805
|
+
// The join's words: for a gateway's token, what to read again (forwardHostQuestion).
|
|
1806
|
+
question: asks[0].question,
|
|
1807
|
+
options: [
|
|
1808
|
+
...ranked.map((r) => ({
|
|
1809
|
+
label: r,
|
|
1810
|
+
means: serves2.has(r) ? `${r} serves ${serves2.get(r)}, a path the calls on ${host} make` : `${r} serves HTTP`,
|
|
1811
|
+
changes: `${them} on ${host} ${n === 1 ? "joins" : "join"} ${r} when the facts are next written (${rerun})`
|
|
1812
|
+
})),
|
|
1813
|
+
...[
|
|
1814
|
+
[HOSTS_OUTSIDE_INTERNAL, "internal", "another team's system"],
|
|
1815
|
+
[HOSTS_OUTSIDE_VENDOR, "vendor", "a vendor's system"]
|
|
1816
|
+
].map(([label2, boundary, what2]) => ({
|
|
1817
|
+
label: label2,
|
|
1818
|
+
means: `${host} stands for ${what2}, outside this estate, that the org pack doesn't name yet`,
|
|
1819
|
+
changes: `A system ${system.id} (${system.name}, boundary ${boundary}) goes into the profile, and ${them.toLowerCase()} on ${host} ${n === 1 ? "goes" : "go"} to it when the facts are next written (${rerun})`
|
|
1820
|
+
})),
|
|
1821
|
+
{
|
|
1822
|
+
label: HOSTS_NONE,
|
|
1823
|
+
means: `Neither a repo of this estate nor a system of the org pack answers on ${host}`,
|
|
1824
|
+
changes: `${them} on ${host} ${n === 1 ? "stays a loose end" : "stay loose ends"}, and this isn't asked again`
|
|
1825
|
+
},
|
|
1826
|
+
ignoreOption()
|
|
1827
|
+
],
|
|
1828
|
+
evidence,
|
|
1829
|
+
scope: "repo"
|
|
1830
|
+
}
|
|
1831
|
+
});
|
|
1832
|
+
}
|
|
1833
|
+
return out;
|
|
1834
|
+
}
|
|
1835
|
+
var isJoinHostQuestion = (q) => q.askedBy?.step === TARGETS_STEP_ID && joinHostOfQuestion(q) !== void 0;
|
|
1836
|
+
function joinHostTarget(q) {
|
|
1837
|
+
if (!isJoinHostQuestion(q) || q.state !== "answered" || !q.answer)
|
|
1838
|
+
return void 0;
|
|
1839
|
+
if (ignoredAnswer(q))
|
|
1840
|
+
return HOSTS_NONE;
|
|
1841
|
+
const label2 = q.answer.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer.text;
|
|
1842
|
+
if (!label2)
|
|
1843
|
+
return void 0;
|
|
1844
|
+
if (outsideBoundaryOf(label2))
|
|
1845
|
+
return outsideSystemOfJoinHost(joinHostOfQuestion(q)).id;
|
|
1846
|
+
return label2;
|
|
1847
|
+
}
|
|
1848
|
+
function hostsIgnoreCovers(q, call) {
|
|
1849
|
+
if (q.askedBy?.step !== HOSTS_STEP || q.state !== "answered" || !ignoredAnswer(q))
|
|
1850
|
+
return false;
|
|
1851
|
+
return q.repo === call.repo && q.evidence.includes(call.at) || !!call.hostLabel && hostOfQuestion(q) === call.hostLabel;
|
|
1852
|
+
}
|
|
1853
|
+
function staleJoinHostQuestions(input) {
|
|
1854
|
+
const drafted = new Set(input.drafted.map((d) => d.id));
|
|
1855
|
+
const out = [];
|
|
1856
|
+
for (const q of input.open) {
|
|
1857
|
+
if (q.state !== "open" || q.repo !== input.repo || !isJoinHostQuestion(q))
|
|
1858
|
+
continue;
|
|
1859
|
+
if (drafted.has(q.id))
|
|
1860
|
+
continue;
|
|
1861
|
+
const host = joinHostOfQuestion(q);
|
|
1862
|
+
const by = input.drafted.filter((d) => d.host === host).map((d) => d.id);
|
|
1863
|
+
if (by.length) {
|
|
1864
|
+
out.push({
|
|
1865
|
+
id: q.id,
|
|
1866
|
+
why: `the calls on ${host} are asked now in ${by.join(", ")}`,
|
|
1867
|
+
replacedBy: by
|
|
1868
|
+
});
|
|
1869
|
+
continue;
|
|
1870
|
+
}
|
|
1871
|
+
const at3 = new Set(q.evidence);
|
|
1872
|
+
const joined = (input.join?.joins ?? []).filter((j) => j.call.repo === input.repo && at3.has(j.call.at));
|
|
1873
|
+
const outside = (input.join?.outside ?? []).filter((o) => o.call.repo === input.repo && at3.has(o.call.at));
|
|
1874
|
+
const how = [
|
|
1875
|
+
.../* @__PURE__ */ new Set([
|
|
1876
|
+
...joined.map((j) => `joins ${j.entry.component} in ${j.entry.repo}`),
|
|
1877
|
+
...outside.map((o) => `goes to ${o.target}, outside the estate`)
|
|
1878
|
+
])
|
|
1879
|
+
].sort(cmpText);
|
|
1880
|
+
out.push({
|
|
1881
|
+
id: q.id,
|
|
1882
|
+
why: how.length ? `the join no longer asks about ${host}: the call ${how.join("; ")}` : `the join no longer asks about ${host}: no call of ${input.repo} goes there now`
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
return out.sort((a, b) => cmpText(a.id, b.id));
|
|
1886
|
+
}
|
|
1887
|
+
async function joinAnswerQuestions(root) {
|
|
1888
|
+
const of = (step) => listQuestions(root, { step }).then((r) => r.questions, () => []);
|
|
1889
|
+
return [...await of(TARGETS_STEP_ID), ...await of(HOSTS_STEP)];
|
|
1486
1890
|
}
|
|
1487
1891
|
|
|
1488
|
-
// packages/scanner/dist/facts-scan.js
|
|
1489
|
-
import { readFile as readFile4 } from "node:fs/promises";
|
|
1490
|
-
import { join as join6 } from "node:path";
|
|
1491
|
-
|
|
1492
|
-
// packages/scanner/dist/facts-catalog.js
|
|
1493
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
1494
|
-
|
|
1495
1892
|
// packages/scanner/dist/target-suggest.js
|
|
1496
1893
|
var TARGETS_MAX_SUGGESTED = 5;
|
|
1497
1894
|
var TARGETS_ANOTHER = TARGETS_ANOTHER_LABEL;
|
|
@@ -1504,18 +1901,18 @@ function nameWords(s) {
|
|
|
1504
1901
|
...new Set(s.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter((w) => w.length >= 3 && !STOP.has(w) && !/^v?\d+$/.test(w)).map((w) => w.length > 4 && w.endsWith("s") && !w.endsWith("ss") ? w.slice(0, -1) : w))
|
|
1505
1902
|
];
|
|
1506
1903
|
}
|
|
1507
|
-
var
|
|
1904
|
+
var segs3 = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$]/.test(x) ? "{}" : x);
|
|
1508
1905
|
var sameSeg = (a, b) => a === "{}" || b === "{}" || a === b;
|
|
1509
1906
|
var under = (path, prefix) => {
|
|
1510
|
-
const a =
|
|
1511
|
-
const b =
|
|
1907
|
+
const a = segs3(prefix);
|
|
1908
|
+
const b = segs3(path);
|
|
1512
1909
|
return a.length > 0 && a.length <= b.length && a.every((x, i) => x === b[i]);
|
|
1513
1910
|
};
|
|
1514
1911
|
function serves(entry, call, bases) {
|
|
1515
|
-
const e =
|
|
1912
|
+
const e = segs3(entry);
|
|
1516
1913
|
const tries = [
|
|
1517
|
-
|
|
1518
|
-
...bases.filter((b) => under(call, b)).map((b) =>
|
|
1914
|
+
segs3(call),
|
|
1915
|
+
...bases.filter((b) => under(call, b)).map((b) => segs3(call).slice(segs3(b).length))
|
|
1519
1916
|
];
|
|
1520
1917
|
return tries.some((c) => c.length === e.length && c.every((x, i) => sameSeg(x, e[i])));
|
|
1521
1918
|
}
|
|
@@ -1539,7 +1936,10 @@ function hostOf(f, facts) {
|
|
|
1539
1936
|
}
|
|
1540
1937
|
return void 0;
|
|
1541
1938
|
}
|
|
1542
|
-
var answerLabel = (q) =>
|
|
1939
|
+
var answerLabel = (q) => (
|
|
1940
|
+
// Beta.24 review: Ignore names no target, so it is never suggested again.
|
|
1941
|
+
ignoredAnswer(q) ? void 0 : q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text
|
|
1942
|
+
);
|
|
1543
1943
|
var NOT_A_TARGET = /* @__PURE__ */ new Set(["None of these", TARGETS_SPLIT_LABEL, TARGETS_ANOTHER_LABEL]);
|
|
1544
1944
|
function candidates(callerRepo, ctx) {
|
|
1545
1945
|
const manifest = estateRepos(ctx.op).filter((r) => r.id !== callerRepo || !!ctx.only);
|
|
@@ -1677,7 +2077,7 @@ function targetSuggestions(f, ctx) {
|
|
|
1677
2077
|
},
|
|
1678
2078
|
{
|
|
1679
2079
|
from: `the path ${f.path}`,
|
|
1680
|
-
words: nameWords(
|
|
2080
|
+
words: nameWords(segs3(f.path).filter((x) => x !== "{}").join(" ")),
|
|
1681
2081
|
weight: 2
|
|
1682
2082
|
}
|
|
1683
2083
|
].filter((x) => x.from && x.words.length);
|
|
@@ -1693,8 +2093,10 @@ function targetSuggestions(f, ctx) {
|
|
|
1693
2093
|
s.score += n;
|
|
1694
2094
|
s.why.push(why);
|
|
1695
2095
|
};
|
|
1696
|
-
if (only?.has(c.s.label))
|
|
1697
|
-
|
|
2096
|
+
if (only?.has(c.s.label)) {
|
|
2097
|
+
const at3 = ctx.onlyAt?.[c.s.label] ?? [];
|
|
2098
|
+
add(6, `the join found an entry of it that serves the call${at3.length ? ` (${at3.join(", ")})` : ""}`);
|
|
2099
|
+
}
|
|
1698
2100
|
const hit = c.entries.find((e) => (!method || !e.method || e.method === method || e.method === "ANY") && serves(e.path, f.path, c.bases.map((b) => b.path)));
|
|
1699
2101
|
if (hit && !only) {
|
|
1700
2102
|
const what2 = [hit.method, hit.path].filter(Boolean).join(" ");
|
|
@@ -1951,14 +2353,17 @@ var anotherOption = (op) => {
|
|
|
1951
2353
|
function offered(members, facts, records, op, asks, ctx) {
|
|
1952
2354
|
const merged = /* @__PURE__ */ new Map();
|
|
1953
2355
|
for (const m of members) {
|
|
1954
|
-
const ambiguous = asks?.
|
|
2356
|
+
const ambiguous = asks?.find((a) => a.reason === "ambiguous" && a.call.repo === m.f.repo && a.call.fact === m.f.id);
|
|
2357
|
+
const onlyAt = {};
|
|
2358
|
+
for (const c of ambiguous?.candidates ?? [])
|
|
2359
|
+
(onlyAt[c.component] ??= []).push(c.at);
|
|
1955
2360
|
for (const s of targetSuggestions(m.f, {
|
|
1956
2361
|
op,
|
|
1957
2362
|
records,
|
|
1958
2363
|
facts,
|
|
1959
2364
|
...ctx.estate ? { estate: ctx.estate } : {},
|
|
1960
2365
|
...ctx.questions ? { questions: ctx.questions } : {},
|
|
1961
|
-
...ambiguous ? { only: m.servers } : {}
|
|
2366
|
+
...ambiguous ? { only: m.servers, onlyAt } : {}
|
|
1962
2367
|
})) {
|
|
1963
2368
|
const x = merged.get(s.label);
|
|
1964
2369
|
if (!x)
|
|
@@ -1994,7 +2399,9 @@ function targetQuestionDrafts(facts, records, op, asks, ctx = {}) {
|
|
|
1994
2399
|
label: TARGETS_NONE,
|
|
1995
2400
|
means: "Nothing in the estate or the org pack's systems answers it",
|
|
1996
2401
|
changes: "The call stays a loose end, and this isn't asked again"
|
|
1997
|
-
}
|
|
2402
|
+
},
|
|
2403
|
+
// Beta.24 review: every join question offers Ignore from the start.
|
|
2404
|
+
ignoreOption()
|
|
1998
2405
|
],
|
|
1999
2406
|
evidence: q.evidence,
|
|
2000
2407
|
scope: "repo"
|
|
@@ -2058,7 +2465,7 @@ function targetGroupWordings(repo, f, facts) {
|
|
|
2058
2465
|
}
|
|
2059
2466
|
var repo0 = (members) => members[0].f.repo;
|
|
2060
2467
|
var byLine = (a, b) => cmpNatural(a, b);
|
|
2061
|
-
var answerLabel2 = (q) => q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text;
|
|
2468
|
+
var answerLabel2 = (q) => ignoredAnswer(q) ? TARGETS_NONE : q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text;
|
|
2062
2469
|
function splitTargetGroups(questions) {
|
|
2063
2470
|
return new Set(questions.filter((q) => q.askedBy?.step === TARGETS_STEP && q.state === "answered" && answerLabel2(q) === TARGETS_SPLIT).map((q) => q.question.trim()));
|
|
2064
2471
|
}
|
|
@@ -2103,7 +2510,8 @@ function groupedTargetDrafts(facts, records, op, asks, o) {
|
|
|
2103
2510
|
label: TARGETS_NONE,
|
|
2104
2511
|
means: "Nothing in the estate or the org pack's systems answers any of them",
|
|
2105
2512
|
changes: "The calls stay loose ends, and this isn't asked again"
|
|
2106
|
-
}
|
|
2513
|
+
},
|
|
2514
|
+
ignoreOption()
|
|
2107
2515
|
],
|
|
2108
2516
|
evidence,
|
|
2109
2517
|
scope: "repo"
|
|
@@ -2184,6 +2592,8 @@ function targetsFromAnswers(repo, facts, questions, o = {}) {
|
|
|
2184
2592
|
for (const q of [...questions].filter((x) => x.askedBy?.step === TARGETS_STEP && x.state === "answered" && !!x.answer && typeof x.question === "string").sort((a, b) => cmpText(a.answer.at, b.answer.at) || cmpText(a.id, b.id)))
|
|
2185
2593
|
groups.set(q.question.trim(), q);
|
|
2186
2594
|
const ruled = ruledTargets(repo, facts, questions, o);
|
|
2595
|
+
const joinHosts = questions.filter((x) => x.repo === repo && isJoinHostQuestion(x) && x.state === "answered").sort((a, b) => cmpText(b.answer.at, a.answer.at) || cmpText(a.id, b.id));
|
|
2596
|
+
const ignoredHosts = questions.filter((x) => x.askedBy?.step === HOSTS_STEP && x.state === "answered" && !!ignoredAnswer(x));
|
|
2187
2597
|
const out = {};
|
|
2188
2598
|
for (const f of [...facts].sort((a, b) => cmpText(a.id, b.id))) {
|
|
2189
2599
|
if (f.kind !== "call")
|
|
@@ -2198,6 +2608,21 @@ function targetsFromAnswers(repo, facts, questions, o = {}) {
|
|
|
2198
2608
|
}
|
|
2199
2609
|
let label2 = asked && asked.state === "answered" && asked.answer ? answerLabel2(asked) : void 0;
|
|
2200
2610
|
let byAi = label2 && asked?.answer && isAiBy(asked.answer.by) ? asked.answer.by : void 0;
|
|
2611
|
+
const at3 = q.evidence[0];
|
|
2612
|
+
if (!label2 || label2 === TARGETS_SPLIT || label2 === TARGETS_ANOTHER) {
|
|
2613
|
+
const jh = joinHosts.find((x) => x.evidence.includes(at3) && !!joinHostTarget(x));
|
|
2614
|
+
if (jh) {
|
|
2615
|
+
label2 = joinHostTarget(jh);
|
|
2616
|
+
byAi = jh.answer && isAiBy(jh.answer.by) ? jh.answer.by : void 0;
|
|
2617
|
+
} else if (ignoredHosts.length) {
|
|
2618
|
+
const url = urlOf(f, facts);
|
|
2619
|
+
const hostLabel = url ? callHostLabel(url) : void 0;
|
|
2620
|
+
if (ignoredHosts.some((x) => hostsIgnoreCovers(x, { repo, at: at3, hostLabel }))) {
|
|
2621
|
+
label2 = TARGETS_NONE;
|
|
2622
|
+
byAi = void 0;
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2201
2626
|
if (!label2 || label2 === TARGETS_SPLIT || label2 === TARGETS_ANOTHER) {
|
|
2202
2627
|
label2 = ruled.get(f.id)?.label;
|
|
2203
2628
|
byAi = void 0;
|
|
@@ -2871,7 +3296,7 @@ async function factsForScan(root, op, repo, commit, readerRecords, at3 = {}) {
|
|
|
2871
3296
|
const left = report.rejected.length;
|
|
2872
3297
|
carriedSaid = `; ${report.carried.length} carried from commit ${from} to ${commit.slice(0, 7)} (the files they cite are unchanged, their lines checked again)${left ? `, ${left} left out until read again (they cite a file changed since, or name a fact that does: /atticus-map ${repo}, then atticus verify ${repo} --write)` : ""}`;
|
|
2873
3298
|
}
|
|
2874
|
-
const questions =
|
|
3299
|
+
const questions = await joinAnswerQuestions(root);
|
|
2875
3300
|
const targets = targetsFromAnswers(repo, facts, questions, {
|
|
2876
3301
|
repoType: estateRepos(op).find((r) => r.id === repo)?.type
|
|
2877
3302
|
});
|
|
@@ -2922,14 +3347,13 @@ async function estateFacts(root, op, except) {
|
|
|
2922
3347
|
const pairs = {};
|
|
2923
3348
|
const notes = [];
|
|
2924
3349
|
const unverified = [];
|
|
2925
|
-
const questions =
|
|
3350
|
+
const questions = await joinAnswerQuestions(root);
|
|
2926
3351
|
for (const r of productionRepos(op)) {
|
|
2927
3352
|
if (r.id === except)
|
|
2928
3353
|
continue;
|
|
2929
|
-
const
|
|
2930
|
-
if (
|
|
3354
|
+
const parsed = await keptParse(join6(factsDirOf(root), `${r.id}.jsonl`), "facts", (t) => t.trim() ? parseFacts(t) : null, { copy: true }).catch(() => void 0);
|
|
3355
|
+
if (!parsed)
|
|
2931
3356
|
continue;
|
|
2932
|
-
const parsed = parseFacts(text2);
|
|
2933
3357
|
if (!parsed.ok) {
|
|
2934
3358
|
notes.push(`${r.id}: its facts don't read, so the estate join leaves them out.`);
|
|
2935
3359
|
continue;
|
|
@@ -4661,7 +5085,7 @@ function parseEntry(s) {
|
|
|
4661
5085
|
const m = /^([A-Za-z]+)\s+(\S+)$/.exec(s.trim());
|
|
4662
5086
|
return m ? { method: m[1].toUpperCase(), path: m[2] } : { path: s.trim() };
|
|
4663
5087
|
}
|
|
4664
|
-
var
|
|
5088
|
+
var segs4 = (p) => normalizePath(p).toLowerCase().split("/").filter(Boolean);
|
|
4665
5089
|
var sameMethod = (a, b) => !a || !b || a.toUpperCase() === b.toUpperCase();
|
|
4666
5090
|
async function joinEstate(o) {
|
|
4667
5091
|
const byId = new Map(o.records.map((r) => [r.id, r]));
|
|
@@ -4673,8 +5097,8 @@ async function joinEstate(o) {
|
|
|
4673
5097
|
const out = [i.normalizedPath];
|
|
4674
5098
|
const route = i.route ? byId.get(i.route) : void 0;
|
|
4675
5099
|
if (route?.kind === "GatewayRoute") {
|
|
4676
|
-
const base2 =
|
|
4677
|
-
const p =
|
|
5100
|
+
const base2 = segs4(route.basepath);
|
|
5101
|
+
const p = segs4(i.normalizedPath);
|
|
4678
5102
|
if (base2.length && base2.every((s, k) => p[k] === s))
|
|
4679
5103
|
out.push(`/${p.slice(base2.length).join("/")}`);
|
|
4680
5104
|
}
|
|
@@ -5036,219 +5460,6 @@ function fieldLineage(f, field) {
|
|
|
5036
5460
|
return out;
|
|
5037
5461
|
}
|
|
5038
5462
|
|
|
5039
|
-
// packages/scanner/dist/hosts-asked.js
|
|
5040
|
-
var segs3 = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$]/.test(x) ? "{}" : x);
|
|
5041
|
-
var underPath = (path, base2) => {
|
|
5042
|
-
const b = segs3(base2);
|
|
5043
|
-
const c = segs3(path);
|
|
5044
|
-
return b.length > 0 && b.length <= c.length && b.every((x, i) => x === c[i]);
|
|
5045
|
-
};
|
|
5046
|
-
var servesPath = (entry, path) => {
|
|
5047
|
-
const e = segs3(entry);
|
|
5048
|
-
const c = segs3(path);
|
|
5049
|
-
return e.length === c.length && e.every((x, i) => x === "{}" || c[i] === "{}" || x === c[i]);
|
|
5050
|
-
};
|
|
5051
|
-
var HTTP_TYPES = /* @__PURE__ */ new Set(["rest", "graphql", "soap", "websocket", "sse", "webhook"]);
|
|
5052
|
-
var CONFIG_FILES = [
|
|
5053
|
-
"**/application*.properties",
|
|
5054
|
-
"**/application*.yml",
|
|
5055
|
-
"**/application*.yaml",
|
|
5056
|
-
"**/bootstrap*.properties",
|
|
5057
|
-
"**/bootstrap*.yml",
|
|
5058
|
-
"**/bootstrap*.yaml",
|
|
5059
|
-
"**/.env",
|
|
5060
|
-
"**/.env.*",
|
|
5061
|
-
"**/Dockerfile",
|
|
5062
|
-
"**/docker-compose*.yml",
|
|
5063
|
-
"**/docker-compose*.yaml",
|
|
5064
|
-
"**/compose*.yml",
|
|
5065
|
-
"**/compose*.yaml",
|
|
5066
|
-
"**/package.json"
|
|
5067
|
-
];
|
|
5068
|
-
function lineSetsPort(line, port) {
|
|
5069
|
-
const p = String(port);
|
|
5070
|
-
const end = "(?![0-9])";
|
|
5071
|
-
return [
|
|
5072
|
-
new RegExp(`port["']?\\s*[:=]\\s*["']?${p}${end}`, "i"),
|
|
5073
|
-
new RegExp(`^\\s*EXPOSE\\s+(?:[0-9]+(?:/[a-z]+)?\\s+)*${p}${end}`, "i"),
|
|
5074
|
-
new RegExp(`--port[=\\s]+${p}${end}`, "i"),
|
|
5075
|
-
new RegExp(`(?:^|[\\s"'-])${p}:[0-9]+`)
|
|
5076
|
-
].some((re) => re.test(line));
|
|
5077
|
-
}
|
|
5078
|
-
function callHost(url) {
|
|
5079
|
-
if (url.includes("${"))
|
|
5080
|
-
return void 0;
|
|
5081
|
-
const hp = urlHostPort(url);
|
|
5082
|
-
if (!hp || !hp.host)
|
|
5083
|
-
return void 0;
|
|
5084
|
-
const explicit = /^[a-z][a-z0-9+.-]*:\/\/(?:[^/@?#]*@)?[^/:?#]+:(\d+)/i.exec(url);
|
|
5085
|
-
return {
|
|
5086
|
-
label: explicit ? `${hp.host}:${explicit[1]}` : hp.host,
|
|
5087
|
-
host: hp.host,
|
|
5088
|
-
...hp.port !== void 0 ? { port: hp.port } : {}
|
|
5089
|
-
};
|
|
5090
|
-
}
|
|
5091
|
-
async function unknownHosts(o) {
|
|
5092
|
-
const patterns = o.repos.flatMap((r) => [
|
|
5093
|
-
...r.hosts,
|
|
5094
|
-
...(r.modules ?? []).flatMap((m) => m.hosts)
|
|
5095
|
-
]);
|
|
5096
|
-
const byHost = /* @__PURE__ */ new Map();
|
|
5097
|
-
for (const r of o.records) {
|
|
5098
|
-
if (r.kind !== "Unresolved" || r.unresolvedKind !== "http-call")
|
|
5099
|
-
continue;
|
|
5100
|
-
const url = r.raw.slice(r.raw.indexOf(" ") + 1);
|
|
5101
|
-
const h = callHost(url);
|
|
5102
|
-
if (!h)
|
|
5103
|
-
continue;
|
|
5104
|
-
if (patterns.some((p) => hostMatches(p, h.host, h.port)))
|
|
5105
|
-
continue;
|
|
5106
|
-
const e = r.evidence[0];
|
|
5107
|
-
const repo = e?.repo ?? r.owner;
|
|
5108
|
-
if (!e?.path || e.line === void 0 || !repo)
|
|
5109
|
-
continue;
|
|
5110
|
-
const entry = byHost.get(h.label) ?? {
|
|
5111
|
-
...h.port !== void 0 ? { port: h.port } : {},
|
|
5112
|
-
explicit: h.label !== h.host,
|
|
5113
|
-
calls: [],
|
|
5114
|
-
paths: /* @__PURE__ */ new Set()
|
|
5115
|
-
};
|
|
5116
|
-
const path = /^[a-z][a-z0-9+.-]*:\/\/[^/?#]*(\/[^?#]*)?/i.exec(url)?.[1];
|
|
5117
|
-
if (path)
|
|
5118
|
-
entry.paths.add(path);
|
|
5119
|
-
const at3 = `${e.path}:${e.line}`;
|
|
5120
|
-
if (!entry.calls.some((c) => c.repo === repo && c.at === at3))
|
|
5121
|
-
entry.calls.push({ repo, at: at3 });
|
|
5122
|
-
byHost.set(h.label, entry);
|
|
5123
|
-
}
|
|
5124
|
-
if (byHost.size === 0)
|
|
5125
|
-
return [];
|
|
5126
|
-
const compRepo = /* @__PURE__ */ new Map();
|
|
5127
|
-
for (const r of o.repos) {
|
|
5128
|
-
compRepo.set(r.component ?? r.id, r.id);
|
|
5129
|
-
for (const m of r.modules ?? [])
|
|
5130
|
-
compRepo.set(m.component, r.id);
|
|
5131
|
-
}
|
|
5132
|
-
const serving = /* @__PURE__ */ new Set();
|
|
5133
|
-
for (const r of o.records)
|
|
5134
|
-
if (r.kind === "Endpoint" && HTTP_TYPES.has(r.endpointType)) {
|
|
5135
|
-
const repo = compRepo.get(r.component);
|
|
5136
|
-
if (repo)
|
|
5137
|
-
serving.add(repo);
|
|
5138
|
-
}
|
|
5139
|
-
const servers = [...serving].sort();
|
|
5140
|
-
const configs = /* @__PURE__ */ new Map();
|
|
5141
|
-
const configOf = async (repo) => {
|
|
5142
|
-
if (configs.has(repo))
|
|
5143
|
-
return configs.get(repo);
|
|
5144
|
-
const h = o.handle(repo);
|
|
5145
|
-
const out = [];
|
|
5146
|
-
if (h)
|
|
5147
|
-
for await (const path of h.listFiles(CONFIG_FILES)) {
|
|
5148
|
-
const t = await h.readText(path).catch(() => void 0);
|
|
5149
|
-
if (t !== void 0)
|
|
5150
|
-
out.push({ path, lines: t.replace(/\r\n?/g, "\n").split("\n") });
|
|
5151
|
-
}
|
|
5152
|
-
configs.set(repo, out);
|
|
5153
|
-
return out;
|
|
5154
|
-
};
|
|
5155
|
-
const asks = [];
|
|
5156
|
-
for (const [host, entry] of [...byHost.entries()].sort(([a], [b]) => cmpText(a, b))) {
|
|
5157
|
-
if (servers.length === 0)
|
|
5158
|
-
continue;
|
|
5159
|
-
const hits = [];
|
|
5160
|
-
if (entry.explicit && entry.port !== void 0)
|
|
5161
|
-
for (const repo of servers) {
|
|
5162
|
-
hit: for (const f of await configOf(repo))
|
|
5163
|
-
for (const [i, l] of f.lines.entries())
|
|
5164
|
-
if (lineSetsPort(l, entry.port)) {
|
|
5165
|
-
hits.push({ repo, at: `${f.path}:${i + 1}`, line: l.trim() });
|
|
5166
|
-
break hit;
|
|
5167
|
-
}
|
|
5168
|
-
}
|
|
5169
|
-
const suggest = hits.length === 1 ? hits[0] : void 0;
|
|
5170
|
-
const calls = entry.calls.sort((a, b) => cmpText(a.repo, b.repo) || cmpNatural(a.at, b.at));
|
|
5171
|
-
const byPath = [];
|
|
5172
|
-
for (const g of o.records) {
|
|
5173
|
-
if (g.kind !== "GatewayRoute")
|
|
5174
|
-
continue;
|
|
5175
|
-
const repo = g.evidence.find((e) => e.repo)?.repo;
|
|
5176
|
-
if (!repo || byPath.some((b) => b.repo === repo))
|
|
5177
|
-
continue;
|
|
5178
|
-
const under2 = [...entry.paths].filter((p) => underPath(p, g.basepath));
|
|
5179
|
-
if (!under2.length)
|
|
5180
|
-
continue;
|
|
5181
|
-
const comps = new Set([...compRepo].filter(([, r]) => r === repo).map(([c]) => c));
|
|
5182
|
-
const hit = o.records.find((r) => r.kind === "Endpoint" && comps.has(r.component) && under2.some((p) => servesPath(r.pathOrTopic, p)));
|
|
5183
|
-
byPath.push({
|
|
5184
|
-
repo,
|
|
5185
|
-
serves: hit ? [hit.method?.toUpperCase(), hit.pathOrTopic].filter(Boolean).join(" ") : `the routes under ${g.basepath}`
|
|
5186
|
-
});
|
|
5187
|
-
}
|
|
5188
|
-
byPath.sort((a, b) => cmpText(a.repo, b.repo));
|
|
5189
|
-
const first = suggest ? [suggest.repo] : byPath.map((b) => b.repo).filter((x) => servers.includes(x));
|
|
5190
|
-
const about = Object.fromEntries(servers.flatMap((s) => {
|
|
5191
|
-
const d = o.repos.find((r) => r.id === s)?.description;
|
|
5192
|
-
return d ? [[s, { text: d.text, trust: d.trust }]] : [];
|
|
5193
|
-
}));
|
|
5194
|
-
asks.push({
|
|
5195
|
-
host,
|
|
5196
|
-
calls,
|
|
5197
|
-
servers: [...first, ...servers.filter((s) => !first.includes(s))],
|
|
5198
|
-
...suggest ? { suggest } : {},
|
|
5199
|
-
...Object.keys(about).length ? { about } : {},
|
|
5200
|
-
...byPath.length ? { byPath } : {}
|
|
5201
|
-
});
|
|
5202
|
-
}
|
|
5203
|
-
return asks;
|
|
5204
|
-
}
|
|
5205
|
-
function aboutOf(a, repo) {
|
|
5206
|
-
const d = a.about?.[repo];
|
|
5207
|
-
if (!d)
|
|
5208
|
-
return "";
|
|
5209
|
-
return d.trust === "suggested" ? `. What it is, as your assistant drafted it (unconfirmed): ${d.text}` : `. What it is: ${d.text}`;
|
|
5210
|
-
}
|
|
5211
|
-
function gatewayHostFix(host, byPath) {
|
|
5212
|
-
const repos = byPath.map((b) => b.repo);
|
|
5213
|
-
return `${repos.length === 1 ? `${repos[0]}'s routes serve` : `The routes of ${repos.join(", ")} serve`} the paths the calls to ${host} make, and no repo lists ${host}: it looks like a shared gateway's host. Once, not per call: list ${host} under hosts: on each proxy repo in repos.manifest.yaml (${repos.join(", ")}, and any other proxy on it); the path then picks the proxy, and this question retires itself`;
|
|
5214
|
-
}
|
|
5215
|
-
function hostQuestionDrafts(asks) {
|
|
5216
|
-
return asks.map((a) => {
|
|
5217
|
-
const repo = a.calls[0].repo;
|
|
5218
|
-
const byPath = new Map((a.byPath ?? []).map((b) => [b.repo, b.serves]));
|
|
5219
|
-
return {
|
|
5220
|
-
repo,
|
|
5221
|
-
...a.byPath?.length ? { byPath: a.byPath } : {},
|
|
5222
|
-
draft: {
|
|
5223
|
-
question: hostQuestionText(a.host),
|
|
5224
|
-
options: [
|
|
5225
|
-
...a.servers.map((s) => ({
|
|
5226
|
-
label: s,
|
|
5227
|
-
means: (a.suggest?.repo === s ? `${s} serves HTTP, and its ${a.suggest.at} sets the port ${a.host.split(":").pop()} (${a.suggest.line})` : byPath.has(s) ? `${s} serves ${byPath.get(s)}, a path the calls to ${a.host} make` : `${s} serves HTTP`) + aboutOf(a, s),
|
|
5228
|
-
changes: byPath.has(s) ? `${a.host} goes under hosts for ${s} in repos.manifest.yaml, and the calls to it join ${s} on the next scan; on a shared gateway host, list it on each proxy repo instead (${[...byPath.keys()].join(", ")}, and any other proxy on it), and the path picks the proxy` : `${a.host} goes under hosts for ${s} in repos.manifest.yaml, and the calls to it join ${s} on the next scan`
|
|
5229
|
-
})),
|
|
5230
|
-
// O1: a system outside the estate, declared in the profile with the host as its alias.
|
|
5231
|
-
...[
|
|
5232
|
-
[HOSTS_OUTSIDE_INTERNAL, "internal", "another team's system"],
|
|
5233
|
-
[HOSTS_OUTSIDE_VENDOR, "vendor", "a vendor's system"]
|
|
5234
|
-
].map(([label2, boundary, what2]) => ({
|
|
5235
|
-
label: label2,
|
|
5236
|
-
means: `${a.host} is ${what2}, outside this estate, that the org pack doesn't name yet`,
|
|
5237
|
-
changes: `A system ${outsideSystemOf(a.host).id} (boundary ${boundary}, alias ${a.host}) goes into the profile, and the calls to ${a.host} go to it on the next scan`
|
|
5238
|
-
})),
|
|
5239
|
-
{
|
|
5240
|
-
label: HOSTS_NONE,
|
|
5241
|
-
means: `Neither a repo of this estate nor a system to add to the org pack answers on ${a.host}`,
|
|
5242
|
-
changes: "Nothing is added to the manifest or the profile; the calls stay loose ends, and this isn't asked again"
|
|
5243
|
-
}
|
|
5244
|
-
],
|
|
5245
|
-
evidence: a.calls.filter((c) => c.repo === repo).slice(0, 3).map((c) => c.at),
|
|
5246
|
-
scope: "repo"
|
|
5247
|
-
}
|
|
5248
|
-
};
|
|
5249
|
-
});
|
|
5250
|
-
}
|
|
5251
|
-
|
|
5252
5463
|
// packages/scanner/dist/measure-links.js
|
|
5253
5464
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
5254
5465
|
var METHODS = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS|TRACE|ANY)\s+(\S.*)$/i;
|
|
@@ -5344,12 +5555,12 @@ function parseLinkReference(source) {
|
|
|
5344
5555
|
return { ok: true, reference: { ...estate ? { estate } : {}, repos } };
|
|
5345
5556
|
}
|
|
5346
5557
|
var stripped = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
|
|
5347
|
-
function
|
|
5558
|
+
function segs5(path) {
|
|
5348
5559
|
return path.split(/[?#]/)[0].split("/").filter(Boolean).map((s) => /^(\{[^}]*\}|:\w+|\*)$/.test(s) ? "{}" : s.toLowerCase());
|
|
5349
5560
|
}
|
|
5350
5561
|
function pathMatch(a, b) {
|
|
5351
|
-
const x =
|
|
5352
|
-
const y =
|
|
5562
|
+
const x = segs5(a);
|
|
5563
|
+
const y = segs5(b);
|
|
5353
5564
|
if (x.length === y.length && x.every((s, i) => s === y[i]))
|
|
5354
5565
|
return 2;
|
|
5355
5566
|
const [short, long] = x.length < y.length ? [x, y] : [y, x];
|
|
@@ -5646,6 +5857,19 @@ export {
|
|
|
5646
5857
|
estateMergeInput,
|
|
5647
5858
|
mergeEstate,
|
|
5648
5859
|
curatedDirOf,
|
|
5860
|
+
lineSetsPort,
|
|
5861
|
+
tokenHost,
|
|
5862
|
+
callHostLabel,
|
|
5863
|
+
unknownHosts,
|
|
5864
|
+
gatewayHostFix,
|
|
5865
|
+
hostQuestionDrafts,
|
|
5866
|
+
isTokenHost,
|
|
5867
|
+
joinHostQuestionDrafts,
|
|
5868
|
+
isJoinHostQuestion,
|
|
5869
|
+
joinHostTarget,
|
|
5870
|
+
hostsIgnoreCovers,
|
|
5871
|
+
staleJoinHostQuestions,
|
|
5872
|
+
joinAnswerQuestions,
|
|
5649
5873
|
TARGETS_MAX_SUGGESTED,
|
|
5650
5874
|
TARGETS_ANOTHER,
|
|
5651
5875
|
TARGETS_NO_EVIDENCE,
|
|
@@ -5728,10 +5952,6 @@ export {
|
|
|
5728
5952
|
estateFlow,
|
|
5729
5953
|
flattenEstateFlow,
|
|
5730
5954
|
fieldLineage,
|
|
5731
|
-
lineSetsPort,
|
|
5732
|
-
unknownHosts,
|
|
5733
|
-
gatewayHostFix,
|
|
5734
|
-
hostQuestionDrafts,
|
|
5735
5955
|
parseLinkReference,
|
|
5736
5956
|
measureLinks,
|
|
5737
5957
|
estateJoinOf,
|