@maycombhq/atticus 2.0.0-beta.2 → 2.0.0-beta.22
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 +8 -4
- package/dist/chunk-23XVSEV5.js +49 -0
- package/dist/{chunk-ZDPAS56H.js → chunk-24OXGB3P.js} +8 -2
- package/dist/{chunk-7EOBHUMC.js → chunk-24XLDU72.js} +4 -3
- package/dist/{chunk-CR3MTH32.js → chunk-2F4CYZKJ.js} +86 -11
- package/dist/{chunk-6IU67AEK.js → chunk-2GF7OLF3.js} +23 -15
- package/dist/chunk-2IIMFOPM.js +41 -0
- package/dist/chunk-2LGRMVCA.js +617 -0
- package/dist/{chunk-XPCM366L.js → chunk-2MMCFP5C.js} +10 -8
- package/dist/{chunk-JBTK5OP2.js → chunk-2Q56PQPS.js} +6 -4
- package/dist/{chunk-Z6LF7HQN.js → chunk-2Q5EDGEO.js} +7 -5
- package/dist/{chunk-3USYZGRF.js → chunk-2RLKFUUL.js} +38 -27
- package/dist/chunk-2SKB4O2E.js +59 -0
- package/dist/{chunk-SP2I63OO.js → chunk-34S2WGOB.js} +87 -4
- package/dist/{chunk-GQ4N4WKF.js → chunk-3NFFJL5D.js} +33 -27
- package/dist/{chunk-SJRGMG6A.js → chunk-3NWDLGG6.js} +28 -25
- package/dist/{chunk-4WBVUHXN.js → chunk-3RM4UK6W.js} +20 -18
- package/dist/chunk-42SIDKEU.js +583 -0
- package/dist/{chunk-GLUX4EEP.js → chunk-4EURQWQD.js} +20 -15
- package/dist/chunk-4U276ICE.js +39 -0
- package/dist/{chunk-ZMFPW66A.js → chunk-53T4O55J.js} +4 -3
- package/dist/{chunk-6J5OKA4Y.js → chunk-57TDNMI3.js} +17 -15
- package/dist/chunk-5BD2KYLE.js +57 -0
- package/dist/{chunk-7EFILTCI.js → chunk-5F7GFN2F.js} +28 -0
- package/dist/chunk-5NMKONLP.js +95 -0
- package/dist/{chunk-7ZUIMTOU.js → chunk-5SJZW52K.js} +26 -24
- package/dist/{chunk-4RS5KZQD.js → chunk-63YRMR6J.js} +6 -5
- package/dist/chunk-66PPNOON.js +62 -0
- package/dist/chunk-6H3Z5JHH.js +64 -0
- package/dist/{chunk-CEXSU4S6.js → chunk-6MUGR4LS.js} +775 -89
- package/dist/{chunk-QSXK2RGH.js → chunk-6OJQOPUN.js} +5 -3
- package/dist/{chunk-MVZVGYXH.js → chunk-6PPOWY5E.js} +84 -14
- package/dist/{chunk-7EKXJZ2Y.js → chunk-6ZGLAACW.js} +299 -38
- package/dist/chunk-6ZJ5A7AF.js +222 -0
- package/dist/{chunk-L24C55VN.js → chunk-745DAZ4L.js} +142 -30
- package/dist/{chunk-Q4D5X7QB.js → chunk-7ASNL4Q4.js} +46 -24
- package/dist/chunk-7BR7IPOH.js +35 -0
- package/dist/{chunk-7WD63HU2.js → chunk-7DOR27HL.js} +6 -6
- package/dist/chunk-7FTTA3HD.js +341 -0
- package/dist/{chunk-OLQJTJJU.js → chunk-7GJS6DNX.js} +12 -3
- package/dist/{chunk-7JUKDRSZ.js → chunk-7IGKHZ4Z.js} +347 -226
- package/dist/{chunk-G2B4ZQGH.js → chunk-7IOWA5D5.js} +11 -6
- package/dist/{chunk-EBEW3XXQ.js → chunk-7JITZFJC.js} +7 -5
- package/dist/chunk-7MJSQTL5.js +174 -0
- package/dist/{chunk-I4JRCD6M.js → chunk-7UOMVMFG.js} +25 -17
- package/dist/{chunk-YY6ZQQBP.js → chunk-AFWUDXEM.js} +19 -7
- package/dist/chunk-AFZ3QA6W.js +47 -0
- package/dist/chunk-AJQ72EBM.js +420 -0
- package/dist/chunk-AJYXNTNZ.js +317 -0
- package/dist/chunk-AVTBS4OW.js +49 -0
- package/dist/{chunk-FHH4I4ZV.js → chunk-BDKC6H5P.js} +12 -6
- package/dist/{chunk-IPKHE5D6.js → chunk-BEVTIBRH.js} +1526 -875
- package/dist/chunk-BHT7QK4G.js +162 -0
- package/dist/{chunk-6JUBZBMW.js → chunk-BIGDQDHD.js} +6 -4
- package/dist/{chunk-2BFCZ3RK.js → chunk-BO4KX37X.js} +20 -18
- package/dist/chunk-BPK5P77O.js +115 -0
- package/dist/chunk-BQ4SQQC6.js +59 -0
- package/dist/chunk-BQGDB6ZL.js +7342 -0
- package/dist/{chunk-2ANOROX3.js → chunk-BTGPE6CR.js} +11 -9
- package/dist/chunk-BTY3HZBO.js +93 -0
- package/dist/{chunk-DPZHZQKE.js → chunk-BXYMYEJ4.js} +44 -10
- package/dist/{chunk-2RMYG36Q.js → chunk-C3RY6KU6.js} +309 -346
- package/dist/chunk-C4R4JLHE.js +40 -0
- package/dist/chunk-CADWLE2T.js +18 -0
- package/dist/chunk-CBGGOQWU.js +82 -0
- package/dist/chunk-CMDXGQTS.js +47 -0
- package/dist/{chunk-MC3H7736.js → chunk-CQDGOPGH.js} +58 -18
- package/dist/{chunk-HFQCFSJR.js → chunk-CX4RZ2KS.js} +4 -3
- package/dist/{chunk-PAMPPUR6.js → chunk-CXJ6FUKN.js} +1852 -207
- package/dist/{chunk-ABWHYWNI.js → chunk-D73UEXYW.js} +3 -3
- package/dist/chunk-DCZWQLYT.js +1205 -0
- package/dist/chunk-DLOBCJL6.js +48 -0
- package/dist/{chunk-4BN53TG3.js → chunk-DOBQKHIF.js} +31 -23
- package/dist/chunk-E3ISYXO3.js +423 -0
- package/dist/{chunk-7SW2QWLU.js → chunk-E6ZIEVOI.js} +16 -13
- package/dist/chunk-EBL2R3YG.js +43 -0
- package/dist/{chunk-AIOQPLA5.js → chunk-EGQRREQH.js} +41 -15
- package/dist/chunk-EHA7RMZ3.js +58 -0
- package/dist/{chunk-M766ZJ6W.js → chunk-EIPTLPFC.js} +38 -27
- package/dist/chunk-EMRIQUND.js +517 -0
- package/dist/{chunk-DFBCSHVT.js → chunk-EPCJQQWD.js} +6 -4
- package/dist/{chunk-RZPYKDWS.js → chunk-F3P7N7SF.js} +1 -1
- package/dist/{chunk-R77KLRB3.js → chunk-FFLNS6VP.js} +21 -18
- package/dist/chunk-FFTRTL6R.js +26 -0
- package/dist/{chunk-IHMLFRVV.js → chunk-FPJPLKDW.js} +62 -16
- package/dist/{chunk-JCZIKA4C.js → chunk-FSMSFDLD.js} +5 -4
- package/dist/{chunk-AVJDSJ2F.js → chunk-FUJM6RTF.js} +8 -7
- package/dist/chunk-FZOJFH7Q.js +132 -0
- package/dist/{chunk-QRAOANID.js → chunk-G6X77UJZ.js} +23 -21
- package/dist/{chunk-3ALD2W2A.js → chunk-GCWRWSU7.js} +10 -4
- package/dist/chunk-GIW4ZVDB.js +39 -0
- package/dist/{chunk-B2WLAWNJ.js → chunk-GUX3PTYM.js} +3 -3
- package/dist/{chunk-DPUYDDQG.js → chunk-GZY6RUZ6.js} +25 -3
- package/dist/chunk-H4VO6WG3.js +10 -0
- package/dist/{chunk-MMOSZPWJ.js → chunk-H5HBGNXU.js} +5 -4
- package/dist/chunk-H7KM7LZE.js +229 -0
- package/dist/{chunk-AA6YULYB.js → chunk-HNM2YQT2.js} +7 -7
- package/dist/{chunk-3C7EYRFZ.js → chunk-HYU5VLGA.js} +1 -1
- package/dist/{chunk-XY3P7JW7.js → chunk-IDKCWSM5.js} +1032 -172
- package/dist/chunk-IFKEI4SA.js +237 -0
- package/dist/{chunk-F7HYOUFF.js → chunk-IGOE6KPG.js} +67 -22
- package/dist/{chunk-TDD55CJH.js → chunk-IH2XURVQ.js} +6 -5
- package/dist/chunk-INQHESFB.js +38 -0
- package/dist/chunk-IP74LCOQ.js +57 -0
- package/dist/chunk-IPHHDDC6.js +45 -0
- package/dist/{chunk-T6AIP7H5.js → chunk-ISUAAMGS.js} +110 -153
- package/dist/{chunk-A7UPUQFY.js → chunk-IUPG3UKI.js} +624 -319
- package/dist/{chunk-L6SGQIR3.js → chunk-IVBOQAGB.js} +7 -3
- package/dist/{chunk-27NKUS3X.js → chunk-J2JAKCIW.js} +2205 -796
- package/dist/{chunk-V2YTAIQO.js → chunk-J3IOLXWM.js} +24 -7
- package/dist/chunk-JA5FI3QV.js +142 -0
- package/dist/chunk-JAVI7JSP.js +49 -0
- package/dist/{chunk-HLJAXMM4.js → chunk-JB5LINEM.js} +6 -2
- package/dist/{chunk-2VHF7OXM.js → chunk-JENSEMXF.js} +1 -1
- package/dist/{chunk-6BVONWJ7.js → chunk-JJF6HALY.js} +4 -3
- package/dist/chunk-JLUCKAEL.js +38 -0
- package/dist/chunk-JRBFANFE.js +221 -0
- package/dist/{chunk-R6XF6UR3.js → chunk-KDNTAPLX.js} +4 -4
- package/dist/chunk-KFAVQZSX.js +33 -0
- package/dist/chunk-KJXD4PNL.js +50 -0
- package/dist/chunk-KN5BXMWN.js +44 -0
- package/dist/{chunk-PCVDV3UZ.js → chunk-KQGURXFU.js} +9 -7
- package/dist/{chunk-WY6PP6AA.js → chunk-KXITGYLF.js} +40 -6
- package/dist/{chunk-66YVAGGM.js → chunk-L27SV425.js} +22 -20
- package/dist/{chunk-NE2W3OO7.js → chunk-LDLL7LB3.js} +24 -22
- package/dist/chunk-LFGTYX5U.js +379 -0
- package/dist/{chunk-EYWIDJFU.js → chunk-LGBMTVNT.js} +7 -5
- package/dist/{chunk-Q5AMFEWD.js → chunk-LGFL54FP.js} +3 -2
- package/dist/{chunk-6TACQN3N.js → chunk-LJXMYKZJ.js} +7 -5
- package/dist/{chunk-BKVWTZ6A.js → chunk-LKOR5UET.js} +29 -26
- package/dist/chunk-LNBQOP7D.js +294 -0
- package/dist/{chunk-O3WI5KWW.js → chunk-LO6P2VYG.js} +2 -2
- package/dist/chunk-LQJPN536.js +122 -0
- package/dist/{chunk-YEDDOYSC.js → chunk-LYBNHMVZ.js} +29 -5
- package/dist/{chunk-A3GY6SOA.js → chunk-LZ7NUC62.js} +20 -18
- package/dist/chunk-M32BLWDH.js +37 -0
- package/dist/{chunk-VYDBJ73M.js → chunk-M3NANSDZ.js} +17 -15
- package/dist/chunk-MFHL5URL.js +31 -0
- package/dist/chunk-MFR5OPBD.js +109 -0
- package/dist/{chunk-DE76JROX.js → chunk-MG4ZL5RW.js} +32 -20
- package/dist/{chunk-N7IXEHK3.js → chunk-MO6P2JZH.js} +10 -8
- package/dist/{chunk-65NYPGRC.js → chunk-MUWDB4R4.js} +1 -1
- package/dist/chunk-MZCGSXVR.js +34 -0
- package/dist/{chunk-MGYZM27B.js → chunk-N3XIYPU3.js} +51 -23
- package/dist/chunk-NDCF4R6S.js +172 -0
- package/dist/{chunk-DHPACDG7.js → chunk-NR2UJWOC.js} +10 -8
- package/dist/chunk-NXJ5URP6.js +51 -0
- package/dist/{chunk-UNM6ZOKP.js → chunk-NY2XSR5K.js} +147 -18
- package/dist/{chunk-5GDRCDQB.js → chunk-O45HFTFS.js} +3 -2
- package/dist/{chunk-ONLS5QA5.js → chunk-O4GXGGBX.js} +14 -12
- package/dist/chunk-O5PXQR67.js +249 -0
- package/dist/{chunk-PRPPGYZG.js → chunk-O66DM6DJ.js} +6 -4
- package/dist/{chunk-KEM4SDDP.js → chunk-O7FDLW7L.js} +11 -8
- package/dist/{chunk-T2UYZSCQ.js → chunk-O7XLYEFA.js} +169 -29
- package/dist/{chunk-FITWGOJ2.js → chunk-OHNCWBKF.js} +4 -4
- package/dist/{chunk-652QWTLZ.js → chunk-OHVTTOPS.js} +3 -3
- package/dist/chunk-OMI6FPPN.js +43 -0
- package/dist/chunk-ONUPY3H6.js +53 -0
- package/dist/chunk-OTLDSZDV.js +69 -0
- package/dist/chunk-OUBGGKDU.js +22 -0
- package/dist/chunk-OWNCM4ZN.js +330 -0
- package/dist/{chunk-YISXLPHN.js → chunk-P2V7QW4D.js} +235 -35
- package/dist/{chunk-CNUKCS2T.js → chunk-P32RUW3B.js} +1632 -93
- package/dist/{chunk-BWZ77RQT.js → chunk-PAQ2AS5E.js} +1 -1
- package/dist/{chunk-ZMAINWBW.js → chunk-PBPBMP2B.js} +4 -3
- package/dist/{chunk-ZVM6AKKM.js → chunk-PJSJPMJI.js} +3 -3
- package/dist/{chunk-EFHQ3TWP.js → chunk-PKBHS4AA.js} +233 -56
- package/dist/{chunk-GT4I4ZWM.js → chunk-PMUAJGLI.js} +20 -16
- package/dist/chunk-PPD7HTDP.js +152 -0
- package/dist/chunk-PSOFBQWB.js +42 -0
- package/dist/{chunk-S2A7YC3Q.js → chunk-Q2TECDIT.js} +10694 -8896
- package/dist/chunk-Q4K5WB2W.js +42 -0
- package/dist/{chunk-UGLN7QHV.js → chunk-Q6DFNVRJ.js} +14 -12
- package/dist/chunk-QA4O2GGC.js +265 -0
- package/dist/chunk-QAXW2N3B.js +1216 -0
- package/dist/chunk-QBNWF5ZU.js +19 -0
- package/dist/chunk-QFWA2DPH.js +224 -0
- package/dist/{chunk-23W7VWKR.js → chunk-QKUJMING.js} +1363 -114
- package/dist/{chunk-NXFPS2LR.js → chunk-R44CYFPV.js} +16 -13
- package/dist/{chunk-CKSITVS4.js → chunk-R7NYHMUU.js} +2687 -786
- package/dist/chunk-REWWDVQB.js +162 -0
- package/dist/{chunk-JMSCMUCA.js → chunk-RGERPOIV.js} +145 -21
- package/dist/{chunk-6JCPI55B.js → chunk-RLDGWLQ7.js} +49 -7
- package/dist/chunk-RUGXBPWI.js +384 -0
- package/dist/{chunk-CPA6HPVR.js → chunk-RXPJMEOW.js} +18 -12
- package/dist/{chunk-3HI6Z55Y.js → chunk-S4PMJU6H.js} +339 -43
- package/dist/chunk-S5LSDXV4.js +40 -0
- package/dist/chunk-S7FCV7S5.js +51 -0
- package/dist/{chunk-5GGOLAKC.js → chunk-SDKLKB6I.js} +28 -26
- package/dist/chunk-SFSPGFCV.js +62 -0
- package/dist/{chunk-ZNCEKR4J.js → chunk-SFUP7TTO.js} +12 -8
- package/dist/{chunk-64EQYWCA.js → chunk-SLXZOMA6.js} +69 -19
- package/dist/chunk-SQV37XO2.js +273 -0
- package/dist/{chunk-K65BJIMT.js → chunk-SU74NDMQ.js} +19 -17
- package/dist/chunk-SYV5LHML.js +165 -0
- package/dist/chunk-T4YPZIQN.js +36 -0
- package/dist/chunk-T6DQR5TV.js +323 -0
- package/dist/{chunk-JIITQXFB.js → chunk-THDMSZ3R.js} +3075 -802
- package/dist/{chunk-JGZCG5VM.js → chunk-TNR75OXT.js} +7 -7
- package/dist/{chunk-D3PO4DOZ.js → chunk-TUULXQRW.js} +174 -15
- package/dist/chunk-TYQBFTBR.js +516 -0
- package/dist/chunk-U76OWS3Q.js +49 -0
- package/dist/{chunk-YYQN46FY.js → chunk-UCROWG2D.js} +27 -24
- package/dist/{chunk-6M5NK3K3.js → chunk-UF4AZOZB.js} +50 -10
- package/dist/chunk-UF4GLFBX.js +345 -0
- package/dist/{chunk-OT2O76OS.js → chunk-UGUP3ZM6.js} +240 -39
- package/dist/chunk-UNAGJYET.js +45 -0
- package/dist/{chunk-5WG5YP4T.js → chunk-UOR2DTHH.js} +16 -14
- package/dist/{chunk-S3QNRWYR.js → chunk-UPOY4YSQ.js} +14 -12
- package/dist/{chunk-EPTBZ3GP.js → chunk-UPS2DGFC.js} +1 -1
- package/dist/{chunk-4AK7IBVP.js → chunk-UUU4CLJG.js} +4 -2
- package/dist/{chunk-W3BQAZ3Q.js → chunk-UWMJKX5U.js} +14 -12
- package/dist/{chunk-QZSX3F7C.js → chunk-UWOJLHFT.js} +27 -23
- package/dist/chunk-VBTP56CE.js +535 -0
- package/dist/chunk-VCTWPLAO.js +211 -0
- package/dist/chunk-VNU26RCO.js +1215 -0
- package/dist/{chunk-CSZ4C5N6.js → chunk-VTZMAJ3W.js} +93 -10
- package/dist/{chunk-TXLH6WHQ.js → chunk-VW62D6QE.js} +14 -12
- package/dist/{chunk-CAQZUNOH.js → chunk-VY72R2XZ.js} +610 -3
- package/dist/{chunk-2DIQQJCB.js → chunk-VZALIKIF.js} +18 -15
- package/dist/{chunk-TYAID7B7.js → chunk-W62H2XSO.js} +25 -23
- package/dist/{chunk-HVUPKCGJ.js → chunk-W7VWI2YH.js} +9 -6
- package/dist/{chunk-TANFV3MZ.js → chunk-WERM6KPJ.js} +7 -4
- package/dist/{chunk-BOHJZTEQ.js → chunk-WF7B67YE.js} +208 -87
- package/dist/{chunk-7FBGJFEE.js → chunk-WG5U3F5V.js} +14 -12
- package/dist/{chunk-4NDAAFQT.js → chunk-WJF2CS6M.js} +8 -5
- package/dist/{chunk-XAKWMCXI.js → chunk-WKUJ3KPV.js} +4 -4
- package/dist/chunk-WMTRHUI5.js +103 -0
- package/dist/chunk-WNKPRSGI.js +36 -0
- package/dist/chunk-WXFLMQSR.js +223 -0
- package/dist/{chunk-RRTKKSLQ.js → chunk-X3WY6MN3.js} +8 -6
- package/dist/{chunk-ZCJDOK2S.js → chunk-X4CXA2IL.js} +47 -23
- package/dist/{chunk-UBBC2XSG.js → chunk-X5F3Q5LV.js} +560 -105
- package/dist/{chunk-C6EKFH7J.js → chunk-XD75VZIH.js} +9 -7
- package/dist/chunk-XERYFDB5.js +297 -0
- package/dist/chunk-XI2LCCYQ.js +420 -0
- package/dist/chunk-Y2EQNWKV.js +933 -0
- package/dist/{chunk-LR3R6Z2A.js → chunk-YHCMZC2J.js} +7 -7
- package/dist/chunk-YYY3AZFE.js +122 -0
- package/dist/{chunk-GDLULHTC.js → chunk-Z5IA3WDR.js} +19 -31
- package/dist/{chunk-T6XQL73F.js → chunk-ZFFYNRIO.js} +63 -23
- package/dist/{chunk-EDS2L2LD.js → chunk-ZFL7NY4F.js} +56 -27
- package/dist/{chunk-YMZ3TNYB.js → chunk-ZGULQAPZ.js} +7 -4
- package/dist/{chunk-4SKZDI62.js → chunk-ZIUFM5HT.js} +3 -1
- package/dist/{chunk-DKJA76CJ.js → chunk-ZJFRMSJT.js} +15 -13
- package/dist/chunk-ZJXLNDH4.js +239 -0
- package/dist/chunk-ZQ3ON2VQ.js +252 -0
- package/dist/{chunk-HITVBIJS.js → chunk-ZQ7SKESZ.js} +150 -415
- package/dist/{chunk-6QSERWXH.js → chunk-ZQXZ2SES.js} +24 -21
- package/dist/chunk-ZX57KSEQ.js +39 -0
- package/dist/{chunk-I3E7CX4H.js → chunk-ZZK56BLP.js} +5 -3
- package/dist/files.json +664 -368
- package/dist/packages/naysayer/constitution/constitution.yaml +19 -0
- package/dist/packages/sdk/npm/index.js +6194 -2542
- package/dist/packages/ui/dist/assets/{elk-api-tma0MCuh.js → elk-api-CIf-0gz5.js} +2 -2
- package/dist/packages/ui/dist/assets/index-CoK_Dl0D.js +47 -0
- package/dist/packages/ui/dist/assets/index-Dw20IRhQ.css +1 -0
- package/dist/packages/ui/dist/index.html +3 -2
- package/package.json +5 -5
- package/dist/chunk-2BF2EYJV.js +0 -174
- package/dist/chunk-42EVSKME.js +0 -37
- package/dist/chunk-4BKGMUIK.js +0 -53
- package/dist/chunk-5KLGBXG5.js +0 -48
- package/dist/chunk-6BNC6EQ4.js +0 -41
- package/dist/chunk-6D2CQ5II.js +0 -41
- package/dist/chunk-7AVHLZGD.js +0 -45
- package/dist/chunk-D46WUV3T.js +0 -33
- package/dist/chunk-E36QOJMD.js +0 -47
- package/dist/chunk-FQXYPF7E.js +0 -147
- package/dist/chunk-GBRFVT63.js +0 -45
- package/dist/chunk-ICY36XCH.js +0 -34
- package/dist/chunk-J4K3KVLD.js +0 -131
- package/dist/chunk-JZU3H6UQ.js +0 -54
- package/dist/chunk-NN2ZQEB4.js +0 -38
- package/dist/chunk-PCOCACY3.js +0 -385
- package/dist/chunk-RTEYOSJY.js +0 -29
- package/dist/chunk-RUVFXE2L.js +0 -666
- package/dist/chunk-RVH5SUW5.js +0 -69
- package/dist/chunk-VN3DP4LQ.js +0 -43
- package/dist/chunk-W5BVQF44.js +0 -36
- package/dist/chunk-WVPJSRRJ.js +0 -52
- package/dist/chunk-XPTOBS2D.js +0 -48
- package/dist/packages/ui/dist/assets/index-B54fm9FQ.js +0 -29
- package/dist/packages/ui/dist/assets/index-DD_hufQz.css +0 -1
|
@@ -4,30 +4,27 @@ 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
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
QueryError,
|
|
8
|
+
askLookup,
|
|
9
|
+
graph,
|
|
10
|
+
impact,
|
|
11
|
+
openIndex,
|
|
12
|
+
translate
|
|
13
|
+
} from "./chunk-ISUAAMGS.js";
|
|
9
14
|
import {
|
|
10
15
|
readRound,
|
|
11
16
|
reviewedGates,
|
|
12
17
|
roundsOf
|
|
13
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-S4PMJU6H.js";
|
|
14
19
|
import {
|
|
15
20
|
changeFolder,
|
|
16
21
|
changeStore
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import {
|
|
19
|
-
QueryError,
|
|
20
|
-
askLookup,
|
|
21
|
-
graph,
|
|
22
|
-
impact,
|
|
23
|
-
openIndex,
|
|
24
|
-
translate
|
|
25
|
-
} from "./chunk-T6AIP7H5.js";
|
|
22
|
+
} from "./chunk-IDKCWSM5.js";
|
|
26
23
|
import {
|
|
27
24
|
baseClonePath,
|
|
28
25
|
gitUser,
|
|
29
26
|
loadRepos
|
|
30
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-PKBHS4AA.js";
|
|
31
28
|
import {
|
|
32
29
|
API_VERSION,
|
|
33
30
|
DEFAULT_PORT,
|
|
@@ -35,8 +32,8 @@ import {
|
|
|
35
32
|
RECORD_KINDS,
|
|
36
33
|
RecordId,
|
|
37
34
|
Severity,
|
|
35
|
+
api_exports,
|
|
38
36
|
catalogDirOf,
|
|
39
|
-
changesDirOf,
|
|
40
37
|
factsDirOf,
|
|
41
38
|
fastPathOf,
|
|
42
39
|
inputsDirOf,
|
|
@@ -48,23 +45,14 @@ import {
|
|
|
48
45
|
proposalsDirOf,
|
|
49
46
|
questionOfLens,
|
|
50
47
|
questionsDirOf,
|
|
51
|
-
readRepoSpec,
|
|
52
|
-
require_dist,
|
|
53
48
|
runsDirOf,
|
|
54
|
-
specRepos,
|
|
55
49
|
specsDirOf,
|
|
56
50
|
withSignal
|
|
57
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-Q2TECDIT.js";
|
|
58
52
|
import {
|
|
53
|
+
FileChangedError,
|
|
59
54
|
SCHEMA_VERSION
|
|
60
|
-
} from "./chunk-
|
|
61
|
-
import {
|
|
62
|
-
__toESM
|
|
63
|
-
} from "./chunk-TV45EUGM.js";
|
|
64
|
-
|
|
65
|
-
// packages/cli/dist/ui-api-cites.js
|
|
66
|
-
import { readdir, readFile as readFile3, stat as stat3 } from "node:fs/promises";
|
|
67
|
-
import { isAbsolute, join as join4, relative as relative2, sep as sep3 } from "node:path";
|
|
55
|
+
} from "./chunk-TUULXQRW.js";
|
|
68
56
|
|
|
69
57
|
// packages/server/dist/http.js
|
|
70
58
|
var HttpError = class extends Error {
|
|
@@ -148,6 +136,115 @@ function intParam(q, name, min, max) {
|
|
|
148
136
|
}
|
|
149
137
|
var strParam = (q, name) => q.get(name) || void 0;
|
|
150
138
|
|
|
139
|
+
// packages/server/dist/server.js
|
|
140
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
141
|
+
import { createServer } from "node:http";
|
|
142
|
+
|
|
143
|
+
// packages/server/dist/jobs.js
|
|
144
|
+
var JobManager = class {
|
|
145
|
+
publish;
|
|
146
|
+
now;
|
|
147
|
+
jobs = /* @__PURE__ */ new Map();
|
|
148
|
+
cancelledIds = /* @__PURE__ */ new Set();
|
|
149
|
+
aborts = /* @__PURE__ */ new Map();
|
|
150
|
+
seq = 0;
|
|
151
|
+
/** Round 41: every running job of a kind, in start order (a later one never hides an earlier). */
|
|
152
|
+
running = /* @__PURE__ */ new Map();
|
|
153
|
+
constructor(publish, now = () => /* @__PURE__ */ new Date()) {
|
|
154
|
+
this.publish = publish;
|
|
155
|
+
this.now = now;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* A running job of a kind, if any: the earliest still running (one scan at a time: a second
|
|
159
|
+
* ask gets 409).
|
|
160
|
+
*/
|
|
161
|
+
runningOf(kind) {
|
|
162
|
+
for (const id of this.running.get(kind) ?? []) {
|
|
163
|
+
const j = this.jobs.get(id);
|
|
164
|
+
if (j?.state === "running")
|
|
165
|
+
return j;
|
|
166
|
+
}
|
|
167
|
+
return void 0;
|
|
168
|
+
}
|
|
169
|
+
get(id) {
|
|
170
|
+
return this.jobs.get(id);
|
|
171
|
+
}
|
|
172
|
+
start(kind, work) {
|
|
173
|
+
const id = `job-${++this.seq}`;
|
|
174
|
+
const job = {
|
|
175
|
+
id,
|
|
176
|
+
kind,
|
|
177
|
+
state: "running",
|
|
178
|
+
progress: { done: 0, total: 0, message: "Starting" },
|
|
179
|
+
startedAt: this.now().toISOString(),
|
|
180
|
+
errors: []
|
|
181
|
+
};
|
|
182
|
+
this.jobs.set(id, job);
|
|
183
|
+
const ofKind = this.running.get(kind) ?? /* @__PURE__ */ new Set();
|
|
184
|
+
ofKind.add(id);
|
|
185
|
+
this.running.set(kind, ofKind);
|
|
186
|
+
const abort = new AbortController();
|
|
187
|
+
this.aborts.set(id, abort);
|
|
188
|
+
const cancelled = this.cancelledIds;
|
|
189
|
+
const control = {
|
|
190
|
+
progress: (done, total, message) => {
|
|
191
|
+
job.progress = { done, total, message };
|
|
192
|
+
this.publish({ type: "job.progress", jobId: id, done, total, message });
|
|
193
|
+
},
|
|
194
|
+
get cancelled() {
|
|
195
|
+
return cancelled.has(id);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
void (async () => {
|
|
199
|
+
try {
|
|
200
|
+
const out = await withSignal(abort.signal, () => work(control));
|
|
201
|
+
if (out?.result)
|
|
202
|
+
job.result = out.result;
|
|
203
|
+
if (out?.errors?.length)
|
|
204
|
+
job.errors.push(...out.errors);
|
|
205
|
+
job.state = this.cancelledIds.has(id) ? "cancelled" : job.errors.length ? "failed" : "done";
|
|
206
|
+
} catch (e) {
|
|
207
|
+
if (this.cancelledIds.has(id))
|
|
208
|
+
job.state = "cancelled";
|
|
209
|
+
else {
|
|
210
|
+
job.errors.push(e instanceof Error ? e.message : String(e));
|
|
211
|
+
job.state = "failed";
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
this.aborts.delete(id);
|
|
215
|
+
job.finishedAt = this.now().toISOString();
|
|
216
|
+
ofKind.delete(id);
|
|
217
|
+
if (!ofKind.size && this.running.get(kind) === ofKind)
|
|
218
|
+
this.running.delete(kind);
|
|
219
|
+
this.publish({ type: "job.done", jobId: id, state: job.state });
|
|
220
|
+
})();
|
|
221
|
+
return job;
|
|
222
|
+
}
|
|
223
|
+
/** Ask a running job to stop; false when it already finished. */
|
|
224
|
+
cancel(id) {
|
|
225
|
+
const j = this.jobs.get(id);
|
|
226
|
+
if (!j || j.state !== "running")
|
|
227
|
+
return false;
|
|
228
|
+
this.cancelledIds.add(id);
|
|
229
|
+
this.aborts.get(id)?.abort();
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
/** Wait for a job to finish (tests and the CLI). */
|
|
233
|
+
async settle(id, timeoutMs = 6e4) {
|
|
234
|
+
const start = Date.now();
|
|
235
|
+
for (; ; ) {
|
|
236
|
+
const j = this.jobs.get(id);
|
|
237
|
+
if (!j)
|
|
238
|
+
throw new Error(`No job ${id}`);
|
|
239
|
+
if (j.state !== "running" && j.state !== "queued")
|
|
240
|
+
return j;
|
|
241
|
+
if (Date.now() - start > timeoutMs)
|
|
242
|
+
throw new Error(`Job ${id} did not finish`);
|
|
243
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
151
248
|
// packages/server/dist/routes.js
|
|
152
249
|
import { readFile, stat } from "node:fs/promises";
|
|
153
250
|
import { join } from "node:path";
|
|
@@ -232,6 +329,7 @@ function apiRoutes(r, ctx) {
|
|
|
232
329
|
...strParam(query, "status") ? { status: strParam(query, "status") } : {},
|
|
233
330
|
...strParam(query, "system") ? { system: strParam(query, "system") } : {},
|
|
234
331
|
...strParam(query, "q") ? { q: strParam(query, "q") } : {},
|
|
332
|
+
...strParam(query, "confidence") ? { confidence: strParam(query, "confidence") } : {},
|
|
235
333
|
...strParam(query, "cursor") ? { cursor: strParam(query, "cursor") } : {},
|
|
236
334
|
...limit !== void 0 ? { limit } : {}
|
|
237
335
|
};
|
|
@@ -289,7 +387,20 @@ function apiRoutes(r, ctx) {
|
|
|
289
387
|
return { status: 200, body: await withIndex(root, (ix) => graph(ix, o)) };
|
|
290
388
|
}).add("GET", "/api/impact/{id}", async ({ params, query }) => {
|
|
291
389
|
const depth = intParam(query, "depth", 1, 10);
|
|
292
|
-
const res = await withIndex(root, (ix) =>
|
|
390
|
+
const res = await withIndex(root, (ix) => {
|
|
391
|
+
const r2 = impact(ix, params.id, depth);
|
|
392
|
+
if (!r2)
|
|
393
|
+
return void 0;
|
|
394
|
+
return {
|
|
395
|
+
...r2,
|
|
396
|
+
affected: r2.affected.map((a) => {
|
|
397
|
+
const rec = ix.find(a.id)[0];
|
|
398
|
+
const ai = (rec?.evidence ?? []).find((e) => e.source === "ai");
|
|
399
|
+
const flagged = Array.isArray(rec?.flags) && rec.flags.includes("joined-by-ai");
|
|
400
|
+
return flagged || ai ? { ...a, byAi: true, ...ai?.run ? { run: ai.run } : {} } : a;
|
|
401
|
+
})
|
|
402
|
+
};
|
|
403
|
+
});
|
|
293
404
|
if (!res)
|
|
294
405
|
throw notFound(`There is no record ${params.id} in the catalog.`);
|
|
295
406
|
return { status: 200, body: res };
|
|
@@ -380,6 +491,8 @@ function apiRoutes(r, ctx) {
|
|
|
380
491
|
return { status: 200, body };
|
|
381
492
|
}).add("GET", "/api/findings", async ({ query }) => {
|
|
382
493
|
const change = strParam(query, "change");
|
|
494
|
+
if (change !== void 0 && !RecordId.safeParse(change).success)
|
|
495
|
+
throw badRequest(`${change} isn't a change id.`);
|
|
383
496
|
const gate = strParam(query, "gate");
|
|
384
497
|
const state = strParam(query, "state");
|
|
385
498
|
const lens = enumParam(query, "lens", Lens.options);
|
|
@@ -393,6 +506,8 @@ function apiRoutes(r, ctx) {
|
|
|
393
506
|
body.push(f);
|
|
394
507
|
return { status: 200, body };
|
|
395
508
|
}).add("GET", "/api/findings/{changeId}/{findingId}", async ({ params }) => {
|
|
509
|
+
if (!RecordId.safeParse(params.changeId).success)
|
|
510
|
+
throw badRequest(`${params.changeId} isn't a change id.`);
|
|
396
511
|
const f = (await latestFindings(root, params.changeId)).find((x) => x.id === params.findingId);
|
|
397
512
|
if (!f)
|
|
398
513
|
throw notFound(`Change ${params.changeId} has no finding ${params.findingId}.`);
|
|
@@ -435,107 +550,9 @@ function apiRoutes(r, ctx) {
|
|
|
435
550
|
});
|
|
436
551
|
}
|
|
437
552
|
|
|
438
|
-
// packages/server/dist/server.js
|
|
439
|
-
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
440
|
-
import { createServer } from "node:http";
|
|
441
|
-
|
|
442
|
-
// packages/server/dist/jobs.js
|
|
443
|
-
var JobManager = class {
|
|
444
|
-
publish;
|
|
445
|
-
now;
|
|
446
|
-
jobs = /* @__PURE__ */ new Map();
|
|
447
|
-
cancelledIds = /* @__PURE__ */ new Set();
|
|
448
|
-
aborts = /* @__PURE__ */ new Map();
|
|
449
|
-
seq = 0;
|
|
450
|
-
running = /* @__PURE__ */ new Map();
|
|
451
|
-
constructor(publish, now = () => /* @__PURE__ */ new Date()) {
|
|
452
|
-
this.publish = publish;
|
|
453
|
-
this.now = now;
|
|
454
|
-
}
|
|
455
|
-
/** The running job of a kind, if any (one scan at a time: a second asks gets 409). */
|
|
456
|
-
runningOf(kind) {
|
|
457
|
-
const id = this.running.get(kind);
|
|
458
|
-
return id ? this.jobs.get(id) : void 0;
|
|
459
|
-
}
|
|
460
|
-
get(id) {
|
|
461
|
-
return this.jobs.get(id);
|
|
462
|
-
}
|
|
463
|
-
start(kind, work) {
|
|
464
|
-
const id = `job-${++this.seq}`;
|
|
465
|
-
const job = {
|
|
466
|
-
id,
|
|
467
|
-
kind,
|
|
468
|
-
state: "running",
|
|
469
|
-
progress: { done: 0, total: 0, message: "Starting" },
|
|
470
|
-
startedAt: this.now().toISOString(),
|
|
471
|
-
errors: []
|
|
472
|
-
};
|
|
473
|
-
this.jobs.set(id, job);
|
|
474
|
-
this.running.set(kind, id);
|
|
475
|
-
const abort = new AbortController();
|
|
476
|
-
this.aborts.set(id, abort);
|
|
477
|
-
const cancelled = this.cancelledIds;
|
|
478
|
-
const control = {
|
|
479
|
-
progress: (done, total, message) => {
|
|
480
|
-
job.progress = { done, total, message };
|
|
481
|
-
this.publish({ type: "job.progress", jobId: id, done, total, message });
|
|
482
|
-
},
|
|
483
|
-
get cancelled() {
|
|
484
|
-
return cancelled.has(id);
|
|
485
|
-
}
|
|
486
|
-
};
|
|
487
|
-
void (async () => {
|
|
488
|
-
try {
|
|
489
|
-
const out = await withSignal(abort.signal, () => work(control));
|
|
490
|
-
if (out?.result)
|
|
491
|
-
job.result = out.result;
|
|
492
|
-
if (out?.errors?.length)
|
|
493
|
-
job.errors.push(...out.errors);
|
|
494
|
-
job.state = this.cancelledIds.has(id) ? "cancelled" : job.errors.length ? "failed" : "done";
|
|
495
|
-
} catch (e) {
|
|
496
|
-
if (this.cancelledIds.has(id))
|
|
497
|
-
job.state = "cancelled";
|
|
498
|
-
else {
|
|
499
|
-
job.errors.push(e instanceof Error ? e.message : String(e));
|
|
500
|
-
job.state = "failed";
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
this.aborts.delete(id);
|
|
504
|
-
job.finishedAt = this.now().toISOString();
|
|
505
|
-
if (this.running.get(kind) === id)
|
|
506
|
-
this.running.delete(kind);
|
|
507
|
-
this.publish({ type: "job.done", jobId: id, state: job.state });
|
|
508
|
-
})();
|
|
509
|
-
return job;
|
|
510
|
-
}
|
|
511
|
-
/** Ask a running job to stop; false when it already finished. */
|
|
512
|
-
cancel(id) {
|
|
513
|
-
const j = this.jobs.get(id);
|
|
514
|
-
if (!j || j.state !== "running")
|
|
515
|
-
return false;
|
|
516
|
-
this.cancelledIds.add(id);
|
|
517
|
-
this.aborts.get(id)?.abort();
|
|
518
|
-
return true;
|
|
519
|
-
}
|
|
520
|
-
/** Wait for a job to finish (tests and the CLI). */
|
|
521
|
-
async settle(id, timeoutMs = 6e4) {
|
|
522
|
-
const start = Date.now();
|
|
523
|
-
for (; ; ) {
|
|
524
|
-
const j = this.jobs.get(id);
|
|
525
|
-
if (!j)
|
|
526
|
-
throw new Error(`No job ${id}`);
|
|
527
|
-
if (j.state !== "running" && j.state !== "queued")
|
|
528
|
-
return j;
|
|
529
|
-
if (Date.now() - start > timeoutMs)
|
|
530
|
-
throw new Error(`Job ${id} did not finish`);
|
|
531
|
-
await new Promise((r) => setTimeout(r, 20));
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
};
|
|
535
|
-
|
|
536
553
|
// packages/server/dist/static.js
|
|
537
554
|
import { readFile as readFile2, stat as stat2 } from "node:fs/promises";
|
|
538
|
-
import { extname, join as join2, normalize, sep } from "node:path";
|
|
555
|
+
import { extname, join as join2, normalize, resolve, sep } from "node:path";
|
|
539
556
|
var TYPES = {
|
|
540
557
|
".html": "text/html; charset=utf-8",
|
|
541
558
|
".js": "text/javascript; charset=utf-8",
|
|
@@ -564,7 +581,8 @@ function appCsp(port, embed) {
|
|
|
564
581
|
].join("; ");
|
|
565
582
|
}
|
|
566
583
|
var escapeAttr = (s) => s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
567
|
-
async function staticFile(
|
|
584
|
+
async function staticFile(givenDir, path, token, pageKey) {
|
|
585
|
+
const dir = resolve(givenDir);
|
|
568
586
|
let rel;
|
|
569
587
|
try {
|
|
570
588
|
rel = decodeURIComponent(path);
|
|
@@ -583,7 +601,12 @@ async function staticFile(dir, path, token) {
|
|
|
583
601
|
const ext = extname(target).toLowerCase();
|
|
584
602
|
const type = TYPES[ext] ?? "application/octet-stream";
|
|
585
603
|
if (ext === ".html") {
|
|
586
|
-
const
|
|
604
|
+
const tokenMeta = `<meta name="atticus-token" content="${escapeAttr(token)}" />`;
|
|
605
|
+
const keyMeta = pageKey === void 0 ? "" : `<meta name="atticus-page-key" content="${escapeAttr(pageKey)}" />`;
|
|
606
|
+
let html = (await readFile2(target, "utf8")).replace(/<meta name="atticus-token" content="[^"]*"\s*\/?>/, () => tokenMeta);
|
|
607
|
+
if (keyMeta)
|
|
608
|
+
html = /<meta name="atticus-page-key" content="[^"]*"\s*\/?>/.test(html) ? html.replace(/<meta name="atticus-page-key" content="[^"]*"\s*\/?>/, () => keyMeta) : html.replace(tokenMeta, () => `${tokenMeta}
|
|
609
|
+
${keyMeta}`);
|
|
587
610
|
return { status: 200, type, body: html, cache: "no-store" };
|
|
588
611
|
}
|
|
589
612
|
return {
|
|
@@ -595,6 +618,91 @@ async function staticFile(dir, path, token) {
|
|
|
595
618
|
};
|
|
596
619
|
}
|
|
597
620
|
|
|
621
|
+
// packages/server/dist/confirm.js
|
|
622
|
+
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
623
|
+
var CONFIRM_TTL_MS = 12e4;
|
|
624
|
+
var MAX_OPEN = 256;
|
|
625
|
+
var Confirmations = class {
|
|
626
|
+
now;
|
|
627
|
+
open = /* @__PURE__ */ new Map();
|
|
628
|
+
constructor(now = () => Date.now()) {
|
|
629
|
+
this.now = now;
|
|
630
|
+
}
|
|
631
|
+
issue(write, target) {
|
|
632
|
+
const t = this.now();
|
|
633
|
+
for (const [k, v] of this.open)
|
|
634
|
+
if (v.until < t)
|
|
635
|
+
this.open.delete(k);
|
|
636
|
+
while (this.open.size >= MAX_OPEN)
|
|
637
|
+
this.open.delete(this.open.keys().next().value);
|
|
638
|
+
const confirmation = randomBytes(32).toString("base64url");
|
|
639
|
+
const until = t + CONFIRM_TTL_MS;
|
|
640
|
+
this.open.set(confirmation, { write, target, until });
|
|
641
|
+
return { confirmation, write, target, expiresAt: new Date(until).toISOString() };
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Whether `given` confirms this write of this target now. It is spent whatever the answer, so a
|
|
645
|
+
* confirmation is never tried twice: a replay, another target or another write is refused.
|
|
646
|
+
*/
|
|
647
|
+
take(write, target, given) {
|
|
648
|
+
if (typeof given !== "string" || !given)
|
|
649
|
+
return false;
|
|
650
|
+
const c = this.open.get(given);
|
|
651
|
+
if (!c)
|
|
652
|
+
return false;
|
|
653
|
+
this.open.delete(given);
|
|
654
|
+
return c.write === write && c.target === target && this.now() <= c.until;
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
function sameSecret(a, b) {
|
|
658
|
+
const x = Buffer.from(a);
|
|
659
|
+
const y = Buffer.from(b);
|
|
660
|
+
return x.length === y.length && timingSafeEqual(x, y);
|
|
661
|
+
}
|
|
662
|
+
var WITHOUT_THE_APP = {
|
|
663
|
+
handoff: {
|
|
664
|
+
what: "Raising a hand-off opens a PR",
|
|
665
|
+
cli: "atticus change handoff <change> --approve"
|
|
666
|
+
},
|
|
667
|
+
"release-prs": {
|
|
668
|
+
what: "Raising the release PRs pushes the change branch and opens PRs",
|
|
669
|
+
cli: "atticus change release-prs <change> --approve"
|
|
670
|
+
},
|
|
671
|
+
merge: { what: "Merging a ready PR", cli: "atticus change sync <change> --approve" },
|
|
672
|
+
"task-pr": {
|
|
673
|
+
what: "Raising a task's PR pushes its branch and opens a PR",
|
|
674
|
+
cli: "atticus task run <change> <task> --level pr --approve"
|
|
675
|
+
},
|
|
676
|
+
"digest-send": {
|
|
677
|
+
what: "Sending the digest posts a message",
|
|
678
|
+
cli: "atticus digest --send"
|
|
679
|
+
},
|
|
680
|
+
propose: {
|
|
681
|
+
what: "Propose for review pushes a branch and opens a PR",
|
|
682
|
+
cli: "git commit, push and open the PR yourself"
|
|
683
|
+
},
|
|
684
|
+
"step-run": {
|
|
685
|
+
what: "Running a step with a team's tool acts on their systems",
|
|
686
|
+
cli: "atticus todo run <step> --with <executor> --approve <you> --inputs <sha-256>"
|
|
687
|
+
},
|
|
688
|
+
"ai-model": {
|
|
689
|
+
what: "Changing where runtime.yaml sends the model's key (its provider, keyEnv or address)",
|
|
690
|
+
cli: "edit runtime.yaml yourself and propose it for review"
|
|
691
|
+
},
|
|
692
|
+
"ai-test": {
|
|
693
|
+
what: "Testing model settings that aren't committed sends the key to them",
|
|
694
|
+
cli: "commit runtime.yaml first, or run the step from the command line"
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
function needsConfirmation(write) {
|
|
698
|
+
const w = WITHOUT_THE_APP[write];
|
|
699
|
+
return new HttpError(403, "This needs a person's confirmation", `${w.what}, which a person confirms: click it in the Atticus app, or run ${w.cli} in a terminal. The session token alone (atticus ui --show-token, for assistants and scripts) never approves a write to a shared system (ADR 0186).`, { confirm: write });
|
|
700
|
+
}
|
|
701
|
+
function requireConfirmation(c, write, target, given) {
|
|
702
|
+
if (!c.take(write, target, given))
|
|
703
|
+
throw needsConfirmation(write);
|
|
704
|
+
}
|
|
705
|
+
|
|
598
706
|
// packages/server/dist/watch.js
|
|
599
707
|
import { statSync, watch } from "node:fs";
|
|
600
708
|
import { join as join3, relative, sep as sep2 } from "node:path";
|
|
@@ -613,6 +721,14 @@ function watchMetarepo(o) {
|
|
|
613
721
|
const delay = o.delayMs ?? 300;
|
|
614
722
|
const maxPaths = o.maxPaths ?? 50;
|
|
615
723
|
const watchers = /* @__PURE__ */ new Map();
|
|
724
|
+
const inodes = /* @__PURE__ */ new Map();
|
|
725
|
+
const inodeOf = (d) => {
|
|
726
|
+
try {
|
|
727
|
+
return statSync(d).ino;
|
|
728
|
+
} catch {
|
|
729
|
+
return void 0;
|
|
730
|
+
}
|
|
731
|
+
};
|
|
616
732
|
const problems = [];
|
|
617
733
|
const pending = /* @__PURE__ */ new Set();
|
|
618
734
|
let timer;
|
|
@@ -673,21 +789,39 @@ function watchMetarepo(o) {
|
|
|
673
789
|
note(name ? join3(dir, String(name)) : dir);
|
|
674
790
|
});
|
|
675
791
|
w.on("error", (e) => {
|
|
676
|
-
problems.push(`${posix(relative(root, dir)) || "."}: ${e.message}`);
|
|
677
792
|
w.close();
|
|
793
|
+
if (watchers.get(dir) !== w)
|
|
794
|
+
return;
|
|
795
|
+
problems.push(`${posix(relative(root, dir)) || "."}: ${e.message}`);
|
|
678
796
|
watchers.delete(dir);
|
|
797
|
+
inodes.delete(dir);
|
|
679
798
|
});
|
|
680
799
|
watchers.set(dir, w);
|
|
800
|
+
const ino = inodeOf(dir);
|
|
801
|
+
if (ino !== void 0)
|
|
802
|
+
inodes.set(dir, ino);
|
|
803
|
+
const label = `${posix(relative(root, dir)) || "."}: `;
|
|
804
|
+
for (let i = problems.length - 1; i >= 0; i--)
|
|
805
|
+
if (problems[i].startsWith(label))
|
|
806
|
+
problems.splice(i, 1);
|
|
681
807
|
} catch (e) {
|
|
682
808
|
problems.push(`${posix(relative(root, dir)) || "."}: ${e.message}`);
|
|
683
809
|
}
|
|
684
810
|
};
|
|
685
811
|
const attach = () => {
|
|
812
|
+
for (const [d, w] of watchers) {
|
|
813
|
+
const ino = inodeOf(d);
|
|
814
|
+
if (ino === void 0 || inodes.has(d) && inodes.get(d) !== ino) {
|
|
815
|
+
w.close();
|
|
816
|
+
watchers.delete(d);
|
|
817
|
+
inodes.delete(d);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
follow(root, false);
|
|
821
|
+
follow(join3(root, ".atticus"), false);
|
|
686
822
|
for (const d of folders())
|
|
687
823
|
follow(d, true);
|
|
688
824
|
};
|
|
689
|
-
follow(root, false);
|
|
690
|
-
follow(join3(root, ".atticus"), false);
|
|
691
825
|
attach();
|
|
692
826
|
return {
|
|
693
827
|
get following() {
|
|
@@ -707,6 +841,8 @@ function watchMetarepo(o) {
|
|
|
707
841
|
|
|
708
842
|
// packages/server/dist/ws.js
|
|
709
843
|
import { createHash } from "node:crypto";
|
|
844
|
+
var MAX_CLIENT_FRAME = 64 * 1024;
|
|
845
|
+
var MAX_CLIENT_BUFFER = 256 * 1024;
|
|
710
846
|
var GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
711
847
|
function acceptKey(key) {
|
|
712
848
|
return createHash("sha1").update(key + GUID).digest("base64");
|
|
@@ -758,8 +894,14 @@ var Socket = class {
|
|
|
758
894
|
this.closed = true;
|
|
759
895
|
this.onClose(this);
|
|
760
896
|
}
|
|
761
|
-
/**
|
|
897
|
+
/**
|
|
898
|
+
* Client frames are masked; only control frames matter to us. The page sends nothing but pings
|
|
899
|
+
* and a close, so a frame over MAX_CLIENT_FRAME, a buffer over MAX_CLIENT_BUFFER or an unmasked
|
|
900
|
+
* frame (RFC 6455 5.1) closes the connection rather than growing memory.
|
|
901
|
+
*/
|
|
762
902
|
read(d) {
|
|
903
|
+
if (this.buf.length + d.length > MAX_CLIENT_BUFFER)
|
|
904
|
+
return this.close();
|
|
763
905
|
this.buf = Buffer.concat([this.buf, d]);
|
|
764
906
|
while (this.buf.length >= 2) {
|
|
765
907
|
const opcode = this.buf[0] & 15;
|
|
@@ -777,15 +919,15 @@ var Socket = class {
|
|
|
777
919
|
len = Number(this.buf.readBigUInt64BE(2));
|
|
778
920
|
off = 10;
|
|
779
921
|
}
|
|
922
|
+
if (!masked || len > MAX_CLIENT_FRAME)
|
|
923
|
+
return this.close();
|
|
780
924
|
const maskOff = off;
|
|
781
|
-
|
|
782
|
-
off += 4;
|
|
925
|
+
off += 4;
|
|
783
926
|
if (this.buf.length < off + len)
|
|
784
927
|
return;
|
|
785
928
|
const payload = Buffer.from(this.buf.subarray(off, off + len));
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
payload[i] ^= this.buf[maskOff + i % 4];
|
|
929
|
+
for (let i = 0; i < payload.length; i++)
|
|
930
|
+
payload[i] ^= this.buf[maskOff + i % 4];
|
|
789
931
|
this.buf = this.buf.subarray(off + len);
|
|
790
932
|
if (opcode === 8)
|
|
791
933
|
return this.close();
|
|
@@ -842,11 +984,8 @@ var EventHub = class {
|
|
|
842
984
|
}
|
|
843
985
|
};
|
|
844
986
|
var MAX_BODY = 4 * 1024 * 1024;
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
const y = Buffer.from(b);
|
|
848
|
-
return x.length === y.length && timingSafeEqual(x, y);
|
|
849
|
-
}
|
|
987
|
+
var sameToken = sameSecret;
|
|
988
|
+
var STRONG = /^[A-Za-z0-9_-]{32,}$/;
|
|
850
989
|
async function readBody(req, max = MAX_BODY) {
|
|
851
990
|
const chunks = [];
|
|
852
991
|
let size = 0;
|
|
@@ -888,9 +1027,11 @@ async function startServer(o) {
|
|
|
888
1027
|
const host = o.host ?? "127.0.0.1";
|
|
889
1028
|
if (host !== "127.0.0.1")
|
|
890
1029
|
throw new Error(`Atticus only listens on 127.0.0.1 (asked for ${host}).`);
|
|
891
|
-
const token = o.token &&
|
|
1030
|
+
const token = o.token && STRONG.test(o.token) ? o.token : randomBytes2(32).toString("base64url");
|
|
1031
|
+
const pageKey = o.pageKey && STRONG.test(o.pageKey) && o.pageKey !== token ? o.pageKey : randomBytes2(32).toString("base64url");
|
|
892
1032
|
const events = new EventHub();
|
|
893
1033
|
const jobs = new JobManager((e) => events.publish(e));
|
|
1034
|
+
const confirmations = new Confirmations();
|
|
894
1035
|
const person = o.user ? { handle: o.user, source: "given" } : await gitUser(o.root);
|
|
895
1036
|
const ctx = {
|
|
896
1037
|
root: o.root,
|
|
@@ -899,9 +1040,17 @@ async function startServer(o) {
|
|
|
899
1040
|
version: o.version ?? "0.0.0",
|
|
900
1041
|
full: o.full === true,
|
|
901
1042
|
events,
|
|
902
|
-
jobs
|
|
1043
|
+
jobs,
|
|
1044
|
+
confirmations
|
|
903
1045
|
};
|
|
904
|
-
const router = apiRoutes(new Router(), ctx).add("
|
|
1046
|
+
const router = apiRoutes(new Router(), ctx).add("POST", "/api/confirmations", ({ body }) => {
|
|
1047
|
+
const b = api_exports.ConfirmationRequest.safeParse(body ?? {});
|
|
1048
|
+
if (!b.success)
|
|
1049
|
+
throw badRequest(`Say which write and what for: { write: ${api_exports.CONFIRMED_WRITES.join(" | ")}, target }.`);
|
|
1050
|
+
if (!b.data.pageKey || !sameSecret(b.data.pageKey, pageKey))
|
|
1051
|
+
throw new HttpError(403, "Only the Atticus app asks for a confirmation", "A write to a shared system is a person's: they click it in the Atticus app, or run its command with --approve in a terminal. The session token alone (atticus ui --show-token) can't confirm one (ADR 0186).");
|
|
1052
|
+
return { status: 201, body: confirmations.issue(b.data.write, b.data.target) };
|
|
1053
|
+
}).add("GET", "/api/jobs/{jobId}", ({ params }) => {
|
|
905
1054
|
const j = jobs.get(params.jobId);
|
|
906
1055
|
if (!j)
|
|
907
1056
|
throw notFound(`There is no job ${params.jobId}.`);
|
|
@@ -947,7 +1096,7 @@ async function startServer(o) {
|
|
|
947
1096
|
throw new HttpError(403, "Requests must be addressed to this server");
|
|
948
1097
|
if (!o.staticDir || req.method !== "GET" && req.method !== "HEAD")
|
|
949
1098
|
throw new HttpError(404, "Not found", `Nothing is served at ${url.pathname}.`);
|
|
950
|
-
const f = await staticFile(o.staticDir, url.pathname, token);
|
|
1099
|
+
const f = await staticFile(o.staticDir, url.pathname, token, pageKey);
|
|
951
1100
|
const { "X-Frame-Options": deny, ...rest } = HARDENING;
|
|
952
1101
|
res.writeHead(f.status, {
|
|
953
1102
|
...o.embed ? rest : { ...rest, "X-Frame-Options": deny },
|
|
@@ -976,14 +1125,18 @@ async function startServer(o) {
|
|
|
976
1125
|
send(res, out.status, out.body);
|
|
977
1126
|
done(out.status);
|
|
978
1127
|
} catch (e) {
|
|
979
|
-
const err = e instanceof HttpError ? e : new HttpError(
|
|
1128
|
+
const err = e instanceof HttpError ? e : e instanceof FileChangedError ? new HttpError(409, "The file changed meanwhile", e.message) : (
|
|
1129
|
+
// The message stays in the log (onRequest gets the error): an fs error names the
|
|
1130
|
+
// metarepo's absolute path, which the page has no use for.
|
|
1131
|
+
new HttpError(500, "Something went wrong", "The app's log (.atticus/logs/atticus.log) has the details.")
|
|
1132
|
+
);
|
|
980
1133
|
send(res, err.status, problem(err), "application/problem+json");
|
|
981
1134
|
done(err.status, err.status >= 500 && e instanceof Error ? e : void 0);
|
|
982
1135
|
}
|
|
983
1136
|
});
|
|
984
1137
|
server.on("upgrade", (req, sock) => {
|
|
985
|
-
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
986
1138
|
try {
|
|
1139
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
987
1140
|
if (url.pathname !== "/api/events")
|
|
988
1141
|
throw new HttpError(404, "Not found");
|
|
989
1142
|
guard(req, url, true);
|
|
@@ -999,9 +1152,9 @@ Connection: close\r
|
|
|
999
1152
|
if (s)
|
|
1000
1153
|
events.add(s);
|
|
1001
1154
|
});
|
|
1002
|
-
await new Promise((
|
|
1155
|
+
await new Promise((resolve2, reject) => {
|
|
1003
1156
|
server.once("error", reject);
|
|
1004
|
-
server.listen(o.port ?? DEFAULT_PORT, host, () =>
|
|
1157
|
+
server.listen(o.port ?? DEFAULT_PORT, host, () => resolve2());
|
|
1005
1158
|
});
|
|
1006
1159
|
port = server.address().port;
|
|
1007
1160
|
const watcher = o.watch === false ? void 0 : watchMetarepo({ root: o.root, publish: (e) => events.publish(e) });
|
|
@@ -1009,219 +1162,29 @@ Connection: close\r
|
|
|
1009
1162
|
url: `http://127.0.0.1:${port}`,
|
|
1010
1163
|
port,
|
|
1011
1164
|
token,
|
|
1165
|
+
pageKey,
|
|
1166
|
+
confirmations,
|
|
1012
1167
|
events,
|
|
1013
1168
|
jobs,
|
|
1014
1169
|
person,
|
|
1015
1170
|
get following() {
|
|
1016
1171
|
return watcher?.following ?? [];
|
|
1017
1172
|
},
|
|
1018
|
-
close: () => new Promise((
|
|
1173
|
+
close: () => new Promise((resolve2) => {
|
|
1019
1174
|
watcher?.close();
|
|
1020
1175
|
events.closeAll();
|
|
1021
1176
|
server.closeAllConnections?.();
|
|
1022
|
-
server.close(() =>
|
|
1177
|
+
server.close(() => resolve2());
|
|
1023
1178
|
})
|
|
1024
1179
|
};
|
|
1025
1180
|
}
|
|
1026
1181
|
|
|
1027
|
-
// packages/cli/dist/ui-api-cites.js
|
|
1028
|
-
var import_yaml = __toESM(require_dist(), 1);
|
|
1029
|
-
async function fingerprint(dirs) {
|
|
1030
|
-
let count = 0;
|
|
1031
|
-
let newest = 0;
|
|
1032
|
-
const walk = async (d) => {
|
|
1033
|
-
const entries = await readdir(d, { withFileTypes: true }).catch(() => []);
|
|
1034
|
-
for (const e of entries) {
|
|
1035
|
-
const p = join4(d, e.name);
|
|
1036
|
-
if (e.isDirectory())
|
|
1037
|
-
await walk(p);
|
|
1038
|
-
else {
|
|
1039
|
-
count++;
|
|
1040
|
-
const s = await stat3(p).catch(() => void 0);
|
|
1041
|
-
if (s && s.mtimeMs > newest)
|
|
1042
|
-
newest = s.mtimeMs;
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
};
|
|
1046
|
-
for (const d of dirs)
|
|
1047
|
-
await walk(d);
|
|
1048
|
-
return `${count}:${newest}`;
|
|
1049
|
-
}
|
|
1050
|
-
async function build(root) {
|
|
1051
|
-
const index = /* @__PURE__ */ new Map();
|
|
1052
|
-
const lineOf = (repo, path, line) => {
|
|
1053
|
-
const files = index.get(repo) ?? /* @__PURE__ */ new Map();
|
|
1054
|
-
index.set(repo, files);
|
|
1055
|
-
const lines = files.get(path) ?? /* @__PURE__ */ new Map();
|
|
1056
|
-
files.set(path, lines);
|
|
1057
|
-
const l = lines.get(line) ?? { line, flows: [], records: [] };
|
|
1058
|
-
lines.set(line, l);
|
|
1059
|
-
return l;
|
|
1060
|
-
};
|
|
1061
|
-
for (const specRepo of await specRepos(root))
|
|
1062
|
-
for (const f of (await readRepoSpec(root, specRepo, { cacheRoot: root })).flows) {
|
|
1063
|
-
const parts = [
|
|
1064
|
-
{ step: 0, kind: f.trigger.kind, evidence: f.trigger.evidence },
|
|
1065
|
-
...f.steps.map((s, i) => ({
|
|
1066
|
-
step: i + 1,
|
|
1067
|
-
kind: s.kind,
|
|
1068
|
-
...s.confirmedBy ? { confirmedBy: s.confirmedBy } : {},
|
|
1069
|
-
evidence: s.evidence
|
|
1070
|
-
}))
|
|
1071
|
-
];
|
|
1072
|
-
for (const part of parts)
|
|
1073
|
-
for (const e of part.evidence) {
|
|
1074
|
-
if (!e.path || e.line === void 0)
|
|
1075
|
-
continue;
|
|
1076
|
-
const l = lineOf(e.repo ?? specRepo, e.path, e.line);
|
|
1077
|
-
if (l.flows.some((x) => x.flow === f.id && x.step === part.step))
|
|
1078
|
-
continue;
|
|
1079
|
-
l.flows.push({
|
|
1080
|
-
repo: specRepo,
|
|
1081
|
-
flow: f.id,
|
|
1082
|
-
name: f.name,
|
|
1083
|
-
step: part.step,
|
|
1084
|
-
kind: part.kind,
|
|
1085
|
-
...part.confirmedBy ? { confirmedBy: part.confirmedBy } : {}
|
|
1086
|
-
});
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
for (const r of await catalogRecords(root)) {
|
|
1090
|
-
const name = r.name;
|
|
1091
|
-
for (const e of r.evidence) {
|
|
1092
|
-
if (!e.repo || !e.path || e.line === void 0)
|
|
1093
|
-
continue;
|
|
1094
|
-
const l = lineOf(e.repo, e.path, e.line);
|
|
1095
|
-
if (l.records.some((x) => x.kind === r.kind && x.id === r.id))
|
|
1096
|
-
continue;
|
|
1097
|
-
l.records.push({
|
|
1098
|
-
kind: r.kind,
|
|
1099
|
-
id: r.id,
|
|
1100
|
-
...typeof name === "string" && name !== r.id ? { name } : {},
|
|
1101
|
-
source: e.source
|
|
1102
|
-
});
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
return index;
|
|
1106
|
-
}
|
|
1107
|
-
var DONE = /* @__PURE__ */ new Set(["released", "archived", "post-release-review"]);
|
|
1108
|
-
async function inFlight(root) {
|
|
1109
|
-
const out = /* @__PURE__ */ new Map();
|
|
1110
|
-
const dir = changesDirOf(root);
|
|
1111
|
-
for (const e of await readdir(dir, { withFileTypes: true }).catch(() => [])) {
|
|
1112
|
-
if (!e.isDirectory() || e.name === "archive")
|
|
1113
|
-
continue;
|
|
1114
|
-
const yaml = await readFile3(join4(dir, e.name, "change.yaml"), "utf8").catch(() => "");
|
|
1115
|
-
const state = (() => {
|
|
1116
|
-
try {
|
|
1117
|
-
return (0, import_yaml.parse)(yaml)?.state;
|
|
1118
|
-
} catch {
|
|
1119
|
-
return void 0;
|
|
1120
|
-
}
|
|
1121
|
-
})();
|
|
1122
|
-
if (!yaml || typeof state === "string" && DONE.has(state))
|
|
1123
|
-
continue;
|
|
1124
|
-
for (const f of await readdir(join4(dir, e.name, "target-flows")).catch(() => []))
|
|
1125
|
-
if (f.endsWith(".yaml")) {
|
|
1126
|
-
const flow = f.slice(0, -".yaml".length);
|
|
1127
|
-
out.set(flow, [...out.get(flow) ?? [], e.name]);
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
return out;
|
|
1131
|
-
}
|
|
1132
|
-
async function citeList(root, index, repo, path) {
|
|
1133
|
-
const lines = [...index.get(repo)?.get(path)?.values() ?? []].sort((a, b) => a.line - b.line);
|
|
1134
|
-
const flying = await inFlight(root);
|
|
1135
|
-
const shown = lines.map((l) => ({
|
|
1136
|
-
...l,
|
|
1137
|
-
flows: [...l.flows].sort((a, b) => a.flow.localeCompare(b.flow) || a.step - b.step).map((f) => flying.get(f.flow)?.length ? { ...f, changes: flying.get(f.flow) } : f)
|
|
1138
|
-
}));
|
|
1139
|
-
return { repo, path, lines: shown };
|
|
1140
|
-
}
|
|
1141
|
-
function fileInRepo(root, file) {
|
|
1142
|
-
const rel = relative2(root, file);
|
|
1143
|
-
if (!rel || rel.startsWith("..") || isAbsolute(rel))
|
|
1144
|
-
return void 0;
|
|
1145
|
-
const parts = rel.split(sep3);
|
|
1146
|
-
if (parts[0] !== "workspace")
|
|
1147
|
-
return { path: parts.join("/") };
|
|
1148
|
-
const at = parts[1] === ".worktrees" ? 3 : parts[1] === ".branches" ? 2 : 1;
|
|
1149
|
-
const repo = parts[at];
|
|
1150
|
-
const rest = parts.slice(parts[1] === ".branches" ? 4 : at + 1);
|
|
1151
|
-
if (!repo || !rest.length || !RecordId.safeParse(repo).success)
|
|
1152
|
-
return void 0;
|
|
1153
|
-
return { repo, path: rest.join("/") };
|
|
1154
|
-
}
|
|
1155
|
-
async function citesCli(root, o, io) {
|
|
1156
|
-
let repo = o.repo;
|
|
1157
|
-
let path = o.path;
|
|
1158
|
-
const index = await build(root);
|
|
1159
|
-
if (o.file) {
|
|
1160
|
-
const at = fileInRepo(root, o.file);
|
|
1161
|
-
if (!at) {
|
|
1162
|
-
io.err(`${o.file} isn't in this metarepo or a repo's checkout in its workspace.`);
|
|
1163
|
-
return 1;
|
|
1164
|
-
}
|
|
1165
|
-
path = at.path;
|
|
1166
|
-
repo = at.repo ?? [...index.keys()].find((r) => index.get(r).has(at.path)) ?? void 0;
|
|
1167
|
-
if (!repo) {
|
|
1168
|
-
if (o.json)
|
|
1169
|
-
io.out(JSON.stringify({ repo: "", path, lines: [] }, null, 2));
|
|
1170
|
-
else
|
|
1171
|
-
io.out(`Nothing in the specs or the catalog cites ${path}.`);
|
|
1172
|
-
return 0;
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
if (!repo || !path || !RecordId.safeParse(repo).success) {
|
|
1176
|
-
io.err("Say which file: atticus cites --repo <repo> --path <its path in the repo>, or --file <path on disk>.");
|
|
1177
|
-
return 2;
|
|
1178
|
-
}
|
|
1179
|
-
const v = await citeList(root, index, repo, path);
|
|
1180
|
-
if (o.json) {
|
|
1181
|
-
io.out(JSON.stringify(v, null, 2));
|
|
1182
|
-
return 0;
|
|
1183
|
-
}
|
|
1184
|
-
if (!v.lines.length) {
|
|
1185
|
-
io.out(`Nothing in the specs or the catalog cites ${repo}/${path}.`);
|
|
1186
|
-
return 0;
|
|
1187
|
-
}
|
|
1188
|
-
for (const l of v.lines) {
|
|
1189
|
-
const flows = l.flows.map((f) => `${f.name} (step ${f.step})${f.changes?.length ? `, changed by ${f.changes.join(", ")}` : ""}`);
|
|
1190
|
-
const records = l.records.map((r) => `${r.kind} ${r.name ?? r.id}`);
|
|
1191
|
-
io.out(`Line ${l.line}: ${[...flows, ...records].join("; ")}`);
|
|
1192
|
-
}
|
|
1193
|
-
return 0;
|
|
1194
|
-
}
|
|
1195
|
-
function uiCiteRoutes(r, ctx) {
|
|
1196
|
-
const root = ctx.root;
|
|
1197
|
-
let cached;
|
|
1198
|
-
const indexNow = async () => {
|
|
1199
|
-
const print = await fingerprint([specsDirOf(root), catalogDirOf(root)]);
|
|
1200
|
-
if (cached?.print !== print)
|
|
1201
|
-
cached = { print, index: build(root) };
|
|
1202
|
-
return cached.index;
|
|
1203
|
-
};
|
|
1204
|
-
void indexNow().catch(() => void 0);
|
|
1205
|
-
r.add("GET", "/api/cites", async ({ query }) => {
|
|
1206
|
-
const repo = query.get("repo");
|
|
1207
|
-
const path = query.get("path");
|
|
1208
|
-
if (!repo || !RecordId.safeParse(repo).success)
|
|
1209
|
-
throw badRequest("Say which repo: ?repo=<the repo's id>.");
|
|
1210
|
-
if (!path)
|
|
1211
|
-
throw badRequest("Say which file: ?path=<its path in the repo>.");
|
|
1212
|
-
return { status: 200, body: await citeList(root, await indexNow(), repo, path) };
|
|
1213
|
-
});
|
|
1214
|
-
return r;
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
1182
|
export {
|
|
1218
1183
|
HttpError,
|
|
1219
1184
|
badRequest,
|
|
1220
1185
|
notFound,
|
|
1221
1186
|
conflict,
|
|
1222
1187
|
strParam,
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
citesCli,
|
|
1226
|
-
uiCiteRoutes
|
|
1188
|
+
requireConfirmation,
|
|
1189
|
+
startServer
|
|
1227
1190
|
};
|