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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/dist/bin.js +3 -3
  2. package/dist/{chunk-IKAW2KJU.js → chunk-25CUJJTP.js} +505 -285
  3. package/dist/chunk-26AB2WNW.js +62 -0
  4. package/dist/{chunk-TXNSQ24G.js → chunk-2ITYURTR.js} +3 -3
  5. package/dist/{chunk-66AQ2JIU.js → chunk-2JHE75RW.js} +13 -11
  6. package/dist/{chunk-T7IIEDA3.js → chunk-37UTWGU4.js} +6 -4
  7. package/dist/{chunk-OCQWSFJD.js → chunk-3BEGKSDW.js} +14 -12
  8. package/dist/{chunk-4MYHETJ3.js → chunk-3FGQFDS4.js} +20 -18
  9. package/dist/{chunk-ZFHFC74B.js → chunk-3NS4RS3C.js} +20 -18
  10. package/dist/{chunk-LO6Y7OTG.js → chunk-3TGX4SJ3.js} +10 -7
  11. package/dist/{chunk-K4OXYSGS.js → chunk-3UMKLB6P.js} +7 -5
  12. package/dist/{chunk-4R3TO4VL.js → chunk-3VS7RNEB.js} +19 -17
  13. package/dist/{chunk-ICBGVVRI.js → chunk-3XCCT2GR.js} +163 -38
  14. package/dist/{chunk-MWF4PXQR.js → chunk-3XZRYQWU.js} +37 -34
  15. package/dist/{chunk-KDJ2YKAZ.js → chunk-432FGEVB.js} +9 -7
  16. package/dist/{chunk-C6ORPLCN.js → chunk-44QUCNPH.js} +7 -5
  17. package/dist/{chunk-RLZFL76D.js → chunk-4CS3PMIM.js} +15 -13
  18. package/dist/{chunk-T6MX7WXM.js → chunk-4DCIUKIE.js} +18 -11
  19. package/dist/{chunk-FRCOKUU4.js → chunk-4DX4DIND.js} +9 -7
  20. package/dist/{chunk-RGZFOKVO.js → chunk-4MNMOUU7.js} +6 -4
  21. package/dist/{chunk-BP33TBLI.js → chunk-4RKIOUPA.js} +9 -7
  22. package/dist/{chunk-HUGQZQ2K.js → chunk-532HDXMM.js} +9 -7
  23. package/dist/{chunk-6RQOINER.js → chunk-5EIKOU7L.js} +6 -4
  24. package/dist/{chunk-G6EFXTUO.js → chunk-5FPAKAGE.js} +7 -5
  25. package/dist/{chunk-CA3DKO4D.js → chunk-5FUFVNXB.js} +4 -2
  26. package/dist/{chunk-NC755EKE.js → chunk-5MKV4TV6.js} +1 -1
  27. package/dist/{chunk-VRO7KSGL.js → chunk-5ORLKITZ.js} +23 -21
  28. package/dist/{chunk-W3AZE7LN.js → chunk-5PSKLTBR.js} +3 -3
  29. package/dist/{chunk-JMEWJPF2.js → chunk-5QF5W5P2.js} +7 -7
  30. package/dist/{chunk-CT6NINGR.js → chunk-5Z7L2TSR.js} +3 -3
  31. package/dist/{chunk-SCT4CEF7.js → chunk-66DWUSNY.js} +22 -20
  32. package/dist/{chunk-SRTUETF5.js → chunk-6FIYEB7M.js} +24 -22
  33. package/dist/{chunk-6NCPLIIP.js → chunk-6OZAQPU5.js} +417 -365
  34. package/dist/{chunk-4FLNCK6Q.js → chunk-6TNQO76I.js} +13 -11
  35. package/dist/{chunk-LPDTDFKA.js → chunk-6UTD5RQH.js} +18 -16
  36. package/dist/{chunk-ZNHQGG7J.js → chunk-775FMPUB.js} +4 -4
  37. package/dist/{chunk-GM4EFHUX.js → chunk-77AZRGWE.js} +19 -16
  38. package/dist/{chunk-75OMRKY2.js → chunk-7HWCEDPX.js} +7 -5
  39. package/dist/{chunk-TMFMXQEN.js → chunk-7U46TCRZ.js} +22 -19
  40. package/dist/{chunk-5VTIWEWP.js → chunk-A3NUZJFI.js} +4 -2
  41. package/dist/{chunk-OK6JGLE7.js → chunk-A4VDFIMR.js} +14 -12
  42. package/dist/{chunk-QLWDIKO4.js → chunk-A53IYUCR.js} +20 -17
  43. package/dist/{chunk-D6BVLTDV.js → chunk-A6ZG3UOS.js} +28 -26
  44. package/dist/{chunk-QVVGJVVX.js → chunk-AAY6VPPO.js} +18 -16
  45. package/dist/{chunk-VNIN7Q6Q.js → chunk-ABDE5IRC.js} +18 -16
  46. package/dist/{chunk-XFDDJQT7.js → chunk-AM7PYKVP.js} +15 -13
  47. package/dist/{chunk-J32IPTVQ.js → chunk-ANUMIPF6.js} +22 -20
  48. package/dist/{chunk-SK5RVP7X.js → chunk-ASFRT33J.js} +11 -9
  49. package/dist/{chunk-6R5VHR3N.js → chunk-AWDCVZYO.js} +9 -7
  50. package/dist/{chunk-YD3KTW4H.js → chunk-B63NWU3P.js} +14 -12
  51. package/dist/{chunk-HMZ2DRBC.js → chunk-BBZ6UKN3.js} +16 -5
  52. package/dist/{chunk-3ZA3AK2D.js → chunk-BFQ5IKQA.js} +12 -10
  53. package/dist/{chunk-3UHV76UD.js → chunk-BLVFHN3C.js} +41 -38
  54. package/dist/{chunk-PT4USJNN.js → chunk-BQXAHIZ6.js} +10 -8
  55. package/dist/{chunk-5OXKCH4Z.js → chunk-BTS56NV7.js} +90 -40
  56. package/dist/{chunk-S5GSQPIN.js → chunk-BWYW533C.js} +18 -16
  57. package/dist/{chunk-4ETO2FXE.js → chunk-BYKWWSXL.js} +14 -12
  58. package/dist/chunk-C7BB6IQT.js +147 -0
  59. package/dist/{chunk-S35DIFJH.js → chunk-CCQWQFOT.js} +19 -17
  60. package/dist/{chunk-TVQSXWWV.js → chunk-CCQZN6W3.js} +35 -33
  61. package/dist/{chunk-POSDBRKV.js → chunk-CFSBBLDD.js} +28 -25
  62. package/dist/{chunk-2UMSHYCB.js → chunk-CFSHLQPK.js} +26 -24
  63. package/dist/{chunk-X7ZKNSK4.js → chunk-CI4D6VSU.js} +20 -18
  64. package/dist/{chunk-JXAKYP45.js → chunk-CKRPMRFQ.js} +27 -25
  65. package/dist/{chunk-QAVRDONY.js → chunk-CNF2EZ6S.js} +120 -118
  66. package/dist/chunk-CTJHEG6A.js +97 -0
  67. package/dist/{chunk-ENH6Z4TY.js → chunk-CU7ZK7KP.js} +17 -17
  68. package/dist/{chunk-4GAB5ZOZ.js → chunk-CZ75S2EZ.js} +30 -26
  69. package/dist/{chunk-EVTI22PQ.js → chunk-D5CJEKZI.js} +7 -4
  70. package/dist/{chunk-TV56QLLV.js → chunk-D5ZC7IMC.js} +5 -3
  71. package/dist/{chunk-YDCOZOER.js → chunk-D63NU53X.js} +20 -18
  72. package/dist/{chunk-N2YX6JMY.js → chunk-DCQSPSXU.js} +28 -23
  73. package/dist/{chunk-ZLQEQR3D.js → chunk-DCRZ3OQ7.js} +8 -6
  74. package/dist/chunk-DD2AXECF.js +41 -0
  75. package/dist/{chunk-PRMUQUWN.js → chunk-DF6DPCW2.js} +16 -14
  76. package/dist/{chunk-ZJGCGKA4.js → chunk-DH3EQMIA.js} +5 -3
  77. package/dist/{chunk-UALE35WK.js → chunk-DIXA74N7.js} +5 -3
  78. package/dist/{chunk-TDSCKP3V.js → chunk-DIYNRYXW.js} +2 -2
  79. package/dist/chunk-DYDNW4O6.js +52 -0
  80. package/dist/{chunk-TNCF26JK.js → chunk-E7YDJH6B.js} +14 -12
  81. package/dist/chunk-EEKQI3U4.js +45 -0
  82. package/dist/{chunk-IYNCSYU4.js → chunk-EHF2MBGR.js} +6 -4
  83. package/dist/{chunk-FQVSLBTV.js → chunk-ENZ3PI7L.js} +3 -3
  84. package/dist/{chunk-HJQVUOUL.js → chunk-EPQQ2XVM.js} +13 -11
  85. package/dist/{chunk-FL344WQD.js → chunk-ESJALLOK.js} +6 -4
  86. package/dist/{chunk-MBYYQHPM.js → chunk-ETQSQ2EC.js} +6 -4
  87. package/dist/{chunk-7XYLNQFO.js → chunk-EUMXLSW5.js} +13 -5
  88. package/dist/{chunk-PWXB5GBB.js → chunk-F63F4NKT.js} +18 -16
  89. package/dist/{chunk-6Y4FXOMI.js → chunk-FDL2JOLB.js} +24 -22
  90. package/dist/{chunk-T33TPFGI.js → chunk-FFDVAV56.js} +24 -22
  91. package/dist/{chunk-S6LW2RRC.js → chunk-FFYOZ7PF.js} +10 -8
  92. package/dist/{chunk-6SNTHK43.js → chunk-FGW5TLGM.js} +24 -19
  93. package/dist/{chunk-RRQUQAXP.js → chunk-FL53R4SW.js} +1 -1
  94. package/dist/chunk-FYWLB7PO.js +38 -0
  95. package/dist/{chunk-ZENHDXRZ.js → chunk-G3W7GNEP.js} +20 -18
  96. package/dist/{chunk-B4AEL3RF.js → chunk-G3ZFEHCX.js} +21 -107
  97. package/dist/{chunk-Y2H7X3VI.js → chunk-G67GOK4S.js} +10 -8
  98. package/dist/{chunk-73GFVW2L.js → chunk-GCMDDVIE.js} +14 -9
  99. package/dist/{chunk-A4JXVO5O.js → chunk-GFYVVTKH.js} +10 -8
  100. package/dist/chunk-GJVCBTSO.js +20722 -0
  101. package/dist/{chunk-7NQAGYK4.js → chunk-GKZDHXC2.js} +8 -8
  102. package/dist/{chunk-P22EPEBR.js → chunk-GQFUEUC7.js} +18 -16
  103. package/dist/chunk-GQPP4P2E.js +33 -0
  104. package/dist/{chunk-UJF7PIMP.js → chunk-GS7N3RFG.js} +53 -34
  105. package/dist/{chunk-LZVHP7CT.js → chunk-GXQYEIYM.js} +7 -5
  106. package/dist/{chunk-2YSD6E6V.js → chunk-H5EQOSTC.js} +42 -33
  107. package/dist/{chunk-FTLYXMHA.js → chunk-H7KERB6Q.js} +7 -5
  108. package/dist/{chunk-IMZFOMVX.js → chunk-HGDBM3A5.js} +5 -3
  109. package/dist/{chunk-73CC73I4.js → chunk-HI7ADE4E.js} +1 -1
  110. package/dist/{chunk-CZ2ZS7AT.js → chunk-HNPKCRCE.js} +1004 -329
  111. package/dist/{chunk-CMB7FXHJ.js → chunk-HRHXTLUM.js} +16 -14
  112. package/dist/{chunk-CFUDAW3R.js → chunk-HRYI22QU.js} +17 -15
  113. package/dist/{chunk-XOMEQVLK.js → chunk-HWNFFCGB.js} +5 -3
  114. package/dist/{chunk-VJFXQISZ.js → chunk-HXFZX2BI.js} +12 -8
  115. package/dist/{chunk-BAY4K55I.js → chunk-HYHV2P3G.js} +16 -13
  116. package/dist/{chunk-QZWRPQTI.js → chunk-IB66ZLDN.js} +8 -6
  117. package/dist/{chunk-PQQKZPBU.js → chunk-IJQHBK76.js} +1 -1
  118. package/dist/{chunk-XF6TSZW2.js → chunk-IK6LHW3E.js} +6 -4
  119. package/dist/{chunk-FSN6JFXB.js → chunk-IOHRX4KF.js} +20 -18
  120. package/dist/{chunk-TUM52SOE.js → chunk-IRXZKKCG.js} +17 -15
  121. package/dist/{chunk-TABH4RBZ.js → chunk-IUBBEU6O.js} +16 -14
  122. package/dist/{chunk-S6W3D5GS.js → chunk-IWPO5AUT.js} +29 -26
  123. package/dist/{chunk-J4CPHJUL.js → chunk-J4K4C4T5.js} +30 -14
  124. package/dist/{chunk-JSP73CDW.js → chunk-JCEYOSST.js} +8 -5
  125. package/dist/{chunk-POEMZECG.js → chunk-JCG2EBNB.js} +1 -1
  126. package/dist/{chunk-63NFFAGI.js → chunk-JFBVIMGY.js} +14 -12
  127. package/dist/{chunk-FMR2D3AZ.js → chunk-JJ4SCGRJ.js} +8 -6
  128. package/dist/{chunk-ZNTTW4IT.js → chunk-JLYH2QOE.js} +7 -5
  129. package/dist/{chunk-W5VYJWOG.js → chunk-JMH6TCZJ.js} +25 -23
  130. package/dist/{chunk-2WUTCPPJ.js → chunk-JUHZBZPZ.js} +17 -13
  131. package/dist/{chunk-NAPHHWW2.js → chunk-JVMNEI7B.js} +3 -3
  132. package/dist/{chunk-S5XFO4GY.js → chunk-JYJMIAFS.js} +6 -4
  133. package/dist/{chunk-BFMTGNAQ.js → chunk-KIY2WCN7.js} +5 -3
  134. package/dist/{chunk-DCRYOMTM.js → chunk-KYO5HT4G.js} +14 -12
  135. package/dist/chunk-L27KUL5B.js +38 -0
  136. package/dist/{chunk-PGAMTKBI.js → chunk-L3PIN47C.js} +6 -4
  137. package/dist/{chunk-FMJYKLDY.js → chunk-L6Z6TMIK.js} +5 -5
  138. package/dist/{chunk-QBMLBCQH.js → chunk-LAGZBQHK.js} +16 -13
  139. package/dist/{chunk-SYP56T2D.js → chunk-LBG4GMOR.js} +7 -4
  140. package/dist/{chunk-XAPXKFIS.js → chunk-LDKP7OWQ.js} +33 -24
  141. package/dist/{chunk-ZR6J4QFQ.js → chunk-LELM7X5H.js} +13 -11
  142. package/dist/{chunk-CQ7RF4QN.js → chunk-LIB6AUZS.js} +6 -4
  143. package/dist/{chunk-J25YOUIZ.js → chunk-LIQWFDOZ.js} +6 -4
  144. package/dist/{chunk-OPWGPQ2N.js → chunk-LKUTBQ2Y.js} +8 -6
  145. package/dist/{chunk-7IFTSAHP.js → chunk-LOCJHNZI.js} +10 -8
  146. package/dist/{chunk-6ZFF7XSL.js → chunk-LTIXFLYE.js} +6 -6
  147. package/dist/{chunk-M3EOFSPY.js → chunk-M3RWF7MC.js} +33 -29
  148. package/dist/chunk-MA6UK7GX.js +42 -0
  149. package/dist/{chunk-RCG5IAAT.js → chunk-MCE74XMF.js} +12 -10
  150. package/dist/{chunk-BYBU2EIB.js → chunk-MDTAZ6NE.js} +23 -21
  151. package/dist/{chunk-Y5IE6YKD.js → chunk-MMOMKHAX.js} +6 -4
  152. package/dist/{chunk-3424TLIJ.js → chunk-MOWUP33K.js} +12 -10
  153. package/dist/{chunk-WYGTSZHR.js → chunk-MPATOMY5.js} +16 -14
  154. package/dist/{chunk-QX4MAMUG.js → chunk-MQFSEGTU.js} +23 -21
  155. package/dist/{chunk-WXVTYLVH.js → chunk-MT3FNSXO.js} +4 -4
  156. package/dist/{chunk-MH2ZK67S.js → chunk-MUY5MAGM.js} +15 -12
  157. package/dist/{chunk-WF3RCZNO.js → chunk-MVXMISNA.js} +9 -7
  158. package/dist/{chunk-S7GUZ45I.js → chunk-MWN7CBVL.js} +5 -3
  159. package/dist/{chunk-AGOLEMHK.js → chunk-MZWM73S2.js} +10 -8
  160. package/dist/chunk-NBZ7RKX3.js +46 -0
  161. package/dist/{chunk-CKVBDVIW.js → chunk-NC56V6KQ.js} +6 -4
  162. package/dist/{chunk-Z3RAFU5B.js → chunk-NN6AXKFX.js} +17 -15
  163. package/dist/{chunk-T6MAWL5P.js → chunk-NOU5IBLM.js} +6 -4
  164. package/dist/{chunk-YERAAEO4.js → chunk-NQDHRT2H.js} +15 -13
  165. package/dist/{chunk-POSZFDSQ.js → chunk-NTEPBOAF.js} +6 -4
  166. package/dist/{chunk-27AJAKX7.js → chunk-NTOPAOBY.js} +3 -3
  167. package/dist/{chunk-K757G7AD.js → chunk-NX5IPHI3.js} +19 -16
  168. package/dist/{chunk-7YQBDE5W.js → chunk-O4ZWZZZT.js} +6 -4
  169. package/dist/{chunk-J2H7YG3K.js → chunk-OCU5S2XG.js} +5 -3
  170. package/dist/{chunk-LSHSDC6S.js → chunk-OKSRK2LJ.js} +19 -17
  171. package/dist/{chunk-BFL4PO64.js → chunk-OSWOIFRQ.js} +6 -4
  172. package/dist/{chunk-3EWKO457.js → chunk-OSZTENIA.js} +8 -6
  173. package/dist/{chunk-Q367UGYN.js → chunk-OTUBMKSG.js} +10 -8
  174. package/dist/{chunk-E3PDCQRH.js → chunk-OYKNPZCV.js} +291 -247
  175. package/dist/{chunk-NROSSWMS.js → chunk-OYTSRNSZ.js} +8 -6
  176. package/dist/chunk-OYZ64UMQ.js +67 -0
  177. package/dist/{chunk-RPQITJNX.js → chunk-PB3NCPRF.js} +10 -8
  178. package/dist/chunk-PIPJZIJE.js +47 -0
  179. package/dist/{chunk-XMUWPA56.js → chunk-PIPYJTIL.js} +27 -24
  180. package/dist/{chunk-SVGGMBJI.js → chunk-PUMNCWHJ.js} +15 -13
  181. package/dist/{chunk-L3RCQWVQ.js → chunk-PZBNDFZ7.js} +31 -24
  182. package/dist/chunk-Q2ULHBCJ.js +59 -0
  183. package/dist/{chunk-Z2D4P3R3.js → chunk-Q5QSWV2R.js} +14 -12
  184. package/dist/{chunk-FPBUTZI5.js → chunk-QFDPX6C4.js} +3236 -22928
  185. package/dist/{chunk-6RYB3EET.js → chunk-QGBS4GMS.js} +14 -12
  186. package/dist/{chunk-EMVZIOOD.js → chunk-QIDSEHJA.js} +17 -15
  187. package/dist/{chunk-VK7WYA64.js → chunk-QJ3AYXVO.js} +14 -12
  188. package/dist/{chunk-KTNOBTV5.js → chunk-QK6CGRKK.js} +6 -4
  189. package/dist/{chunk-PXW2RZGQ.js → chunk-QOC3Q4UU.js} +1 -1
  190. package/dist/{chunk-UTPIFH4I.js → chunk-QPLNB2BM.js} +5 -3
  191. package/dist/chunk-QVF4KYIO.js +71 -0
  192. package/dist/{chunk-VKTXFFOZ.js → chunk-QXXEO4TF.js} +5 -3
  193. package/dist/{chunk-JFFKHIM6.js → chunk-QYFNVQLK.js} +1 -1
  194. package/dist/{chunk-PNSSE7JM.js → chunk-R6CJOMPC.js} +25 -23
  195. package/dist/{chunk-3MYBT62N.js → chunk-ROWZYQOI.js} +9 -7
  196. package/dist/{chunk-3ASYYMOX.js → chunk-RQAMZVWW.js} +10 -8
  197. package/dist/chunk-RQSUFGU2.js +55 -0
  198. package/dist/{chunk-SWNKO4C4.js → chunk-RRKM3GJA.js} +29 -26
  199. package/dist/{chunk-XGO74QWR.js → chunk-RSHVSXPJ.js} +7 -5
  200. package/dist/chunk-RSKMV3VC.js +22 -0
  201. package/dist/{chunk-X5ZHDSLU.js → chunk-RU5W7JJQ.js} +25 -23
  202. package/dist/{chunk-CS4BMJLL.js → chunk-RYY554OA.js} +7 -5
  203. package/dist/{chunk-AVMWESFZ.js → chunk-SGYQORAD.js} +6 -3
  204. package/dist/{chunk-6ZSYLZ7O.js → chunk-SLGUSFOD.js} +3 -3
  205. package/dist/{chunk-73V2OONC.js → chunk-SUAHNYNQ.js} +17 -15
  206. package/dist/{chunk-KT6Q44CA.js → chunk-SUYC5NP6.js} +27 -25
  207. package/dist/{chunk-CJEBRJBS.js → chunk-SWSGRRNO.js} +6 -4
  208. package/dist/{chunk-FJVUHQPS.js → chunk-SYLXQNPC.js} +26 -23
  209. package/dist/{chunk-FRAEQVYN.js → chunk-T24TBI7F.js} +24 -22
  210. package/dist/chunk-T2HXLDY3.js +55 -0
  211. package/dist/{chunk-7XWJ6ED2.js → chunk-T5NH5L7A.js} +16 -13
  212. package/dist/{chunk-2QPJ4E4Z.js → chunk-TAR6T2RE.js} +4 -2
  213. package/dist/{chunk-AQRUQNFB.js → chunk-TBQHBOFF.js} +10 -8
  214. package/dist/{chunk-AFBCNZRZ.js → chunk-TKE6ZJMM.js} +26 -24
  215. package/dist/chunk-TKEXS74L.js +52 -0
  216. package/dist/{chunk-3EX5HCZD.js → chunk-TXYMNKGM.js} +16 -14
  217. package/dist/{chunk-WZYM5M4U.js → chunk-U2JTTRKS.js} +19 -17
  218. package/dist/{chunk-LM45GMMB.js → chunk-U37ZOYJJ.js} +7 -7
  219. package/dist/{chunk-EXJZBL5N.js → chunk-U57VLY6X.js} +23 -21
  220. package/dist/{chunk-YHMPDIRG.js → chunk-U66RQUFC.js} +6 -4
  221. package/dist/{chunk-PFULMC2D.js → chunk-UCFNHK5L.js} +22 -20
  222. package/dist/{chunk-BUUJ7N4O.js → chunk-UI6KNLSO.js} +31 -11
  223. package/dist/{chunk-FVYZ4Y52.js → chunk-UKRJ2ISN.js} +5 -3
  224. package/dist/{chunk-GOZLTLRY.js → chunk-UWJOM457.js} +4 -4
  225. package/dist/{chunk-6NN36LVK.js → chunk-UXO25YBN.js} +3 -3
  226. package/dist/chunk-VE2T5URA.js +51 -0
  227. package/dist/{chunk-HRS5O7VV.js → chunk-W4EG25TI.js} +21 -17
  228. package/dist/{chunk-Z3H27OMV.js → chunk-WAAPMZWO.js} +6 -4
  229. package/dist/{chunk-MLGWSBF4.js → chunk-WECCLSYY.js} +47 -45
  230. package/dist/chunk-WQDJGNJQ.js +45 -0
  231. package/dist/{chunk-OBUB3H72.js → chunk-WWSCJBF6.js} +14 -12
  232. package/dist/{chunk-FBCVC2GJ.js → chunk-X7HFXXTZ.js} +16 -13
  233. package/dist/{chunk-RQQYEDAC.js → chunk-XERIHPBF.js} +12 -9
  234. package/dist/{chunk-XNFM6WUK.js → chunk-XKNISZ6N.js} +21 -18
  235. package/dist/{chunk-OSYHGGL3.js → chunk-XNH5ZWIA.js} +20 -18
  236. package/dist/{chunk-LHH5KG5A.js → chunk-XNW3EDCY.js} +3 -3
  237. package/dist/{chunk-DSHRA72L.js → chunk-XPXOKHNZ.js} +13 -11
  238. package/dist/{chunk-T3FNG2H2.js → chunk-XXRBAJ36.js} +14 -12
  239. package/dist/{chunk-K4RNVDR4.js → chunk-YA2IJJ6N.js} +8 -6
  240. package/dist/{chunk-WOMQQWTO.js → chunk-YB5AKYVQ.js} +7 -5
  241. package/dist/{chunk-G7VBMOZH.js → chunk-YDDLVBQ4.js} +3 -3
  242. package/dist/{chunk-ZSNOILL5.js → chunk-YF6N45QN.js} +1 -1
  243. package/dist/{chunk-NCLZJCXA.js → chunk-YHWX5LPT.js} +23 -21
  244. package/dist/{chunk-MEJ63LDG.js → chunk-YLZNTVZR.js} +11 -9
  245. package/dist/{chunk-APDN6UOR.js → chunk-YUJTOALL.js} +20 -18
  246. package/dist/{chunk-QLQIFJP3.js → chunk-Z5YDTIWQ.js} +19 -16
  247. package/dist/{chunk-ISG547IS.js → chunk-ZCU2UY47.js} +24 -22
  248. package/dist/{chunk-7K5OH45X.js → chunk-ZIAYNHHE.js} +69 -9
  249. package/dist/{chunk-MNIPPBCT.js → chunk-ZJ2W2RDE.js} +7 -5
  250. package/dist/{chunk-DHKDH464.js → chunk-ZRQHSMPK.js} +6 -4
  251. package/dist/{chunk-V7PEHQZU.js → chunk-ZSD75FYI.js} +21 -19
  252. package/dist/{chunk-PCCLVIDP.js → chunk-ZSNNF26J.js} +25 -22
  253. package/dist/{chunk-GUGQSIQM.js → chunk-ZX6RAGE6.js} +11 -9
  254. package/dist/files.json +561 -545
  255. package/dist/packages/sdk/npm/index.js +5502 -4956
  256. package/dist/packages/ui/dist/assets/{elk-api-DxfAMOJq.js → elk-api--rH6Kdl4.js} +2 -2
  257. package/dist/packages/ui/dist/assets/{index-Jyc9dFeZ.css → index-Bf2immpE.css} +1 -1
  258. package/dist/packages/ui/dist/assets/index-CH4nGIW3.js +62 -0
  259. package/dist/packages/ui/dist/index.html +2 -2
  260. package/package.json +5 -5
  261. package/dist/chunk-5MYE42AP.js +0 -43
  262. package/dist/chunk-5O7U67UA.js +0 -57
  263. package/dist/chunk-6JVPBGQG.js +0 -50
  264. package/dist/chunk-AHFQHPFF.js +0 -49
  265. package/dist/chunk-CXTG6AWM.js +0 -40
  266. package/dist/chunk-GPNMSX5H.js +0 -36
  267. package/dist/chunk-HMWJWYE2.js +0 -31
  268. package/dist/chunk-J2CDBSFP.js +0 -69
  269. package/dist/chunk-NKJDO4UC.js +0 -39
  270. package/dist/chunk-NOYOFYAJ.js +0 -59
  271. package/dist/chunk-OXXZZ7HQ.js +0 -50
  272. package/dist/chunk-P4YUT7W7.js +0 -45
  273. package/dist/chunk-RQSLHZ7T.js +0 -36
  274. package/dist/chunk-RYQ4JCFT.js +0 -65
  275. package/dist/chunk-UMCDODBX.js +0 -53
  276. package/dist/chunk-VJZI6KFP.js +0 -47
  277. package/dist/chunk-W4TNCEI4.js +0 -44
  278. package/dist/chunk-XLZAAAPX.js +0 -43
  279. package/dist/packages/ui/dist/assets/index-Buit9TfP.js +0 -62
@@ -8,18 +8,18 @@ import {
8
8
  rereadPlan,
9
9
  sameCommit,
10
10
  verifyFacts
11
- } from "./chunk-CZ2ZS7AT.js";
11
+ } from "./chunk-HNPKCRCE.js";
12
12
  import {
13
13
  featuresForScan,
14
14
  namingHint,
15
15
  syncSources
16
- } from "./chunk-4GAB5ZOZ.js";
16
+ } from "./chunk-CZ75S2EZ.js";
17
17
  import {
18
18
  scanInputs
19
- } from "./chunk-A4JXVO5O.js";
19
+ } from "./chunk-GFYVVTKH.js";
20
20
  import {
21
21
  listIngestors
22
- } from "./chunk-TDSCKP3V.js";
22
+ } from "./chunk-DIYNRYXW.js";
23
23
  import {
24
24
  BUILT_IN_EXTRACTORS,
25
25
  MODEL_READERS,
@@ -34,7 +34,7 @@ import {
34
34
  runDialectTests,
35
35
  runFrameworkTests,
36
36
  unmodelledFrameworks
37
- } from "./chunk-G6EFXTUO.js";
37
+ } from "./chunk-5FPAKAGE.js";
38
38
  import {
39
39
  DEFAULT_IGNORES,
40
40
  configHash,
@@ -46,31 +46,24 @@ import {
46
46
  sandboxedExtractor,
47
47
  scanRepo,
48
48
  withParseCache
49
- } from "./chunk-PQQKZPBU.js";
49
+ } from "./chunk-IJQHBK76.js";
50
+ import {
51
+ buildContextPack,
52
+ toRunSummary
53
+ } from "./chunk-MOWUP33K.js";
50
54
  import {
51
55
  baseClonePath,
52
56
  changesSince,
53
57
  checkoutState,
54
58
  inPlaceDir
55
- } from "./chunk-3EWKO457.js";
56
- import {
57
- buildContextPack,
58
- toRunSummary
59
- } from "./chunk-3424TLIJ.js";
59
+ } from "./chunk-OSZTENIA.js";
60
60
  import {
61
- AgentDefinition,
62
61
  DECLARED_CALLER,
63
- DEFAULT_SPEC_TEMPLATE,
64
62
  HOSTS_NONE,
65
63
  HOSTS_OUTSIDE_INTERNAL,
66
64
  HOSTS_OUTSIDE_VENDOR,
67
- IsoDateTime,
68
- NEVER_CHECKED_STEPS,
65
+ HOSTS_STEP,
69
66
  NO_TARGET,
70
- PluginExpected,
71
- REPO_TYPE_SCHEMA_VERSION,
72
- RecordId,
73
- SCAN_SETTINGS_SCHEMA_VERSION,
74
67
  TARGETS_ANOTHER_LABEL,
75
68
  TARGETS_SPLIT_LABEL,
76
69
  TARGETS_STEP_ID,
@@ -83,31 +76,26 @@ import {
83
76
  callTargetQuestion,
84
77
  callerRecords,
85
78
  catalogDirOf,
86
- cmpNatural,
87
- cmpText,
88
- conventionsOf,
89
79
  declaredCallsOf,
90
80
  deserializeRecord,
91
- effectiveComponentTypes,
92
- external_exports,
93
81
  factIdPart,
94
82
  factsDirOf,
95
83
  factsRelOf,
96
84
  fieldKey,
97
85
  flowFiles,
98
86
  helperOn,
99
- hostMatches,
87
+ hostOfQuestion,
100
88
  hostQuestionText,
101
89
  identifierWords,
102
- isAiBy,
90
+ ignoreOption,
91
+ ignoredAnswer,
103
92
  isGuessedJoin,
104
- isPathMatch,
105
93
  isPrototypeType,
106
94
  joinCallers,
107
- joinConventions,
108
95
  joinFacts,
109
96
  joinFlagsOf,
110
97
  joinGuessesOf,
98
+ joinHostOfQuestion,
111
99
  joinRecords,
112
100
  joinSharedMaps,
113
101
  joinTerms,
@@ -116,15 +104,16 @@ import {
116
104
  lineNamesWord,
117
105
  linkEvidenceOf,
118
106
  listQuestions,
119
- loadOrgPack,
120
107
  mergeCatalog,
121
- normalizePath,
122
108
  orgPackDirOf,
109
+ outsideBoundaryOf,
123
110
  outsideSystemOf,
111
+ outsideSystemOfJoinHost,
124
112
  pairsFromCorrections,
125
113
  parseCorrections,
126
114
  parseFacts,
127
115
  parseRecord,
116
+ placeholderIn,
128
117
  projectFacts,
129
118
  questionId,
130
119
  readParsedFiles,
@@ -132,7 +121,6 @@ import {
132
121
  serializeRecord,
133
122
  sharedJoinAbout,
134
123
  singularNoun,
135
- slugify,
136
124
  specFileHash,
137
125
  specFindingFingerprint,
138
126
  stackHelpersOff,
@@ -142,14 +130,38 @@ import {
142
130
  throwIfCancelled,
143
131
  toCanonicalYaml,
144
132
  topicOfQuestion,
145
- topicQuestionText,
133
+ topicQuestionText
134
+ } from "./chunk-GJVCBTSO.js";
135
+ import {
136
+ writeFileAtomic
137
+ } from "./chunk-G3ZFEHCX.js";
138
+ import {
139
+ AgentDefinition,
140
+ DEFAULT_SPEC_TEMPLATE,
141
+ IsoDateTime,
142
+ NEVER_CHECKED_STEPS,
143
+ PluginExpected,
144
+ REPO_TYPE_SCHEMA_VERSION,
145
+ RecordId,
146
+ SCAN_SETTINGS_SCHEMA_VERSION,
147
+ cmpNatural,
148
+ cmpText,
149
+ conventionsOf,
150
+ effectiveComponentTypes,
151
+ external_exports,
152
+ hostMatches,
153
+ isAiBy,
154
+ isPathMatch,
155
+ joinConventions,
156
+ loadOrgPack,
157
+ normalizePath,
158
+ slugify,
146
159
  urlHostPort
147
- } from "./chunk-FPBUTZI5.js";
160
+ } from "./chunk-QFDPX6C4.js";
148
161
  import {
149
162
  SCHEMA_VERSION,
150
- keptParse,
151
- writeFileAtomic
152
- } from "./chunk-B4AEL3RF.js";
163
+ keptParse
164
+ } from "./chunk-CTJHEG6A.js";
153
165
  import {
154
166
  require_dist
155
167
  } from "./chunk-BQGDB6ZL.js";
@@ -1482,17 +1494,401 @@ function estateMergeInput(op, repos, records, modulesOf = (id) => repos.find((r)
1482
1494
  function mergeEstate(op, repos, records, modulesOf, read) {
1483
1495
  return mergeCatalog(estateMergeInput(op, repos, records, modulesOf, read));
1484
1496
  }
1485
- function curatedDirOf(root, op) {
1486
- return join5(root, ...op.sources.layout.catalog.split("/"), "curated");
1497
+ function curatedDirOf(root, op) {
1498
+ return join5(root, ...op.sources.layout.catalog.split("/"), "curated");
1499
+ }
1500
+
1501
+ // packages/scanner/dist/facts-scan.js
1502
+ import { readFile as readFile4 } from "node:fs/promises";
1503
+ import { join as join6 } from "node:path";
1504
+
1505
+ // packages/scanner/dist/facts-catalog.js
1506
+ import { createHash as createHash2 } from "node:crypto";
1507
+
1508
+ // packages/scanner/dist/hosts-asked.js
1509
+ var segs = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$]/.test(x) ? "{}" : x);
1510
+ var underPath = (path, base2) => {
1511
+ const b = segs(base2);
1512
+ const c = segs(path);
1513
+ return b.length > 0 && b.length <= c.length && b.every((x, i) => x === c[i]);
1514
+ };
1515
+ var servesPath = (entry, path) => {
1516
+ const e = segs(entry);
1517
+ const c = segs(path);
1518
+ return e.length === c.length && e.every((x, i) => x === "{}" || c[i] === "{}" || x === c[i]);
1519
+ };
1520
+ var HTTP_TYPES = /* @__PURE__ */ new Set(["rest", "graphql", "soap", "websocket", "sse", "webhook"]);
1521
+ var CONFIG_FILES = [
1522
+ "**/application*.properties",
1523
+ "**/application*.yml",
1524
+ "**/application*.yaml",
1525
+ "**/bootstrap*.properties",
1526
+ "**/bootstrap*.yml",
1527
+ "**/bootstrap*.yaml",
1528
+ "**/.env",
1529
+ "**/.env.*",
1530
+ "**/Dockerfile",
1531
+ "**/docker-compose*.yml",
1532
+ "**/docker-compose*.yaml",
1533
+ "**/compose*.yml",
1534
+ "**/compose*.yaml",
1535
+ "**/package.json"
1536
+ ];
1537
+ function lineSetsPort(line, port) {
1538
+ const p = String(port);
1539
+ const end = "(?![0-9])";
1540
+ return [
1541
+ new RegExp(`port["']?\\s*[:=]\\s*["']?${p}${end}`, "i"),
1542
+ new RegExp(`^\\s*EXPOSE\\s+(?:[0-9]+(?:/[a-z]+)?\\s+)*${p}${end}`, "i"),
1543
+ new RegExp(`--port[=\\s]+${p}${end}`, "i"),
1544
+ new RegExp(`(?:^|[\\s"'-])${p}:[0-9]+`)
1545
+ ].some((re) => re.test(line));
1546
+ }
1547
+ function callHost(url) {
1548
+ if (url.includes("${"))
1549
+ return void 0;
1550
+ if (tokenHost(url))
1551
+ return void 0;
1552
+ const hp = urlHostPort(url);
1553
+ if (!hp || !hp.host)
1554
+ return void 0;
1555
+ const explicit = /^[a-z][a-z0-9+.-]*:\/\/(?:[^/@?#]*@)?[^/:?#]+:(\d+)/i.exec(url);
1556
+ return {
1557
+ label: explicit ? `${hp.host}:${explicit[1]}` : hp.host,
1558
+ host: hp.host,
1559
+ ...hp.port !== void 0 ? { port: hp.port } : {}
1560
+ };
1561
+ }
1562
+ function tokenHost(url) {
1563
+ const authority = /^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)/i.exec(url)?.[1] ?? url;
1564
+ return !!placeholderIn(authority);
1565
+ }
1566
+ var callHostLabel = (url) => callHost(url)?.label;
1567
+ async function unknownHosts(o) {
1568
+ const patterns = o.repos.flatMap((r) => [
1569
+ ...r.hosts,
1570
+ ...(r.modules ?? []).flatMap((m) => m.hosts)
1571
+ ]);
1572
+ const byHost = /* @__PURE__ */ new Map();
1573
+ for (const r of o.records) {
1574
+ if (r.kind !== "Unresolved" || r.unresolvedKind !== "http-call")
1575
+ continue;
1576
+ const url = r.raw.slice(r.raw.indexOf(" ") + 1);
1577
+ const h = callHost(url);
1578
+ if (!h)
1579
+ continue;
1580
+ if (patterns.some((p) => hostMatches(p, h.host, h.port)))
1581
+ continue;
1582
+ const e = r.evidence[0];
1583
+ const repo = e?.repo ?? r.owner;
1584
+ if (!e?.path || e.line === void 0 || !repo)
1585
+ continue;
1586
+ const entry = byHost.get(h.label) ?? {
1587
+ ...h.port !== void 0 ? { port: h.port } : {},
1588
+ explicit: h.label !== h.host,
1589
+ calls: [],
1590
+ paths: /* @__PURE__ */ new Set()
1591
+ };
1592
+ const path = /^[a-z][a-z0-9+.-]*:\/\/[^/?#]*(\/[^?#]*)?/i.exec(url)?.[1];
1593
+ if (path)
1594
+ entry.paths.add(path);
1595
+ const at3 = `${e.path}:${e.line}`;
1596
+ if (!entry.calls.some((c) => c.repo === repo && c.at === at3))
1597
+ entry.calls.push({ repo, at: at3 });
1598
+ byHost.set(h.label, entry);
1599
+ }
1600
+ if (byHost.size === 0)
1601
+ return [];
1602
+ const compRepo = /* @__PURE__ */ new Map();
1603
+ for (const r of o.repos) {
1604
+ compRepo.set(r.component ?? r.id, r.id);
1605
+ for (const m of r.modules ?? [])
1606
+ compRepo.set(m.component, r.id);
1607
+ }
1608
+ const serving = /* @__PURE__ */ new Set();
1609
+ for (const r of o.records)
1610
+ if (r.kind === "Endpoint" && HTTP_TYPES.has(r.endpointType)) {
1611
+ const repo = compRepo.get(r.component);
1612
+ if (repo)
1613
+ serving.add(repo);
1614
+ }
1615
+ const servers = [...serving].sort();
1616
+ const configs = /* @__PURE__ */ new Map();
1617
+ const configOf = async (repo) => {
1618
+ if (configs.has(repo))
1619
+ return configs.get(repo);
1620
+ const h = o.handle(repo);
1621
+ const out = [];
1622
+ if (h)
1623
+ for await (const path of h.listFiles(CONFIG_FILES)) {
1624
+ const t = await h.readText(path).catch(() => void 0);
1625
+ if (t !== void 0)
1626
+ out.push({ path, lines: t.replace(/\r\n?/g, "\n").split("\n") });
1627
+ }
1628
+ configs.set(repo, out);
1629
+ return out;
1630
+ };
1631
+ const asks = [];
1632
+ for (const [host, entry] of [...byHost.entries()].sort(([a], [b]) => cmpText(a, b))) {
1633
+ if (servers.length === 0)
1634
+ continue;
1635
+ const hits = [];
1636
+ if (entry.explicit && entry.port !== void 0)
1637
+ for (const repo of servers) {
1638
+ hit: for (const f of await configOf(repo))
1639
+ for (const [i, l] of f.lines.entries())
1640
+ if (lineSetsPort(l, entry.port)) {
1641
+ hits.push({ repo, at: `${f.path}:${i + 1}`, line: l.trim() });
1642
+ break hit;
1643
+ }
1644
+ }
1645
+ const suggest = hits.length === 1 ? hits[0] : void 0;
1646
+ const calls = entry.calls.sort((a, b) => cmpText(a.repo, b.repo) || cmpNatural(a.at, b.at));
1647
+ const byPath = [];
1648
+ for (const g of o.records) {
1649
+ if (g.kind !== "GatewayRoute")
1650
+ continue;
1651
+ const repo = g.evidence.find((e) => e.repo)?.repo;
1652
+ if (!repo || byPath.some((b) => b.repo === repo))
1653
+ continue;
1654
+ const under2 = [...entry.paths].filter((p) => underPath(p, g.basepath));
1655
+ if (!under2.length)
1656
+ continue;
1657
+ const comps = new Set([...compRepo].filter(([, r]) => r === repo).map(([c]) => c));
1658
+ const hit = o.records.find((r) => r.kind === "Endpoint" && comps.has(r.component) && under2.some((p) => servesPath(r.pathOrTopic, p)));
1659
+ byPath.push({
1660
+ repo,
1661
+ serves: hit ? [hit.method?.toUpperCase(), hit.pathOrTopic].filter(Boolean).join(" ") : `the routes under ${g.basepath}`
1662
+ });
1663
+ }
1664
+ byPath.sort((a, b) => cmpText(a.repo, b.repo));
1665
+ const first = suggest ? [suggest.repo] : byPath.map((b) => b.repo).filter((x) => servers.includes(x));
1666
+ const about = Object.fromEntries(servers.flatMap((s) => {
1667
+ const d = o.repos.find((r) => r.id === s)?.description;
1668
+ return d ? [[s, { text: d.text, trust: d.trust }]] : [];
1669
+ }));
1670
+ asks.push({
1671
+ host,
1672
+ calls,
1673
+ servers: [...first, ...servers.filter((s) => !first.includes(s))],
1674
+ ...suggest ? { suggest } : {},
1675
+ ...Object.keys(about).length ? { about } : {},
1676
+ ...byPath.length ? { byPath } : {}
1677
+ });
1678
+ }
1679
+ return asks;
1680
+ }
1681
+ function aboutOf(a, repo) {
1682
+ const d = a.about?.[repo];
1683
+ if (!d)
1684
+ return "";
1685
+ return d.trust === "suggested" ? `. What it is, as your assistant drafted it (unconfirmed): ${d.text}` : `. What it is: ${d.text}`;
1686
+ }
1687
+ function gatewayHostFix(host, byPath) {
1688
+ const repos = byPath.map((b) => b.repo);
1689
+ return `${repos.length === 1 ? `${repos[0]}'s routes serve` : `The routes of ${repos.join(", ")} serve`} the paths the calls to ${host} make, and no repo lists ${host}: it looks like a shared gateway's host. Once, not per call: list ${host} under hosts: on each proxy repo in repos.manifest.yaml (${repos.join(", ")}, and any other proxy on it); the path then picks the proxy, and this question retires itself`;
1690
+ }
1691
+ function hostQuestionDrafts(asks) {
1692
+ return asks.map((a) => {
1693
+ const repo = a.calls[0].repo;
1694
+ const byPath = new Map((a.byPath ?? []).map((b) => [b.repo, b.serves]));
1695
+ return {
1696
+ repo,
1697
+ ...a.byPath?.length ? { byPath: a.byPath } : {},
1698
+ draft: {
1699
+ question: hostQuestionText(a.host),
1700
+ options: [
1701
+ ...a.servers.map((s) => ({
1702
+ label: s,
1703
+ means: (a.suggest?.repo === s ? `${s} serves HTTP, and its ${a.suggest.at} sets the port ${a.host.split(":").pop()} (${a.suggest.line})` : byPath.has(s) ? `${s} serves ${byPath.get(s)}, a path the calls to ${a.host} make` : `${s} serves HTTP`) + aboutOf(a, s),
1704
+ changes: byPath.has(s) ? `${a.host} goes under hosts for ${s} in repos.manifest.yaml, and the calls to it join ${s} on the next scan; on a shared gateway host, list it on each proxy repo instead (${[...byPath.keys()].join(", ")}, and any other proxy on it), and the path picks the proxy` : `${a.host} goes under hosts for ${s} in repos.manifest.yaml, and the calls to it join ${s} on the next scan`
1705
+ })),
1706
+ // O1: a system outside the estate, declared in the profile with the host as its alias.
1707
+ ...[
1708
+ [HOSTS_OUTSIDE_INTERNAL, "internal", "another team's system"],
1709
+ [HOSTS_OUTSIDE_VENDOR, "vendor", "a vendor's system"]
1710
+ ].map(([label2, boundary, what2]) => ({
1711
+ label: label2,
1712
+ means: `${a.host} is ${what2}, outside this estate, that the org pack doesn't name yet`,
1713
+ changes: `A system ${outsideSystemOf(a.host).id} (boundary ${boundary}, alias ${a.host}) goes into the profile, and the calls to ${a.host} go to it on the next scan`
1714
+ })),
1715
+ {
1716
+ label: HOSTS_NONE,
1717
+ means: `Neither a repo of this estate nor a system to add to the org pack answers on ${a.host}`,
1718
+ changes: "Nothing is added to the manifest or the profile; the calls stay loose ends, and this isn't asked again"
1719
+ },
1720
+ // Beta.24 review: every join question offers Ignore from the start.
1721
+ ignoreOption()
1722
+ ],
1723
+ evidence: a.calls.filter((c) => c.repo === repo).slice(0, 3).map((c) => c.at),
1724
+ scope: "repo"
1725
+ }
1726
+ };
1727
+ });
1728
+ }
1729
+
1730
+ // packages/scanner/dist/join-host-questions.js
1731
+ var HTTP_TYPES2 = /* @__PURE__ */ new Set(["rest", "graphql", "soap", "websocket", "sse", "webhook"]);
1732
+ var segs2 = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$*]/.test(x) ? "{}" : x);
1733
+ var servesPath2 = (entry, path) => {
1734
+ const e = segs2(entry);
1735
+ const c = segs2(path);
1736
+ if (!c.length || c.length > e.length)
1737
+ return false;
1738
+ const tail = e.slice(e.length - c.length);
1739
+ return tail.every((x, i) => x === "{}" || c[i] === "{}" || x === c[i]);
1740
+ };
1741
+ var isTokenHost = (host) => !!placeholderIn(host);
1742
+ function joinHostQuestionDrafts(input) {
1743
+ const byHost = /* @__PURE__ */ new Map();
1744
+ for (const a of input.asks) {
1745
+ if (a.reason !== "unknown-host" || !a.host || a.call.repo !== input.repo)
1746
+ continue;
1747
+ if (input.skip?.has(a.call.fact))
1748
+ continue;
1749
+ if (!isTokenHost(a.host) && input.hostsAsked?.has(a.host))
1750
+ continue;
1751
+ byHost.set(a.host, [...byHost.get(a.host) ?? [], a]);
1752
+ }
1753
+ if (!byHost.size)
1754
+ return [];
1755
+ const compRepo = /* @__PURE__ */ new Map();
1756
+ for (const r of input.repos) {
1757
+ compRepo.set(r.component ?? r.id, r.id);
1758
+ for (const m of r.modules ?? [])
1759
+ compRepo.set(m.component, r.id);
1760
+ }
1761
+ const endpoints = input.records.filter((r) => r.kind === "Endpoint" && HTTP_TYPES2.has(r.endpointType));
1762
+ const servers = [
1763
+ ...new Set(endpoints.flatMap((e) => compRepo.has(e.component) ? [compRepo.get(e.component)] : []))
1764
+ ].filter((r) => r !== input.repo).sort(cmpText);
1765
+ const factOf = new Map(input.facts.map((f) => [f.id, f]));
1766
+ const out = [];
1767
+ for (const [host, asks] of [...byHost].sort(([a], [b]) => cmpText(a, b))) {
1768
+ const calls = asks.map((a) => ({ id: a.call.fact, at: a.call.at, f: factOf.get(a.call.fact) })).sort((a, b) => cmpNatural(a.at, b.at) || cmpText(a.id, b.id));
1769
+ const paths = calls.flatMap((c) => c.f?.kind === "call" ? [c.f.path] : []);
1770
+ const byPath = [];
1771
+ for (const r of servers) {
1772
+ const hit = endpoints.find((e) => compRepo.get(e.component) === r && paths.some((p) => servesPath2(e.pathOrTopic, p)));
1773
+ if (hit)
1774
+ byPath.push({
1775
+ repo: r,
1776
+ serves: [hit.method?.toUpperCase(), hit.pathOrTopic].filter(Boolean).join(" ")
1777
+ });
1778
+ }
1779
+ const evidence = [...new Set(calls.map((c) => c.at))].sort(cmpNatural);
1780
+ const factIds = [...new Set(calls.map((c) => c.id))].sort(cmpText);
1781
+ if (!isTokenHost(host)) {
1782
+ const first = byPath.map((b) => b.repo);
1783
+ const ask = {
1784
+ host,
1785
+ calls: evidence.map((at3) => ({ repo: input.repo, at: at3 })),
1786
+ servers: [...first, ...servers.filter((s) => !first.includes(s))],
1787
+ ...byPath.length ? { byPath } : {}
1788
+ };
1789
+ const [d] = hostQuestionDrafts([ask]);
1790
+ if (d)
1791
+ out.push({ step: HOSTS_STEP, host, factIds, draft: d.draft });
1792
+ continue;
1793
+ }
1794
+ const n = factIds.length;
1795
+ const them = n === 1 ? "The call" : `The ${n} calls`;
1796
+ const system = outsideSystemOfJoinHost(host);
1797
+ const rerun = `atticus verify ${input.repo} --write`;
1798
+ const serves2 = new Map(byPath.map((b) => [b.repo, b.serves]));
1799
+ const ranked = [...byPath.map((b) => b.repo), ...servers.filter((s) => !serves2.has(s))];
1800
+ out.push({
1801
+ step: TARGETS_STEP_ID,
1802
+ host,
1803
+ factIds,
1804
+ draft: {
1805
+ // The join's words: for a gateway's token, what to read again (forwardHostQuestion).
1806
+ question: asks[0].question,
1807
+ options: [
1808
+ ...ranked.map((r) => ({
1809
+ label: r,
1810
+ means: serves2.has(r) ? `${r} serves ${serves2.get(r)}, a path the calls on ${host} make` : `${r} serves HTTP`,
1811
+ changes: `${them} on ${host} ${n === 1 ? "joins" : "join"} ${r} when the facts are next written (${rerun})`
1812
+ })),
1813
+ ...[
1814
+ [HOSTS_OUTSIDE_INTERNAL, "internal", "another team's system"],
1815
+ [HOSTS_OUTSIDE_VENDOR, "vendor", "a vendor's system"]
1816
+ ].map(([label2, boundary, what2]) => ({
1817
+ label: label2,
1818
+ means: `${host} stands for ${what2}, outside this estate, that the org pack doesn't name yet`,
1819
+ changes: `A system ${system.id} (${system.name}, boundary ${boundary}) goes into the profile, and ${them.toLowerCase()} on ${host} ${n === 1 ? "goes" : "go"} to it when the facts are next written (${rerun})`
1820
+ })),
1821
+ {
1822
+ label: HOSTS_NONE,
1823
+ means: `Neither a repo of this estate nor a system of the org pack answers on ${host}`,
1824
+ changes: `${them} on ${host} ${n === 1 ? "stays a loose end" : "stay loose ends"}, and this isn't asked again`
1825
+ },
1826
+ ignoreOption()
1827
+ ],
1828
+ evidence,
1829
+ scope: "repo"
1830
+ }
1831
+ });
1832
+ }
1833
+ return out;
1834
+ }
1835
+ var isJoinHostQuestion = (q) => q.askedBy?.step === TARGETS_STEP_ID && joinHostOfQuestion(q) !== void 0;
1836
+ function joinHostTarget(q) {
1837
+ if (!isJoinHostQuestion(q) || q.state !== "answered" || !q.answer)
1838
+ return void 0;
1839
+ if (ignoredAnswer(q))
1840
+ return HOSTS_NONE;
1841
+ const label2 = q.answer.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer.text;
1842
+ if (!label2)
1843
+ return void 0;
1844
+ if (outsideBoundaryOf(label2))
1845
+ return outsideSystemOfJoinHost(joinHostOfQuestion(q)).id;
1846
+ return label2;
1847
+ }
1848
+ function hostsIgnoreCovers(q, call) {
1849
+ if (q.askedBy?.step !== HOSTS_STEP || q.state !== "answered" || !ignoredAnswer(q))
1850
+ return false;
1851
+ return q.repo === call.repo && q.evidence.includes(call.at) || !!call.hostLabel && hostOfQuestion(q) === call.hostLabel;
1852
+ }
1853
+ function staleJoinHostQuestions(input) {
1854
+ const drafted = new Set(input.drafted.map((d) => d.id));
1855
+ const out = [];
1856
+ for (const q of input.open) {
1857
+ if (q.state !== "open" || q.repo !== input.repo || !isJoinHostQuestion(q))
1858
+ continue;
1859
+ if (drafted.has(q.id))
1860
+ continue;
1861
+ const host = joinHostOfQuestion(q);
1862
+ const by = input.drafted.filter((d) => d.host === host).map((d) => d.id);
1863
+ if (by.length) {
1864
+ out.push({
1865
+ id: q.id,
1866
+ why: `the calls on ${host} are asked now in ${by.join(", ")}`,
1867
+ replacedBy: by
1868
+ });
1869
+ continue;
1870
+ }
1871
+ const at3 = new Set(q.evidence);
1872
+ const joined = (input.join?.joins ?? []).filter((j) => j.call.repo === input.repo && at3.has(j.call.at));
1873
+ const outside = (input.join?.outside ?? []).filter((o) => o.call.repo === input.repo && at3.has(o.call.at));
1874
+ const how = [
1875
+ .../* @__PURE__ */ new Set([
1876
+ ...joined.map((j) => `joins ${j.entry.component} in ${j.entry.repo}`),
1877
+ ...outside.map((o) => `goes to ${o.target}, outside the estate`)
1878
+ ])
1879
+ ].sort(cmpText);
1880
+ out.push({
1881
+ id: q.id,
1882
+ why: how.length ? `the join no longer asks about ${host}: the call ${how.join("; ")}` : `the join no longer asks about ${host}: no call of ${input.repo} goes there now`
1883
+ });
1884
+ }
1885
+ return out.sort((a, b) => cmpText(a.id, b.id));
1886
+ }
1887
+ async function joinAnswerQuestions(root) {
1888
+ const of = (step) => listQuestions(root, { step }).then((r) => r.questions, () => []);
1889
+ return [...await of(TARGETS_STEP_ID), ...await of(HOSTS_STEP)];
1487
1890
  }
1488
1891
 
1489
- // packages/scanner/dist/facts-scan.js
1490
- import { readFile as readFile4 } from "node:fs/promises";
1491
- import { join as join6 } from "node:path";
1492
-
1493
- // packages/scanner/dist/facts-catalog.js
1494
- import { createHash as createHash2 } from "node:crypto";
1495
-
1496
1892
  // packages/scanner/dist/target-suggest.js
1497
1893
  var TARGETS_MAX_SUGGESTED = 5;
1498
1894
  var TARGETS_ANOTHER = TARGETS_ANOTHER_LABEL;
@@ -1505,18 +1901,18 @@ function nameWords(s) {
1505
1901
  ...new Set(s.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter((w) => w.length >= 3 && !STOP.has(w) && !/^v?\d+$/.test(w)).map((w) => w.length > 4 && w.endsWith("s") && !w.endsWith("ss") ? w.slice(0, -1) : w))
1506
1902
  ];
1507
1903
  }
1508
- var segs = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$]/.test(x) ? "{}" : x);
1904
+ var segs3 = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$]/.test(x) ? "{}" : x);
1509
1905
  var sameSeg = (a, b) => a === "{}" || b === "{}" || a === b;
1510
1906
  var under = (path, prefix) => {
1511
- const a = segs(prefix);
1512
- const b = segs(path);
1907
+ const a = segs3(prefix);
1908
+ const b = segs3(path);
1513
1909
  return a.length > 0 && a.length <= b.length && a.every((x, i) => x === b[i]);
1514
1910
  };
1515
1911
  function serves(entry, call, bases) {
1516
- const e = segs(entry);
1912
+ const e = segs3(entry);
1517
1913
  const tries = [
1518
- segs(call),
1519
- ...bases.filter((b) => under(call, b)).map((b) => segs(call).slice(segs(b).length))
1914
+ segs3(call),
1915
+ ...bases.filter((b) => under(call, b)).map((b) => segs3(call).slice(segs3(b).length))
1520
1916
  ];
1521
1917
  return tries.some((c) => c.length === e.length && c.every((x, i) => sameSeg(x, e[i])));
1522
1918
  }
@@ -1540,7 +1936,10 @@ function hostOf(f, facts) {
1540
1936
  }
1541
1937
  return void 0;
1542
1938
  }
1543
- var answerLabel = (q) => q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text;
1939
+ var answerLabel = (q) => (
1940
+ // Beta.24 review: Ignore names no target, so it is never suggested again.
1941
+ ignoredAnswer(q) ? void 0 : q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text
1942
+ );
1544
1943
  var NOT_A_TARGET = /* @__PURE__ */ new Set(["None of these", TARGETS_SPLIT_LABEL, TARGETS_ANOTHER_LABEL]);
1545
1944
  function candidates(callerRepo, ctx) {
1546
1945
  const manifest = estateRepos(ctx.op).filter((r) => r.id !== callerRepo || !!ctx.only);
@@ -1678,7 +2077,7 @@ function targetSuggestions(f, ctx) {
1678
2077
  },
1679
2078
  {
1680
2079
  from: `the path ${f.path}`,
1681
- words: nameWords(segs(f.path).filter((x) => x !== "{}").join(" ")),
2080
+ words: nameWords(segs3(f.path).filter((x) => x !== "{}").join(" ")),
1682
2081
  weight: 2
1683
2082
  }
1684
2083
  ].filter((x) => x.from && x.words.length);
@@ -1694,8 +2093,10 @@ function targetSuggestions(f, ctx) {
1694
2093
  s.score += n;
1695
2094
  s.why.push(why);
1696
2095
  };
1697
- if (only?.has(c.s.label))
1698
- add(6, "the join found an entry of it that serves the call");
2096
+ if (only?.has(c.s.label)) {
2097
+ const at3 = ctx.onlyAt?.[c.s.label] ?? [];
2098
+ add(6, `the join found an entry of it that serves the call${at3.length ? ` (${at3.join(", ")})` : ""}`);
2099
+ }
1699
2100
  const hit = c.entries.find((e) => (!method || !e.method || e.method === method || e.method === "ANY") && serves(e.path, f.path, c.bases.map((b) => b.path)));
1700
2101
  if (hit && !only) {
1701
2102
  const what2 = [hit.method, hit.path].filter(Boolean).join(" ");
@@ -1952,14 +2353,17 @@ var anotherOption = (op) => {
1952
2353
  function offered(members, facts, records, op, asks, ctx) {
1953
2354
  const merged = /* @__PURE__ */ new Map();
1954
2355
  for (const m of members) {
1955
- const ambiguous = asks?.some((a) => a.reason === "ambiguous" && a.call.repo === m.f.repo && a.call.fact === m.f.id);
2356
+ const ambiguous = asks?.find((a) => a.reason === "ambiguous" && a.call.repo === m.f.repo && a.call.fact === m.f.id);
2357
+ const onlyAt = {};
2358
+ for (const c of ambiguous?.candidates ?? [])
2359
+ (onlyAt[c.component] ??= []).push(c.at);
1956
2360
  for (const s of targetSuggestions(m.f, {
1957
2361
  op,
1958
2362
  records,
1959
2363
  facts,
1960
2364
  ...ctx.estate ? { estate: ctx.estate } : {},
1961
2365
  ...ctx.questions ? { questions: ctx.questions } : {},
1962
- ...ambiguous ? { only: m.servers } : {}
2366
+ ...ambiguous ? { only: m.servers, onlyAt } : {}
1963
2367
  })) {
1964
2368
  const x = merged.get(s.label);
1965
2369
  if (!x)
@@ -1995,7 +2399,9 @@ function targetQuestionDrafts(facts, records, op, asks, ctx = {}) {
1995
2399
  label: TARGETS_NONE,
1996
2400
  means: "Nothing in the estate or the org pack's systems answers it",
1997
2401
  changes: "The call stays a loose end, and this isn't asked again"
1998
- }
2402
+ },
2403
+ // Beta.24 review: every join question offers Ignore from the start.
2404
+ ignoreOption()
1999
2405
  ],
2000
2406
  evidence: q.evidence,
2001
2407
  scope: "repo"
@@ -2059,7 +2465,7 @@ function targetGroupWordings(repo, f, facts) {
2059
2465
  }
2060
2466
  var repo0 = (members) => members[0].f.repo;
2061
2467
  var byLine = (a, b) => cmpNatural(a, b);
2062
- var answerLabel2 = (q) => q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text;
2468
+ var answerLabel2 = (q) => ignoredAnswer(q) ? TARGETS_NONE : q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text;
2063
2469
  function splitTargetGroups(questions) {
2064
2470
  return new Set(questions.filter((q) => q.askedBy?.step === TARGETS_STEP && q.state === "answered" && answerLabel2(q) === TARGETS_SPLIT).map((q) => q.question.trim()));
2065
2471
  }
@@ -2104,7 +2510,8 @@ function groupedTargetDrafts(facts, records, op, asks, o) {
2104
2510
  label: TARGETS_NONE,
2105
2511
  means: "Nothing in the estate or the org pack's systems answers any of them",
2106
2512
  changes: "The calls stay loose ends, and this isn't asked again"
2107
- }
2513
+ },
2514
+ ignoreOption()
2108
2515
  ],
2109
2516
  evidence,
2110
2517
  scope: "repo"
@@ -2185,6 +2592,8 @@ function targetsFromAnswers(repo, facts, questions, o = {}) {
2185
2592
  for (const q of [...questions].filter((x) => x.askedBy?.step === TARGETS_STEP && x.state === "answered" && !!x.answer && typeof x.question === "string").sort((a, b) => cmpText(a.answer.at, b.answer.at) || cmpText(a.id, b.id)))
2186
2593
  groups.set(q.question.trim(), q);
2187
2594
  const ruled = ruledTargets(repo, facts, questions, o);
2595
+ const joinHosts = questions.filter((x) => x.repo === repo && isJoinHostQuestion(x) && x.state === "answered").sort((a, b) => cmpText(b.answer.at, a.answer.at) || cmpText(a.id, b.id));
2596
+ const ignoredHosts = questions.filter((x) => x.askedBy?.step === HOSTS_STEP && x.state === "answered" && !!ignoredAnswer(x));
2188
2597
  const out = {};
2189
2598
  for (const f of [...facts].sort((a, b) => cmpText(a.id, b.id))) {
2190
2599
  if (f.kind !== "call")
@@ -2199,6 +2608,21 @@ function targetsFromAnswers(repo, facts, questions, o = {}) {
2199
2608
  }
2200
2609
  let label2 = asked && asked.state === "answered" && asked.answer ? answerLabel2(asked) : void 0;
2201
2610
  let byAi = label2 && asked?.answer && isAiBy(asked.answer.by) ? asked.answer.by : void 0;
2611
+ const at3 = q.evidence[0];
2612
+ if (!label2 || label2 === TARGETS_SPLIT || label2 === TARGETS_ANOTHER) {
2613
+ const jh = joinHosts.find((x) => x.evidence.includes(at3) && !!joinHostTarget(x));
2614
+ if (jh) {
2615
+ label2 = joinHostTarget(jh);
2616
+ byAi = jh.answer && isAiBy(jh.answer.by) ? jh.answer.by : void 0;
2617
+ } else if (ignoredHosts.length) {
2618
+ const url = urlOf(f, facts);
2619
+ const hostLabel = url ? callHostLabel(url) : void 0;
2620
+ if (ignoredHosts.some((x) => hostsIgnoreCovers(x, { repo, at: at3, hostLabel }))) {
2621
+ label2 = TARGETS_NONE;
2622
+ byAi = void 0;
2623
+ }
2624
+ }
2625
+ }
2202
2626
  if (!label2 || label2 === TARGETS_SPLIT || label2 === TARGETS_ANOTHER) {
2203
2627
  label2 = ruled.get(f.id)?.label;
2204
2628
  byAi = void 0;
@@ -2872,7 +3296,7 @@ async function factsForScan(root, op, repo, commit, readerRecords, at3 = {}) {
2872
3296
  const left = report.rejected.length;
2873
3297
  carriedSaid = `; ${report.carried.length} carried from commit ${from} to ${commit.slice(0, 7)} (the files they cite are unchanged, their lines checked again)${left ? `, ${left} left out until read again (they cite a file changed since, or name a fact that does: /atticus-map ${repo}, then atticus verify ${repo} --write)` : ""}`;
2874
3298
  }
2875
- const questions = (await listQuestions(root, { step: TARGETS_STEP }).catch(() => ({ questions: [] }))).questions;
3299
+ const questions = await joinAnswerQuestions(root);
2876
3300
  const targets = targetsFromAnswers(repo, facts, questions, {
2877
3301
  repoType: estateRepos(op).find((r) => r.id === repo)?.type
2878
3302
  });
@@ -2923,7 +3347,7 @@ async function estateFacts(root, op, except) {
2923
3347
  const pairs = {};
2924
3348
  const notes = [];
2925
3349
  const unverified = [];
2926
- const questions = (await listQuestions(root, { step: TARGETS_STEP }).catch(() => ({ questions: [] }))).questions;
3350
+ const questions = await joinAnswerQuestions(root);
2927
3351
  for (const r of productionRepos(op)) {
2928
3352
  if (r.id === except)
2929
3353
  continue;
@@ -4661,7 +5085,7 @@ function parseEntry(s) {
4661
5085
  const m = /^([A-Za-z]+)\s+(\S+)$/.exec(s.trim());
4662
5086
  return m ? { method: m[1].toUpperCase(), path: m[2] } : { path: s.trim() };
4663
5087
  }
4664
- var segs2 = (p) => normalizePath(p).toLowerCase().split("/").filter(Boolean);
5088
+ var segs4 = (p) => normalizePath(p).toLowerCase().split("/").filter(Boolean);
4665
5089
  var sameMethod = (a, b) => !a || !b || a.toUpperCase() === b.toUpperCase();
4666
5090
  async function joinEstate(o) {
4667
5091
  const byId = new Map(o.records.map((r) => [r.id, r]));
@@ -4673,8 +5097,8 @@ async function joinEstate(o) {
4673
5097
  const out = [i.normalizedPath];
4674
5098
  const route = i.route ? byId.get(i.route) : void 0;
4675
5099
  if (route?.kind === "GatewayRoute") {
4676
- const base2 = segs2(route.basepath);
4677
- const p = segs2(i.normalizedPath);
5100
+ const base2 = segs4(route.basepath);
5101
+ const p = segs4(i.normalizedPath);
4678
5102
  if (base2.length && base2.every((s, k) => p[k] === s))
4679
5103
  out.push(`/${p.slice(base2.length).join("/")}`);
4680
5104
  }
@@ -5036,219 +5460,6 @@ function fieldLineage(f, field) {
5036
5460
  return out;
5037
5461
  }
5038
5462
 
5039
- // packages/scanner/dist/hosts-asked.js
5040
- var segs3 = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$]/.test(x) ? "{}" : x);
5041
- var underPath = (path, base2) => {
5042
- const b = segs3(base2);
5043
- const c = segs3(path);
5044
- return b.length > 0 && b.length <= c.length && b.every((x, i) => x === c[i]);
5045
- };
5046
- var servesPath = (entry, path) => {
5047
- const e = segs3(entry);
5048
- const c = segs3(path);
5049
- return e.length === c.length && e.every((x, i) => x === "{}" || c[i] === "{}" || x === c[i]);
5050
- };
5051
- var HTTP_TYPES = /* @__PURE__ */ new Set(["rest", "graphql", "soap", "websocket", "sse", "webhook"]);
5052
- var CONFIG_FILES = [
5053
- "**/application*.properties",
5054
- "**/application*.yml",
5055
- "**/application*.yaml",
5056
- "**/bootstrap*.properties",
5057
- "**/bootstrap*.yml",
5058
- "**/bootstrap*.yaml",
5059
- "**/.env",
5060
- "**/.env.*",
5061
- "**/Dockerfile",
5062
- "**/docker-compose*.yml",
5063
- "**/docker-compose*.yaml",
5064
- "**/compose*.yml",
5065
- "**/compose*.yaml",
5066
- "**/package.json"
5067
- ];
5068
- function lineSetsPort(line, port) {
5069
- const p = String(port);
5070
- const end = "(?![0-9])";
5071
- return [
5072
- new RegExp(`port["']?\\s*[:=]\\s*["']?${p}${end}`, "i"),
5073
- new RegExp(`^\\s*EXPOSE\\s+(?:[0-9]+(?:/[a-z]+)?\\s+)*${p}${end}`, "i"),
5074
- new RegExp(`--port[=\\s]+${p}${end}`, "i"),
5075
- new RegExp(`(?:^|[\\s"'-])${p}:[0-9]+`)
5076
- ].some((re) => re.test(line));
5077
- }
5078
- function callHost(url) {
5079
- if (url.includes("${"))
5080
- return void 0;
5081
- const hp = urlHostPort(url);
5082
- if (!hp || !hp.host)
5083
- return void 0;
5084
- const explicit = /^[a-z][a-z0-9+.-]*:\/\/(?:[^/@?#]*@)?[^/:?#]+:(\d+)/i.exec(url);
5085
- return {
5086
- label: explicit ? `${hp.host}:${explicit[1]}` : hp.host,
5087
- host: hp.host,
5088
- ...hp.port !== void 0 ? { port: hp.port } : {}
5089
- };
5090
- }
5091
- async function unknownHosts(o) {
5092
- const patterns = o.repos.flatMap((r) => [
5093
- ...r.hosts,
5094
- ...(r.modules ?? []).flatMap((m) => m.hosts)
5095
- ]);
5096
- const byHost = /* @__PURE__ */ new Map();
5097
- for (const r of o.records) {
5098
- if (r.kind !== "Unresolved" || r.unresolvedKind !== "http-call")
5099
- continue;
5100
- const url = r.raw.slice(r.raw.indexOf(" ") + 1);
5101
- const h = callHost(url);
5102
- if (!h)
5103
- continue;
5104
- if (patterns.some((p) => hostMatches(p, h.host, h.port)))
5105
- continue;
5106
- const e = r.evidence[0];
5107
- const repo = e?.repo ?? r.owner;
5108
- if (!e?.path || e.line === void 0 || !repo)
5109
- continue;
5110
- const entry = byHost.get(h.label) ?? {
5111
- ...h.port !== void 0 ? { port: h.port } : {},
5112
- explicit: h.label !== h.host,
5113
- calls: [],
5114
- paths: /* @__PURE__ */ new Set()
5115
- };
5116
- const path = /^[a-z][a-z0-9+.-]*:\/\/[^/?#]*(\/[^?#]*)?/i.exec(url)?.[1];
5117
- if (path)
5118
- entry.paths.add(path);
5119
- const at3 = `${e.path}:${e.line}`;
5120
- if (!entry.calls.some((c) => c.repo === repo && c.at === at3))
5121
- entry.calls.push({ repo, at: at3 });
5122
- byHost.set(h.label, entry);
5123
- }
5124
- if (byHost.size === 0)
5125
- return [];
5126
- const compRepo = /* @__PURE__ */ new Map();
5127
- for (const r of o.repos) {
5128
- compRepo.set(r.component ?? r.id, r.id);
5129
- for (const m of r.modules ?? [])
5130
- compRepo.set(m.component, r.id);
5131
- }
5132
- const serving = /* @__PURE__ */ new Set();
5133
- for (const r of o.records)
5134
- if (r.kind === "Endpoint" && HTTP_TYPES.has(r.endpointType)) {
5135
- const repo = compRepo.get(r.component);
5136
- if (repo)
5137
- serving.add(repo);
5138
- }
5139
- const servers = [...serving].sort();
5140
- const configs = /* @__PURE__ */ new Map();
5141
- const configOf = async (repo) => {
5142
- if (configs.has(repo))
5143
- return configs.get(repo);
5144
- const h = o.handle(repo);
5145
- const out = [];
5146
- if (h)
5147
- for await (const path of h.listFiles(CONFIG_FILES)) {
5148
- const t = await h.readText(path).catch(() => void 0);
5149
- if (t !== void 0)
5150
- out.push({ path, lines: t.replace(/\r\n?/g, "\n").split("\n") });
5151
- }
5152
- configs.set(repo, out);
5153
- return out;
5154
- };
5155
- const asks = [];
5156
- for (const [host, entry] of [...byHost.entries()].sort(([a], [b]) => cmpText(a, b))) {
5157
- if (servers.length === 0)
5158
- continue;
5159
- const hits = [];
5160
- if (entry.explicit && entry.port !== void 0)
5161
- for (const repo of servers) {
5162
- hit: for (const f of await configOf(repo))
5163
- for (const [i, l] of f.lines.entries())
5164
- if (lineSetsPort(l, entry.port)) {
5165
- hits.push({ repo, at: `${f.path}:${i + 1}`, line: l.trim() });
5166
- break hit;
5167
- }
5168
- }
5169
- const suggest = hits.length === 1 ? hits[0] : void 0;
5170
- const calls = entry.calls.sort((a, b) => cmpText(a.repo, b.repo) || cmpNatural(a.at, b.at));
5171
- const byPath = [];
5172
- for (const g of o.records) {
5173
- if (g.kind !== "GatewayRoute")
5174
- continue;
5175
- const repo = g.evidence.find((e) => e.repo)?.repo;
5176
- if (!repo || byPath.some((b) => b.repo === repo))
5177
- continue;
5178
- const under2 = [...entry.paths].filter((p) => underPath(p, g.basepath));
5179
- if (!under2.length)
5180
- continue;
5181
- const comps = new Set([...compRepo].filter(([, r]) => r === repo).map(([c]) => c));
5182
- const hit = o.records.find((r) => r.kind === "Endpoint" && comps.has(r.component) && under2.some((p) => servesPath(r.pathOrTopic, p)));
5183
- byPath.push({
5184
- repo,
5185
- serves: hit ? [hit.method?.toUpperCase(), hit.pathOrTopic].filter(Boolean).join(" ") : `the routes under ${g.basepath}`
5186
- });
5187
- }
5188
- byPath.sort((a, b) => cmpText(a.repo, b.repo));
5189
- const first = suggest ? [suggest.repo] : byPath.map((b) => b.repo).filter((x) => servers.includes(x));
5190
- const about = Object.fromEntries(servers.flatMap((s) => {
5191
- const d = o.repos.find((r) => r.id === s)?.description;
5192
- return d ? [[s, { text: d.text, trust: d.trust }]] : [];
5193
- }));
5194
- asks.push({
5195
- host,
5196
- calls,
5197
- servers: [...first, ...servers.filter((s) => !first.includes(s))],
5198
- ...suggest ? { suggest } : {},
5199
- ...Object.keys(about).length ? { about } : {},
5200
- ...byPath.length ? { byPath } : {}
5201
- });
5202
- }
5203
- return asks;
5204
- }
5205
- function aboutOf(a, repo) {
5206
- const d = a.about?.[repo];
5207
- if (!d)
5208
- return "";
5209
- return d.trust === "suggested" ? `. What it is, as your assistant drafted it (unconfirmed): ${d.text}` : `. What it is: ${d.text}`;
5210
- }
5211
- function gatewayHostFix(host, byPath) {
5212
- const repos = byPath.map((b) => b.repo);
5213
- return `${repos.length === 1 ? `${repos[0]}'s routes serve` : `The routes of ${repos.join(", ")} serve`} the paths the calls to ${host} make, and no repo lists ${host}: it looks like a shared gateway's host. Once, not per call: list ${host} under hosts: on each proxy repo in repos.manifest.yaml (${repos.join(", ")}, and any other proxy on it); the path then picks the proxy, and this question retires itself`;
5214
- }
5215
- function hostQuestionDrafts(asks) {
5216
- return asks.map((a) => {
5217
- const repo = a.calls[0].repo;
5218
- const byPath = new Map((a.byPath ?? []).map((b) => [b.repo, b.serves]));
5219
- return {
5220
- repo,
5221
- ...a.byPath?.length ? { byPath: a.byPath } : {},
5222
- draft: {
5223
- question: hostQuestionText(a.host),
5224
- options: [
5225
- ...a.servers.map((s) => ({
5226
- label: s,
5227
- means: (a.suggest?.repo === s ? `${s} serves HTTP, and its ${a.suggest.at} sets the port ${a.host.split(":").pop()} (${a.suggest.line})` : byPath.has(s) ? `${s} serves ${byPath.get(s)}, a path the calls to ${a.host} make` : `${s} serves HTTP`) + aboutOf(a, s),
5228
- changes: byPath.has(s) ? `${a.host} goes under hosts for ${s} in repos.manifest.yaml, and the calls to it join ${s} on the next scan; on a shared gateway host, list it on each proxy repo instead (${[...byPath.keys()].join(", ")}, and any other proxy on it), and the path picks the proxy` : `${a.host} goes under hosts for ${s} in repos.manifest.yaml, and the calls to it join ${s} on the next scan`
5229
- })),
5230
- // O1: a system outside the estate, declared in the profile with the host as its alias.
5231
- ...[
5232
- [HOSTS_OUTSIDE_INTERNAL, "internal", "another team's system"],
5233
- [HOSTS_OUTSIDE_VENDOR, "vendor", "a vendor's system"]
5234
- ].map(([label2, boundary, what2]) => ({
5235
- label: label2,
5236
- means: `${a.host} is ${what2}, outside this estate, that the org pack doesn't name yet`,
5237
- changes: `A system ${outsideSystemOf(a.host).id} (boundary ${boundary}, alias ${a.host}) goes into the profile, and the calls to ${a.host} go to it on the next scan`
5238
- })),
5239
- {
5240
- label: HOSTS_NONE,
5241
- means: `Neither a repo of this estate nor a system to add to the org pack answers on ${a.host}`,
5242
- changes: "Nothing is added to the manifest or the profile; the calls stay loose ends, and this isn't asked again"
5243
- }
5244
- ],
5245
- evidence: a.calls.filter((c) => c.repo === repo).slice(0, 3).map((c) => c.at),
5246
- scope: "repo"
5247
- }
5248
- };
5249
- });
5250
- }
5251
-
5252
5463
  // packages/scanner/dist/measure-links.js
5253
5464
  var import_yaml4 = __toESM(require_dist(), 1);
5254
5465
  var METHODS = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS|TRACE|ANY)\s+(\S.*)$/i;
@@ -5344,12 +5555,12 @@ function parseLinkReference(source) {
5344
5555
  return { ok: true, reference: { ...estate ? { estate } : {}, repos } };
5345
5556
  }
5346
5557
  var stripped = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
5347
- function segs4(path) {
5558
+ function segs5(path) {
5348
5559
  return path.split(/[?#]/)[0].split("/").filter(Boolean).map((s) => /^(\{[^}]*\}|:\w+|\*)$/.test(s) ? "{}" : s.toLowerCase());
5349
5560
  }
5350
5561
  function pathMatch(a, b) {
5351
- const x = segs4(a);
5352
- const y = segs4(b);
5562
+ const x = segs5(a);
5563
+ const y = segs5(b);
5353
5564
  if (x.length === y.length && x.every((s, i) => s === y[i]))
5354
5565
  return 2;
5355
5566
  const [short, long] = x.length < y.length ? [x, y] : [y, x];
@@ -5646,6 +5857,19 @@ export {
5646
5857
  estateMergeInput,
5647
5858
  mergeEstate,
5648
5859
  curatedDirOf,
5860
+ lineSetsPort,
5861
+ tokenHost,
5862
+ callHostLabel,
5863
+ unknownHosts,
5864
+ gatewayHostFix,
5865
+ hostQuestionDrafts,
5866
+ isTokenHost,
5867
+ joinHostQuestionDrafts,
5868
+ isJoinHostQuestion,
5869
+ joinHostTarget,
5870
+ hostsIgnoreCovers,
5871
+ staleJoinHostQuestions,
5872
+ joinAnswerQuestions,
5649
5873
  TARGETS_MAX_SUGGESTED,
5650
5874
  TARGETS_ANOTHER,
5651
5875
  TARGETS_NO_EVIDENCE,
@@ -5728,10 +5952,6 @@ export {
5728
5952
  estateFlow,
5729
5953
  flattenEstateFlow,
5730
5954
  fieldLineage,
5731
- lineSetsPort,
5732
- unknownHosts,
5733
- gatewayHostFix,
5734
- hostQuestionDrafts,
5735
5955
  parseLinkReference,
5736
5956
  measureLinks,
5737
5957
  estateJoinOf,