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

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 (271) hide show
  1. package/dist/bin.js +3 -3
  2. package/dist/{chunk-MWN7CBVL.js → chunk-23QHP4JJ.js} +3 -3
  3. package/dist/{chunk-SUAHNYNQ.js → chunk-2RABF6RT.js} +15 -15
  4. package/dist/{chunk-CU7ZK7KP.js → chunk-2ULVUSIP.js} +15 -15
  5. package/dist/{chunk-5FPAKAGE.js → chunk-2VN4TLGI.js} +3 -3
  6. package/dist/{chunk-YF6N45QN.js → chunk-2Y5FJQSF.js} +1 -1
  7. package/dist/{chunk-D63NU53X.js → chunk-334N6EI2.js} +18 -18
  8. package/dist/{chunk-RSKMV3VC.js → chunk-3D74UADA.js} +1 -1
  9. package/dist/{chunk-JFBVIMGY.js → chunk-3NA2VE45.js} +12 -12
  10. package/dist/{chunk-SWSGRRNO.js → chunk-3VC2XJ53.js} +4 -4
  11. package/dist/{chunk-GKZDHXC2.js → chunk-3WO7ASU7.js} +7 -7
  12. package/dist/{chunk-77AZRGWE.js → chunk-4GWQVT2C.js} +15 -15
  13. package/dist/{chunk-PUMNCWHJ.js → chunk-4PW5SRKJ.js} +13 -13
  14. package/dist/{chunk-NTOPAOBY.js → chunk-4SS5ZK47.js} +2 -2
  15. package/dist/{chunk-IJQHBK76.js → chunk-4U3JLIRC.js} +1 -1
  16. package/dist/{chunk-WAAPMZWO.js → chunk-4WIVTPGE.js} +4 -4
  17. package/dist/{chunk-IK6LHW3E.js → chunk-5267F4BS.js} +3 -3
  18. package/dist/{chunk-L27KUL5B.js → chunk-5CPZIWIN.js} +19 -19
  19. package/dist/{chunk-F63F4NKT.js → chunk-5GLGLWAJ.js} +16 -16
  20. package/dist/{chunk-TAR6T2RE.js → chunk-5K6ZKHZR.js} +2 -2
  21. package/dist/{chunk-IB66ZLDN.js → chunk-5OVSDV77.js} +5 -5
  22. package/dist/{chunk-SYLXQNPC.js → chunk-5P4PNGPL.js} +22 -22
  23. package/dist/{chunk-M3RWF7MC.js → chunk-5R3FRI6H.js} +26 -26
  24. package/dist/{chunk-R6CJOMPC.js → chunk-5RDKQOY3.js} +12 -12
  25. package/dist/{chunk-432FGEVB.js → chunk-5RKN5QIX.js} +7 -7
  26. package/dist/{chunk-TXYMNKGM.js → chunk-5UJ7C7IH.js} +5 -5
  27. package/dist/{chunk-DCRZ3OQ7.js → chunk-5WZV37WS.js} +6 -6
  28. package/dist/{chunk-WWSCJBF6.js → chunk-62FMA437.js} +12 -12
  29. package/dist/{chunk-DIXA74N7.js → chunk-6576X5BJ.js} +3 -3
  30. package/dist/{chunk-2ITYURTR.js → chunk-6WYOJCB4.js} +2 -2
  31. package/dist/{chunk-D5ZC7IMC.js → chunk-77REYYY5.js} +3 -3
  32. package/dist/{chunk-Z5YDTIWQ.js → chunk-7AKJ2XTW.js} +12 -12
  33. package/dist/{chunk-JUHZBZPZ.js → chunk-7E3G5NCH.js} +6 -6
  34. package/dist/{chunk-UKRJ2ISN.js → chunk-7EAH2MFY.js} +3 -3
  35. package/dist/{chunk-QOC3Q4UU.js → chunk-7F4GZ7U2.js} +2 -2
  36. package/dist/{chunk-5EIKOU7L.js → chunk-7FUQAT2R.js} +4 -4
  37. package/dist/{chunk-TBQHBOFF.js → chunk-7HW2CMIN.js} +8 -8
  38. package/dist/{chunk-MZWM73S2.js → chunk-7NLYSTEK.js} +5 -5
  39. package/dist/{chunk-U66RQUFC.js → chunk-7QZDGM5V.js} +4 -4
  40. package/dist/{chunk-YLZNTVZR.js → chunk-7U6PBBXG.js} +7 -7
  41. package/dist/{chunk-QPLNB2BM.js → chunk-7UYRN4ON.js} +3 -3
  42. package/dist/{chunk-BTS56NV7.js → chunk-7X3WLAKP.js} +36 -33
  43. package/dist/{chunk-LOCJHNZI.js → chunk-7YFUNWFM.js} +8 -8
  44. package/dist/chunk-7YSMZEO3.js +55 -0
  45. package/dist/{chunk-PB3NCPRF.js → chunk-A3AADMM2.js} +6 -6
  46. package/dist/{chunk-QJ3AYXVO.js → chunk-A3J75BO2.js} +12 -12
  47. package/dist/chunk-AENMOZMM.js +42 -0
  48. package/dist/{chunk-ZIAYNHHE.js → chunk-AGAFNUYZ.js} +31 -14
  49. package/dist/{chunk-QXXEO4TF.js → chunk-AYWJMHSX.js} +3 -3
  50. package/dist/{chunk-BLVFHN3C.js → chunk-B2U4AOZ5.js} +38 -38
  51. package/dist/chunk-BDKYHCGI.js +71 -0
  52. package/dist/{chunk-XERIHPBF.js → chunk-BEDZNT62.js} +8 -8
  53. package/dist/{chunk-L3PIN47C.js → chunk-BIQNPWGX.js} +4 -4
  54. package/dist/{chunk-OKSRK2LJ.js → chunk-BJDVI5W6.js} +17 -17
  55. package/dist/{chunk-UCFNHK5L.js → chunk-BMMTWRWE.js} +20 -20
  56. package/dist/{chunk-SUYC5NP6.js → chunk-BPDS7KUR.js} +21 -21
  57. package/dist/{chunk-EUMXLSW5.js → chunk-BS52P2CM.js} +5 -5
  58. package/dist/{chunk-IUBBEU6O.js → chunk-C5LX54QK.js} +10 -10
  59. package/dist/{chunk-YHWX5LPT.js → chunk-CB6H7MH2.js} +21 -21
  60. package/dist/{chunk-HNPKCRCE.js → chunk-CGVRLQAY.js} +1375 -210
  61. package/dist/{chunk-EPQQ2XVM.js → chunk-CMUJSPP4.js} +9 -9
  62. package/dist/{chunk-5Z7L2TSR.js → chunk-CNF7D3A7.js} +3 -3
  63. package/dist/{chunk-4RKIOUPA.js → chunk-CPFAWYVC.js} +4 -4
  64. package/dist/{chunk-EEKQI3U4.js → chunk-CQRFCWQV.js} +21 -21
  65. package/dist/{chunk-66DWUSNY.js → chunk-CVWKS6GO.js} +20 -20
  66. package/dist/chunk-D2CGJ7RR.js +46 -0
  67. package/dist/{chunk-NX5IPHI3.js → chunk-D45K3XKK.js} +12 -12
  68. package/dist/{chunk-FYWLB7PO.js → chunk-D7QIZLWB.js} +19 -19
  69. package/dist/{chunk-NQDHRT2H.js → chunk-DAHKLVHU.js} +12 -12
  70. package/dist/{chunk-LKUTBQ2Y.js → chunk-DBVQEPZB.js} +5 -5
  71. package/dist/{chunk-FFDVAV56.js → chunk-DCPI3ETH.js} +22 -22
  72. package/dist/{chunk-FL53R4SW.js → chunk-DJ4C5ELF.js} +5 -2
  73. package/dist/{chunk-MCE74XMF.js → chunk-DLNQ3HUM.js} +6 -6
  74. package/dist/chunk-DM3H4V2G.js +62 -0
  75. package/dist/{chunk-D5CJEKZI.js → chunk-DMQJDHXG.js} +2 -2
  76. package/dist/{chunk-A3NUZJFI.js → chunk-DPZD7WVX.js} +2 -2
  77. package/dist/{chunk-MVXMISNA.js → chunk-DYVUNT4O.js} +7 -7
  78. package/dist/{chunk-CFSHLQPK.js → chunk-E2OP6JNF.js} +24 -24
  79. package/dist/{chunk-FDL2JOLB.js → chunk-E7PR4WMM.js} +22 -22
  80. package/dist/{chunk-E7YDJH6B.js → chunk-EAGSM3XY.js} +9 -9
  81. package/dist/{chunk-RU5W7JJQ.js → chunk-EJGUEUXG.js} +23 -23
  82. package/dist/chunk-ELKTDXV3.js +67 -0
  83. package/dist/{chunk-XXRBAJ36.js → chunk-ELNIQYLR.js} +12 -12
  84. package/dist/{chunk-ZRQHSMPK.js → chunk-ELNLHU7Y.js} +4 -4
  85. package/dist/{chunk-5FUFVNXB.js → chunk-EM7F6XEU.js} +2 -2
  86. package/dist/{chunk-3UMKLB6P.js → chunk-EP7ZBZLT.js} +5 -5
  87. package/dist/chunk-EPXYFJTY.js +278 -0
  88. package/dist/{chunk-ETQSQ2EC.js → chunk-EUCATH2U.js} +4 -4
  89. package/dist/{chunk-HI7ADE4E.js → chunk-EXCXNDTQ.js} +1 -1
  90. package/dist/{chunk-6FIYEB7M.js → chunk-EXGXCVWC.js} +22 -22
  91. package/dist/{chunk-MDTAZ6NE.js → chunk-F36DIKJ3.js} +11 -11
  92. package/dist/{chunk-GQFUEUC7.js → chunk-F4WKGX7K.js} +16 -16
  93. package/dist/{chunk-DH3EQMIA.js → chunk-F56DNMDD.js} +3 -3
  94. package/dist/{chunk-DD2AXECF.js → chunk-FJS2FZFZ.js} +20 -20
  95. package/dist/{chunk-H5EQOSTC.js → chunk-FNP4M4VL.js} +38 -38
  96. package/dist/{chunk-HWNFFCGB.js → chunk-G5P7F6RQ.js} +3 -3
  97. package/dist/{chunk-GQPP4P2E.js → chunk-GAU2IFIC.js} +16 -16
  98. package/dist/{chunk-XKNISZ6N.js → chunk-GAVEIYKH.js} +15 -15
  99. package/dist/{chunk-IRXZKKCG.js → chunk-GD6FXN6R.js} +15 -15
  100. package/dist/{chunk-A6ZG3UOS.js → chunk-GDGE7ZHC.js} +5 -5
  101. package/dist/{chunk-LBG4GMOR.js → chunk-GIOOA2ZO.js} +3 -3
  102. package/dist/{chunk-GJVCBTSO.js → chunk-GLISHJ4G.js} +797 -174
  103. package/dist/{chunk-RQSUFGU2.js → chunk-GPOL5H3B.js} +24 -24
  104. package/dist/{chunk-3NS4RS3C.js → chunk-GVOQJPKA.js} +18 -18
  105. package/dist/{chunk-YDDLVBQ4.js → chunk-GX67TNFA.js} +3 -3
  106. package/dist/{chunk-ABDE5IRC.js → chunk-H75SPCAW.js} +16 -16
  107. package/dist/{chunk-J4K4C4T5.js → chunk-H7GAPNGQ.js} +13 -18
  108. package/dist/{chunk-CI4D6VSU.js → chunk-HD72AL3L.js} +18 -18
  109. package/dist/{chunk-X7HFXXTZ.js → chunk-HHZ2ZKUD.js} +12 -12
  110. package/dist/{chunk-YA2IJJ6N.js → chunk-HHZEXF7V.js} +5 -5
  111. package/dist/{chunk-A4VDFIMR.js → chunk-HR34F2AJ.js} +12 -12
  112. package/dist/{chunk-ROWZYQOI.js → chunk-HU7VXMFV.js} +6 -6
  113. package/dist/{chunk-6UTD5RQH.js → chunk-HV3KPEFH.js} +11 -11
  114. package/dist/{chunk-BYKWWSXL.js → chunk-I2M7MXSV.js} +6 -6
  115. package/dist/{chunk-5PSKLTBR.js → chunk-IDTVBZQI.js} +3 -3
  116. package/dist/{chunk-OSWOIFRQ.js → chunk-IFDCCCEN.js} +4 -4
  117. package/dist/{chunk-BFQ5IKQA.js → chunk-IKRM64KR.js} +10 -10
  118. package/dist/{chunk-5QF5W5P2.js → chunk-IMTAHDME.js} +5 -5
  119. package/dist/{chunk-KYO5HT4G.js → chunk-IP6TSICI.js} +12 -12
  120. package/dist/{chunk-BQXAHIZ6.js → chunk-IW3QMW3X.js} +8 -8
  121. package/dist/{chunk-WECCLSYY.js → chunk-IWQEZFVV.js} +228 -31
  122. package/dist/{chunk-44QUCNPH.js → chunk-J65TN6QU.js} +5 -5
  123. package/dist/{chunk-LAGZBQHK.js → chunk-JCKKAELC.js} +12 -12
  124. package/dist/{chunk-RSHVSXPJ.js → chunk-JJEPU4VS.js} +5 -5
  125. package/dist/{chunk-KIY2WCN7.js → chunk-JKEUPSCE.js} +3 -3
  126. package/dist/{chunk-BBZ6UKN3.js → chunk-JMOZ6K5A.js} +3 -3
  127. package/dist/{chunk-U2JTTRKS.js → chunk-JQGWP3SC.js} +6 -6
  128. package/dist/{chunk-LELM7X5H.js → chunk-JWLABUXL.js} +8 -8
  129. package/dist/{chunk-U57VLY6X.js → chunk-JXLUHMTC.js} +20 -20
  130. package/dist/{chunk-XPXOKHNZ.js → chunk-K373N5U6.js} +10 -10
  131. package/dist/{chunk-MPATOMY5.js → chunk-K3OIBTCV.js} +14 -14
  132. package/dist/{chunk-HYHV2P3G.js → chunk-K4C2DWOZ.js} +11 -11
  133. package/dist/{chunk-UWJOM457.js → chunk-K77ILFUQ.js} +3 -3
  134. package/dist/{chunk-3VS7RNEB.js → chunk-KFDOL2Y4.js} +17 -17
  135. package/dist/{chunk-4DCIUKIE.js → chunk-KGT5RIGE.js} +23 -13
  136. package/dist/{chunk-RRKM3GJA.js → chunk-KJPKIU2R.js} +23 -23
  137. package/dist/{chunk-37UTWGU4.js → chunk-KN4UQJ7R.js} +4 -4
  138. package/dist/{chunk-SGYQORAD.js → chunk-KW4DIXUL.js} +2 -2
  139. package/dist/{chunk-T24TBI7F.js → chunk-KY3BUZYI.js} +22 -22
  140. package/dist/{chunk-L6Z6TMIK.js → chunk-LGE6H4UP.js} +15 -8
  141. package/dist/{chunk-LDKP7OWQ.js → chunk-LKRMVWXB.js} +28 -28
  142. package/dist/{chunk-UI6KNLSO.js → chunk-LMNCRSER.js} +11 -11
  143. package/dist/{chunk-7U46TCRZ.js → chunk-LNGFTPU7.js} +18 -18
  144. package/dist/{chunk-DCQSPSXU.js → chunk-LOJGNSPA.js} +18 -18
  145. package/dist/{chunk-SLGUSFOD.js → chunk-LP5QGTCR.js} +3 -3
  146. package/dist/{chunk-CCQWQFOT.js → chunk-LPXH2DA4.js} +17 -17
  147. package/dist/{chunk-4DX4DIND.js → chunk-LQD3R6NZ.js} +7 -7
  148. package/dist/{chunk-QFDPX6C4.js → chunk-LZFKJ2BR.js} +4 -0
  149. package/dist/{chunk-DIYNRYXW.js → chunk-M6HI36T3.js} +2 -2
  150. package/dist/{chunk-ASFRT33J.js → chunk-M7XNX5IC.js} +9 -9
  151. package/dist/{chunk-4MNMOUU7.js → chunk-MELS6T5J.js} +4 -4
  152. package/dist/{chunk-UXO25YBN.js → chunk-MJAIBPI5.js} +3 -3
  153. package/dist/{chunk-G67GOK4S.js → chunk-MJMEF7SD.js} +7 -7
  154. package/dist/{chunk-H7KERB6Q.js → chunk-MJOIMGS4.js} +5 -5
  155. package/dist/chunk-MLUHBVCI.js +45 -0
  156. package/dist/{chunk-CKRPMRFQ.js → chunk-MM5OAVSW.js} +25 -25
  157. package/dist/{chunk-LTIXFLYE.js → chunk-MM7YWUBB.js} +6 -6
  158. package/dist/{chunk-BWYW533C.js → chunk-MN2XDLDM.js} +9 -9
  159. package/dist/{chunk-ZJ2W2RDE.js → chunk-MWOPED6I.js} +5 -5
  160. package/dist/{chunk-QYFNVQLK.js → chunk-MXPKXCGP.js} +1 -1
  161. package/dist/{chunk-EHF2MBGR.js → chunk-MZTU5L6S.js} +3 -3
  162. package/dist/{chunk-JVMNEI7B.js → chunk-N3OEBQTA.js} +3 -3
  163. package/dist/{chunk-ZSNNF26J.js → chunk-N6SSI6XO.js} +20 -20
  164. package/dist/{chunk-CFSBBLDD.js → chunk-NB664KWQ.js} +23 -23
  165. package/dist/{chunk-NN6AXKFX.js → chunk-NL6GIEJU.js} +15 -15
  166. package/dist/{chunk-ZCU2UY47.js → chunk-NMBHFSJQ.js} +22 -22
  167. package/dist/{chunk-HRYI22QU.js → chunk-NMGFXT4S.js} +15 -15
  168. package/dist/{chunk-G3W7GNEP.js → chunk-NPZ4KXIV.js} +17 -17
  169. package/dist/{chunk-LIB6AUZS.js → chunk-NQLTWGF4.js} +4 -4
  170. package/dist/{chunk-QK6CGRKK.js → chunk-O6DJMDBR.js} +4 -4
  171. package/dist/{chunk-MUY5MAGM.js → chunk-OEUTV6EL.js} +11 -11
  172. package/dist/{chunk-NC56V6KQ.js → chunk-OMSH46JK.js} +4 -4
  173. package/dist/chunk-ONB7M2AF.js +52 -0
  174. package/dist/{chunk-MQFSEGTU.js → chunk-OOU4N2JQ.js} +134 -30
  175. package/dist/{chunk-3FGQFDS4.js → chunk-OW53P52N.js} +18 -18
  176. package/dist/{chunk-YUJTOALL.js → chunk-P4QTTCVK.js} +18 -18
  177. package/dist/{chunk-JCEYOSST.js → chunk-P56N3NPT.js} +3 -3
  178. package/dist/{chunk-RYY554OA.js → chunk-PCZ4C2V7.js} +5 -5
  179. package/dist/{chunk-GFYVVTKH.js → chunk-PGKCRK77.js} +5 -5
  180. package/dist/{chunk-4CS3PMIM.js → chunk-PYVFLITV.js} +5 -5
  181. package/dist/{chunk-Q5QSWV2R.js → chunk-Q52KWTG5.js} +12 -12
  182. package/dist/{chunk-B63NWU3P.js → chunk-Q6UYUCNS.js} +12 -12
  183. package/dist/{chunk-VE2T5URA.js → chunk-QBK33722.js} +22 -22
  184. package/dist/{chunk-PZBNDFZ7.js → chunk-QE444DZ2.js} +39 -19
  185. package/dist/{chunk-MMOMKHAX.js → chunk-QEP4HTJE.js} +4 -4
  186. package/dist/{chunk-IOHRX4KF.js → chunk-QFOJ3UPU.js} +17 -13
  187. package/dist/{chunk-MOWUP33K.js → chunk-QQD25YNF.js} +2 -2
  188. package/dist/{chunk-W4EG25TI.js → chunk-QSKY7FE3.js} +6 -6
  189. package/dist/{chunk-3TGX4SJ3.js → chunk-R6HJ4SDB.js} +4 -4
  190. package/dist/{chunk-A53IYUCR.js → chunk-RFQW7XT3.js} +15 -15
  191. package/dist/{chunk-CZ75S2EZ.js → chunk-RL7PETU6.js} +5 -5
  192. package/dist/{chunk-2JHE75RW.js → chunk-ROVOAF2O.js} +10 -10
  193. package/dist/{chunk-GS7N3RFG.js → chunk-RSA5JJMN.js} +29 -24
  194. package/dist/{chunk-ANUMIPF6.js → chunk-RX56MZLX.js} +20 -20
  195. package/dist/chunk-S7I7SLZN.js +59 -0
  196. package/dist/{chunk-IWPO5AUT.js → chunk-S7UQFI4B.js} +23 -23
  197. package/dist/{chunk-CCQZN6W3.js → chunk-SBNBVUOF.js} +33 -33
  198. package/dist/{chunk-JCG2EBNB.js → chunk-SD3PGZSR.js} +1 -1
  199. package/dist/{chunk-QIDSEHJA.js → chunk-SEBBJQWK.js} +7 -7
  200. package/dist/{chunk-3XZRYQWU.js → chunk-SGTAQNOP.js} +31 -31
  201. package/dist/{chunk-532HDXMM.js → chunk-SHWHRCMU.js} +6 -6
  202. package/dist/{chunk-NTEPBOAF.js → chunk-SRLUADSY.js} +4 -4
  203. package/dist/{chunk-LIQWFDOZ.js → chunk-SXF66YNZ.js} +4 -4
  204. package/dist/{chunk-DF6DPCW2.js → chunk-T5QYYB5L.js} +10 -10
  205. package/dist/{chunk-XNH5ZWIA.js → chunk-TAIYQDIV.js} +18 -18
  206. package/dist/{chunk-OYTSRNSZ.js → chunk-TIOYZDRB.js} +5 -5
  207. package/dist/{chunk-FFYOZ7PF.js → chunk-TKCNJJ2S.js} +8 -8
  208. package/dist/{chunk-NOU5IBLM.js → chunk-TVFADTAT.js} +4 -4
  209. package/dist/{chunk-JJ4SCGRJ.js → chunk-U4HZ5CXL.js} +6 -6
  210. package/dist/{chunk-PIPYJTIL.js → chunk-U7F6E5M3.js} +23 -23
  211. package/dist/{chunk-ESJALLOK.js → chunk-U7YZ3IRI.js} +2 -2
  212. package/dist/{chunk-3BEGKSDW.js → chunk-UCKG6UE7.js} +8 -8
  213. package/dist/{chunk-U37ZOYJJ.js → chunk-UCQB6NKS.js} +6 -6
  214. package/dist/{chunk-FGW5TLGM.js → chunk-UI7ID4HG.js} +11 -11
  215. package/dist/{chunk-JYJMIAFS.js → chunk-UJ535VWR.js} +4 -4
  216. package/dist/{chunk-TKEXS74L.js → chunk-UKMA5JFE.js} +24 -24
  217. package/dist/{chunk-OYKNPZCV.js → chunk-UR6JGVX2.js} +183 -175
  218. package/dist/{chunk-HGDBM3A5.js → chunk-USH4VU5D.js} +2 -2
  219. package/dist/{chunk-ZSD75FYI.js → chunk-UTYL4XVA.js} +19 -19
  220. package/dist/{chunk-5MKV4TV6.js → chunk-UTZMF5CV.js} +1 -1
  221. package/dist/{chunk-ENZ3PI7L.js → chunk-UVKJVTKX.js} +3 -3
  222. package/dist/{chunk-OTUBMKSG.js → chunk-V7T6URII.js} +3 -3
  223. package/dist/{chunk-QGBS4GMS.js → chunk-VAZYNF6I.js} +12 -12
  224. package/dist/{chunk-OCU5S2XG.js → chunk-VBJHIRKV.js} +3 -3
  225. package/dist/{chunk-AAY6VPPO.js → chunk-VOBG7BLB.js} +16 -16
  226. package/dist/{chunk-T5NH5L7A.js → chunk-W2W7YCFL.js} +12 -12
  227. package/dist/{chunk-AM7PYKVP.js → chunk-WA644MUQ.js} +10 -10
  228. package/dist/{chunk-6OZAQPU5.js → chunk-WDJGJ3HV.js} +28 -4
  229. package/dist/{chunk-3XCCT2GR.js → chunk-WGOQZ4PQ.js} +155 -109
  230. package/dist/{chunk-OSZTENIA.js → chunk-WS7KBKP4.js} +2 -2
  231. package/dist/chunk-X7QLAUNS.js +47 -0
  232. package/dist/{chunk-6TNQO76I.js → chunk-XC5ZDFW7.js} +6 -6
  233. package/dist/{chunk-5ORLKITZ.js → chunk-XF5UMMQL.js} +21 -21
  234. package/dist/{chunk-YB5AKYVQ.js → chunk-XM3JE4QY.js} +5 -5
  235. package/dist/{chunk-GCMDDVIE.js → chunk-XP5DF5MC.js} +42 -10
  236. package/dist/{chunk-JMH6TCZJ.js → chunk-XUCHGEF5.js} +20 -20
  237. package/dist/{chunk-TKE6ZJMM.js → chunk-XVQQ3BQS.js} +24 -24
  238. package/dist/{chunk-HXFZX2BI.js → chunk-XXJSGCDO.js} +8 -8
  239. package/dist/{chunk-MT3FNSXO.js → chunk-XY6FVBBV.js} +1 -1
  240. package/dist/{chunk-CNF2EZ6S.js → chunk-XZQBFF65.js} +116 -116
  241. package/dist/{chunk-GXQYEIYM.js → chunk-Y3J365UC.js} +5 -5
  242. package/dist/{chunk-ZX6RAGE6.js → chunk-Y6KPWRZJ.js} +9 -9
  243. package/dist/{chunk-775FMPUB.js → chunk-YAUMNRCB.js} +4 -4
  244. package/dist/{chunk-AWDCVZYO.js → chunk-YEGGQG5E.js} +5 -5
  245. package/dist/{chunk-XNW3EDCY.js → chunk-YGNQUFVZ.js} +2 -2
  246. package/dist/{chunk-HRHXTLUM.js → chunk-YGS2YVF2.js} +14 -14
  247. package/dist/{chunk-25CUJJTP.js → chunk-YRKAJ42V.js} +34 -16
  248. package/dist/{chunk-O4ZWZZZT.js → chunk-Z3KEX7ON.js} +4 -4
  249. package/dist/{chunk-JLYH2QOE.js → chunk-Z4N7BKLN.js} +5 -5
  250. package/dist/{chunk-7HWCEDPX.js → chunk-ZD64ZR64.js} +5 -5
  251. package/dist/{chunk-RQAMZVWW.js → chunk-ZJQ64T6M.js} +8 -8
  252. package/dist/files.json +547 -547
  253. package/dist/packages/sdk/npm/index.js +110 -28
  254. package/dist/packages/ui/dist/assets/{elk-api--rH6Kdl4.js → elk-api-ts8TigYQ.js} +2 -2
  255. package/dist/packages/ui/dist/assets/index-CIfmX7DJ.css +1 -0
  256. package/dist/packages/ui/dist/assets/index-DNtpSfZS.js +63 -0
  257. package/dist/packages/ui/dist/index.html +2 -2
  258. package/package.json +5 -5
  259. package/dist/chunk-26AB2WNW.js +0 -62
  260. package/dist/chunk-C7BB6IQT.js +0 -147
  261. package/dist/chunk-DYDNW4O6.js +0 -52
  262. package/dist/chunk-MA6UK7GX.js +0 -42
  263. package/dist/chunk-NBZ7RKX3.js +0 -46
  264. package/dist/chunk-OYZ64UMQ.js +0 -67
  265. package/dist/chunk-PIPJZIJE.js +0 -47
  266. package/dist/chunk-Q2ULHBCJ.js +0 -59
  267. package/dist/chunk-QVF4KYIO.js +0 -71
  268. package/dist/chunk-T2HXLDY3.js +0 -55
  269. package/dist/chunk-WQDJGNJQ.js +0 -45
  270. package/dist/packages/ui/dist/assets/index-Bf2immpE.css +0 -1
  271. package/dist/packages/ui/dist/assets/index-CH4nGIW3.js +0 -62
@@ -118,7 +118,7 @@ import {
118
118
  normalizePath,
119
119
  slugify,
120
120
  urlHostPort
121
- } from "./chunk-QFDPX6C4.js";
121
+ } from "./chunk-LZFKJ2BR.js";
122
122
  import {
123
123
  SCHEMA_VERSION,
124
124
  keptParse
@@ -239,12 +239,14 @@ var TOKEN_SHAPES = [
239
239
  /\bAIza[0-9A-Za-z_-]{35}/g,
240
240
  /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g
241
241
  ];
242
- function hasSecretShape(text4) {
242
+ function hasSecretShape(text4, o = {}) {
243
243
  for (const m of text4.matchAll(URL_CREDENTIALS))
244
244
  if (!refersOnly(m[2]))
245
245
  return true;
246
246
  if (new RegExp(BEARER.source).test(text4))
247
247
  return true;
248
+ if (o.basic !== false && new RegExp(BASIC.source).test(text4))
249
+ return true;
248
250
  return TOKEN_SHAPES.some((re) => new RegExp(re.source).test(text4));
249
251
  }
250
252
  var placeholder = (v) => PLACEHOLDER.test(v.trim().replace(/^["'`]/, ""));
@@ -366,7 +368,12 @@ var common = {
366
368
  id: FactId,
367
369
  repo: str(),
368
370
  commit: external_exports.string().regex(/^[0-9a-f]{7,64}$/),
369
- /** The module in the repo the fact belongs to; the repo itself when left out. */
371
+ /**
372
+ * The component the fact belongs to: the component the manifest names (a module only when the
373
+ * manifest lists modules); the repo's own when left out. Review of beta.25: in a repo whose
374
+ * manifest lists no modules, one the manifest doesn't name (a folder's) is placed in the repo's
375
+ * component (`placedComponentOf`), with a note.
376
+ */
370
377
  component: external_exports.string().optional(),
371
378
  cite: Cite,
372
379
  verified: FactVerified.default("none"),
@@ -566,6 +573,133 @@ function namesOfKey(key3) {
566
573
  function looksLikeSecret(key3, value) {
567
574
  return value !== void 0 && namesOfKey(key3).some((n) => SECRET_KEY2.test(n)) && !SECRET_SOURCE.test(value) && !NOT_A_SECRET.test(value.trim());
568
575
  }
576
+ var tokenLike = (t) => /^[A-Za-z0-9+/=_.~-]{6,}$/.test(t) && /[0-9]/.test(t) && /[A-Za-z]/.test(t) && !/\.[a-z]{2,5}$/i.test(t) && !pathOfNames(t);
577
+ var pathOfNames = (t) => t.startsWith("/") || t.includes("/") && t.split("/").every((s) => s === "" || NAME_LIKE.some((r) => r.test(s)) || identifierName(s) || fileName(s));
578
+ var fileName = (t) => /^[A-Za-z][\w.-]*\.[A-Za-z]{2,5}$/.test(t);
579
+ var NAME_LIKE = [
580
+ /^[A-Z]+[0-9]{0,3}(?:_(?:[A-Z]+[0-9]{0,3}|[0-9]{1,4}))*$/,
581
+ /^[a-z]+[0-9]{0,3}(?:[-_.](?:[a-z]+[0-9]{0,3}|[0-9]{1,4}))*$/
582
+ ];
583
+ function identifierName(t) {
584
+ return NAME_LIKE[0].test(t) && (t.includes("_") || !/[0-9]/.test(t)) || NAME_LIKE[1].test(t) && t.split(/[-_.]/).filter((w) => /[a-z]/.test(w)).length >= 2 || /^[A-Za-z][a-z]+[0-9]{0,3}(?:[A-Z][a-z]+[0-9]{0,3}|[A-Z][0-9]{1,3})+$/.test(t);
585
+ }
586
+ var NO_DEFAULT = /^(true|false|yes|no|on|off|none|null)$/i;
587
+ var REFERENCE_SCHEMES = /* @__PURE__ */ new Set([
588
+ "env",
589
+ "vault",
590
+ "secret",
591
+ "ref",
592
+ "secretkeyref",
593
+ "configmapkeyref",
594
+ "file",
595
+ "kvm"
596
+ ]);
597
+ var PLACEHOLDER_SCHEMES = /* @__PURE__ */ new Set([
598
+ ...REFERENCE_SCHEMES,
599
+ "ssm",
600
+ "sm",
601
+ "secretsmanager",
602
+ "aws",
603
+ "azure",
604
+ "keyvault",
605
+ "gcp",
606
+ "k8s",
607
+ "cf",
608
+ "opt",
609
+ "self",
610
+ "sys",
611
+ "param"
612
+ ]);
613
+ function literalDefault(t) {
614
+ for (const m of t.matchAll(/\$\{([^{}:$]*):(-?)([^}$]*)/g)) {
615
+ const name = m[1].trim();
616
+ if (!/^[A-Za-z0-9_.-]+$/.test(name) || PLACEHOLDER_SCHEMES.has(name.toLowerCase()))
617
+ continue;
618
+ const d = m[3].trim();
619
+ if (!m[2] && /^[?+]/.test(d))
620
+ continue;
621
+ if (d && !NO_DEFAULT.test(d))
622
+ return true;
623
+ }
624
+ return false;
625
+ }
626
+ var VARIABLE_REFERENCE = [
627
+ /^\$\{\{[^{}]*\}\}$/,
628
+ /^\$[A-Za-z_][A-Za-z0-9_]*$/,
629
+ /^\$\{[A-Za-z_][A-Za-z0-9_.-]*\}$/,
630
+ /^%[A-Za-z_][A-Za-z0-9_]*%$/,
631
+ /^#\{[^{}]*\}$/
632
+ ];
633
+ var LITERAL_FILE = /^literal:\s*(?:(?:[\w.-]+\/)+[\w.-]+|[\w-][\w.-]*\.[A-Za-z0-9]{1,10}|\.[\w.-]+|[A-Za-z][\w-]*file)$/i;
634
+ function isReference(t) {
635
+ if (VARIABLE_REFERENCE.some((r) => r.test(t)) && !literalDefault(t))
636
+ return true;
637
+ if (LITERAL_FILE.test(t))
638
+ return true;
639
+ if (/^basic:/i.test(t))
640
+ return isReference(t.slice("basic:".length).trim());
641
+ if (/^(\$\{|\{\{)/.test(t)) {
642
+ if (literalDefault(t))
643
+ return false;
644
+ let rest2 = t;
645
+ for (let was = ""; was !== rest2; ) {
646
+ was = rest2;
647
+ rest2 = rest2.replace(/\$\{[^{}]*\}|\{\{[^{}]*\}\}/g, "");
648
+ }
649
+ return rest2.trim() === "";
650
+ }
651
+ const m = /^([A-Za-z][A-Za-z0-9-]*):(.+)$/.exec(t);
652
+ if (!m)
653
+ return false;
654
+ const rest = m[2].trim();
655
+ return REFERENCE_SCHEMES.has(m[1].toLowerCase()) || /[/:]/.test(rest) || identifierName(rest) || /^(\$\{|\{\{)/.test(rest) && isReference(rest);
656
+ }
657
+ var entropy = (t) => {
658
+ const n = /* @__PURE__ */ new Map();
659
+ for (const ch of t)
660
+ n.set(ch, (n.get(ch) ?? 0) + 1);
661
+ let h = 0;
662
+ for (const c of n.values())
663
+ h -= c / t.length * Math.log2(c / t.length);
664
+ return h;
665
+ };
666
+ var credentialStrength = (t) => {
667
+ const kinds = [/[a-z]/, /[A-Z]/, /[0-9]/, /[^A-Za-z0-9]/].filter((r) => r.test(t)).length;
668
+ return t.length >= 16 && kinds >= 2 || t.length >= 8 && kinds >= 3 || t.length >= 12 && entropy(t) >= 3.5;
669
+ };
670
+ function credentialLike(t) {
671
+ return tokenLike(t) && !NAME_LIKE.some((r) => r.test(t)) && credentialStrength(t);
672
+ }
673
+ function configSecretField(c) {
674
+ const secretKey = looksLikeSecret(c.key, "x");
675
+ if (c.value !== void 0 && (looksLikeSecret(c.key, c.value) || hasSecretShape(c.value) || secretKey && literalDefault(c.value)))
676
+ return "value";
677
+ const target = c.target?.trim();
678
+ const own = new Set([c.key, c.env, target, target?.replace(/\.[^.]*$/, "")].filter((x) => !!x).map((x) => x.trim()));
679
+ const keyText = c.key.toLowerCase();
680
+ const source = c.source?.trim();
681
+ const ownName = (t) => own.has(t) || keyText.includes(t.toLowerCase());
682
+ const secret = (v, isSource) => {
683
+ const t = v.trim();
684
+ if (!t)
685
+ return false;
686
+ if (hasSecretShape(t))
687
+ return true;
688
+ if (secretKey && literalDefault(t))
689
+ return true;
690
+ if (isSource)
691
+ return secretKey && !isReference(t) && !identifierName(t) && // the file it is read from (`config/app.yml`, `src/Creds.java`)
692
+ !pathOfNames(t) && !fileName(t) && !NOT_A_SECRET.test(t) && !ownName(t) && // where it lives said in words (`the Kubernetes Secret forge-db`)
693
+ t.split(/\s+/).filter((w) => /^[A-Za-z]{2,}$/.test(w)).length < 2;
694
+ return looksLikeSecret(c.key, t) && // a credential, or a password by its marks (`Summer2024!`): no name, version or hash has one
695
+ (credentialLike(t) || /^\S+$/.test(t) && /[A-Za-z]/.test(t) && /[0-9]/.test(t) && /[!#%^&*?]/.test(t)) && !ownName(t) && (!source || !source.includes(t));
696
+ };
697
+ if (source !== void 0 && secret(source, true))
698
+ return "source";
699
+ if ((c.cite.with ?? []).some((w) => typeof w?.value === "string" && secret(w.value, false)))
700
+ return "cite.with";
701
+ return void 0;
702
+ }
569
703
  var ConfigFact = external_exports.strictObject({
570
704
  kind: external_exports.literal("config"),
571
705
  ...common,
@@ -586,7 +720,7 @@ var ConfigFact = external_exports.strictObject({
586
720
  path: ["value"],
587
721
  message: `"${c.key}" looks like a secret: give its source (env:NAME, vault:path), never its value`
588
722
  });
589
- } else if (c.value !== void 0 && hasSecretShape(c.value)) {
723
+ } else if (c.value !== void 0 && hasSecretShape(c.value, { basic: false })) {
590
724
  ctx.addIssue({
591
725
  code: "custom",
592
726
  path: ["value"],
@@ -1183,8 +1317,121 @@ function migrationOf(path) {
1183
1317
  }
1184
1318
 
1185
1319
  // packages/core/dist/facts.js
1320
+ var KNOWN_KINDS = new Set(FACT_KINDS);
1321
+ function newerFactOf(json, line) {
1322
+ if (!json || typeof json !== "object" || Array.isArray(json))
1323
+ return void 0;
1324
+ const { kind, id } = json;
1325
+ if (typeof kind !== "string" || typeof id !== "string" || KNOWN_KINDS.has(kind))
1326
+ return void 0;
1327
+ return {
1328
+ ...line !== void 0 ? { line } : {},
1329
+ factId: id,
1330
+ kind,
1331
+ message: `fact ${id} is written by a newer Atticus (fact kind ${kind}); install it to read this fact`
1332
+ };
1333
+ }
1334
+ var FIELD_NAME = /^[a-z][A-Za-z0-9]*$/;
1335
+ var ENUM_VALUE = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/;
1336
+ var FIELDS = /* @__PURE__ */ new Map();
1337
+ function fieldsOf(kind) {
1338
+ const held = FIELDS.get(kind);
1339
+ if (held)
1340
+ return held;
1341
+ const option = Fact.options.find((o) => o.shape.kind.safeParse(kind).success);
1342
+ const out = [...Object.keys(option?.shape ?? {}), "file", "line", "value", "quote", "with"];
1343
+ FIELDS.set(kind, out);
1344
+ return out;
1345
+ }
1346
+ function edits(a, b) {
1347
+ if (Math.abs(a.length - b.length) > 2)
1348
+ return 3;
1349
+ const d = [];
1350
+ for (let i = 0; i <= a.length; i++) {
1351
+ d[i] = [i];
1352
+ for (let j = 1; j <= b.length; j++) {
1353
+ if (i === 0) {
1354
+ d[0][j] = j;
1355
+ continue;
1356
+ }
1357
+ let v = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
1358
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1])
1359
+ v = Math.min(v, d[i - 2][j - 2] + 1);
1360
+ d[i][j] = v;
1361
+ }
1362
+ }
1363
+ return Math.min(d[a.length][b.length], 3);
1364
+ }
1365
+ var nearFieldOf = (kind, key3) => {
1366
+ if (key3.length <= 3)
1367
+ return false;
1368
+ const k = key3.toLowerCase();
1369
+ return fieldsOf(kind).some((field) => {
1370
+ const f = field.toLowerCase();
1371
+ if (f === k || f[0] !== k[0])
1372
+ return false;
1373
+ const inflected = [`${f}s`, `${f}d`].includes(k) || [`${k}s`, `${k}d`].includes(f);
1374
+ return !inflected && edits(f, k) === 1;
1375
+ });
1376
+ };
1377
+ var meantValueOf = (v, values) => values.filter((x) => typeof x === "string").map((x) => [x, edits(x, v)]).filter(([, n]) => n <= 2).sort((a, b) => a[1] - b[1])[0]?.[0];
1378
+ function sayIssue(json, i) {
1379
+ if (i.code !== "invalid_value")
1380
+ return i;
1381
+ const v = valueAt(json, i.path);
1382
+ if (typeof v !== "string")
1383
+ return i;
1384
+ const kind = json?.kind;
1385
+ if (kind === "dependency" && i.path.length === 1 && i.path[0] === "scope" && v === "system")
1386
+ return { ...i, message: "record a system-scoped dependency as provided" };
1387
+ const meant = ENUM_VALUE.test(v) ? meantValueOf(v, i.values) : void 0;
1388
+ return meant ? { ...i, message: `${i.message} (did you mean "${meant}"?)` } : i;
1389
+ }
1390
+ var valueAt = (json, path) => {
1391
+ let at3 = json;
1392
+ for (const k of path) {
1393
+ if (!at3 || typeof at3 !== "object")
1394
+ return void 0;
1395
+ at3 = at3[k];
1396
+ }
1397
+ return at3;
1398
+ };
1399
+ function newerShapeOf(json, issues3, line) {
1400
+ if (!json || typeof json !== "object" || Array.isArray(json) || !issues3.length)
1401
+ return void 0;
1402
+ const { kind, id } = json;
1403
+ if (typeof kind !== "string" || typeof id !== "string" || !KNOWN_KINDS.has(kind))
1404
+ return void 0;
1405
+ const said = [];
1406
+ for (const i of issues3) {
1407
+ const where2 = i.path.map(String).join(".");
1408
+ const near = i.code === "unrecognized_keys" && i.keys.some((k) => nearFieldOf(kind, k));
1409
+ if (i.code === "unrecognized_keys" && !near && i.keys.length && i.keys.every((k) => FIELD_NAME.test(k)))
1410
+ said.push(...i.keys.map((k) => `field ${where2 ? `${where2}.` : ""}${k} is new to the ${kind} fact`));
1411
+ else if (i.code === "invalid_value") {
1412
+ const v = valueAt(json, i.path);
1413
+ if (typeof v !== "string" || !ENUM_VALUE.test(v))
1414
+ return void 0;
1415
+ if (meantValueOf(v, i.values) !== void 0)
1416
+ return void 0;
1417
+ if (kind === "dependency" && where2 === "scope" && v === "system")
1418
+ return void 0;
1419
+ said.push(`${where2} "${v}" is a value this Atticus doesn't know`);
1420
+ } else
1421
+ return void 0;
1422
+ }
1423
+ return {
1424
+ ...line !== void 0 ? { line } : {},
1425
+ factId: id,
1426
+ kind,
1427
+ message: `fact ${id} is written by a newer Atticus (${said.join("; ")}); install it to read this fact`
1428
+ };
1429
+ }
1186
1430
  function parseFacts(text4) {
1187
1431
  const trimmed = text4.trim();
1432
+ const facts = [];
1433
+ const issues3 = [];
1434
+ const newer2 = [];
1188
1435
  if (trimmed.startsWith("[")) {
1189
1436
  let json;
1190
1437
  try {
@@ -1192,13 +1439,25 @@ function parseFacts(text4) {
1192
1439
  } catch (e) {
1193
1440
  return { ok: false, issues: [{ code: "not-json", message: e.message }] };
1194
1441
  }
1195
- const r = FactsFile.safeParse(normalizeFactPaths(json));
1196
- if (r.success)
1197
- return { ok: true, facts: r.data };
1198
- return { ok: false, issues: r.error.issues.map((i) => issueOf(i)) };
1442
+ if (!Array.isArray(json))
1443
+ return { ok: false, issues: [{ code: "invalid_type", message: "(root): not an array" }] };
1444
+ json.forEach((item, i) => {
1445
+ const n = newerFactOf(item);
1446
+ if (n)
1447
+ return void newer2.push(n);
1448
+ const r = Fact.safeParse(normalizeFactPaths(item));
1449
+ if (r.success)
1450
+ facts.push(r.data);
1451
+ else if (newerShapeOf(item, r.error.issues))
1452
+ newer2.push(newerShapeOf(item, r.error.issues));
1453
+ else
1454
+ for (const iss of r.error.issues.map((x) => sayIssue(item, x)))
1455
+ issues3.push({ code: iss.code, message: `${[i, ...iss.path].join(".")}: ${iss.message}` });
1456
+ });
1457
+ if (issues3.length)
1458
+ return { ok: false, issues: issues3 };
1459
+ return { ok: true, facts, ...newer2.length ? { newer: newer2 } : {} };
1199
1460
  }
1200
- const facts = [];
1201
- const issues3 = [];
1202
1461
  const lines = trimmed === "" ? [] : trimmed.split(/\r?\n/);
1203
1462
  lines.forEach((raw, i) => {
1204
1463
  const line = i + 1;
@@ -1211,12 +1470,17 @@ function parseFacts(text4) {
1211
1470
  issues3.push({ line, code: "not-json", message: e.message });
1212
1471
  return;
1213
1472
  }
1473
+ const n = newerFactOf(json, line);
1474
+ if (n)
1475
+ return void newer2.push(n);
1214
1476
  const r = Fact.safeParse(normalizeFactPaths(json));
1215
1477
  if (r.success)
1216
1478
  facts.push(r.data);
1479
+ else if (newerShapeOf(json, r.error.issues, line))
1480
+ newer2.push(newerShapeOf(json, r.error.issues, line));
1217
1481
  else
1218
1482
  for (const iss of r.error.issues)
1219
- issues3.push({ line, ...issueOf(iss) });
1483
+ issues3.push({ line, ...issueOf(sayIssue(json, iss)) });
1220
1484
  });
1221
1485
  const seen = /* @__PURE__ */ new Map();
1222
1486
  facts.forEach((f, i) => {
@@ -1226,11 +1490,60 @@ function parseFacts(text4) {
1226
1490
  else
1227
1491
  seen.set(f.id, i);
1228
1492
  });
1229
- return issues3.length ? { ok: false, issues: issues3 } : { ok: true, facts };
1493
+ return issues3.length ? { ok: false, issues: issues3 } : { ok: true, facts, ...newer2.length ? { newer: newer2 } : {} };
1230
1494
  }
1231
1495
  function issueOf(i) {
1232
1496
  return { code: i.code, message: `${i.path.join(".") || "(root)"}: ${i.message}` };
1233
1497
  }
1498
+ var REDACTED = "<redacted>";
1499
+ function redactFactLine(raw) {
1500
+ const text4 = raw.charCodeAt(0) === 65279 ? raw.slice(1) : raw;
1501
+ let json;
1502
+ try {
1503
+ json = JSON.parse(text4);
1504
+ } catch {
1505
+ const out2 = redactSecrets(raw).replace(/"((?:[^"\\]|\\.){6,})"/g, (all, v) => credentialLike(v) || hasSecretShape(v) ? `"${REDACTED}"` : all);
1506
+ const key4 = /"key"\s*:\s*"((?:[^"\\]|\\.)*)"/.exec(out2)?.[1];
1507
+ if (key4 === void 0 || !looksLikeSecret(key4, "x"))
1508
+ return out2;
1509
+ return out2.replace(/("(?:value|source|quote)"\s*:\s*)"(?:[^"\\]|\\.)*("|$)/g, (_, head, end) => `${head}"${REDACTED}${end}`);
1510
+ }
1511
+ if (!json || typeof json !== "object" || Array.isArray(json))
1512
+ return raw;
1513
+ const f = json;
1514
+ const str3 = (v) => typeof v === "string" ? v : void 0;
1515
+ const cite = f.cite && typeof f.cite === "object" && !Array.isArray(f.cite) ? f.cite : {};
1516
+ const withs = Array.isArray(cite.with) ? cite.with : [];
1517
+ const parts = withs.map((w) => w && typeof w === "object" ? str3(w.value) : void 0);
1518
+ const key3 = str3(f.key);
1519
+ const strings = [str3(f.value), str3(f.source), ...parts].filter((x) => !!x);
1520
+ const quote = str3(cite.quote);
1521
+ const quoteHolds = quote !== void 0 && key3 !== void 0 && looksLikeSecret(key3, "x") && quote.split(/[\s"'`:=,;{}()<>[\]]+/).some((w) => credentialLike(w));
1522
+ const secret = key3 !== void 0 && !!configSecretField({
1523
+ key: key3,
1524
+ value: str3(f.value),
1525
+ source: str3(f.source),
1526
+ target: str3(f.target),
1527
+ env: str3(f.env),
1528
+ cite: { with: parts.flatMap((v) => v === void 0 ? [] : [{ value: v }]) }
1529
+ }) || strings.some((s) => hasSecretShape(s)) || quoteHolds || quote !== void 0 && redactSecrets(quote) !== quote;
1530
+ if (!secret)
1531
+ return raw;
1532
+ const out = { ...f };
1533
+ if (str3(f.value) !== void 0)
1534
+ out.value = REDACTED;
1535
+ if (str3(f.source) !== void 0)
1536
+ out.source = REDACTED;
1537
+ if (Object.keys(cite).length) {
1538
+ const c = { ...cite };
1539
+ if (c.quote !== void 0)
1540
+ c.quote = REDACTED;
1541
+ if (withs.length)
1542
+ c.with = withs.map((w) => w && typeof w === "object" ? { ...w, value: REDACTED } : REDACTED);
1543
+ out.cite = c;
1544
+ }
1545
+ return JSON.stringify(out);
1546
+ }
1234
1547
  function parseFactLine(raw, line, seen) {
1235
1548
  if (raw.trim() === "")
1236
1549
  return {};
@@ -1242,11 +1555,22 @@ function parseFactLine(raw, line, seen) {
1242
1555
  const message = text4.includes("\0") ? "the file is UTF-16 (PowerShell's Out-File writes it): save it as UTF-8, one JSON fact per line" : e.message;
1243
1556
  return { bad: { line, raw, issues: [{ line, code: "not-json", message }] } };
1244
1557
  }
1558
+ const newer2 = newerFactOf(json, line);
1559
+ if (newer2)
1560
+ return { newer: { ...newer2, raw } };
1245
1561
  const r = Fact.safeParse(normalizeFactPaths(json));
1246
- if (!r.success)
1562
+ if (!r.success) {
1563
+ const shape = newerShapeOf(json, r.error.issues, line);
1564
+ if (shape)
1565
+ return { newer: { ...shape, raw } };
1247
1566
  return {
1248
- bad: { line, raw, issues: r.error.issues.map((iss) => ({ line, ...issueOf(iss) })) }
1567
+ bad: {
1568
+ line,
1569
+ raw,
1570
+ issues: r.error.issues.map((iss) => ({ line, ...issueOf(sayIssue(json, iss)) }))
1571
+ }
1249
1572
  };
1573
+ }
1250
1574
  if (seen.has(r.data.id))
1251
1575
  return {
1252
1576
  bad: {
@@ -1268,6 +1592,7 @@ function parseFactLine(raw, line, seen) {
1268
1592
  function parseFactsLines(text4) {
1269
1593
  const facts = [];
1270
1594
  const bad = [];
1595
+ const newer2 = [];
1271
1596
  const seen = /* @__PURE__ */ new Set();
1272
1597
  text4.split(/\r?\n/).forEach((raw, i) => {
1273
1598
  const r = parseFactLine(raw, i + 1, seen);
@@ -1275,8 +1600,10 @@ function parseFactsLines(text4) {
1275
1600
  facts.push(r.fact);
1276
1601
  else if (r.bad)
1277
1602
  bad.push(r.bad);
1603
+ else if (r.newer)
1604
+ newer2.push(r.newer);
1278
1605
  });
1279
- return { facts, bad };
1606
+ return { facts, bad, newer: newer2 };
1280
1607
  }
1281
1608
  function serializeFacts(facts) {
1282
1609
  const sorted2 = [...facts].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
@@ -1288,6 +1615,18 @@ function entryEndpointId(f, component) {
1288
1615
  const name = f.entryType === "event-topic" || f.entryType === "mq-queue" ? `on-${idPart(f.path)}` : idPart(`${f.method ?? ""} ${f.path}`);
1289
1616
  return `${component}.${name}`;
1290
1617
  }
1618
+ function placedComponentOf(f, manifest) {
1619
+ if (f.component === void 0 || f.kind === "artifact" || f.kind === "dependency")
1620
+ return;
1621
+ if (manifest.modules?.length || manifest.prototype)
1622
+ return;
1623
+ const c = idPart(f.component);
1624
+ if (c === idPart(manifest.component))
1625
+ return;
1626
+ if (manifest.components.some((x) => idPart(x) === c))
1627
+ return;
1628
+ return manifest.component;
1629
+ }
1291
1630
  function callPath(callType, path) {
1292
1631
  if (callType === "grpc" || callType === "soap")
1293
1632
  return path.trim().replace(/^\/+/, "");
@@ -2383,6 +2722,7 @@ var ignoreOption = () => ({
2383
2722
  means: "These aren't real calls: a CI/CD job, a test or a template, not code that runs",
2384
2723
  changes: "The join leaves these calls (ignored by you), no box is drawn for them, and this isn't asked again"
2385
2724
  });
2725
+ var IGNORE_REASON_MAX = 300;
2386
2726
  var ignoreText = (reason) => `${IGNORE_PREFIX} ${reason.trim()}`;
2387
2727
  function ignoredAnswer(q2) {
2388
2728
  const a = q2.answer;
@@ -2399,18 +2739,17 @@ function ignoredAnswer(q2) {
2399
2739
  return reason ? { reason } : {};
2400
2740
  }
2401
2741
  var SYSTEM_NAME_MAX = 40;
2402
- var SENTENCE_WORDS = /* @__PURE__ */ new Set([
2403
- "ignore",
2404
- "this",
2405
- "is",
2406
- "a",
2407
- "to",
2408
- "the",
2409
- "related",
2410
- "not",
2411
- "its",
2412
- "it"
2413
- ]);
2742
+ var SENTENCE_WORDS = /* @__PURE__ */ new Set(["this", "is", "a", "to", "the", "not", "its", "it"]);
2743
+ var sentenceWordsIn = (words) => words.trim().toLowerCase().split(/[\s_'’,;:!?."“”()-]+/).filter((w) => SENTENCE_WORDS.has(w)).length;
2744
+ function nameReadsAsSentence(name) {
2745
+ return sentenceWordsIn(name) >= 2;
2746
+ }
2747
+ function readsAsSentence(words) {
2748
+ const n = words.trim();
2749
+ if (/[,;!?"“”]|\.(?:\s|$)/.test(n))
2750
+ return true;
2751
+ return sentenceWordsIn(n) >= 2;
2752
+ }
2414
2753
  function systemNameProblem(name) {
2415
2754
  const n = name.trim();
2416
2755
  if (!n)
@@ -2419,27 +2758,21 @@ function systemNameProblem(name) {
2419
2758
  return `a system's name is at most ${SYSTEM_NAME_MAX} characters (this is ${n.length})`;
2420
2759
  if (!/^[A-Za-z0-9][A-Za-z0-9 -]*$/.test(n))
2421
2760
  return "a system's name is letters, digits, spaces and dashes only";
2422
- const words = n.toLowerCase().split(/[\s-]+/).filter(Boolean);
2423
- if (words.length > 4 || words.some((w) => SENTENCE_WORDS.has(w)))
2761
+ if (readsAsSentence(n))
2424
2762
  return "that reads as a sentence, not a system's name";
2425
2763
  return void 0;
2426
2764
  }
2427
- function madeFromWords(id, name) {
2428
- const words = id.toLowerCase().split(/[-_.]+/).filter(Boolean);
2429
- if (words.length >= 5)
2430
- return true;
2431
- if (words.some((w) => SENTENCE_WORDS.has(w)))
2432
- return true;
2433
- const n = name?.trim() ?? "";
2434
- return /\s/.test(n) && n.length > SYSTEM_NAME_MAX;
2435
- }
2436
- async function namesKnownTarget(root, words) {
2437
- const { loadOrgPack } = await import("./chunk-RSKMV3VC.js");
2765
+ async function knownTargetNames(root, o = {}) {
2766
+ const { loadOrgPack } = await import("./chunk-3D74UADA.js");
2438
2767
  const op = await loadOrgPack(orgPackDirOf(root)).catch(() => void 0);
2768
+ const ids = /* @__PURE__ */ new Set();
2439
2769
  const names = /* @__PURE__ */ new Set();
2440
- const add = (n) => {
2770
+ const systemNames = /* @__PURE__ */ new Set();
2771
+ const add = (n, isId = true) => {
2441
2772
  if (!n?.trim())
2442
2773
  return;
2774
+ if (isId)
2775
+ ids.add(n.trim().toLowerCase());
2443
2776
  names.add(n.trim().toLowerCase());
2444
2777
  names.add(slugify(n));
2445
2778
  };
@@ -2450,15 +2783,18 @@ async function namesKnownTarget(root, words) {
2450
2783
  for (const m of r.modules ?? [])
2451
2784
  add(m.component);
2452
2785
  }
2453
- for (const s of p2.profile?.systems ?? [])
2454
- for (const n of [s.id, s.name, ...s.aliases, ...s.topics ?? []])
2786
+ for (const s of p2.profile?.systems ?? []) {
2787
+ if (o.except?.has(s.id))
2788
+ continue;
2789
+ for (const n of [s.id, ...s.aliases, ...s.topics ?? []])
2455
2790
  add(n);
2791
+ add(s.name, false);
2792
+ if (s.name.trim() && !nameReadsAsSentence(s.name))
2793
+ systemNames.add(s.name.trim().toLowerCase());
2794
+ }
2456
2795
  }
2457
2796
  for (const t of op?.roles?.teams ?? [])
2458
2797
  add(t.id);
2459
- const want = words.trim().toLowerCase();
2460
- if (names.has(want) || names.has(slugify(words)))
2461
- return true;
2462
2798
  const dir = factsDirOf(root);
2463
2799
  for (const f of await readdir2(dir).catch(() => [])) {
2464
2800
  if (!/^[^.][^/]*\.jsonl$/.test(f) || /\.(corrections|reviewed|rejected)\.jsonl$/.test(f))
@@ -2466,10 +2802,21 @@ async function namesKnownTarget(root, words) {
2466
2802
  const text4 = await readFile2(join3(dir, f), "utf8").catch(() => "");
2467
2803
  for (const m of text4.matchAll(/"component"\s*:\s*"([^"]+)"/g))
2468
2804
  add(m[1]);
2469
- if (names.has(want) || names.has(slugify(words)))
2470
- return true;
2471
2805
  }
2472
- return false;
2806
+ return { ids, names, systemNames };
2807
+ }
2808
+ function namesKnown(known, words) {
2809
+ const want = words.trim().toLowerCase();
2810
+ if (!want)
2811
+ return false;
2812
+ if (known.systemNames?.has(want))
2813
+ return true;
2814
+ if (readsAsSentence(want))
2815
+ return known.ids.has(want);
2816
+ return known.names.has(want) || known.names.has(slugify(words));
2817
+ }
2818
+ async function namesKnownTarget(root, words, o = {}) {
2819
+ return namesKnown(await knownTargetNames(root, o), words);
2473
2820
  }
2474
2821
  var wordsNameNothing = (words) => `"${words.length > 60 ? `${words.slice(0, 57)}...` : words}" names no repo, component or system Atticus knows, so it isn't made into a box on the map. Pick a repo or system; or choose "An outside system (new)" and type its name (a short name: letters, digits, spaces and dashes, up to ${SYSTEM_NAME_MAX} characters, not a sentence); or choose "${JOIN_IGNORE_LABEL}" if these aren't real calls.`;
2475
2822
  var HOSTS_OUTSIDE_INTERNAL = "An outside system (new): another team's";
@@ -2489,7 +2836,7 @@ function hostOfQuestion(q2) {
2489
2836
  return /^Which repo answers on (\S+)\?$/.exec(q2.question.trim())?.[1];
2490
2837
  }
2491
2838
  function joinHostOfQuestion(q2) {
2492
- return /^Which repo answers on (\S+)\?(?:\s|$)/.exec(q2.question.trim())?.[1];
2839
+ return /^Which repo answers on (\S(?:.*?\S)?)\?(?:\s|$)/.exec(q2.question.trim())?.[1];
2493
2840
  }
2494
2841
  var WHOLE_TOKEN = [
2495
2842
  /^@([A-Za-z_][A-Za-z0-9_.-]*)@$/,
@@ -2509,6 +2856,36 @@ async function platformsOf(root) {
2509
2856
  const names = await readdir2(profiles, { withFileTypes: true }).catch(() => []);
2510
2857
  return names.filter((x) => x.isDirectory()).map((x) => ({ dir: join3(profiles, x.name), platform: x.name })).sort((a, b) => cmpText(a.platform, b.platform));
2511
2858
  }
2859
+ var unpadded = (line) => line.replace(/([[{]) +/g, "$1").replace(/ +([\]}])/g, "$1").replace(/[ \t]+#/g, " #").replace(/[ \t]+$/, "");
2860
+ function profileText(doc, before) {
2861
+ const was = before === void 0 ? void 0 : lfOnly(before);
2862
+ const out = doc.toString({
2863
+ lineWidth: 0,
2864
+ flowCollectionPadding: was === void 0 ? true : /[[{] \S/.test(was)
2865
+ });
2866
+ if (was === void 0)
2867
+ return out;
2868
+ const kept = /* @__PURE__ */ new Map();
2869
+ for (const l of was.split("\n"))
2870
+ if (!kept.has(unpadded(l)))
2871
+ kept.set(unpadded(l), l);
2872
+ const text4 = out.split("\n").map((l) => kept.get(unpadded(l)) ?? l).join("\n");
2873
+ return was && !was.endsWith("\n") ? text4.replace(/\n+$/, "") : text4;
2874
+ }
2875
+ var ProfileEditError = class extends Error {
2876
+ };
2877
+ function aliasesLeftOf(doc) {
2878
+ const anchors = /* @__PURE__ */ new Set();
2879
+ const left = [];
2880
+ (0, import_yaml6.visit)(doc, (_key, node) => {
2881
+ if ((0, import_yaml6.isAlias)(node)) {
2882
+ if (!anchors.has(node.source) && !left.includes(node.source))
2883
+ left.push(node.source);
2884
+ } else if ((0, import_yaml6.isNode)(node) && node.anchor)
2885
+ anchors.add(node.anchor);
2886
+ });
2887
+ return left;
2888
+ }
2512
2889
  async function addOutsideSystem(root, repo, host, boundary) {
2513
2890
  const platforms = await platformsOf(root);
2514
2891
  const sys = outsideSystemOf(host);
@@ -2532,10 +2909,10 @@ async function addOutsideSystem(root, repo, host, boundary) {
2532
2909
  const file = join3(dir, "profile.yaml");
2533
2910
  const rel = `${isAdopted(root) ? ".atticus/" : ""}org-pack/profiles/${platform}/profile.yaml`;
2534
2911
  const before = await readFile2(file, "utf8").catch(() => void 0);
2535
- const doc = (0, import_yaml6.parseDocument)(before ?? `schemaVersion: 1
2912
+ const doc = (0, import_yaml6.parseDocument)(before === void 0 ? `schemaVersion: 1
2536
2913
  platform: ${platform}
2537
2914
  name: ${platform}
2538
- `);
2915
+ ` : lfOnly(before));
2539
2916
  let systems = doc.get("systems");
2540
2917
  if (!(0, import_yaml6.isSeq)(systems)) {
2541
2918
  doc.set("systems", doc.createNode([]));
@@ -2545,7 +2922,7 @@ name: ${platform}
2545
2922
  const checked = Profile.safeParse(doc.toJS());
2546
2923
  if (!checked.success)
2547
2924
  throw new Error(`${rel} would not be valid: ${checked.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`);
2548
- await writeFileIfUnchanged(file, before, inEol(doc.toString(), eolOf(before ?? "")));
2925
+ await writeFileIfUnchanged(file, before, inEol(profileText(doc, before), eolOf(before ?? "")));
2549
2926
  return { id: sys.id, profile: rel, added: true };
2550
2927
  }
2551
2928
  throw new Error(`${repo} isn't in any repos.manifest.yaml`);
@@ -2580,7 +2957,7 @@ async function addProfileSystem(root, repo, s, o = {}) {
2580
2957
  else
2581
2958
  node.set("topics", doc.createNode([...had.topics ?? [], ...missing]));
2582
2959
  valid(doc, platform);
2583
- await writeFileIfUnchanged(file, text4, inEol(doc.toString(), eolOf(text4)));
2960
+ await writeFileIfUnchanged(file, text4, inEol(profileText(doc, text4), eolOf(text4)));
2584
2961
  }
2585
2962
  }
2586
2963
  return {
@@ -2621,12 +2998,13 @@ name: ${platform}
2621
2998
  ...topics.length ? { topics: [...topics] } : {}
2622
2999
  }));
2623
3000
  valid(doc, platform);
2624
- const after = doc.toString({ lineWidth: 0, flowCollectionPadding: true });
3001
+ const after = profileText(doc, before);
2625
3002
  const changes = changedLines(before ?? "", after);
3003
+ const write2 = { file, before: raw, after: inEol(after, eol) };
2626
3004
  if (o.preview)
2627
- return { id: s.id, profile: relOf(platform), added: true, changes };
2628
- await writeFileIfUnchanged(file, raw, inEol(after, eol));
2629
- return { id: s.id, profile: relOf(platform), added: true, changes };
3005
+ return { id: s.id, profile: relOf(platform), added: true, changes, write: write2 };
3006
+ await writeFileIfUnchanged(file, raw, write2.after);
3007
+ return { id: s.id, profile: relOf(platform), added: true, changes, write: write2 };
2630
3008
  }
2631
3009
  throw new Error(`${repo} isn't in any repos.manifest.yaml`);
2632
3010
  }
@@ -2650,17 +3028,33 @@ async function editProfileSystem(root, id, o = {}) {
2650
3028
  node.set("id", o.rename.id);
2651
3029
  node.set("name", o.rename.name);
2652
3030
  }
2653
- } else
2654
- seq.items.splice(at3, 1);
3031
+ } else {
3032
+ const [gone] = seq.items.splice(at3, 1);
3033
+ const lead = gone?.commentBefore;
3034
+ if (lead) {
3035
+ const next = seq.items[at3];
3036
+ if (next)
3037
+ next.commentBefore = next.commentBefore ? `${lead}
3038
+ ${next.commentBefore}` : lead;
3039
+ else
3040
+ seq.comment = seq.comment ? `${lead}
3041
+ ${seq.comment}` : lead;
3042
+ }
3043
+ }
3044
+ const left = aliasesLeftOf(doc);
3045
+ if (left.length)
3046
+ throw new ProfileEditError(`${id} holds the YAML anchor ${left.map((a) => `&${a}`).join(", ")} in ${rel}, which other lines use (${left.map((a) => `*${a}`).join(", ")}): Atticus doesn't ${o.rename ? "rename" : "take out"} it, as they would name nothing. Write the value in place of ${left.map((a) => `*${a}`).join(", ")} by hand (or move the anchor to another line), then do this again.`);
2655
3047
  const checked = Profile.safeParse(doc.toJS());
2656
3048
  if (!checked.success)
2657
3049
  throw new Error(`${rel} would not be valid: ${checked.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`);
2658
- const after = doc.toString({ lineWidth: 0, flowCollectionPadding: true });
3050
+ const after = profileText(doc, raw);
2659
3051
  const changes = changedLines(lfOnly(raw), after);
3052
+ const text4 = inEol(after, eolOf(raw));
3053
+ const out = { profile: rel, changes, file, before: raw, after: text4 };
2660
3054
  if (o.preview)
2661
- return { profile: rel, changes, written: false };
2662
- await writeFileIfUnchanged(file, raw, inEol(after, eolOf(raw)));
2663
- return { profile: rel, changes, written: true };
3055
+ return { ...out, written: false };
3056
+ await writeFileIfUnchanged(file, raw, text4);
3057
+ return { ...out, written: true };
2664
3058
  }
2665
3059
  return void 0;
2666
3060
  }
@@ -2903,22 +3297,39 @@ function urlPathOf(s) {
2903
3297
  const m = s ? /^[a-z][a-z0-9+.-]*:\/\/[^/?#]+(\/[^?#]*)/i.exec(s.trim()) : null;
2904
3298
  return m && m[1] !== "/" ? m[1] : void 0;
2905
3299
  }
3300
+ function pathAroundPlaceholder(s) {
3301
+ const t = (s ?? "").trim();
3302
+ const p2 = urlPathOf(t) ?? (() => {
3303
+ const ph = placeholderIn(t);
3304
+ if (!ph || ph.before.trim())
3305
+ return void 0;
3306
+ const after = ph.after.split(/[?#]/, 1)[0] ?? "";
3307
+ return after.startsWith("/") && after !== "/" ? after : void 0;
3308
+ })();
3309
+ return p2 && !placeholderIn(p2) ? p2 : void 0;
3310
+ }
2906
3311
  var PUBLIC_TLDS = /* @__PURE__ */ new Set([
2907
3312
  "com",
2908
3313
  "net",
2909
3314
  "org",
2910
3315
  "io",
2911
- "dev",
2912
- "app",
2913
- "cloud",
2914
3316
  "ai",
3317
+ "co",
3318
+ "cloud",
2915
3319
  "biz",
2916
3320
  "info",
2917
- "co",
2918
3321
  "tech",
3322
+ "xyz",
3323
+ "gov",
3324
+ "edu",
3325
+ "mil",
3326
+ "example"
3327
+ ]);
3328
+ var PUBLIC_TLDS_3 = /* @__PURE__ */ new Set([
3329
+ "dev",
3330
+ "app",
2919
3331
  "online",
2920
3332
  "site",
2921
- "xyz",
2922
3333
  "pro",
2923
3334
  "services",
2924
3335
  "solutions",
@@ -2932,13 +3343,7 @@ var PUBLIC_TLDS = /* @__PURE__ */ new Set([
2932
3343
  "group",
2933
3344
  "company",
2934
3345
  "network",
2935
- "software",
2936
- "api",
2937
- "gov",
2938
- "edu",
2939
- "mil",
2940
- "int",
2941
- "example"
3346
+ "software"
2942
3347
  ]);
2943
3348
  var TWO_PART_SUFFIXES = /* @__PURE__ */ new Set([
2944
3349
  "co.uk",
@@ -2995,11 +3400,13 @@ function registrableDomain(host) {
2995
3400
  if (ls.length < 2 || ls.some((l) => !l))
2996
3401
  return void 0;
2997
3402
  const tld = ls.at(-1);
2998
- if (!PUBLIC_TLDS.has(tld) && !/^[a-z]{2}$/.test(tld))
2999
- return void 0;
3000
3403
  if (TWO_PART_SUFFIXES.has(ls.slice(-2).join(".")))
3001
3404
  return ls.length >= 3 ? ls.slice(-3).join(".") : void 0;
3002
- return ls.slice(-2).join(".");
3405
+ if (PUBLIC_TLDS.has(tld))
3406
+ return ls.slice(-2).join(".");
3407
+ if ((PUBLIC_TLDS_3.has(tld) || /^[a-z]{2}$/.test(tld)) && ls.length >= 3)
3408
+ return ls.slice(-2).join(".");
3409
+ return void 0;
3003
3410
  }
3004
3411
  var joinPaths = (base, path) => base ? `${base.replace(/\/+$/, "")}/${(path ?? "").replace(/^\/+/, "")}` : path;
3005
3412
  function hostIn(s) {
@@ -3026,46 +3433,48 @@ var TOKEN_FORMS = [
3026
3433
  /@([A-Za-z_][A-Za-z0-9_.-]*)@/,
3027
3434
  /\{\{\s*([A-Za-z_][A-Za-z0-9_.-]*)\s*\}\}/
3028
3435
  ];
3436
+ var CAMEL_SIMPLE = /^(headers?|body|in\.(headers?|body)|out\.(headers?|body)|exchangeProperty|exchangeId|camelContext|routeId|messageTimestamp)(\.|$|\[)/;
3029
3437
  function placeholderIn(s) {
3030
3438
  const t = (s ?? "").trim();
3031
3439
  const env = /^env:([A-Za-z_][A-Za-z0-9_.-]*)$/i.exec(t);
3032
3440
  if (env)
3033
3441
  return { name: env[1], before: "", after: "" };
3034
- const i = t.indexOf("${");
3035
- if (i < 0) {
3036
- const found = TOKEN_FORMS.flatMap((re) => {
3037
- const m = re.exec(t);
3038
- return m ? [m] : [];
3039
- }).sort((a, b) => a.index - b.index)[0];
3040
- if (!found)
3041
- return void 0;
3042
- return {
3043
- name: found[1],
3044
- before: t.slice(0, found.index),
3045
- after: t.slice(found.index + found[0].length)
3046
- };
3047
- }
3048
- let depth = 0;
3049
- let j = i + 2;
3050
- for (; j < t.length; j++) {
3051
- if (t[j] === "{")
3052
- depth++;
3053
- else if (t[j] === "}") {
3054
- if (depth === 0)
3055
- break;
3056
- depth--;
3442
+ let dollar;
3443
+ for (let i = t.indexOf("${"); i >= 0 && !dollar; i = t.indexOf("${", i + 2)) {
3444
+ let depth = 0;
3445
+ let j = i + 2;
3446
+ for (; j < t.length; j++) {
3447
+ if (t[j] === "{")
3448
+ depth++;
3449
+ else if (t[j] === "}") {
3450
+ if (depth === 0)
3451
+ break;
3452
+ depth--;
3453
+ }
3057
3454
  }
3058
- }
3059
- if (j >= t.length)
3060
- return void 0;
3061
- const inner = t.slice(i + 2, j);
3062
- const after = t.slice(j + 1);
3063
- const colon = inner.indexOf(":");
3064
- const name = (colon < 0 ? inner : inner.slice(0, colon)).trim();
3065
- if (!/^[A-Za-z_][A-Za-z0-9_.[\]-]*$/.test(name))
3455
+ if (j >= t.length)
3456
+ break;
3457
+ const inner = t.slice(i + 2, j);
3458
+ const colon = inner.indexOf(":");
3459
+ const name = (colon < 0 ? inner : inner.slice(0, colon)).trim();
3460
+ if (!/^[A-Za-z_][A-Za-z0-9_.[\]-]*$/.test(name) || CAMEL_SIMPLE.test(name))
3461
+ continue;
3462
+ const fallback = colon < 0 ? void 0 : inner.slice(colon + 1).trim();
3463
+ dollar = { at: i, end: j + 1, name, ...fallback ? { fallback } : {} };
3464
+ }
3465
+ const token = TOKEN_FORMS.flatMap((re) => {
3466
+ const m = re.exec(t);
3467
+ return m ? [{ at: m.index, end: m.index + m[0].length, name: m[1] }] : [];
3468
+ }).sort((a, b) => a.at - b.at)[0];
3469
+ const first = [dollar, token].filter((x) => !!x).sort((a, b) => a.at - b.at)[0];
3470
+ if (!first)
3066
3471
  return void 0;
3067
- const fallback = colon < 0 ? void 0 : inner.slice(colon + 1).trim();
3068
- return { name, ...fallback ? { fallback } : {}, before: t.slice(0, i), after };
3472
+ return {
3473
+ name: first.name,
3474
+ ...first.fallback ? { fallback: first.fallback } : {},
3475
+ before: t.slice(0, first.at),
3476
+ after: t.slice(first.end)
3477
+ };
3069
3478
  }
3070
3479
  var settingNameKey = (name) => name.toUpperCase().replace(/[^A-Z0-9]/g, "");
3071
3480
  function keyRefIn(s) {
@@ -3450,6 +3859,12 @@ function joinFacts(input) {
3450
3859
  };
3451
3860
  };
3452
3861
  const outside = new Set((input.outside ?? []).map(factIdPart));
3862
+ const outsideByHost = (h) => {
3863
+ if (outside.has(factIdPart(h)))
3864
+ return h;
3865
+ const bare = h.replace(/:\d+$/, "");
3866
+ return bare !== h && outside.has(factIdPart(bare)) ? bare : void 0;
3867
+ };
3453
3868
  const joins = [];
3454
3869
  const asks = [];
3455
3870
  const misses = [];
@@ -3737,8 +4152,28 @@ function joinFacts(input) {
3737
4152
  ...b.by.length ? { by: uniqueEnds(b.by) } : {}
3738
4153
  });
3739
4154
  const replacedFor = (call) => {
3740
- const cited = [call.fact.cite, ...call.fact.cite.with ?? []].map((p2) => (p2.file.split("/").pop() ?? p2.file).toLowerCase());
3741
- const names = new Set(cited.flatMap((b) => [b, b.replace(/\.[^.]*$/, "")]));
4155
+ const parts = [call.fact.cite, ...call.fact.cite.with ?? []];
4156
+ const urlText = (call.fact.host ?? call.fact.base ?? "").trim();
4157
+ const writing = urlText ? parts.filter((p2) => p2.value.trim() === urlText) : [];
4158
+ const cited = (writing.length ? writing : parts).map((p2) => p2.file);
4159
+ const rootFits = (file, xpath) => {
4160
+ const root = /^\/([A-Za-z]+)/.exec(xpath.trim())?.[1]?.toLowerCase();
4161
+ const folder2 = file.split("/").at(-2)?.toLowerCase();
4162
+ if (folder2 === "targets")
4163
+ return root === "targetendpoint";
4164
+ if (folder2 === "proxies")
4165
+ return root === "proxyendpoint";
4166
+ if (folder2 === "policies")
4167
+ return root !== "targetendpoint" && root !== "proxyendpoint";
4168
+ return true;
4169
+ };
4170
+ const forCited = (target, xpath) => {
4171
+ const t = target.trim().toLowerCase();
4172
+ return cited.some((file) => {
4173
+ const b = (file.split("/").pop() ?? file).toLowerCase();
4174
+ return (b === t || b.replace(/\.[^.]*$/, "") === t) && rootFits(file, xpath);
4175
+ });
4176
+ };
3742
4177
  const home = bundleHomeOf(call.fact.cite.file);
3743
4178
  const homes = home === void 0 ? void 0 : bundleHomesOf(call.repo);
3744
4179
  const ownedBy = (file) => homes.filter((h) => file.startsWith(h)).sort((a, b) => b.length - a.length)[0] ?? (homes.length === 1 ? homes[0] : void 0);
@@ -3747,7 +4182,7 @@ function joinFacts(input) {
3747
4182
  const p2 = v && /^\s*(@[^@\s]+@|\{\{[^}]+\}\})\s*$/.test(v) ? placeholderIn(v) : void 0;
3748
4183
  return p2 ? [p2.name] : [];
3749
4184
  });
3750
- return (configsByRepo.get(call.repo) ?? []).filter((n) => !!n.fact.target && names.has(n.fact.target.trim().toLowerCase()) && n.fact.key.trim().startsWith("/") && /^[a-z][a-z0-9+.-]*:\/\//i.test((n.fact.value ?? "").trim()) && !!hostIn(n.fact.value) && (home === void 0 || ownedBy(n.fact.cite.file) === home) && (() => {
4185
+ return (configsByRepo.get(call.repo) ?? []).filter((n) => !!n.fact.target && forCited(n.fact.target, n.fact.key) && n.fact.key.trim().startsWith("/") && /^[a-z][a-z0-9+.-]*:\/\//i.test((n.fact.value ?? "").trim()) && !!hostIn(n.fact.value) && (home === void 0 || ownedBy(n.fact.cite.file) === home) && (() => {
3751
4186
  const said = tokenNames(n);
3752
4187
  return !said.length || !!wanted && said.includes(wanted);
3753
4188
  })()).sort((x, y) => cmp(x.fact.id, y.fact.id)).map((n) => ({ value: n.fact.value.trim(), through: [n], guesses: [] }));
@@ -3768,8 +4203,86 @@ function joinFacts(input) {
3768
4203
  return !!d && !known2.has(d);
3769
4204
  }))
3770
4205
  return false;
3771
- const whole = configs.length ? configs.map((x) => joinPaths(urlPathOf(x.value), call.fact.path)) : [fullPath ?? call.fact.path];
3772
- return ![...new Set(whole)].some((p2) => !!p2 && serving({ ...call, fact: { ...call.fact, path: p2 } }, () => true, true).length);
4206
+ if (!configs.length) {
4207
+ const p2 = fullPath ?? call.fact.path;
4208
+ return !(p2 && servedSomewhere(call, p2));
4209
+ }
4210
+ const urls = [...new Set(configs.map((x) => x.value))].sort(cmp);
4211
+ if (urls.some((u) => {
4212
+ const p2 = urlPathOf(u);
4213
+ return !!p2 && isOwnBase(call.component, p2);
4214
+ }))
4215
+ return false;
4216
+ const k = `${call.repo}\0${bundleRootOf(call.fact.cite.file) ?? ""}\0${call.fact.host ?? ""}\0${call.fact.base ?? ""}\0${urls.join("\0")}`;
4217
+ let served = targetServed.get(k);
4218
+ if (served === void 0) {
4219
+ const root = bundleRootOf(call.fact.cite.file);
4220
+ served = nodes.some((n) => n.fact.kind === "call" && n.repo === call.repo && n.fact.callType === "rest" && (n.fact.host ?? "") === (call.fact.host ?? "") && (n.fact.base ?? "") === (call.fact.base ?? "") && bundleRootOf(n.fact.cite.file) === root && urls.some((u) => {
4221
+ const p2 = joinPaths(urlPathOf(u), n.fact.path);
4222
+ return !!p2 && servedSomewhere(n, p2);
4223
+ }));
4224
+ targetServed.set(k, served);
4225
+ }
4226
+ return !served;
4227
+ };
4228
+ const targetServed = /* @__PURE__ */ new Map();
4229
+ const genericBase = (segs2) => segs2.every((s) => /^(v\d+(\.\d+)*|api|rest|services)$/i.test(s));
4230
+ const ownBaseSeen = /* @__PURE__ */ new Map();
4231
+ let baseOwners;
4232
+ const ownersOfBases = () => {
4233
+ if (baseOwners)
4234
+ return baseOwners;
4235
+ const seen = /* @__PURE__ */ new Set();
4236
+ baseOwners = [];
4237
+ for (const n of [...entries, ...nodes]) {
4238
+ const k = key3(n.repo, n.component);
4239
+ if (seen.has(k))
4240
+ continue;
4241
+ seen.add(k);
4242
+ baseOwners.push(n);
4243
+ }
4244
+ return baseOwners;
4245
+ };
4246
+ const isOwnBase = (component, p2) => {
4247
+ const segs2 = rawSegs(p2);
4248
+ if (genericBase(segs2))
4249
+ return false;
4250
+ const k = `${component}\0${segs2.join("/").toLowerCase()}`;
4251
+ const was = ownBaseSeen.get(k);
4252
+ if (was !== void 0)
4253
+ return was;
4254
+ const done = /* @__PURE__ */ new Set();
4255
+ let got = false;
4256
+ for (const e of ownersOfBases()) {
4257
+ if (e.component === component)
4258
+ continue;
4259
+ const ek = key3(e.repo, e.component);
4260
+ if (done.has(ek))
4261
+ continue;
4262
+ done.add(ek);
4263
+ if (basesOf(e).some((b) => b.segs.length === segs2.length && startsWithSegs(segs2, b.segs))) {
4264
+ got = true;
4265
+ break;
4266
+ }
4267
+ }
4268
+ ownBaseSeen.set(k, got);
4269
+ return got;
4270
+ };
4271
+ const servedSomewhere = (call, p2) => {
4272
+ if (serving({ ...call, fact: { ...call.fact, path: p2 } }, () => true, true).length)
4273
+ return true;
4274
+ if (call.fact.callType !== "rest")
4275
+ return false;
4276
+ const segs2 = rawSegs(p2);
4277
+ return routeCandidates(p2).some((e) => {
4278
+ if (e.component === call.component || !SERVES.rest.includes(e.fact.entryType) || !sameMethod(call.fact.method, e.fact.method))
4279
+ return false;
4280
+ const gatewayRoute = gatewayRepos.has(e.repo) || !!bundleRootOf(e.fact.cite.file);
4281
+ if (gatewayRoute && isPassThrough(e.fact))
4282
+ return false;
4283
+ const least = gatewayRoute ? 400 : 100;
4284
+ return basesOf(e).some((b) => b.segs.length > 0 && b.segs.length < segs2.length && startsWithSegs(segs2, b.segs) && routeScore(toPath(segs2.slice(b.segs.length)), e.fact.path) >= least);
4285
+ });
3773
4286
  };
3774
4287
  const gatewayRepos = new Set(repos.filter((r) => r.gateway).map((r) => r.repo));
3775
4288
  const isForwarding = (c) => c.fact.callType === "rest" && (!!bundleRootOf(c.fact.cite.file) || gatewayRepos.has(c.repo));
@@ -3810,7 +4323,8 @@ function joinFacts(input) {
3810
4323
  const { byFirst, all } = baseRoutesOf();
3811
4324
  const first = segKey(segs2[0]);
3812
4325
  const pool = first === "{}" ? all : [...byFirst.get(first) ?? [], ...byFirst.get("{}") ?? []];
3813
- const under2 = pool.filter((x) => x.r.component !== c.component && x.base.length < segs2.length && startsWithSegs(segs2, x.base));
4326
+ const ownBundle = bundleRootOf(c.fact.cite.file);
4327
+ const under2 = pool.filter((x) => (x.r.component !== c.component || !!ownBundle && proxyOf(x.r) !== key3(c.repo, ownBundle)) && x.base.length < segs2.length && startsWithSegs(segs2, x.base));
3814
4328
  if (!under2.length)
3815
4329
  return void 0;
3816
4330
  const longest2 = Math.max(...under2.map((x) => x.base.length));
@@ -3897,7 +4411,15 @@ function joinFacts(input) {
3897
4411
  ...throughEnds.length ? { through: throughEnds } : {}
3898
4412
  };
3899
4413
  const host = hostIn(f.host) ?? (used[0] ? hostIn(used[0].value) : void 0) ?? (keyed.length ? void 0 : hostIn(f.base));
3900
- const fullPath = joinPaths(urlPathOf(f.host) ?? (used[0] ? urlPathOf(used[0].value) : void 0) ?? (keyed.length ? void 0 : urlPathOf(f.base)), f.path);
4414
+ const unresolvedBase = () => {
4415
+ if (host)
4416
+ return void 0;
4417
+ if (!keyed.length)
4418
+ return pathAroundPlaceholder(f.host) ?? pathAroundPlaceholder(f.base);
4419
+ const ps = new Set(keyed.map((t) => pathAroundPlaceholder(t.fact.value ?? t.fact.source)));
4420
+ return ps.size === 1 ? [...ps][0] : void 0;
4421
+ };
4422
+ const fullPath = joinPaths(urlPathOf(f.host) ?? (used[0] ? urlPathOf(used[0].value) : void 0) ?? (keyed.length ? void 0 : urlPathOf(f.base)) ?? unresolvedBase(), f.path);
3901
4423
  const answer = input.targets?.[call.repo]?.[f.id];
3902
4424
  const aiAnswer = answer ? input.aiTargets?.[call.repo]?.[f.id] : void 0;
3903
4425
  const onFile = input.pairs?.[call.repo]?.[f.id];
@@ -4002,10 +4524,10 @@ function joinFacts(input) {
4002
4524
  exposedBy = d.by;
4003
4525
  disputed = d.disputed;
4004
4526
  byServiceName = d.byServiceName;
4005
- } else if (host && outside.has(factIdPart(host.named ? `${host.host}:${host.named}` : host.host))) {
4527
+ } else if (host && outsideByHost(host.named ? `${host.host}:${host.named}` : host.host)) {
4006
4528
  outsideCalls.push({
4007
4529
  call: end(call),
4008
- target: host.named ? `${host.host}:${host.named}` : host.host
4530
+ target: outsideByHost(host.named ? `${host.host}:${host.named}` : host.host)
4009
4531
  });
4010
4532
  continue;
4011
4533
  } else if (host && components.has(factIdPart(host.host.split(".")[0]))) {
@@ -4016,11 +4538,11 @@ function joinFacts(input) {
4016
4538
  } else if (f.to && (host || outside.has(factIdPart(f.to)))) {
4017
4539
  outsideCalls.push({ call: end(call), target: f.to });
4018
4540
  continue;
4019
- } else if (host && isForwarding(call) && (forwardHosts(configs, host).some((h) => outside.has(factIdPart(h))) || outsideOfEstate(call, configs, host, fullPath))) {
4541
+ } else if (host && isForwarding(call) && (forwardHosts(configs, host).some((h) => !!outsideByHost(h)) || outsideOfEstate(call, configs, host, fullPath))) {
4020
4542
  const hosts = forwardHosts(configs, host);
4021
4543
  outsideCalls.push({
4022
4544
  call: end(call),
4023
- target: hosts.find((h) => outside.has(factIdPart(h))) ?? hosts[0]
4545
+ target: hosts.map(outsideByHost).find((h) => !!h) ?? hosts[0]
4024
4546
  });
4025
4547
  continue;
4026
4548
  } else if (host) {
@@ -4069,6 +4591,11 @@ function joinFacts(input) {
4069
4591
  entry: end(e),
4070
4592
  ...tie,
4071
4593
  how: "base-path",
4594
+ // Beta.25 review: never verified on a guess. A gateway's forwarding call that names no
4595
+ // host goes to its own gateway (a proxy chained to another), so the BasePath is all it
4596
+ // takes; a call whose host nothing resolves may go to any host that serves the path,
4597
+ // so the join is kept as a guess (by its path), shown so and correctable.
4598
+ ...namesHost ? { inferred: { within: "estate" } } : {},
4072
4599
  callType: f.callType,
4073
4600
  ...f.method || e.fact.method ? { method: (f.method ?? e.fact.method).toUpperCase() } : {},
4074
4601
  path: e.fact.path,
@@ -4336,7 +4863,7 @@ function joinFacts(input) {
4336
4863
  writesUnder.set(k, [n]);
4337
4864
  }
4338
4865
  }
4339
- const fieldsOf2 = (repo, owner) => fieldsByOwner.get(key3(repo, owner)) ?? [];
4866
+ const fieldsOf3 = (repo, owner) => fieldsByOwner.get(key3(repo, owner)) ?? [];
4340
4867
  const sideOf = (f) => f.side ?? "request";
4341
4868
  const fieldEnd = (n) => ({
4342
4869
  repo: n.repo,
@@ -4354,7 +4881,7 @@ function joinFacts(input) {
4354
4881
  const want = fieldNameKey(field.name);
4355
4882
  for (const n of writesUnder.get(key3(repo, entry)) ?? []) {
4356
4883
  const s = n.fact;
4357
- const col = fieldsOf2(repo, s.id).find((x) => fieldNameKey(x.fact.name) === want);
4884
+ const col = fieldsOf3(repo, s.id).find((x) => fieldNameKey(x.fact.name) === want);
4358
4885
  if (col)
4359
4886
  return { table: tableOf(s), name: col.fact.name, fact: col.fact.id, how: "name" };
4360
4887
  const named = (s.columns ?? []).find((x) => fieldNameKey(x) === want);
@@ -4367,8 +4894,8 @@ function joinFacts(input) {
4367
4894
  const gaps = [];
4368
4895
  for (const j of joins) {
4369
4896
  const callNode = byKey.get(key3(j.call.repo, j.call.fact));
4370
- const sent = fieldsOf2(j.call.repo, j.call.fact);
4371
- const took = fieldsOf2(j.entry.repo, j.entry.fact);
4897
+ const sent = fieldsOf3(j.call.repo, j.call.fact);
4898
+ const took = fieldsOf3(j.entry.repo, j.entry.fact);
4372
4899
  const event = j.how === "topic";
4373
4900
  const what2 = event ? callNode.fact.path : [callNode.fact.method?.toUpperCase(), callNode.fact.path].filter(Boolean).join(" ");
4374
4901
  const outward = event ? ["message"] : ["request"];
@@ -4477,7 +5004,7 @@ function joinFlagsOf(j) {
4477
5004
  const overlap = isOverlapJoin(j) ? [JOINED_BY_PATH_OVERLAP] : [];
4478
5005
  const guessed = joinGuessesOf(j);
4479
5006
  if (guessed.length)
4480
- return [...guessed, ...overlap];
5007
+ return j.how === "base-path" ? [JOINED_BY_BASE_PATH, ...guessed, ...overlap] : [...guessed, ...overlap];
4481
5008
  const HOW = {
4482
5009
  answer: JOINED_BY_ANSWER,
4483
5010
  named: JOINED_BY_NAME,
@@ -4488,20 +5015,29 @@ function joinFlagsOf(j) {
4488
5015
  return [...overlap, ...HOW[j.how] ? [HOW[j.how]] : []];
4489
5016
  }
4490
5017
  var HOW_FLAG_ORDER = [
4491
- JOINED_BY_PERSON,
4492
- JOINED_BY_AI,
4493
5018
  JOINED_BY_ANSWER,
4494
5019
  JOINED_BY_NAME,
4495
5020
  JOINED_BY_REPO,
4496
5021
  JOINED_BY_HOST,
4497
- JOINED_BY_BASE_PATH
5022
+ JOINED_BY_BASE_PATH,
5023
+ JOINED_BY_PERSON,
5024
+ JOINED_BY_AI
4498
5025
  ];
4499
5026
  function sharedLinkFlags(flags, confidence) {
4500
5027
  const all = new Set(flags);
4501
5028
  const guesses = GUESS_ORDER.filter((f) => all.has(f));
4502
5029
  const hows = HOW_FLAG_ORDER.filter((f) => all.has(f));
4503
5030
  const rest = [...all].filter((f) => !guesses.includes(f) && !hows.includes(f)).sort(cmp);
4504
- return confidence === "verified" ? [...hows, ...guesses, ...rest] : [...guesses, ...hows, ...rest];
5031
+ if (confidence === "verified")
5032
+ return [...hows, ...guesses, ...rest];
5033
+ if (all.has(JOINED_BY_BASE_PATH) && guesses.length === 1 && guesses[0] === JOINED_BY_PATH)
5034
+ return [
5035
+ JOINED_BY_BASE_PATH,
5036
+ ...guesses,
5037
+ ...hows.filter((f) => f !== JOINED_BY_BASE_PATH),
5038
+ ...rest
5039
+ ];
5040
+ return [...guesses, ...hows, ...rest];
4505
5041
  }
4506
5042
  function joinRecords(result, repos) {
4507
5043
  const facts = /* @__PURE__ */ new Map();
@@ -5005,7 +5541,7 @@ function enumValues(type) {
5005
5541
  }
5006
5542
  var HEADER_NAME = /^(x-[a-z0-9-]+|authorization|accept(-[a-z]+)*|content-[a-z]+|if-[a-z-]+|etag|location|cookie|set-cookie|user-agent|cache-control|retry-after|traceparent|tracestate|link)$/i;
5007
5543
  var isHeaderName = (name) => HEADER_NAME.test(name) || /^[A-Z][A-Za-z0-9]*(-[A-Z][A-Za-z0-9]*)+$/.test(name);
5008
- var fieldsOf = (facts, owner) => facts.filter((f) => f.kind === "field" && f.owner === owner && (f.side === "request" || f.side === "response")).map((f) => {
5544
+ var fieldsOf2 = (facts, owner) => facts.filter((f) => f.kind === "field" && f.owner === owner && (f.side === "request" || f.side === "response")).map((f) => {
5009
5545
  const values = enumValues(f.type);
5010
5546
  return {
5011
5547
  side: f.side,
@@ -5018,8 +5554,8 @@ var fieldsOf = (facts, owner) => facts.filter((f) => f.kind === "field" && f.own
5018
5554
  };
5019
5555
  }).sort((a, b) => cmp3(a.side, b.side) || cmp3(a.name, b.name) || cmp3(a.at, b.at));
5020
5556
  var needsOf = (facts, call, lands) => {
5021
- const own = fieldsOf(facts, lands);
5022
- return [...own, ...fieldsOf(facts, call).filter((f) => !own.some((g) => g.side === f.side))];
5557
+ const own = fieldsOf2(facts, lands);
5558
+ return [...own, ...fieldsOf2(facts, call).filter((f) => !own.some((g) => g.side === f.side))];
5023
5559
  };
5024
5560
  var lower = (v) => v.toLowerCase();
5025
5561
  function enumDifferences(f, t, repo) {
@@ -5301,7 +5837,7 @@ function comparePrototype(input) {
5301
5837
  const repo = j.entry.repo;
5302
5838
  const theirScopes = sorted([...j.scopes ?? [], ...(e.scopes ?? []).map((x) => x.value)]);
5303
5839
  const repoFacts = estate.find((r) => r.repo === repo)?.facts ?? [];
5304
- const differences = fieldDifferences(mine, fieldsOf(repoFacts, e.id), repo);
5840
+ const differences = fieldDifferences(mine, fieldsOf2(repoFacts, e.id), repo);
5305
5841
  differences.push(...errorDifferences(myErrors, errorsOf(repoFacts, e.id), repo));
5306
5842
  if (theirScopes.length)
5307
5843
  for (const sc of s.lands.scopes ?? []) {
@@ -6026,9 +6562,23 @@ function endOf(repo, component, f) {
6026
6562
  }
6027
6563
  return { repo, fact: f.id, component, at: at3, lines };
6028
6564
  }
6565
+ var dirOf = (file) => {
6566
+ const f = file.replace(/\\/g, "/");
6567
+ return f.includes("/") ? f.slice(0, f.lastIndexOf("/")) : "";
6568
+ };
6569
+ var normDir = (p2) => p2.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+$/, "");
6570
+ function buildComponentOf(r, f) {
6571
+ if (f.component)
6572
+ return f.component;
6573
+ const catalog = /(^|\/)gradle\/[\w-]+\.versions\.toml$/i.test(f.cite.file.replace(/\\/g, "/"));
6574
+ const build = catalog ? (f.cite.with ?? []).find((p2) => /(^|[/\\])build\.gradle(\.kts)?$/i.test(p2.file))?.file : f.cite.file;
6575
+ const dir = dirOf(build ?? f.cite.file);
6576
+ const mod = [...r.moduleDirs ?? []].map((m) => ({ ...m, path: normDir(m.path) })).filter((m) => m.path && (dir === m.path || dir.startsWith(`${m.path}/`))).sort((a, b) => b.path.length - a.path.length)[0];
6577
+ return mod?.component ?? r.component ?? r.repo;
6578
+ }
6029
6579
  function joinDependencies(input) {
6030
6580
  const repos = [...input.repos].sort((x, y) => cmp6(x.repo, y.repo));
6031
- const componentOf = (r, f) => factIdPart(f.component ?? r.component ?? r.repo);
6581
+ const componentOf = (r, f) => factIdPart(buildComponentOf(r, f));
6032
6582
  const byId = (x, y) => cmp6(x.id, y.id);
6033
6583
  const published = /* @__PURE__ */ new Map();
6034
6584
  for (const r of repos)
@@ -6059,7 +6609,7 @@ function joinDependencies(input) {
6059
6609
  });
6060
6610
  }
6061
6611
  const links = [];
6062
- const seen = /* @__PURE__ */ new Set();
6612
+ const seen = /* @__PURE__ */ new Map();
6063
6613
  let outside = 0;
6064
6614
  let test = 0;
6065
6615
  for (const r of repos)
@@ -6083,19 +6633,36 @@ function joinDependencies(input) {
6083
6633
  const lib = to[0];
6084
6634
  if (from.repo === lib.repo && from.component === lib.component)
6085
6635
  continue;
6086
- const key3 = `${from.repo}\0${from.component}\0${lib.repo}\0${lib.component}\0${coordinates(f)}`;
6087
- if (seen.has(key3))
6088
- continue;
6089
- seen.add(key3);
6090
6636
  const pub = facts.get(`${lib.repo}\0${lib.fact}`);
6091
- links.push({
6637
+ const fact = {
6638
+ ...from,
6639
+ group: pub.group,
6640
+ name: pub.name,
6641
+ ...f.version ? { version: f.version } : {},
6642
+ ...f.scope && f.scope !== "compile" ? { scope: f.scope } : {}
6643
+ };
6644
+ const key3 = `${from.repo}\0${from.component}\0${lib.repo}\0${lib.component}`;
6645
+ const twin = seen.get(key3);
6646
+ if (twin) {
6647
+ twin.facts.push(fact);
6648
+ if (twin.scope !== fact.scope)
6649
+ delete twin.scope;
6650
+ if (!twin.published.some((p2) => p2.repo === lib.repo && p2.fact === lib.fact))
6651
+ twin.published.push(lib);
6652
+ continue;
6653
+ }
6654
+ const link = {
6092
6655
  from,
6656
+ facts: [fact],
6093
6657
  to: lib,
6658
+ published: [lib],
6094
6659
  group: pub.group,
6095
6660
  name: pub.name,
6096
6661
  ...f.scope && f.scope !== "compile" ? { scope: f.scope } : {},
6097
6662
  ...f.version ? { version: f.version } : {}
6098
- });
6663
+ };
6664
+ seen.set(key3, link);
6665
+ links.push(link);
6099
6666
  }
6100
6667
  links.sort((a, b) => cmp6(a.from.component, b.from.component) || cmp6(a.to.component, b.to.component) || cmp6(a.from.repo, b.from.repo) || cmp6(a.from.fact, b.from.fact));
6101
6668
  return { links, ambiguous, outside, test };
@@ -8673,6 +9240,7 @@ __export(api_exports, {
8673
9240
  KnowledgeScanView: () => KnowledgeScanView,
8674
9241
  KnowledgeSource: () => KnowledgeSource,
8675
9242
  KnowledgeSourceList: () => KnowledgeSourceList,
9243
+ LINK_CORRECTIONS_MAX: () => LINK_CORRECTIONS_MAX,
8676
9244
  LINK_HOWS: () => LINK_HOWS,
8677
9245
  LayoutPosition: () => LayoutPosition,
8678
9246
  LineChangeView: () => LineChangeView,
@@ -8842,7 +9410,7 @@ __export(api_exports, {
8842
9410
  WorkItemSyncResult: () => WorkItemSyncResult,
8843
9411
  openApiDocument: () => openApiDocument
8844
9412
  });
8845
- var API_VERSION = "3.10.0";
9413
+ var API_VERSION = "3.11.0";
8846
9414
  var DEFAULT_PORT = 4321;
8847
9415
  var NextStep = external_exports.object({ step: external_exports.literal("sync"), repos: external_exports.array(external_exports.string()) });
8848
9416
  var Problem = external_exports.object({
@@ -8855,7 +9423,12 @@ var Problem = external_exports.object({
8855
9423
  /** For 403s on gated actions: who can act, e.g. "Needs an architect: R. Patel". */
8856
9424
  needs: external_exports.object({ role: external_exports.string(), names: external_exports.array(external_exports.string()) }).optional(),
8857
9425
  /** 3.9.0: what the app offers next, e.g. Sync the repos with no base clone here. */
8858
- next: NextStep.optional()
9426
+ next: NextStep.optional(),
9427
+ /**
9428
+ * 3.11.0 (beta.25): for a 500 that wrote only part of what was asked, the files left written
9429
+ * (each in the metarepo, or in `repo`'s working copy), so the app reads them again.
9430
+ */
9431
+ written: external_exports.array(external_exports.object({ repo: external_exports.string().optional(), file: external_exports.string() })).optional()
8859
9432
  });
8860
9433
  var Kind = external_exports.enum(RECORD_KINDS);
8861
9434
  var CatalogRecord2 = external_exports.union(RECORD_KINDS.map((k) => RECORD_SCHEMAS[k]));
@@ -9011,7 +9584,8 @@ var HierJoin = external_exports.object({
9011
9584
  run: external_exports.string().optional(),
9012
9585
  /**
9013
9586
  * 3.10.0 (ADR 0192): on a `depends-on` edge's join (`how: coordinates`), the coordinates the
9014
- * dependency names and the library publishes, and its scope when not compile. `interface` is
9587
+ * dependency names and the library publishes, and its scope when not compile (review of
9588
+ * beta.25: on a link of several facts, only when every one has it). `interface` is
9015
9589
  * then the link's own id (`depends-on:<repo>/<component>><repo>/<component>`, no Interface
9016
9590
  * record), `caller` the dependency's lines in the depending build file, `callee` the lines that
9017
9591
  * publish the coordinates. Left out on a call's join.
@@ -9020,7 +9594,24 @@ var HierJoin = external_exports.object({
9020
9594
  group: external_exports.string(),
9021
9595
  name: external_exports.string(),
9022
9596
  version: external_exports.string().optional(),
9023
- scope: external_exports.string().optional()
9597
+ scope: external_exports.string().optional(),
9598
+ /**
9599
+ * 3.11.0: every dependency fact the link rests on, the first (`caller`'s first line) first:
9600
+ * its repo, its id, its cited line (`file:line`) and every line it rests on, and the
9601
+ * coordinates it names (`group`, `name`, its `version` and `scope` when said): a link is
9602
+ * one per pair of components, so it holds every coordinate one builds on of the other's
9603
+ * (`group` and `name` above are the first's).
9604
+ */
9605
+ facts: external_exports.array(external_exports.object({
9606
+ repo: external_exports.string(),
9607
+ fact: external_exports.string(),
9608
+ at: external_exports.string(),
9609
+ lines: external_exports.array(external_exports.string()),
9610
+ group: external_exports.string().optional(),
9611
+ name: external_exports.string().optional(),
9612
+ version: external_exports.string().optional(),
9613
+ scope: external_exports.string().optional()
9614
+ })).optional()
9024
9615
  }).optional()
9025
9616
  });
9026
9617
  var HierEdge = external_exports.object({
@@ -9625,7 +10216,12 @@ var AnswerBoxRequest = external_exports.strictObject({
9625
10216
  id: external_exports.string().trim().min(1).max(200),
9626
10217
  /** For rename: the repo or system it is, or a new outside system's name. */
9627
10218
  name: external_exports.string().trim().min(1).max(200).optional(),
9628
- preview: external_exports.literal(true).optional()
10219
+ preview: external_exports.literal(true).optional(),
10220
+ /**
10221
+ * 3.11.0 (beta.25): the preview's `stamp`. A write with it is refused (409, nothing written)
10222
+ * when a file the fix writes changed since that preview.
10223
+ */
10224
+ stamp: external_exports.string().trim().min(1).max(100).optional()
9629
10225
  });
9630
10226
  var AnswerBoxResult = external_exports.object({
9631
10227
  id: external_exports.string(),
@@ -9638,7 +10234,12 @@ var AnswerBoxResult = external_exports.object({
9638
10234
  changes: external_exports.array(external_exports.object({ was: external_exports.string().optional(), now: external_exports.string().optional() }))
9639
10235
  }).optional(),
9640
10236
  /** The repos whose answers changed: Apply (verify --write) puts them on the map. */
9641
- repos: external_exports.array(external_exports.string())
10237
+ repos: external_exports.array(external_exports.string()),
10238
+ /**
10239
+ * 3.11.0 (beta.25): what the files the fix writes held when it was worked out, to send back
10240
+ * with the write (`stamp`), so the write is the one previewed.
10241
+ */
10242
+ stamp: external_exports.string().optional()
9642
10243
  });
9643
10244
  var FreshState = external_exports.enum([
9644
10245
  /** Facts cite files that changed, or source files changed: read again. */
@@ -9842,6 +10443,7 @@ var FactCorrectionResult = external_exports.object({
9842
10443
  /** 2.42.0 (ADR 0149): the line appended to the file, exactly as written. */
9843
10444
  line: external_exports.string().optional()
9844
10445
  });
10446
+ var LINK_CORRECTIONS_MAX = 5e3;
9845
10447
  var LinkCorrectionsRequest = external_exports.strictObject({
9846
10448
  items: external_exports.array(external_exports.strictObject({
9847
10449
  repo: external_exports.string().min(1),
@@ -9849,7 +10451,7 @@ var LinkCorrectionsRequest = external_exports.strictObject({
9849
10451
  action: external_exports.enum(["wrong", "edit"]),
9850
10452
  set: external_exports.record(external_exports.string().min(1), external_exports.string()).optional(),
9851
10453
  reason: external_exports.string().trim().min(1).max(500).optional()
9852
- })).min(1).max(200),
10454
+ })).min(1).max(LINK_CORRECTIONS_MAX),
9853
10455
  reason: external_exports.string().trim().min(1).max(500).optional()
9854
10456
  });
9855
10457
  var LinkCorrectionsResult = external_exports.object({
@@ -9865,8 +10467,9 @@ var LinkCorrectionsResult = external_exports.object({
9865
10467
  /** The commands that apply them, one per repo. */
9866
10468
  verify: external_exports.array(external_exports.string()),
9867
10469
  /**
9868
- * Review of beta.24: the items left out because the newest correction on file for that fact
9869
- * says the same already (asked again, nothing is written twice).
10470
+ * Review of beta.24: the items left out because the correction on file that the fact meets
10471
+ * now says the same already (asked again, nothing is written twice; 3.11.0: one for a line the
10472
+ * fact has left meets nothing).
9870
10473
  */
9871
10474
  skipped: external_exports.array(external_exports.object({ repo: external_exports.string(), fact: external_exports.string() })).optional()
9872
10475
  });
@@ -11509,7 +12112,7 @@ var AnswerQuestionRequest = external_exports.strictObject({
11509
12112
  * text and target; `reason` is kept as the answer's words (`Ignore: <reason>`).
11510
12113
  */
11511
12114
  ignore: external_exports.literal(true).optional(),
11512
- reason: external_exports.string().trim().min(1).max(300).optional()
12115
+ reason: external_exports.string().trim().min(1).max(IGNORE_REASON_MAX).optional()
11513
12116
  });
11514
12117
  var AnsweredQuestion = external_exports.object({
11515
12118
  question: Question,
@@ -13164,10 +13767,12 @@ var OPS = {
13164
13767
  summary: "Every call merged into one edge of a view (a node's, or a focus), not only the first 20 the view lists (review of beta.24)",
13165
13768
  tag: "views",
13166
13769
  params: [
13167
- q("edge", str2, "The edge's id, as the view gives it (required)"),
13168
- q("node", str2, "The node whose view has the edge (or focus)"),
13169
- q("focus", str2, "The node whose focus view has the edge (or node)"),
13170
- q("lens", { type: "string", enum: [...GRAPH_LENSES] }, "The view's lens")
13770
+ { ...q("edge", str2, "The edge's id, as the view gives it"), required: true },
13771
+ q("node", str2, "The node whose view has the edge: one of node or focus is required"),
13772
+ q("focus", str2, "The node whose focus view has the edge: one of node or focus is required"),
13773
+ q("lens", { type: "string", enum: [...GRAPH_LENSES] }, "The view's lens"),
13774
+ q("depth", { type: "string", enum: ["1", "2", "3"] }, "With node: the view's depth, as GET /api/graph/node/{id} takes it (3.11.0)"),
13775
+ q("all", { type: "string", enum: ["1"] }, "With node: every box, as GET /api/graph/node/{id} takes it (3.11.0)")
13171
13776
  ],
13172
13777
  ok: { status: 200, schema: "GraphEdgeCallsView", description: "OK" },
13173
13778
  errors: [400, 404, 422]
@@ -13570,21 +14175,21 @@ var OPS = {
13570
14175
  "/api/trust/answer-boxes/ignore": {
13571
14176
  post: {
13572
14177
  id: "ignoreAnswerBox",
13573
- summary: "A box an answer's words made (beta.24 review), put right as 'it was ignore this': each answer that names it becomes Ignore (the join leaves its calls) and the system leaves its profile. preview writes nothing; the write is local, for Propose for review",
14178
+ summary: "A box an answer's words made (beta.24 review), put right as 'it was ignore this': each answer that names it becomes Ignore (the join leaves its calls) and the system leaves its profile. preview writes nothing; the write (with the preview's stamp) writes all or none, only over the files previewed, local, for Propose for review",
13574
14179
  tag: "workspace",
13575
14180
  body: AnswerBoxRequest,
13576
14181
  ok: { status: 200, schema: "AnswerBoxResult", description: "Previewed or written" },
13577
- errors: [400, 404, 409, 422]
14182
+ errors: [400, 404, 409, 422, 500]
13578
14183
  }
13579
14184
  },
13580
14185
  "/api/trust/answer-boxes/rename": {
13581
14186
  post: {
13582
14187
  id: "renameAnswerBox",
13583
- summary: "A box an answer's words made (beta.24 review), renamed to a real system: a repo or system Atticus knows, or a new outside system's short name; the answers that name it name that instead. preview writes nothing; the write is local, for Propose for review",
14188
+ summary: "A box an answer's words made (beta.24 review), renamed to a real system: a repo or system Atticus knows, or a new outside system's short name; the answers that name it name that instead. preview writes nothing; the write (with the preview's stamp) writes all or none, only over the files previewed, local, for Propose for review",
13584
14189
  tag: "workspace",
13585
14190
  body: AnswerBoxRequest,
13586
14191
  ok: { status: 200, schema: "AnswerBoxResult", description: "Previewed or written" },
13587
- errors: [400, 404, 409, 422]
14192
+ errors: [400, 404, 409, 422, 500]
13588
14193
  }
13589
14194
  },
13590
14195
  "/api/trust/fresh": {
@@ -13619,11 +14224,11 @@ var OPS = {
13619
14224
  "/api/links/corrections": {
13620
14225
  post: {
13621
14226
  id: "correctLinkCalls",
13622
- summary: "This whole arrow is wrong (beta.24): one correction of every call on a link, each in its caller repo's facts/<repo>.corrections.jsonl (several lines in one write per repo), every item checked before any is written. Returns each file, the git command that commits them all and the verify command per repo",
14227
+ summary: "This whole arrow is wrong (beta.24): one correction of every call on a link, or (beta.25) of every dependency fact a depends-on link rests on, each in its repo's facts/<repo>.corrections.jsonl (several lines in one write per repo), every item checked before any is written, all or none. Returns each file, the git command that commits them all and the verify command per repo",
13623
14228
  tag: "workspace",
13624
14229
  body: LinkCorrectionsRequest,
13625
14230
  ok: { status: 200, schema: "LinkCorrectionsResult", description: "Recorded" },
13626
- errors: [400, 404, 422, 500]
14231
+ errors: [400, 404, 409, 413, 422, 500]
13627
14232
  }
13628
14233
  },
13629
14234
  "/api/facts/{repo}/preview": {
@@ -15453,7 +16058,7 @@ var ERROR_TEXT = {
15453
16058
  409: "Conflict: the file changed since you read it, or the state doesn't allow this",
15454
16059
  413: "Too large: the upload is over the limit the problem names",
15455
16060
  422: "Atticus refused: the problem carries the command's own words (ADR 0043)",
15456
- 500: "Written only in part: the problem names exactly what was written"
16061
+ 500: "Not done: the problem says what was written all the same (`written`), most often nothing"
15457
16062
  };
15458
16063
  function openApiDocument() {
15459
16064
  const reg = external_exports.registry();
@@ -16507,7 +17112,7 @@ function referenceFields(kind) {
16507
17112
  }
16508
17113
  function recordReferences(record) {
16509
17114
  const out = [];
16510
- const visit = (value, parts, field) => {
17115
+ const visit2 = (value, parts, field) => {
16511
17116
  if (value === void 0 || value === null)
16512
17117
  return;
16513
17118
  if (parts.length === 0) {
@@ -16520,12 +17125,12 @@ function recordReferences(record) {
16520
17125
  const v = value[head.slice(0, -2)];
16521
17126
  if (Array.isArray(v))
16522
17127
  for (const item of v)
16523
- visit(item, rest, field);
17128
+ visit2(item, rest, field);
16524
17129
  } else
16525
- visit(value[head], rest, field);
17130
+ visit2(value[head], rest, field);
16526
17131
  };
16527
17132
  for (const field of PATHS.get(record.kind) ?? []) {
16528
- visit(record, field.split("."), field);
17133
+ visit2(record, field.split("."), field);
16529
17134
  }
16530
17135
  return out;
16531
17136
  }
@@ -17228,7 +17833,7 @@ function listRepoFilesSync(root, o = {}) {
17228
17833
  go("", [], []);
17229
17834
  return out;
17230
17835
  }
17231
- async function walkRepo(root, visit, o = {}) {
17836
+ async function walkRepo(root, visit2, o = {}) {
17232
17837
  const max = o.max ?? Number.POSITIVE_INFINITY;
17233
17838
  let files = 0;
17234
17839
  let cut = false;
@@ -17256,7 +17861,7 @@ async function walkRepo(root, visit, o = {}) {
17256
17861
  return false;
17257
17862
  }
17258
17863
  files++;
17259
- if (await visit(path) === false)
17864
+ if (await visit2(path) === false)
17260
17865
  return false;
17261
17866
  }
17262
17867
  }
@@ -18630,6 +19235,9 @@ async function answerQuestion(root, id, a) {
18630
19235
  const text4 = a.text?.trim() || void 0;
18631
19236
  if (a.option === void 0 === (text4 === void 0))
18632
19237
  throw new QuestionError("bad-answer", "Give an option or your own words, one of the two.");
19238
+ const ignoreWhy = text4 && JOIN_STEPS.has(q2.askedBy.step) ? ignoredAnswer({ options: q2.options, answer: { text: text4, by: a.by } })?.reason : void 0;
19239
+ if (ignoreWhy && ignoreWhy.length > IGNORE_REASON_MAX)
19240
+ throw new QuestionError("bad-answer", `An Ignore's reason is at most ${IGNORE_REASON_MAX} characters (this is ${ignoreWhy.length}): say it in fewer words.`);
18633
19241
  if (a.option !== void 0 && (!Number.isInteger(a.option) || a.option < 1 || a.option > q2.options.length))
18634
19242
  throw new QuestionError("bad-answer", q2.options.length ? `There is no option ${a.option}: pick 1 to ${q2.options.length}.` : `There is no option ${a.option}: this question has no options, so answer in your own words.`);
18635
19243
  const pickerLabel = a.option !== void 0 ? q2.options[a.option - 1]?.label : void 0;
@@ -18821,9 +19429,12 @@ async function repoReadOf(root, repo) {
18821
19429
  let facts = [];
18822
19430
  if (raw !== void 0 && raw.trim()) {
18823
19431
  const parsed = parseFacts(raw);
18824
- if (parsed.ok)
19432
+ if (parsed.ok) {
18825
19433
  facts = parsed.facts;
18826
- else
19434
+ const newer2 = parsed.newer ?? [];
19435
+ if (newer2.length)
19436
+ why.push(`${plural(newer2.length, "fact")} ${newer2.length === 1 ? "is" : "are"} written by a newer Atticus (fact kind ${[...new Set(newer2.map((n) => n.kind))].sort().join(", ")}); install it to read ${newer2.length === 1 ? "it" : "them"}`);
19437
+ } else
18827
19438
  why.push(`its facts file doesn't read as facts`);
18828
19439
  }
18829
19440
  let report;
@@ -20206,6 +20817,8 @@ export {
20206
20817
  FACTS_SCHEMA_VERSION,
20207
20818
  SETTING_KINDS,
20208
20819
  looksLikeSecret,
20820
+ credentialLike,
20821
+ configSecretField,
20209
20822
  ConfigFact,
20210
20823
  FrameworkFact,
20211
20824
  TERM_ROLES,
@@ -20240,12 +20853,16 @@ export {
20240
20853
  toCanonicalYaml,
20241
20854
  deserializeRecord,
20242
20855
  migrationOf,
20856
+ newerFactOf,
20857
+ newerShapeOf,
20243
20858
  parseFacts,
20859
+ redactFactLine,
20244
20860
  parseFactLine,
20245
20861
  parseFactsLines,
20246
20862
  serializeFacts,
20247
20863
  factIdPart,
20248
20864
  entryEndpointId,
20865
+ placedComponentOf,
20249
20866
  callPath,
20250
20867
  catalogAuth,
20251
20868
  projectFacts,
@@ -20317,11 +20934,15 @@ export {
20317
20934
  JOIN_IGNORE_LABEL,
20318
20935
  IGNORE_PREFIX,
20319
20936
  ignoreOption,
20937
+ IGNORE_REASON_MAX,
20320
20938
  ignoreText,
20321
20939
  ignoredAnswer,
20322
20940
  SYSTEM_NAME_MAX,
20941
+ nameReadsAsSentence,
20942
+ readsAsSentence,
20323
20943
  systemNameProblem,
20324
- madeFromWords,
20944
+ knownTargetNames,
20945
+ namesKnown,
20325
20946
  namesKnownTarget,
20326
20947
  wordsNameNothing,
20327
20948
  HOSTS_OUTSIDE_INTERNAL,
@@ -20332,6 +20953,8 @@ export {
20332
20953
  hostOfQuestion,
20333
20954
  joinHostOfQuestion,
20334
20955
  outsideSystemOfJoinHost,
20956
+ profileText,
20957
+ ProfileEditError,
20335
20958
  addOutsideSystem,
20336
20959
  addProfileSystem,
20337
20960
  editProfileSystem,