@maycombhq/atticus 2.0.0-beta.2 → 2.0.0-beta.21
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-265LWMOA.js +91 -0
- package/dist/chunk-26WBY34Y.js +37 -0
- package/dist/{chunk-UBBC2XSG.js → chunk-26Z7OGQW.js} +518 -93
- package/dist/chunk-2D7PWSOK.js +172 -0
- package/dist/{chunk-JCZIKA4C.js → chunk-2HH3UCZM.js} +4 -4
- package/dist/{chunk-GDLULHTC.js → chunk-2HTEMYTB.js} +12 -26
- package/dist/chunk-2UCRFXFZ.js +130 -0
- package/dist/{chunk-MVZVGYXH.js → chunk-2V2ZPQQU.js} +81 -13
- package/dist/{chunk-BOHJZTEQ.js → chunk-36RY7ZXM.js} +130 -71
- package/dist/{chunk-I3E7CX4H.js → chunk-37WE3LS2.js} +3 -3
- package/dist/{chunk-IPKHE5D6.js → chunk-3AQ2R5NL.js} +1520 -871
- package/dist/chunk-3G6S7LAA.js +43 -0
- package/dist/chunk-3J5I7ZOU.js +58 -0
- package/dist/{chunk-65NYPGRC.js → chunk-3LZ6P5EP.js} +1 -1
- package/dist/chunk-3SSTNB4E.js +191 -0
- package/dist/chunk-3TD6S4TC.js +49 -0
- package/dist/{chunk-3C7EYRFZ.js → chunk-3UTYPHN3.js} +1 -1
- package/dist/{chunk-G2B4ZQGH.js → chunk-3WON4G3M.js} +2 -2
- package/dist/{chunk-S3QNRWYR.js → chunk-42EPP7OB.js} +12 -12
- package/dist/chunk-455SYIIE.js +113 -0
- package/dist/{chunk-YISXLPHN.js → chunk-4B6BT75O.js} +166 -23
- package/dist/{chunk-C6EKFH7J.js → chunk-4CLK2RJO.js} +7 -7
- package/dist/chunk-4CYTJ5TZ.js +38 -0
- package/dist/{chunk-EYWIDJFU.js → chunk-4D62IZII.js} +5 -5
- package/dist/chunk-4FOAYLI4.js +328 -0
- package/dist/{chunk-7JUKDRSZ.js → chunk-4KNOJC6J.js} +294 -215
- package/dist/{chunk-YMZ3TNYB.js → chunk-4PYC2UGC.js} +2 -2
- package/dist/{chunk-27NKUS3X.js → chunk-4SLBCEPD.js} +2104 -726
- package/dist/chunk-4TKVU2I2.js +122 -0
- package/dist/{chunk-RUVFXE2L.js → chunk-4WXRPQDE.js} +448 -47
- package/dist/{chunk-7ZUIMTOU.js → chunk-5CMPVC3N.js} +24 -24
- package/dist/chunk-5G7ILBUG.js +66 -0
- package/dist/{chunk-HFQCFSJR.js → chunk-5PV7S2ZP.js} +3 -3
- package/dist/{chunk-FITWGOJ2.js → chunk-5QUOPNLN.js} +4 -4
- package/dist/{chunk-Z6LF7HQN.js → chunk-5TDRBOAV.js} +5 -5
- package/dist/{chunk-T6AIP7H5.js → chunk-5WERBKLE.js} +199 -63
- package/dist/{chunk-XPCM366L.js → chunk-62DLJSLV.js} +8 -8
- package/dist/{chunk-L24C55VN.js → chunk-64AADMTW.js} +99 -25
- package/dist/{chunk-K65BJIMT.js → chunk-67BP7HXL.js} +17 -17
- package/dist/chunk-6DQYZU2W.js +379 -0
- package/dist/{chunk-EDS2L2LD.js → chunk-6EXDI5GI.js} +52 -26
- package/dist/chunk-6FNAKCET.js +38 -0
- package/dist/{chunk-6IU67AEK.js → chunk-75ASLHBT.js} +21 -15
- package/dist/{chunk-A3GY6SOA.js → chunk-75ZOZFGH.js} +18 -18
- package/dist/{chunk-MGYZM27B.js → chunk-77O633L5.js} +49 -23
- package/dist/{chunk-GQ4N4WKF.js → chunk-7AB6OWTV.js} +3 -3
- package/dist/{chunk-M766ZJ6W.js → chunk-7CZHUZBL.js} +25 -25
- package/dist/{chunk-A7UPUQFY.js → chunk-7FHNFCHK.js} +643 -124
- package/dist/chunk-7FUIVIBG.js +415 -0
- package/dist/{chunk-6QSERWXH.js → chunk-7QPCGTPS.js} +21 -21
- package/dist/{chunk-LR3R6Z2A.js → chunk-A2G72UI4.js} +7 -7
- package/dist/{chunk-I4JRCD6M.js → chunk-AE4P57KK.js} +23 -17
- package/dist/{chunk-AVJDSJ2F.js → chunk-AHW3RY3X.js} +7 -7
- package/dist/chunk-AM6FP6JW.js +43 -0
- package/dist/{chunk-CSZ4C5N6.js → chunk-AOCWFA7T.js} +93 -10
- package/dist/{chunk-EPTBZ3GP.js → chunk-API5TOUB.js} +1 -1
- package/dist/{chunk-652QWTLZ.js → chunk-AZDITBCT.js} +3 -3
- package/dist/{chunk-DPUYDDQG.js → chunk-BA2HUMDN.js} +25 -3
- package/dist/chunk-BA3U7ALS.js +99 -0
- package/dist/{chunk-HVUPKCGJ.js → chunk-BC6KKZ67.js} +5 -5
- package/dist/{chunk-CKSITVS4.js → chunk-BEPCKDCP.js} +2554 -722
- package/dist/{chunk-3ALD2W2A.js → chunk-BPPU3PW7.js} +4 -4
- package/dist/{chunk-QRAOANID.js → chunk-BVWWPBKD.js} +21 -21
- package/dist/{chunk-ZDPAS56H.js → chunk-BXBCMGIQ.js} +7 -1
- package/dist/chunk-BXZ4PKIT.js +233 -0
- package/dist/chunk-C7CEK3KW.js +247 -0
- package/dist/chunk-CFH3QH26.js +29 -0
- package/dist/chunk-CG6CULP6.js +170 -0
- package/dist/chunk-CLD4RVTA.js +45 -0
- package/dist/{chunk-DKJA76CJ.js → chunk-CNPY4NTZ.js} +13 -13
- package/dist/chunk-CNU5Q2D5.js +575 -0
- package/dist/{chunk-T2UYZSCQ.js → chunk-COYN3UAN.js} +126 -23
- package/dist/{chunk-23W7VWKR.js → chunk-CPK7QSBG.js} +1360 -113
- package/dist/{chunk-4AK7IBVP.js → chunk-D2WSW4GU.js} +1 -1
- package/dist/{chunk-ABWHYWNI.js → chunk-D57MFJPP.js} +3 -3
- package/dist/chunk-D5KV5PSK.js +45 -0
- package/dist/chunk-D5MASS4I.js +48 -0
- package/dist/{chunk-7EOBHUMC.js → chunk-DCWN3HFV.js} +2 -2
- package/dist/{chunk-QSXK2RGH.js → chunk-DDJPM5YX.js} +2 -2
- package/dist/chunk-DN4A2Q2O.js +57 -0
- package/dist/{chunk-IHMLFRVV.js → chunk-DUPZPDCJ.js} +58 -16
- package/dist/{chunk-PRPPGYZG.js → chunk-E2VXBSIR.js} +4 -4
- package/dist/chunk-E57AOFYN.js +32 -0
- package/dist/{chunk-UGLN7QHV.js → chunk-ECLXZWAG.js} +12 -12
- package/dist/{chunk-5WG5YP4T.js → chunk-EDZ45WIR.js} +14 -14
- package/dist/chunk-EFCQSMXB.js +37 -0
- package/dist/{chunk-2ANOROX3.js → chunk-EZIN5E5B.js} +8 -8
- package/dist/{chunk-BWZ77RQT.js → chunk-F6H2RJ3N.js} +1 -1
- package/dist/{chunk-OLQJTJJU.js → chunk-FAJDKNSD.js} +7 -3
- package/dist/chunk-FGAGWYZB.js +47 -0
- package/dist/{chunk-4WBVUHXN.js → chunk-FLVZFTLQ.js} +18 -18
- package/dist/chunk-FQ6WH6PB.js +140 -0
- package/dist/{chunk-T6XQL73F.js → chunk-FRHD22WM.js} +61 -23
- package/dist/{chunk-XAKWMCXI.js → chunk-FVMPFCDS.js} +4 -4
- package/dist/{chunk-B2WLAWNJ.js → chunk-FY3QIRTL.js} +3 -3
- package/dist/{chunk-CPA6HPVR.js → chunk-FYBF5MB2.js} +15 -11
- package/dist/{chunk-V2YTAIQO.js → chunk-G5YJBNDZ.js} +21 -6
- package/dist/chunk-G6IQYM25.js +339 -0
- package/dist/chunk-G6X4YL4D.js +161 -0
- package/dist/{chunk-SJRGMG6A.js → chunk-GC2VK3JT.js} +25 -25
- package/dist/{chunk-SP2I63OO.js → chunk-GCS3FZOB.js} +77 -3
- package/dist/{chunk-6TACQN3N.js → chunk-GDZB57IU.js} +5 -5
- package/dist/chunk-GIFMBCTW.js +221 -0
- package/dist/{chunk-YY6ZQQBP.js → chunk-GK4PYVEC.js} +18 -8
- package/dist/{chunk-TDD55CJH.js → chunk-GNWAOVFQ.js} +6 -5
- package/dist/chunk-GS76RXQE.js +226 -0
- package/dist/{chunk-YYQN46FY.js → chunk-GSGIZ2OO.js} +23 -23
- package/dist/chunk-GUYL7RMK.js +60 -0
- package/dist/chunk-GX74YWR7.js +321 -0
- package/dist/chunk-HE3HRDNZ.js +122 -0
- package/dist/{chunk-AIOQPLA5.js → chunk-HGHRSF3E.js} +30 -12
- package/dist/{chunk-2RMYG36Q.js → chunk-HK3VOHIE.js} +198 -336
- package/dist/{chunk-QZSX3F7C.js → chunk-HS4BGB4G.js} +24 -22
- package/dist/{chunk-XY3P7JW7.js → chunk-HSZMPH5T.js} +834 -149
- package/dist/{chunk-L6SGQIR3.js → chunk-HWD4JPU7.js} +4 -2
- package/dist/{chunk-PCVDV3UZ.js → chunk-HXXP2NTE.js} +6 -6
- package/dist/{chunk-AA6YULYB.js → chunk-I2A3Z5AK.js} +7 -7
- package/dist/{chunk-N7IXEHK3.js → chunk-ICHDSWEY.js} +7 -7
- package/dist/chunk-IFFRGC3N.js +31 -0
- package/dist/{chunk-4BN53TG3.js → chunk-IFHDV6KQ.js} +31 -23
- package/dist/chunk-J2O4LFVI.js +80 -0
- package/dist/chunk-J5AAZ6OJ.js +161 -0
- package/dist/{chunk-ZMFPW66A.js → chunk-JAABT3DA.js} +3 -3
- package/dist/chunk-JITJP64K.js +34 -0
- package/dist/chunk-JKIGL3XQ.js +162 -0
- package/dist/chunk-JRVNXLZP.js +615 -0
- package/dist/chunk-JRXHON4E.js +41 -0
- package/dist/{chunk-DHPACDG7.js → chunk-JS6WMC3J.js} +8 -8
- package/dist/chunk-JU4QNJSR.js +62 -0
- package/dist/{chunk-PAMPPUR6.js → chunk-JYMIB5XY.js} +1697 -172
- package/dist/{chunk-RRTKKSLQ.js → chunk-JYTIHTIK.js} +8 -6
- package/dist/{chunk-3HI6Z55Y.js → chunk-K332XW7K.js} +324 -39
- package/dist/{chunk-GLUX4EEP.js → chunk-K6JB6XTX.js} +9 -9
- package/dist/chunk-KDAHXQIE.js +294 -0
- package/dist/chunk-KYZMRSPS.js +93 -0
- package/dist/chunk-L4CESDPB.js +22 -0
- package/dist/{chunk-NXFPS2LR.js → chunk-LEBR5NHW.js} +14 -14
- package/dist/chunk-LIJJCBQI.js +223 -0
- package/dist/{chunk-DE76JROX.js → chunk-LIRVU3HW.js} +16 -16
- package/dist/{chunk-JMSCMUCA.js → chunk-LN77DXBM.js} +145 -21
- package/dist/{chunk-JIITQXFB.js → chunk-LNWEWYCM.js} +2969 -788
- package/dist/{chunk-TANFV3MZ.js → chunk-LO3BLMVG.js} +3 -3
- package/dist/chunk-LPV6T362.js +250 -0
- package/dist/{chunk-2VHF7OXM.js → chunk-LQH4P45K.js} +1 -1
- package/dist/chunk-LU4MQVAL.js +41 -0
- package/dist/chunk-LWDNKE4X.js +273 -0
- package/dist/chunk-M4H2UG4R.js +218 -0
- package/dist/{chunk-6BVONWJ7.js → chunk-M6D2U3YM.js} +3 -3
- package/dist/chunk-MD7KUEJ3.js +514 -0
- package/dist/{chunk-66YVAGGM.js → chunk-MMZUN7ZO.js} +20 -20
- package/dist/chunk-MZGRDONP.js +916 -0
- package/dist/chunk-N3RUGTGV.js +39 -0
- package/dist/{chunk-JGZCG5VM.js → chunk-NCB6656Z.js} +7 -7
- package/dist/{chunk-4NDAAFQT.js → chunk-NRQ65LTQ.js} +7 -5
- package/dist/{chunk-UNM6ZOKP.js → chunk-NTAVOWYD.js} +145 -18
- package/dist/{chunk-3USYZGRF.js → chunk-NYOABJNK.js} +36 -27
- package/dist/{chunk-WVPJSRRJ.js → chunk-O4IKAIZ2.js} +24 -20
- package/dist/{chunk-D3PO4DOZ.js → chunk-ODMBPDDV.js} +51 -14
- package/dist/chunk-OKUB6RJA.js +533 -0
- package/dist/chunk-OMPENNWY.js +39 -0
- package/dist/chunk-OPQZISG3.js +25 -0
- package/dist/{chunk-5GGOLAKC.js → chunk-OV57AHCG.js} +26 -26
- package/dist/chunk-OZJ3JLYI.js +58 -0
- package/dist/{chunk-KEM4SDDP.js → chunk-P2VBXX7N.js} +11 -10
- package/dist/{chunk-S2A7YC3Q.js → chunk-PAINMSID.js} +10150 -1720
- package/dist/chunk-PKJAV25S.js +43 -0
- package/dist/{chunk-EBEW3XXQ.js → chunk-PNQLCRSS.js} +4 -4
- package/dist/{chunk-WY6PP6AA.js → chunk-PQH56YF6.js} +37 -5
- package/dist/chunk-PRTBPXYA.js +50 -0
- package/dist/{chunk-YEDDOYSC.js → chunk-PRW3HXM3.js} +2 -2
- package/dist/chunk-PRZ7KMWL.js +42 -0
- package/dist/{chunk-6M5NK3K3.js → chunk-PTQ3ZALZ.js} +42 -4
- package/dist/{chunk-5GDRCDQB.js → chunk-PUEWDYGP.js} +2 -2
- package/dist/chunk-Q26LDIUV.js +236 -0
- package/dist/{chunk-CR3MTH32.js → chunk-Q46QDDMF.js} +77 -7
- package/dist/chunk-QBNWF5ZU.js +19 -0
- package/dist/chunk-QE527XRY.js +342 -0
- package/dist/{chunk-CNUKCS2T.js → chunk-QHJJMZLX.js} +1518 -54
- package/dist/chunk-QJCJOMW3.js +425 -0
- package/dist/{chunk-VYDBJ73M.js → chunk-QKMRFNMA.js} +15 -15
- package/dist/chunk-QOOEYDNJ.js +317 -0
- package/dist/chunk-QSIDVFB7.js +45 -0
- package/dist/{chunk-R77KLRB3.js → chunk-RA33EYS4.js} +19 -18
- package/dist/{chunk-DFBCSHVT.js → chunk-RALY3E5U.js} +4 -4
- package/dist/{chunk-ZCJDOK2S.js → chunk-S2RY3BOD.js} +35 -21
- package/dist/chunk-S5LSDXV4.js +40 -0
- package/dist/chunk-SB5GRUFM.js +54 -0
- package/dist/chunk-SH27FYPF.js +150 -0
- package/dist/chunk-T74WQQGS.js +40 -0
- package/dist/{chunk-O3WI5KWW.js → chunk-TGVVUKTG.js} +2 -2
- package/dist/chunk-THN26IEF.js +48 -0
- package/dist/chunk-TJH2EUAZ.js +47 -0
- package/dist/{chunk-ZNCEKR4J.js → chunk-TQ4TG57V.js} +12 -8
- package/dist/{chunk-7FBGJFEE.js → chunk-TQTRWENN.js} +12 -12
- package/dist/{chunk-TYAID7B7.js → chunk-TSM6T6GQ.js} +23 -23
- package/dist/{chunk-DPZHZQKE.js → chunk-TW3KOSQK.js} +43 -10
- package/dist/{chunk-MC3H7736.js → chunk-TWQRPM76.js} +37 -4
- package/dist/chunk-TYD6I4CZ.js +109 -0
- package/dist/chunk-U3NBK4EU.js +420 -0
- package/dist/{chunk-6JCPI55B.js → chunk-UDXWIPCB.js} +47 -7
- package/dist/{chunk-MMOSZPWJ.js → chunk-UEVZZZU2.js} +4 -4
- package/dist/{chunk-JBTK5OP2.js → chunk-UF4UHCIG.js} +2 -2
- package/dist/{chunk-6JUBZBMW.js → chunk-UFE36WJH.js} +4 -4
- package/dist/{chunk-ONLS5QA5.js → chunk-URIKUID7.js} +12 -12
- package/dist/chunk-UYLBRRFK.js +1106 -0
- package/dist/chunk-UZACEG2C.js +515 -0
- package/dist/{chunk-7SW2QWLU.js → chunk-VAMHOHUU.js} +12 -12
- package/dist/{chunk-RZPYKDWS.js → chunk-VUVGX5L2.js} +1 -1
- package/dist/{chunk-Q4D5X7QB.js → chunk-VYOCPTUB.js} +44 -24
- package/dist/{chunk-CAQZUNOH.js → chunk-WAZEXEJH.js} +567 -3
- package/dist/chunk-WCEF7H6L.js +221 -0
- package/dist/{chunk-2DIQQJCB.js → chunk-WEOMJHPV.js} +12 -12
- package/dist/{chunk-FHH4I4ZV.js → chunk-WFU77T3A.js} +12 -6
- package/dist/chunk-WIWTJMMR.js +292 -0
- package/dist/{chunk-2BFCZ3RK.js → chunk-WNTIOBOG.js} +18 -18
- package/dist/{chunk-7WD63HU2.js → chunk-X2CUXTWU.js} +6 -6
- package/dist/chunk-X7EMBM5X.js +34 -0
- package/dist/chunk-XEQCQO66.js +33 -0
- package/dist/{chunk-F7HYOUFF.js → chunk-XG4WJHLQ.js} +20 -4
- package/dist/{chunk-EFHQ3TWP.js → chunk-XOL3GFW2.js} +171 -31
- package/dist/{chunk-NE2W3OO7.js → chunk-XQ3YZ4QW.js} +22 -22
- package/dist/{chunk-CEXSU4S6.js → chunk-Y6K3CJBU.js} +723 -85
- package/dist/{chunk-4RS5KZQD.js → chunk-YAH5IQAL.js} +5 -5
- package/dist/{chunk-64EQYWCA.js → chunk-YBOVNMHC.js} +51 -14
- package/dist/chunk-YF5DZCPN.js +1212 -0
- package/dist/chunk-YIGBJNH4.js +37 -0
- package/dist/{chunk-BKVWTZ6A.js → chunk-YJ3TBOTK.js} +25 -25
- package/dist/{chunk-Q5AMFEWD.js → chunk-YKTE2RU3.js} +2 -2
- package/dist/{chunk-7EKXJZ2Y.js → chunk-YO2PKTXT.js} +296 -37
- package/dist/{chunk-6J5OKA4Y.js → chunk-YTTNTQOX.js} +15 -15
- package/dist/{chunk-OT2O76OS.js → chunk-YWAKDNMH.js} +183 -33
- package/dist/{chunk-R6XF6UR3.js → chunk-YZDZOEV4.js} +4 -4
- package/dist/chunk-Z3QFH7YG.js +17 -0
- package/dist/{chunk-W5BVQF44.js → chunk-Z6VLC5X4.js} +17 -17
- package/dist/{chunk-HLJAXMM4.js → chunk-ZFQMMU5Y.js} +2 -2
- package/dist/{chunk-W3BQAZ3Q.js → chunk-ZKYRDV7A.js} +12 -12
- package/dist/{chunk-ZMAINWBW.js → chunk-ZLS6PU2O.js} +3 -3
- package/dist/{chunk-ZVM6AKKM.js → chunk-ZOSD4FXV.js} +3 -3
- package/dist/chunk-ZPDDEVQX.js +47 -0
- package/dist/{chunk-TXLH6WHQ.js → chunk-ZQLRCA2V.js} +11 -11
- package/dist/{chunk-HITVBIJS.js → chunk-ZX7235KR.js} +128 -54
- package/dist/{chunk-GT4I4ZWM.js → chunk-ZZFHLRQW.js} +18 -16
- package/dist/files.json +636 -364
- package/dist/packages/naysayer/constitution/constitution.yaml +19 -0
- package/dist/packages/sdk/npm/index.js +5614 -2343
- package/dist/packages/ui/dist/assets/{elk-api-tma0MCuh.js → elk-api-CowTnhEJ.js} +2 -2
- package/dist/packages/ui/dist/assets/index-Dw20IRhQ.css +1 -0
- package/dist/packages/ui/dist/assets/index-z2wv0d5d.js +47 -0
- package/dist/packages/ui/dist/index.html +2 -2
- package/package.json +4 -4
- 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-RVH5SUW5.js +0 -69
- package/dist/chunk-VN3DP4LQ.js +0 -43
- 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
|
@@ -3,57 +3,88 @@ 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
|
+
componentTypeIds,
|
|
8
|
+
componentTypesAt
|
|
9
|
+
} from "./chunk-L4CESDPB.js";
|
|
10
|
+
import {
|
|
11
|
+
modelsData,
|
|
12
|
+
modelsLine,
|
|
13
|
+
reachHeadOf,
|
|
14
|
+
reachPlanOf,
|
|
15
|
+
readPathsOf
|
|
16
|
+
} from "./chunk-455SYIIE.js";
|
|
17
|
+
import {
|
|
18
|
+
houseUntaughtLines,
|
|
19
|
+
houseUntaughtOf
|
|
20
|
+
} from "./chunk-3J5I7ZOU.js";
|
|
21
|
+
import {
|
|
22
|
+
effectiveRules,
|
|
23
|
+
notesAt,
|
|
24
|
+
readingRulesText,
|
|
25
|
+
ruleIds
|
|
26
|
+
} from "./chunk-GIFMBCTW.js";
|
|
6
27
|
import {
|
|
7
28
|
loadReadPlan,
|
|
29
|
+
modelsModeOf,
|
|
8
30
|
partOfWords,
|
|
9
31
|
readPlanProgress,
|
|
10
32
|
readPlanRelOf,
|
|
33
|
+
recordNotReached,
|
|
34
|
+
saveReadPlan,
|
|
11
35
|
writeReadPlan
|
|
12
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-MD7KUEJ3.js";
|
|
13
37
|
import {
|
|
14
38
|
carryOf,
|
|
15
39
|
checkoutOf,
|
|
40
|
+
conventionsAt,
|
|
41
|
+
estateComponentsOf,
|
|
16
42
|
excludesOf,
|
|
17
43
|
headOf,
|
|
18
44
|
raiseReadQuestions,
|
|
19
45
|
readCorrections,
|
|
20
46
|
readReviewed,
|
|
21
47
|
reviewedProblemsOf,
|
|
48
|
+
slipNoteLines,
|
|
22
49
|
writeVerifyFiles
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-O3WI5KWW.js";
|
|
50
|
+
} from "./chunk-Q46QDDMF.js";
|
|
25
51
|
import {
|
|
26
52
|
ABOUT_RULE,
|
|
53
|
+
MODELS_RULE,
|
|
54
|
+
RULE_SETS,
|
|
27
55
|
assistantTier,
|
|
28
56
|
mapBatchInstructions,
|
|
29
57
|
readProbes,
|
|
58
|
+
rulesNow,
|
|
59
|
+
taughtFrameworksText,
|
|
30
60
|
tierSource,
|
|
31
61
|
tierWords
|
|
32
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-3AQ2R5NL.js";
|
|
33
63
|
import {
|
|
34
64
|
FILE_KINDS,
|
|
35
|
-
SESSION_TOKENS,
|
|
36
65
|
SHOWN_PROPOSALS,
|
|
37
66
|
dirSource,
|
|
38
67
|
exclusionYaml,
|
|
39
68
|
frameworkTopics,
|
|
40
69
|
frameworkTopicsOfType,
|
|
41
70
|
kindsOf,
|
|
71
|
+
lineRangeOf,
|
|
42
72
|
numberedSlice,
|
|
43
73
|
onlyFiles,
|
|
44
74
|
planBatches,
|
|
45
75
|
planParts,
|
|
46
76
|
proposeExclusions,
|
|
77
|
+
repairFormSlips,
|
|
47
78
|
rereadPlan,
|
|
48
79
|
sameCommit,
|
|
80
|
+
sessionTokensFor,
|
|
49
81
|
sliceText,
|
|
50
82
|
staleMessage,
|
|
51
83
|
verifyFacts
|
|
52
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-JYMIB5XY.js";
|
|
53
85
|
import {
|
|
54
86
|
loadRepos
|
|
55
|
-
} from "./chunk-
|
|
56
|
-
import "./chunk-GQ4N4WKF.js";
|
|
87
|
+
} from "./chunk-XOL3GFW2.js";
|
|
57
88
|
import {
|
|
58
89
|
DATA_RULE,
|
|
59
90
|
HandoffRuntime,
|
|
@@ -63,32 +94,36 @@ import {
|
|
|
63
94
|
estimateTokens,
|
|
64
95
|
promptBudget,
|
|
65
96
|
wrapData
|
|
66
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-QHJJMZLX.js";
|
|
67
98
|
import {
|
|
68
99
|
AgentDefinition,
|
|
69
100
|
Fact,
|
|
70
101
|
REPO_DESCRIPTION_MAX,
|
|
71
102
|
citedFiles,
|
|
103
|
+
componentTypesText,
|
|
104
|
+
conventionsOf,
|
|
72
105
|
descriptionNote,
|
|
73
106
|
descriptionTrust,
|
|
74
107
|
factsDirOf,
|
|
75
108
|
factsRelOf,
|
|
76
109
|
listQuestions,
|
|
77
110
|
loadOrgPack,
|
|
111
|
+
normalizeFactPaths,
|
|
112
|
+
notesText,
|
|
78
113
|
orgPackDirOf,
|
|
79
114
|
parseFacts,
|
|
80
115
|
runsDirOf,
|
|
81
|
-
saysNotProduct
|
|
82
|
-
|
|
116
|
+
saysNotProduct,
|
|
117
|
+
stackHelpersOff
|
|
118
|
+
} from "./chunk-PAINMSID.js";
|
|
83
119
|
import {
|
|
84
120
|
writeFileAtomic
|
|
85
|
-
} from "./chunk-
|
|
86
|
-
import "./chunk-TV45EUGM.js";
|
|
121
|
+
} from "./chunk-ODMBPDDV.js";
|
|
87
122
|
|
|
88
123
|
// packages/cli/dist/map-commands.js
|
|
89
124
|
import { existsSync } from "node:fs";
|
|
90
125
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
91
|
-
import { dirname, join, relative } from "node:path";
|
|
126
|
+
import { dirname, join, relative, sep } from "node:path";
|
|
92
127
|
var REPO_READER = "repo-reader";
|
|
93
128
|
var OUTPUT = "facts.jsonl";
|
|
94
129
|
var KEPT_RESERVE = 1500;
|
|
@@ -115,6 +150,9 @@ var plural = (n, w) => `${n} ${w}${n === 1 ? "" : "s"}`;
|
|
|
115
150
|
var batches = (n) => `${n} ${n === 1 ? "batch" : "batches"}`;
|
|
116
151
|
var changeOf = (repo) => `map-${repo}`;
|
|
117
152
|
var stateFile = (root, repo) => join(runsDirOf(root), changeOf(repo), "state.json");
|
|
153
|
+
async function mapStateOf(root, repo) {
|
|
154
|
+
return readState(root, repo).catch(() => void 0);
|
|
155
|
+
}
|
|
118
156
|
async function readState(root, repo) {
|
|
119
157
|
const text = await readFile(stateFile(root, repo), "utf8").catch(() => void 0);
|
|
120
158
|
return text ? JSON.parse(text) : void 0;
|
|
@@ -151,7 +189,7 @@ var overheadOf = (repo, commit, frameworks) => {
|
|
|
151
189
|
return (kinds) => instructionTokens(repo, commit, kinds, frameworks) - core;
|
|
152
190
|
};
|
|
153
191
|
async function frameworksFor(root, repo, facts) {
|
|
154
|
-
const fromFacts = frameworkTopics(facts);
|
|
192
|
+
const fromFacts = frameworkTopics(facts, (await conventionsAt(root)).frameworks);
|
|
155
193
|
if (fromFacts)
|
|
156
194
|
return fromFacts;
|
|
157
195
|
const type = (await loadRepos(root).catch(() => [])).find((r) => r.id === repo)?.type;
|
|
@@ -175,12 +213,17 @@ function claimOf(f) {
|
|
|
175
213
|
return `${f.name}${f.version ? ` ${f.version}` : ""}`;
|
|
176
214
|
case "flow":
|
|
177
215
|
return f.name;
|
|
216
|
+
case "term":
|
|
217
|
+
return `${f.term} ${f.value} (${f.role})`;
|
|
218
|
+
case "component":
|
|
219
|
+
return `${f.component ?? f.repo} is a ${f.type}`;
|
|
178
220
|
}
|
|
179
221
|
}
|
|
180
|
-
function readAnswer(text, repo, commit) {
|
|
222
|
+
function readAnswer(text, repo, commit, onFile = []) {
|
|
181
223
|
const facts = /* @__PURE__ */ new Map();
|
|
182
224
|
const questions = [];
|
|
183
225
|
const problems = [];
|
|
226
|
+
const refused = [];
|
|
184
227
|
let about;
|
|
185
228
|
text.split(/\r?\n/).forEach((raw, i) => {
|
|
186
229
|
const line = raw.trim();
|
|
@@ -190,14 +233,17 @@ function readAnswer(text, repo, commit) {
|
|
|
190
233
|
try {
|
|
191
234
|
json = JSON.parse(line);
|
|
192
235
|
} catch {
|
|
193
|
-
problems.push(
|
|
236
|
+
problems.push({
|
|
237
|
+
line: i + 1,
|
|
238
|
+
message: `line ${i + 1} is not one JSON object: ${line.slice(0, 80)}`
|
|
239
|
+
});
|
|
194
240
|
return;
|
|
195
241
|
}
|
|
196
242
|
if (!json || typeof json !== "object" || Array.isArray(json)) {
|
|
197
|
-
problems.push(`line ${i + 1} is not one JSON object`);
|
|
243
|
+
problems.push({ line: i + 1, message: `line ${i + 1} is not one JSON object` });
|
|
198
244
|
return;
|
|
199
245
|
}
|
|
200
|
-
const o = json;
|
|
246
|
+
const o = normalizeFactPaths(json);
|
|
201
247
|
if ("question" in o && !("kind" in o)) {
|
|
202
248
|
questions.push(o);
|
|
203
249
|
return;
|
|
@@ -205,7 +251,10 @@ function readAnswer(text, repo, commit) {
|
|
|
205
251
|
if ("about" in o && !("kind" in o)) {
|
|
206
252
|
const text2 = typeof o.about === "string" ? o.about.trim() : "";
|
|
207
253
|
if (!text2) {
|
|
208
|
-
problems.push(
|
|
254
|
+
problems.push({
|
|
255
|
+
line: i + 1,
|
|
256
|
+
message: `line ${i + 1}: "about" needs one line saying what the repo is`
|
|
257
|
+
});
|
|
209
258
|
return;
|
|
210
259
|
}
|
|
211
260
|
const cites = (Array.isArray(o.cites) ? o.cites : []).flatMap((c) => {
|
|
@@ -213,19 +262,43 @@ function readAnswer(text, repo, commit) {
|
|
|
213
262
|
return typeof x.file === "string" && Number.isInteger(x.line) && Number(x.line) > 0 ? [{ file: x.file, line: Number(x.line) }] : [];
|
|
214
263
|
}).slice(0, 6);
|
|
215
264
|
if (!cites.length) {
|
|
216
|
-
problems.push(
|
|
265
|
+
problems.push({
|
|
266
|
+
line: i + 1,
|
|
267
|
+
message: `line ${i + 1}: "about" needs "cites": the file and line it was read from, as a fact cites its line`
|
|
268
|
+
});
|
|
217
269
|
return;
|
|
218
270
|
}
|
|
219
271
|
about ??= { text: text2.slice(0, REPO_DESCRIPTION_MAX), cites };
|
|
220
272
|
return;
|
|
221
273
|
}
|
|
222
|
-
const
|
|
274
|
+
const marked = { repo, commit, ...o, verified: "none", by: "assistant" };
|
|
275
|
+
const r = Fact.safeParse(marked);
|
|
223
276
|
if (r.success)
|
|
224
277
|
facts.set(r.data.id, r.data);
|
|
225
278
|
else
|
|
226
|
-
|
|
279
|
+
refused.push({
|
|
280
|
+
line: i + 1,
|
|
281
|
+
raw: JSON.stringify(marked),
|
|
282
|
+
issues: [
|
|
283
|
+
{
|
|
284
|
+
line: i + 1,
|
|
285
|
+
code: "schema",
|
|
286
|
+
message: `line ${i + 1}${typeof o.id === "string" ? ` (${o.id})` : ""}: ${r.error.issues.map((x) => `${x.path.join(".") || "(fact)"}: ${x.message}`).join("; ")}`
|
|
287
|
+
}
|
|
288
|
+
]
|
|
289
|
+
});
|
|
227
290
|
});
|
|
228
|
-
|
|
291
|
+
const repaired = repairFormSlips([...facts.values()], refused, onFile);
|
|
292
|
+
for (const b of repaired.bad)
|
|
293
|
+
problems.push({ line: b.line, message: b.issues.map((x) => x.message).join("; ") });
|
|
294
|
+
problems.sort((x, y) => x.line - y.line);
|
|
295
|
+
return {
|
|
296
|
+
facts: repaired.facts,
|
|
297
|
+
questions,
|
|
298
|
+
problems: problems.map((x) => x.message),
|
|
299
|
+
slips: repaired.slips,
|
|
300
|
+
...about ? { about } : {}
|
|
301
|
+
};
|
|
229
302
|
}
|
|
230
303
|
function rejectedText(r, source) {
|
|
231
304
|
const text = source.read(r.fact.cite.file);
|
|
@@ -241,10 +314,26 @@ function rejectedText(r, source) {
|
|
|
241
314
|
] : []
|
|
242
315
|
].join("\n");
|
|
243
316
|
}
|
|
244
|
-
function
|
|
317
|
+
async function rulesCovering(root, repo, op) {
|
|
318
|
+
const type = op.profiles.flatMap((p) => p.repos?.repos ?? []).find((r) => r.id === repo)?.type;
|
|
319
|
+
const all = (await listQuestions(root, { state: "answered" }).catch(() => ({ questions: [] }))).questions;
|
|
320
|
+
return all.filter((q) => q.repo !== repo && !!q.answer?.match && (q.answer.scope.level === "repo" ? q.answer.scope.id === repo : !!type && q.answer.scope.id === type)).map((q) => ({
|
|
321
|
+
id: q.id,
|
|
322
|
+
from: q.repo,
|
|
323
|
+
match: q.answer.match,
|
|
324
|
+
answer: q.answer.text ?? q.options[(q.answer.option ?? 1) - 1]?.label ?? "",
|
|
325
|
+
scope: q.answer.scope.level === "repo" ? repo : `every ${q.answer.scope.id} repo`
|
|
326
|
+
})).sort((a, b) => a.id.localeCompare(b.id));
|
|
327
|
+
}
|
|
328
|
+
var ruleLineOf = (r) => `Rule ${r.id} (answered for ${r.from}, covers ${r.scope}): the calls matching ${r.match} go to ${r.answer}.`;
|
|
329
|
+
function questionsText(qs, rules = []) {
|
|
245
330
|
return [
|
|
246
331
|
"Questions already on file for this repo. Don't ask them again; follow each answer a person gave.",
|
|
247
|
-
...qs.map((q) => `- ${q.question} (${q.evidence.join(", ")}): ${q.state === "answered" ? `answered: ${q.answer?.text ?? q.options[(q.answer?.option ?? 1) - 1]?.label ?? ""}` : "waiting for a person"}`)
|
|
332
|
+
...qs.map((q) => `- ${q.question} (${q.evidence.join(", ")}): ${q.state === "answered" ? `answered: ${q.answer?.text ?? q.options[(q.answer?.option ?? 1) - 1]?.label ?? ""}` : "waiting for a person"}`),
|
|
333
|
+
...rules.length ? [
|
|
334
|
+
"Answers by rule that cover this repo, from other repos' questions. A call one matches goes where it says: don't ask about it.",
|
|
335
|
+
...rules.map((r) => `- ${ruleLineOf(r)}`)
|
|
336
|
+
] : []
|
|
248
337
|
].join("\n");
|
|
249
338
|
}
|
|
250
339
|
function keptText(facts, budgetTokens) {
|
|
@@ -282,15 +371,44 @@ function rereadInstructions(s) {
|
|
|
282
371
|
"Write a fact for anything new in the changed files, as in a first read."
|
|
283
372
|
].join("\n");
|
|
284
373
|
}
|
|
285
|
-
async function rereadOf(dir, facts, commit, source, exclude, git) {
|
|
374
|
+
async function rereadOf(dir, facts, commit, source, exclude, git, conventions) {
|
|
286
375
|
if (!facts.some((f) => !sameCommit(f.commit, commit)))
|
|
287
376
|
return { missing: [] };
|
|
288
377
|
const { carry, missing } = await carryOf(dir, facts, commit, git);
|
|
289
378
|
if (!Object.keys(carry).length)
|
|
290
379
|
return { missing };
|
|
291
|
-
return {
|
|
380
|
+
return {
|
|
381
|
+
plan: rereadPlan({
|
|
382
|
+
facts,
|
|
383
|
+
commit,
|
|
384
|
+
carry,
|
|
385
|
+
source,
|
|
386
|
+
exclude,
|
|
387
|
+
...conventions ? { conventions } : {}
|
|
388
|
+
}),
|
|
389
|
+
missing
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
var taughtOption = (models) => {
|
|
393
|
+
const taught = taughtFrameworksText(models);
|
|
394
|
+
return taught ? { taught } : {};
|
|
395
|
+
};
|
|
396
|
+
var BUILD_FILE = /(^|\/)(pom\.xml|build\.gradle(\.kts)?|package\.json|[^/]+\.csproj|requirements[^/]*\.txt|pyproject\.toml|go\.mod)$/;
|
|
397
|
+
function taughtIn(source, op) {
|
|
398
|
+
if (stackHelpersOff().has("framework-models"))
|
|
399
|
+
return [];
|
|
400
|
+
const models = op.frameworks.filter((m) => m.artifacts.length);
|
|
401
|
+
if (!models.length)
|
|
402
|
+
return [];
|
|
403
|
+
const texts = source.list().filter((p) => BUILD_FILE.test(p)).map((p) => source.read(p) ?? "");
|
|
404
|
+
const esc = (x) => x.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
405
|
+
return models.filter((m) => m.artifacts.some((a) => {
|
|
406
|
+
const artifact = a.split(":")[1] ?? a;
|
|
407
|
+
const declared = new RegExp(`<artifactId>\\s*${esc(artifact)}\\s*</artifactId>|["':]${esc(artifact)}["':@]`);
|
|
408
|
+
return texts.some((t) => declared.test(t));
|
|
409
|
+
}));
|
|
292
410
|
}
|
|
293
|
-
async function packFor(root, s, batch, source, op, now) {
|
|
411
|
+
async function packFor(root, s, batch, source, op, now, notes) {
|
|
294
412
|
const agent = repoReaderAgent(op);
|
|
295
413
|
const budget = op.runtime.budgets.perAgent[agent.id] ?? agent.tokenBudget;
|
|
296
414
|
const fix = batch >= s.batches.length;
|
|
@@ -299,7 +417,14 @@ async function packFor(root, s, batch, source, op, now) {
|
|
|
299
417
|
const kept = await readFactsFile(root, s.repo);
|
|
300
418
|
const facts = typeof kept === "string" ? [] : kept;
|
|
301
419
|
const onFile = (await listQuestions(root, { repo: s.repo })).questions.filter((q) => q.state !== "retired");
|
|
420
|
+
const rules = await rulesCovering(root, s.repo, op);
|
|
302
421
|
const slices = fix ? [] : s.batches[batch];
|
|
422
|
+
const inBatch = new Set(slices.map((x) => x.path));
|
|
423
|
+
const reachedHere = (s.reached ?? []).filter((r) => inBatch.has(r.path));
|
|
424
|
+
const models = reachedHere.length ? [
|
|
425
|
+
"Model classes in this batch the entry points and calls reach (read these, and write their fields):",
|
|
426
|
+
...reachedHere.map((r) => `- ${r.path} (${r.types.join(", ")}), from ${r.from}`)
|
|
427
|
+
].join("\n") : void 0;
|
|
303
428
|
const rejected = s.rejected.map((r) => rejectedText(r, source));
|
|
304
429
|
const own = kindsOf(slices.map((x) => x.path));
|
|
305
430
|
const theirs = kindsOf(s.rejected.flatMap((r) => citedFiles(r.fact)));
|
|
@@ -322,11 +447,31 @@ async function packFor(root, s, batch, source, op, now) {
|
|
|
322
447
|
// build files are read first, so from the second batch on this is what the code says.
|
|
323
448
|
frameworks: await frameworksFor(root, s.repo, facts),
|
|
324
449
|
// Nothing says what this repo is: ask for one line, cited, for a person to confirm.
|
|
325
|
-
...about ? {} : { askAbout: true }
|
|
450
|
+
...about || s.sets ? {} : { askAbout: true },
|
|
451
|
+
// ADR 0167: a top-up carries only the rule sets the read lacked.
|
|
452
|
+
...s.sets ? {
|
|
453
|
+
sets: s.sets.filter((x) => RULE_SETS.includes(x))
|
|
454
|
+
} : {},
|
|
455
|
+
// A-taught: how to read the wrapper calls and annotations of the frameworks it is built on.
|
|
456
|
+
...taughtOption(taughtIn(source, op)),
|
|
457
|
+
// ADR 0163: what the organisation's terms mean here and what must hold, as data.
|
|
458
|
+
...notes ? { notes } : {},
|
|
459
|
+
// ADR 0169: the model classes of this batch the read reaches, listed beside it.
|
|
460
|
+
...models ? { models: true } : {}
|
|
326
461
|
}),
|
|
327
462
|
classification: "public",
|
|
328
463
|
trusted: true
|
|
329
464
|
},
|
|
465
|
+
...models ? [
|
|
466
|
+
{
|
|
467
|
+
id: "1-models",
|
|
468
|
+
kind: "document",
|
|
469
|
+
origin: "atticus/reachable",
|
|
470
|
+
text: models,
|
|
471
|
+
classification: "internal",
|
|
472
|
+
priority: 9
|
|
473
|
+
}
|
|
474
|
+
] : [],
|
|
330
475
|
...s.reread ? [
|
|
331
476
|
{
|
|
332
477
|
id: "0-reread",
|
|
@@ -366,12 +511,12 @@ ${s.problems.map((p) => `- ${p}`).join("\n")}`,
|
|
|
366
511
|
priority: 5
|
|
367
512
|
}
|
|
368
513
|
] : [],
|
|
369
|
-
...onFile.length ? [
|
|
514
|
+
...onFile.length || rules.length ? [
|
|
370
515
|
{
|
|
371
516
|
id: "4-questions",
|
|
372
517
|
kind: "document",
|
|
373
518
|
origin: "questions/",
|
|
374
|
-
text: questionsText(onFile),
|
|
519
|
+
text: questionsText(onFile, rules),
|
|
375
520
|
classification: "internal",
|
|
376
521
|
priority: 4
|
|
377
522
|
}
|
|
@@ -443,9 +588,60 @@ async function mapCommand(root, repo, o, io, deps = {}) {
|
|
|
443
588
|
return 2;
|
|
444
589
|
}
|
|
445
590
|
const op = await loadOrgPack(orgPackDirOf(root));
|
|
591
|
+
const conventions = conventionsOf(op);
|
|
446
592
|
const source = dirSource(dir);
|
|
447
593
|
const exclude = await excludesOf(root, repo);
|
|
448
594
|
const factsFile = `${factsRelOf(root)}/${repo}.jsonl`;
|
|
595
|
+
const repoNotes = await notesAt(root, repo, dir, op);
|
|
596
|
+
const orgRules = await effectiveRules(root, repo, { dir, op });
|
|
597
|
+
const notesPrompt = [
|
|
598
|
+
notesText(repoNotes.notes, repoNotes.type),
|
|
599
|
+
readingRulesText(orgRules),
|
|
600
|
+
// ADR 0180: the component types, the same for every batch.
|
|
601
|
+
componentTypesText(await componentTypesAt(root, op))
|
|
602
|
+
].filter(Boolean).join("\n\n");
|
|
603
|
+
if (o.gaps) {
|
|
604
|
+
const { mapGaps } = await import("./chunk-Q26LDIUV.js");
|
|
605
|
+
const tier = await tierHere(root, op);
|
|
606
|
+
let part;
|
|
607
|
+
if (o.part !== void 0) {
|
|
608
|
+
const p = (await readPlanProgress(root, repo))?.parts.find((x) => x.part === o.part);
|
|
609
|
+
if (!p) {
|
|
610
|
+
io.err(`${repo}'s read plan has no part ${o.part} (${readPlanRelOf(root, repo)}): atticus map ${repo} --estimate plans it.`);
|
|
611
|
+
return 2;
|
|
612
|
+
}
|
|
613
|
+
part = {
|
|
614
|
+
n: p.part,
|
|
615
|
+
left: [...p.paths.filter((g) => !lineRangeOf(g)), ...p.left.filter((g) => lineRangeOf(g))]
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
return mapGaps(root, repo, {
|
|
619
|
+
commit,
|
|
620
|
+
source,
|
|
621
|
+
session: sessionTokensFor(limitOf(o, op, tier).limit),
|
|
622
|
+
checkout: relative(root, dir).split(sep).join("/") || ".",
|
|
623
|
+
...o.json ? { json: true } : {},
|
|
624
|
+
...part ? { part } : {},
|
|
625
|
+
...o.models ? { models: o.models } : {},
|
|
626
|
+
exclude,
|
|
627
|
+
conventions
|
|
628
|
+
}, io);
|
|
629
|
+
}
|
|
630
|
+
if (o.rules && !deps.runtime) {
|
|
631
|
+
const { mapRules } = await import("./chunk-TJH2EUAZ.js");
|
|
632
|
+
const tier = await tierHere(root, op);
|
|
633
|
+
return mapRules(root, repo, {
|
|
634
|
+
commit,
|
|
635
|
+
source,
|
|
636
|
+
exclude,
|
|
637
|
+
conventions,
|
|
638
|
+
session: sessionTokensFor(limitOf(o, op, tier).limit),
|
|
639
|
+
notes: notesPrompt,
|
|
640
|
+
checkout: relative(root, dir).split(sep).join("/") || ".",
|
|
641
|
+
...o.json ? { json: true } : {},
|
|
642
|
+
...o.models ? { models: o.models } : {}
|
|
643
|
+
}, io);
|
|
644
|
+
}
|
|
449
645
|
if (o.estimate)
|
|
450
646
|
return estimate(root, repo, { o, op, dir, commit, source, exclude, factsFile, ...deps.git ? { git: deps.git } : {} }, io);
|
|
451
647
|
const runtime = deps.runtime;
|
|
@@ -518,44 +714,133 @@ async function mapCommand(root, repo, o, io, deps = {}) {
|
|
|
518
714
|
if (room < MIN_ROOM)
|
|
519
715
|
return tooSmall(0);
|
|
520
716
|
const frameworks = await frameworksFor(root, repo, existing);
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
717
|
+
if (o.rules) {
|
|
718
|
+
const { topUpOf, recordRulesNow, ruleSetsOfFiles } = await import("./chunk-TJH2EUAZ.js");
|
|
719
|
+
const t = await topUpOf(root, repo, {
|
|
720
|
+
commit,
|
|
721
|
+
facts: existing,
|
|
722
|
+
source,
|
|
723
|
+
exclude,
|
|
724
|
+
conventions,
|
|
725
|
+
...o.models ? { models: o.models } : {}
|
|
726
|
+
});
|
|
727
|
+
if ("error" in t) {
|
|
728
|
+
io.err(t.error);
|
|
729
|
+
return 2;
|
|
730
|
+
}
|
|
731
|
+
if (!t.lacking.length) {
|
|
732
|
+
io.out(`${repo} was read under the reading rules there are now: nothing to top up.`);
|
|
733
|
+
return 0;
|
|
734
|
+
}
|
|
735
|
+
if (!t.files.length) {
|
|
736
|
+
await recordRulesNow(root, repo, commit, t.lacking);
|
|
737
|
+
io.out(`No file of ${repo} is one the reading rules added since it was read apply to (${t.lacking.join(", ")}): its read is recorded as under the rules there are now.`);
|
|
738
|
+
return 0;
|
|
739
|
+
}
|
|
740
|
+
const sets = ruleSetsOfFiles(t.files);
|
|
741
|
+
const plan = planBatches(onlyFiles(source, t.files.map((f) => f.path)), { room, exclude, overhead: overheadOf(repo, commit, frameworks), conventions });
|
|
742
|
+
if (plan.leastRoom < MIN_ROOM)
|
|
743
|
+
return tooSmall(room - plan.leastRoom);
|
|
744
|
+
s = {
|
|
745
|
+
schemaVersion: 1,
|
|
746
|
+
repo,
|
|
747
|
+
commit,
|
|
748
|
+
...limit ? { maxTokens: limit } : {},
|
|
749
|
+
room,
|
|
750
|
+
batches: plan.batches,
|
|
751
|
+
next: 0,
|
|
752
|
+
rejected: [],
|
|
753
|
+
problems: [],
|
|
754
|
+
sets,
|
|
755
|
+
// ADR 0169: the reached model classes, listed in the prompts of the batches holding them.
|
|
756
|
+
...t.reach?.reach.rooted && t.reach.reach.reached.length ? {
|
|
757
|
+
reached: t.reach.reach.reached.map((r) => ({
|
|
758
|
+
path: r.path,
|
|
759
|
+
types: r.types,
|
|
760
|
+
from: r.from
|
|
761
|
+
}))
|
|
762
|
+
} : {}
|
|
763
|
+
};
|
|
764
|
+
if (t.reach)
|
|
765
|
+
await recordNotReached(root, repo, {
|
|
766
|
+
commit,
|
|
767
|
+
session: sessionTokensFor(limit),
|
|
768
|
+
models: t.reach.mode,
|
|
769
|
+
...t.reach.notReached ? { notReached: t.reach.notReached } : {}
|
|
770
|
+
});
|
|
771
|
+
await saveState(root, s);
|
|
772
|
+
io.out(`Topping up ${repo} at ${commit.slice(0, 12)} for the reading rules added since it was read (${sets.join(", ")}): ${plural(plan.files, "source file")} in ${batches(plan.batches.length)}; facts go to ${factsFile}.`);
|
|
773
|
+
} else {
|
|
774
|
+
const re = await rereadOf(dir, existing, commit, source, exclude, deps.git, conventions);
|
|
775
|
+
const reread = re.plan && !re.plan.unknown.length ? re.plan : void 0;
|
|
776
|
+
const since = reread?.from.map((x) => x.commit.slice(0, 12)).join(", ");
|
|
777
|
+
if (reread && !reread.files.length && !reread.reread.length) {
|
|
778
|
+
io.out(`Nothing ${repo}'s facts cite changed since ${since}, and no source file did: atticus verify ${repo} carries its ${plural(reread.carried, "fact")} to ${commit.slice(0, 12)}.`);
|
|
779
|
+
return 0;
|
|
780
|
+
}
|
|
781
|
+
const mode = await modelsModeOf(root, repo, o.models);
|
|
782
|
+
const rp = reread ? void 0 : reachPlanOf({
|
|
783
|
+
paths: readPathsOf(source, exclude, conventions),
|
|
784
|
+
source,
|
|
785
|
+
facts: existing,
|
|
786
|
+
mode
|
|
787
|
+
});
|
|
788
|
+
const plan = planBatches(reread ? onlyFiles(source, reread.files.map((f) => f.path)) : source, {
|
|
789
|
+
room,
|
|
790
|
+
exclude,
|
|
791
|
+
overhead: overheadOf(repo, commit, frameworks),
|
|
792
|
+
conventions,
|
|
793
|
+
...rp?.reach.rooted && rp.reach.models ? { reach: { first: rp.first, leaveOut: rp.leaveOut } } : {}
|
|
794
|
+
});
|
|
795
|
+
if (plan.leastRoom < MIN_ROOM)
|
|
796
|
+
return tooSmall(room - plan.leastRoom);
|
|
797
|
+
if (!plan.batches.length && !reread) {
|
|
798
|
+
io.out(`${repo} has no source files to read${plan.excluded.length ? ` (${plural(plan.excluded.length, "file")} excluded)` : ""}.`);
|
|
799
|
+
return 0;
|
|
800
|
+
}
|
|
801
|
+
const byId = new Map(existing.map((f) => [f.id, f]));
|
|
802
|
+
s = {
|
|
803
|
+
schemaVersion: 1,
|
|
804
|
+
repo,
|
|
805
|
+
commit,
|
|
806
|
+
...limit ? { maxTokens: limit } : {},
|
|
807
|
+
room,
|
|
808
|
+
batches: plan.batches,
|
|
809
|
+
next: 0,
|
|
810
|
+
rejected: (reread?.reread ?? []).map((r) => {
|
|
811
|
+
const fact = byId.get(r.id);
|
|
812
|
+
return { id: r.id, code: "cite-changed", message: staleMessage(fact, r, commit), fact };
|
|
813
|
+
}),
|
|
814
|
+
problems: [],
|
|
815
|
+
...rp?.reach.rooted && rp.reach.reached.length ? {
|
|
816
|
+
reached: rp.reach.reached.map((r) => ({
|
|
817
|
+
path: r.path,
|
|
818
|
+
types: r.types,
|
|
819
|
+
from: r.from
|
|
820
|
+
}))
|
|
821
|
+
} : {},
|
|
822
|
+
...reread ? {
|
|
823
|
+
reread: {
|
|
824
|
+
from: reread.from.map((x) => x.commit),
|
|
825
|
+
carried: reread.carried,
|
|
826
|
+
facts: reread.reread.length
|
|
827
|
+
}
|
|
828
|
+
} : {}
|
|
829
|
+
};
|
|
830
|
+
await saveState(root, s);
|
|
831
|
+
if (rp)
|
|
832
|
+
await recordNotReached(root, repo, {
|
|
833
|
+
commit,
|
|
834
|
+
session: sessionTokensFor(limit),
|
|
835
|
+
models: mode,
|
|
836
|
+
...rp.notReached ? { notReached: rp.notReached } : {}
|
|
837
|
+
});
|
|
838
|
+
if (rp?.clientOnly.length)
|
|
839
|
+
io.out(`${rp.clientOnly.length} model ${rp.clientOnly.length === 1 ? "class" : "classes"} only an outbound client reaches are left out (ADR 0170, --models entries; recorded in ${readPlanRelOf(root, repo)}): atticus map ${repo} --models reachable reads them.`);
|
|
840
|
+
if (rp && rp.leaveOut.length > rp.clientOnly.length)
|
|
841
|
+
io.out(`${rp.leaveOut.length - rp.clientOnly.length} model ${rp.leaveOut.length - rp.clientOnly.length === 1 ? "class" : "classes"} no entry or call reaches are left out (ADR 0169; recorded in ${readPlanRelOf(root, repo)}): atticus map ${repo} --models all reads them.`);
|
|
842
|
+
io.out(reread ? `Re-reading ${repo} at ${commit.slice(0, 12)}: ${plural(plan.files, "source file")} changed since ${since}, in ${batches(plan.batches.length)}${plan.batches.length ? ` (about ${plan.tokens} tokens${limit ? `, each prompt within ${limit} tokens` : ""})` : ""}; ${plural(reread.reread.length, "fact")} to rewrite, ${reread.carried} carried as they are; facts go to ${factsFile}.` : `Reading ${repo} at ${commit.slice(0, 12)} in ${batches(plan.batches.length)} (${plural(plan.files, "source file")}, about ${plan.tokens} tokens${limit ? `, each prompt within ${limit} tokens` : ""}); facts go to ${factsFile}.`);
|
|
534
843
|
}
|
|
535
|
-
const byId = new Map(existing.map((f) => [f.id, f]));
|
|
536
|
-
s = {
|
|
537
|
-
schemaVersion: 1,
|
|
538
|
-
repo,
|
|
539
|
-
commit,
|
|
540
|
-
...limit ? { maxTokens: limit } : {},
|
|
541
|
-
room,
|
|
542
|
-
batches: plan.batches,
|
|
543
|
-
next: 0,
|
|
544
|
-
rejected: (reread?.reread ?? []).map((r) => {
|
|
545
|
-
const fact = byId.get(r.id);
|
|
546
|
-
return { id: r.id, code: "cite-changed", message: staleMessage(fact, r, commit), fact };
|
|
547
|
-
}),
|
|
548
|
-
problems: [],
|
|
549
|
-
...reread ? {
|
|
550
|
-
reread: {
|
|
551
|
-
from: reread.from.map((x) => x.commit),
|
|
552
|
-
carried: reread.carried,
|
|
553
|
-
facts: reread.reread.length
|
|
554
|
-
}
|
|
555
|
-
} : {}
|
|
556
|
-
};
|
|
557
|
-
await saveState(root, s);
|
|
558
|
-
io.out(reread ? `Re-reading ${repo} at ${commit.slice(0, 12)}: ${plural(plan.files, "source file")} changed since ${since}, in ${batches(plan.batches.length)}${plan.batches.length ? ` (about ${plan.tokens} tokens${limit ? `, each prompt within ${limit} tokens` : ""})` : ""}; ${plural(reread.reread.length, "fact")} to rewrite, ${reread.carried} carried as they are; facts go to ${factsFile}.` : `Reading ${repo} at ${commit.slice(0, 12)} in ${batches(plan.batches.length)} (${plural(plan.files, "source file")}, about ${plan.tokens} tokens${limit ? `, each prompt within ${limit} tokens` : ""}); facts go to ${factsFile}.`);
|
|
559
844
|
}
|
|
560
845
|
if (!s)
|
|
561
846
|
return 2;
|
|
@@ -565,7 +850,7 @@ async function mapCommand(root, repo, o, io, deps = {}) {
|
|
|
565
850
|
break;
|
|
566
851
|
if (fixRound)
|
|
567
852
|
s.fixRound = true;
|
|
568
|
-
const { agent, pack } = await packFor(root, s, s.next, source, op, now());
|
|
853
|
+
const { agent, pack } = await packFor(root, s, s.next, source, op, now(), notesPrompt);
|
|
569
854
|
const prepared = await runtime.prepare({
|
|
570
855
|
change: changeOf(repo),
|
|
571
856
|
agent,
|
|
@@ -617,36 +902,50 @@ async function takeAnswer(root, s, run, batch, source, exclude, now, io, at) {
|
|
|
617
902
|
await saveState(root, { ...rest2, next: batch });
|
|
618
903
|
return 1;
|
|
619
904
|
}
|
|
620
|
-
const answer = readAnswer(run.output ?? "", s.repo, s.commit);
|
|
621
905
|
const existing = await readFactsFile(root, s.repo);
|
|
622
906
|
if (typeof existing === "string") {
|
|
623
907
|
io.err(existing);
|
|
624
908
|
return 2;
|
|
625
909
|
}
|
|
910
|
+
const answer = readAnswer(run.output ?? "", s.repo, s.commit, existing);
|
|
626
911
|
const merged = new Map(existing.map((f) => [f.id, f]));
|
|
627
912
|
for (const f of answer.facts)
|
|
628
913
|
merged.set(f.id, f);
|
|
629
914
|
const { carry } = await carryOf(at.dir, [...merged.values()], s.commit, at.git);
|
|
630
915
|
const reviewed = await readReviewed(root, s.repo);
|
|
916
|
+
const estate = await estateComponentsOf(root);
|
|
917
|
+
const off = stackHelpersOff();
|
|
631
918
|
const report = await verifyFacts({
|
|
632
919
|
facts: [...merged.values()],
|
|
633
920
|
source,
|
|
634
921
|
commit: s.commit,
|
|
922
|
+
// G4: the stack helpers this run switched off (ATTICUS_HELPERS_OFF).
|
|
923
|
+
...off.has("derived-names") ? { derivedNames: false } : {},
|
|
924
|
+
...off.has("readers") ? { readers: false } : {},
|
|
635
925
|
carry,
|
|
636
926
|
exclude,
|
|
637
927
|
// ADR 0124 addendum D-app: a person's corrections hold through every batch of a read.
|
|
638
928
|
corrections: (await readCorrections(root, s.repo)).corrections,
|
|
639
929
|
// ADR 0124 addendum A-read: files the reader read and found nothing in, if it wrote any.
|
|
640
|
-
reviewed: reviewed.entries
|
|
930
|
+
reviewed: reviewed.entries,
|
|
931
|
+
// J1 (ADR 0143): an exposure names a component the manifest lists.
|
|
932
|
+
...estate ? { estate } : {},
|
|
933
|
+
conventions: await conventionsAt(root),
|
|
934
|
+
// ADR 0163: a term's note is one of those the batch was handed.
|
|
935
|
+
notes: (await notesAt(root, s.repo, at.dir)).notes,
|
|
936
|
+
// ADR 0180: a component's type is one of the organisation's.
|
|
937
|
+
componentTypes: componentTypeIds(await componentTypesAt(root)),
|
|
938
|
+
// ADR 0169: the model files the read leaves out, counted apart.
|
|
939
|
+
notReached: (await loadReadPlan(root, s.repo))?.notReached?.files ?? []
|
|
641
940
|
});
|
|
642
941
|
const q = await raiseReadQuestions(root, s.repo, answer.questions, source, {
|
|
643
942
|
command: `atticus map ${s.repo}`,
|
|
644
943
|
run: run.runId,
|
|
645
944
|
at: now().toISOString()
|
|
646
945
|
});
|
|
647
|
-
const summary = await writeVerifyFiles(root, s.repo, report, s.commit, q.problems, [], reviewedProblemsOf(reviewed.bad, report));
|
|
946
|
+
const summary = await writeVerifyFiles(root, s.repo, report, s.commit, q.problems, [], reviewedProblemsOf(reviewed.bad, report), answer.slips);
|
|
648
947
|
if (answer.about) {
|
|
649
|
-
const { keepDraftedDescription } = await import("./chunk-
|
|
948
|
+
const { keepDraftedDescription } = await import("./chunk-TW3KOSQK.js");
|
|
650
949
|
const d = await keepDraftedDescription(root, s.repo, answer.about, now());
|
|
651
950
|
if (d.kept)
|
|
652
951
|
io.out(`Your assistant says ${s.repo} is: "${answer.about.text}" \u2014 written to the manifest as a draft, unconfirmed. Confirm it (atticus repo describe ${s.repo} --accept), change it (--description "...") or drop it (--reject).`);
|
|
@@ -656,6 +955,8 @@ async function takeAnswer(root, s, run, batch, source, exclude, now, io, at) {
|
|
|
656
955
|
const fresh = new Set(answer.facts.map((f) => f.id));
|
|
657
956
|
const kept = report.accepted.filter((f) => fresh.has(f.id)).length;
|
|
658
957
|
io.out(`${label}: ${plural(kept, "fact")} kept (${report.accepted.length} in all${report.carried.length ? `, ${report.carried.length} carried from an earlier commit` : ""}), ${report.rejected.length} rejected${q.raised.length ? `, ${plural(q.raised.length, "question")} raised for a person` : ""}${answer.problems.length ? `, ${plural(answer.problems.length, "line")} not read` : ""}.`);
|
|
958
|
+
for (const l of slipNoteLines(answer.slips, `${factsRelOf(root)}/${s.repo}.verify.yaml`))
|
|
959
|
+
io.out(l);
|
|
659
960
|
const { waiting: _w, ...rest } = s;
|
|
660
961
|
const rejected = report.rejected.map((r) => ({
|
|
661
962
|
id: r.fact.id,
|
|
@@ -677,6 +978,10 @@ async function finish(root, s, io, o) {
|
|
|
677
978
|
s.done = true;
|
|
678
979
|
await saveState(root, s);
|
|
679
980
|
const last = s.last;
|
|
981
|
+
if (last && !last.rejected && !s.reread) {
|
|
982
|
+
const { recordRulesNow } = await import("./chunk-TJH2EUAZ.js");
|
|
983
|
+
await recordRulesNow(root, s.repo, s.commit, s.sets);
|
|
984
|
+
}
|
|
680
985
|
const rel = factsRelOf(root);
|
|
681
986
|
if (o.json) {
|
|
682
987
|
io.out(JSON.stringify({ state: "done", repo: s.repo, batches: s.batches.length, ...last }, null, 2));
|
|
@@ -686,7 +991,7 @@ async function finish(root, s, io, o) {
|
|
|
686
991
|
io.out(`Read ${s.repo}: nothing was kept.`);
|
|
687
992
|
return 0;
|
|
688
993
|
}
|
|
689
|
-
io.out(`Read ${s.repo} in ${batches(s.batches.length)}: ${plural(last.accepted, "fact")} kept in ${rel}/${s.repo}.jsonl, ${last.rejected} still rejected; coverage ${Math.round(last.coverage.ratio * 100)}% (${last.coverage.read} read, ${last.coverage.reviewed ? `${last.coverage.reviewed} reviewed with nothing to record, ` : ""}${last.coverage.unknown.length} unknown).`);
|
|
994
|
+
io.out(`Read ${s.repo} in ${batches(s.batches.length)}: ${plural(last.accepted, "fact")} kept in ${rel}/${s.repo}.jsonl, ${last.rejected} still rejected; coverage ${Math.round(last.coverage.ratio * 100)}% (${last.coverage.read} read, ${last.coverage.reviewed ? `${last.coverage.reviewed} reviewed with nothing to record, ` : ""}${last.coverage.unknown.length} unknown${last.coverage.notReached?.length ? `, ${last.coverage.notReached.length} model files no entry or call reaches` : ""}).`);
|
|
690
995
|
if (last.rejected)
|
|
691
996
|
io.out(`The rejected facts are in ${rel}/${s.repo}.rejected.jsonl; fix them by hand or with your assistant, then atticus verify ${s.repo}.`);
|
|
692
997
|
if (last.coverage.unknown.length)
|
|
@@ -718,37 +1023,103 @@ function rereadLines(repo, r) {
|
|
|
718
1023
|
}
|
|
719
1024
|
async function estimate(root, repo, c, io) {
|
|
720
1025
|
const tier = await tierHere(root, c.op);
|
|
1026
|
+
const conventions = conventionsOf(c.op);
|
|
721
1027
|
const { limit: given, from } = limitOf(c.o, c.op, tier);
|
|
722
1028
|
const limit = given ?? EXAMPLE_LIMIT;
|
|
723
1029
|
const about = await aboutOf(root, repo);
|
|
724
1030
|
const room = roomFor(limit, c.op, repo, c.commit);
|
|
725
1031
|
const existing = await readFactsFile(root, repo);
|
|
726
|
-
const re = typeof existing === "string" ? { missing: [] } : await rereadOf(c.dir, existing, c.commit, c.source, c.exclude, c.git);
|
|
1032
|
+
const re = typeof existing === "string" ? { missing: [] } : await rereadOf(c.dir, existing, c.commit, c.source, c.exclude, c.git, conventions);
|
|
727
1033
|
const reread = re.plan && !re.plan.unknown.length ? re.plan : void 0;
|
|
728
1034
|
const readSource = reread ? onlyFiles(c.source, reread.files.map((f) => f.path)) : c.source;
|
|
729
|
-
const repoWhole = reread ? planBatches(c.source, { room: Number.MAX_SAFE_INTEGER, exclude: c.exclude }) : void 0;
|
|
730
|
-
const whole = planBatches(readSource, {
|
|
731
|
-
|
|
732
|
-
room,
|
|
1035
|
+
const repoWhole = reread ? planBatches(c.source, { room: Number.MAX_SAFE_INTEGER, exclude: c.exclude, conventions }) : void 0;
|
|
1036
|
+
const whole = planBatches(readSource, {
|
|
1037
|
+
room: Number.MAX_SAFE_INTEGER,
|
|
733
1038
|
exclude: c.exclude,
|
|
734
|
-
|
|
735
|
-
})
|
|
736
|
-
const plan = planned && planned.leastRoom >= MIN_ROOM ? planned : void 0;
|
|
1039
|
+
conventions
|
|
1040
|
+
});
|
|
737
1041
|
const files = whole.batches.flat().map((s) => ({ path: s.path, tokens: s.tokens }));
|
|
738
1042
|
const proposed = reread ? { proposals: [], before: whole.tokens, after: whole.tokens } : proposeExclusions(files, c.source.list(), (p) => c.source.read(p), {
|
|
739
1043
|
// What the person's description plainly says this repo holds (ADR 0128).
|
|
740
1044
|
saysNotProduct: saysNotProduct(about)
|
|
741
1045
|
});
|
|
742
1046
|
const left = proposed.proposals.map((p) => p.path.slice(0, -2));
|
|
743
|
-
const session =
|
|
744
|
-
const product = files.filter((f) => !left.some((d) => f.path.startsWith(d)))
|
|
745
|
-
|
|
1047
|
+
const session = sessionTokensFor(given);
|
|
1048
|
+
const product = files.filter((f) => !left.some((d) => f.path.startsWith(d))).map((f) => {
|
|
1049
|
+
if (f.tokens <= session)
|
|
1050
|
+
return f;
|
|
1051
|
+
const text = c.source.read(f.path);
|
|
1052
|
+
return text === void 0 ? f : { ...f, lines: text.split(/\r?\n/).length };
|
|
1053
|
+
});
|
|
1054
|
+
const mode = await modelsModeOf(root, repo, c.o.models);
|
|
1055
|
+
const facts0 = typeof existing === "string" ? [] : existing;
|
|
1056
|
+
const rp = reread ? void 0 : reachPlanOf({ paths: product.map((f) => f.path), source: c.source, facts: facts0, mode });
|
|
1057
|
+
const leave = new Set(rp?.leaveOut ?? []);
|
|
1058
|
+
const kept = product.filter((f) => !leave.has(f.path));
|
|
1059
|
+
const ordered = rp && rp.reach.rooted && rp.reach.models > 0;
|
|
1060
|
+
const parts = planParts(kept, session, ordered ? {
|
|
1061
|
+
head: reachHeadOf(kept.map((f) => f.path), rp),
|
|
1062
|
+
models: rp.reach.reached.map((r) => r.path),
|
|
1063
|
+
leftOut: rp.leaveOut
|
|
1064
|
+
} : void 0);
|
|
1065
|
+
const planned = room >= MIN_ROOM ? planBatches(readSource, {
|
|
1066
|
+
room,
|
|
1067
|
+
exclude: c.exclude,
|
|
1068
|
+
conventions,
|
|
1069
|
+
overhead: overheadOf(repo, c.commit, await frameworksFor(root, repo, facts0)),
|
|
1070
|
+
...rp && ordered ? { reach: { first: rp.first, leaveOut: rp.leaveOut } } : {}
|
|
1071
|
+
}) : void 0;
|
|
1072
|
+
const plan = planned && planned.leastRoom >= MIN_ROOM ? planned : void 0;
|
|
746
1073
|
const plan0 = await loadReadPlan(root, repo);
|
|
747
1074
|
const same = plan0 !== void 0 && plan0.commit === c.commit && plan0.session === session && plan0.parts.length === parts.length && plan0.parts.every((p, i) => p.paths.length === parts[i].paths.length && p.paths.every((x, j) => x === parts[i].paths[j]));
|
|
748
|
-
|
|
749
|
-
|
|
1075
|
+
const estimate2 = {
|
|
1076
|
+
files: kept.length,
|
|
1077
|
+
tokens: kept.reduce((n, f) => n + f.tokens, 0),
|
|
1078
|
+
sessions: parts.length || 1,
|
|
1079
|
+
...reread ? { reread: true } : {}
|
|
1080
|
+
};
|
|
1081
|
+
const sameEstimate = plan0?.estimate !== void 0 && plan0.estimate.files === estimate2.files && plan0.estimate.tokens === estimate2.tokens && plan0.estimate.sessions === estimate2.sessions && plan0.estimate.reread === estimate2.reread;
|
|
1082
|
+
const firstRead = typeof existing !== "string" && existing.length === 0 && !reread;
|
|
1083
|
+
const orgRuleIds = ruleIds(await effectiveRules(root, repo, { dir: c.dir, op: c.op }));
|
|
1084
|
+
const readRules = firstRead ? { hash: rulesNow().hash, sets: [...rulesNow().sets, ...orgRuleIds] } : plan0?.rules;
|
|
1085
|
+
const notReached = rp ? rp.notReached : plan0?.notReached;
|
|
1086
|
+
const sameModels = plan0 !== void 0 && (plan0.models ?? "reachable") === mode && JSON.stringify(plan0.notReached ?? null) === JSON.stringify(notReached ?? null);
|
|
1087
|
+
if (!same)
|
|
1088
|
+
await writeReadPlan(root, repo, {
|
|
1089
|
+
commit: c.commit,
|
|
1090
|
+
session,
|
|
1091
|
+
parts,
|
|
1092
|
+
estimate: estimate2,
|
|
1093
|
+
// What the reader reported of an earlier plan stays, under the commit it was of.
|
|
1094
|
+
...plan0?.reported ? { reported: plan0.reported } : {},
|
|
1095
|
+
...readRules ? { rules: readRules } : {},
|
|
1096
|
+
models: mode,
|
|
1097
|
+
...notReached ? { notReached } : {}
|
|
1098
|
+
});
|
|
1099
|
+
else if (!sameEstimate || !sameModels || firstRead && plan0.rules?.hash !== readRules?.hash) {
|
|
1100
|
+
const { notReached: _n, models: _m, ...rest0 } = plan0;
|
|
1101
|
+
await saveReadPlan(root, {
|
|
1102
|
+
...rest0,
|
|
1103
|
+
estimate: estimate2,
|
|
1104
|
+
...readRules ? { rules: readRules } : {},
|
|
1105
|
+
...mode !== "reachable" ? { models: mode } : {},
|
|
1106
|
+
...notReached ? { notReached } : {}
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
750
1109
|
const progress = parts.length ? await readPlanProgress(root, repo, { commit: c.commit }) : void 0;
|
|
751
1110
|
const questions = (await listQuestions(root, { repo })).questions.filter((q) => q.state !== "retired");
|
|
1111
|
+
const notes = await notesAt(root, repo, c.dir, c.op);
|
|
1112
|
+
const rules = await rulesCovering(root, repo, c.op);
|
|
1113
|
+
const house = await houseUntaughtOf(root, repo, {
|
|
1114
|
+
dir: c.dir,
|
|
1115
|
+
source: c.source,
|
|
1116
|
+
op: c.op,
|
|
1117
|
+
exclude: c.exclude
|
|
1118
|
+
});
|
|
1119
|
+
if (c.o.part !== void 0 && !parts[c.o.part - 1]) {
|
|
1120
|
+
io.err(`${repo} is read in ${parts.length ? `parts 1 to ${parts.length}` : "one session (no parts)"} at this limit: there is no part ${c.o.part}.`);
|
|
1121
|
+
return 2;
|
|
1122
|
+
}
|
|
752
1123
|
if (c.o.json) {
|
|
753
1124
|
io.out(JSON.stringify({
|
|
754
1125
|
repo,
|
|
@@ -763,6 +1134,8 @@ async function estimate(root, repo, c, io) {
|
|
|
763
1134
|
maxTokensGiven: given !== void 0,
|
|
764
1135
|
maxTokensFrom: from ?? "example",
|
|
765
1136
|
batches: plan?.batches.length ?? null,
|
|
1137
|
+
// ADR 0169: what the read plans to read (the model classes it leaves out, out).
|
|
1138
|
+
read: { files: estimate2.files, tokens: estimate2.tokens },
|
|
766
1139
|
order: whole.batches.flat().map((x) => x.path),
|
|
767
1140
|
// ADR 0128: what a person says the repo is, and whether that eased the proposals.
|
|
768
1141
|
about: about ? { text: about.text, trust: about.trust, eased: saysNotProduct(about) } : null,
|
|
@@ -786,13 +1159,29 @@ async function estimate(root, repo, c, io) {
|
|
|
786
1159
|
}
|
|
787
1160
|
} : {}
|
|
788
1161
|
},
|
|
1162
|
+
// ADR 0169: the model classes reached from the entry points and calls, and those left out.
|
|
1163
|
+
models: rp ? {
|
|
1164
|
+
mode,
|
|
1165
|
+
roots: rp.reach.roots,
|
|
1166
|
+
reached: rp.reach.reached,
|
|
1167
|
+
notReached: rp.leaveOut
|
|
1168
|
+
} : null,
|
|
789
1169
|
tier,
|
|
1170
|
+
// A-taught: the frameworks of the organisation it is built on, as taught to Atticus.
|
|
1171
|
+
taughtFrameworks: taughtIn(c.source, c.op).map((m) => m.name),
|
|
1172
|
+
// R3: the house packages to teach before the first read.
|
|
1173
|
+
houseUntaught: house,
|
|
1174
|
+
// ADR 0163: the org notes the reader is handed, numbered, and the repo type they are of.
|
|
1175
|
+
notes: { ...notes.type ? { repoType: notes.type } : {}, notes: notes.notes },
|
|
1176
|
+
// G4 (ADR 0176): the organisation's reading rules for this repo, as the reader follows them.
|
|
1177
|
+
readingRules: readingRulesText(await effectiveRules(root, repo, { dir: c.dir, op: c.op })),
|
|
790
1178
|
questions: questions.map((q) => ({
|
|
791
1179
|
id: q.id,
|
|
792
1180
|
question: q.question,
|
|
793
1181
|
state: q.state,
|
|
794
1182
|
...q.answer ? { answer: q.answer } : {}
|
|
795
1183
|
})),
|
|
1184
|
+
rules,
|
|
796
1185
|
// A re-read: what the files and batches above are, and the facts to revisit.
|
|
797
1186
|
reread: reread ? {
|
|
798
1187
|
...reread,
|
|
@@ -809,6 +1198,23 @@ async function estimate(root, repo, c, io) {
|
|
|
809
1198
|
io.out(`${repo} at ${c.commit} in ${c.dir}`);
|
|
810
1199
|
io.out(about ? `What it is (${descriptionTrust(about)}${about.by ? `, ${about.by}` : ""}): ${about.text} \u2014 a person's note from the manifest, not read from the code: where the code says otherwise, the code is right.` : `What it is: nothing says yet. A person writes one line (atticus repo describe ${repo} --description "..."); if the files say plainly, hand yours over with atticus repo describe ${repo} --drafted "..." --cites <file>:<line>, and it waits for a person.`);
|
|
811
1200
|
io.out(`Facts file: ${c.factsFile}`);
|
|
1201
|
+
const taught = taughtFrameworksText(taughtIn(c.source, c.op));
|
|
1202
|
+
if (taught)
|
|
1203
|
+
for (const l of taught.split("\n"))
|
|
1204
|
+
io.out(l);
|
|
1205
|
+
const notesLines = notesText(notes.notes, notes.type);
|
|
1206
|
+
if (notesLines)
|
|
1207
|
+
for (const l of notesLines.split("\n"))
|
|
1208
|
+
io.out(l);
|
|
1209
|
+
for (const l of componentTypesText(await componentTypesAt(root, c.op)).split("\n"))
|
|
1210
|
+
if (l)
|
|
1211
|
+
io.out(l);
|
|
1212
|
+
const orgRulesLines = readingRulesText(await effectiveRules(root, repo, { dir: c.dir, op: c.op }));
|
|
1213
|
+
if (orgRulesLines)
|
|
1214
|
+
for (const l of orgRulesLines.split("\n"))
|
|
1215
|
+
io.out(l);
|
|
1216
|
+
for (const l of houseUntaughtLines(repo, house))
|
|
1217
|
+
io.out(l);
|
|
812
1218
|
if (reread)
|
|
813
1219
|
for (const l of rereadLines(repo, reread))
|
|
814
1220
|
io.out(l);
|
|
@@ -839,13 +1245,25 @@ repo: ${repo}`);
|
|
|
839
1245
|
const stateOf = (i) => progress?.parts[i]?.state;
|
|
840
1246
|
const words = (s) => s === "done" ? "done" : s === "in-progress" ? "part-read" : "to read";
|
|
841
1247
|
parts.forEach((p, i) => io.out(` part ${i + 1} (${words(stateOf(i))}, about ${p.tokens} tokens, ${plural(p.files, "file")}): ${p.paths.join(", ")}`));
|
|
842
|
-
|
|
1248
|
+
const asked = c.o.part !== void 0 ? parts[c.o.part - 1] : void 0;
|
|
1249
|
+
if (asked)
|
|
1250
|
+
io.out(`This session reads part ${c.o.part} of ${parts.length} (--part ${c.o.part}): ${asked.paths.join(", ")}. The facts on file stay, as already kept: name one by its id and don't write it again.`);
|
|
1251
|
+
if (progress && !asked) {
|
|
843
1252
|
io.out(`Read plan: ${readPlanRelOf(root, repo)}. ${progress.next ? `${partOfWords({ part: progress.next.part, total: progress.total })} is next (${progress.done ? `${progress.done} of ${progress.total} read` : `none of ${progress.total} read yet`}): ${progress.next.paths.join(", ")}.` : `All ${progress.total} parts are read.`} A part counts as read when every folder it covers is in the facts (a fact citing a file, or a line of ${factsRelOf(root)}/${repo}.reviewed.jsonl); atticus next says which comes next.`);
|
|
844
1253
|
for (const p of progress.parts)
|
|
845
1254
|
if (p.state === "in-progress")
|
|
846
1255
|
io.out(` part ${p.part} is part-read: nothing in the facts yet for ${p.left.join(", ")}.`);
|
|
847
1256
|
}
|
|
848
1257
|
}
|
|
1258
|
+
const line = rp ? modelsLine(repo, rp) : void 0;
|
|
1259
|
+
if (rp && line) {
|
|
1260
|
+
io.out(line);
|
|
1261
|
+
const data = modelsData(repo, rp);
|
|
1262
|
+
if (data) {
|
|
1263
|
+
io.out(MODELS_RULE);
|
|
1264
|
+
io.out(data);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
849
1267
|
io.out(`Your assistant: ${tierWords(tier)}, ${tierSource(tier)}. ${tier.how}`);
|
|
850
1268
|
io.out(`Another agentic assistant (Claude Code, Cursor, Gemini CLI) reads it the same way: /atticus-map ${repo}; one without file tools gets batches with atticus map ${repo} --handoff --max-tokens <its limit>.`);
|
|
851
1269
|
if (tier.fallback)
|
|
@@ -861,13 +1279,20 @@ repo: ${repo}`);
|
|
|
861
1279
|
io.out(plan ? `In batches at ${limit} tokens a prompt${given === void 0 ? " (GPT-4o mini through Copilot; --max-tokens n for your model's limit)" : from === "probe" ? ` (the limit stated when your assistant was measured on ${tier.measured?.at})` : ""}: ${plural(plan.batches.length, "prompt")}, one more if facts are rejected in the last.` : `A model of ${limit} tokens leaves too little room for the files beside the instructions: use a model with a bigger limit.`);
|
|
862
1280
|
for (const q of questions)
|
|
863
1281
|
io.out(`Question ${q.id}: ${q.question} (${q.state === "answered" ? `answered: ${q.answer?.text ?? q.options[(q.answer?.option ?? 1) - 1]?.label ?? ""}` : "open"})`);
|
|
864
|
-
|
|
865
|
-
io.out(
|
|
1282
|
+
for (const r of rules)
|
|
1283
|
+
io.out(ruleLineOf(r));
|
|
1284
|
+
if (questions.length || rules.length)
|
|
1285
|
+
io.out("Follow each answer and each rule; don't ask what they settle again.");
|
|
866
1286
|
return 0;
|
|
867
1287
|
}
|
|
1288
|
+
|
|
868
1289
|
export {
|
|
869
1290
|
REPO_READER,
|
|
870
|
-
|
|
1291
|
+
repoReaderAgent,
|
|
1292
|
+
mapStateOf,
|
|
871
1293
|
readAnswer,
|
|
872
|
-
|
|
1294
|
+
rulesCovering,
|
|
1295
|
+
ruleLineOf,
|
|
1296
|
+
taughtIn,
|
|
1297
|
+
mapCommand
|
|
873
1298
|
};
|