@maycombhq/atticus 2.0.0-beta.22 → 2.0.0-beta.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/dist/bin.js +12 -7
  2. package/dist/{chunk-J2JAKCIW.js → chunk-25CUJJTP.js} +511 -291
  3. package/dist/chunk-26AB2WNW.js +62 -0
  4. package/dist/{chunk-VBTP56CE.js → chunk-2ITYURTR.js} +9 -8
  5. package/dist/{chunk-6ZJ5A7AF.js → chunk-2JHE75RW.js} +13 -11
  6. package/dist/{chunk-QFWA2DPH.js → chunk-37UTWGU4.js} +8 -6
  7. package/dist/{chunk-VW62D6QE.js → chunk-3BEGKSDW.js} +14 -12
  8. package/dist/{chunk-3RM4UK6W.js → chunk-3FGQFDS4.js} +20 -18
  9. package/dist/{chunk-23XVSEV5.js → chunk-3NS4RS3C.js} +20 -18
  10. package/dist/{chunk-FSMSFDLD.js → chunk-3TGX4SJ3.js} +10 -7
  11. package/dist/{chunk-7JITZFJC.js → chunk-3UMKLB6P.js} +7 -5
  12. package/dist/chunk-3VS7RNEB.js +96 -0
  13. package/dist/{chunk-AJYXNTNZ.js → chunk-3XCCT2GR.js} +167 -42
  14. package/dist/{chunk-XERYFDB5.js → chunk-3XZRYQWU.js} +38 -34
  15. package/dist/{chunk-FUJM6RTF.js → chunk-432FGEVB.js} +9 -7
  16. package/dist/{chunk-SFUP7TTO.js → chunk-44QUCNPH.js} +7 -5
  17. package/dist/{chunk-O5PXQR67.js → chunk-4CS3PMIM.js} +15 -13
  18. package/dist/{chunk-RGERPOIV.js → chunk-4DCIUKIE.js} +22 -12
  19. package/dist/{chunk-RLDGWLQ7.js → chunk-4DX4DIND.js} +9 -7
  20. package/dist/chunk-4MNMOUU7.js +108 -0
  21. package/dist/{chunk-SLXZOMA6.js → chunk-4RKIOUPA.js} +9 -7
  22. package/dist/{chunk-AJQ72EBM.js → chunk-532HDXMM.js} +9 -7
  23. package/dist/{chunk-CADWLE2T.js → chunk-5EIKOU7L.js} +6 -4
  24. package/dist/{chunk-CQDGOPGH.js → chunk-5FPAKAGE.js} +7 -5
  25. package/dist/{chunk-IVBOQAGB.js → chunk-5FUFVNXB.js} +27 -3
  26. package/dist/{chunk-UUU4CLJG.js → chunk-5MKV4TV6.js} +5 -1
  27. package/dist/{chunk-ZQXZ2SES.js → chunk-5ORLKITZ.js} +23 -21
  28. package/dist/{chunk-OHVTTOPS.js → chunk-5PSKLTBR.js} +3 -3
  29. package/dist/{chunk-RUGXBPWI.js → chunk-5QF5W5P2.js} +10 -10
  30. package/dist/{chunk-BPK5P77O.js → chunk-5Z7L2TSR.js} +3 -3
  31. package/dist/{chunk-L27SV425.js → chunk-66DWUSNY.js} +22 -20
  32. package/dist/{chunk-JAVI7JSP.js → chunk-6FIYEB7M.js} +25 -22
  33. package/dist/{chunk-VY72R2XZ.js → chunk-6OZAQPU5.js} +532 -358
  34. package/dist/{chunk-AFWUDXEM.js → chunk-6TNQO76I.js} +34 -17
  35. package/dist/{chunk-WF7B67YE.js → chunk-6UTD5RQH.js} +18 -16
  36. package/dist/{chunk-HNM2YQT2.js → chunk-775FMPUB.js} +7 -7
  37. package/dist/{chunk-7ASNL4Q4.js → chunk-77AZRGWE.js} +19 -16
  38. package/dist/{chunk-WKUJ3KPV.js → chunk-7HWCEDPX.js} +7 -5
  39. package/dist/{chunk-G6X77UJZ.js → chunk-7U46TCRZ.js} +25 -22
  40. package/dist/{chunk-O45HFTFS.js → chunk-A3NUZJFI.js} +4 -2
  41. package/dist/{chunk-UPOY4YSQ.js → chunk-A4VDFIMR.js} +14 -12
  42. package/dist/{chunk-EMRIQUND.js → chunk-A53IYUCR.js} +87 -29
  43. package/dist/{chunk-S4PMJU6H.js → chunk-A6ZG3UOS.js} +108 -50
  44. package/dist/{chunk-PMUAJGLI.js → chunk-AAY6VPPO.js} +18 -16
  45. package/dist/{chunk-MG4ZL5RW.js → chunk-ABDE5IRC.js} +18 -16
  46. package/dist/{chunk-T6DQR5TV.js → chunk-AM7PYKVP.js} +15 -13
  47. package/dist/{chunk-SFSPGFCV.js → chunk-ANUMIPF6.js} +22 -20
  48. package/dist/{chunk-VTZMAJ3W.js → chunk-ASFRT33J.js} +11 -9
  49. package/dist/{chunk-7FTTA3HD.js → chunk-AWDCVZYO.js} +9 -7
  50. package/dist/{chunk-KFAVQZSX.js → chunk-B63NWU3P.js} +14 -12
  51. package/dist/{chunk-YYY3AZFE.js → chunk-BBZ6UKN3.js} +16 -5
  52. package/dist/{chunk-Q4K5WB2W.js → chunk-BFQ5IKQA.js} +12 -10
  53. package/dist/{chunk-ZFL7NY4F.js → chunk-BLVFHN3C.js} +73 -42
  54. package/dist/{chunk-MO6P2JZH.js → chunk-BQXAHIZ6.js} +10 -8
  55. package/dist/{chunk-Y2EQNWKV.js → chunk-BTS56NV7.js} +91 -41
  56. package/dist/{chunk-UGUP3ZM6.js → chunk-BWYW533C.js} +18 -16
  57. package/dist/{chunk-O7FDLW7L.js → chunk-BYKWWSXL.js} +14 -12
  58. package/dist/chunk-C7BB6IQT.js +147 -0
  59. package/dist/{chunk-JLUCKAEL.js → chunk-CCQWQFOT.js} +19 -17
  60. package/dist/{chunk-SYV5LHML.js → chunk-CCQZN6W3.js} +35 -33
  61. package/dist/{chunk-UCROWG2D.js → chunk-CFSBBLDD.js} +28 -25
  62. package/dist/{chunk-EIPTLPFC.js → chunk-CFSHLQPK.js} +26 -24
  63. package/dist/{chunk-2IIMFOPM.js → chunk-CI4D6VSU.js} +20 -18
  64. package/dist/{chunk-66PPNOON.js → chunk-CKRPMRFQ.js} +28 -25
  65. package/dist/{chunk-IUPG3UKI.js → chunk-CNF2EZ6S.js} +191 -125
  66. package/dist/chunk-CTJHEG6A.js +97 -0
  67. package/dist/{chunk-DOBQKHIF.js → chunk-CU7ZK7KP.js} +30 -29
  68. package/dist/{chunk-745DAZ4L.js → chunk-CZ75S2EZ.js} +886 -313
  69. package/dist/{chunk-LGFL54FP.js → chunk-D5CJEKZI.js} +11 -4
  70. package/dist/{chunk-PBPBMP2B.js → chunk-D5ZC7IMC.js} +5 -3
  71. package/dist/{chunk-LZ7NUC62.js → chunk-D63NU53X.js} +20 -18
  72. package/dist/{chunk-BO4KX37X.js → chunk-DCQSPSXU.js} +28 -23
  73. package/dist/{chunk-WXFLMQSR.js → chunk-DCRZ3OQ7.js} +8 -6
  74. package/dist/chunk-DD2AXECF.js +41 -0
  75. package/dist/{chunk-4EURQWQD.js → chunk-DF6DPCW2.js} +16 -14
  76. package/dist/{chunk-53T4O55J.js → chunk-DH3EQMIA.js} +5 -3
  77. package/dist/{chunk-ZX57KSEQ.js → chunk-DIXA74N7.js} +5 -3
  78. package/dist/{chunk-6ZGLAACW.js → chunk-DIYNRYXW.js} +2 -2
  79. package/dist/chunk-DYDNW4O6.js +52 -0
  80. package/dist/{chunk-P2V7QW4D.js → chunk-E7YDJH6B.js} +16 -14
  81. package/dist/chunk-EEKQI3U4.js +45 -0
  82. package/dist/{chunk-GZY6RUZ6.js → chunk-EHF2MBGR.js} +9 -4
  83. package/dist/chunk-EHXDB3SA.js +25 -0
  84. package/dist/{chunk-PJSJPMJI.js → chunk-ENZ3PI7L.js} +3 -3
  85. package/dist/{chunk-E3ISYXO3.js → chunk-EPQQ2XVM.js} +16 -14
  86. package/dist/{chunk-7IGKHZ4Z.js → chunk-ESJALLOK.js} +222 -213
  87. package/dist/chunk-ETQSQ2EC.js +33 -0
  88. package/dist/{chunk-MFR5OPBD.js → chunk-EUMXLSW5.js} +14 -6
  89. package/dist/{chunk-BTY3HZBO.js → chunk-F63F4NKT.js} +18 -16
  90. package/dist/{chunk-ZFFYNRIO.js → chunk-FDL2JOLB.js} +26 -22
  91. package/dist/{chunk-5SJZW52K.js → chunk-FFDVAV56.js} +24 -22
  92. package/dist/chunk-FFYOZ7PF.js +27 -0
  93. package/dist/{chunk-RXPJMEOW.js → chunk-FGW5TLGM.js} +24 -19
  94. package/dist/{chunk-UPS2DGFC.js → chunk-FL53R4SW.js} +1 -1
  95. package/dist/chunk-FYWLB7PO.js +38 -0
  96. package/dist/{chunk-FFLNS6VP.js → chunk-G3W7GNEP.js} +24 -18
  97. package/dist/chunk-G3ZFEHCX.js +925 -0
  98. package/dist/{chunk-YHCMZC2J.js → chunk-G67GOK4S.js} +10 -8
  99. package/dist/{chunk-2F4CYZKJ.js → chunk-GCMDDVIE.js} +14 -9
  100. package/dist/{chunk-QKUJMING.js → chunk-GFYVVTKH.js} +10 -8
  101. package/dist/chunk-GJVCBTSO.js +20722 -0
  102. package/dist/{chunk-VCTWPLAO.js → chunk-GKZDHXC2.js} +8 -8
  103. package/dist/{chunk-5BD2KYLE.js → chunk-GQFUEUC7.js} +18 -16
  104. package/dist/chunk-GQPP4P2E.js +33 -0
  105. package/dist/{chunk-42SIDKEU.js → chunk-GS7N3RFG.js} +51 -32
  106. package/dist/{chunk-LJXMYKZJ.js → chunk-GXQYEIYM.js} +7 -5
  107. package/dist/{chunk-VNU26RCO.js → chunk-H5EQOSTC.js} +43 -33
  108. package/dist/{chunk-W7VWI2YH.js → chunk-H7KERB6Q.js} +7 -5
  109. package/dist/{chunk-OUBGGKDU.js → chunk-HGDBM3A5.js} +5 -3
  110. package/dist/{chunk-JENSEMXF.js → chunk-HI7ADE4E.js} +1 -1
  111. package/dist/{chunk-CXJ6FUKN.js → chunk-HNPKCRCE.js} +1010 -330
  112. package/dist/{chunk-FPJPLKDW.js → chunk-HRHXTLUM.js} +40 -16
  113. package/dist/{chunk-57TDNMI3.js → chunk-HRYI22QU.js} +17 -15
  114. package/dist/{chunk-LO6P2VYG.js → chunk-HWNFFCGB.js} +5 -3
  115. package/dist/{chunk-XI2LCCYQ.js → chunk-HXFZX2BI.js} +12 -8
  116. package/dist/{chunk-H7KM7LZE.js → chunk-HYHV2P3G.js} +16 -13
  117. package/dist/{chunk-X3WY6MN3.js → chunk-IB66ZLDN.js} +10 -8
  118. package/dist/{chunk-3NFFJL5D.js → chunk-IJQHBK76.js} +1 -1
  119. package/dist/{chunk-LQJPN536.js → chunk-IK6LHW3E.js} +6 -4
  120. package/dist/{chunk-DCZWQLYT.js → chunk-IOHRX4KF.js} +26 -21
  121. package/dist/{chunk-2GF7OLF3.js → chunk-IRXZKKCG.js} +21 -15
  122. package/dist/{chunk-Z5IA3WDR.js → chunk-IUBBEU6O.js} +160 -81
  123. package/dist/{chunk-W62H2XSO.js → chunk-IWPO5AUT.js} +29 -26
  124. package/dist/{chunk-BEVTIBRH.js → chunk-J4K4C4T5.js} +31 -15
  125. package/dist/{chunk-WERM6KPJ.js → chunk-JCEYOSST.js} +14 -6
  126. package/dist/{chunk-HYU5VLGA.js → chunk-JCG2EBNB.js} +1 -1
  127. package/dist/{chunk-UNAGJYET.js → chunk-JFBVIMGY.js} +14 -12
  128. package/dist/chunk-JJ4SCGRJ.js +43 -0
  129. package/dist/{chunk-2Q5EDGEO.js → chunk-JLYH2QOE.js} +7 -5
  130. package/dist/{chunk-X4CXA2IL.js → chunk-JMH6TCZJ.js} +23 -21
  131. package/dist/{chunk-6PPOWY5E.js → chunk-JUHZBZPZ.js} +17 -13
  132. package/dist/{chunk-GUX3PTYM.js → chunk-JVMNEI7B.js} +3 -3
  133. package/dist/chunk-JYJMIAFS.js +44 -0
  134. package/dist/{chunk-34S2WGOB.js → chunk-KIY2WCN7.js} +7 -3
  135. package/dist/chunk-KVVNAUIG.js +66 -0
  136. package/dist/{chunk-M32BLWDH.js → chunk-KYO5HT4G.js} +14 -12
  137. package/dist/chunk-L27KUL5B.js +38 -0
  138. package/dist/chunk-L3PIN47C.js +18 -0
  139. package/dist/{chunk-IH2XURVQ.js → chunk-L6Z6TMIK.js} +5 -5
  140. package/dist/{chunk-E6ZIEVOI.js → chunk-LAGZBQHK.js} +16 -13
  141. package/dist/chunk-LBG4GMOR.js +68 -0
  142. package/dist/{chunk-UF4GLFBX.js → chunk-LDKP7OWQ.js} +33 -24
  143. package/dist/{chunk-ZQ7SKESZ.js → chunk-LELM7X5H.js} +13 -11
  144. package/dist/{chunk-INQHESFB.js → chunk-LIB6AUZS.js} +6 -4
  145. package/dist/{chunk-H5HBGNXU.js → chunk-LIQWFDOZ.js} +6 -4
  146. package/dist/{chunk-TYQBFTBR.js → chunk-LKUTBQ2Y.js} +8 -6
  147. package/dist/{chunk-7BR7IPOH.js → chunk-LOCJHNZI.js} +10 -8
  148. package/dist/{chunk-SQV37XO2.js → chunk-LTIXFLYE.js} +6 -6
  149. package/dist/{chunk-3NWDLGG6.js → chunk-M3RWF7MC.js} +33 -29
  150. package/dist/chunk-MA6UK7GX.js +42 -0
  151. package/dist/{chunk-ISUAAMGS.js → chunk-MCE74XMF.js} +25 -16
  152. package/dist/{chunk-EGQRREQH.js → chunk-MDTAZ6NE.js} +37 -24
  153. package/dist/{chunk-ZZK56BLP.js → chunk-MMOMKHAX.js} +6 -4
  154. package/dist/{chunk-P32RUW3B.js → chunk-MOWUP33K.js} +49 -15
  155. package/dist/{chunk-UOR2DTHH.js → chunk-MPATOMY5.js} +18 -14
  156. package/dist/{chunk-LNBQOP7D.js → chunk-MQFSEGTU.js} +23 -21
  157. package/dist/{chunk-2Q56PQPS.js → chunk-MT3FNSXO.js} +4 -4
  158. package/dist/{chunk-FZOJFH7Q.js → chunk-MUY5MAGM.js} +15 -12
  159. package/dist/{chunk-7DOR27HL.js → chunk-MVXMISNA.js} +9 -7
  160. package/dist/{chunk-CX4RZ2KS.js → chunk-MWN7CBVL.js} +5 -3
  161. package/dist/{chunk-BXYMYEJ4.js → chunk-MZWM73S2.js} +18 -17
  162. package/dist/chunk-NBZ7RKX3.js +46 -0
  163. package/dist/{chunk-EPCJQQWD.js → chunk-NC56V6KQ.js} +6 -4
  164. package/dist/{chunk-7UOMVMFG.js → chunk-NN6AXKFX.js} +17 -15
  165. package/dist/{chunk-BIGDQDHD.js → chunk-NOU5IBLM.js} +6 -4
  166. package/dist/{chunk-LFGTYX5U.js → chunk-NQDHRT2H.js} +20 -18
  167. package/dist/{chunk-KDNTAPLX.js → chunk-NTEPBOAF.js} +6 -4
  168. package/dist/{chunk-LYBNHMVZ.js → chunk-NTOPAOBY.js} +3 -3
  169. package/dist/{chunk-R44CYFPV.js → chunk-NX5IPHI3.js} +19 -16
  170. package/dist/{chunk-GCWRWSU7.js → chunk-O4ZWZZZT.js} +6 -4
  171. package/dist/chunk-OCU5S2XG.js +36 -0
  172. package/dist/{chunk-SU74NDMQ.js → chunk-OKSRK2LJ.js} +19 -17
  173. package/dist/{chunk-XD75VZIH.js → chunk-OSWOIFRQ.js} +9 -7
  174. package/dist/{chunk-PKBHS4AA.js → chunk-OSZTENIA.js} +54 -21
  175. package/dist/{chunk-NDCF4R6S.js → chunk-OTUBMKSG.js} +10 -8
  176. package/dist/{chunk-THDMSZ3R.js → chunk-OYKNPZCV.js} +2837 -693
  177. package/dist/{chunk-ZQ3ON2VQ.js → chunk-OYTSRNSZ.js} +8 -6
  178. package/dist/chunk-OYZ64UMQ.js +67 -0
  179. package/dist/{chunk-UF4AZOZB.js → chunk-PB3NCPRF.js} +10 -8
  180. package/dist/chunk-PIPJZIJE.js +47 -0
  181. package/dist/{chunk-2RLKFUUL.js → chunk-PIPYJTIL.js} +27 -24
  182. package/dist/{chunk-MZCGSXVR.js → chunk-PUMNCWHJ.js} +15 -13
  183. package/dist/{chunk-X5F3Q5LV.js → chunk-PZBNDFZ7.js} +35 -25
  184. package/dist/chunk-Q2ULHBCJ.js +59 -0
  185. package/dist/{chunk-ZJFRMSJT.js → chunk-Q5QSWV2R.js} +14 -12
  186. package/dist/{chunk-Q2TECDIT.js → chunk-QFDPX6C4.js} +2886 -20703
  187. package/dist/{chunk-WG5U3F5V.js → chunk-QGBS4GMS.js} +14 -12
  188. package/dist/{chunk-BTGPE6CR.js → chunk-QIDSEHJA.js} +17 -15
  189. package/dist/{chunk-Q6DFNVRJ.js → chunk-QJ3AYXVO.js} +14 -12
  190. package/dist/{chunk-EBL2R3YG.js → chunk-QK6CGRKK.js} +6 -4
  191. package/dist/{chunk-S7FCV7S5.js → chunk-QOC3Q4UU.js} +1 -1
  192. package/dist/{chunk-JJF6HALY.js → chunk-QPLNB2BM.js} +5 -3
  193. package/dist/chunk-QVF4KYIO.js +71 -0
  194. package/dist/{chunk-6OJQOPUN.js → chunk-QXXEO4TF.js} +5 -3
  195. package/dist/{chunk-F3P7N7SF.js → chunk-QYFNVQLK.js} +1 -1
  196. package/dist/{chunk-6MUGR4LS.js → chunk-R6CJOMPC.js} +106 -29
  197. package/dist/{chunk-BDKC6H5P.js → chunk-ROWZYQOI.js} +9 -7
  198. package/dist/{chunk-2MMCFP5C.js → chunk-RQAMZVWW.js} +10 -8
  199. package/dist/chunk-RQSUFGU2.js +55 -0
  200. package/dist/{chunk-SDKLKB6I.js → chunk-RRKM3GJA.js} +38 -28
  201. package/dist/{chunk-OHNCWBKF.js → chunk-RSHVSXPJ.js} +7 -5
  202. package/dist/chunk-RSKMV3VC.js +22 -0
  203. package/dist/{chunk-U76OWS3Q.js → chunk-RU5W7JJQ.js} +25 -23
  204. package/dist/{chunk-63YRMR6J.js → chunk-RYY554OA.js} +7 -5
  205. package/dist/{chunk-5NMKONLP.js → chunk-SGYQORAD.js} +7 -3
  206. package/dist/{chunk-JA5FI3QV.js → chunk-SLGUSFOD.js} +3 -3
  207. package/dist/{chunk-M3NANSDZ.js → chunk-SUAHNYNQ.js} +17 -15
  208. package/dist/{chunk-QAXW2N3B.js → chunk-SUYC5NP6.js} +34 -34
  209. package/dist/{chunk-FFTRTL6R.js → chunk-SWSGRRNO.js} +6 -4
  210. package/dist/{chunk-UWOJLHFT.js → chunk-SYLXQNPC.js} +38 -24
  211. package/dist/chunk-T24TBI7F.js +54 -0
  212. package/dist/chunk-T2HXLDY3.js +55 -0
  213. package/dist/{chunk-O4GXGGBX.js → chunk-T5NH5L7A.js} +16 -13
  214. package/dist/{chunk-KXITGYLF.js → chunk-TAR6T2RE.js} +4 -2
  215. package/dist/chunk-TBQHBOFF.js +324 -0
  216. package/dist/{chunk-LKOR5UET.js → chunk-TKE6ZJMM.js} +26 -24
  217. package/dist/chunk-TKEXS74L.js +52 -0
  218. package/dist/{chunk-J3IOLXWM.js → chunk-TXYMNKGM.js} +16 -14
  219. package/dist/{chunk-IDKCWSM5.js → chunk-U2JTTRKS.js} +401 -115
  220. package/dist/{chunk-TNR75OXT.js → chunk-U37ZOYJJ.js} +11 -8
  221. package/dist/{chunk-7MJSQTL5.js → chunk-U57VLY6X.js} +23 -21
  222. package/dist/{chunk-BHT7QK4G.js → chunk-U66RQUFC.js} +6 -4
  223. package/dist/chunk-UCFNHK5L.js +50 -0
  224. package/dist/{chunk-IFKEI4SA.js → chunk-UI6KNLSO.js} +31 -11
  225. package/dist/{chunk-7GJS6DNX.js → chunk-UKRJ2ISN.js} +13 -3
  226. package/dist/chunk-UWJOM457.js +232 -0
  227. package/dist/{chunk-D73UEXYW.js → chunk-UXO25YBN.js} +3 -3
  228. package/dist/chunk-VE2T5URA.js +51 -0
  229. package/dist/{chunk-C3RY6KU6.js → chunk-W4EG25TI.js} +513 -172
  230. package/dist/{chunk-O66DM6DJ.js → chunk-WAAPMZWO.js} +6 -4
  231. package/dist/{chunk-R7NYHMUU.js → chunk-WECCLSYY.js} +4884 -3669
  232. package/dist/chunk-WQDJGNJQ.js +45 -0
  233. package/dist/{chunk-UWMJKX5U.js → chunk-WWSCJBF6.js} +14 -12
  234. package/dist/{chunk-N3XIYPU3.js → chunk-X7HFXXTZ.js} +16 -13
  235. package/dist/chunk-X7XVMYIL.js +5 -0
  236. package/dist/{chunk-NR2UJWOC.js → chunk-XERIHPBF.js} +12 -9
  237. package/dist/{chunk-JRBFANFE.js → chunk-XKNISZ6N.js} +21 -18
  238. package/dist/{chunk-PPD7HTDP.js → chunk-XNH5ZWIA.js} +20 -18
  239. package/dist/{chunk-7IOWA5D5.js → chunk-XNW3EDCY.js} +13 -3
  240. package/dist/{chunk-2LGRMVCA.js → chunk-XPXOKHNZ.js} +13 -11
  241. package/dist/{chunk-ZJXLNDH4.js → chunk-XXRBAJ36.js} +14 -12
  242. package/dist/{chunk-EHA7RMZ3.js → chunk-YA2IJJ6N.js} +8 -6
  243. package/dist/{chunk-LGBMTVNT.js → chunk-YB5AKYVQ.js} +7 -5
  244. package/dist/{chunk-JB5LINEM.js → chunk-YDDLVBQ4.js} +3 -3
  245. package/dist/{chunk-PAQ2AS5E.js → chunk-YF6N45QN.js} +1 -1
  246. package/dist/{chunk-WMTRHUI5.js → chunk-YHWX5LPT.js} +23 -21
  247. package/dist/{chunk-KQGURXFU.js → chunk-YLZNTVZR.js} +36 -13
  248. package/dist/{chunk-NY2XSR5K.js → chunk-YUJTOALL.js} +118 -18
  249. package/dist/{chunk-VZALIKIF.js → chunk-Z5YDTIWQ.js} +19 -16
  250. package/dist/{chunk-LDLL7LB3.js → chunk-ZCU2UY47.js} +24 -22
  251. package/dist/{chunk-OWNCM4ZN.js → chunk-ZIAYNHHE.js} +197 -17
  252. package/dist/{chunk-WJF2CS6M.js → chunk-ZJ2W2RDE.js} +7 -5
  253. package/dist/{chunk-REWWDVQB.js → chunk-ZRQHSMPK.js} +6 -4
  254. package/dist/{chunk-O7XLYEFA.js → chunk-ZSD75FYI.js} +57 -23
  255. package/dist/chunk-ZSNNF26J.js +220 -0
  256. package/dist/{chunk-BQ4SQQC6.js → chunk-ZX6RAGE6.js} +11 -9
  257. package/dist/files.json +583 -515
  258. package/dist/packages/sdk/npm/index.js +6428 -4882
  259. package/dist/packages/ui/dist/assets/{elk-api-CIf-0gz5.js → elk-api--rH6Kdl4.js} +2 -2
  260. package/dist/packages/ui/dist/assets/index-Bf2immpE.css +1 -0
  261. package/dist/packages/ui/dist/assets/index-CH4nGIW3.js +62 -0
  262. package/dist/packages/ui/dist/index.html +2 -2
  263. package/package.json +6 -6
  264. package/dist/chunk-2SKB4O2E.js +0 -59
  265. package/dist/chunk-4U276ICE.js +0 -39
  266. package/dist/chunk-6H3Z5JHH.js +0 -64
  267. package/dist/chunk-AFZ3QA6W.js +0 -47
  268. package/dist/chunk-AVTBS4OW.js +0 -49
  269. package/dist/chunk-C4R4JLHE.js +0 -40
  270. package/dist/chunk-CBGGOQWU.js +0 -82
  271. package/dist/chunk-CMDXGQTS.js +0 -47
  272. package/dist/chunk-DLOBCJL6.js +0 -48
  273. package/dist/chunk-GIW4ZVDB.js +0 -39
  274. package/dist/chunk-IP74LCOQ.js +0 -57
  275. package/dist/chunk-IPHHDDC6.js +0 -45
  276. package/dist/chunk-KJXD4PNL.js +0 -50
  277. package/dist/chunk-KN5BXMWN.js +0 -44
  278. package/dist/chunk-MFHL5URL.js +0 -31
  279. package/dist/chunk-NXJ5URP6.js +0 -51
  280. package/dist/chunk-OMI6FPPN.js +0 -43
  281. package/dist/chunk-ONUPY3H6.js +0 -53
  282. package/dist/chunk-OTLDSZDV.js +0 -69
  283. package/dist/chunk-PSOFBQWB.js +0 -42
  284. package/dist/chunk-T4YPZIQN.js +0 -36
  285. package/dist/chunk-TUULXQRW.js +0 -420
  286. package/dist/chunk-WNKPRSGI.js +0 -36
  287. package/dist/packages/ui/dist/assets/index-CoK_Dl0D.js +0 -47
  288. package/dist/packages/ui/dist/assets/index-Dw20IRhQ.css +0 -1
  289. package/dist/{chunk-24XLDU72.js → chunk-PXMV2LLY.js} +3 -3
@@ -5,30 +5,31 @@ var __atticusUrl = (p) => new URL("./" + p, import.meta.url).href;
5
5
  var __atticusPath = (p) => __atticusFileURLToPath(__atticusUrl(p));
6
6
  import {
7
7
  readOpenApiDocument
8
- } from "./chunk-CQDGOPGH.js";
8
+ } from "./chunk-5FPAKAGE.js";
9
9
  import {
10
10
  globToRegExp
11
- } from "./chunk-3NFFJL5D.js";
11
+ } from "./chunk-IJQHBK76.js";
12
12
  import {
13
13
  DECLARED_TOPIC,
14
- DEFAULT_CONVENTIONS,
15
14
  Fact,
16
15
  FactId,
17
16
  JOINED_BY_AI,
17
+ JOINED_BY_BASE_PATH,
18
18
  JOINED_BY_PERSON,
19
19
  JOINED_TO_SHARED_MAP,
20
+ JOIN_GUESS_FLAGS,
20
21
  JOIN_HOW_FLAGS,
21
22
  LINK_EVIDENCE_NOT_GAPS,
22
23
  MOCK_FILE,
23
- NEVER_CHECKED_STEPS,
24
24
  SHARED_MAP_EVIDENCE,
25
25
  citedFiles,
26
26
  claimOnLines,
27
27
  clusterServiceAddress,
28
28
  decodeText,
29
+ dependencyLinkId,
29
30
  factIdPart,
30
31
  forwardSlashes,
31
- gatewayBundleTest,
32
+ hasSecretShape,
32
33
  isBinaryText,
33
34
  isLfsPointer,
34
35
  isPatternPath,
@@ -36,8 +37,7 @@ import {
36
37
  lineNamesClaim,
37
38
  linksFor,
38
39
  listRepoFilesSync,
39
- normalizePath,
40
- notDeviceName,
40
+ looksLikeSecret,
41
41
  noteProblem,
42
42
  partsBuildWord,
43
43
  partsNamePath,
@@ -48,9 +48,16 @@ import {
48
48
  redactSecrets,
49
49
  staleCite,
50
50
  toCanonicalYaml,
51
- tokenUnits,
51
+ tokenUnits
52
+ } from "./chunk-GJVCBTSO.js";
53
+ import {
54
+ DEFAULT_CONVENTIONS,
55
+ NEVER_CHECKED_STEPS,
56
+ gatewayBundleTest,
57
+ normalizePath,
58
+ notDeviceName,
52
59
  underFolders
53
- } from "./chunk-Q2TECDIT.js";
60
+ } from "./chunk-QFDPX6C4.js";
54
61
 
55
62
  // packages/verify/dist/source.js
56
63
  import { lstatSync, readFileSync, realpathSync, statSync } from "node:fs";
@@ -166,6 +173,269 @@ function tooBigToRead(source, path) {
166
173
  return n !== void 0 && n > MAX_SOURCE_BYTES;
167
174
  }
168
175
 
176
+ // packages/verify/dist/build-coords.js
177
+ var POM = /(^|\/)pom\.xml$|\.pom$/i;
178
+ var GRADLE_BUILD = /(^|\/)build\.gradle(\.kts)?$/i;
179
+ var GRADLE_SETTINGS = /(^|\/)settings\.gradle(\.kts)?$/i;
180
+ var isPomFile = (p) => POM.test(p.replace(/\\/g, "/"));
181
+ var isGradleFile = (p) => GRADLE_BUILD.test(p.replace(/\\/g, "/")) || GRADLE_SETTINGS.test(p.replace(/\\/g, "/"));
182
+ var isBuildFile = (p) => isPomFile(p) || isGradleFile(p);
183
+ var TAG = /<(\/?)([A-Za-z_][\w.:-]*)([^>]*?)(\/?)>/g;
184
+ function pomCoordinates(lines) {
185
+ const out = { dependencies: [] };
186
+ const stack = [];
187
+ let inComment = false;
188
+ const names = () => stack.map((f) => f.name);
189
+ lines.forEach((raw, i) => {
190
+ const n = i + 1;
191
+ let line = "";
192
+ let rest = raw;
193
+ while (rest.length) {
194
+ if (inComment) {
195
+ const end = rest.indexOf("-->");
196
+ if (end < 0)
197
+ break;
198
+ rest = rest.slice(end + 3);
199
+ inComment = false;
200
+ continue;
201
+ }
202
+ const start = rest.indexOf("<!--");
203
+ if (start < 0) {
204
+ line += rest;
205
+ break;
206
+ }
207
+ line += rest.slice(0, start);
208
+ rest = rest.slice(start + 4);
209
+ inComment = true;
210
+ }
211
+ let last = 0;
212
+ for (const m of line.matchAll(TAG)) {
213
+ const text = line.slice(last, m.index);
214
+ last = m.index + m[0].length;
215
+ const top2 = stack[stack.length - 1];
216
+ if (top2 && text.trim() && !top2.text) {
217
+ top2.text = text.trim();
218
+ top2.textLine = n;
219
+ }
220
+ if (m[2].startsWith("?") || m[0].startsWith("<!"))
221
+ continue;
222
+ const close = m[1] === "/";
223
+ const selfClosing = m[4] === "/";
224
+ if (!close) {
225
+ if (top2)
226
+ top2.children = true;
227
+ if (selfClosing)
228
+ continue;
229
+ stack.push({ name: m[2], leaves: /* @__PURE__ */ new Map(), children: false, text: "", textLine: n });
230
+ continue;
231
+ }
232
+ const at = names().lastIndexOf(m[2]);
233
+ if (at < 0)
234
+ continue;
235
+ while (stack.length > at + 1)
236
+ stack.pop();
237
+ const done = stack.pop();
238
+ const parent = stack[stack.length - 1];
239
+ if (!done.children && done.text && parent)
240
+ parent.leaves.set(done.name, { value: done.text, line: done.textLine });
241
+ const path = [...names(), done.name];
242
+ if (done.name === "dependency") {
243
+ out.dependencies.push({
244
+ ...done.leaves.get("groupId") ? { group: done.leaves.get("groupId") } : {},
245
+ ...done.leaves.get("artifactId") ? { artifact: done.leaves.get("artifactId") } : {},
246
+ ...done.leaves.get("version") ? { version: done.leaves.get("version") } : {},
247
+ ...done.leaves.get("scope") ? { scope: done.leaves.get("scope") } : {},
248
+ managed: path.includes("dependencyManagement"),
249
+ plugin: path.includes("plugin") || path.includes("extension")
250
+ });
251
+ } else if (done.name === "parent" && path.length === 2 && path[0] === "project") {
252
+ if (done.leaves.get("groupId"))
253
+ out.parentGroup = done.leaves.get("groupId");
254
+ if (done.leaves.get("artifactId"))
255
+ out.parentArtifact = done.leaves.get("artifactId");
256
+ if (done.leaves.get("version"))
257
+ out.parentVersion = done.leaves.get("version");
258
+ } else if (done.name === "project" && path.length === 1) {
259
+ if (done.leaves.get("groupId"))
260
+ out.group = done.leaves.get("groupId");
261
+ if (done.leaves.get("artifactId"))
262
+ out.artifact = done.leaves.get("artifactId");
263
+ if (done.leaves.get("version"))
264
+ out.version = done.leaves.get("version");
265
+ }
266
+ }
267
+ const top = stack[stack.length - 1];
268
+ const tail = line.slice(last);
269
+ if (top && tail.trim() && !top.text) {
270
+ top.text = tail.trim();
271
+ top.textLine = n;
272
+ }
273
+ });
274
+ return out;
275
+ }
276
+ var QUOTED = `(['"])([^'"\\s]+)\\`;
277
+ var GRADLE_DEP = new RegExp(`^\\s*([A-Za-z][\\w]*)\\s*\\(?\\s*(?:(platform|enforcedPlatform)\\s*\\(\\s*)?${QUOTED}3`);
278
+ var GRADLE_MAP_DEP = /^\s*([A-Za-z]\w*)\s*\(?\s*group\s*[:=]\s*(['"])([^'"]+)\2\s*,\s*name\s*[:=]\s*(['"])([^'"]+)\4(?:\s*,\s*version\s*[:=]\s*(['"])([^'"]+)\6)?/;
279
+ var NOT_A_CONFIGURATION = /* @__PURE__ */ new Set(["id", "apply", "plugin", "include", "classpath", "group"]);
280
+ function scopeOfConfiguration(c, platform) {
281
+ if (platform)
282
+ return "import";
283
+ if (/^test/i.test(c))
284
+ return "test";
285
+ if (/^(compileOnly|annotationProcessor|kapt|compileOnlyApi)$/i.test(c))
286
+ return "provided";
287
+ if (/^runtimeOnly$/i.test(c))
288
+ return "runtime";
289
+ return "compile";
290
+ }
291
+ function gradleDependencyOn(line) {
292
+ const map = GRADLE_MAP_DEP.exec(line);
293
+ if (map && !NOT_A_CONFIGURATION.has(map[1]))
294
+ return {
295
+ configuration: map[1],
296
+ group: map[3],
297
+ name: map[5],
298
+ ...map[7] ? { version: map[7] } : {},
299
+ scope: scopeOfConfiguration(map[1], false)
300
+ };
301
+ const m = GRADLE_DEP.exec(line);
302
+ if (!m || NOT_A_CONFIGURATION.has(m[1]))
303
+ return void 0;
304
+ const parts = m[4].split(":");
305
+ if (parts.length < 2 || !parts[0] || !parts[1])
306
+ return void 0;
307
+ return {
308
+ configuration: m[1],
309
+ group: parts[0],
310
+ name: parts[1],
311
+ ...parts[2] ? { version: parts[2] } : {},
312
+ scope: scopeOfConfiguration(m[1], !!m[2])
313
+ };
314
+ }
315
+ function gradleGroupOn(line) {
316
+ return /^\s*(?:project\.)?group\s*=?\s*(['"])([^'"]+)\1\s*$/.exec(line)?.[2];
317
+ }
318
+ function gradleNameOn(line) {
319
+ return /^\s*(?:rootProject\.name|archivesBaseName|(?:base\.)?archivesName(?:\.set)?)\s*[=(]?\s*(['"])([^'"]+)\1\s*\)?\s*$/.exec(line)?.[2];
320
+ }
321
+ var PROJECT_GROUP = /^\$\{(project\.|pom\.)?groupId\}$/;
322
+ var citedLine = (f, file, line) => f.cite.file === file && f.cite.line === line || (f.cite.with ?? []).some((p) => p.file === file && p.line === line);
323
+ function buildCoordinatesProblem(f, linesOf2) {
324
+ const file = f.cite.file;
325
+ const label = `${f.kind} ${f.id}`;
326
+ const lines = linesOf2(file);
327
+ if (!lines)
328
+ return void 0;
329
+ const where = `${file}:${f.cite.line}`;
330
+ if (isPomFile(file))
331
+ return pomProblem(f, label, where, pomCoordinates(lines));
332
+ if (isGradleFile(file))
333
+ return gradleProblem(f, label, where, lines, linesOf2);
334
+ return `${label} cites ${file}, which is no build file Atticus reads coordinates from: cite the pom.xml, build.gradle or settings.gradle line that writes them`;
335
+ }
336
+ function pomProblem(f, label, where, pom) {
337
+ const line = f.cite.line;
338
+ const file = f.cite.file;
339
+ if (f.kind === "artifact") {
340
+ if (pom.artifact?.line !== line) {
341
+ const dep2 = pom.dependencies.find((d) => d.artifact?.line === line);
342
+ const what = dep2 ? `a dependency's <artifactId> (${dep2.artifact.value})` : pom.parentArtifact?.line === line ? `the <parent>'s <artifactId> (${pom.parentArtifact.value})` : "not the project's own <artifactId>";
343
+ return `${label} says ${where} is the coordinates the build publishes, and that line is ${what}${pom.artifact ? `: the project's own is at line ${pom.artifact.line}` : ""}`;
344
+ }
345
+ if (pom.artifact.value !== f.name)
346
+ return `${label} names "${f.name}", and ${where} writes the project's artifactId as "${pom.artifact.value}"`;
347
+ const group2 = pom.group ?? pom.parentGroup;
348
+ if (!group2)
349
+ return `${label} names group "${f.group}", and ${file} writes no groupId of the project or its <parent>`;
350
+ if (group2.value !== f.group)
351
+ return `${label} names group "${f.group}", and ${file}:${group2.line} writes "${group2.value}"${pom.group ? "" : " (the <parent>'s, which the project inherits)"}`;
352
+ if (!citedLine(f, file, group2.line))
353
+ return `${label}: the group is written at ${file}:${group2.line}${pom.group ? "" : " (the <parent>'s)"}; cite that line in cite.with`;
354
+ return void 0;
355
+ }
356
+ const dep = pom.dependencies.find((d) => d.artifact?.line === line);
357
+ if (!dep) {
358
+ const what = pom.artifact?.line === line ? "the project's own <artifactId>" : pom.parentArtifact?.line === line ? "the <parent>'s <artifactId>" : "no dependency's <artifactId>";
359
+ return `${label} says ${where} declares a dependency, and that line is ${what}: cite the <artifactId> line of the <dependency> in <dependencies>`;
360
+ }
361
+ if (dep.managed)
362
+ return `${label} cites ${where}, a <dependencyManagement> entry, which only pins a version: cite the dependency where <dependencies> declares it`;
363
+ if (dep.plugin)
364
+ return `${label} cites ${where}, a dependency of a build plugin, not of the component: leave it out`;
365
+ if (dep.artifact.value !== f.name)
366
+ return `${label} names "${f.name}", and ${where} declares "${dep.artifact.value}"`;
367
+ if (!dep.group)
368
+ return `${label}: the <dependency> at ${where} writes no <groupId>`;
369
+ const ownGroup = pom.group ?? pom.parentGroup;
370
+ const group = PROJECT_GROUP.test(dep.group.value) ? ownGroup : dep.group;
371
+ if (!group || group.value !== f.group)
372
+ return `${label} names group "${f.group}", and the <dependency> at ${where} writes "${dep.group.value}"${group && group !== dep.group ? ` (${group.value})` : ""}`;
373
+ if (!citedLine(f, file, dep.group.line))
374
+ return `${label}: the dependency's group is written at ${file}:${dep.group.line}; cite that line in cite.with`;
375
+ const declared = dep.scope?.value ?? "compile";
376
+ if (declared !== (f.scope ?? "compile"))
377
+ return `${label} says scope ${f.scope ?? "compile"}, and the <dependency> at ${where} declares ${declared}${dep.scope ? ` (${file}:${dep.scope.line})` : ""}`;
378
+ return void 0;
379
+ }
380
+ function gradleProblem(f, label, where, lines, linesOf2) {
381
+ const text = lines[f.cite.line - 1] ?? "";
382
+ if (f.kind === "dependency") {
383
+ const d = gradleDependencyOn(text);
384
+ if (!d)
385
+ return `${label} says ${where} declares a dependency, and that line declares none: cite the line in dependencies { } that names it`;
386
+ if (d.group !== f.group || d.name !== f.name)
387
+ return `${label} names "${f.group}:${f.name}", and ${where} declares "${d.group}:${d.name}"`;
388
+ if (d.scope !== (f.scope ?? "compile"))
389
+ return `${label} says scope ${f.scope ?? "compile"}, and ${where} declares it with ${d.configuration} (${d.scope})`;
390
+ return void 0;
391
+ }
392
+ const name = gradleNameOn(text);
393
+ if (name === void 0)
394
+ return `${label} says ${where} is the coordinates the build publishes, and that line sets no project name: cite rootProject.name in settings.gradle, or archivesBaseName`;
395
+ if (name !== f.name)
396
+ return `${label} names "${f.name}", and ${where} sets "${name}"`;
397
+ const parts = [{ file: f.cite.file, line: f.cite.line }, ...f.cite.with ?? []];
398
+ const groups = parts.flatMap((p) => {
399
+ const g2 = gradleGroupOn(linesOf2(p.file)?.[p.line - 1] ?? "");
400
+ return g2 === void 0 ? [] : [{ ...p, group: g2 }];
401
+ });
402
+ if (!groups.length)
403
+ return `${label}: no line it cites sets the group; cite the build.gradle line that does (group = '${f.group}') in cite.with`;
404
+ const g = groups[0];
405
+ if (g.group !== f.group)
406
+ return `${label} names group "${f.group}", and ${g.file}:${g.line} sets "${g.group}"`;
407
+ return void 0;
408
+ }
409
+ function buildUnrecorded(files, linesOf2, kept) {
410
+ const cited = new Set(kept.filter((f) => f.kind === "artifact" || f.kind === "dependency").map((f) => `${f.cite.file}:${f.cite.line}`));
411
+ const out = [];
412
+ const add = (file, line, kind, c) => {
413
+ if (!cited.has(`${file}:${line}`))
414
+ out.push({ cite: `${file}:${line}`, kind, coordinates: c });
415
+ };
416
+ for (const file of [...files].sort()) {
417
+ const lines = linesOf2(file);
418
+ if (!lines)
419
+ continue;
420
+ if (isPomFile(file)) {
421
+ const pom = pomCoordinates(lines);
422
+ const group = pom.group ?? pom.parentGroup;
423
+ if (pom.artifact)
424
+ add(file, pom.artifact.line, "artifact", `${group?.value ?? "?"}:${pom.artifact.value}`);
425
+ for (const d of pom.dependencies)
426
+ if (!d.managed && !d.plugin && d.artifact)
427
+ add(file, d.artifact.line, "dependency", `${d.group?.value ?? "?"}:${d.artifact.value}`);
428
+ } else if (GRADLE_BUILD.test(file.replace(/\\/g, "/"))) {
429
+ lines.forEach((l, i) => {
430
+ const d = gradleDependencyOn(l);
431
+ if (d && d.scope !== "import")
432
+ add(file, i + 1, "dependency", `${d.group}:${d.name}`);
433
+ });
434
+ }
435
+ }
436
+ return out;
437
+ }
438
+
169
439
  // packages/verify/dist/frameworks.js
170
440
  var FRAMEWORKS = [
171
441
  "spring",
@@ -618,7 +888,7 @@ function applyCorrections(facts, corrections) {
618
888
  const p = outsidePairingFor(as, corrections);
619
889
  if (!p)
620
890
  return f;
621
- if (over && over.at > p.at && over.set?.to !== void 0)
891
+ if (over && over.set?.to !== void 0 && (over.at > p.at || !!p.ai && !over.ai))
622
892
  return f;
623
893
  const fixed = correctedFact(f, { ...p, action: "edit", set: { to: p.link.system } });
624
894
  if (typeof fixed === "string") {
@@ -1530,201 +1800,67 @@ function pageRouteMatches(file, lines, exists, path) {
1530
1800
  const route = pageRouteOf(file, lines, exists);
1531
1801
  if (route === void 0)
1532
1802
  return false;
1533
- const norm = (p) => normalizePath(p.replace(/\{([^}:?]*)[^}]*\}/g, "{$1}")).toLowerCase() || "/";
1534
- return norm(route) === norm(path);
1803
+ const norm2 = (p) => normalizePath(p.replace(/\{([^}:?]*)[^}]*\}/g, "{$1}")).toLowerCase() || "/";
1804
+ return norm2(route) === norm2(path);
1535
1805
  }
1536
1806
 
1537
- // packages/verify/dist/reachable.js
1538
- var CODE = /\.(java|kt|kts|scala|groovy|cs|vb|fs|py|rb|go|rs|php|swift|ts|tsx|js|mjs|cjs|dart)$/i;
1539
- var MODEL_DIR = /(^|\/)(models?|dtos?|payloads?|schemas?|pojos?|beans|viewmodels?)\//i;
1540
- var MODEL_NAME = /(dto|request|response|payload|model|body)$/i;
1541
- var MODEL_PART = /[._-](dto|model|schema|payload|request|response)\.[^/.]+$/i;
1542
- var MAPS_TABLE = /@Entity\b|@Table\b|@Document\b|\[Table\(|__tablename__|models\.Model\b|@Entity\(|\bgorm\.Model\b/;
1543
- var ROOT_PART = /[._-](controller|resolver|gateway|handlers?|router|routes?|consumer|listener|subscriber|client|publisher|producer|endpoints?)\.[^/.]+$/i;
1544
- var CLIENT_NAME = /(client|gateway|publisher|producer|sender|feign|proxy|connector)$/i;
1545
- var CLIENT_DIR = /(^|\/)(clients?|gateways?|integrations?|publishers?|producers?|outbound)\//i;
1546
- var base = (path) => path.slice(path.lastIndexOf("/") + 1);
1547
- var stem = (path) => {
1548
- const b = base(path);
1549
- const dot = b.indexOf(".");
1550
- return dot > 0 ? b.slice(0, dot) : b;
1551
- };
1552
- function isModelFile(path, text) {
1553
- if (!CODE.test(path) || readingRank(path) === 5)
1554
- return false;
1555
- if (!MODEL_DIR.test(path) && !MODEL_NAME.test(stem(path)) && !MODEL_PART.test(path))
1556
- return false;
1557
- return text === void 0 || !MAPS_TABLE.test(text);
1558
- }
1559
- var ENTRY_POINT_NAME = /(controller|resource|router|routes?|handlers?|listener|consumer|subscriber|endpoints?|servlet|webhook|resolver)$/i;
1560
- var ENTRY_POINT_DIR = /(^|\/)(controllers?|routes|routers|handlers|endpoints|listeners|consumers)\//i;
1561
- var ENTRY_POINT_PART = /[._-](controller|resolver|handlers?|router|routes?|consumer|listener|subscriber|endpoints?)\.[^/.]+$/i;
1562
- function isEntryPointFile(path) {
1563
- if (!CODE.test(path) || readingRank(path) === 5 || isModelFile(path))
1564
- return false;
1565
- return ENTRY_POINT_NAME.test(stem(path)) || ENTRY_POINT_DIR.test(path) || ENTRY_POINT_PART.test(path);
1566
- }
1567
- function isRootFile(path) {
1568
- if (!CODE.test(path) || readingRank(path) === 5 || isModelFile(path))
1569
- return false;
1570
- return readingRank(path) === 2 || isEntryPointFile(path) || ROOT_PART.test(path) || CLIENT_NAME.test(stem(path)) || CLIENT_DIR.test(path);
1571
- }
1572
- var DECLARES = /\b(?:class|record|interface|struct|enum|object)\s+([A-Za-z_][A-Za-z0-9_]*)|^\s*(?:export\s+)?(?:declare\s+)?type\s+([A-Za-z_][A-Za-z0-9_]*)/gm;
1573
- var IDENT = /[A-Za-z_][A-Za-z0-9_]*/g;
1574
- function declaredTypes(path, text) {
1575
- const out = [];
1576
- const s = stem(path);
1577
- if (/^[A-Z][A-Za-z0-9_]*$/.test(s))
1578
- out.push(s);
1579
- for (const m of text.matchAll(DECLARES)) {
1580
- const n = m[1] ?? m[2];
1581
- if (n && !out.includes(n))
1582
- out.push(n);
1583
- }
1584
- return out;
1585
- }
1586
- function identifiers(text) {
1587
- return [...new Set(text.match(IDENT) ?? [])];
1588
- }
1589
- var NOT_REACHED_WHY = "model classes no entry point, call or field fact reaches (ADR 0169): left out of the read; atticus map <repo> --models all reads them";
1590
- function reachableModels(o) {
1591
- const texts = /* @__PURE__ */ new Map();
1592
- const textOf = (p) => {
1593
- if (!texts.has(p))
1594
- texts.set(p, o.read(p) ?? "");
1595
- return texts.get(p);
1596
- };
1597
- const ordered = readingOrder(o.paths);
1598
- const models = ordered.filter((p) => isModelFile(p, textOf(p))).sort();
1599
- const isModel = new Set(models);
1600
- const byName = /* @__PURE__ */ new Map();
1601
- const declared = /* @__PURE__ */ new Map();
1602
- for (const p of models) {
1603
- const names = declaredTypes(p, textOf(p));
1604
- declared.set(p, names);
1605
- for (const n of names)
1606
- byName.set(n, [...byName.get(n) ?? [], p]);
1607
- }
1608
- const known = new Set(o.paths);
1609
- const roots = [];
1610
- const addRoot = (p) => {
1611
- if (known.has(p) && !isModel.has(p) && !roots.includes(p))
1612
- roots.push(p);
1613
- };
1614
- const facts = o.facts ?? [];
1615
- const entries = o.from === "entries";
1616
- const calls2 = new Set(facts.filter((f) => f.kind === "call").map((f) => f.id));
1617
- for (const f of facts)
1618
- if (f.kind === "entry" || f.kind === "call" && !entries)
1619
- for (const p of citedFiles(f))
1620
- addRoot(p);
1621
- for (const p of ordered)
1622
- if (entries ? isEntryPointFile(p) : isRootFile(p))
1623
- addRoot(p);
1624
- const reached = /* @__PURE__ */ new Map();
1625
- const queue = [];
1626
- const reach = (names, from, own = []) => {
1627
- for (const n of names) {
1628
- if (own.includes(n))
1629
- continue;
1630
- for (const p of byName.get(n) ?? []) {
1631
- const r = reached.get(p);
1632
- if (r) {
1633
- if (r.from === from && !r.types.includes(n))
1634
- r.types.push(n);
1635
- continue;
1636
- }
1637
- reached.set(p, { path: p, types: [n], from });
1638
- queue.push(p);
1639
- }
1807
+ // packages/verify/dist/secrets.js
1808
+ var CONFIG_FILE = /\.(ya?ml|properties|json|xml|config|env|ini|toml|conf|cfg)$|(^|\/)\.env(\.[^/]*)?$|(^|\/)credentials?$/i;
1809
+ var isConfigFile = (path) => CONFIG_FILE.test(path.replace(/\\/g, "/"));
1810
+ var PLACEHOLDER = /^(<[^>]*>|\*+|x{3,}|changeme|change-me|secret|password|todo|tbd|none|null|nil|dummy|example|sample|test|redacted|your[-_ ].*)$/i;
1811
+ var KEY_VALUE = /^\s*(?:-\s+)?(?:export\s+)?["']?([A-Za-z0-9_.\-[\]]+)["']?\s*[:=]\s*(.*?)\s*,?\s*$/;
1812
+ var XML_ELEMENT = /<([A-Za-z_][\w.-]*)>([^<]+)<\/\1>/g;
1813
+ var XML_NAMED = /\b(?:key|name)\s*=\s*"([^"]+)"\s+value\s*=\s*"([^"]*)"/g;
1814
+ var CONNECTION_PAIR = /(?:^|[;"'])\s*([A-Za-z][A-Za-z0-9 _.-]*?)\s*=\s*([^;"'<>\s][^;"'<>]*)/g;
1815
+ var TOKEN_VALUE_KEY = /^(value|val)$/i;
1816
+ var TOKEN_NAME = /^\s*"(xpath|name|key)"\s*:\s*"([^"]+)"/;
1817
+ function isReference(value) {
1818
+ return /^(vault|env|secret|ref|arn|kms|sm|gcp-sm|azure-kv|classpath\*?|file):/i.test(value) || /\$\{|\{\{/.test(value) || /^(~|\.{1,2})?\/[\w.\-/]+$/.test(value) || /^[\w.-]+(\/[\w.-]+)+\.[A-Za-z0-9]{1,10}$/.test(value);
1819
+ }
1820
+ var unquote = (v) => v.replace(/\s+#.*$/, "").replace(/^["']|["']$/g, "").trim();
1821
+ function tokenKeyNear(lines, i) {
1822
+ for (const step of [-1, 1])
1823
+ for (let j = i + step; j >= 0 && j < lines.length && Math.abs(j - i) <= 4; j += step) {
1824
+ const l = lines[j];
1825
+ const m = TOKEN_NAME.exec(l);
1826
+ if (m)
1827
+ return m[2];
1828
+ if (/[{}]/.test(l))
1829
+ break;
1640
1830
  }
1641
- };
1642
- for (const p of roots)
1643
- reach(identifiers(textOf(p)), p);
1644
- for (const f of facts) {
1645
- for (const p of citedFiles(f))
1646
- if (isModel.has(p) && !reached.has(p)) {
1647
- reached.set(p, { path: p, types: [...(declared.get(p) ?? []).slice(0, 1)], from: f.id });
1648
- queue.push(p);
1649
- }
1650
- if (f.kind === "field" && !(entries && calls2.has(f.owner)))
1651
- reach(identifiers([f.type ?? "", f.transform === "message type" ? f.name : ""].join(" ")), f.id);
1652
- }
1653
- const rooted = roots.length > 0 || reached.size > 0;
1654
- if (!rooted)
1655
- return {
1656
- rooted,
1657
- roots,
1658
- reached: models.map((p) => ({ path: p, types: declared.get(p) ?? [], from: "" })),
1659
- notReached: [],
1660
- models: models.length
1661
- };
1662
- for (let i = 0; i < queue.length; i++) {
1663
- const p = queue[i];
1664
- reach(identifiers(textOf(p)), p, declared.get(p));
1665
- }
1666
- return {
1667
- rooted,
1668
- roots,
1669
- reached: queue.map((p) => reached.get(p)),
1670
- notReached: models.filter((p) => !reached.has(p)),
1671
- models: models.length
1672
- };
1673
- }
1674
-
1675
- // packages/verify/dist/method.js
1676
- var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
1677
- function wordsOf(line) {
1678
- return line.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").toLowerCase().split(/[^a-z]+/).filter(Boolean);
1679
- }
1680
- function methodOnLines(method, lines) {
1681
- const m = method.toLowerCase();
1682
- return lines.some((l) => wordsOf(l).includes(m));
1831
+ return void 0;
1683
1832
  }
1684
- var CHAIN_LINES = 8;
1685
- var CONTINUES = /^\s*\??\./;
1686
- function chainOf(file, line) {
1687
- const at = (n) => file?.[n - 1];
1688
- const cited = at(line);
1689
- if (cited === void 0)
1833
+ function liveSecretsIn(file, lines) {
1834
+ if (!isConfigFile(file))
1690
1835
  return [];
1691
- const out = [cited];
1692
- for (let n = line, k = 0; k < CHAIN_LINES && CONTINUES.test(at(n) ?? ""); k++, n--) {
1693
- const above = at(n - 1);
1694
- if (above === void 0)
1695
- break;
1696
- out.push(above);
1697
- }
1698
- for (let n = line + 1, k = 0; k < CHAIN_LINES && CONTINUES.test(at(n) ?? ""); k++, n++)
1699
- out.push(at(n));
1836
+ const out = [];
1837
+ lines.forEach((text, i) => {
1838
+ if (/^\s*(#|\/\/|;|<!--)/.test(text))
1839
+ return;
1840
+ const pairs = [];
1841
+ const kv = KEY_VALUE.exec(text);
1842
+ if (kv) {
1843
+ const key = TOKEN_VALUE_KEY.test(kv[1]) ? tokenKeyNear(lines, i) ?? kv[1] : kv[1];
1844
+ pairs.push({ key, value: unquote(kv[2]) });
1845
+ }
1846
+ for (const m of text.matchAll(XML_ELEMENT))
1847
+ pairs.push({ key: m[1], value: m[2].trim() });
1848
+ for (const m of text.matchAll(XML_NAMED))
1849
+ pairs.push({ key: m[1], value: m[2].trim() });
1850
+ if (text.includes(";"))
1851
+ for (const m of text.matchAll(CONNECTION_PAIR))
1852
+ pairs.push({ key: m[1].trim(), value: m[2].trim() });
1853
+ const named = pairs.find(({ key, value }) => value && !PLACEHOLDER.test(value) && // a key with a nested map under it, or an encrypted value (`{cipher}…`), sets nothing here
1854
+ !/^[{[]/.test(value) && !isReference(value) && looksLikeSecret(key, value));
1855
+ if (named) {
1856
+ out.push({ file, line: i + 1, key: named.key });
1857
+ return;
1858
+ }
1859
+ if (hasSecretShape(text))
1860
+ out.push({ file, line: i + 1, key: pairs[0]?.key ?? "(token)" });
1861
+ });
1700
1862
  return out;
1701
1863
  }
1702
- function methodUnseenOf(f, lines, factOf) {
1703
- if (f.kind !== "entry" && f.kind !== "call")
1704
- return void 0;
1705
- if (!f.method || !HTTP_METHODS.has(f.method.toUpperCase()))
1706
- return void 0;
1707
- const at = (file, line) => lines(file)?.[line - 1];
1708
- const route = f.kind === "call" && f.from ? factOf?.(f.from) : void 0;
1709
- const forwards = route?.kind === "entry" && route.method?.toUpperCase() === f.method.toUpperCase();
1710
- const looked = [
1711
- ...chainOf(lines(f.cite.file), f.cite.line),
1712
- at(f.cite.file, f.cite.line + 1),
1713
- ...(f.cite.with ?? []).map((p) => at(p.file, p.line)),
1714
- ...forwards ? [at(route.cite.file, route.cite.line), at(route.cite.file, route.cite.line + 1)] : []
1715
- ].filter((l) => l !== void 0);
1716
- if (methodOnLines(f.method, looked))
1717
- return void 0;
1718
- const cite2 = `${f.cite.file}:${f.cite.line}`;
1719
- const method = f.method.toUpperCase();
1720
- return {
1721
- id: f.id,
1722
- kind: f.kind,
1723
- method,
1724
- cite: cite2,
1725
- message: `${f.id} claims ${method}, which neither ${cite2}, the chain it is in, the next line, a cite.with line nor the route it forwards writes`
1726
- };
1727
- }
1728
1864
 
1729
1865
  // packages/verify/dist/skipped.js
1730
1866
  function notReadForSkipped(path, rules = DEFAULT_READ_RULES) {
@@ -1744,10 +1880,10 @@ var NOT_TOPIC_LAST = new Set("com org net io dev app ai co uk de fr in jp us eu
1744
1880
  var NOT_TOPIC_FIRST = new Set("com org net io java javax jakarta android androidx kotlin kotlinx scala sun microsoft system google apache spring springframework management server logging hibernate jdk www".split(" "));
1745
1881
  var DOTTED_TOPIC = /^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*){2,}$/;
1746
1882
  var SEPARATED_NAME = /^[A-Za-z][A-Za-z0-9_]*([._:-][A-Za-z0-9_]+)+$/;
1747
- var QUOTED = /(["'`])((?:\\.|(?!\1)[^\\\n])*)\1/g;
1748
- var KEY_VALUE = /^\s*-?\s*["']?([A-Za-z0-9_.\-[\]]+)["']?\s*[:=]\s*([^\s"'#]+)\s*$/;
1883
+ var QUOTED2 = /(["'`])((?:\\.|(?!\1)[^\\\n])*)\1/g;
1884
+ var KEY_VALUE2 = /^\s*-?\s*["']?([A-Za-z0-9_.\-[\]]+)["']?\s*[:=]\s*([^\s"'#]+)\s*$/;
1749
1885
  var ELEMENT_TEXT = /<([A-Za-z][\w:.-]*)[^>]*>([^<\s]+)<\/\1>/g;
1750
- var wordsOf2 = (line) => line.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").toLowerCase().split(/[^a-z]+/).filter(Boolean);
1886
+ var wordsOf = (line) => line.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").toLowerCase().split(/[^a-z]+/).filter(Boolean);
1751
1887
  var TOPIC_WORDS = /* @__PURE__ */ new Set([
1752
1888
  "topic",
1753
1889
  "topics",
@@ -1761,7 +1897,7 @@ var TOPIC_WORDS = /* @__PURE__ */ new Set([
1761
1897
  "exchanges"
1762
1898
  ]);
1763
1899
  var topicContext = (line) => {
1764
- const w = wordsOf2(line);
1900
+ const w = wordsOf(line);
1765
1901
  return w.some((x) => TOPIC_WORDS.has(x)) || w.join(" ").includes("routing key");
1766
1902
  };
1767
1903
  var BUILD_KEY_WORDS = new Set("scm git gitlab github bitbucket repository repositories repo registry mirror mirrors nexus artifactory snapshot snapshots distribution maven npm nuget pypi sonar sonarqube jenkins ci".split(" "));
@@ -1772,7 +1908,7 @@ var keysBefore = (prefix) => [
1772
1908
  ...[...prefix.matchAll(/["']?([A-Za-z][\w.-]*)["']?\s*[:=]/g)].map((m) => m[1]),
1773
1909
  ...[...prefix.matchAll(/\b([A-Za-z]\w*)\s*\{/g)].map((m) => m[1])
1774
1910
  ];
1775
- var isBuildUrl = (u, prefix) => /\.git\/?$/i.test(u) || /\bscm:\w+:$/i.test(prefix) || keysBefore(prefix).some((k) => wordsOf2(k).some((w) => BUILD_KEY_WORDS.has(w)));
1911
+ var isBuildUrl = (u, prefix) => /\.git\/?$/i.test(u) || /\bscm:\w+:$/i.test(prefix) || keysBefore(prefix).some((k) => wordsOf(k).some((w) => BUILD_KEY_WORDS.has(w)));
1776
1912
  var HEADER_ARG = /header\w*\s*(?:\.\s*\w+\s*)?\(\s*(?:(?:value|name)\s*=\s*)?$/i;
1777
1913
  var isHeaderName = (s, prefix) => /^x-/i.test(s) || HEADER_ARG.test(prefix.replace(/["'`]$/, ""));
1778
1914
  var cleanUrl = (u) => u.replace(/[.:]+$/, "").replace(/^([a-z0-9+.-]+:\/\/)[^/@\s]+@/i, "$1<redacted>@");
@@ -1863,11 +1999,11 @@ function candidatesIn(path, lines) {
1863
1999
  add("url", u);
1864
2000
  urls.push(m[0]);
1865
2001
  }
1866
- const strings2 = [...code2.matchAll(QUOTED)].map((m) => ({
2002
+ const strings2 = [...code2.matchAll(QUOTED2)].map((m) => ({
1867
2003
  s: m[2],
1868
2004
  before: code2.slice(0, m.index + 1)
1869
2005
  }));
1870
- const kv = KEY_VALUE.exec(code2);
2006
+ const kv = KEY_VALUE2.exec(code2);
1871
2007
  if (kv)
1872
2008
  strings2.push({ s: kv[2], before: "" });
1873
2009
  for (const m of code2.matchAll(ELEMENT_TEXT))
@@ -1880,125 +2016,537 @@ function candidatesIn(path, lines) {
1880
2016
  add("path", p);
1881
2017
  continue;
1882
2018
  }
1883
- const t = topicOf(s, context);
1884
- if (t && !isHeaderName(t, before))
1885
- add("topic", t);
1886
- }
1887
- });
1888
- return out;
1889
- }
1890
- var cleanUrlIn = (line) => line.replace(/\b([a-z0-9+.-]+:\/\/)[^/@\s"'`]+@/gi, "$1<redacted>@");
1891
- var normPath = (p) => normalizePath(p.replace(/(^|\/)%[sd](?=\/|$)/g, "$1{}"));
1892
- function indexFacts(facts) {
1893
- const at = /* @__PURE__ */ new Set();
1894
- const strings2 = /* @__PURE__ */ new Set();
1895
- const walk = (v) => {
1896
- if (typeof v === "string") {
1897
- if (v.length >= 3)
1898
- strings2.add(v);
1899
- return;
1900
- }
1901
- if (Array.isArray(v))
1902
- return v.forEach(walk);
1903
- if (v && typeof v === "object") {
1904
- const o = v;
1905
- if (typeof o.file === "string" && typeof o.line === "number")
1906
- at.add(`${o.file}:${o.line}`);
1907
- Object.values(o).forEach(walk);
2019
+ const t = topicOf(s, context);
2020
+ if (t && !isHeaderName(t, before))
2021
+ add("topic", t);
2022
+ }
2023
+ });
2024
+ return out;
2025
+ }
2026
+ var cleanUrlIn = (line) => line.replace(/\b([a-z0-9+.-]+:\/\/)[^/@\s"'`]+@/gi, "$1<redacted>@");
2027
+ var normPath = (p) => normalizePath(p.replace(/(^|\/)%[sd](?=\/|$)/g, "$1{}"));
2028
+ function indexFacts(facts) {
2029
+ const at = /* @__PURE__ */ new Set();
2030
+ const strings2 = /* @__PURE__ */ new Set();
2031
+ const walk = (v) => {
2032
+ if (typeof v === "string") {
2033
+ if (v.length >= 3)
2034
+ strings2.add(v);
2035
+ return;
2036
+ }
2037
+ if (Array.isArray(v))
2038
+ return v.forEach(walk);
2039
+ if (v && typeof v === "object") {
2040
+ const o = v;
2041
+ if (typeof o.file === "string" && typeof o.line === "number")
2042
+ at.add(`${o.file}:${o.line}`);
2043
+ Object.values(o).forEach(walk);
2044
+ }
2045
+ };
2046
+ facts.forEach(walk);
2047
+ const paths = /* @__PURE__ */ new Set();
2048
+ for (const s of strings2) {
2049
+ if (/\s/.test(s))
2050
+ continue;
2051
+ const u = /^[a-z0-9+.-]+:\/\/[^/]+(\/.*)?$/i.exec(s);
2052
+ const p = u ? u[1] : s.includes("/") ? s : void 0;
2053
+ if (p && p.length > 1)
2054
+ paths.add(`${normPath(p)}/`);
2055
+ }
2056
+ return { at, strings: [...strings2].map((s) => s.toLowerCase()), paths: [...paths] };
2057
+ }
2058
+ function factsCover(file, c, ix) {
2059
+ if ([c.line - 1, c.line, c.line + 1].some((n) => ix.at.has(`${file}:${n}`)))
2060
+ return true;
2061
+ if (c.kind === "path") {
2062
+ const p = `${normPath(c.value)}/`;
2063
+ return ix.paths.some((f) => f.includes(p));
2064
+ }
2065
+ const v = c.value.toLowerCase().replace(/\/+$/, "");
2066
+ return ix.strings.some((s) => s.includes(v));
2067
+ }
2068
+ var skippedOf = (file, c) => ({
2069
+ cite: `${file}:${c.line}`,
2070
+ kind: c.kind,
2071
+ value: c.value,
2072
+ text: c.text
2073
+ });
2074
+ var SPEC_MARK = /^\s*["']?(openapi|swagger)["']?\s*:/m;
2075
+ var SPEC_EXT = /\.(ya?ml|json)$/i;
2076
+ function specOpsUncoveredIn(file, text, facts) {
2077
+ if (!SPEC_EXT.test(file) || !SPEC_MARK.test(text.slice(0, 4e3)))
2078
+ return void 0;
2079
+ let doc;
2080
+ try {
2081
+ doc = readOpenApiDocument(text);
2082
+ } catch {
2083
+ return void 0;
2084
+ }
2085
+ if (!doc || !doc.operations.length)
2086
+ return void 0;
2087
+ const server = (() => {
2088
+ const s = doc.servers[0];
2089
+ if (!s)
2090
+ return "";
2091
+ const p = /^[a-z0-9+.-]+:\/\/[^/]+(\/.*)?$/i.exec(s)?.[1] ?? (s.startsWith("/") ? s : "");
2092
+ return p.replace(/\/+$/, "");
2093
+ })();
2094
+ const entries = facts.filter((f) => f.kind === "entry");
2095
+ const atLines = /* @__PURE__ */ new Set();
2096
+ for (const e of entries)
2097
+ for (const k of indexFacts([e]).at)
2098
+ atLines.add(k);
2099
+ const out = [];
2100
+ for (const op of doc.operations) {
2101
+ const lines = [op.methodLine, op.line].filter((n) => n !== void 0);
2102
+ if (lines.some((n) => [n - 1, n, n + 1].some((x) => atLines.has(`${file}:${x}`))))
2103
+ continue;
2104
+ const method = op.method.toUpperCase();
2105
+ const own = normPath(op.path);
2106
+ const full = normPath(`${server}${op.path}`);
2107
+ const covered = entries.some((e) => {
2108
+ if (e.method && e.method.toUpperCase() !== method)
2109
+ return false;
2110
+ const p = normPath(e.path);
2111
+ return p === own || p === full || p.endsWith(own) || p.split("/").length > 2 && own.endsWith(p);
2112
+ });
2113
+ if (covered)
2114
+ continue;
2115
+ const opId = op.node?.get?.("operationId");
2116
+ const line = op.methodLine ?? op.line ?? 1;
2117
+ out.push({
2118
+ spec: file,
2119
+ method,
2120
+ path: op.path,
2121
+ ...typeof opId === "string" ? { operationId: opId } : {},
2122
+ cite: `${file}:${line}`,
2123
+ message: `${file}:${line} declares ${method} ${op.path}${typeof opId === "string" ? ` (${opId})` : ""}, which no entry covers`
2124
+ });
2125
+ }
2126
+ return out;
2127
+ }
2128
+ var REVIEWED_HOLDS_SHOWN = 5;
2129
+ function reviewedHoldsOf(r, skipped) {
2130
+ const n = skipped.length;
2131
+ const first = skipped.slice(0, 3).map((s) => `${s.cite} (${s.value})`);
2132
+ return {
2133
+ path: r.path,
2134
+ why: r.why,
2135
+ count: n,
2136
+ skipped: skipped.slice(0, REVIEWED_HOLDS_SHOWN),
2137
+ message: `${r.line !== void 0 ? `line ${r.line}: ` : ""}${r.path} is reviewed as holding nothing to record, but ${n} ${n === 1 ? "line in it writes" : "lines in it write"} a path, URL or topic: ${first.join(", ")}${n > 3 ? ` and ${n - 3} more` : ""}`
2138
+ };
2139
+ }
2140
+
2141
+ // packages/verify/dist/settings-path.js
2142
+ var SETTINGS_FILE = /\.(ya?ml|properties|json|xml|config|conf|ini|toml|cfg|env)$|(^|\/)\.env(\.[^/]*)?$/i;
2143
+ var isSettingsFile = (path) => SETTINGS_FILE.test(path);
2144
+ var isYaml = (path) => /\.ya?ml$/i.test(path);
2145
+ var isProperties = (path) => /\.properties$/i.test(path);
2146
+ var escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2147
+ var YAML_KEY = /^(["']?)([^\s"'#:{}[\],&*!|>][^"'#:]*?)\1\s*:(?:\s+(.*))?$/;
2148
+ function yamlLine(text) {
2149
+ if (!text.trim() || /^\s*#/.test(text) || /^\s*(---|\.\.\.)\s*$/.test(text))
2150
+ return void 0;
2151
+ const lead = /^ */.exec(text)[0].length;
2152
+ const dash = /^ *-(\s+|$)/.exec(text);
2153
+ const col = dash ? dash[0].length : lead;
2154
+ const body = text.slice(col);
2155
+ const m = YAML_KEY.exec(body.trimEnd());
2156
+ const rest = m?.[3]?.trim();
2157
+ return {
2158
+ lead,
2159
+ col,
2160
+ item: !!dash,
2161
+ key: m?.[2]?.trim(),
2162
+ // a comment or an anchor after the key sets nothing
2163
+ rest: rest && !/^[#&]/.test(rest) ? rest : void 0
2164
+ };
2165
+ }
2166
+ function yamlPathAt(lines, line) {
2167
+ const at = yamlLine(lines[line - 1] ?? "");
2168
+ if (!at?.key)
2169
+ return void 0;
2170
+ const path = [at.key];
2171
+ let col = at.item ? at.lead : at.col;
2172
+ for (let j = line - 2; j >= 0 && col > 0; j--) {
2173
+ const l = lines[j];
2174
+ if (/^\s*(---|\.\.\.)\s*$/.test(l))
2175
+ break;
2176
+ const y = yamlLine(l);
2177
+ if (!y)
2178
+ continue;
2179
+ if (y.item && y.col === col) {
2180
+ col = y.lead;
2181
+ continue;
2182
+ }
2183
+ if (y.col >= col)
2184
+ continue;
2185
+ if (!y.key || y.rest)
2186
+ return void 0;
2187
+ path.unshift(y.key);
2188
+ col = y.lead;
2189
+ }
2190
+ if (col > 0)
2191
+ return void 0;
2192
+ return path.flatMap((k) => k.split("."));
2193
+ }
2194
+ function yamlChildren(lines, line) {
2195
+ const at = yamlLine(lines[line - 1] ?? "");
2196
+ if (!at?.key)
2197
+ return [];
2198
+ const out = [];
2199
+ let childCol;
2200
+ for (let j = line; j < lines.length; j++) {
2201
+ const y = yamlLine(lines[j]);
2202
+ if (!y)
2203
+ continue;
2204
+ if (y.lead <= at.col)
2205
+ break;
2206
+ childCol ??= y.col;
2207
+ if (y.col < childCol)
2208
+ break;
2209
+ if (y.col === childCol && y.key && !y.item)
2210
+ out.push(y.key);
2211
+ }
2212
+ return out;
2213
+ }
2214
+ function propertiesKeyAt(lines, line) {
2215
+ const l = lines[line - 1] ?? "";
2216
+ if (/^\s*[#!]/.test(l))
2217
+ return void 0;
2218
+ return /^\s*((?:\\.|[^\s=:\\])+)\s*[=:\s]/.exec(l)?.[1];
2219
+ }
2220
+ var sameSegs = (a, b) => a.length === b.length && a.every((s, i) => s === b[i]);
2221
+ var keySegments = (key) => key.trim().split(".").map((s) => s.replace(/\[[^\]]*\]$/, "")).filter(Boolean);
2222
+ var fieldNames = (seg) => [
2223
+ seg,
2224
+ seg.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase())
2225
+ ];
2226
+ var CONFIG_PROPS = /@ConfigurationProperties\s*\(\s*(?:(?:prefix|value)\s*=\s*)?"([^"]+)"/;
2227
+ function helperBuildsKey(key, cite2, linesOf2) {
2228
+ if (isSettingsFile(cite2.file))
2229
+ return false;
2230
+ const segs = keySegments(key);
2231
+ if (segs.length < 2 || segs.join(".") !== key.trim())
2232
+ return false;
2233
+ const last = segs[segs.length - 1];
2234
+ const prefix = segs.slice(0, -1);
2235
+ const line = linesOf2(cite2.file)?.[cite2.line - 1];
2236
+ if (line === void 0)
2237
+ return false;
2238
+ const code2 = isCommentLine(line) ? line : line.replace(/\/\*.*?\*\//g, "").replace(/(^|\s)\/\/.*$/, "");
2239
+ if (!new RegExp(`(^|[^A-Za-z0-9_$-])${escape(last)}($|[^A-Za-z0-9_$-])`).test(code2))
2240
+ return false;
2241
+ const parts = cite2.with ?? [];
2242
+ const files = [...new Set(parts.map((p) => p.file))];
2243
+ return files.some((file) => {
2244
+ const ls = linesOf2(file);
2245
+ if (!ls)
2246
+ return false;
2247
+ const here = parts.filter((p) => p.file === file);
2248
+ if (isYaml(file))
2249
+ return here.some((p) => {
2250
+ const at = yamlPathAt(ls, p.line);
2251
+ if (!at)
2252
+ return false;
2253
+ if (sameSegs(at, segs))
2254
+ return true;
2255
+ return sameSegs(at, prefix) && yamlChildren(ls, p.line).includes(last);
2256
+ });
2257
+ if (isProperties(file))
2258
+ return here.some((p) => propertiesKeyAt(ls, p.line) === segs.join("."));
2259
+ if (isSettingsFile(file))
2260
+ return false;
2261
+ return here.some((p) => {
2262
+ const m = CONFIG_PROPS.exec(ls[p.line - 1] ?? "");
2263
+ if (!m)
2264
+ return false;
2265
+ const pre = m[1].split(".");
2266
+ if (pre.length > prefix.length || !pre.every((s, i) => s === prefix[i]))
2267
+ return false;
2268
+ return prefix.slice(pre.length).every((seg) => here.some((q) => q.line > p.line && q.line <= p.line + 40 && fieldNames(seg).some((n) => new RegExp(`(^|[^A-Za-z0-9_$])${escape(n)}($|[^A-Za-z0-9_$])`).test(ls[q.line - 1] ?? ""))));
2269
+ });
2270
+ });
2271
+ }
2272
+ var norm = (s) => s.replace(/[‘’‚'"“”„`]/g, "").replace(/\s+/g, " ").trim();
2273
+ function enclosingObject(lines, line) {
2274
+ let depth = 0;
2275
+ let start = -1;
2276
+ for (let j = line - 1; j >= 0; j--) {
2277
+ const l = lines[j];
2278
+ for (let k = l.length - 1; k >= 0; k--) {
2279
+ if (l[k] === "}" && j !== line - 1)
2280
+ depth++;
2281
+ if (l[k] === "{") {
2282
+ if (depth === 0) {
2283
+ start = j;
2284
+ break;
2285
+ }
2286
+ depth--;
2287
+ }
2288
+ }
2289
+ if (start >= 0)
2290
+ break;
2291
+ }
2292
+ if (start < 0)
2293
+ return void 0;
2294
+ depth = 0;
2295
+ for (let j = start; j < lines.length; j++) {
2296
+ for (const ch of lines[j]) {
2297
+ if (ch === "{")
2298
+ depth++;
2299
+ if (ch === "}" && --depth === 0)
2300
+ return lines.slice(start, j + 1);
2301
+ }
2302
+ }
2303
+ return void 0;
2304
+ }
2305
+ function configLineProblem(f, linesOf2, listed2) {
2306
+ const lines = linesOf2(f.cite.file);
2307
+ if (!lines)
2308
+ return void 0;
2309
+ const at = lines[f.cite.line - 1] ?? "";
2310
+ const where = `${f.cite.file}:${f.cite.line}`;
2311
+ const segs = keySegments(f.key);
2312
+ const value = f.value === void 0 ? void 0 : norm(f.value);
2313
+ const has = (l) => value !== void 0 && norm(l).includes(value);
2314
+ if (f.key.trim().startsWith("/") && /(^|\/)config\.json$/i.test(f.cite.file)) {
2315
+ const dir = f.cite.file.replace(/[^/]*$/, "");
2316
+ if (!listed2().some((p) => p.startsWith(`${dir}apiproxy/`)))
2317
+ return `config ${where} is a config.json beside no gateway bundle (no ${dir}apiproxy/); a token's setting is read only from the bundle's own`;
2318
+ const obj = enclosingObject(lines, f.cite.line);
2319
+ const xpathRe = new RegExp(`"xpath"\\s*:\\s*"${escape(f.key.trim())}"`);
2320
+ if (!obj || !obj.some((l) => xpathRe.test(l)))
2321
+ return `the token at ${where} has no "xpath" of ${f.key}`;
2322
+ if (value !== void 0 && !obj.some((l) => /"value"\s*:/.test(l) && has(l)))
2323
+ return `the token at ${where} sets no such value; cite the token whose "value" it is`;
2324
+ return void 0;
2325
+ }
2326
+ if (isYaml(f.cite.file)) {
2327
+ const y = yamlLine(at);
2328
+ const path = yamlPathAt(lines, f.cite.line);
2329
+ if (y?.key && path && segs.length && keySegments(y.key).at(-1) === segs.at(-1)) {
2330
+ const tail = path.slice(path.length - segs.length);
2331
+ if (path.length < segs.length || !sameSegs(tail, segs))
2332
+ return `${where} sets ${path.join(".")}, not ${f.key}: the key's parents are not the lines above it`;
2333
+ if (value !== void 0 && y.rest && !/^[|>]/.test(y.rest)) {
2334
+ if (!has(y.rest))
2335
+ return `${where} sets ${y.key} to something other than the value claimed`;
2336
+ return void 0;
2337
+ }
2338
+ }
2339
+ }
2340
+ if (isProperties(f.cite.file)) {
2341
+ const k = propertiesKeyAt(lines, f.cite.line);
2342
+ if (k && k.split(".").at(-1) === segs.at(-1)) {
2343
+ if (k !== segs.join(".") && !k.endsWith(`.${segs.join(".")}`))
2344
+ return `${where} sets ${k}, not ${f.key}`;
2345
+ if (value !== void 0) {
2346
+ if (!has(at.slice(at.indexOf(k) + k.length)))
2347
+ return `${where} sets ${k} to something other than the value claimed`;
2348
+ return void 0;
2349
+ }
2350
+ }
2351
+ }
2352
+ if (value === void 0 || value === "")
2353
+ return void 0;
2354
+ const near = [f.cite.line - 1, f.cite.line, f.cite.line + 1].map((n) => lines[n - 1] ?? "");
2355
+ const partLines = (f.cite.with ?? []).map((p) => linesOf2(p.file)?.[p.line - 1] ?? "");
2356
+ if (![...near, ...partLines].some(has))
2357
+ return `${where} (or the line either side) and its parts don't write the value claimed`;
2358
+ return void 0;
2359
+ }
2360
+
2361
+ // packages/verify/dist/reachable.js
2362
+ var CODE = /\.(java|kt|kts|scala|groovy|cs|vb|fs|py|rb|go|rs|php|swift|ts|tsx|js|mjs|cjs|dart)$/i;
2363
+ var MODEL_DIR = /(^|\/)(models?|dtos?|payloads?|schemas?|pojos?|beans|viewmodels?)\//i;
2364
+ var MODEL_NAME = /(dto|request|response|payload|model|body)$/i;
2365
+ var MODEL_PART = /[._-](dto|model|schema|payload|request|response)\.[^/.]+$/i;
2366
+ var MAPS_TABLE = /@Entity\b|@Table\b|@Document\b|\[Table\(|__tablename__|models\.Model\b|@Entity\(|\bgorm\.Model\b/;
2367
+ var ROOT_PART = /[._-](controller|resolver|gateway|handlers?|router|routes?|consumer|listener|subscriber|client|publisher|producer|endpoints?)\.[^/.]+$/i;
2368
+ var CLIENT_NAME = /(client|gateway|publisher|producer|sender|feign|proxy|connector)$/i;
2369
+ var CLIENT_DIR = /(^|\/)(clients?|gateways?|integrations?|publishers?|producers?|outbound)\//i;
2370
+ var base = (path) => path.slice(path.lastIndexOf("/") + 1);
2371
+ var stem = (path) => {
2372
+ const b = base(path);
2373
+ const dot = b.indexOf(".");
2374
+ return dot > 0 ? b.slice(0, dot) : b;
2375
+ };
2376
+ function isModelFile(path, text) {
2377
+ if (!CODE.test(path) || readingRank(path) === 5)
2378
+ return false;
2379
+ if (!MODEL_DIR.test(path) && !MODEL_NAME.test(stem(path)) && !MODEL_PART.test(path))
2380
+ return false;
2381
+ return text === void 0 || !MAPS_TABLE.test(text);
2382
+ }
2383
+ var ENTRY_POINT_NAME = /(controller|resource|router|routes?|handlers?|listener|consumer|subscriber|endpoints?|servlet|webhook|resolver)$/i;
2384
+ var ENTRY_POINT_DIR = /(^|\/)(controllers?|routes|routers|handlers|endpoints|listeners|consumers)\//i;
2385
+ var ENTRY_POINT_PART = /[._-](controller|resolver|handlers?|router|routes?|consumer|listener|subscriber|endpoints?)\.[^/.]+$/i;
2386
+ function isEntryPointFile(path) {
2387
+ if (!CODE.test(path) || readingRank(path) === 5 || isModelFile(path))
2388
+ return false;
2389
+ return ENTRY_POINT_NAME.test(stem(path)) || ENTRY_POINT_DIR.test(path) || ENTRY_POINT_PART.test(path);
2390
+ }
2391
+ function isRootFile(path) {
2392
+ if (!CODE.test(path) || readingRank(path) === 5 || isModelFile(path))
2393
+ return false;
2394
+ return readingRank(path) === 2 || isEntryPointFile(path) || ROOT_PART.test(path) || CLIENT_NAME.test(stem(path)) || CLIENT_DIR.test(path);
2395
+ }
2396
+ var DECLARES = /\b(?:class|record|interface|struct|enum|object)\s+([A-Za-z_][A-Za-z0-9_]*)|^\s*(?:export\s+)?(?:declare\s+)?type\s+([A-Za-z_][A-Za-z0-9_]*)/gm;
2397
+ var IDENT = /[A-Za-z_][A-Za-z0-9_]*/g;
2398
+ function declaredTypes(path, text) {
2399
+ const out = [];
2400
+ const s = stem(path);
2401
+ if (/^[A-Z][A-Za-z0-9_]*$/.test(s))
2402
+ out.push(s);
2403
+ for (const m of text.matchAll(DECLARES)) {
2404
+ const n = m[1] ?? m[2];
2405
+ if (n && !out.includes(n))
2406
+ out.push(n);
2407
+ }
2408
+ return out;
2409
+ }
2410
+ function identifiers(text) {
2411
+ return [...new Set(text.match(IDENT) ?? [])];
2412
+ }
2413
+ var NOT_REACHED_WHY = "model classes no entry point, call or field fact reaches (ADR 0169): left out of the read; atticus map <repo> --models all reads them";
2414
+ function reachableModels(o) {
2415
+ const texts = /* @__PURE__ */ new Map();
2416
+ const textOf = (p) => {
2417
+ if (!texts.has(p))
2418
+ texts.set(p, o.read(p) ?? "");
2419
+ return texts.get(p);
2420
+ };
2421
+ const ordered = readingOrder(o.paths);
2422
+ const models = ordered.filter((p) => isModelFile(p, textOf(p))).sort();
2423
+ const isModel = new Set(models);
2424
+ const byName = /* @__PURE__ */ new Map();
2425
+ const declared = /* @__PURE__ */ new Map();
2426
+ for (const p of models) {
2427
+ const names = declaredTypes(p, textOf(p));
2428
+ declared.set(p, names);
2429
+ for (const n of names)
2430
+ byName.set(n, [...byName.get(n) ?? [], p]);
2431
+ }
2432
+ const known = new Set(o.paths);
2433
+ const roots = [];
2434
+ const addRoot = (p) => {
2435
+ if (known.has(p) && !isModel.has(p) && !roots.includes(p))
2436
+ roots.push(p);
2437
+ };
2438
+ const facts = o.facts ?? [];
2439
+ const entries = o.from === "entries";
2440
+ const calls2 = new Set(facts.filter((f) => f.kind === "call").map((f) => f.id));
2441
+ for (const f of facts)
2442
+ if (f.kind === "entry" || f.kind === "call" && !entries)
2443
+ for (const p of citedFiles(f))
2444
+ addRoot(p);
2445
+ for (const p of ordered)
2446
+ if (entries ? isEntryPointFile(p) : isRootFile(p))
2447
+ addRoot(p);
2448
+ const reached = /* @__PURE__ */ new Map();
2449
+ const queue = [];
2450
+ const reach = (names, from, own = []) => {
2451
+ for (const n of names) {
2452
+ if (own.includes(n))
2453
+ continue;
2454
+ for (const p of byName.get(n) ?? []) {
2455
+ const r = reached.get(p);
2456
+ if (r) {
2457
+ if (r.from === from && !r.types.includes(n))
2458
+ r.types.push(n);
2459
+ continue;
2460
+ }
2461
+ reached.set(p, { path: p, types: [n], from });
2462
+ queue.push(p);
2463
+ }
1908
2464
  }
1909
2465
  };
1910
- facts.forEach(walk);
1911
- const paths = /* @__PURE__ */ new Set();
1912
- for (const s of strings2) {
1913
- if (/\s/.test(s))
1914
- continue;
1915
- const u = /^[a-z0-9+.-]+:\/\/[^/]+(\/.*)?$/i.exec(s);
1916
- const p = u ? u[1] : s.includes("/") ? s : void 0;
1917
- if (p && p.length > 1)
1918
- paths.add(`${normPath(p)}/`);
2466
+ for (const p of roots)
2467
+ reach(identifiers(textOf(p)), p);
2468
+ for (const f of facts) {
2469
+ for (const p of citedFiles(f))
2470
+ if (isModel.has(p) && !reached.has(p)) {
2471
+ reached.set(p, { path: p, types: [...(declared.get(p) ?? []).slice(0, 1)], from: f.id });
2472
+ queue.push(p);
2473
+ }
2474
+ if (f.kind === "field" && !(entries && calls2.has(f.owner)))
2475
+ reach(identifiers([f.type ?? "", f.transform === "message type" ? f.name : ""].join(" ")), f.id);
1919
2476
  }
1920
- return { at, strings: [...strings2].map((s) => s.toLowerCase()), paths: [...paths] };
2477
+ const rooted = roots.length > 0 || reached.size > 0;
2478
+ if (!rooted)
2479
+ return {
2480
+ rooted,
2481
+ roots,
2482
+ reached: models.map((p) => ({ path: p, types: declared.get(p) ?? [], from: "" })),
2483
+ notReached: [],
2484
+ models: models.length
2485
+ };
2486
+ for (let i = 0; i < queue.length; i++) {
2487
+ const p = queue[i];
2488
+ reach(identifiers(textOf(p)), p, declared.get(p));
2489
+ }
2490
+ return {
2491
+ rooted,
2492
+ roots,
2493
+ reached: queue.map((p) => reached.get(p)),
2494
+ notReached: models.filter((p) => !reached.has(p)),
2495
+ models: models.length
2496
+ };
1921
2497
  }
1922
- function factsCover(file, c, ix) {
1923
- if ([c.line - 1, c.line, c.line + 1].some((n) => ix.at.has(`${file}:${n}`)))
1924
- return true;
1925
- if (c.kind === "path") {
1926
- const p = `${normPath(c.value)}/`;
1927
- return ix.paths.some((f) => f.includes(p));
2498
+
2499
+ // packages/verify/dist/method.js
2500
+ var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
2501
+ function wordsOf2(line) {
2502
+ return line.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").toLowerCase().split(/[^a-z]+/).filter(Boolean);
2503
+ }
2504
+ function methodOnLines(method, lines) {
2505
+ const m = method.toLowerCase();
2506
+ return lines.some((l) => wordsOf2(l).includes(m));
2507
+ }
2508
+ var CHAIN_LINES = 8;
2509
+ var CONTINUES = /^\s*\??\./;
2510
+ function chainOf(file, line) {
2511
+ const at = (n) => file?.[n - 1];
2512
+ const cited = at(line);
2513
+ if (cited === void 0)
2514
+ return [];
2515
+ const out = [cited];
2516
+ for (let n = line, k = 0; k < CHAIN_LINES && CONTINUES.test(at(n) ?? ""); k++, n--) {
2517
+ const above = at(n - 1);
2518
+ if (above === void 0)
2519
+ break;
2520
+ out.push(above);
1928
2521
  }
1929
- const v = c.value.toLowerCase().replace(/\/+$/, "");
1930
- return ix.strings.some((s) => s.includes(v));
2522
+ for (let n = line + 1, k = 0; k < CHAIN_LINES && CONTINUES.test(at(n) ?? ""); k++, n++)
2523
+ out.push(at(n));
2524
+ return out;
1931
2525
  }
1932
- var skippedOf = (file, c) => ({
1933
- cite: `${file}:${c.line}`,
1934
- kind: c.kind,
1935
- value: c.value,
1936
- text: c.text
1937
- });
1938
- var SPEC_MARK = /^\s*["']?(openapi|swagger)["']?\s*:/m;
1939
- var SPEC_EXT = /\.(ya?ml|json)$/i;
1940
- function specOpsUncoveredIn(file, text, facts) {
1941
- if (!SPEC_EXT.test(file) || !SPEC_MARK.test(text.slice(0, 4e3)))
2526
+ function methodUnseenOf(f, lines, factOf) {
2527
+ if (f.kind !== "entry" && f.kind !== "call")
1942
2528
  return void 0;
1943
- let doc;
1944
- try {
1945
- doc = readOpenApiDocument(text);
1946
- } catch {
2529
+ if (!f.method || !HTTP_METHODS.has(f.method.toUpperCase()))
1947
2530
  return void 0;
1948
- }
1949
- if (!doc || !doc.operations.length)
2531
+ const at = (file, line) => lines(file)?.[line - 1];
2532
+ const route = f.kind === "call" && f.from ? factOf?.(f.from) : void 0;
2533
+ const forwards = route?.kind === "entry" && route.method?.toUpperCase() === f.method.toUpperCase();
2534
+ const looked = [
2535
+ ...chainOf(lines(f.cite.file), f.cite.line),
2536
+ at(f.cite.file, f.cite.line + 1),
2537
+ ...(f.cite.with ?? []).map((p) => at(p.file, p.line)),
2538
+ ...forwards ? [at(route.cite.file, route.cite.line), at(route.cite.file, route.cite.line + 1)] : []
2539
+ ].filter((l) => l !== void 0);
2540
+ if (methodOnLines(f.method, looked))
1950
2541
  return void 0;
1951
- const server = (() => {
1952
- const s = doc.servers[0];
1953
- if (!s)
1954
- return "";
1955
- const p = /^[a-z0-9+.-]+:\/\/[^/]+(\/.*)?$/i.exec(s)?.[1] ?? (s.startsWith("/") ? s : "");
1956
- return p.replace(/\/+$/, "");
1957
- })();
1958
- const entries = facts.filter((f) => f.kind === "entry");
1959
- const atLines = /* @__PURE__ */ new Set();
1960
- for (const e of entries)
1961
- for (const k of indexFacts([e]).at)
1962
- atLines.add(k);
1963
- const out = [];
1964
- for (const op of doc.operations) {
1965
- const lines = [op.methodLine, op.line].filter((n) => n !== void 0);
1966
- if (lines.some((n) => [n - 1, n, n + 1].some((x) => atLines.has(`${file}:${x}`))))
1967
- continue;
1968
- const method = op.method.toUpperCase();
1969
- const own = normPath(op.path);
1970
- const full = normPath(`${server}${op.path}`);
1971
- const covered = entries.some((e) => {
1972
- if (e.method && e.method.toUpperCase() !== method)
1973
- return false;
1974
- const p = normPath(e.path);
1975
- return p === own || p === full || p.endsWith(own) || p.split("/").length > 2 && own.endsWith(p);
1976
- });
1977
- if (covered)
1978
- continue;
1979
- const opId = op.node?.get?.("operationId");
1980
- const line = op.methodLine ?? op.line ?? 1;
1981
- out.push({
1982
- spec: file,
1983
- method,
1984
- path: op.path,
1985
- ...typeof opId === "string" ? { operationId: opId } : {},
1986
- cite: `${file}:${line}`,
1987
- message: `${file}:${line} declares ${method} ${op.path}${typeof opId === "string" ? ` (${opId})` : ""}, which no entry covers`
1988
- });
1989
- }
1990
- return out;
1991
- }
1992
- var REVIEWED_HOLDS_SHOWN = 5;
1993
- function reviewedHoldsOf(r, skipped) {
1994
- const n = skipped.length;
1995
- const first = skipped.slice(0, 3).map((s) => `${s.cite} (${s.value})`);
2542
+ const cite2 = `${f.cite.file}:${f.cite.line}`;
2543
+ const method = f.method.toUpperCase();
1996
2544
  return {
1997
- path: r.path,
1998
- why: r.why,
1999
- count: n,
2000
- skipped: skipped.slice(0, REVIEWED_HOLDS_SHOWN),
2001
- message: `${r.line !== void 0 ? `line ${r.line}: ` : ""}${r.path} is reviewed as holding nothing to record, but ${n} ${n === 1 ? "line in it writes" : "lines in it write"} a path, URL or topic: ${first.join(", ")}${n > 3 ? ` and ${n - 3} more` : ""}`
2545
+ id: f.id,
2546
+ kind: f.kind,
2547
+ method,
2548
+ cite: cite2,
2549
+ message: `${f.id} claims ${method}, which neither ${cite2}, the chain it is in, the next line, a cite.with line nor the route it forwards writes`
2002
2550
  };
2003
2551
  }
2004
2552
 
@@ -2076,9 +2624,12 @@ var repoModule = (exposes) => {
2076
2624
  const m = /^([^/]+)\/([^/]+)$/.exec(exposes.trim());
2077
2625
  return m ? { repo: m[1], module: m[2] } : void 0;
2078
2626
  };
2627
+ var PLACEHOLDER_KEY = /^\$\{([A-Za-z_][A-Za-z0-9_.-]*)\}$/;
2079
2628
  var routeOrWord = (v) => v.includes("/") ? { kind: "route", value: v } : { kind: "word", value: v };
2080
2629
  function claimsOf(f) {
2081
2630
  switch (f.kind) {
2631
+ // A call whose path is a setting's placeholder a helper puts together is checked apart
2632
+ // (`helperBuildsKey`): its bare key is never a claim, or a settings line would be a call.
2082
2633
  case "entry":
2083
2634
  case "call":
2084
2635
  return [routeOrWord(f.path)];
@@ -2117,6 +2668,14 @@ function claimsOf(f) {
2117
2668
  // ADR 0180: the signal the type rests on, as written on its line.
2118
2669
  case "component":
2119
2670
  return [{ kind: "word", value: f.cite.value }];
2671
+ // ADR 0192: the coordinates as the build file writes them on the line (the name, or a
2672
+ // Gradle line's whole `group:name:version`); `buildCoordinatesProblem` reads the rest.
2673
+ case "artifact":
2674
+ case "dependency":
2675
+ return [
2676
+ { kind: "word", value: f.cite.value },
2677
+ { kind: "word", value: f.name }
2678
+ ];
2120
2679
  }
2121
2680
  }
2122
2681
  var sameCommit = (a, b) => a.startsWith(b) || b.startsWith(a);
@@ -2295,6 +2854,11 @@ async function verifyFacts(o) {
2295
2854
  code: "claim-not-on-line",
2296
2855
  message: `${label} claims ${claims.map((c) => `"${c.value}"`).join(" or ")}, which ${where} (or the line either side)${parts.length ? " and its parts" : ""} does not name${parts.length || !withHint ? "" : "; if it is put together from other lines (a base URL, a prefix, a context path), cite them in cite.with"}`
2297
2856
  };
2857
+ if (claims && parts.length && isCommentLine(lines[cite2.line - 1] ?? "") && !/(^|\/)_redirects$/.test(cite2.file))
2858
+ return {
2859
+ code: "claim-in-comment",
2860
+ message: `${label} cites ${where}, which is a comment; cite the code that does it`
2861
+ };
2298
2862
  if (claims && !parts.length) {
2299
2863
  const naming = [cite2.line - 1, cite2.line, cite2.line + 1].map((n) => lines[n - 1]).filter((l) => l !== void 0 && claims.some((c) => lineNamesClaim(l, c)));
2300
2864
  if (naming.length && !/(^|\/)_redirects$/.test(cite2.file) && naming.every(isCommentLine))
@@ -2342,7 +2906,16 @@ async function verifyFacts(o) {
2342
2906
  problem(f, "wrong-commit", `${label} was read at ${f.commit}, not at ${o.commit}; read it again`);
2343
2907
  continue;
2344
2908
  }
2345
- add(f, checkCite(f.cite, claimsOf(f), label, true, f.kind === "entry" || f.kind === "call" ? (ls, n) => apigeePassThrough({ kind: f.kind, forwards: f.kind === "call" && !!f.from }, f.cite.file, ls, n, f.path) : void 0));
2909
+ add(f, checkCite(f.cite, claimsOf(f), label, true, f.kind === "entry" || f.kind === "call" ? (ls, n) => apigeePassThrough({ kind: f.kind, forwards: f.kind === "call" && !!f.from }, f.cite.file, ls, n, f.path) || // A path written as a setting's placeholder that no line writes whole (ADR 0172,
2910
+ // beta.24): a helper puts the key together (a `@ConfigurationProperties` prefix, a
2911
+ // map field, the name passed to a lookup). The cited line is code naming the key's
2912
+ // last segment, and one file among the parts proves the rest of the key nests so.
2913
+ f.kind === "call" && PLACEHOLDER_KEY.test(f.path.trim()) && helperBuildsKey(PLACEHOLDER_KEY.exec(f.path.trim())[1], f.cite, linesOf2) : void 0));
2914
+ if (f.kind === "config" && !found.has(f.id)) {
2915
+ const bad = configLineProblem(f, linesOf2, listed2);
2916
+ if (bad)
2917
+ problem(f, "claim-not-on-line", `${label}: ${bad}`);
2918
+ }
2346
2919
  if (f.kind === "entry" && f.authCite)
2347
2920
  add(f, checkCite({ ...f.authCite }, [{ kind: "word", value: f.authCite.value }], `${label} authCite${f.auth ? ` (auth ${f.auth})` : ""}`, false));
2348
2921
  if (f.kind === "entry" && f.authCite && f.auth) {
@@ -2433,6 +3006,13 @@ async function verifyFacts(o) {
2433
3006
  if (f.version !== void 0)
2434
3007
  add(f, checkCite(f.cite, [{ kind: "word", value: f.version }], `${label} version`, false));
2435
3008
  }
3009
+ if ((f.kind === "artifact" || f.kind === "dependency") && !found.has(f.id)) {
3010
+ const bad = buildCoordinatesProblem(f, linesOf2);
3011
+ if (bad)
3012
+ problem(f, "build-coordinates", bad);
3013
+ else if (f.version !== void 0)
3014
+ add(f, checkCite(f.cite, [{ kind: "word", value: f.version }], `${label} version`, false));
3015
+ }
2436
3016
  if (f.kind === "flow") {
2437
3017
  f.steps.forEach((s, i) => add(f, checkCite(s.cite, stepClaims(s.kind, s.cite.value), `${label} step ${i + 1}`)));
2438
3018
  f.errors.forEach((e, i) => add(f, checkCite(e.cite, [routeOrWord(e.cite.value)], `${label} error ${i + 1}`)));
@@ -2553,8 +3133,18 @@ async function verifyFacts(o) {
2553
3133
  const excludeRes = (o.exclude ?? []).map(globToRegExp);
2554
3134
  const sources = [];
2555
3135
  const excluded = [];
3136
+ const secrets = [];
2556
3137
  for (const p of o.source.list()) {
2557
3138
  o.room?.();
3139
+ if (isSecretPath(p)) {
3140
+ if (insideRepo(p) && isConfigFile(p) && !rules.notProduct.test(p) && !tooBigToRead(o.source, p)) {
3141
+ const text = o.source.read(p);
3142
+ const ls2 = text === void 0 ? void 0 : text.replace(/\r\n?/g, "\n").split("\n");
3143
+ if (ls2 && !binaryLines(ls2))
3144
+ secrets.push(...liveSecretsIn(p, ls2));
3145
+ }
3146
+ continue;
3147
+ }
2558
3148
  if (!isSourceFile(p, "", void 0, rules) || tooBigToRead(o.source, p))
2559
3149
  continue;
2560
3150
  const ls = readLines(p) ?? [""];
@@ -2562,8 +3152,10 @@ async function verifyFacts(o) {
2562
3152
  continue;
2563
3153
  if (excludeRes.some((re) => re.test(p)))
2564
3154
  excluded.push(p);
2565
- else
3155
+ else {
2566
3156
  sources.push(p);
3157
+ secrets.push(...liveSecretsIn(p, ls));
3158
+ }
2567
3159
  }
2568
3160
  const touched = new Set(o.routed ?? []);
2569
3161
  for (const f of accepted)
@@ -2664,6 +3256,7 @@ async function verifyFacts(o) {
2664
3256
  const held = files.flatMap(skippedIn);
2665
3257
  return held.length ? [reviewedHoldsOf(entry, held)] : [];
2666
3258
  });
3259
+ const unrecorded = buildUnrecorded([...touched].filter((p) => isBuildFile(p) && insideRepo(p) && !isSecretPath(p)), (p) => linesOf2(p), accepted);
2667
3260
  return {
2668
3261
  accepted,
2669
3262
  // a rejected fact goes back as it was read, at its own commit, even one that was carried
@@ -2677,6 +3270,7 @@ async function verifyFacts(o) {
2677
3270
  ratio
2678
3271
  },
2679
3272
  redacted,
3273
+ secrets: secrets.sort((a, b) => a.file < b.file ? -1 : a.file > b.file ? 1 : a.line - b.line),
2680
3274
  quotesDropped,
2681
3275
  carried: accepted.flatMap((f) => carriedFrom.has(f.id) ? [{ id: f.id, from: carriedFrom.get(f.id) }] : []),
2682
3276
  corrections: { applied: corrected.applied, stale: corrected.stale },
@@ -2689,7 +3283,8 @@ async function verifyFacts(o) {
2689
3283
  skipped,
2690
3284
  reviewedHolds,
2691
3285
  specOpsUncovered,
2692
- frameworkGaps: frameworkGaps(accepted, rules.frameworks)
3286
+ frameworkGaps: frameworkGaps(accepted, rules.frameworks),
3287
+ ...unrecorded.length ? { buildUnrecorded: unrecorded } : {}
2693
3288
  };
2694
3289
  }
2695
3290
 
@@ -4446,8 +5041,25 @@ var LENS_KINDS = {
4446
5041
  infrastructure: /* @__PURE__ */ new Set(["estate", "system", "repo", "component", "deployment", "environment"])
4447
5042
  };
4448
5043
  var LENS_EDGES = {
4449
- architecture: /* @__PURE__ */ new Set(["calls", "publishes", "subscribes", "uses", "reads", "writes"]),
4450
- repo: /* @__PURE__ */ new Set(["calls", "publishes", "subscribes", "uses", "reads", "writes", "references"]),
5044
+ architecture: /* @__PURE__ */ new Set([
5045
+ "calls",
5046
+ "publishes",
5047
+ "subscribes",
5048
+ "uses",
5049
+ "depends-on",
5050
+ "reads",
5051
+ "writes"
5052
+ ]),
5053
+ repo: /* @__PURE__ */ new Set([
5054
+ "calls",
5055
+ "publishes",
5056
+ "subscribes",
5057
+ "uses",
5058
+ "depends-on",
5059
+ "reads",
5060
+ "writes",
5061
+ "references"
5062
+ ]),
4451
5063
  data: /* @__PURE__ */ new Set(["reads", "writes", "references"]),
4452
5064
  integration: /* @__PURE__ */ new Set(["calls", "publishes", "subscribes"]),
4453
5065
  infrastructure: /* @__PURE__ */ new Set(["deployed-to"])
@@ -4510,30 +5122,57 @@ var HOW_OF_FLAG = {
4510
5122
  "joined-by-name": "named",
4511
5123
  "joined-by-repo": "repo",
4512
5124
  "joined-by-host": "host",
5125
+ // beta.24: a call whose host nothing resolves, by the one proxy BasePath its path starts with.
5126
+ [JOINED_BY_BASE_PATH]: "base-path",
4513
5127
  "declared-caller": "declared",
4514
5128
  // ADR 0162 §6 (F8): a topic or queue the profile names as an outside system's: a person's word.
4515
5129
  [DECLARED_TOPIC]: "declared",
4516
5130
  // ADR 0160 (O3): answered by an entry of another team's shared map.
4517
5131
  [JOINED_TO_SHARED_MAP]: "shared"
4518
5132
  };
5133
+ var GUESS_FLAGS = new Set(JOIN_GUESS_FLAGS);
4519
5134
  function joinHow(i) {
4520
- for (const f of i.flags ?? [])
5135
+ const flags = i.flags ?? [];
5136
+ const topic = i.via === "event-bus" || i.via === "mq";
5137
+ if (i.confidence === "verified") {
5138
+ for (const f of flags)
5139
+ if (HOW_OF_FLAG[f] && !GUESS_FLAGS.has(f))
5140
+ return HOW_OF_FLAG[f];
5141
+ if (topic)
5142
+ return "topic";
5143
+ }
5144
+ for (const f of flags)
4521
5145
  if (HOW_OF_FLAG[f])
4522
5146
  return HOW_OF_FLAG[f];
4523
- if (i.via === "event-bus" || i.via === "mq")
5147
+ if (topic)
4524
5148
  return "topic";
4525
5149
  return "unknown";
4526
5150
  }
5151
+ var GUESS_HOWS = new Set(JOIN_GUESS_FLAGS.map((f) => HOW_OF_FLAG[f]).filter(Boolean));
5152
+ function alsoOf(i, how) {
5153
+ if (i.confidence !== "verified" || GUESS_HOWS.has(how))
5154
+ return [];
5155
+ return [
5156
+ ...new Set((i.flags ?? []).flatMap((f) => GUESS_FLAGS.has(f) && HOW_OF_FLAG[f] ? [HOW_OF_FLAG[f]] : []))
5157
+ ];
5158
+ }
4527
5159
  function joinOf(i) {
4528
5160
  const side = (s) => evidenceOf(i.evidence.filter((e) => e.side === s));
4529
5161
  const sided = /* @__PURE__ */ new Set(["caller", "callee", "gateway"]);
5162
+ const how = joinHow(i);
5163
+ const also = alsoOf(i, how);
4530
5164
  return {
4531
5165
  interface: i.id,
4532
5166
  from: i.from,
4533
5167
  to: i.to,
4534
- how: joinHow(i),
5168
+ how,
4535
5169
  gateway: i.via === "gateway",
4536
- verified: i.confidence === "verified",
5170
+ // A link is verified when one of its calls is (ADR 0135 section 5): its how is that call's,
5171
+ // and the guesses its other calls rest on are `also`, never the reason. One with no how but
5172
+ // a guess has no call that wasn't guessed to show, so it is never shown verified beside the
5173
+ // guess's words (beta.24).
5174
+ verified: i.confidence === "verified" && !GUESS_HOWS.has(how),
5175
+ ...also.length ? { also } : {},
4537
5176
  ...i.method ? { method: i.method } : {},
4538
5177
  ...i.normalizedPath ? { path: i.normalizedPath } : {},
4539
5178
  caller: side("caller"),
@@ -4565,12 +5204,12 @@ function sharedOf(i) {
4565
5204
  }
4566
5205
  };
4567
5206
  }
4568
- function mergeJoins(a, b) {
5207
+ function mergeJoins(a, b, cap = MAX_JOINS) {
4569
5208
  const by = new Map(a.map((j) => [j.interface, j]));
4570
5209
  for (const j of b)
4571
5210
  if (!by.has(j.interface))
4572
5211
  by.set(j.interface, j);
4573
- return [...by.values()].sort((x, y) => x.interface < y.interface ? -1 : x.interface > y.interface ? 1 : 0).slice(0, MAX_JOINS);
5212
+ return [...by.values()].sort((x, y) => x.interface < y.interface ? -1 : x.interface > y.interface ? 1 : 0).slice(0, cap);
4574
5213
  }
4575
5214
  var props = (o) => {
4576
5215
  const out = {};
@@ -4586,7 +5225,29 @@ var props = (o) => {
4586
5225
  return out;
4587
5226
  };
4588
5227
  var all = (rs, k) => rs.filter((r) => r.kind === k).sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
4589
- function buildEstate(records2) {
5228
+ function dependencyJoin(l) {
5229
+ const lines = (end) => end.lines.map((at) => ({ source: "code", repo: end.repo, at }));
5230
+ return {
5231
+ interface: dependencyLinkId(l),
5232
+ from: l.from.component,
5233
+ to: l.to.component,
5234
+ how: "coordinates",
5235
+ gateway: false,
5236
+ // code at both ends, each claim checked on its line, and nobody had to guess
5237
+ verified: true,
5238
+ caller: lines(l.from),
5239
+ callee: lines(l.to),
5240
+ hops: [],
5241
+ other: [],
5242
+ dependency: {
5243
+ group: l.group,
5244
+ name: l.name,
5245
+ ...l.version ? { version: l.version } : {},
5246
+ ...l.scope ? { scope: l.scope } : {}
5247
+ }
5248
+ };
5249
+ }
5250
+ function buildEstate(records2, o = {}) {
4590
5251
  const nodes = /* @__PURE__ */ new Map();
4591
5252
  const atoms = [];
4592
5253
  const add = (n) => {
@@ -4692,6 +5353,11 @@ function buildEstate(records2) {
4692
5353
  }
4693
5354
  });
4694
5355
  }
5356
+ for (const [sys, n] of [...nodes.entries()].filter(([id]) => id.startsWith("system:"))) {
5357
+ const inside = [...repoSystem.entries()].filter(([, s]) => `system:${s}` === sys && systems.has(s)).map(([r]) => r).sort();
5358
+ if (inside.length)
5359
+ n.properties = { ...n.properties, repos: inside };
5360
+ }
4695
5361
  const unknown = (ref) => add({
4696
5362
  id: `unknown:${slug2(ref)}`,
4697
5363
  kind: "unknown",
@@ -4892,6 +5558,19 @@ function buildEstate(records2) {
4892
5558
  evidence: evidenceOf(c.evidence),
4893
5559
  gaps: recordGaps(c)
4894
5560
  });
5561
+ for (const l of o.dependsOn ?? []) {
5562
+ if (!components.has(l.from.component) || !components.has(l.to.component))
5563
+ continue;
5564
+ const join2 = dependencyJoin(l);
5565
+ atoms.push({
5566
+ from: `component:${l.from.component}`,
5567
+ to: `component:${l.to.component}`,
5568
+ type: "depends-on",
5569
+ evidence: mergeEvidence(join2.caller.slice(0, 1), join2.callee.slice(0, 1)),
5570
+ gaps: [],
5571
+ join: join2
5572
+ });
5573
+ }
4895
5574
  for (const t of tables) {
4896
5575
  const ev = evidenceOf(t.evidence);
4897
5576
  const part = (ref) => {
@@ -5044,7 +5723,7 @@ function need(est, lens, id) {
5044
5723
  if (!est.visible.get(lens).has(id))
5045
5724
  throw new NoSuchNode(`There is no node ${id} in the ${lens} lens.`);
5046
5725
  }
5047
- function merge(mapped) {
5726
+ function merge(mapped, cap = MAX_JOINS) {
5048
5727
  const by = /* @__PURE__ */ new Map();
5049
5728
  for (const { from, to, atom } of mapped) {
5050
5729
  const id = `${atom.type}:${from}>${to}`;
@@ -5066,7 +5745,7 @@ function merge(mapped) {
5066
5745
  continue;
5067
5746
  }
5068
5747
  if (atom.join)
5069
- e.joins = mergeJoins(e.joins ?? [], [atom.join]);
5748
+ e.joins = mergeJoins(e.joins ?? [], [atom.join], cap);
5070
5749
  e.count++;
5071
5750
  if (atom.sync && e.sync !== atom.sync)
5072
5751
  e.sync = "mixed";
@@ -5155,7 +5834,7 @@ function nodeView(est, id, o) {
5155
5834
  continue;
5156
5835
  mapped.push({ from, to, atom });
5157
5836
  }
5158
- let edges = merge(mapped);
5837
+ let edges = merge(mapped, o.everyJoin ? Infinity : MAX_JOINS);
5159
5838
  let hidden = 0;
5160
5839
  if (!o.all)
5161
5840
  ({ edges, hidden } = reduceUses(edges));
@@ -5200,7 +5879,7 @@ function focusView(est, id, o) {
5200
5879
  node: toNode(est, lens, id),
5201
5880
  path: ancestors(est, id).map((n) => toNode(est, lens, n)),
5202
5881
  neighbours: [...near].sort().map((n) => toNode(est, lens, n)),
5203
- edges: merge(ends.filter((e) => set.has(e.from) && set.has(e.to)))
5882
+ edges: merge(ends.filter((e) => set.has(e.from) && set.has(e.to)), o.everyJoin ? Infinity : MAX_JOINS)
5204
5883
  };
5205
5884
  }
5206
5885
 
@@ -6091,6 +6770,7 @@ function houseImportsUntaught(source, o) {
6091
6770
  export {
6092
6771
  insideRepo,
6093
6772
  dirSource,
6773
+ isBuildFile,
6094
6774
  correctionFor,
6095
6775
  outsidePairingFor,
6096
6776
  correctedFact,