@maycombhq/atticus 2.0.0-beta.10 → 2.0.0-beta.11

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 (232) hide show
  1. package/dist/bin.js +3 -3
  2. package/dist/{chunk-GZ4TKR3Q.js → chunk-23VFQHFQ.js} +33 -134
  3. package/dist/{chunk-VKMTFIWS.js → chunk-26DBAGOP.js} +18 -18
  4. package/dist/{chunk-PKCMRPPB.js → chunk-27EDZN52.js} +33 -27
  5. package/dist/{chunk-AJJK7GLO.js → chunk-2K2ZEJVR.js} +3 -3
  6. package/dist/{chunk-XRO65C7V.js → chunk-3DDJLI7N.js} +8 -6
  7. package/dist/{chunk-XQ3YIV5R.js → chunk-3LU6YCSQ.js} +6 -6
  8. package/dist/{chunk-XTVDAHH2.js → chunk-3WU7LVTL.js} +5 -5
  9. package/dist/{chunk-6GNS32SI.js → chunk-4AYZQ3SY.js} +4 -4
  10. package/dist/{chunk-6VBXAGJX.js → chunk-4ONORLK5.js} +14 -14
  11. package/dist/{chunk-7TGYNOXD.js → chunk-4URR24DD.js} +7 -7
  12. package/dist/{chunk-CIUHAHM6.js → chunk-4UZJOQYK.js} +8 -8
  13. package/dist/chunk-4Y4FY34K.js +34 -0
  14. package/dist/{chunk-52R2YXP5.js → chunk-4YWRU7JK.js} +16 -16
  15. package/dist/chunk-52WCHTVZ.js +41 -0
  16. package/dist/{chunk-YIEOFHOL.js → chunk-55TBYJF2.js} +17 -11
  17. package/dist/{chunk-MH5OCRUM.js → chunk-5ACUW753.js} +2 -2
  18. package/dist/chunk-5BJFMAQU.js +32 -0
  19. package/dist/{chunk-YPBQNJHA.js → chunk-5ICB2BXH.js} +8 -8
  20. package/dist/{chunk-YGKYFMSL.js → chunk-5NZSJ5ZG.js} +3 -3
  21. package/dist/{chunk-YPIEYQF4.js → chunk-5P5BGG5L.js} +6 -6
  22. package/dist/{chunk-B7434AE2.js → chunk-5RUMHLIS.js} +2 -2
  23. package/dist/{chunk-5MI2SEV5.js → chunk-5TY4DTHQ.js} +3 -3
  24. package/dist/{chunk-NIXVDQVO.js → chunk-5V5BJACL.js} +2 -2
  25. package/dist/{chunk-7DUDLVFJ.js → chunk-6E2GJANQ.js} +20 -20
  26. package/dist/{chunk-RK6MKKKP.js → chunk-6N2GUZMZ.js} +1 -1
  27. package/dist/{chunk-LK44ULGI.js → chunk-6RGIM2ZH.js} +32 -6
  28. package/dist/{chunk-OS7PQ35Z.js → chunk-6V3DTQWK.js} +22 -22
  29. package/dist/{chunk-OSGQW2Z6.js → chunk-77RSRG3A.js} +8 -8
  30. package/dist/{chunk-5YIBJXGB.js → chunk-7A7IG7OA.js} +10 -10
  31. package/dist/{chunk-YLAJAI2W.js → chunk-7HQOZALR.js} +11 -11
  32. package/dist/{chunk-XB5RFZHH.js → chunk-7HWXYP4H.js} +12 -12
  33. package/dist/{chunk-PIVKU64W.js → chunk-7J7UY46S.js} +2 -2
  34. package/dist/{chunk-62YMDXY6.js → chunk-7KXYMC2P.js} +16 -16
  35. package/dist/{chunk-23M2LUYM.js → chunk-7LCQ7JAM.js} +1 -1
  36. package/dist/{chunk-5XN76FTF.js → chunk-7RGCQ4VZ.js} +5 -5
  37. package/dist/{chunk-CHC5FKTU.js → chunk-7RUMD56V.js} +1 -1
  38. package/dist/{chunk-IUD3ME4E.js → chunk-7S3XFWOU.js} +4 -4
  39. package/dist/{chunk-ZONE6E3Z.js → chunk-7SZPENUP.js} +2 -2
  40. package/dist/{chunk-T6USVBEJ.js → chunk-7VFVQX5K.js} +5 -5
  41. package/dist/chunk-ACWQDL6T.js +37 -0
  42. package/dist/{chunk-AKJTKMXU.js → chunk-ANCI3LFS.js} +5 -5
  43. package/dist/{chunk-B3O52AUQ.js → chunk-ASKDCMW5.js} +4 -4
  44. package/dist/chunk-ATNG5VOZ.js +122 -0
  45. package/dist/{chunk-I7IWQIEB.js → chunk-B3QOYE74.js} +4 -4
  46. package/dist/chunk-B3UHYXHU.js +41 -0
  47. package/dist/{chunk-GXJVY6WT.js → chunk-BA5DTXHQ.js} +5 -5
  48. package/dist/{chunk-5XDNUJ4P.js → chunk-BKFGGJKA.js} +2 -2
  49. package/dist/{chunk-DDAHCPGA.js → chunk-BQNEHB5U.js} +12 -12
  50. package/dist/{chunk-P3TKKBAH.js → chunk-BUWSOQLU.js} +4 -4
  51. package/dist/{chunk-X4W4XXWP.js → chunk-BX52REMA.js} +5 -5
  52. package/dist/{chunk-4SVJNVEE.js → chunk-BXBCMGIQ.js} +2 -0
  53. package/dist/{chunk-CRE4BJHM.js → chunk-C2YGYTU6.js} +23 -23
  54. package/dist/{chunk-7URGP4DD.js → chunk-C5JFMAXX.js} +12 -12
  55. package/dist/chunk-C75W7VXX.js +42 -0
  56. package/dist/{chunk-NGPU2ARF.js → chunk-CAN3EBE5.js} +1 -1
  57. package/dist/{chunk-FR7JPYBD.js → chunk-CE4S5ZY3.js} +12 -12
  58. package/dist/{chunk-BMHGA7WD.js → chunk-CRQ73DIF.js} +12 -12
  59. package/dist/{chunk-KIAI6PWL.js → chunk-CZI2ACNT.js} +17 -17
  60. package/dist/chunk-D7MWYJZF.js +43 -0
  61. package/dist/chunk-DDAEAZEV.js +54 -0
  62. package/dist/{chunk-G2E5MNYP.js → chunk-DGKNOPSE.js} +7 -7
  63. package/dist/{chunk-UF7TAFJM.js → chunk-DQNKG4HY.js} +18 -18
  64. package/dist/{chunk-6TJCUYC5.js → chunk-DS3ZEJVN.js} +3 -3
  65. package/dist/{chunk-3QAKDIEU.js → chunk-DYWTQXP4.js} +23 -23
  66. package/dist/chunk-E25G46RW.js +54 -0
  67. package/dist/{chunk-F2FOQLJ7.js → chunk-EAQFRD2B.js} +6 -6
  68. package/dist/{chunk-W5OYJMBT.js → chunk-EATSD7YD.js} +5 -5
  69. package/dist/{chunk-YGR6OCHQ.js → chunk-EBWIOODZ.js} +8 -14
  70. package/dist/{chunk-LVGBKKSM.js → chunk-EHUYLNLC.js} +15 -15
  71. package/dist/{chunk-IDGSU7JF.js → chunk-EI4KQYJ3.js} +9 -9
  72. package/dist/{chunk-FQSRHTTC.js → chunk-EQOSXLK3.js} +15 -15
  73. package/dist/{chunk-KC5DROFC.js → chunk-EV4TEFOD.js} +14 -14
  74. package/dist/{chunk-2KDSXJFJ.js → chunk-EW7MRMD5.js} +24 -6
  75. package/dist/{chunk-FZL2HNWP.js → chunk-EZSZFI54.js} +3 -3
  76. package/dist/{chunk-MKRBG5EF.js → chunk-FMRMTI7W.js} +1 -1
  77. package/dist/{chunk-E3JYO547.js → chunk-FOQXYMOR.js} +20 -20
  78. package/dist/{chunk-G5SFOH7P.js → chunk-G3PBLW4K.js} +8 -18
  79. package/dist/{chunk-2XM6PYQQ.js → chunk-G7WZH54P.js} +33 -11
  80. package/dist/{chunk-FTV6I76U.js → chunk-GG6HIU74.js} +25 -25
  81. package/dist/{chunk-6EDQE7GO.js → chunk-GMJXC5AL.js} +2 -2
  82. package/dist/chunk-GPLFYLGH.js +130 -0
  83. package/dist/{chunk-UR7RMZ3R.js → chunk-GVFUEGGM.js} +2 -2
  84. package/dist/{chunk-WGZWR4RF.js → chunk-GWSWS264.js} +5 -5
  85. package/dist/{chunk-NPCD54I7.js → chunk-H4VJO3M2.js} +8 -5
  86. package/dist/{chunk-73VPWF5R.js → chunk-HGQZTUAC.js} +4 -4
  87. package/dist/{chunk-2RX7PI2Y.js → chunk-HOUUBE74.js} +4 -4
  88. package/dist/{chunk-BDEKREZH.js → chunk-HQMCHHY5.js} +3 -3
  89. package/dist/{chunk-DPHCFZ7W.js → chunk-HR4DVO6X.js} +3 -3
  90. package/dist/chunk-HZYFLEWO.js +39 -0
  91. package/dist/chunk-IA2RKC6I.js +279 -0
  92. package/dist/{chunk-AY2IUF4K.js → chunk-IILZ7J3L.js} +541 -64
  93. package/dist/chunk-IRW64JFF.js +247 -0
  94. package/dist/{chunk-BJPMKJTL.js → chunk-IVHN2VYG.js} +100 -2
  95. package/dist/{chunk-OEI7LVRP.js → chunk-IWZPGIGT.js} +24 -24
  96. package/dist/{chunk-QICFHVRW.js → chunk-IY4PHPHT.js} +4 -4
  97. package/dist/{chunk-ZE3P35DA.js → chunk-J27QGXO4.js} +9 -9
  98. package/dist/{chunk-BMCKL3VQ.js → chunk-JBSD57N7.js} +24 -24
  99. package/dist/{chunk-67J3VZBA.js → chunk-JEUXCIRD.js} +5 -5
  100. package/dist/{chunk-577AJVRS.js → chunk-JMOLB347.js} +1976 -282
  101. package/dist/{chunk-7EKESFWV.js → chunk-JQX6BSE4.js} +11 -11
  102. package/dist/{chunk-YXJ4XOHF.js → chunk-JRPQX2EK.js} +4 -4
  103. package/dist/{chunk-MTEBM4Y4.js → chunk-JUQHYTXN.js} +18 -12
  104. package/dist/{chunk-APSVL2AI.js → chunk-JUZ75OG4.js} +15 -15
  105. package/dist/{chunk-7GB4ZRE2.js → chunk-KIWEBM6G.js} +12 -12
  106. package/dist/{chunk-KM2FBM3T.js → chunk-KLKENMWQ.js} +282 -50
  107. package/dist/chunk-KQK6SQPE.js +48 -0
  108. package/dist/{chunk-TM7LC37P.js → chunk-KQRYW7OS.js} +179 -115
  109. package/dist/{chunk-65C57N7P.js → chunk-KU4T2CXJ.js} +19 -19
  110. package/dist/{chunk-GFXLPJWY.js → chunk-KXZR2BLL.js} +2 -2
  111. package/dist/{chunk-MGVYVW7Q.js → chunk-L7I5PKGD.js} +1 -1
  112. package/dist/{chunk-XKS6THI5.js → chunk-LDIARP6F.js} +2 -2
  113. package/dist/{chunk-NNUASOAA.js → chunk-LEHZTKB3.js} +12 -12
  114. package/dist/{chunk-FJCFYKVO.js → chunk-LS3WR2RF.js} +86 -29
  115. package/dist/{chunk-Y4BRGOJR.js → chunk-LUPW4WLK.js} +13 -10
  116. package/dist/{chunk-HE4ZQXZM.js → chunk-LVBPY2M6.js} +14 -4
  117. package/dist/{chunk-EX6ZXS5K.js → chunk-LZWVK4YY.js} +4 -4
  118. package/dist/chunk-MCWWMMLN.js +48 -0
  119. package/dist/{chunk-BXIX7S7O.js → chunk-MKC7P5LD.js} +15 -15
  120. package/dist/{chunk-JQ7XQPQS.js → chunk-MKIULIUQ.js} +4 -4
  121. package/dist/{chunk-D3PO4DOZ.js → chunk-MMB2OHUY.js} +4 -2
  122. package/dist/{chunk-MTAUZW2Z.js → chunk-MQNBEO3N.js} +210 -104
  123. package/dist/{chunk-4PJADZRR.js → chunk-MSL3CLHX.js} +16 -16
  124. package/dist/{chunk-5KTOPOEP.js → chunk-MV4637YA.js} +25 -25
  125. package/dist/{chunk-WARBF2KY.js → chunk-MYKQVS5W.js} +4 -4
  126. package/dist/{chunk-4QUQEBFT.js → chunk-MYOW3RPC.js} +6 -6
  127. package/dist/{chunk-ROTY5J2L.js → chunk-NBGBMRIS.js} +1 -1
  128. package/dist/{chunk-BUYJL3GJ.js → chunk-NBQO75XT.js} +1 -1
  129. package/dist/chunk-NCR24CPV.js +41 -0
  130. package/dist/chunk-NDW4ROST.js +38 -0
  131. package/dist/{chunk-AWECWW5Y.js → chunk-NELU7LSL.js} +13 -11
  132. package/dist/{chunk-R64GLVBO.js → chunk-NG5R2WIY.js} +10 -10
  133. package/dist/{chunk-ZZXF6OOJ.js → chunk-NH5QH3WS.js} +2 -2
  134. package/dist/{chunk-XIWYUQZQ.js → chunk-NIYB5K5B.js} +9 -9
  135. package/dist/{chunk-LDKUC2QJ.js → chunk-NR5T46ZY.js} +17 -17
  136. package/dist/{chunk-PEF5OEMB.js → chunk-NX6QEEOA.js} +4 -4
  137. package/dist/{chunk-OGRWQ562.js → chunk-O6ILVBYB.js} +2 -2
  138. package/dist/{chunk-Y7KBQ4BD.js → chunk-OFWYZH6B.js} +22 -22
  139. package/dist/{chunk-N3NBWIYQ.js → chunk-OHXTB6CO.js} +11 -9
  140. package/dist/chunk-OJN7WME4.js +34 -0
  141. package/dist/{chunk-2HMWX4T6.js → chunk-OR5VRULZ.js} +11 -11
  142. package/dist/{chunk-UBWCUP3G.js → chunk-ORZSD2KD.js} +2 -2
  143. package/dist/{chunk-V2TH46ZY.js → chunk-OXVVRJDQ.js} +12 -12
  144. package/dist/{chunk-7YYEKTYF.js → chunk-PQW7PYUR.js} +8 -8
  145. package/dist/{chunk-EZIUFEN6.js → chunk-Q32Y5T2U.js} +12 -12
  146. package/dist/{chunk-FOGG4AUR.js → chunk-QWHTTA2X.js} +23 -7
  147. package/dist/{chunk-HKTUIMH4.js → chunk-R3RVFCJ2.js} +3 -3
  148. package/dist/{chunk-J5LHDJU4.js → chunk-R3VFLYZZ.js} +7 -7
  149. package/dist/{chunk-QKEFZRHS.js → chunk-R6UTCLH5.js} +17 -17
  150. package/dist/{chunk-SS66Q4VE.js → chunk-RB2VSED2.js} +12 -12
  151. package/dist/chunk-REWZE2XI.js +53 -0
  152. package/dist/{chunk-MF7QH4AX.js → chunk-RIEFYHXI.js} +5 -5
  153. package/dist/{chunk-7F2RUWPU.js → chunk-RJDP642F.js} +1 -1
  154. package/dist/{chunk-YFSSNGLR.js → chunk-RWMSJP7H.js} +31 -29
  155. package/dist/{chunk-JMSEEBN4.js → chunk-S2FDPN32.js} +1 -1
  156. package/dist/chunk-S5LSDXV4.js +40 -0
  157. package/dist/{chunk-OJLRFGBP.js → chunk-S7ZWCMDO.js} +79 -15
  158. package/dist/{chunk-ILFKECGI.js → chunk-SG5KY4VB.js} +4 -4
  159. package/dist/{chunk-FEZE6NIA.js → chunk-SH7AZZDA.js} +18 -18
  160. package/dist/{chunk-E3Z67HRK.js → chunk-SILY6ZEZ.js} +4 -4
  161. package/dist/{chunk-5IALSMZ2.js → chunk-SINJKQSI.js} +14 -14
  162. package/dist/chunk-SIUDWWKS.js +47 -0
  163. package/dist/{chunk-XEG3FE2R.js → chunk-SKMHS4CL.js} +1 -1
  164. package/dist/chunk-SNHOLLGN.js +280 -0
  165. package/dist/{chunk-LTQANUDH.js → chunk-SUQZGPVG.js} +25 -25
  166. package/dist/{chunk-47QE246J.js → chunk-T6ESD5KM.js} +5 -5
  167. package/dist/{chunk-YVLMBAYE.js → chunk-TC3KTG33.js} +3 -3
  168. package/dist/{chunk-IV7BCWWN.js → chunk-TCADP67G.js} +3 -3
  169. package/dist/{chunk-6JLPXDWN.js → chunk-TEBBD4XH.js} +5 -5
  170. package/dist/{chunk-F7UQR4ZX.js → chunk-TGEOLIAK.js} +3 -3
  171. package/dist/{chunk-FMKKVWZD.js → chunk-TQYBXDVH.js} +2 -2
  172. package/dist/{chunk-TZDSDDSV.js → chunk-TZXHUDI6.js} +2 -2
  173. package/dist/{chunk-YMOJD5BO.js → chunk-U5PDQTLA.js} +3 -3
  174. package/dist/{chunk-CNKGYDMG.js → chunk-U6YKL7SI.js} +23 -23
  175. package/dist/{chunk-7UKVYFQ2.js → chunk-UABFFMWH.js} +8 -8
  176. package/dist/{chunk-XPEEICAO.js → chunk-UFBKJOWB.js} +15 -15
  177. package/dist/chunk-UFTQIK2J.js +43 -0
  178. package/dist/{chunk-ZP4FJHR4.js → chunk-UNFCFJMF.js} +18 -18
  179. package/dist/{chunk-IZNSAEBX.js → chunk-UTR67XU2.js} +2 -2
  180. package/dist/{chunk-6GWHKMQR.js → chunk-V4XKYGLK.js} +4 -4
  181. package/dist/{chunk-ISNZYKAS.js → chunk-VYNZED7B.js} +21 -21
  182. package/dist/{chunk-FV5YFR6I.js → chunk-WCLAOKCH.js} +9 -9
  183. package/dist/chunk-WFYHOXTB.js +29 -0
  184. package/dist/{chunk-QWVBEK4P.js → chunk-WGU6NIUV.js} +13 -13
  185. package/dist/{chunk-R4TBNKKC.js → chunk-WIMOJMAK.js} +974 -489
  186. package/dist/{chunk-XKZHAD6Y.js → chunk-WKXOEIOY.js} +15 -15
  187. package/dist/chunk-WUE6HKIU.js +790 -0
  188. package/dist/{chunk-R6B6XAKK.js → chunk-WUP77GG2.js} +4 -4
  189. package/dist/{chunk-RRVT4MPS.js → chunk-XF3DATVU.js} +18 -18
  190. package/dist/{chunk-KIHOIVST.js → chunk-XJAJQGXJ.js} +3 -3
  191. package/dist/{chunk-Y5PZHS4K.js → chunk-XKJRPVJO.js} +5 -5
  192. package/dist/{chunk-N4QZJJVB.js → chunk-XNRPCI23.js} +5 -5
  193. package/dist/{chunk-XNYNEEBR.js → chunk-XOVLGBKI.js} +18 -18
  194. package/dist/{chunk-GR6YKM55.js → chunk-XPJR74MA.js} +95 -13
  195. package/dist/{chunk-4GZXS6S2.js → chunk-XPWSNKF3.js} +226 -8
  196. package/dist/{chunk-LRS573EX.js → chunk-XR5DD5DQ.js} +4 -4
  197. package/dist/{chunk-PGKHJYOB.js → chunk-XZJE6WIT.js} +1 -1
  198. package/dist/{chunk-3GTZ2OON.js → chunk-Y5AYBGLB.js} +16 -10
  199. package/dist/{chunk-OIU657QQ.js → chunk-YLAM4HZH.js} +4 -4
  200. package/dist/{chunk-JF2NSTFO.js → chunk-YVCOQ5TZ.js} +3 -3
  201. package/dist/{chunk-F7YL2RZ4.js → chunk-YWOMGMZB.js} +23 -23
  202. package/dist/{chunk-WLIIQ2A4.js → chunk-YWZDAZMA.js} +7 -7
  203. package/dist/{chunk-JAA53T23.js → chunk-Z2EYRUOH.js} +20 -20
  204. package/dist/{chunk-UYYN2IUZ.js → chunk-Z46OXTBE.js} +6 -6
  205. package/dist/chunk-ZHWSL6SR.js +45 -0
  206. package/dist/chunk-ZJQUIG3A.js +87 -0
  207. package/dist/{chunk-T4RTWMJD.js → chunk-ZKUDS7JG.js} +5 -5
  208. package/dist/{chunk-HHUFVJF7.js → chunk-ZTNS3L5Z.js} +6 -6
  209. package/dist/files.json +471 -423
  210. package/dist/packages/sdk/npm/index.js +2300 -1983
  211. package/dist/packages/ui/dist/assets/{elk-api-Mo5w5xCa.js → elk-api-DDup23Us.js} +2 -2
  212. package/dist/packages/ui/dist/assets/{index-Bp3XhPHX.css → index-C0JEkXyN.css} +1 -1
  213. package/dist/packages/ui/dist/assets/index-mTOWhQZm.js +29 -0
  214. package/dist/packages/ui/dist/index.html +2 -2
  215. package/package.json +5 -5
  216. package/dist/chunk-26PLPSQW.js +0 -48
  217. package/dist/chunk-2G4DFUWJ.js +0 -43
  218. package/dist/chunk-2M6WXO73.js +0 -38
  219. package/dist/chunk-5F3RJCHB.js +0 -45
  220. package/dist/chunk-B2VSVN4P.js +0 -34
  221. package/dist/chunk-CITDNDIZ.js +0 -53
  222. package/dist/chunk-DAQBIK5G.js +0 -47
  223. package/dist/chunk-DZRQDNPT.js +0 -34
  224. package/dist/chunk-FLOEZA6K.js +0 -29
  225. package/dist/chunk-FNHSVBRA.js +0 -48
  226. package/dist/chunk-FPGVOSOG.js +0 -41
  227. package/dist/chunk-FZ2E5LGK.js +0 -54
  228. package/dist/chunk-HB6XSGI6.js +0 -131
  229. package/dist/chunk-HUZQDKQK.js +0 -48
  230. package/dist/chunk-L4VJ4ETL.js +0 -41
  231. package/dist/chunk-XPCWQXTY.js +0 -37
  232. package/dist/packages/ui/dist/assets/index-DM212ZbV.js +0 -29
@@ -7,18 +7,18 @@ import {
7
7
  featuresForScan,
8
8
  namingHint,
9
9
  syncSources
10
- } from "./chunk-6JLPXDWN.js";
10
+ } from "./chunk-TEBBD4XH.js";
11
11
  import {
12
12
  dirSource,
13
13
  sameCommit,
14
14
  verifyFacts
15
- } from "./chunk-4GZXS6S2.js";
15
+ } from "./chunk-XPWSNKF3.js";
16
16
  import {
17
17
  scanInputs
18
- } from "./chunk-R4TBNKKC.js";
18
+ } from "./chunk-WIMOJMAK.js";
19
19
  import {
20
20
  listIngestors
21
- } from "./chunk-NIXVDQVO.js";
21
+ } from "./chunk-5V5BJACL.js";
22
22
  import {
23
23
  BUILT_IN_EXTRACTORS,
24
24
  MODEL_READERS,
@@ -33,12 +33,12 @@ import {
33
33
  runDialectTests,
34
34
  runFrameworkTests,
35
35
  unmodelledFrameworks
36
- } from "./chunk-UR7RMZ3R.js";
36
+ } from "./chunk-GVFUEGGM.js";
37
37
  import {
38
38
  baseClonePath,
39
39
  changesSince,
40
40
  checkoutState
41
- } from "./chunk-PGKHJYOB.js";
41
+ } from "./chunk-XZJE6WIT.js";
42
42
  import {
43
43
  DEFAULT_IGNORES,
44
44
  configHash,
@@ -50,11 +50,11 @@ import {
50
50
  sandboxedExtractor,
51
51
  scanRepo,
52
52
  withParseCache
53
- } from "./chunk-MKRBG5EF.js";
53
+ } from "./chunk-FMRMTI7W.js";
54
54
  import {
55
55
  buildContextPack,
56
56
  toRunSummary
57
- } from "./chunk-5XDNUJ4P.js";
57
+ } from "./chunk-BKFGGJKA.js";
58
58
  import {
59
59
  AgentDefinition,
60
60
  DECLARED_CALLER,
@@ -69,8 +69,11 @@ import {
69
69
  REPO_TYPE_SCHEMA_VERSION,
70
70
  RecordId,
71
71
  SCAN_SETTINGS_SCHEMA_VERSION,
72
+ TARGETS_ANOTHER_LABEL,
72
73
  TARGETS_SPLIT_LABEL,
73
74
  TARGETS_STEP_ID,
75
+ TOPICS_OUTSIDE_LABEL,
76
+ TOPICS_STEP_ID,
74
77
  applyCurated,
75
78
  applyLinkEvidence,
76
79
  applySharedMaps,
@@ -101,6 +104,7 @@ import {
101
104
  joinGuessesOf,
102
105
  joinRecords,
103
106
  joinSharedMaps,
107
+ joinTerms,
104
108
  lineNamesField,
105
109
  lineNamesRoute,
106
110
  lineNamesWord,
@@ -126,14 +130,16 @@ import {
126
130
  stackHelpersOff,
127
131
  stripLinkEvidence,
128
132
  stripSharedMaps,
133
+ termGrantRecords,
129
134
  throwIfCancelled,
130
135
  toCanonicalYaml,
136
+ topicQuestionText,
131
137
  urlHostPort
132
- } from "./chunk-577AJVRS.js";
138
+ } from "./chunk-JMOLB347.js";
133
139
  import {
134
140
  SCHEMA_VERSION,
135
141
  writeFileAtomic
136
- } from "./chunk-D3PO4DOZ.js";
142
+ } from "./chunk-MMB2OHUY.js";
137
143
  import {
138
144
  __toESM
139
145
  } from "./chunk-TV45EUGM.js";
@@ -1484,6 +1490,338 @@ import { join as join6 } from "node:path";
1484
1490
 
1485
1491
  // packages/scanner/dist/facts-catalog.js
1486
1492
  import { createHash as createHash2 } from "node:crypto";
1493
+
1494
+ // packages/scanner/dist/target-suggest.js
1495
+ var TARGETS_MAX_SUGGESTED = 5;
1496
+ var TARGETS_ANOTHER = TARGETS_ANOTHER_LABEL;
1497
+ var STOP = new Set("url uri base host client clients service services svc api apis http https rest endpoint endpoints impl java kt ts js py cs go src main test get post put delete patch the and for com www internal example config configs properties yaml yml env app apps application new call calls feign template web request requests response gateway proxy remote adapter port".split(" "));
1498
+ function nameWords(s) {
1499
+ if (!s)
1500
+ return [];
1501
+ return [
1502
+ ...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))
1503
+ ];
1504
+ }
1505
+ var segs = (p) => p.split(/[?#]/)[0].split("/").filter(Boolean).map((x) => /^[{:<$]/.test(x) ? "{}" : x);
1506
+ var sameSeg = (a, b) => a === "{}" || b === "{}" || a === b;
1507
+ var under = (path, prefix) => {
1508
+ const a = segs(prefix);
1509
+ const b = segs(path);
1510
+ return a.length > 0 && a.length <= b.length && a.every((x, i) => x === b[i]);
1511
+ };
1512
+ function serves(entry, call, bases) {
1513
+ const e = segs(entry);
1514
+ const tries = [
1515
+ segs(call),
1516
+ ...bases.filter((b) => under(call, b)).map((b) => segs(call).slice(segs(b).length))
1517
+ ];
1518
+ return tries.some((c) => c.length === e.length && c.every((x, i) => sameSeg(x, e[i])));
1519
+ }
1520
+ function clientOf(f) {
1521
+ const q = f.cite.quote ?? "";
1522
+ const named2 = /\b([A-Z][A-Za-z0-9]*(?:Client|Service|Api|Feign|Gateway|Proxy))\b/.exec(q)?.[1];
1523
+ if (named2)
1524
+ return named2;
1525
+ const file = f.cite.file.split("/").pop().replace(/\.[^.]+$/, "");
1526
+ return /(Client|Service|Api|Feign|Gateway|Proxy)$/.test(file) ? file : void 0;
1527
+ }
1528
+ function hostOf(f, facts) {
1529
+ const fromUrl = (u) => /^[a-z][a-z0-9+.-]*:\/\/([^/:?#]+)/i.exec(u)?.[1];
1530
+ if (f.host)
1531
+ return fromUrl(f.host) ?? f.host.split(/[/:]/)[0];
1532
+ if (f.base) {
1533
+ const cfg = facts.find((x) => x.kind === "config" && x.key === f.base && !!x.value);
1534
+ return cfg?.value ? fromUrl(cfg.value) : void 0;
1535
+ }
1536
+ return void 0;
1537
+ }
1538
+ var answerLabel = (q) => q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text;
1539
+ var NOT_A_TARGET = /* @__PURE__ */ new Set(["None of these", TARGETS_SPLIT_LABEL, TARGETS_ANOTHER_LABEL]);
1540
+ var SERVES = {
1541
+ rest: ["rest"],
1542
+ soap: ["soap"],
1543
+ graphql: ["graphql"],
1544
+ grpc: ["grpc"],
1545
+ webhook: ["webhook"],
1546
+ sftp: ["file-drop"]
1547
+ };
1548
+ function candidates(callerRepo, ctx) {
1549
+ const manifest = estateRepos(ctx.op).filter((r) => r.id !== callerRepo || !!ctx.only);
1550
+ const systems = ctx.op.profiles.flatMap((p) => p.profile?.systems ?? []);
1551
+ const reposOfSystem = /* @__PURE__ */ new Map();
1552
+ for (const r of estateRepos(ctx.op))
1553
+ if (r.system)
1554
+ reposOfSystem.set(r.system, (reposOfSystem.get(r.system) ?? 0) + 1);
1555
+ const read = new Set((ctx.estate ?? []).filter((x) => x.facts.length > 0).map((x) => x.repo));
1556
+ const repoOf = /* @__PURE__ */ new Map();
1557
+ for (const r of ctx.records)
1558
+ if (r.kind === "Component" && r.repo)
1559
+ repoOf.set(r.id, r.repo);
1560
+ if (!ctx.estate)
1561
+ for (const repo of repoOf.values())
1562
+ read.add(repo);
1563
+ const endpoints = ctx.records.filter((r) => r.kind === "Endpoint");
1564
+ const deploys = (ctx.estate ?? []).flatMap((x) => x.facts.filter((f) => f.kind === "deploy" && !!f.basePath));
1565
+ const out = [];
1566
+ for (const m of manifest) {
1567
+ const own2 = new Set([m.id, m.component, ...m.modules.map((x) => x.component)].filter((x) => !!x).map(factIdPart));
1568
+ const sys = m.system && reposOfSystem.get(m.system) === 1 ? systems.find((s) => s.id === m.system) : void 0;
1569
+ const names = /* @__PURE__ */ new Map();
1570
+ for (const n of [m.id, m.component, ...m.modules.map((x) => x.component)])
1571
+ for (const w of nameWords(n))
1572
+ if (!names.has(w))
1573
+ names.set(w, n);
1574
+ for (const a of sys ? [sys.id, ...sys.aliases] : [])
1575
+ for (const w of nameWords(a))
1576
+ if (!names.has(w))
1577
+ names.set(w, a);
1578
+ const bases = [];
1579
+ if (m.basePath)
1580
+ bases.push({ path: m.basePath, from: "the manifest's basePath" });
1581
+ for (const x of m.modules)
1582
+ if (x.basePath)
1583
+ bases.push({ path: x.basePath, from: `the basePath of its module ${x.component}` });
1584
+ for (const d of deploys) {
1585
+ const reaches = d.exposes ? factIdPart(d.exposes) : d.repo === m.id ? m.id : void 0;
1586
+ if (!reaches || !(own2.has(reaches) || d.repo === m.id && !d.exposes))
1587
+ continue;
1588
+ const what2 = d.platform === "apigee" ? "its proxy's BasePath" : `the ${d.resourceType ?? "route"} ${d.resourceName ?? d.id}`;
1589
+ bases.push({ path: d.basePath, from: `${what2} (${d.repo} ${d.cite.file}:${d.cite.line})` });
1590
+ }
1591
+ const comps = [
1592
+ ...new Set(endpoints.filter((e) => repoOf.get(e.component) === m.id).map((e) => e.component))
1593
+ ].sort();
1594
+ const isRead = read.has(m.id);
1595
+ const forLabel = comps.length ? comps : [m.id];
1596
+ for (const label2 of forLabel) {
1597
+ const mine = endpoints.filter((e) => e.component === label2);
1598
+ const entries = (ctx.estate ?? []).filter((x) => x.repo === m.id).flatMap((x) => x.facts.filter((f) => f.kind === "entry" && (!comps.length || factIdPart(f.component ?? m.component ?? m.id) === label2 || comps.length === 1))).map((f) => ({
1599
+ ...f.method ? { method: f.method.toUpperCase() } : {},
1600
+ path: f.path,
1601
+ at: `${f.cite.file}:${f.cite.line}`
1602
+ }));
1603
+ for (const e of mine)
1604
+ if (!entries.some((x) => x.path === e.pathOrTopic))
1605
+ entries.push({
1606
+ ...e.method ? { method: e.method.toUpperCase() } : {},
1607
+ path: e.pathOrTopic,
1608
+ at: e.id
1609
+ });
1610
+ out.push({
1611
+ s: { label: label2, kind: "repo", repo: m.id, read: isRead, score: 0, why: [] },
1612
+ names,
1613
+ bases,
1614
+ entries,
1615
+ types: new Set(mine.map((e) => e.endpointType)),
1616
+ ...m.description?.text ? { description: m.description.text } : {},
1617
+ hosts: m.hosts.map((h) => h.toLowerCase())
1618
+ });
1619
+ }
1620
+ }
1621
+ for (const c of ctx.only ?? [])
1622
+ if (!out.some((x) => x.s.label === c))
1623
+ out.push({
1624
+ s: {
1625
+ label: c,
1626
+ kind: "repo",
1627
+ repo: repoOf.get(c) ?? callerRepo,
1628
+ read: true,
1629
+ score: 0,
1630
+ why: []
1631
+ },
1632
+ names: /* @__PURE__ */ new Map(),
1633
+ bases: [],
1634
+ entries: [],
1635
+ types: /* @__PURE__ */ new Set(),
1636
+ hosts: []
1637
+ });
1638
+ const own = new Set(estateRepos(ctx.op).flatMap((r) => r.system ? [r.system] : []));
1639
+ const seen = /* @__PURE__ */ new Set();
1640
+ for (const s of systems) {
1641
+ if (!(s.boundary === "vendor" || !own.has(s.id)) || seen.has(s.id))
1642
+ continue;
1643
+ seen.add(s.id);
1644
+ const names = /* @__PURE__ */ new Map();
1645
+ for (const n of [s.id, s.name, ...s.aliases])
1646
+ for (const w of nameWords(n))
1647
+ if (!names.has(w))
1648
+ names.set(w, n);
1649
+ out.push({
1650
+ s: {
1651
+ label: s.id,
1652
+ kind: "outside",
1653
+ read: false,
1654
+ name: s.name,
1655
+ boundary: s.boundary,
1656
+ score: 0,
1657
+ why: []
1658
+ },
1659
+ names,
1660
+ bases: [],
1661
+ entries: [],
1662
+ types: /* @__PURE__ */ new Set(),
1663
+ hosts: s.aliases.map((a) => a.toLowerCase())
1664
+ });
1665
+ }
1666
+ return out;
1667
+ }
1668
+ function targetSuggestions(f, ctx) {
1669
+ const all = candidates(f.repo, ctx);
1670
+ const df = /* @__PURE__ */ new Map();
1671
+ for (const c of all)
1672
+ for (const w of c.names.keys())
1673
+ df.set(w, (df.get(w) ?? 0) + 1);
1674
+ const telling = (w) => (df.get(w) ?? 0) <= Math.max(2, Math.floor(all.length / 3));
1675
+ const host = hostOf(f, ctx.facts)?.toLowerCase();
1676
+ const client = clientOf(f);
1677
+ const said = [
1678
+ { from: f.base ? `its config key ${f.base}` : "", words: nameWords(f.base), weight: 4 },
1679
+ { from: client ? `its client ${client}` : "", words: nameWords(client), weight: 4 },
1680
+ {
1681
+ from: host ? `its host ${host}` : "",
1682
+ words: host ? nameWords(host.split(".")[0]) : [],
1683
+ weight: 4
1684
+ },
1685
+ {
1686
+ from: `its path ${f.path}`,
1687
+ words: nameWords(segs(f.path).filter((x) => x !== "{}").join(" ")),
1688
+ weight: 2
1689
+ }
1690
+ ].filter((x) => x.from && x.words.length);
1691
+ const method = f.method?.toUpperCase();
1692
+ const types = new Set(SERVES[f.callType] ?? []);
1693
+ const earlier = (ctx.questions ?? []).filter((q) => q.askedBy?.step === TARGETS_STEP_ID && q.state === "answered" && q.repo === f.repo && !q.evidence.includes(`${f.cite.file}:${f.cite.line}`));
1694
+ const only = ctx.only ? new Set(ctx.only) : void 0;
1695
+ const out = [];
1696
+ for (const c of all) {
1697
+ if (only && c.s.kind === "repo" && !only.has(c.s.label))
1698
+ continue;
1699
+ const s = { ...c.s, why: [] };
1700
+ const add = (n, why) => {
1701
+ s.score += n;
1702
+ s.why.push(why);
1703
+ };
1704
+ if (only?.has(c.s.label))
1705
+ add(6, "the join found an entry of it that serves the call");
1706
+ const hit = c.entries.find((e) => (!method || !e.method || e.method === method) && serves(e.path, f.path, c.bases.map((b) => b.path)));
1707
+ if (hit && !only)
1708
+ add(6, `it serves ${[hit.method, hit.path].filter(Boolean).join(" ")} (${hit.at})`);
1709
+ const base2 = c.bases.find((b) => under(f.path, b.path));
1710
+ if (base2)
1711
+ add(5, `${f.path} is under ${base2.path}, ${base2.from}`);
1712
+ if (host && c.hosts.includes(host))
1713
+ add(8, `it answers on ${host}`);
1714
+ for (const x of said) {
1715
+ const w = x.words.find((y) => c.names.has(y) && telling(y));
1716
+ if (w)
1717
+ add(x.weight, `${x.from} names ${c.names.get(w)}`);
1718
+ }
1719
+ if (c.description) {
1720
+ const d = new Set(nameWords(c.description));
1721
+ const w = said.flatMap((x) => x.words).find((y) => d.has(y) && telling(y));
1722
+ if (w)
1723
+ add(2, `its description mentions ${w}`);
1724
+ }
1725
+ const named2 = earlier.filter((q) => {
1726
+ const l = answerLabel(q);
1727
+ if (!l || NOT_A_TARGET.has(l))
1728
+ return false;
1729
+ const t = slugify(l);
1730
+ return t === slugify(c.s.label) || !!c.s.repo && t === slugify(c.s.repo);
1731
+ }).length;
1732
+ if (named2)
1733
+ add(3, `${f.repo}'s answers name it for ${named2} other ${named2 === 1 ? "call" : "calls"}`);
1734
+ if (c.s.kind === "repo" && c.s.read && [...c.types].some((t) => types.has(t)) && !s.score)
1735
+ s.why.push(`it serves ${[...types].join(" and ")} calls`);
1736
+ s.why = [...new Set(s.why)];
1737
+ out.push(s);
1738
+ }
1739
+ return out.sort((a, b) => b.score - a.score || Number(b.read) - Number(a.read) || (a.kind === b.kind ? 0 : a.kind === "repo" ? -1 : 1) || a.label.localeCompare(b.label));
1740
+ }
1741
+ function offeredSuggestions(ranked, o) {
1742
+ const max = o.max ?? TARGETS_MAX_SUGGESTED;
1743
+ const strong = ranked.filter((s) => s.score >= 2);
1744
+ const fill = ranked.filter((s) => s.score < 2 && (s.kind === "outside" || s.read && o.serving.has(s.label)));
1745
+ return [...strong, ...fill].slice(0, max);
1746
+ }
1747
+ function targetPicker(op, read = /* @__PURE__ */ new Set()) {
1748
+ const repos = estateRepos(op).map((r) => ({
1749
+ id: r.id,
1750
+ kind: "repo",
1751
+ name: r.component && r.component !== r.id ? `${r.id} (${r.component})` : r.id,
1752
+ read: read.has(r.id)
1753
+ })).sort((a, b) => a.id.localeCompare(b.id));
1754
+ const seen = /* @__PURE__ */ new Set();
1755
+ const systems = op.profiles.flatMap((p) => p.profile?.systems ?? []).filter((s) => !seen.has(s.id) && !!seen.add(s.id)).map((s) => ({ id: s.id, kind: "system", name: s.name, boundary: s.boundary })).sort((a, b) => a.id.localeCompare(b.id));
1756
+ const owned = new Set(op.profiles.flatMap((p) => (p.profile?.systems ?? []).flatMap((s) => s.owner ? [s.owner] : [])));
1757
+ const teams = (op.roles?.teams ?? []).map((t) => {
1758
+ const name = t.name ?? t.id;
1759
+ const has = owned.has(t.id);
1760
+ return {
1761
+ id: t.id,
1762
+ kind: "team",
1763
+ name,
1764
+ ...has ? {} : {
1765
+ adds: {
1766
+ id: slugify(`${t.id}-system`),
1767
+ name: `${name}'s system`,
1768
+ boundary: "internal",
1769
+ owner: t.id
1770
+ }
1771
+ }
1772
+ };
1773
+ }).sort((a, b) => a.id.localeCompare(b.id));
1774
+ return [...repos, ...systems, ...teams];
1775
+ }
1776
+ function pickerLines(picks) {
1777
+ const of = (k) => picks.filter((p) => p.kind === k);
1778
+ return [
1779
+ `Repos (${of("repo").length}): ${of("repo").map((p) => `${p.id}${p.read ? "" : " (not read yet)"}`).join(", ") || "none"}`,
1780
+ `Systems (${of("system").length}): ${of("system").map((p) => `${p.id} (${p.boundary})`).join(", ") || "none"}`,
1781
+ `Teams (${of("team").length}): ${of("team").map((p) => `${p.id}${p.adds ? " (no system yet)" : ""}`).join(", ") || "none"}`
1782
+ ];
1783
+ }
1784
+ function topicQuestionDrafts(repo, records) {
1785
+ const out = /* @__PURE__ */ new Map();
1786
+ for (const r of records) {
1787
+ if (r.kind !== "Unresolved")
1788
+ continue;
1789
+ const x = r;
1790
+ if (x.unresolvedKind !== "event-publish" && x.unresolvedKind !== "event-subscribe")
1791
+ continue;
1792
+ const topic = String(x.raw);
1793
+ if (!topic || topic.includes("${") || /\s/.test(topic))
1794
+ continue;
1795
+ const ev = x.evidence.filter((e) => e.repo === repo && e.path && e.line && !/[\s:]/.test(e.path)).map((e) => `${e.path}:${e.line}`).sort();
1796
+ if (!ev.length)
1797
+ continue;
1798
+ const side = x.unresolvedKind === "event-publish" ? "publish" : "listen";
1799
+ const question = topicQuestionText(topic, x.owner ?? repo, side);
1800
+ const draft = {
1801
+ question,
1802
+ options: [
1803
+ {
1804
+ label: TOPICS_OUTSIDE_LABEL,
1805
+ means: `${topic} belongs to another team's system or a vendor's: name it, or the team, from the list`,
1806
+ changes: `${topic} is added under that system's topics in the profile (or the system is added, owner the team), as a file change for review; the next write ${side === "publish" ? "sends the publish to it" : "takes the listener's messages from it"}, marked as your word`
1807
+ },
1808
+ {
1809
+ label: "None of these",
1810
+ means: `Nothing outside the estate owns ${topic}, or a repo not read yet serves it`,
1811
+ changes: `It stays a loose end, and this isn't asked again`
1812
+ }
1813
+ ],
1814
+ evidence: [...new Set(ev)],
1815
+ scope: "repo"
1816
+ };
1817
+ const id = questionId({ step: TOPICS_STEP_ID, repo, question, evidence: draft.evidence });
1818
+ if (!out.has(id))
1819
+ out.set(id, { topic, id, draft });
1820
+ }
1821
+ return [...out.values()].sort((a, b) => a.topic.localeCompare(b.topic));
1822
+ }
1823
+
1824
+ // packages/scanner/dist/facts-catalog.js
1487
1825
  var TARGETS_STEP = TARGETS_STEP_ID;
1488
1826
  var TARGETS_NONE = "None of these";
1489
1827
  var byKindId = (a, b) => a.kind === b.kind ? a.id.localeCompare(b.id) : a.kind.localeCompare(b.kind);
@@ -1529,7 +1867,7 @@ function targetQuestionFor(f) {
1529
1867
  evidence: [`${f.cite.file}:${f.cite.line}`]
1530
1868
  };
1531
1869
  }
1532
- var SERVES = {
1870
+ var SERVES2 = {
1533
1871
  rest: ["rest"],
1534
1872
  soap: ["soap"],
1535
1873
  graphql: ["graphql"],
@@ -1548,7 +1886,7 @@ function targetAsks(facts, records, asks) {
1548
1886
  if (f.kind !== "call" || !needsTarget(f, facts) && !ask)
1549
1887
  continue;
1550
1888
  const own = slugify(f.component ?? f.repo).replace(/\./g, "-");
1551
- const types = new Set(SERVES[f.callType] ?? []);
1889
+ const types = new Set(SERVES2[f.callType] ?? []);
1552
1890
  const servers = ask ? [...new Set(ask.candidates.map((c) => c.component))].sort() : [
1553
1891
  ...new Set(records.filter((r) => r.kind === "Endpoint" && types.has(r.endpointType) && r.component !== own).filter((r) => repoOf.get(r.component) !== f.repo).map((r) => r.component))
1554
1892
  ].sort();
@@ -1556,27 +1894,73 @@ function targetAsks(facts, records, asks) {
1556
1894
  }
1557
1895
  return { list, repoOf };
1558
1896
  }
1559
- var vendorsOf = (op) => outsideProfileSystems(op);
1560
1897
  var outsideAs = (s) => s.boundary === "vendor" ? "an outside system" : "another team's system";
1561
1898
  var callWhat = (f) => [f.method?.toUpperCase(), f.path].filter(Boolean).join(" ");
1562
- function targetQuestionDrafts(facts, records, op, asks) {
1563
- const { list, repoOf } = targetAsks(facts, records, asks);
1564
- const vendors = vendorsOf(op);
1565
- return list.map(({ f, q, servers }) => {
1899
+ function suggestionOption(s, callerRepo, what2, n) {
1900
+ const calls = n ? `all ${n} calls: ${what2}` : what2;
1901
+ const why = s.why.length ? `. Suggested: ${s.why.slice(0, 3).join("; ")}` : "";
1902
+ if (s.kind === "outside")
1903
+ return {
1904
+ label: s.label,
1905
+ means: `${s.name}, ${outsideAs({ boundary: s.boundary ?? "vendor" })}, answers ${calls}${why}`,
1906
+ changes: n ? `The ${n} calls go to ${s.name} when the facts are next written` : `The call goes to ${s.name} when the facts are next written`
1907
+ };
1908
+ const who = s.label === s.repo ? `${s.repo}${s.read ? "" : ", not read yet,"}` : `${s.label}, built in ${s.repo}${s.read ? "" : ", not read yet"},`;
1909
+ const them = n ? `The ${n} calls` : "The call";
1910
+ return {
1911
+ label: s.label,
1912
+ means: `${who} answers ${calls}${why}`,
1913
+ changes: s.read ? `${them} ${n ? "join" : "joins"} ${s.label} when the facts are next written (atticus verify ${callerRepo} --write)` : `${them} ${n ? "go" : "goes"} to ${s.repo} when the facts are next written (atticus verify ${callerRepo} --write), and ${n ? "join" : "joins"} its route once ${s.repo} is read and verified (/atticus-map ${s.repo}); if no route of it serves ${n ? "them" : "it"}, the question opens again`
1914
+ };
1915
+ }
1916
+ var anotherOption = (op) => {
1917
+ const repos = estateRepos(op).length;
1918
+ const systems = new Set(op.profiles.flatMap((p) => (p.profile?.systems ?? []).map((s) => s.id))).size;
1919
+ const teams = op.roles?.teams?.length ?? 0;
1920
+ return {
1921
+ label: TARGETS_ANOTHER,
1922
+ means: `A repo, system or team not listed here: the manifest's ${repos} repos (read or not), the profiles' ${systems} systems and the ${teams} teams in roles.yaml`,
1923
+ changes: "Nothing until you name one: atticus questions answer <id> --target <repo, system or team id> lists them and takes the one you name (the app's Questions page lists them too); naming a vendor or a team with no system adds that system to the profile for review"
1924
+ };
1925
+ };
1926
+ function offered(members, facts, records, op, asks, ctx) {
1927
+ const merged = /* @__PURE__ */ new Map();
1928
+ for (const m of members) {
1929
+ const ambiguous = asks?.some((a) => a.reason === "ambiguous" && a.call.repo === m.f.repo && a.call.fact === m.f.id);
1930
+ for (const s of targetSuggestions(m.f, {
1931
+ op,
1932
+ records,
1933
+ facts,
1934
+ ...ctx.estate ? { estate: ctx.estate } : {},
1935
+ ...ctx.questions ? { questions: ctx.questions } : {},
1936
+ ...ambiguous ? { only: m.servers } : {}
1937
+ })) {
1938
+ const x = merged.get(s.label);
1939
+ if (!x)
1940
+ merged.set(s.label, { ...s, why: [...s.why] });
1941
+ else {
1942
+ x.score += s.score;
1943
+ for (const w of s.why)
1944
+ if (!x.why.includes(w))
1945
+ x.why.push(w);
1946
+ }
1947
+ }
1948
+ }
1949
+ const ranked = [...merged.values()].sort((a, b) => b.score - a.score || Number(b.read) - Number(a.read) || (a.kind === b.kind ? 0 : a.kind === "repo" ? -1 : 1) || a.label.localeCompare(b.label));
1950
+ const serving = new Set(members.flatMap((m) => m.servers));
1951
+ const types = new Set(members.flatMap((m) => SERVES2[m.f.callType] ?? []));
1952
+ return offeredSuggestions(ranked, { types, serving });
1953
+ }
1954
+ function targetQuestionDrafts(facts, records, op, asks, ctx = {}) {
1955
+ const { list } = targetAsks(facts, records, asks);
1956
+ return list.map((m) => {
1957
+ const { f, q } = m;
1566
1958
  const what2 = callWhat(f);
1567
1959
  const draft = {
1568
1960
  question: q.question,
1569
1961
  options: [
1570
- ...servers.map((c) => ({
1571
- label: c,
1572
- means: `${c}${repoOf.get(c) ? `, built in ${repoOf.get(c)},` : ""} answers ${what2}`,
1573
- changes: `The call joins ${c} when the facts are next written (atticus verify ${f.repo} --write)`
1574
- })),
1575
- ...vendors.map((s) => ({
1576
- label: s.id,
1577
- means: `${s.name}, ${outsideAs(s)}, answers ${what2}`,
1578
- changes: `The call goes to ${s.name} when the facts are next written`
1579
- })),
1962
+ ...offered([m], facts, records, op, asks, ctx).map((s) => suggestionOption(s, f.repo, what2)),
1963
+ anotherOption(op),
1580
1964
  {
1581
1965
  label: TARGETS_NONE,
1582
1966
  means: "Nothing in the estate or the org pack's systems answers it",
@@ -1626,13 +2010,17 @@ function targetGroupQuestion(repo, f) {
1626
2010
  return `Which repo or system answers the calls ${repo} makes under ${targetPathPrefix(f.path)}${groupVia(f)}?`;
1627
2011
  }
1628
2012
  var byLine = (a, b) => a.localeCompare(b, "en", { numeric: true });
1629
- var answerLabel = (q) => q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text;
2013
+ var answerLabel2 = (q) => q.answer?.option !== void 0 ? q.options[q.answer.option - 1]?.label : q.answer?.text;
1630
2014
  function splitTargetGroups(questions) {
1631
- return new Set(questions.filter((q) => q.askedBy?.step === TARGETS_STEP && q.state === "answered" && answerLabel(q) === TARGETS_SPLIT).map((q) => q.question.trim()));
2015
+ return new Set(questions.filter((q) => q.askedBy?.step === TARGETS_STEP && q.state === "answered" && answerLabel2(q) === TARGETS_SPLIT).map((q) => q.question.trim()));
1632
2016
  }
1633
2017
  function groupedTargetDrafts(facts, records, op, asks, o) {
1634
- const { list, repoOf } = targetAsks(facts, records, asks);
1635
- const own = new Map(targetQuestionDrafts(facts, records, op, asks).map((d) => [d.factId, d]));
2018
+ const { list } = targetAsks(facts, records, asks);
2019
+ const ctx = {
2020
+ ...o.estate ? { estate: o.estate } : {},
2021
+ ...o.questions ? { questions: o.questions } : {}
2022
+ };
2023
+ const own = new Map(targetQuestionDrafts(facts, records, op, asks, ctx).map((d) => [d.factId, d]));
1636
2024
  const groups = /* @__PURE__ */ new Map();
1637
2025
  for (const a of list) {
1638
2026
  if (!o.ask.has(a.f.id))
@@ -1640,7 +2028,6 @@ function groupedTargetDrafts(facts, records, op, asks, o) {
1640
2028
  const k = targetGroupQuestion(a.f.repo, a.f);
1641
2029
  groups.set(k, [...groups.get(k) ?? [], a]);
1642
2030
  }
1643
- const vendors = vendorsOf(op);
1644
2031
  const out = [];
1645
2032
  for (const [question, members] of groups) {
1646
2033
  if (members.length === 1 || o.split?.has(question)) {
@@ -1652,21 +2039,12 @@ function groupedTargetDrafts(facts, records, op, asks, o) {
1652
2039
  const whats = [...new Set(members.map((m) => callWhat(m.f)))];
1653
2040
  const listed = whats.length > 5 ? `${whats.slice(0, 5).join(", ")} and ${whats.length - 5} more` : whats.join(", ");
1654
2041
  const n = members.length;
1655
- const servers = [...new Set(members.flatMap((m) => m.servers))].sort();
1656
2042
  const evidence = [...new Set(members.flatMap((m) => m.q.evidence))].sort(byLine);
1657
2043
  const draft = {
1658
2044
  question,
1659
2045
  options: [
1660
- ...servers.map((c) => ({
1661
- label: c,
1662
- means: `${c}${repoOf.get(c) ? `, built in ${repoOf.get(c)},` : ""} answers all ${n} calls: ${listed}`,
1663
- changes: `The ${n} calls join ${c} when the facts are next written (atticus verify ${repo} --write)`
1664
- })),
1665
- ...vendors.map((s) => ({
1666
- label: s.id,
1667
- means: `${s.name}, ${outsideAs(s)}, answers all ${n} calls: ${listed}`,
1668
- changes: `The ${n} calls go to ${s.name} when the facts are next written`
1669
- })),
2046
+ ...offered(members, facts, records, op, asks, ctx).map((s) => suggestionOption(s, repo, listed, n)),
2047
+ anotherOption(op),
1670
2048
  {
1671
2049
  label: TARGETS_SPLIT,
1672
2050
  means: `The ${n} calls (${listed}) don't all go to one place`,
@@ -1711,7 +2089,7 @@ function ruledTargets(repo, facts, questions, o = {}) {
1711
2089
  if (!needsTarget(f, facts))
1712
2090
  continue;
1713
2091
  const q = rules.find((r) => ruleCoversCall(r.answer.match, f, facts));
1714
- const label2 = q ? answerLabel(q) : void 0;
2092
+ const label2 = q ? answerLabel2(q) : void 0;
1715
2093
  if (q && label2 && label2 !== TARGETS_SPLIT)
1716
2094
  out.set(f.id, { id: q.id, match: q.answer.match, label: label2 });
1717
2095
  }
@@ -1735,10 +2113,10 @@ function targetsFromAnswers(repo, facts, questions, o = {}) {
1735
2113
  const g = groups.get(targetGroupQuestion(repo, f));
1736
2114
  asked = g && (needsTarget(f, facts) || g.evidence.includes(q.evidence[0])) ? g : void 0;
1737
2115
  }
1738
- let label2 = asked && asked.state === "answered" && asked.answer ? answerLabel(asked) : void 0;
1739
- if (!label2 || label2 === TARGETS_SPLIT)
2116
+ let label2 = asked && asked.state === "answered" && asked.answer ? answerLabel2(asked) : void 0;
2117
+ if (!label2 || label2 === TARGETS_SPLIT || label2 === TARGETS_ANOTHER)
1740
2118
  label2 = ruled.get(f.id)?.label;
1741
- if (!label2 || label2 === TARGETS_SPLIT)
2119
+ if (!label2 || label2 === TARGETS_SPLIT || label2 === TARGETS_ANOTHER)
1742
2120
  continue;
1743
2121
  if (label2 === TARGETS_NONE) {
1744
2122
  out[f.id] = NO_TARGET;
@@ -1750,6 +2128,23 @@ function targetsFromAnswers(repo, facts, questions, o = {}) {
1750
2128
  }
1751
2129
  return out;
1752
2130
  }
2131
+ function answeredQuestionOfCall(repo, facts, questions, factId) {
2132
+ const f = facts.find((x) => x.id === factId);
2133
+ if (!f || f.kind !== "call")
2134
+ return void 0;
2135
+ const own = targetQuestionFor(f);
2136
+ const ownId = questionId({ step: TARGETS_STEP, repo, ...own });
2137
+ const answered = questions.filter((q2) => q2.askedBy?.step === TARGETS_STEP && q2.state === "answered" && q2.repo === repo);
2138
+ const q = answered.find((x) => x.id === ownId) ?? answered.find((x) => x.question.trim() === targetGroupQuestion(repo, f) && x.evidence.includes(own.evidence[0]));
2139
+ return q?.answer?.match ? void 0 : q;
2140
+ }
2141
+ function answerReconfirmed(q) {
2142
+ if (!q.answer || !q.reopened)
2143
+ return false;
2144
+ const now2 = answerLabel2(q);
2145
+ const was = answerLabel2({ ...q, answer: q.reopened.answer });
2146
+ return !!now2 && !!was && slugify(now2) === slugify(was);
2147
+ }
1753
2148
  var JOINED_BY = {
1754
2149
  named: "the call names it",
1755
2150
  repo: "the call names its repo",
@@ -2055,7 +2450,9 @@ function catalogWithFacts(given) {
2055
2450
  const remap = /* @__PURE__ */ new Map();
2056
2451
  const stepTo = /* @__PURE__ */ new Map();
2057
2452
  let join10;
2453
+ let answerMisses;
2058
2454
  let estateJoin;
2455
+ let terms;
2059
2456
  let records0 = [...kept2, ...newRecords];
2060
2457
  if (input.estate) {
2061
2458
  const repos = joinReposOf(op, [{ repo, facts }, ...others], renames);
@@ -2069,6 +2466,16 @@ function catalogWithFacts(given) {
2069
2466
  });
2070
2467
  join10 = joinAbout(whole, repo);
2071
2468
  estateJoin = { whole, repos };
2469
+ const named2 = { ...input.estateTargets, [repo]: input.targets ?? {} };
2470
+ const mine2 = /* @__PURE__ */ new Set([
2471
+ factIdPart(repo),
2472
+ ...repos.filter((r) => r.repo === repo).flatMap((r) => [r.component, ...(r.modules ?? []).map((m) => m.component)]).filter((x) => !!x).map(factIdPart),
2473
+ ...facts.flatMap((f) => f.component ? [factIdPart(f.component)] : [])
2474
+ ]);
2475
+ answerMisses = whole.misses.filter((m) => {
2476
+ const t = named2[m.call.repo]?.[m.call.fact];
2477
+ return !!t && t !== NO_TARGET && (m.call.repo === repo || mine2.has(factIdPart(m.target)));
2478
+ });
2072
2479
  records0 = applyFactJoins(records0, join10, repos, {
2073
2480
  callers: joinCallers({
2074
2481
  repos,
@@ -2079,6 +2486,8 @@ function catalogWithFacts(given) {
2079
2486
  join: whole,
2080
2487
  only: [repo]
2081
2488
  });
2489
+ terms = joinTerms({ repos, join: whole, bundleFolders: joinConventions(op).bundleFolders });
2490
+ records0 = [...records0, ...termGrantRecords(terms, repos, { only: [repo] })];
2082
2491
  for (const j of join10.joins) {
2083
2492
  const id = j.call.repo === repo ? projected.ids[j.call.fact] : void 0;
2084
2493
  if (!id || remap.has(id))
@@ -2185,7 +2594,9 @@ function catalogWithFacts(given) {
2185
2594
  notes: merged.notes,
2186
2595
  ...join10 ? { join: join10 } : {},
2187
2596
  ...linkEvidence ? { linkEvidence } : {},
2188
- ...sharedWhole ? { shared: sharedJoinAbout(sharedWhole, repo) } : {}
2597
+ ...sharedWhole ? { shared: sharedJoinAbout(sharedWhole, repo) } : {},
2598
+ ...terms ? { terms } : {},
2599
+ ...answerMisses?.length ? { answerMisses } : {}
2189
2600
  };
2190
2601
  }
2191
2602
  function prototypeLeftOut(input) {
@@ -2238,6 +2649,61 @@ function estateFromFacts(input) {
2238
2649
  });
2239
2650
  return { records, specs, join: join10, invalid };
2240
2651
  }
2652
+ function answerRuleOffers(input) {
2653
+ const ruled = input.questions.filter((q) => q.askedBy?.step === TARGETS_STEP && q.state === "answered" && !!q.answer?.match);
2654
+ const groups = /* @__PURE__ */ new Map();
2655
+ for (const r of input.repos)
2656
+ for (const f of r.facts) {
2657
+ if (f.kind !== "call")
2658
+ continue;
2659
+ const q = answeredQuestionOfCall(r.repo, r.facts, input.questions, f.id);
2660
+ const label2 = q ? answerLabel2(q) : void 0;
2661
+ if (!q || !label2 || label2 === TARGETS_NONE || label2 === TARGETS_SPLIT || label2 === TARGETS_ANOTHER)
2662
+ continue;
2663
+ const url = urlOf(f, r.facts);
2664
+ const host = url ? urlHostPort(url)?.host : void 0;
2665
+ const via = host ? `on ${host.toLowerCase()}` : f.base ? `through ${f.base}` : void 0;
2666
+ if (!via)
2667
+ continue;
2668
+ groups.set(via, [
2669
+ ...groups.get(via) ?? [],
2670
+ { repo: r.repo, q, label: label2, f, facts: r.facts, ...r.type ? { type: r.type } : {} }
2671
+ ]);
2672
+ }
2673
+ const out = [];
2674
+ for (const [via, xs] of [...groups].sort(([a], [b]) => a.localeCompare(b))) {
2675
+ const repos = [...new Set(xs.map((x) => x.repo))].sort();
2676
+ const labels = new Set(xs.map((x) => slugify(x.label)));
2677
+ if (repos.length < 2 || labels.size !== 1)
2678
+ continue;
2679
+ if (xs.every((x) => ruled.some((q) => ruleCoversCall(q.answer.match, x.f, x.facts))))
2680
+ continue;
2681
+ const label2 = xs[0].label;
2682
+ const prefixes = new Set(xs.map((x) => targetPathPrefix(x.f.path)));
2683
+ const prefix = prefixes.size === 1 ? [...prefixes][0] : void 0;
2684
+ const match = via.startsWith("on ") ? via.slice(3) : prefix && prefix !== "/" ? `${prefix}/**` : void 0;
2685
+ const types = new Set(xs.map((x) => x.type));
2686
+ const type = types.size === 1 ? xs[0].type : void 0;
2687
+ const questions = [...new Set(xs.map((x) => x.q.id))].sort();
2688
+ const first = xs.find((x) => x.q.id === questions[0]).q;
2689
+ const n = first.options.findIndex((o) => o.label === label2);
2690
+ const pick = n >= 0 ? `--option ${n + 1}` : `--text "${label2}"`;
2691
+ if (!match || !type)
2692
+ continue;
2693
+ const command = `atticus questions answer ${first.id} ${pick} --match ${match} --scope repo-type --type ${type}`;
2694
+ out.push({
2695
+ via,
2696
+ label: label2,
2697
+ repos,
2698
+ questions,
2699
+ match,
2700
+ type,
2701
+ command,
2702
+ line: `${repos.length} repos (${repos.join(", ")}) answer the calls ${via} the same way, ${label2} (${questions.join(", ")}): one answer can say it for every ${type} repo. As a rule: ${command}.`
2703
+ });
2704
+ }
2705
+ return out;
2706
+ }
2241
2707
 
2242
2708
  // packages/scanner/dist/facts-scan.js
2243
2709
  async function factsForScan(root, op, repo, commit, readerRecords, at3 = {}) {
@@ -2422,8 +2888,8 @@ async function checkScanSettings(s, repo) {
2422
2888
  if (!(isConfigFile(file) && names)) {
2423
2889
  const dropped = code.filter((f) => re.test(f));
2424
2890
  const root = mainRoots.find((d) => {
2425
- const under = code.filter((f) => f.startsWith(`${d}/`));
2426
- return under.length && under.every((f) => re.test(f));
2891
+ const under2 = code.filter((f) => f.startsWith(`${d}/`));
2892
+ return under2.length && under2.every((f) => re.test(f));
2427
2893
  });
2428
2894
  const why = " so it is still read; only a build or config file that leaves it out itself can say so";
2429
2895
  if (dropped.length * 2 > code.length) {
@@ -3329,8 +3795,8 @@ async function resolveSettingsTemplate(t, repo, repoId) {
3329
3795
  out.exclude.push({ path: e.path, why: e.why, at: `${first}:1` });
3330
3796
  }
3331
3797
  for (const rule of t.settings.prefixes) {
3332
- const candidates = (await files.matching(rule.files)).sort((a, b) => a.length - b.length || a.localeCompare(b));
3333
- for (const f of candidates) {
3798
+ const candidates2 = (await files.matching(rule.files)).sort((a, b) => a.length - b.length || a.localeCompare(b));
3799
+ for (const f of candidates2) {
3334
3800
  const hit = await readRule(rule, f, files);
3335
3801
  if (!hit)
3336
3802
  continue;
@@ -4054,7 +4520,7 @@ function parseEntry(s) {
4054
4520
  const m = /^([A-Za-z]+)\s+(\S+)$/.exec(s.trim());
4055
4521
  return m ? { method: m[1].toUpperCase(), path: m[2] } : { path: s.trim() };
4056
4522
  }
4057
- var segs = (p) => normalizePath(p).toLowerCase().split("/").filter(Boolean);
4523
+ var segs2 = (p) => normalizePath(p).toLowerCase().split("/").filter(Boolean);
4058
4524
  var sameMethod = (a, b) => !a || !b || a.toUpperCase() === b.toUpperCase();
4059
4525
  async function joinEstate(o) {
4060
4526
  const byId = new Map(o.records.map((r) => [r.id, r]));
@@ -4066,8 +4532,8 @@ async function joinEstate(o) {
4066
4532
  const out = [i.normalizedPath];
4067
4533
  const route = i.route ? byId.get(i.route) : void 0;
4068
4534
  if (route?.kind === "GatewayRoute") {
4069
- const base2 = segs(route.basepath);
4070
- const p = segs(i.normalizedPath);
4535
+ const base2 = segs2(route.basepath);
4536
+ const p = segs2(i.normalizedPath);
4071
4537
  if (base2.length && base2.every((s, k) => p[k] === s))
4072
4538
  out.push(`/${p.slice(base2.length).join("/")}`);
4073
4539
  }
@@ -4182,27 +4648,27 @@ async function joinEstate(o) {
4182
4648
  within = "estate";
4183
4649
  hits = servingExactly(flow.component, want);
4184
4650
  }
4185
- const candidates = [...new Set(hits.map((e) => e.component))].sort();
4186
- if (candidates.length === 0) {
4651
+ const candidates2 = [...new Set(hits.map((e) => e.component))].sort();
4652
+ if (candidates2.length === 0) {
4187
4653
  miss({
4188
4654
  reason: "no-target",
4189
4655
  message: `${s.to.component} isn't a component in the catalog, and neither an Interface from ${flow.component} nor an entry point of the estate serves ${s.to.entry}`
4190
4656
  });
4191
4657
  continue;
4192
4658
  }
4193
- if (candidates.length > 1) {
4194
- const repos = [...new Set(candidates.map(repoOfComponent))];
4659
+ if (candidates2.length > 1) {
4660
+ const repos = [...new Set(candidates2.map(repoOfComponent))];
4195
4661
  const of = repos.length === 1 && repos[0] ? repos[0] : "the estate";
4196
4662
  miss({
4197
4663
  reason: "no-target",
4198
- message: `${s.to.component} isn't a component in the catalog, and ${candidates.length} components of ${of} serve ${s.to.entry} (${candidates.join(", ")}): a person says which`
4664
+ message: `${s.to.component} isn't a component in the catalog, and ${candidates2.length} components of ${of} serve ${s.to.entry} (${candidates2.join(", ")}): a person says which`
4199
4665
  });
4200
4666
  asks.push({
4201
4667
  from,
4202
4668
  caller: flow.component,
4203
4669
  named: s.to.component,
4204
4670
  what: s.to.entry,
4205
- candidates
4671
+ candidates: candidates2
4206
4672
  });
4207
4673
  continue;
4208
4674
  }
@@ -4696,12 +5162,12 @@ function parseLinkReference(source) {
4696
5162
  return { ok: true, reference: { ...estate ? { estate } : {}, repos } };
4697
5163
  }
4698
5164
  var stripped = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
4699
- function segs2(path) {
5165
+ function segs3(path) {
4700
5166
  return path.split(/[?#]/)[0].split("/").filter(Boolean).map((s) => /^(\{[^}]*\}|:\w+|\*)$/.test(s) ? "{}" : s.toLowerCase());
4701
5167
  }
4702
5168
  function pathMatch(a, b) {
4703
- const x = segs2(a);
4704
- const y = segs2(b);
5169
+ const x = segs3(a);
5170
+ const y = segs3(b);
4705
5171
  if (x.length === y.length && x.every((s, i) => s === y[i]))
4706
5172
  return 2;
4707
5173
  const [short, long] = x.length < y.length ? [x, y] : [y, x];
@@ -4996,6 +5462,14 @@ export {
4996
5462
  estateMergeInput,
4997
5463
  mergeEstate,
4998
5464
  curatedDirOf,
5465
+ TARGETS_MAX_SUGGESTED,
5466
+ TARGETS_ANOTHER,
5467
+ nameWords,
5468
+ targetSuggestions,
5469
+ offeredSuggestions,
5470
+ targetPicker,
5471
+ pickerLines,
5472
+ topicQuestionDrafts,
4999
5473
  TARGETS_STEP,
5000
5474
  TARGETS_NONE,
5001
5475
  remapIds,
@@ -5009,6 +5483,8 @@ export {
5009
5483
  ruleCoversCall,
5010
5484
  ruledTargets,
5011
5485
  targetsFromAnswers,
5486
+ answeredQuestionOfCall,
5487
+ answerReconfirmed,
5012
5488
  staleTargetQuestions,
5013
5489
  componentRenames,
5014
5490
  factsRecords,
@@ -5020,6 +5496,7 @@ export {
5020
5496
  catalogWithFacts,
5021
5497
  prototypeLeftOut,
5022
5498
  estateFromFacts,
5499
+ answerRuleOffers,
5023
5500
  factsForScan,
5024
5501
  estateFacts,
5025
5502
  NO_SETTINGS,