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

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 (284) hide show
  1. package/dist/bin.js +8 -4
  2. package/dist/chunk-23XVSEV5.js +49 -0
  3. package/dist/{chunk-ZDPAS56H.js → chunk-24OXGB3P.js} +8 -2
  4. package/dist/{chunk-7EOBHUMC.js → chunk-24XLDU72.js} +4 -3
  5. package/dist/{chunk-CR3MTH32.js → chunk-2F4CYZKJ.js} +86 -11
  6. package/dist/{chunk-6IU67AEK.js → chunk-2GF7OLF3.js} +23 -15
  7. package/dist/chunk-2IIMFOPM.js +41 -0
  8. package/dist/chunk-2LGRMVCA.js +617 -0
  9. package/dist/{chunk-XPCM366L.js → chunk-2MMCFP5C.js} +10 -8
  10. package/dist/{chunk-JBTK5OP2.js → chunk-2Q56PQPS.js} +6 -4
  11. package/dist/{chunk-Z6LF7HQN.js → chunk-2Q5EDGEO.js} +7 -5
  12. package/dist/{chunk-3USYZGRF.js → chunk-2RLKFUUL.js} +38 -27
  13. package/dist/chunk-2SKB4O2E.js +59 -0
  14. package/dist/{chunk-SP2I63OO.js → chunk-34S2WGOB.js} +87 -4
  15. package/dist/{chunk-GQ4N4WKF.js → chunk-3NFFJL5D.js} +33 -27
  16. package/dist/{chunk-SJRGMG6A.js → chunk-3NWDLGG6.js} +28 -25
  17. package/dist/{chunk-4WBVUHXN.js → chunk-3RM4UK6W.js} +20 -18
  18. package/dist/chunk-42SIDKEU.js +583 -0
  19. package/dist/{chunk-GLUX4EEP.js → chunk-4EURQWQD.js} +20 -15
  20. package/dist/chunk-4U276ICE.js +39 -0
  21. package/dist/{chunk-ZMFPW66A.js → chunk-53T4O55J.js} +4 -3
  22. package/dist/{chunk-6J5OKA4Y.js → chunk-57TDNMI3.js} +17 -15
  23. package/dist/chunk-5BD2KYLE.js +57 -0
  24. package/dist/{chunk-7EFILTCI.js → chunk-5F7GFN2F.js} +28 -0
  25. package/dist/chunk-5NMKONLP.js +95 -0
  26. package/dist/{chunk-7ZUIMTOU.js → chunk-5SJZW52K.js} +26 -24
  27. package/dist/{chunk-4RS5KZQD.js → chunk-63YRMR6J.js} +6 -5
  28. package/dist/chunk-66PPNOON.js +62 -0
  29. package/dist/chunk-6H3Z5JHH.js +64 -0
  30. package/dist/{chunk-CEXSU4S6.js → chunk-6MUGR4LS.js} +775 -89
  31. package/dist/{chunk-QSXK2RGH.js → chunk-6OJQOPUN.js} +5 -3
  32. package/dist/{chunk-MVZVGYXH.js → chunk-6PPOWY5E.js} +84 -14
  33. package/dist/{chunk-7EKXJZ2Y.js → chunk-6ZGLAACW.js} +299 -38
  34. package/dist/chunk-6ZJ5A7AF.js +222 -0
  35. package/dist/{chunk-L24C55VN.js → chunk-745DAZ4L.js} +142 -30
  36. package/dist/{chunk-Q4D5X7QB.js → chunk-7ASNL4Q4.js} +46 -24
  37. package/dist/chunk-7BR7IPOH.js +35 -0
  38. package/dist/{chunk-7WD63HU2.js → chunk-7DOR27HL.js} +6 -6
  39. package/dist/chunk-7FTTA3HD.js +341 -0
  40. package/dist/{chunk-OLQJTJJU.js → chunk-7GJS6DNX.js} +12 -3
  41. package/dist/{chunk-7JUKDRSZ.js → chunk-7IGKHZ4Z.js} +347 -226
  42. package/dist/{chunk-G2B4ZQGH.js → chunk-7IOWA5D5.js} +11 -6
  43. package/dist/{chunk-EBEW3XXQ.js → chunk-7JITZFJC.js} +7 -5
  44. package/dist/chunk-7MJSQTL5.js +174 -0
  45. package/dist/{chunk-I4JRCD6M.js → chunk-7UOMVMFG.js} +25 -17
  46. package/dist/{chunk-YY6ZQQBP.js → chunk-AFWUDXEM.js} +19 -7
  47. package/dist/chunk-AFZ3QA6W.js +47 -0
  48. package/dist/chunk-AJQ72EBM.js +420 -0
  49. package/dist/chunk-AJYXNTNZ.js +317 -0
  50. package/dist/chunk-AVTBS4OW.js +49 -0
  51. package/dist/{chunk-FHH4I4ZV.js → chunk-BDKC6H5P.js} +12 -6
  52. package/dist/{chunk-IPKHE5D6.js → chunk-BEVTIBRH.js} +1526 -875
  53. package/dist/chunk-BHT7QK4G.js +162 -0
  54. package/dist/{chunk-6JUBZBMW.js → chunk-BIGDQDHD.js} +6 -4
  55. package/dist/{chunk-2BFCZ3RK.js → chunk-BO4KX37X.js} +20 -18
  56. package/dist/chunk-BPK5P77O.js +115 -0
  57. package/dist/chunk-BQ4SQQC6.js +59 -0
  58. package/dist/chunk-BQGDB6ZL.js +7342 -0
  59. package/dist/{chunk-2ANOROX3.js → chunk-BTGPE6CR.js} +11 -9
  60. package/dist/chunk-BTY3HZBO.js +93 -0
  61. package/dist/{chunk-DPZHZQKE.js → chunk-BXYMYEJ4.js} +44 -10
  62. package/dist/{chunk-2RMYG36Q.js → chunk-C3RY6KU6.js} +309 -346
  63. package/dist/chunk-C4R4JLHE.js +40 -0
  64. package/dist/chunk-CADWLE2T.js +18 -0
  65. package/dist/chunk-CBGGOQWU.js +82 -0
  66. package/dist/chunk-CMDXGQTS.js +47 -0
  67. package/dist/{chunk-MC3H7736.js → chunk-CQDGOPGH.js} +58 -18
  68. package/dist/{chunk-HFQCFSJR.js → chunk-CX4RZ2KS.js} +4 -3
  69. package/dist/{chunk-PAMPPUR6.js → chunk-CXJ6FUKN.js} +1852 -207
  70. package/dist/{chunk-ABWHYWNI.js → chunk-D73UEXYW.js} +3 -3
  71. package/dist/chunk-DCZWQLYT.js +1205 -0
  72. package/dist/chunk-DLOBCJL6.js +48 -0
  73. package/dist/{chunk-4BN53TG3.js → chunk-DOBQKHIF.js} +31 -23
  74. package/dist/chunk-E3ISYXO3.js +423 -0
  75. package/dist/{chunk-7SW2QWLU.js → chunk-E6ZIEVOI.js} +16 -13
  76. package/dist/chunk-EBL2R3YG.js +43 -0
  77. package/dist/{chunk-AIOQPLA5.js → chunk-EGQRREQH.js} +41 -15
  78. package/dist/chunk-EHA7RMZ3.js +58 -0
  79. package/dist/{chunk-M766ZJ6W.js → chunk-EIPTLPFC.js} +38 -27
  80. package/dist/chunk-EMRIQUND.js +517 -0
  81. package/dist/{chunk-DFBCSHVT.js → chunk-EPCJQQWD.js} +6 -4
  82. package/dist/{chunk-RZPYKDWS.js → chunk-F3P7N7SF.js} +1 -1
  83. package/dist/{chunk-R77KLRB3.js → chunk-FFLNS6VP.js} +21 -18
  84. package/dist/chunk-FFTRTL6R.js +26 -0
  85. package/dist/{chunk-IHMLFRVV.js → chunk-FPJPLKDW.js} +62 -16
  86. package/dist/{chunk-JCZIKA4C.js → chunk-FSMSFDLD.js} +5 -4
  87. package/dist/{chunk-AVJDSJ2F.js → chunk-FUJM6RTF.js} +8 -7
  88. package/dist/chunk-FZOJFH7Q.js +132 -0
  89. package/dist/{chunk-QRAOANID.js → chunk-G6X77UJZ.js} +23 -21
  90. package/dist/{chunk-3ALD2W2A.js → chunk-GCWRWSU7.js} +10 -4
  91. package/dist/chunk-GIW4ZVDB.js +39 -0
  92. package/dist/{chunk-B2WLAWNJ.js → chunk-GUX3PTYM.js} +3 -3
  93. package/dist/{chunk-DPUYDDQG.js → chunk-GZY6RUZ6.js} +25 -3
  94. package/dist/chunk-H4VO6WG3.js +10 -0
  95. package/dist/{chunk-MMOSZPWJ.js → chunk-H5HBGNXU.js} +5 -4
  96. package/dist/chunk-H7KM7LZE.js +229 -0
  97. package/dist/{chunk-AA6YULYB.js → chunk-HNM2YQT2.js} +7 -7
  98. package/dist/{chunk-3C7EYRFZ.js → chunk-HYU5VLGA.js} +1 -1
  99. package/dist/{chunk-XY3P7JW7.js → chunk-IDKCWSM5.js} +1032 -172
  100. package/dist/chunk-IFKEI4SA.js +237 -0
  101. package/dist/{chunk-F7HYOUFF.js → chunk-IGOE6KPG.js} +67 -22
  102. package/dist/{chunk-TDD55CJH.js → chunk-IH2XURVQ.js} +6 -5
  103. package/dist/chunk-INQHESFB.js +38 -0
  104. package/dist/chunk-IP74LCOQ.js +57 -0
  105. package/dist/chunk-IPHHDDC6.js +45 -0
  106. package/dist/{chunk-T6AIP7H5.js → chunk-ISUAAMGS.js} +110 -153
  107. package/dist/{chunk-A7UPUQFY.js → chunk-IUPG3UKI.js} +624 -319
  108. package/dist/{chunk-L6SGQIR3.js → chunk-IVBOQAGB.js} +7 -3
  109. package/dist/{chunk-27NKUS3X.js → chunk-J2JAKCIW.js} +2205 -796
  110. package/dist/{chunk-V2YTAIQO.js → chunk-J3IOLXWM.js} +24 -7
  111. package/dist/chunk-JA5FI3QV.js +142 -0
  112. package/dist/chunk-JAVI7JSP.js +49 -0
  113. package/dist/{chunk-HLJAXMM4.js → chunk-JB5LINEM.js} +6 -2
  114. package/dist/{chunk-2VHF7OXM.js → chunk-JENSEMXF.js} +1 -1
  115. package/dist/{chunk-6BVONWJ7.js → chunk-JJF6HALY.js} +4 -3
  116. package/dist/chunk-JLUCKAEL.js +38 -0
  117. package/dist/chunk-JRBFANFE.js +221 -0
  118. package/dist/{chunk-R6XF6UR3.js → chunk-KDNTAPLX.js} +4 -4
  119. package/dist/chunk-KFAVQZSX.js +33 -0
  120. package/dist/chunk-KJXD4PNL.js +50 -0
  121. package/dist/chunk-KN5BXMWN.js +44 -0
  122. package/dist/{chunk-PCVDV3UZ.js → chunk-KQGURXFU.js} +9 -7
  123. package/dist/{chunk-WY6PP6AA.js → chunk-KXITGYLF.js} +40 -6
  124. package/dist/{chunk-66YVAGGM.js → chunk-L27SV425.js} +22 -20
  125. package/dist/{chunk-NE2W3OO7.js → chunk-LDLL7LB3.js} +24 -22
  126. package/dist/chunk-LFGTYX5U.js +379 -0
  127. package/dist/{chunk-EYWIDJFU.js → chunk-LGBMTVNT.js} +7 -5
  128. package/dist/{chunk-Q5AMFEWD.js → chunk-LGFL54FP.js} +3 -2
  129. package/dist/{chunk-6TACQN3N.js → chunk-LJXMYKZJ.js} +7 -5
  130. package/dist/{chunk-BKVWTZ6A.js → chunk-LKOR5UET.js} +29 -26
  131. package/dist/chunk-LNBQOP7D.js +294 -0
  132. package/dist/{chunk-O3WI5KWW.js → chunk-LO6P2VYG.js} +2 -2
  133. package/dist/chunk-LQJPN536.js +122 -0
  134. package/dist/{chunk-YEDDOYSC.js → chunk-LYBNHMVZ.js} +29 -5
  135. package/dist/{chunk-A3GY6SOA.js → chunk-LZ7NUC62.js} +20 -18
  136. package/dist/chunk-M32BLWDH.js +37 -0
  137. package/dist/{chunk-VYDBJ73M.js → chunk-M3NANSDZ.js} +17 -15
  138. package/dist/chunk-MFHL5URL.js +31 -0
  139. package/dist/chunk-MFR5OPBD.js +109 -0
  140. package/dist/{chunk-DE76JROX.js → chunk-MG4ZL5RW.js} +32 -20
  141. package/dist/{chunk-N7IXEHK3.js → chunk-MO6P2JZH.js} +10 -8
  142. package/dist/{chunk-65NYPGRC.js → chunk-MUWDB4R4.js} +1 -1
  143. package/dist/chunk-MZCGSXVR.js +34 -0
  144. package/dist/{chunk-MGYZM27B.js → chunk-N3XIYPU3.js} +51 -23
  145. package/dist/chunk-NDCF4R6S.js +172 -0
  146. package/dist/{chunk-DHPACDG7.js → chunk-NR2UJWOC.js} +10 -8
  147. package/dist/chunk-NXJ5URP6.js +51 -0
  148. package/dist/{chunk-UNM6ZOKP.js → chunk-NY2XSR5K.js} +147 -18
  149. package/dist/{chunk-5GDRCDQB.js → chunk-O45HFTFS.js} +3 -2
  150. package/dist/{chunk-ONLS5QA5.js → chunk-O4GXGGBX.js} +14 -12
  151. package/dist/chunk-O5PXQR67.js +249 -0
  152. package/dist/{chunk-PRPPGYZG.js → chunk-O66DM6DJ.js} +6 -4
  153. package/dist/{chunk-KEM4SDDP.js → chunk-O7FDLW7L.js} +11 -8
  154. package/dist/{chunk-T2UYZSCQ.js → chunk-O7XLYEFA.js} +169 -29
  155. package/dist/{chunk-FITWGOJ2.js → chunk-OHNCWBKF.js} +4 -4
  156. package/dist/{chunk-652QWTLZ.js → chunk-OHVTTOPS.js} +3 -3
  157. package/dist/chunk-OMI6FPPN.js +43 -0
  158. package/dist/chunk-ONUPY3H6.js +53 -0
  159. package/dist/chunk-OTLDSZDV.js +69 -0
  160. package/dist/chunk-OUBGGKDU.js +22 -0
  161. package/dist/chunk-OWNCM4ZN.js +330 -0
  162. package/dist/{chunk-YISXLPHN.js → chunk-P2V7QW4D.js} +235 -35
  163. package/dist/{chunk-CNUKCS2T.js → chunk-P32RUW3B.js} +1632 -93
  164. package/dist/{chunk-BWZ77RQT.js → chunk-PAQ2AS5E.js} +1 -1
  165. package/dist/{chunk-ZMAINWBW.js → chunk-PBPBMP2B.js} +4 -3
  166. package/dist/{chunk-ZVM6AKKM.js → chunk-PJSJPMJI.js} +3 -3
  167. package/dist/{chunk-EFHQ3TWP.js → chunk-PKBHS4AA.js} +233 -56
  168. package/dist/{chunk-GT4I4ZWM.js → chunk-PMUAJGLI.js} +20 -16
  169. package/dist/chunk-PPD7HTDP.js +152 -0
  170. package/dist/chunk-PSOFBQWB.js +42 -0
  171. package/dist/{chunk-S2A7YC3Q.js → chunk-Q2TECDIT.js} +10694 -8896
  172. package/dist/chunk-Q4K5WB2W.js +42 -0
  173. package/dist/{chunk-UGLN7QHV.js → chunk-Q6DFNVRJ.js} +14 -12
  174. package/dist/chunk-QA4O2GGC.js +265 -0
  175. package/dist/chunk-QAXW2N3B.js +1216 -0
  176. package/dist/chunk-QBNWF5ZU.js +19 -0
  177. package/dist/chunk-QFWA2DPH.js +224 -0
  178. package/dist/{chunk-23W7VWKR.js → chunk-QKUJMING.js} +1363 -114
  179. package/dist/{chunk-NXFPS2LR.js → chunk-R44CYFPV.js} +16 -13
  180. package/dist/{chunk-CKSITVS4.js → chunk-R7NYHMUU.js} +2687 -786
  181. package/dist/chunk-REWWDVQB.js +162 -0
  182. package/dist/{chunk-JMSCMUCA.js → chunk-RGERPOIV.js} +145 -21
  183. package/dist/{chunk-6JCPI55B.js → chunk-RLDGWLQ7.js} +49 -7
  184. package/dist/chunk-RUGXBPWI.js +384 -0
  185. package/dist/{chunk-CPA6HPVR.js → chunk-RXPJMEOW.js} +18 -12
  186. package/dist/{chunk-3HI6Z55Y.js → chunk-S4PMJU6H.js} +339 -43
  187. package/dist/chunk-S5LSDXV4.js +40 -0
  188. package/dist/chunk-S7FCV7S5.js +51 -0
  189. package/dist/{chunk-5GGOLAKC.js → chunk-SDKLKB6I.js} +28 -26
  190. package/dist/chunk-SFSPGFCV.js +62 -0
  191. package/dist/{chunk-ZNCEKR4J.js → chunk-SFUP7TTO.js} +12 -8
  192. package/dist/{chunk-64EQYWCA.js → chunk-SLXZOMA6.js} +69 -19
  193. package/dist/chunk-SQV37XO2.js +273 -0
  194. package/dist/{chunk-K65BJIMT.js → chunk-SU74NDMQ.js} +19 -17
  195. package/dist/chunk-SYV5LHML.js +165 -0
  196. package/dist/chunk-T4YPZIQN.js +36 -0
  197. package/dist/chunk-T6DQR5TV.js +323 -0
  198. package/dist/{chunk-JIITQXFB.js → chunk-THDMSZ3R.js} +3075 -802
  199. package/dist/{chunk-JGZCG5VM.js → chunk-TNR75OXT.js} +7 -7
  200. package/dist/{chunk-D3PO4DOZ.js → chunk-TUULXQRW.js} +174 -15
  201. package/dist/chunk-TYQBFTBR.js +516 -0
  202. package/dist/chunk-U76OWS3Q.js +49 -0
  203. package/dist/{chunk-YYQN46FY.js → chunk-UCROWG2D.js} +27 -24
  204. package/dist/{chunk-6M5NK3K3.js → chunk-UF4AZOZB.js} +50 -10
  205. package/dist/chunk-UF4GLFBX.js +345 -0
  206. package/dist/{chunk-OT2O76OS.js → chunk-UGUP3ZM6.js} +240 -39
  207. package/dist/chunk-UNAGJYET.js +45 -0
  208. package/dist/{chunk-5WG5YP4T.js → chunk-UOR2DTHH.js} +16 -14
  209. package/dist/{chunk-S3QNRWYR.js → chunk-UPOY4YSQ.js} +14 -12
  210. package/dist/{chunk-EPTBZ3GP.js → chunk-UPS2DGFC.js} +1 -1
  211. package/dist/{chunk-4AK7IBVP.js → chunk-UUU4CLJG.js} +4 -2
  212. package/dist/{chunk-W3BQAZ3Q.js → chunk-UWMJKX5U.js} +14 -12
  213. package/dist/{chunk-QZSX3F7C.js → chunk-UWOJLHFT.js} +27 -23
  214. package/dist/chunk-VBTP56CE.js +535 -0
  215. package/dist/chunk-VCTWPLAO.js +211 -0
  216. package/dist/chunk-VNU26RCO.js +1215 -0
  217. package/dist/{chunk-CSZ4C5N6.js → chunk-VTZMAJ3W.js} +93 -10
  218. package/dist/{chunk-TXLH6WHQ.js → chunk-VW62D6QE.js} +14 -12
  219. package/dist/{chunk-CAQZUNOH.js → chunk-VY72R2XZ.js} +610 -3
  220. package/dist/{chunk-2DIQQJCB.js → chunk-VZALIKIF.js} +18 -15
  221. package/dist/{chunk-TYAID7B7.js → chunk-W62H2XSO.js} +25 -23
  222. package/dist/{chunk-HVUPKCGJ.js → chunk-W7VWI2YH.js} +9 -6
  223. package/dist/{chunk-TANFV3MZ.js → chunk-WERM6KPJ.js} +7 -4
  224. package/dist/{chunk-BOHJZTEQ.js → chunk-WF7B67YE.js} +208 -87
  225. package/dist/{chunk-7FBGJFEE.js → chunk-WG5U3F5V.js} +14 -12
  226. package/dist/{chunk-4NDAAFQT.js → chunk-WJF2CS6M.js} +8 -5
  227. package/dist/{chunk-XAKWMCXI.js → chunk-WKUJ3KPV.js} +4 -4
  228. package/dist/chunk-WMTRHUI5.js +103 -0
  229. package/dist/chunk-WNKPRSGI.js +36 -0
  230. package/dist/chunk-WXFLMQSR.js +223 -0
  231. package/dist/{chunk-RRTKKSLQ.js → chunk-X3WY6MN3.js} +8 -6
  232. package/dist/{chunk-ZCJDOK2S.js → chunk-X4CXA2IL.js} +47 -23
  233. package/dist/{chunk-UBBC2XSG.js → chunk-X5F3Q5LV.js} +560 -105
  234. package/dist/{chunk-C6EKFH7J.js → chunk-XD75VZIH.js} +9 -7
  235. package/dist/chunk-XERYFDB5.js +297 -0
  236. package/dist/chunk-XI2LCCYQ.js +420 -0
  237. package/dist/chunk-Y2EQNWKV.js +933 -0
  238. package/dist/{chunk-LR3R6Z2A.js → chunk-YHCMZC2J.js} +7 -7
  239. package/dist/chunk-YYY3AZFE.js +122 -0
  240. package/dist/{chunk-GDLULHTC.js → chunk-Z5IA3WDR.js} +19 -31
  241. package/dist/{chunk-T6XQL73F.js → chunk-ZFFYNRIO.js} +63 -23
  242. package/dist/{chunk-EDS2L2LD.js → chunk-ZFL7NY4F.js} +56 -27
  243. package/dist/{chunk-YMZ3TNYB.js → chunk-ZGULQAPZ.js} +7 -4
  244. package/dist/{chunk-4SKZDI62.js → chunk-ZIUFM5HT.js} +3 -1
  245. package/dist/{chunk-DKJA76CJ.js → chunk-ZJFRMSJT.js} +15 -13
  246. package/dist/chunk-ZJXLNDH4.js +239 -0
  247. package/dist/chunk-ZQ3ON2VQ.js +252 -0
  248. package/dist/{chunk-HITVBIJS.js → chunk-ZQ7SKESZ.js} +150 -415
  249. package/dist/{chunk-6QSERWXH.js → chunk-ZQXZ2SES.js} +24 -21
  250. package/dist/chunk-ZX57KSEQ.js +39 -0
  251. package/dist/{chunk-I3E7CX4H.js → chunk-ZZK56BLP.js} +5 -3
  252. package/dist/files.json +664 -368
  253. package/dist/packages/naysayer/constitution/constitution.yaml +19 -0
  254. package/dist/packages/sdk/npm/index.js +6194 -2542
  255. package/dist/packages/ui/dist/assets/{elk-api-tma0MCuh.js → elk-api-CIf-0gz5.js} +2 -2
  256. package/dist/packages/ui/dist/assets/index-CoK_Dl0D.js +47 -0
  257. package/dist/packages/ui/dist/assets/index-Dw20IRhQ.css +1 -0
  258. package/dist/packages/ui/dist/index.html +3 -2
  259. package/package.json +5 -5
  260. package/dist/chunk-2BF2EYJV.js +0 -174
  261. package/dist/chunk-42EVSKME.js +0 -37
  262. package/dist/chunk-4BKGMUIK.js +0 -53
  263. package/dist/chunk-5KLGBXG5.js +0 -48
  264. package/dist/chunk-6BNC6EQ4.js +0 -41
  265. package/dist/chunk-6D2CQ5II.js +0 -41
  266. package/dist/chunk-7AVHLZGD.js +0 -45
  267. package/dist/chunk-D46WUV3T.js +0 -33
  268. package/dist/chunk-E36QOJMD.js +0 -47
  269. package/dist/chunk-FQXYPF7E.js +0 -147
  270. package/dist/chunk-GBRFVT63.js +0 -45
  271. package/dist/chunk-ICY36XCH.js +0 -34
  272. package/dist/chunk-J4K3KVLD.js +0 -131
  273. package/dist/chunk-JZU3H6UQ.js +0 -54
  274. package/dist/chunk-NN2ZQEB4.js +0 -38
  275. package/dist/chunk-PCOCACY3.js +0 -385
  276. package/dist/chunk-RTEYOSJY.js +0 -29
  277. package/dist/chunk-RUVFXE2L.js +0 -666
  278. package/dist/chunk-RVH5SUW5.js +0 -69
  279. package/dist/chunk-VN3DP4LQ.js +0 -43
  280. package/dist/chunk-W5BVQF44.js +0 -36
  281. package/dist/chunk-WVPJSRRJ.js +0 -52
  282. package/dist/chunk-XPTOBS2D.js +0 -48
  283. package/dist/packages/ui/dist/assets/index-B54fm9FQ.js +0 -29
  284. package/dist/packages/ui/dist/assets/index-DD_hufQz.css +0 -1
@@ -7,27 +7,30 @@ import {
7
7
  documentFormat,
8
8
  drawioIngestor,
9
9
  officeFormat,
10
+ parseCsv,
10
11
  readDocument,
11
12
  readDrawio,
12
13
  readMermaid,
13
14
  resolveNames
14
- } from "./chunk-7EKXJZ2Y.js";
15
+ } from "./chunk-6ZGLAACW.js";
15
16
  import {
16
17
  openapiExtractor,
17
18
  readOpenApiDocument
18
- } from "./chunk-MC3H7736.js";
19
+ } from "./chunk-CQDGOPGH.js";
19
20
  import {
20
21
  combine,
21
22
  formatOf,
22
23
  screenDiagramXml,
23
24
  screenOfficeXml,
24
25
  screenText
25
- } from "./chunk-CNUKCS2T.js";
26
+ } from "./chunk-P32RUW3B.js";
26
27
  import {
28
+ TrafficFile,
27
29
  endpointId,
28
30
  entryEndpointId,
29
31
  factIdPart,
30
32
  fieldNameKey,
33
+ interfaceId,
31
34
  joinFacts,
32
35
  joinVendorOperations,
33
36
  loadOrgPack,
@@ -35,12 +38,16 @@ import {
35
38
  orgPackDirOf,
36
39
  parseRecord,
37
40
  readZip,
38
- require_dist,
39
- toCanonicalYaml
40
- } from "./chunk-S2A7YC3Q.js";
41
+ routeScore,
42
+ toCanonicalYaml,
43
+ trafficFileText
44
+ } from "./chunk-Q2TECDIT.js";
41
45
  import {
42
46
  writeFileAtomic
43
- } from "./chunk-D3PO4DOZ.js";
47
+ } from "./chunk-TUULXQRW.js";
48
+ import {
49
+ require_dist
50
+ } from "./chunk-BQGDB6ZL.js";
44
51
  import {
45
52
  __toESM
46
53
  } from "./chunk-TV45EUGM.js";
@@ -122,6 +129,151 @@ function fromData(data) {
122
129
  }
123
130
  return void 0;
124
131
  }
132
+ var STRICT_ALIASES = 100;
133
+ var LENIENT_ALIASES = 1e4;
134
+ var LENIENT = { uniqueKeys: false, maxAliasCount: LENIENT_ALIASES };
135
+ var reasonOf = (e) => e.message.split("\n")[0].replace(/\s+at line \d+, column \d+:?\s*$/, "").trim();
136
+ var unreadableOf = (e) => ({
137
+ reason: reasonOf(e),
138
+ ...e.linePos?.[0] ? { line: e.linePos[0].line, column: e.linePos[0].col } : {}
139
+ });
140
+ function duplicateKeys(text3) {
141
+ const lines = text3.split(/\r?\n/);
142
+ return (0, import_yaml.parseDocument)(text3).errors.filter((e) => e.code === "DUPLICATE_KEY" && e.linePos?.[0]).map((e) => {
143
+ const { line, col } = e.linePos[0];
144
+ const key3 = /^\s*["']?([^"':]+)["']?\s*:/.exec((lines[line - 1] ?? "").slice(col - 1))?.[1];
145
+ return `duplicate key ${key3 ? `"${key3.trim()}" ` : ""}at ${line}:${col}: the last one is kept`;
146
+ });
147
+ }
148
+ function braceBalance(line) {
149
+ let n = 0;
150
+ let quote;
151
+ for (let i = 0; i < line.length; i++) {
152
+ const c = line[i];
153
+ if (quote) {
154
+ if (c === "\\" && quote === '"')
155
+ i++;
156
+ else if (c === quote)
157
+ quote = void 0;
158
+ } else if (c === '"' || c === "'")
159
+ quote = c;
160
+ else if (c === "#" && (i === 0 || /\s/.test(line[i - 1])))
161
+ return NaN;
162
+ else if (c === "{")
163
+ n++;
164
+ else if (c === "}")
165
+ n--;
166
+ }
167
+ return quote ? NaN : n;
168
+ }
169
+ var indentOf = (l) => /^\s*/.exec(l)[0].length;
170
+ var blank = (l) => !l.trim() || /^\s*#/.test(l);
171
+ function joinServerVariables(text3) {
172
+ const lines = text3.split(/\r?\n/);
173
+ const at = [];
174
+ let servers;
175
+ let vars;
176
+ for (let i = 0; i < lines.length; i++) {
177
+ const l = lines[i];
178
+ if (blank(l))
179
+ continue;
180
+ const ind = indentOf(l);
181
+ if (vars !== void 0 && ind <= vars)
182
+ vars = void 0;
183
+ if (servers !== void 0 && ind <= servers && !/^\s*-(\s|$)/.test(l))
184
+ servers = void 0;
185
+ if (servers !== void 0 && ind < servers)
186
+ servers = void 0;
187
+ if (/^\s*["']?servers["']?\s*:\s*$/.test(l)) {
188
+ servers = ind;
189
+ vars = void 0;
190
+ continue;
191
+ }
192
+ if (servers === void 0)
193
+ continue;
194
+ const v = /^(\s*)(-\s+)?["']?variables["']?\s*:\s*$/.exec(l);
195
+ if (v) {
196
+ vars = v[1].length + (v[2]?.length ?? 0);
197
+ continue;
198
+ }
199
+ if (vars === void 0)
200
+ continue;
201
+ const m = /^(\s*)(["']?[\w.-]+["']?)\s*:\s*(\{.*)$/.exec(l);
202
+ if (!m)
203
+ continue;
204
+ let balance = braceBalance(m[3]);
205
+ if (Number.isNaN(balance))
206
+ return void 0;
207
+ const parts = [m[3].trim()];
208
+ let j = i;
209
+ while (balance > 0) {
210
+ j++;
211
+ if (j >= lines.length || j - i > 200)
212
+ return void 0;
213
+ const b = braceBalance(lines[j]);
214
+ if (Number.isNaN(b))
215
+ return void 0;
216
+ balance += b;
217
+ parts.push(lines[j].trim());
218
+ }
219
+ if (balance < 0)
220
+ return void 0;
221
+ const joined = `${m[1]}${m[2]}: ${parts.filter(Boolean).join(" ")}`;
222
+ if (joined === l && j === i)
223
+ continue;
224
+ lines[i] = joined;
225
+ for (let k = i + 1; k <= j; k++)
226
+ lines[k] = "";
227
+ at.push(i + 1);
228
+ i = j;
229
+ }
230
+ return at.length ? { text: lines.join("\n"), at } : void 0;
231
+ }
232
+ var SPEC_KINDS = ["openapi", "swagger", "asyncapi"];
233
+ function readYaml(text3) {
234
+ let first;
235
+ try {
236
+ return { data: (0, import_yaml.parse)(text3) };
237
+ } catch (e) {
238
+ first = e;
239
+ }
240
+ const notes = [];
241
+ const dup = first.code === "DUPLICATE_KEY";
242
+ const aliases = /alias count/i.test(first.message);
243
+ const lenient = (t) => {
244
+ try {
245
+ return { data: (0, import_yaml.parse)(t, LENIENT) };
246
+ } catch (e) {
247
+ return { error: e };
248
+ }
249
+ };
250
+ const notesOf = (t) => {
251
+ const out = duplicateKeys(t);
252
+ try {
253
+ (0, import_yaml.parse)(t, { uniqueKeys: false });
254
+ } catch (e) {
255
+ if (/alias count/i.test(e.message))
256
+ out.push(`more aliases than the strict parser allows (${STRICT_ALIASES}): read with a higher limit (${LENIENT_ALIASES})`);
257
+ }
258
+ return out;
259
+ };
260
+ if (dup || aliases) {
261
+ const r = lenient(text3);
262
+ if ("data" in r)
263
+ return { data: r.data, notes: notesOf(text3) };
264
+ }
265
+ const fixed = joinServerVariables(text3);
266
+ if (fixed) {
267
+ const r = lenient(fixed.text);
268
+ if ("data" in r && SPEC_KINDS.includes(fromData(r.data)?.classification ?? "unknown")) {
269
+ notes.push(...notesOf(fixed.text));
270
+ const lines = fixed.at.length === 1 ? `line ${fixed.at[0]} is a flow mapping` : `lines ${fixed.at.slice(0, -1).join(", ")} and ${fixed.at.at(-1)} are flow mappings`;
271
+ notes.push(`servers[].variables at ${lines} written over several lines, not indented past ${fixed.at.length === 1 ? "its key: read as if it were" : "their key: read as if each were"} on one line`);
272
+ return { data: r.data, notes, text: fixed.text };
273
+ }
274
+ }
275
+ return { error: first };
276
+ }
125
277
  function classify(fileName, bytes) {
126
278
  const name = fileName.toLowerCase();
127
279
  const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1) : "";
@@ -163,19 +315,26 @@ function classify(fileName, bytes) {
163
315
  return { classification: "diagram" };
164
316
  if (/^<(!doctype html|html)\b/i.test(head))
165
317
  return { classification: "document" };
318
+ if (ext === "proto" || /^(syntax\s*=\s*["']proto[23]["']|package\s+[\w.]+\s*;)/m.test(head))
319
+ return { classification: "protobuf" };
320
+ if (ext === "avsc" || /^\{/.test(head) && /"type"\s*:\s*"record"/.test(head) && /"fields"\s*:/.test(head))
321
+ return { classification: "avro" };
166
322
  if (["json", "yaml", "yml"].includes(ext) || /^[[{]/.test(head)) {
167
- let data;
168
- try {
169
- data = (0, import_yaml.parse)(text3);
170
- } catch {
171
- data = void 0;
172
- }
323
+ const r = readYaml(text3);
324
+ const named = ["json", "yaml", "yml"].includes(ext);
325
+ if ("error" in r && named)
326
+ return { classification: "unknown", unreadable: unreadableOf(r.error) };
327
+ const data = "data" in r ? r.data : void 0;
328
+ const lenient = {
329
+ ..."notes" in r && r.notes?.length ? { notes: r.notes } : {},
330
+ ..."text" in r && r.text !== void 0 ? { text: r.text } : {}
331
+ };
173
332
  const known = fromData(data);
174
333
  if (known)
175
- return known;
334
+ return { ...known, ...lenient };
176
335
  if (ext === "json" || /^[[{]/.test(head)) {
177
336
  if (isObj(data) || Array.isArray(data))
178
- return { classification: "payload", data };
337
+ return { classification: "payload", data, ...lenient };
179
338
  }
180
339
  if (ext === "yaml" || ext === "yml")
181
340
  return { classification: "unknown" };
@@ -195,7 +354,10 @@ import { createHash } from "node:crypto";
195
354
  var READERS = {
196
355
  openapi: `${openapiExtractor.id}@${openapiExtractor.version}`,
197
356
  asyncapi: "asyncapi@0.1.0",
198
- payload: "payload@0.1.0"
357
+ payload: "payload@0.1.0",
358
+ // ADR 0164: a topic's message spec.
359
+ protobuf: "protobuf@0.1.0",
360
+ avro: "avro@0.1.0"
199
361
  };
200
362
  var short = (s) => createHash("sha256").update(s).digest("hex").slice(0, 6);
201
363
  function oneFile(path, text3) {
@@ -365,8 +527,8 @@ var KIND_ORDER = [
365
527
  "needs-reading"
366
528
  ];
367
529
  var slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
368
- function boundedId(prefix, key2) {
369
- const id = `${prefix}${key2}`;
530
+ function boundedId(prefix, key3) {
531
+ const id = `${prefix}${key3}`;
370
532
  if (id.length <= 120)
371
533
  return id;
372
534
  return `${id.slice(0, 110)}-${createHash2("sha256").update(id).digest("hex").slice(0, 8)}`;
@@ -411,9 +573,9 @@ var opt = {
411
573
  };
412
574
 
413
575
  // packages/intake/dist/scan-inputs.js
414
- import { createHash as createHash4 } from "node:crypto";
415
- import { readdir, readFile, stat } from "node:fs/promises";
416
- import { join, relative, resolve, sep } from "node:path";
576
+ import { createHash as createHash5 } from "node:crypto";
577
+ import { readdir as readdir2, readFile as readFile2, stat as stat2 } from "node:fs/promises";
578
+ import { join as join2, relative, resolve, sep } from "node:path";
417
579
 
418
580
  // packages/intake/dist/screen-file.js
419
581
  var PK = (b) => b[0] === 80 && b[1] === 75;
@@ -455,10 +617,314 @@ function screenFile(path, bytes) {
455
617
  }
456
618
  }
457
619
 
620
+ // packages/intake/dist/contract-specs.js
621
+ var import_yaml4 = __toESM(require_dist(), 1);
622
+ import { readdir, readFile, stat } from "node:fs/promises";
623
+ import { join } from "node:path";
624
+
625
+ // packages/intake/dist/traffic.js
626
+ import { createHash as createHash3 } from "node:crypto";
627
+ var cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;
628
+ var key = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
629
+ var sha = (s) => createHash3("sha256").update(s, "utf8").digest("hex");
630
+ var IPV4 = /\b\d{1,3}(?:\.\d{1,3}){3}\b/;
631
+ var IPV6 = /[0-9a-f]{0,4}::[0-9a-f]{0,4}|\b[0-9a-f]{1,4}(?::[0-9a-f]{1,4}){2,7}\b/i;
632
+ var EMAIL = /[^\s@/]+@[^\s@/]+/;
633
+ var JWT = /\beyJ[A-Za-z0-9_-]{6,}/;
634
+ var OPAQUE = /\b(?=[A-Za-z0-9+_-]*\d)(?=[A-Za-z0-9+_-]*[A-Za-z])[A-Za-z0-9+_-]{24,}={0,2}/;
635
+ var UUID = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i;
636
+ var HEX = /\b[0-9a-f]{16,}\b/i;
637
+ function looksSensitive(v) {
638
+ return [IPV4, IPV6, EMAIL, JWT, OPAQUE, UUID, HEX].some((re) => re.test(v));
639
+ }
640
+ function rowsOf(text3) {
641
+ const t = text3.replace(/^\uFEFF/, "").trim();
642
+ if (!t)
643
+ return void 0;
644
+ if (t.startsWith("[") || t.startsWith("{")) {
645
+ let v;
646
+ try {
647
+ v = JSON.parse(t);
648
+ } catch {
649
+ return void 0;
650
+ }
651
+ const list2 = Array.isArray(v) ? v : v && typeof v === "object" ? ["rows", "data", "records", "items"].map((k) => v[k]).find((x) => Array.isArray(x)) : void 0;
652
+ if (!Array.isArray(list2) || !list2.length)
653
+ return void 0;
654
+ const out = [];
655
+ for (const r of list2) {
656
+ if (!r || typeof r !== "object" || Array.isArray(r))
657
+ return void 0;
658
+ const row = {};
659
+ for (const [k, x] of Object.entries(r))
660
+ if (typeof x === "string" || typeof x === "number")
661
+ row[k] = String(x);
662
+ out.push(row);
663
+ }
664
+ return out;
665
+ }
666
+ const recs = parseCsv(t);
667
+ if (recs.length < 2)
668
+ return void 0;
669
+ const head = recs[0].cells.map((c) => c.trim());
670
+ if (head.length < 2)
671
+ return void 0;
672
+ return recs.slice(1).map((r) => {
673
+ const row = {};
674
+ head.forEach((h, i) => row[h] = (r.cells[i] ?? "").trim());
675
+ return row;
676
+ });
677
+ }
678
+ function dayOf(v) {
679
+ const m = /^(\d{4}-\d{2}-\d{2})/.exec(v.trim());
680
+ if (m)
681
+ return m[1];
682
+ if (/^\d{12,13}$/.test(v.trim()))
683
+ return new Date(Number(v)).toISOString().slice(0, 10);
684
+ return void 0;
685
+ }
686
+ var VERSION = /^v\d+(?:\.\d+)*$/i;
687
+ var PARAM = /^(?:\{[A-Za-z_][A-Za-z0-9_.-]{0,40}\}|:[A-Za-z_][A-Za-z0-9_]{0,40}|<[A-Za-z_][A-Za-z0-9_:]{0,40}>)$/;
688
+ var segmentOf = (s) => VERSION.test(s) || PARAM.test(s) || /^[a-z][a-z._-]*$/.test(s) && s.length <= 20 && /[aeiou]/.test(s) && !looksSensitive(s) ? s : "{id}";
689
+ function barePath(path) {
690
+ let p = path.trim().split(/[?#]/, 1)[0] ?? "";
691
+ p = p.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]*/i, "");
692
+ return p.replace(/;[^/]*/g, "");
693
+ }
694
+ function safePathOf(path) {
695
+ const p = barePath(path);
696
+ if (!p.startsWith("/"))
697
+ return void 0;
698
+ return `/${p.split("/").filter(Boolean).map(segmentOf).join("/")}`;
699
+ }
700
+ var MATCH = 100;
701
+ function pathTemplateOf(path, templates) {
702
+ const p = barePath(path);
703
+ if (!p.startsWith("/"))
704
+ return void 0;
705
+ const sorted2 = [...templates].sort();
706
+ let best;
707
+ let score = 0;
708
+ for (const t of sorted2) {
709
+ const s = routeScore(p, t);
710
+ if (s > MATCH && s > score) {
711
+ score = s;
712
+ best = t;
713
+ }
714
+ }
715
+ if (best)
716
+ return best;
717
+ const segs = p.split("/").filter(Boolean);
718
+ let prefix;
719
+ let len = 0;
720
+ score = 0;
721
+ for (const t of sorted2) {
722
+ const n = t.split("/").filter(Boolean).length;
723
+ if (n === 0 || n >= segs.length || n < len)
724
+ continue;
725
+ const s = routeScore(`/${segs.slice(0, n).join("/")}`, t);
726
+ if (s <= MATCH)
727
+ continue;
728
+ if (n > len || s > score) {
729
+ len = n;
730
+ score = s;
731
+ prefix = t;
732
+ }
733
+ }
734
+ return prefix ? `${prefix.replace(/\/+$/, "")}/**` : void 0;
735
+ }
736
+ var appLabelOf = (name) => `app-${sha(name).slice(0, 8)}`;
737
+ function denyListHits(text3, hashes) {
738
+ const hits = [];
739
+ text3.toLowerCase().split("\n").forEach((line, i) => {
740
+ const w = line.match(/[a-z0-9]+/g) ?? [];
741
+ for (let k = 0; k < w.length; k++)
742
+ if (hashes.has(sha(w[k])) || k + 1 < w.length && hashes.has(sha(`${w[k]} ${w[k + 1]}`))) {
743
+ hits.push(i + 1);
744
+ break;
745
+ }
746
+ });
747
+ return hits;
748
+ }
749
+ function aggregateTraffic(input) {
750
+ const text3 = Buffer.from(input.bytes).toString("utf8");
751
+ const rows = rowsOf(text3);
752
+ const shape = `a CSV with a header row, or a JSON list of rows, with an app, a method and a path column (${input.source}: app ${input.columns.app.join("/")}; method ${input.columns.method.join("/")}; path ${[...input.columns.path, ...input.columns.basepath].join("/")})`;
753
+ if (!rows)
754
+ return { ok: false, message: `The file doesn't read as a traffic export: give ${shape}.` };
755
+ const names = [...new Set(rows.flatMap((r) => Object.keys(r)))];
756
+ const col = (aliases) => {
757
+ for (const a of aliases) {
758
+ const hit = names.find((n) => key(n) === key(a));
759
+ if (hit)
760
+ return hit;
761
+ }
762
+ return void 0;
763
+ };
764
+ const c = {
765
+ app: col(input.columns.app),
766
+ method: col(input.columns.method),
767
+ basepath: col(input.columns.basepath),
768
+ suffix: col(input.columns.suffix),
769
+ proxy: col(input.columns.proxy),
770
+ count: col(input.columns.count),
771
+ time: col(input.columns.time),
772
+ path: void 0
773
+ };
774
+ if (!c.basepath || !c.suffix)
775
+ c.path = col(input.columns.path);
776
+ const missing = [
777
+ !c.app ? "app" : "",
778
+ !c.method ? "method" : "",
779
+ !c.path && !(c.basepath && c.suffix) ? "path" : ""
780
+ ].filter(Boolean);
781
+ if (missing.length)
782
+ return {
783
+ ok: false,
784
+ message: `The file has no ${missing.join(", ")} column, so it can't be kept as aggregates: give ${shape}.`
785
+ };
786
+ const range = (v) => v && /^\d{4}-\d{2}-\d{2}$/.test(v) ? v : void 0;
787
+ if (input.from && !range(input.from) || input.to && !range(input.to))
788
+ return { ok: false, message: "--from and --to are days: YYYY-MM-DD." };
789
+ if ((!input.from || !input.to) && !c.time)
790
+ return {
791
+ ok: false,
792
+ message: "The export has no date column: give --from and --to (YYYY-MM-DD) for the range it covers."
793
+ };
794
+ const kept = new Set(Object.values(c).filter((x) => !!x));
795
+ const dropped = names.filter((n) => !kept.has(n)).sort();
796
+ const secrets = /* @__PURE__ */ new Set();
797
+ const keptValues = /* @__PURE__ */ new Set();
798
+ const agg = /* @__PURE__ */ new Map();
799
+ let outOfRange = 0;
800
+ let skipped2 = 0;
801
+ let unmatched = 0;
802
+ const known = /* @__PURE__ */ new Map();
803
+ for (const a of input.apps ?? [])
804
+ if (a.trim() && !known.has(key(a)))
805
+ known.set(key(a), a.trim());
806
+ const days = [];
807
+ for (const r of rows) {
808
+ for (const n of dropped) {
809
+ const v = (r[n] ?? "").trim();
810
+ const q = /^(?:[a-z][a-z0-9+.-]*:\/\/|\/)/i.test(v) ? v.split(/[?#]/)[1] ?? "" : v;
811
+ if (q.length >= 6)
812
+ secrets.add(q);
813
+ }
814
+ for (const n of [c.path, c.suffix, c.basepath]) {
815
+ const v = n ? r[n] ?? "" : "";
816
+ const q = v.split(/[?#]/)[1] ?? "";
817
+ if (q.length >= 4)
818
+ secrets.add(q);
819
+ for (const m of (v.split(/[?#]/, 1)[0] ?? "").match(/;[^/]*/g) ?? [])
820
+ if (m.length >= 5)
821
+ secrets.add(m.slice(1));
822
+ }
823
+ if (c.time) {
824
+ const d = dayOf(r[c.time] ?? "");
825
+ if (d) {
826
+ if (input.from && d < input.from || input.to && d > input.to) {
827
+ outOfRange++;
828
+ continue;
829
+ }
830
+ days.push(d);
831
+ } else if (!input.from || !input.to) {
832
+ skipped2++;
833
+ continue;
834
+ }
835
+ }
836
+ const method = (r[c.method] ?? "").trim().toUpperCase();
837
+ const rawPath = c.path ? r[c.path] ?? "" : `${(r[c.basepath] ?? "").replace(/\/+$/, "")}/${(r[c.suffix] ?? "").replace(/^\/+/, "")}`;
838
+ const countText = c.count ? (r[c.count] ?? "").trim() : "1";
839
+ const count = Number(countText);
840
+ if (!/^[A-Z]{3,10}$/.test(method) || !barePath(rawPath).startsWith("/") || !Number.isInteger(count) || count < 0) {
841
+ skipped2++;
842
+ continue;
843
+ }
844
+ const path = pathTemplateOf(rawPath, input.templates);
845
+ if (!path) {
846
+ unmatched++;
847
+ continue;
848
+ }
849
+ if (count === 0)
850
+ continue;
851
+ const appRaw = (r[c.app] ?? "").trim();
852
+ const app = !appRaw ? "(none)" : known.get(key(appRaw)) ?? appLabelOf(appRaw);
853
+ const proxyRaw = c.proxy ? (r[c.proxy] ?? "").trim() : "";
854
+ const proxy = proxyRaw && !looksSensitive(proxyRaw) ? proxyRaw : void 0;
855
+ const baseRaw = c.basepath ? (r[c.basepath] ?? "").trim() : "";
856
+ const basepath = baseRaw ? safePathOf(baseRaw) : void 0;
857
+ for (const v of [app, proxy, basepath, path])
858
+ if (v)
859
+ keptValues.add(v);
860
+ const k = [app, method, path, proxy ?? "", basepath ?? ""].join("\0");
861
+ const row = agg.get(k) ?? {
862
+ app,
863
+ method,
864
+ path,
865
+ ...proxy ? { proxy } : {},
866
+ ...basepath ? { basepath } : {},
867
+ count: 0
868
+ };
869
+ row.count += count;
870
+ agg.set(k, row);
871
+ }
872
+ if (!agg.size)
873
+ return {
874
+ ok: false,
875
+ message: `No row of the file is a request in the range to a route of the estate (${rows.length} read, ${outOfRange} outside it, ${skipped2} without a method, path or count, ${unmatched} matching no route template of the estate): nothing to keep.`
876
+ };
877
+ days.sort();
878
+ const from = input.from ?? days[0];
879
+ const to = input.to ?? days[days.length - 1];
880
+ if (!from || !to)
881
+ return { ok: false, message: "The rows carry no dates: give --from and --to (YYYY-MM-DD)." };
882
+ const parsed = TrafficFile.safeParse({
883
+ schemaVersion: 1,
884
+ source: input.source,
885
+ from,
886
+ to,
887
+ inputSha256: createHash3("sha256").update(input.bytes).digest("hex"),
888
+ rows: [...agg.values()].sort((a, b) => cmp(a.app, b.app) || cmp(a.proxy ?? "", b.proxy ?? "") || cmp(a.path, b.path) || cmp(a.method, b.method))
889
+ });
890
+ if (!parsed.success)
891
+ return { ok: false, message: `The aggregate isn't valid: ${parsed.error.issues[0]?.message}.` };
892
+ const out = trafficFileText(parsed.data);
893
+ const lower = out.toLowerCase();
894
+ const leaked = [...secrets].filter((s) => !keptValues.has(s) && lower.includes(s.toLowerCase()));
895
+ if (leaked.length)
896
+ return {
897
+ ok: false,
898
+ message: `Refused: ${leaked.length} value${leaked.length === 1 ? "" : "s"} of the export's dropped columns would be written. Nothing was written.`
899
+ };
900
+ const body = out.replace(/^inputSha256: .*$/m, "");
901
+ if ([IPV4, IPV6, EMAIL, JWT, OPAQUE, UUID, HEX].some((re) => re.test(body)))
902
+ return {
903
+ ok: false,
904
+ message: "Refused: the aggregate would hold an IP, an email or a token-looking value. Nothing was written."
905
+ };
906
+ const hits = input.denyHashes?.size ? denyListHits(out, input.denyHashes) : [];
907
+ if (hits.length)
908
+ return {
909
+ ok: false,
910
+ message: `Refused: the deny-list names a word on line${hits.length === 1 ? "" : "s"} ${hits.join(", ")} of the aggregate. Nothing was written.`
911
+ };
912
+ return {
913
+ ok: true,
914
+ file: parsed.data,
915
+ text: out,
916
+ read: rows.length,
917
+ outOfRange,
918
+ skipped: skipped2,
919
+ unmatched,
920
+ dropped
921
+ };
922
+ }
923
+
458
924
  // packages/intake/dist/vendor-ops.js
459
925
  var import_yaml3 = __toESM(require_dist(), 1);
460
- import { createHash as createHash3 } from "node:crypto";
461
- var short2 = (s) => createHash3("sha256").update(s).digest("hex").slice(0, 6);
926
+ import { createHash as createHash4 } from "node:crypto";
927
+ var short2 = (s) => createHash4("sha256").update(s).digest("hex").slice(0, 6);
462
928
  function specEndpointIds(component, ops) {
463
929
  const ids = ops.map((o) => endpointId(component, o.method, o.normalizedPath));
464
930
  const count = /* @__PURE__ */ new Map();
@@ -507,7 +973,8 @@ function readVendorSpec(path, text3, system) {
507
973
  scopes: op.scopes,
508
974
  cite: `${path}:${op.methodLine ?? op.line ?? 1}`,
509
975
  request: requestFields(ctx, op, swagger2),
510
- response: responseFields(ctx, op, swagger2)
976
+ response: responseFields(ctx, op, swagger2),
977
+ ...errorsOf(ctx, op, swagger2)
511
978
  };
512
979
  });
513
980
  const ids = specEndpointIds(system, ops);
@@ -522,6 +989,56 @@ function readVendorSpec(path, text3, system) {
522
989
  operations: ops.map((o, i) => ({ id: ids[i], ...o }))
523
990
  };
524
991
  }
992
+ function errorsOf(ctx, op, swagger2) {
993
+ const responses = (0, import_yaml3.isMap)(op.node) ? op.node.get("responses") : void 0;
994
+ if (!(0, import_yaml3.isMap)(responses))
995
+ return {};
996
+ const errors = responses.items.flatMap((p) => {
997
+ const status = (0, import_yaml3.isScalar)(p.key) ? String(p.key.value) : "";
998
+ if (!/^[45]\d\d$/.test(status))
999
+ return [];
1000
+ const cite = ctx.at((0, import_yaml3.isScalar)(p.key) ? p.key.range?.[0] : void 0);
1001
+ if (!cite)
1002
+ return [];
1003
+ const fields = [];
1004
+ schemaFields(ctx, bodySchema(ctx, p.value, swagger2), "body", "", 0, /* @__PURE__ */ new Set(), fields);
1005
+ return [{ status, cite, ...fields.length ? { fields } : {} }];
1006
+ });
1007
+ return errors.length ? { errors } : {};
1008
+ }
1009
+ function bodySchema(ctx, response, swagger2) {
1010
+ if (!swagger2)
1011
+ return contentSchema(ctx, response);
1012
+ const r = deref(ctx, response);
1013
+ return (0, import_yaml3.isMap)(r) ? r.get("schema", true) : void 0;
1014
+ }
1015
+ function responseHeaders(ctx, response, swagger2) {
1016
+ const r = deref(ctx, response);
1017
+ const headers = (0, import_yaml3.isMap)(r) ? r.get("headers") : void 0;
1018
+ if (!(0, import_yaml3.isMap)(headers))
1019
+ return [];
1020
+ const out = [];
1021
+ for (const pair of headers.items) {
1022
+ if (!(0, import_yaml3.isScalar)(pair.key))
1023
+ continue;
1024
+ const h = deref(ctx, pair.value);
1025
+ if (!(0, import_yaml3.isMap)(h))
1026
+ continue;
1027
+ const schema = swagger2 ? h : deref(ctx, h.get("schema", true));
1028
+ const sm = (0, import_yaml3.isMap)(schema) ? schema : void 0;
1029
+ const type = sm ? typeOf2(sm) : void 0;
1030
+ const values = sm ? strings(sm.get("enum")) : void 0;
1031
+ out.push({
1032
+ name: String(pair.key.value),
1033
+ in: "header",
1034
+ ...type ? { type } : {},
1035
+ ...swagger2 ? {} : { required: h.get("required") === true },
1036
+ ...values ? { enum: values } : {},
1037
+ cite: ctx.at(pair.key.range?.[0]) ?? `${ctx.path}:1`
1038
+ });
1039
+ }
1040
+ return out;
1041
+ }
525
1042
  function deref(ctx, node, seen = /* @__PURE__ */ new Set()) {
526
1043
  let n = node;
527
1044
  for (let i = 0; i < 8 && (0, import_yaml3.isMap)(n); i++) {
@@ -536,8 +1053,8 @@ function deref(ctx, node, seen = /* @__PURE__ */ new Set()) {
536
1053
  }
537
1054
  return n;
538
1055
  }
539
- var offsetOfKey = (map, key2) => {
540
- const pair = map.items.find((p) => (0, import_yaml3.isScalar)(p.key) && String(p.key.value) === key2);
1056
+ var offsetOfKey = (map, key3) => {
1057
+ const pair = map.items.find((p) => (0, import_yaml3.isScalar)(p.key) && String(p.key.value) === key3);
541
1058
  return pair && (0, import_yaml3.isScalar)(pair.key) ? pair.key.range?.[0] : void 0;
542
1059
  };
543
1060
  var strings = (n) => (0, import_yaml3.isSeq)(n) ? n.items.filter(import_yaml3.isScalar).map((s) => String(s.value)) : void 0;
@@ -587,13 +1104,13 @@ function schemaFields(ctx, node, where, prefix, depth, seen, out) {
587
1104
  for (const pair of props.items) {
588
1105
  if (!(0, import_yaml3.isScalar)(pair.key))
589
1106
  continue;
590
- const key2 = String(pair.key.value);
591
- const name = prefix ? `${prefix}.${key2}` : key2;
1107
+ const key3 = String(pair.key.value);
1108
+ const name = prefix ? `${prefix}.${key3}` : key3;
592
1109
  const prop = deref(ctx, pair.value, new Set(refs));
593
1110
  const p = (0, import_yaml3.isMap)(prop) ? prop : void 0;
594
1111
  const type = p ? typeOf2(p) : void 0;
595
1112
  const values = p ? strings(p.get("enum")) : void 0;
596
- const req = required.has(key2);
1113
+ const req = required.has(key3);
597
1114
  out.push({
598
1115
  name,
599
1116
  in: where,
@@ -601,7 +1118,7 @@ function schemaFields(ctx, node, where, prefix, depth, seen, out) {
601
1118
  ...objectLike ? { required: req } : {},
602
1119
  ...values ? { enum: values } : {},
603
1120
  cite: ctx.at(pair.key.range?.[0]) ?? `${ctx.path}:1`,
604
- ...req && required.get(key2) !== void 0 ? { requiredCite: ctx.at(required.get(key2)) } : {}
1121
+ ...req && required.get(key3) !== void 0 ? { requiredCite: ctx.at(required.get(key3)) } : {}
605
1122
  });
606
1123
  if (p && (type === "object" || type === "array"))
607
1124
  schemaFields(ctx, pair.value, where, name, depth + 1, refs, out);
@@ -683,11 +1200,8 @@ function responseFields(ctx, op, swagger2) {
683
1200
  if (!ok)
684
1201
  return [];
685
1202
  const out = [];
686
- const schema = swagger2 ? (() => {
687
- const r = deref(ctx, ok.value);
688
- return (0, import_yaml3.isMap)(r) ? r.get("schema", true) : void 0;
689
- })() : contentSchema(ctx, ok.value);
690
- schemaFields(ctx, schema, "body", "", 0, /* @__PURE__ */ new Set(), out);
1203
+ schemaFields(ctx, bodySchema(ctx, ok.value, swagger2), "body", "", 0, /* @__PURE__ */ new Set(), out);
1204
+ out.push(...responseHeaders(ctx, ok.value, swagger2));
691
1205
  return out;
692
1206
  }
693
1207
  var pointer = (s) => s.replace(/~/g, "~0").replace(/\//g, "~1");
@@ -722,12 +1236,442 @@ function operationSchemas(spec) {
722
1236
  });
723
1237
  }
724
1238
 
1239
+ // packages/intake/dist/contract-specs.js
1240
+ var MAX_BYTES = 1024 * 1024;
1241
+ var SKIP = /* @__PURE__ */ new Set([
1242
+ ".git",
1243
+ "node_modules",
1244
+ "vendor",
1245
+ "target",
1246
+ "build",
1247
+ "dist",
1248
+ "out",
1249
+ "bin",
1250
+ "obj",
1251
+ ".gradle",
1252
+ ".idea",
1253
+ ".venv",
1254
+ "__pycache__"
1255
+ ]);
1256
+ var cmp2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
1257
+ function readProtoSpecs(path, text3) {
1258
+ const proto3 = /^\s*syntax\s*=\s*["']proto3["']/m.test(text3);
1259
+ let pkg = "";
1260
+ const out = [];
1261
+ const stack = [];
1262
+ let inComment = false;
1263
+ text3.split(/\r?\n/).forEach((raw, i) => {
1264
+ let line = raw;
1265
+ if (inComment) {
1266
+ const end = line.indexOf("*/");
1267
+ if (end < 0)
1268
+ return;
1269
+ line = line.slice(end + 2);
1270
+ inComment = false;
1271
+ }
1272
+ line = line.replace(/\/\*.*?\*\//g, "").replace(/\/\/.*$/, "");
1273
+ const open = line.indexOf("/*");
1274
+ if (open >= 0) {
1275
+ inComment = true;
1276
+ line = line.slice(0, open);
1277
+ }
1278
+ const n = i + 1;
1279
+ const p = /^\s*package\s+([\w.]+)\s*;/.exec(line);
1280
+ if (p)
1281
+ pkg = p[1];
1282
+ const message = /^\s*message\s+(\w+)\s*\{/.exec(line);
1283
+ const oneof = /^\s*oneof\s+(\w+)\s*\{/.exec(line);
1284
+ const other = /^\s*(enum|service|extend|extensions)\b[^{]*\{/.exec(line);
1285
+ let rest = line;
1286
+ if (message) {
1287
+ const outer = stack.filter((f) => f.kind === "message").map((f) => f.name);
1288
+ const name = [...outer, message[1]].join(".");
1289
+ const spec = {
1290
+ kind: "message",
1291
+ format: "protobuf",
1292
+ role: "schema",
1293
+ file: path,
1294
+ line: n,
1295
+ name: pkg ? `${pkg}.${name}` : name,
1296
+ fields: []
1297
+ };
1298
+ out.push(spec);
1299
+ stack.push({ kind: "message", name: message[1], spec });
1300
+ rest = line.slice(line.indexOf("{") + 1);
1301
+ } else if (oneof || other) {
1302
+ stack.push({ kind: oneof ? "oneof" : "other", name: "" });
1303
+ rest = line.slice(line.indexOf("{") + 1);
1304
+ } else {
1305
+ const top = stack.at(-1);
1306
+ const owner = top?.kind === "message" ? top : top?.kind === "oneof" ? stack.at(-2) : void 0;
1307
+ const f = /^\s*(optional|required|repeated)?\s*(map\s*<[^>]+>|[\w.]+)\s+(\w+)\s*=\s*(\d+)\s*(\[[^\]]*\])?\s*;/.exec(line);
1308
+ if (f && owner?.kind === "message" && owner.spec && !["reserved", "option"].includes(f[2])) {
1309
+ const label = f[1];
1310
+ owner.spec.fields.push({
1311
+ side: "message",
1312
+ name: f[3],
1313
+ type: label === "repeated" ? `repeated ${f[2]}` : f[2].replace(/\s+/g, ""),
1314
+ // proto2's `required` must be there; anything else may be left out (proto3 has no required).
1315
+ required: label === "required" && !proto3,
1316
+ number: Number(f[4]),
1317
+ at: `${path}:${n}`
1318
+ });
1319
+ }
1320
+ }
1321
+ for (const _ of rest.matchAll(/\}/g))
1322
+ stack.pop();
1323
+ });
1324
+ return out;
1325
+ }
1326
+ function lineOfName(lines, from, name) {
1327
+ const re = new RegExp(`"name"\\s*:\\s*"${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"`);
1328
+ for (let i = Math.max(0, from); i < lines.length; i++)
1329
+ if (re.test(lines[i]))
1330
+ return i + 1;
1331
+ return from + 1;
1332
+ }
1333
+ function readAvroSpecs(path, text3) {
1334
+ let data;
1335
+ try {
1336
+ data = JSON.parse(text3);
1337
+ } catch {
1338
+ return [];
1339
+ }
1340
+ const lines = text3.split(/\r?\n/);
1341
+ const out = [];
1342
+ let cursor = 0;
1343
+ const typeName = (t) => {
1344
+ if (typeof t === "string")
1345
+ return t;
1346
+ if (Array.isArray(t))
1347
+ return t.map(typeName).join("|");
1348
+ if (t && typeof t === "object") {
1349
+ const o = t;
1350
+ if (o.type === "array")
1351
+ return `repeated ${typeName(o.items)}`;
1352
+ if (o.type === "map")
1353
+ return `map<string,${typeName(o.values)}>`;
1354
+ if (typeof o.logicalType === "string")
1355
+ return String(o.type);
1356
+ if (typeof o.name === "string")
1357
+ return o.name;
1358
+ return typeName(o.type);
1359
+ }
1360
+ return "";
1361
+ };
1362
+ const record = (r, ns) => {
1363
+ if (r.type !== "record" || typeof r.name !== "string" || !Array.isArray(r.fields))
1364
+ return;
1365
+ const space = typeof r.namespace === "string" ? r.namespace : ns;
1366
+ const line = lineOfName(lines, cursor, r.name);
1367
+ cursor = line;
1368
+ const spec = {
1369
+ kind: "message",
1370
+ format: "avro",
1371
+ role: "schema",
1372
+ file: path,
1373
+ line,
1374
+ name: space ? `${space}.${r.name}` : r.name,
1375
+ fields: []
1376
+ };
1377
+ out.push(spec);
1378
+ r.fields.forEach((f, i) => {
1379
+ if (!f || typeof f !== "object")
1380
+ return;
1381
+ const x = f;
1382
+ if (typeof x.name !== "string")
1383
+ return;
1384
+ const at = lineOfName(lines, cursor, x.name);
1385
+ cursor = at;
1386
+ const nullable = Array.isArray(x.type) && x.type.includes("null");
1387
+ const type = typeName(Array.isArray(x.type) ? x.type.filter((t) => t !== "null") : x.type);
1388
+ spec.fields.push({
1389
+ side: "message",
1390
+ name: x.name,
1391
+ ...type ? { type } : {},
1392
+ required: !nullable && !("default" in x),
1393
+ number: i,
1394
+ at: `${path}:${at}`
1395
+ });
1396
+ const inner = Array.isArray(x.type) ? x.type : [x.type];
1397
+ for (const t of inner)
1398
+ if (t && typeof t === "object")
1399
+ record(t, space);
1400
+ });
1401
+ };
1402
+ for (const r of Array.isArray(data) ? data : [data])
1403
+ if (r && typeof r === "object")
1404
+ record(r, "");
1405
+ return out;
1406
+ }
1407
+ var lineAt = (d, node) => {
1408
+ const r = node?.range;
1409
+ return r ? d.lc.linePos(r[0]).line : 1;
1410
+ };
1411
+ function deref2(d, node, depth = 0) {
1412
+ if (!(0, import_yaml4.isMap)(node) || depth > 8)
1413
+ return node;
1414
+ const ref = node.get("$ref");
1415
+ if (typeof ref !== "string" || !ref.startsWith("#/"))
1416
+ return node;
1417
+ let at = d.root;
1418
+ for (const p of ref.slice(2).split("/"))
1419
+ at = (0, import_yaml4.isMap)(at) ? at.get(p.replace(/~1/g, "/").replace(/~0/g, "~"), true) : void 0;
1420
+ return deref2(d, at, depth + 1);
1421
+ }
1422
+ function propsOf(d, schema, prefix, depth, out) {
1423
+ const s = deref2(d, schema);
1424
+ if (!(0, import_yaml4.isMap)(s) || depth > 6)
1425
+ return;
1426
+ const props = s.get("properties", true);
1427
+ const req = s.get("required", true);
1428
+ const required = new Set((0, import_yaml4.isSeq)(req) ? req.items.map((x) => (0, import_yaml4.isScalar)(x) ? String(x.value) : "") : []);
1429
+ if (!(0, import_yaml4.isMap)(props))
1430
+ return;
1431
+ for (const p of props.items) {
1432
+ if (!(0, import_yaml4.isScalar)(p.key))
1433
+ continue;
1434
+ const name = prefix ? `${prefix}.${String(p.key.value)}` : String(p.key.value);
1435
+ const v = deref2(d, p.value);
1436
+ const type = (0, import_yaml4.isMap)(v) ? v.get("type") : void 0;
1437
+ out.push({
1438
+ side: "message",
1439
+ name,
1440
+ ...typeof type === "string" ? { type } : {},
1441
+ required: required.has(String(p.key.value)),
1442
+ at: `${d.path}:${lineAt(d, p.key)}`
1443
+ });
1444
+ if ((0, import_yaml4.isMap)(v)) {
1445
+ if (type === "array")
1446
+ propsOf(d, v.get("items", true), `${name}[]`, depth + 1, out);
1447
+ else
1448
+ propsOf(d, v, name, depth + 1, out);
1449
+ }
1450
+ }
1451
+ }
1452
+ function docOf(path, text3) {
1453
+ const lc = new import_yaml4.LineCounter();
1454
+ const doc = (0, import_yaml4.parseDocument)(text3, { lineCounter: lc });
1455
+ return (0, import_yaml4.isMap)(doc.contents) ? { path, lc, root: doc.contents } : void 0;
1456
+ }
1457
+ function readJsonSchemaSpecs(path, text3) {
1458
+ const d = docOf(path, text3);
1459
+ if (!d)
1460
+ return [];
1461
+ const title = d.root.get("title");
1462
+ const id = d.root.get("$id");
1463
+ const fields = [];
1464
+ propsOf(d, d.root, "", 0, fields);
1465
+ if (!fields.length)
1466
+ return [];
1467
+ const name = typeof title === "string" && title ? title : typeof id === "string" && id ? (id.split("/").pop() ?? id).replace(/\.json$/, "") : (path.split("/").pop() ?? path).replace(/\.(schema\.)?json$|\.ya?ml$/i, "");
1468
+ return [
1469
+ { kind: "message", format: "json-schema", role: "schema", file: path, line: 1, name, fields }
1470
+ ];
1471
+ }
1472
+ function readAsyncApiSpecs(path, text3) {
1473
+ const d = docOf(path, text3);
1474
+ if (!d || d.root.get("asyncapi") === void 0)
1475
+ return [];
1476
+ const out = [];
1477
+ const channels = d.root.get("channels", true);
1478
+ if (!(0, import_yaml4.isMap)(channels))
1479
+ return out;
1480
+ const add = (topic, message) => {
1481
+ const m = deref2(d, message);
1482
+ if (!(0, import_yaml4.isMap)(m))
1483
+ return;
1484
+ const oneOf = m.get("oneOf", true);
1485
+ if ((0, import_yaml4.isSeq)(oneOf)) {
1486
+ for (const x of oneOf.items)
1487
+ add(topic, x);
1488
+ return;
1489
+ }
1490
+ const payload = m.get("payload", true);
1491
+ const fields = [];
1492
+ propsOf(d, payload, "", 0, fields);
1493
+ const p = deref2(d, payload);
1494
+ const title = (0, import_yaml4.isMap)(p) ? p.get("title") : void 0;
1495
+ const name = m.get("name") ?? m.get("title") ?? title;
1496
+ out.push({
1497
+ kind: "message",
1498
+ format: "asyncapi",
1499
+ role: "schema",
1500
+ file: path,
1501
+ line: lineAt(d, m),
1502
+ topic,
1503
+ ...typeof name === "string" && name ? { name } : {},
1504
+ fields
1505
+ });
1506
+ };
1507
+ for (const c of channels.items) {
1508
+ if (!(0, import_yaml4.isScalar)(c.key))
1509
+ continue;
1510
+ const ch = deref2(d, c.value);
1511
+ if (!(0, import_yaml4.isMap)(ch))
1512
+ continue;
1513
+ const address = ch.get("address");
1514
+ const topic = typeof address === "string" && address ? address : String(c.key.value);
1515
+ for (const op of ["publish", "subscribe"]) {
1516
+ const o = ch.get(op, true);
1517
+ if ((0, import_yaml4.isMap)(o))
1518
+ add(topic, o.get("message", true));
1519
+ }
1520
+ const msgs = ch.get("messages", true);
1521
+ if ((0, import_yaml4.isMap)(msgs))
1522
+ for (const m of msgs.items)
1523
+ add(topic, m.value);
1524
+ }
1525
+ return out;
1526
+ }
1527
+ function openApiContractSpecs(spec) {
1528
+ return spec.operations.map((o) => {
1529
+ const [file, line] = splitAt(o.cite, spec.path);
1530
+ const field2 = (side) => (f) => ({
1531
+ side,
1532
+ name: f.name,
1533
+ ...f.type ? { type: f.type } : {},
1534
+ ...f.required !== void 0 ? { required: f.required } : {},
1535
+ ...f.in ? { in: f.in } : {},
1536
+ at: f.cite
1537
+ });
1538
+ return {
1539
+ kind: "operation",
1540
+ format: "openapi",
1541
+ role: "consumer",
1542
+ file,
1543
+ line,
1544
+ method: o.method,
1545
+ path: o.fullPath,
1546
+ id: o.id,
1547
+ fields: [...o.request.map(field2("request")), ...o.response.map(field2("response"))],
1548
+ ...o.errors?.length ? { errors: o.errors.map((e) => ({ status: e.status, at: e.cite })) } : {}
1549
+ };
1550
+ });
1551
+ }
1552
+ function splitAt(cite, path) {
1553
+ const m = /^(.*):(\d+)$/.exec(cite);
1554
+ return m ? [m[1], Number(m[2])] : [path, 1];
1555
+ }
1556
+ function specFormatOf(name, text3) {
1557
+ const lower = name.toLowerCase();
1558
+ if (lower.endsWith(".proto"))
1559
+ return "protobuf";
1560
+ if (lower.endsWith(".avsc"))
1561
+ return "avro";
1562
+ if (!/\.(ya?ml|json)$/.test(lower))
1563
+ return void 0;
1564
+ const head = text3.slice(0, 4e3);
1565
+ if (/^\s*["']?(openapi|swagger)["']?\s*:/m.test(head))
1566
+ return "openapi";
1567
+ if (/^\s*["']?asyncapi["']?\s*:/m.test(head))
1568
+ return "asyncapi";
1569
+ if (/"type"\s*:\s*"record"/.test(head) && /"fields"\s*:/.test(head))
1570
+ return "avro";
1571
+ if (/["']?\$schema["']?\s*:/.test(head) && /json-schema\.org/.test(head))
1572
+ return "json-schema";
1573
+ return void 0;
1574
+ }
1575
+ function readContractSpecs(path, text3) {
1576
+ switch (specFormatOf(path, text3)) {
1577
+ case "protobuf":
1578
+ return readProtoSpecs(path, text3);
1579
+ case "avro":
1580
+ return readAvroSpecs(path, text3);
1581
+ case "json-schema":
1582
+ return readJsonSchemaSpecs(path, text3);
1583
+ case "asyncapi":
1584
+ return readAsyncApiSpecs(path, text3);
1585
+ case "openapi": {
1586
+ const spec = readVendorSpec(path, text3, "spec");
1587
+ return spec ? openApiContractSpecs(spec) : [];
1588
+ }
1589
+ default:
1590
+ return [];
1591
+ }
1592
+ }
1593
+ var sameShape = (a, b) => normalizePath(a).replace(/\{[^}]*\}/g, "{}") === normalizePath(b).replace(/\{[^}]*\}/g, "{}");
1594
+ var SPEC_FILE = /\.(proto|avsc|ya?ml|json)$/i;
1595
+ function cmpPath(a, b) {
1596
+ const x = a.split("/");
1597
+ const y = b.split("/");
1598
+ for (let i = 0; i < Math.min(x.length, y.length); i++) {
1599
+ const c = cmp2(x[i], y[i]);
1600
+ if (c)
1601
+ return c;
1602
+ }
1603
+ return x.length - y.length;
1604
+ }
1605
+ var skipped = (p) => p.split("/").slice(0, -1).some((d) => SKIP.has(d) || d.startsWith("."));
1606
+ function folderTree(dir) {
1607
+ return {
1608
+ async files() {
1609
+ const out = [];
1610
+ const walk2 = async (rel) => {
1611
+ const entries = await readdir(join(dir, ...rel.split("/").filter(Boolean)), {
1612
+ withFileTypes: true
1613
+ }).catch(() => []);
1614
+ for (const e of [...entries].sort((a, b) => cmp2(a.name, b.name))) {
1615
+ const p = rel ? `${rel}/${e.name}` : e.name;
1616
+ if (e.isDirectory()) {
1617
+ if (!SKIP.has(e.name) && !e.name.startsWith("."))
1618
+ await walk2(p);
1619
+ } else if (e.isFile() && SPEC_FILE.test(e.name)) {
1620
+ const size = (await stat(join(dir, ...p.split("/"))).catch(() => void 0))?.size;
1621
+ out.push({ path: p, size: size ?? 0 });
1622
+ }
1623
+ }
1624
+ };
1625
+ await walk2("");
1626
+ return out;
1627
+ },
1628
+ read: (p) => readFile(join(dir, ...p.split("/")), "utf8").catch(() => void 0)
1629
+ };
1630
+ }
1631
+ async function readRepoSpecs(dir, o) {
1632
+ const tree = o.tree ?? folderTree(dir);
1633
+ const files = (await tree.files()).filter((f) => SPEC_FILE.test(f.path) && !skipped(f.path) && f.size > 0 && f.size <= MAX_BYTES).sort((a, b) => cmpPath(a.path, b.path)).map((f) => f.path);
1634
+ const own = o.facts.filter((f) => f.kind === "entry" && f.entryType === "rest");
1635
+ const specs = [];
1636
+ for (const p of files) {
1637
+ const text3 = await tree.read(p);
1638
+ if (text3 === void 0 || !specFormatOf(p, text3))
1639
+ continue;
1640
+ const got = readContractSpecs(p, text3);
1641
+ if (!got.length)
1642
+ continue;
1643
+ if (o.denyHashes?.size && denyListHits(text3, o.denyHashes).length) {
1644
+ o.onRefused?.(`${p}: the deny-list names a word in it, so its specs are left out.`);
1645
+ continue;
1646
+ }
1647
+ for (const s of got) {
1648
+ if (s.kind !== "operation") {
1649
+ specs.push(s);
1650
+ continue;
1651
+ }
1652
+ const vendorPath = readVendorSpec(p, text3, "spec")?.operations.find((x) => x.id === s.id);
1653
+ const paths = [s.path ?? "", vendorPath?.path ?? ""].filter(Boolean);
1654
+ const entry = own.filter((e) => (!e.method || !s.method || e.method.toUpperCase() === s.method) && paths.some((x) => sameShape(x, e.path))).sort((a, b) => cmp2(a.id, b.id))[0];
1655
+ const { id: _id, ...rest } = s;
1656
+ specs.push(entry ? { ...rest, role: "own", entry: entry.id } : rest);
1657
+ }
1658
+ }
1659
+ return {
1660
+ schemaVersion: 1,
1661
+ repo: o.repo,
1662
+ ...o.commit ? { commit: o.commit } : {},
1663
+ specs
1664
+ };
1665
+ }
1666
+
725
1667
  // packages/intake/dist/scan-inputs.js
726
1668
  var SPECS = ["openapi", "swagger", "asyncapi"];
727
1669
  var EVIDENCE_SOURCE = {
728
1670
  openapi: "spec",
729
1671
  swagger: "spec",
730
1672
  asyncapi: "spec",
1673
+ protobuf: "spec",
1674
+ avro: "spec",
731
1675
  diagram: "diagram",
732
1676
  image: "document",
733
1677
  document: "document",
@@ -745,14 +1689,14 @@ async function walk(dir, skip) {
745
1689
  return;
746
1690
  let entries;
747
1691
  try {
748
- entries = await readdir(d, { withFileTypes: true });
1692
+ entries = await readdir2(d, { withFileTypes: true });
749
1693
  } catch {
750
1694
  return;
751
1695
  }
752
1696
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
753
1697
  if (e.name.startsWith("."))
754
1698
  continue;
755
- const full = join(d, e.name);
1699
+ const full = join2(d, e.name);
756
1700
  if (e.isDirectory())
757
1701
  await go(full);
758
1702
  else if (e.isFile())
@@ -763,7 +1707,7 @@ async function walk(dir, skip) {
763
1707
  return out;
764
1708
  }
765
1709
  var DATE = /(?:^|[-_ .])((\d{4})-?(\d{2})-?(\d{2}))(?=$|[-_ .])/;
766
- var VERSION = /(?:^|[-_ .])v(\d+(?:[._]\d+)*)(?=$|[-_ .])/i;
1710
+ var VERSION2 = /(?:^|[-_ .])v(\d+(?:[._]\d+)*)(?=$|[-_ .])/i;
767
1711
  function nameParts(stem) {
768
1712
  let rest = stem;
769
1713
  let date;
@@ -776,7 +1720,7 @@ function nameParts(stem) {
776
1720
  }
777
1721
  }
778
1722
  let version;
779
- const v = VERSION.exec(rest);
1723
+ const v = VERSION2.exec(rest);
780
1724
  if (v) {
781
1725
  version = v[1].replace(/_/g, ".");
782
1726
  rest = rest.replace(v[0], "");
@@ -802,23 +1746,23 @@ function systemsInName(stem, systems) {
802
1746
  return systems.filter((sys) => [sys.id, sys.name, ...sys.aliases].some((n) => slug(n) && s.includes(`-${slug(n)}-`))).map((sys) => sys.id).sort();
803
1747
  }
804
1748
  async function scanInputs(o) {
805
- const orgPackDir = typeof o.orgPack === "string" ? o.orgPack : join(orgPackDirOf(o.root));
1749
+ const orgPackDir = typeof o.orgPack === "string" ? o.orgPack : join2(orgPackDirOf(o.root));
806
1750
  const op = typeof o.orgPack === "object" ? o.orgPack : await loadOrgPack(orgPackDir);
807
1751
  const systems = op.profiles.flatMap((p) => p.profile?.systems ?? []);
808
1752
  const legend = op.profiles.find((p) => p.profile?.legend)?.profile?.legend;
809
1753
  const records = o.records ?? [];
810
1754
  const ingestors = o.ingestors ?? [drawioIngestor];
811
1755
  const scannedAt = o.scannedAt ?? (/* @__PURE__ */ new Date()).toISOString();
812
- const inputsDir = o.inputsDir ?? join(o.root, "inputs");
1756
+ const inputsDir = o.inputsDir ?? join2(o.root, "inputs");
813
1757
  const problems = [];
814
1758
  const triage = [];
815
1759
  const authors = /* @__PURE__ */ new Map();
816
1760
  const wikiDirs = op.sources.wikis.flatMap((w) => /^[a-z][a-z0-9+.-]*:\/\//i.test(w.location) ? [] : [resolve(orgPackDir, w.location), resolve(o.root, w.location)]);
817
- const st = await stat(inputsDir).catch(() => void 0);
1761
+ const st = await stat2(inputsDir).catch(() => void 0);
818
1762
  const paths = st?.isDirectory() ? await walk(inputsDir, wikiDirs) : [];
819
1763
  const files = [];
820
1764
  for (const abs of paths) {
821
- const bytes = new Uint8Array(await readFile(abs));
1765
+ const bytes = new Uint8Array(await readFile2(abs));
822
1766
  const path = `inputs/${posix(relative(inputsDir, abs))}`;
823
1767
  const name = path.split("/").pop();
824
1768
  const c = classify(name, bytes);
@@ -826,14 +1770,19 @@ async function scanInputs(o) {
826
1770
  abs,
827
1771
  path,
828
1772
  bytes,
829
- hash: createHash4("sha256").update(bytes).digest("hex"),
1773
+ hash: createHash5("sha256").update(bytes).digest("hex"),
830
1774
  stem: name.includes(".") ? name.slice(0, name.lastIndexOf(".")) : name,
831
1775
  inbox: path.startsWith("inputs/inbox/"),
832
1776
  ...c.data !== void 0 ? { data: c.data } : {},
1777
+ ...c.text !== void 0 ? { text: c.text } : {},
833
1778
  doc: {
834
1779
  path,
835
1780
  classification: c.classification,
836
- status: "no-reader",
1781
+ status: c.unreadable ? "unreadable" : "no-reader",
1782
+ ...c.unreadable ? {
1783
+ reason: `${c.unreadable.reason}${c.unreadable.line !== void 0 ? ` at ${c.unreadable.line}:${c.unreadable.column}` : ""}`
1784
+ } : {},
1785
+ ...c.notes?.length ? { notes: c.notes } : {},
837
1786
  hash: "",
838
1787
  ...c.title ? { title: c.title } : {},
839
1788
  ...c.version ? { version: c.version } : {},
@@ -896,7 +1845,7 @@ async function scanInputs(o) {
896
1845
  const heads = members.filter((m) => !m.doc.supersededBy);
897
1846
  if (heads.length < 2)
898
1847
  continue;
899
- const distinct = (vals, cmp3) => vals.every((v) => v !== void 0) && vals.every((v, i) => vals.every((w, j) => i === j || cmp3(v, w) !== 0));
1848
+ const distinct = (vals, cmp5) => vals.every((v) => v !== void 0) && vals.every((v, i) => vals.every((w, j) => i === j || cmp5(v, w) !== 0));
900
1849
  const byVersion = distinct(heads.map((h) => h.doc.version), compareVersions);
901
1850
  const byDate = !byVersion && distinct(heads.map((h) => h.doc.date), (a, b) => a < b ? -1 : a > b ? 1 : 0);
902
1851
  if (byVersion || byDate) {
@@ -939,7 +1888,7 @@ async function scanInputs(o) {
939
1888
  for (const f of kept) {
940
1889
  const cls = f.doc.classification;
941
1890
  const current = !f.doc.supersededBy;
942
- const text3 = () => new TextDecoder().decode(f.bytes);
1891
+ const text3 = () => f.text ?? new TextDecoder().decode(f.bytes);
943
1892
  const linked = /* @__PURE__ */ new Set();
944
1893
  const unknown = /* @__PURE__ */ new Set();
945
1894
  if (SPECS.includes(cls)) {
@@ -1053,6 +2002,43 @@ async function scanInputs(o) {
1053
2002
  } catch {
1054
2003
  }
1055
2004
  }
2005
+ if (cls === "protobuf" || cls === "avro") {
2006
+ const specs = cls === "protobuf" ? readProtoSpecs(f.path, text3()) : readAvroSpecs(f.path, text3());
2007
+ const named = new Set(systemsInName(f.stem, systems));
2008
+ for (const s of specs) {
2009
+ const res = s.name ? resolveName(s.name.split(".").slice(0, -1).join(" ")) : void 0;
2010
+ if (res?.id && !named.size)
2011
+ named.add(systemOf(res.id));
2012
+ }
2013
+ for (const s of named)
2014
+ linked.add(s);
2015
+ if (current && specs.length) {
2016
+ for (const s of specs) {
2017
+ const p = parseRecord({
2018
+ schemaVersion: 1,
2019
+ kind: "Schema",
2020
+ id: boundedId("schema.", slug(s.name ?? f.stem)),
2021
+ status: "current",
2022
+ confidence: "verified",
2023
+ format: cls,
2024
+ ref: `${f.path}#${s.name ?? ""}`,
2025
+ fields: s.fields.map((x) => ({
2026
+ name: x.name,
2027
+ ...x.type ? { type: x.type } : {},
2028
+ ...x.required !== void 0 ? { required: x.required } : {}
2029
+ })),
2030
+ evidence: [{ source: "spec", path: f.path, line: s.line, side: "definition" }]
2031
+ });
2032
+ if (!p.ok)
2033
+ continue;
2034
+ const schema = p.record;
2035
+ out.push(schema);
2036
+ f.doc.records.push(schema.id);
2037
+ }
2038
+ f.doc.status = "read";
2039
+ f.doc.reader = cls === "protobuf" ? READERS.protobuf : READERS.avro;
2040
+ }
2041
+ }
1056
2042
  if (current && cls === "payload" && f.data !== void 0) {
1057
2043
  const schema = readPayload(f.path, boundedId("payload.", f.doc.id.slice(4)), f.data);
1058
2044
  out.push(schema);
@@ -1249,9 +2235,9 @@ function safeSniff(ing, path, head) {
1249
2235
  return 0;
1250
2236
  }
1251
2237
  }
1252
- function lineOf(text3, key2) {
2238
+ function lineOf(text3, key3) {
1253
2239
  const lines = text3.split(/\r?\n/);
1254
- const re = new RegExp(`(^|[\\s{,])"?${key2}"?\\s*:`);
2240
+ const re = new RegExp(`(^|[\\s{,])"?${key3}"?\\s*:`);
1255
2241
  const i = lines.findIndex((l) => re.test(l));
1256
2242
  return i >= 0 ? { line: i + 1 } : {};
1257
2243
  }
@@ -1362,11 +2348,11 @@ function imageItems(records) {
1362
2348
  };
1363
2349
  });
1364
2350
  }
1365
- var key = (action, target, value) => `${action}|${target}|${JSON.stringify(value ?? null)}`;
2351
+ var key2 = (action, target, value) => `${action}|${target}|${JSON.stringify(value ?? null)}`;
1366
2352
  function buildTriage(input) {
1367
2353
  const decisions = (input.decisions ?? []).filter((d) => d.kind === "CuratedDecision" && d.status === "current");
1368
2354
  const decidedIds = new Set(decisions.map((d) => d.id));
1369
- const decidedKeys = new Set(decisions.map((d) => key(d.action, d.target, d.value)));
2355
+ const decidedKeys = new Set(decisions.map((d) => key2(d.action, d.target, d.value)));
1370
2356
  const docs = new Map((input.inputs?.documents ?? []).map((d) => [d.path, d.id]));
1371
2357
  const docIdOf = (path) => docs.get(path) ?? boundedId("doc.", slug(path.split("/").pop().replace(/\.[^.]+$/, "")));
1372
2358
  const records = input.records;
@@ -1379,7 +2365,7 @@ function buildTriage(input) {
1379
2365
  ...imageItems([...records, ...inputRecords]),
1380
2366
  ...readingItems(input)
1381
2367
  ];
1382
- const open = all.filter((i) => !i.options.some((o) => decidedIds.has(o.decision.id) || decidedKeys.has(key(o.decision.action, o.decision.target, o.decision.value))));
2368
+ const open = all.filter((i) => !i.options.some((o) => decidedIds.has(o.decision.id) || decidedKeys.has(key2(o.decision.action, o.decision.target, o.decision.value))));
1383
2369
  const items = sortItems(open);
1384
2370
  return {
1385
2371
  items,
@@ -1420,9 +2406,9 @@ function buildTriage(input) {
1420
2406
  }
1421
2407
 
1422
2408
  // packages/intake/dist/work-items.js
1423
- var import_yaml4 = __toESM(require_dist(), 1);
1424
- import { readdir as readdir2, readFile as readFile2 } from "node:fs/promises";
1425
- import { join as join2, relative as relative2, sep as sep2 } from "node:path";
2409
+ var import_yaml5 = __toESM(require_dist(), 1);
2410
+ import { readdir as readdir3, readFile as readFile3 } from "node:fs/promises";
2411
+ import { join as join3, relative as relative2, sep as sep2 } from "node:path";
1426
2412
  var WORK_ITEM_READER = "work-items@0.1.0";
1427
2413
  var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
1428
2414
  var text = (v) => {
@@ -1528,7 +2514,7 @@ function itemOf(o, path, lineOf2) {
1528
2514
  source: { path, ...line ? { line } : {} }
1529
2515
  };
1530
2516
  }
1531
- function parseCsv(s) {
2517
+ function parseCsv2(s) {
1532
2518
  const rows = [];
1533
2519
  let row = [];
1534
2520
  let cell = "";
@@ -1572,7 +2558,7 @@ function parseCsv(s) {
1572
2558
  return rows;
1573
2559
  }
1574
2560
  function fromCsv(textIn, path) {
1575
- const rows = parseCsv(textIn.replace(/^\uFEFF/, ""));
2561
+ const rows = parseCsv2(textIn.replace(/^\uFEFF/, ""));
1576
2562
  const header = rows[0]?.cells.map((h) => h.trim());
1577
2563
  if (!header)
1578
2564
  return void 0;
@@ -1601,7 +2587,7 @@ function readWorkItemExport(path, bytes) {
1601
2587
  return void 0;
1602
2588
  let data;
1603
2589
  try {
1604
- data = (0, import_yaml4.parse)(content);
2590
+ data = (0, import_yaml5.parse)(content);
1605
2591
  } catch {
1606
2592
  return void 0;
1607
2593
  }
@@ -1624,22 +2610,22 @@ function readWorkItemExport(path, bytes) {
1624
2610
  return items;
1625
2611
  }
1626
2612
  async function readWorkItemExports(o) {
1627
- const dir = o.inputsDir ?? join2(o.root, "inputs");
2613
+ const dir = o.inputsDir ?? join3(o.root, "inputs");
1628
2614
  const files = [];
1629
2615
  async function walk2(d) {
1630
2616
  let entries;
1631
2617
  try {
1632
- entries = await readdir2(d, { withFileTypes: true });
2618
+ entries = await readdir3(d, { withFileTypes: true });
1633
2619
  } catch {
1634
2620
  return;
1635
2621
  }
1636
2622
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
1637
2623
  if (e.name.startsWith("."))
1638
2624
  continue;
1639
- const full = join2(d, e.name);
2625
+ const full = join3(d, e.name);
1640
2626
  if (e.isDirectory())
1641
2627
  await walk2(full);
1642
- else if (/\.(json|ya?ml|csv)$/i.test(e.name))
2628
+ else if (e.isFile() && /\.(json|ya?ml|csv)$/i.test(e.name))
1643
2629
  files.push(full);
1644
2630
  }
1645
2631
  }
@@ -1653,7 +2639,7 @@ async function readWorkItemExports(o) {
1653
2639
  const path = `inputs/${relative2(dir, full).split(sep2).join("/")}`;
1654
2640
  let bytes;
1655
2641
  try {
1656
- bytes = new Uint8Array(await readFile2(full));
2642
+ bytes = new Uint8Array(await readFile3(full));
1657
2643
  } catch (e) {
1658
2644
  out.problems.push({ path, message: `can't read it: ${e.message}` });
1659
2645
  continue;
@@ -1668,9 +2654,9 @@ async function readWorkItemExports(o) {
1668
2654
  }
1669
2655
 
1670
2656
  // packages/intake/dist/service-requests.js
1671
- var import_yaml5 = __toESM(require_dist(), 1);
1672
- import { readdir as readdir3, readFile as readFile3 } from "node:fs/promises";
1673
- import { join as join3, relative as relative3, sep as sep3 } from "node:path";
2657
+ var import_yaml6 = __toESM(require_dist(), 1);
2658
+ import { readdir as readdir4, readFile as readFile4 } from "node:fs/promises";
2659
+ import { join as join4, relative as relative3, sep as sep3 } from "node:path";
1674
2660
  var SERVICE_REQUEST_READER = "service-requests@0.1.0";
1675
2661
  var isObj4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
1676
2662
  var text2 = (v) => {
@@ -1821,7 +2807,7 @@ function readServiceRequestExport(path, bytes) {
1821
2807
  return void 0;
1822
2808
  let data;
1823
2809
  try {
1824
- data = (0, import_yaml5.parse)(content);
2810
+ data = (0, import_yaml6.parse)(content);
1825
2811
  } catch {
1826
2812
  return void 0;
1827
2813
  }
@@ -1851,22 +2837,22 @@ function readServiceRequestExport(path, bytes) {
1851
2837
  return out;
1852
2838
  }
1853
2839
  async function readServiceRequestExports(o) {
1854
- const dir = o.inputsDir ?? join3(o.root, "inputs");
2840
+ const dir = o.inputsDir ?? join4(o.root, "inputs");
1855
2841
  const found = [];
1856
2842
  async function walk2(d) {
1857
2843
  let entries;
1858
2844
  try {
1859
- entries = await readdir3(d, { withFileTypes: true });
2845
+ entries = await readdir4(d, { withFileTypes: true });
1860
2846
  } catch {
1861
2847
  return;
1862
2848
  }
1863
2849
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
1864
2850
  if (e.name.startsWith("."))
1865
2851
  continue;
1866
- const full = join3(d, e.name);
2852
+ const full = join4(d, e.name);
1867
2853
  if (e.isDirectory())
1868
2854
  await walk2(full);
1869
- else if (/\.(json|ya?ml|csv)$/i.test(e.name))
2855
+ else if (e.isFile() && /\.(json|ya?ml|csv)$/i.test(e.name))
1870
2856
  found.push(full);
1871
2857
  }
1872
2858
  }
@@ -1880,7 +2866,7 @@ async function readServiceRequestExports(o) {
1880
2866
  const path = `inputs/${relative3(dir, full).split(sep3).join("/")}`;
1881
2867
  let bytes;
1882
2868
  try {
1883
- bytes = new Uint8Array(await readFile3(full));
2869
+ bytes = new Uint8Array(await readFile4(full));
1884
2870
  } catch (e) {
1885
2871
  out.problems.push({ path, message: `can't read it: ${e.message}` });
1886
2872
  continue;
@@ -1895,15 +2881,15 @@ async function readServiceRequestExports(o) {
1895
2881
  }
1896
2882
 
1897
2883
  // packages/intake/dist/change-inputs.js
1898
- var import_yaml6 = __toESM(require_dist(), 1);
1899
- import { createHash as createHash5 } from "node:crypto";
1900
- import { mkdir, readdir as readdir4, readFile as readFile4 } from "node:fs/promises";
1901
- import { join as join4 } from "node:path";
2884
+ var import_yaml7 = __toESM(require_dist(), 1);
2885
+ import { createHash as createHash6 } from "node:crypto";
2886
+ import { mkdir, readdir as readdir5, readFile as readFile5 } from "node:fs/promises";
2887
+ import { join as join5 } from "node:path";
1902
2888
  var INPUTS_DIR = "inputs";
1903
2889
  var INPUTS_INDEX = "inputs/index.yaml";
1904
2890
  var INPUTS_READ_DIR = "inputs/read";
1905
2891
  var CHANGE_INPUTS_SCHEMA_VERSION = 1;
1906
- var sha256 = (b) => createHash5("sha256").update(b).digest("hex");
2892
+ var sha256 = (b) => createHash6("sha256").update(b).digest("hex");
1907
2893
  var KEYS = [
1908
2894
  "path",
1909
2895
  "name",
@@ -1923,10 +2909,10 @@ var KEYS = [
1923
2909
  "defences"
1924
2910
  ];
1925
2911
  async function readChangeInputs(dir) {
1926
- const text3 = await readFile4(join4(dir, ...INPUTS_INDEX.split("/")), "utf8").catch(() => "");
2912
+ const text3 = await readFile5(join5(dir, ...INPUTS_INDEX.split("/")), "utf8").catch(() => "");
1927
2913
  let data;
1928
2914
  try {
1929
- data = text3 ? (0, import_yaml6.parse)(text3) : void 0;
2915
+ data = text3 ? (0, import_yaml7.parse)(text3) : void 0;
1930
2916
  } catch {
1931
2917
  data = void 0;
1932
2918
  }
@@ -1947,7 +2933,7 @@ async function writeIndex(dir, index) {
1947
2933
  o[k] = f[k];
1948
2934
  return o;
1949
2935
  });
1950
- await writeFileAtomic(join4(dir, ...INPUTS_INDEX.split("/")), `# Files attached to this change (ADR 0113): atticus change attach writes this file.
2936
+ await writeFileAtomic(join5(dir, ...INPUTS_INDEX.split("/")), `# Files attached to this change (ADR 0113): atticus change attach writes this file.
1951
2937
  ${toCanonicalYaml({ schemaVersion: index.schemaVersion, files }, ["schemaVersion", "files"])}`);
1952
2938
  }
1953
2939
  var isText = (b) => {
@@ -2038,7 +3024,7 @@ function readText(input, bytes, older) {
2038
3024
  async function attachToChange(dir, files, o) {
2039
3025
  const index = await readChangeInputs(dir);
2040
3026
  const out = { added: [], refused: [], notes: [] };
2041
- const taken = new Set(await readdir4(join4(dir, INPUTS_DIR)).catch(() => []));
3027
+ const taken = new Set((await readdir5(join5(dir, INPUTS_DIR)).catch(() => [])).map((n) => n.toLowerCase()));
2042
3028
  taken.add("index.yaml").add("read");
2043
3029
  const replaced = o.replaces ? index.files.find((x) => x.path === o.replaces.trim().replace(/\\/g, "/")) : void 0;
2044
3030
  let changed = false;
@@ -2076,9 +3062,9 @@ async function attachToChange(dir, files, o) {
2076
3062
  const dot = safe.lastIndexOf(".");
2077
3063
  const [stem, ext] = dot > 0 ? [safe.slice(0, dot), safe.slice(dot)] : [safe, ""];
2078
3064
  let target = safe;
2079
- for (let n = 2; taken.has(target); n++)
3065
+ for (let n = 2; taken.has(target.toLowerCase()); n++)
2080
3066
  target = `${stem}-${n}${ext}`;
2081
- taken.add(target);
3067
+ taken.add(target.toLowerCase());
2082
3068
  const found = classify(target, f.bytes).classification;
2083
3069
  const { format, citeBy } = formatOf2(target, f.bytes, found);
2084
3070
  const kind = found === "unknown" && citeBy ? "document" : found;
@@ -2125,11 +3111,11 @@ async function attachToChange(dir, files, o) {
2125
3111
  const where = o.elsewhere?.(hash);
2126
3112
  if (where)
2127
3113
  out.notes.push(`${name} is also in the metarepo's inputs as ${where}.`);
2128
- await mkdir(join4(dir, INPUTS_DIR), { recursive: true });
2129
- await writeFileAtomic(join4(dir, INPUTS_DIR, target), f.bytes);
3114
+ await mkdir(join5(dir, INPUTS_DIR), { recursive: true });
3115
+ await writeFileAtomic(join5(dir, INPUTS_DIR, target), f.bytes);
2130
3116
  const text3 = readText(input, f.bytes, older);
2131
3117
  if (text3 !== void 0)
2132
- await writeFileAtomic(join4(dir, ...input.readAs.split("/")), text3);
3118
+ await writeFileAtomic(join5(dir, ...input.readAs.split("/")), text3);
2133
3119
  index.files.push(input);
2134
3120
  out.added.push(input);
2135
3121
  }
@@ -2155,7 +3141,7 @@ async function changeInputSources(dir, rel) {
2155
3141
  for (const f of (await readChangeInputs(dir)).files) {
2156
3142
  if (f.supersededBy || f.defences?.risk === "high")
2157
3143
  continue;
2158
- const read = f.readAs ? await readFile4(join4(dir, ...f.readAs.split("/")), "utf8").catch(() => void 0) : void 0;
3144
+ const read = f.readAs ? await readFile5(join5(dir, ...f.readAs.split("/")), "utf8").catch(() => void 0) : void 0;
2159
3145
  const text3 = read ?? `${f.path} (${f.name}) is ${f.kind === "image" ? "a picture; Atticus doesn't read pictures" : `a ${f.format} file no reader takes`}. Open it to see it; say what you rely on from it, citing ${f.path}.`;
2160
3146
  out.push({
2161
3147
  id: f.path,
@@ -2179,9 +3165,12 @@ var KIND_ORDER2 = [
2179
3165
  "field-added",
2180
3166
  "field-required",
2181
3167
  "field-type",
2182
- "field-enum"
3168
+ "field-enum",
3169
+ "error-added",
3170
+ "error-schema",
3171
+ "error-removed"
2183
3172
  ];
2184
- var cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;
3173
+ var cmp3 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
2185
3174
  var opKey = (o) => `${o.method} ${normalizePath(o.fullPath)}`;
2186
3175
  var opName = (o) => `${o.method} ${o.path}`;
2187
3176
  var list = (xs) => xs.length <= 1 ? xs[0] ?? "" : `${xs.slice(0, -1).join(", ")} and ${xs.at(-1)}`;
@@ -2246,16 +3235,21 @@ function diffVendorSpecs(older, newer) {
2246
3235
  });
2247
3236
  for (const [o, n] of pairs)
2248
3237
  out.push(...operationChanges(o, n));
2249
- return out.sort((a, b) => cmp(a.severity === "breaking" ? "0" : "1", b.severity === "breaking" ? "0" : "1") || cmp(a.operation.path, b.operation.path) || cmp(a.operation.method, b.operation.method) || KIND_ORDER2.indexOf(a.kind) - KIND_ORDER2.indexOf(b.kind) || cmp(a.side ?? "", b.side ?? "") || cmp(a.field ?? "", b.field ?? ""));
3238
+ return out.sort((a, b) => cmp3(a.severity === "breaking" ? "0" : "1", b.severity === "breaking" ? "0" : "1") || cmp3(a.operation.path, b.operation.path) || cmp3(a.operation.method, b.operation.method) || KIND_ORDER2.indexOf(a.kind) - KIND_ORDER2.indexOf(b.kind) || cmp3(a.side ?? "", b.side ?? "") || cmp3(a.field ?? "", b.field ?? ""));
2250
3239
  }
2251
3240
  var opOf = (o) => ({
2252
3241
  method: o.method,
2253
3242
  path: o.path,
2254
3243
  ...o.operationId ? { operationId: o.operationId } : {}
2255
3244
  });
2256
- function changeId(kind, o, side, field2) {
3245
+ function changeId(kind, o, side, field2, status) {
2257
3246
  const op = slug(`${o.method} ${o.path}`);
2258
- return [kind, op, ...side && field2 ? [side, slug(field2)] : []].join(".");
3247
+ return [
3248
+ kind,
3249
+ op,
3250
+ ...status ? [status] : [],
3251
+ ...side && field2 ? [side, slug(field2)] : []
3252
+ ].join(".");
2259
3253
  }
2260
3254
  function operationChanges(o, n) {
2261
3255
  const out = [];
@@ -2291,15 +3285,61 @@ function operationChanges(o, n) {
2291
3285
  }
2292
3286
  for (const side of ["request", "response"])
2293
3287
  out.push(...fieldChanges(o[side], n[side], side, at, base));
3288
+ out.push(...errorChanges(o, n, at));
3289
+ return out;
3290
+ }
3291
+ function errorChanges(o, n, at) {
3292
+ const out = [];
3293
+ const olds = new Map((o.errors ?? []).map((e) => [e.status, e]));
3294
+ const news = new Map((n.errors ?? []).map((e) => [e.status, e]));
3295
+ const head = (kind, status) => ({
3296
+ id: changeId(kind, n, void 0, void 0, status),
3297
+ kind,
3298
+ operation: opOf(n),
3299
+ endpoints: { older: o.id, newer: n.id },
3300
+ status
3301
+ });
3302
+ for (const [status, e] of news)
3303
+ if (!olds.has(status))
3304
+ out.push({
3305
+ ...head("error-added", status),
3306
+ severity: "breaking",
3307
+ after: { value: status, cite: e.cite },
3308
+ says: `${at}: it may now answer ${status}; a caller that doesn't handle ${status} must.`
3309
+ });
3310
+ for (const [status, e] of olds)
3311
+ if (!news.has(status))
3312
+ out.push({
3313
+ ...head("error-removed", status),
3314
+ severity: "additive",
3315
+ before: { value: status, cite: e.cite },
3316
+ says: `${at}: it no longer answers ${status}; no caller has to change.`
3317
+ });
3318
+ for (const [status, a] of olds) {
3319
+ const b = news.get(status);
3320
+ if (!b)
3321
+ continue;
3322
+ const base = (_kind, side, field2) => ({
3323
+ id: changeId("error-schema", n, side, field2, status),
3324
+ kind: "error-schema",
3325
+ operation: opOf(n),
3326
+ endpoints: { older: o.id, newer: n.id },
3327
+ ...side ? { side } : {},
3328
+ ...field2 ? { field: field2 } : {},
3329
+ status
3330
+ });
3331
+ out.push(...fieldChanges(a.fields ?? [], b.fields ?? [], "response", `${at} (its ${status} response)`, base));
3332
+ }
2294
3333
  return out;
2295
3334
  }
2296
3335
  function fieldChanges(olds, news, side, at, base) {
2297
3336
  const out = [];
2298
- const key2 = (f) => `${f.in}|${f.name}`;
2299
- const byOld = new Map(olds.map((f) => [key2(f), f]));
2300
- const byNew = new Map(news.map((f) => [key2(f), f]));
2301
- let removed = olds.filter((f) => !byNew.has(key2(f)));
2302
- let added = news.filter((f) => !byOld.has(key2(f)));
3337
+ const what = (f) => `${side} ${f.in === "header" ? "header" : "field"}`;
3338
+ const key3 = (f) => `${f.in}|${f.name}`;
3339
+ const byOld = new Map(olds.map((f) => [key3(f), f]));
3340
+ const byNew = new Map(news.map((f) => [key3(f), f]));
3341
+ let removed = olds.filter((f) => !byNew.has(key3(f)));
3342
+ let added = news.filter((f) => !byOld.has(key3(f)));
2303
3343
  const req = side === "request";
2304
3344
  const parent = (f) => `${f.in}|${f.name.includes(".") ? f.name.slice(0, f.name.lastIndexOf(".")) : ""}`;
2305
3345
  const renamed = [];
@@ -2317,7 +3357,7 @@ function fieldChanges(olds, news, side, at, base) {
2317
3357
  severity: "breaking",
2318
3358
  before: { value: r.name, cite: r.cite },
2319
3359
  after: { value: a.name, cite: a.cite },
2320
- says: `${at}: the ${side} field ${r.name} is now ${a.name}; ${req ? `a caller that still sends ${r.name} no longer sets it` : `a caller that reads ${r.name} gets nothing`}.`
3360
+ says: `${at}: the ${what(r)} ${r.name} is now ${a.name}; ${req ? `a caller that still sends ${r.name} no longer sets it` : `a caller that reads ${r.name} gets nothing`}.`
2321
3361
  });
2322
3362
  }
2323
3363
  removed = removed.filter((f) => !renamed.some(([r]) => r === f));
@@ -2329,7 +3369,7 @@ function fieldChanges(olds, news, side, at, base) {
2329
3369
  ...base("field-removed", side, f.name),
2330
3370
  severity: "breaking",
2331
3371
  before: { value: f.name, cite: f.cite },
2332
- says: req ? `${at}: the request field ${f.name} is gone; a caller that sends it may be refused, and what it meant is lost.` : `${at}: the response field ${f.name} is gone; a caller that reads it gets nothing.`
3372
+ says: req ? `${at}: the ${what(f)} ${f.name} is gone; a caller that sends it may be refused, and what it meant is lost.` : `${at}: the ${what(f)} ${f.name} is gone; a caller that reads it gets nothing.`
2333
3373
  });
2334
3374
  for (const f of topAdded) {
2335
3375
  const breaks = req && f.required === true;
@@ -2337,7 +3377,7 @@ function fieldChanges(olds, news, side, at, base) {
2337
3377
  ...base("field-added", side, f.name),
2338
3378
  severity: breaks ? "breaking" : "additive",
2339
3379
  after: { value: f.name, cite: f.requiredCite ?? f.cite },
2340
- says: !req ? `${at}: the response has a new field ${f.name}; no caller has to change.` : breaks ? `${at}: the request needs a new field ${f.name}; a caller that doesn't send it is refused.` : `${at}: the request takes a new optional field ${f.name}; no caller has to change.`
3380
+ says: !req ? `${at}: the response has a new ${f.in === "header" ? "header" : "field"} ${f.name}; no caller has to change.` : breaks ? `${at}: the request needs a new ${f.in === "header" ? "header" : "field"} ${f.name}; a caller that doesn't send it is refused.` : `${at}: the request takes a new optional ${f.in === "header" ? "header" : "field"} ${f.name}; no caller has to change.`
2341
3381
  });
2342
3382
  }
2343
3383
  for (const [k, a] of byOld) {
@@ -2352,7 +3392,7 @@ function fieldChanges(olds, news, side, at, base) {
2352
3392
  severity: breaks ? "breaking" : "additive",
2353
3393
  before: { value: a.required ? "required" : "optional", cite: a.requiredCite ?? a.cite },
2354
3394
  after: { value: b.required ? "required" : "optional", cite: b.requiredCite ?? b.cite },
2355
- says: req ? nowRequired ? `${at}: the request field ${a.name} is now required; a caller that leaves it out is refused.` : `${at}: the request field ${a.name} is now optional; no caller has to change.` : nowRequired ? `${at}: the response field ${a.name} is now always there; no caller has to change.` : `${at}: the response field ${a.name} may now be left out; a caller that counts on it must allow for that.`
3395
+ says: req ? nowRequired ? `${at}: the ${what(a)} ${a.name} is now required; a caller that leaves it out is refused.` : `${at}: the ${what(a)} ${a.name} is now optional; no caller has to change.` : nowRequired ? `${at}: the ${what(a)} ${a.name} is now always there; no caller has to change.` : `${at}: the ${what(a)} ${a.name} may now be left out; a caller that counts on it must allow for that.`
2356
3396
  });
2357
3397
  }
2358
3398
  if (a.type && b.type && a.type !== b.type)
@@ -2361,7 +3401,7 @@ function fieldChanges(olds, news, side, at, base) {
2361
3401
  severity: "breaking",
2362
3402
  before: { value: a.type, cite: a.cite },
2363
3403
  after: { value: b.type, cite: b.cite },
2364
- says: `${at}: the ${side} field ${a.name} was ${a.type} and is now ${b.type}; a caller that ${req ? "sends" : "reads"} it must change.`
3404
+ says: `${at}: the ${what(a)} ${a.name} was ${a.type} and is now ${b.type}; a caller that ${req ? "sends" : "reads"} it must change.`
2365
3405
  });
2366
3406
  if (a.enum || b.enum) {
2367
3407
  const was = a.enum ?? [];
@@ -2371,7 +3411,7 @@ function fieldChanges(olds, news, side, at, base) {
2371
3411
  if (!gained.length && !lost.length)
2372
3412
  continue;
2373
3413
  const breaks = req ? lost.length > 0 : gained.length > 0;
2374
- const words = req ? lost.length ? `${at}: the request field ${a.name} no longer takes ${list(lost)}${gained.length ? ` and now takes ${list(gained)}` : ""}; a caller that sends a value it no longer takes is refused.` : `${at}: the request field ${a.name} now also takes ${list(gained)}; no caller has to change.` : gained.length ? `${at}: the response field ${a.name} may now be ${orList(gained)}; a caller that reads it must handle the new value${gained.length > 1 ? "s" : ""}.` : `${at}: the response field ${a.name} no longer returns ${list(lost)}; no caller has to change.`;
3414
+ const words = req ? lost.length ? `${at}: the ${what(a)} ${a.name} no longer takes ${list(lost)}${gained.length ? ` and now takes ${list(gained)}` : ""}; a caller that sends a value it no longer takes is refused.` : `${at}: the ${what(a)} ${a.name} now also takes ${list(gained)}; no caller has to change.` : gained.length ? `${at}: the ${what(a)} ${a.name} may now be ${orList(gained)}; a caller that reads it must handle the new value${gained.length > 1 ? "s" : ""}.` : `${at}: the ${what(a)} ${a.name} no longer returns ${list(lost)}; no caller has to change.`;
2375
3415
  out.push({
2376
3416
  ...base("field-enum", side, a.name),
2377
3417
  severity: breaks ? "breaking" : "additive",
@@ -2386,12 +3426,13 @@ function fieldChanges(olds, news, side, at, base) {
2386
3426
 
2387
3427
  // packages/intake/dist/vendor-impact.js
2388
3428
  var MAX_UPSTREAM = 4;
2389
- var cmp2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
3429
+ var cmp4 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
2390
3430
  var sorted = (xs) => [...new Set(xs)].sort();
2391
3431
  var joinVendorOf = (input, spec) => ({
2392
3432
  system: input.vendor.system,
2393
3433
  names: input.vendor.names,
2394
3434
  hosts: [.../* @__PURE__ */ new Set([...spec.hosts, ...input.vendor.hosts ?? []])],
3435
+ ...input.vendor.boundary ? { boundary: input.vendor.boundary } : {},
2395
3436
  operations: spec.operations.map((o) => ({
2396
3437
  id: o.id,
2397
3438
  method: o.method,
@@ -2407,20 +3448,24 @@ var versionOf = (v) => ({
2407
3448
  });
2408
3449
  function vendorImpact(input) {
2409
3450
  const diff = diffVendorSpecs(input.older.spec, input.newer.spec);
2410
- const join5 = joinFacts({
3451
+ const bundle = input.bundleFolders ? { bundleFolders: input.bundleFolders } : {};
3452
+ const join7 = joinFacts({
2411
3453
  repos: input.repos,
2412
3454
  ...input.targets ? { targets: input.targets } : {},
2413
- ...input.facing ? { facing: input.facing } : {}
3455
+ ...input.facing ? { facing: input.facing } : {},
3456
+ ...bundle
2414
3457
  });
2415
3458
  const today = joinVendorOperations({
2416
3459
  repos: input.repos,
2417
3460
  vendors: [joinVendorOf(input, input.older.spec)],
2418
- ...input.targets ? { targets: input.targets } : {}
3461
+ ...input.targets ? { targets: input.targets } : {},
3462
+ ...bundle
2419
3463
  });
2420
3464
  const next = joinVendorOperations({
2421
3465
  repos: input.repos,
2422
3466
  vendors: [joinVendorOf(input, input.newer.spec)],
2423
- ...input.targets ? { targets: input.targets } : {}
3467
+ ...input.targets ? { targets: input.targets } : {},
3468
+ ...bundle
2424
3469
  });
2425
3470
  const k = (e) => `${e.repo}\0${e.fact}`;
2426
3471
  const facts = /* @__PURE__ */ new Map();
@@ -2444,8 +3489,8 @@ function vendorImpact(input) {
2444
3489
  const f = facts.get(k(call))?.fact;
2445
3490
  return f?.kind === "call" && f.from ? endOf(call.repo, f.from) : void 0;
2446
3491
  };
2447
- const hops = new Set(join5.joins.flatMap((j) => (j.gateway ?? []).map((h) => k(h.call))));
2448
- const joins = join5.joins.filter((j) => j.how !== "topic" && !hops.has(k(j.call)));
3492
+ const hops = new Set(join7.joins.flatMap((j) => (j.gateway ?? []).map((h) => k(h.call))));
3493
+ const joins = join7.joins.filter((j) => j.how !== "topic" && !hops.has(k(j.call)));
2449
3494
  const via = (j) => j.gateway?.length ? { via: j.gateway.map((h) => h.route) } : {};
2450
3495
  const upstreamOf = (start) => {
2451
3496
  const out = [];
@@ -2475,10 +3520,10 @@ function vendorImpact(input) {
2475
3520
  return out;
2476
3521
  };
2477
3522
  const fieldUse = (call, change) => {
2478
- if (!change.side || !change.field)
3523
+ if (!change.side || !change.field || change.status)
2479
3524
  return void 0;
2480
3525
  const side = change.side;
2481
- const mine = (input.repos.find((r) => r.repo === call.repo)?.facts ?? []).filter((f) => f.kind === "field" && f.owner === call.fact && (f.side ?? "request") === side).sort((a, b) => cmp2(a.id, b.id));
3526
+ const mine = (input.repos.find((r) => r.repo === call.repo)?.facts ?? []).filter((f) => f.kind === "field" && f.owner === call.fact && (f.side ?? "request") === side).sort((a, b) => cmp4(a.id, b.id));
2482
3527
  if (!mine.length)
2483
3528
  return void 0;
2484
3529
  const want = fieldNameKey(change.field);
@@ -2490,6 +3535,24 @@ function vendorImpact(input) {
2490
3535
  const older = c.endpoints.older;
2491
3536
  const matches = older ? today.matches.filter((m) => m.operation === older) : next.matches.filter((m) => m.operation === c.endpoints.newer);
2492
3537
  const forwards = matches.map((m) => {
3538
+ if (m.direct) {
3539
+ const f = facts.get(k(m.call))?.fact;
3540
+ const field2 = fieldUse(m.call, c);
3541
+ const self = {
3542
+ call: m.call,
3543
+ interface: interfaceId(m.call.component, factIdPart(f?.to ?? input.vendor.system), m.method, m.path),
3544
+ ...field2 ? { field: field2 } : {},
3545
+ ...m.route ? { under: m.route } : {},
3546
+ upstream: upstreamOf(m.route)
3547
+ };
3548
+ return {
3549
+ call: m.call,
3550
+ ...m.route ? { route: m.route } : {},
3551
+ operation: m.operation,
3552
+ direct: true,
3553
+ callers: [self]
3554
+ };
3555
+ }
2493
3556
  const callers = m.route ? joins.filter((j) => k(j.entry) === k(m.route) || (j.gateway ?? []).some((h) => k(h.entry) === k(m.route))).map((j) => {
2494
3557
  const u = under(j.call);
2495
3558
  const field2 = fieldUse(j.call, c);
@@ -2540,7 +3603,7 @@ function vendorImpact(input) {
2540
3603
  if (got?.fact.kind === "entry")
2541
3604
  endpointIds.add(entryEndpointId(got.fact, componentOf(got.repo, got.fact)));
2542
3605
  }
2543
- const flows = (input.flows ?? []).filter((f) => f.trigger && endpointIds.has(f.trigger) || (f.refs ?? []).some((r) => endpointIds.has(r))).map((f) => ({ id: f.id, repo: f.repo })).sort((a, b) => cmp2(a.id, b.id));
3606
+ const flows = (input.flows ?? []).filter((f) => f.trigger && endpointIds.has(f.trigger) || (f.refs ?? []).some((r) => endpointIds.has(r))).map((f) => ({ id: f.id, repo: f.repo })).sort((a, b) => cmp4(a.id, b.id));
2544
3607
  for (const f of flows)
2545
3608
  repos.add(f.repo);
2546
3609
  const systems = /* @__PURE__ */ new Set([input.vendor.system]);
@@ -2567,7 +3630,174 @@ function vendorImpact(input) {
2567
3630
  };
2568
3631
  }
2569
3632
 
3633
+ // packages/intake/dist/contract-files.js
3634
+ var import_yaml8 = __toESM(require_dist(), 1);
3635
+ import { readdir as readdir6, readFile as readFile6, stat as stat3 } from "node:fs/promises";
3636
+ import { join as join6 } from "node:path";
3637
+ function safeServerUrl(url) {
3638
+ const m = /^([a-z][a-z0-9+.-]*:\/\/)([^/?#]*)(.*)$/i.exec(url.trim());
3639
+ if (!m) {
3640
+ const p = safePathOf(url);
3641
+ return p === "/" ? void 0 : p;
3642
+ }
3643
+ const host = m[2].replace(/^.*@/, "");
3644
+ if (!host)
3645
+ return void 0;
3646
+ const rest = (m[3] ?? "").split(/[?#]/, 1)[0] ?? "";
3647
+ const path = rest && rest !== "/" ? safePathOf(rest) : "";
3648
+ return `${m[1].toLowerCase()}${host}${path === "/" ? "" : path ?? ""}`;
3649
+ }
3650
+ var str2 = (m, key3) => {
3651
+ const v = m?.get(key3);
3652
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
3653
+ };
3654
+ var mapAt = (m, key3) => {
3655
+ const v = (0, import_yaml8.isMap)(m) ? m.get(key3, true) : void 0;
3656
+ return (0, import_yaml8.isMap)(v) ? v : void 0;
3657
+ };
3658
+ function readPactFile(text3, file) {
3659
+ const lc = new import_yaml8.LineCounter();
3660
+ let doc;
3661
+ try {
3662
+ doc = (0, import_yaml8.parseDocument)(text3, { lineCounter: lc });
3663
+ } catch {
3664
+ return void 0;
3665
+ }
3666
+ if (doc.errors.length || !(0, import_yaml8.isMap)(doc.contents))
3667
+ return void 0;
3668
+ const root = doc.contents;
3669
+ const consumer = str2(mapAt(root, "consumer"), "name");
3670
+ const provider = str2(mapAt(root, "provider"), "name");
3671
+ const list2 = root.get("interactions", true);
3672
+ if (!consumer || !provider || !(0, import_yaml8.isSeq)(list2))
3673
+ return void 0;
3674
+ const out = [];
3675
+ for (const it of list2.items) {
3676
+ if (!(0, import_yaml8.isMap)(it))
3677
+ continue;
3678
+ const type = str2(it, "type");
3679
+ if (type && !/http/i.test(type))
3680
+ continue;
3681
+ const req = mapAt(it, "request");
3682
+ if (!req)
3683
+ continue;
3684
+ const method = str2(req, "method");
3685
+ const pair = req.items.find((p) => (0, import_yaml8.isScalar)(p.key) && p.key.value === "path");
3686
+ const path = pair && (0, import_yaml8.isScalar)(pair.value) ? String(pair.value.value) : void 0;
3687
+ const safe = path?.startsWith("/") ? safePathOf(path) : void 0;
3688
+ if (!safe)
3689
+ continue;
3690
+ const range = pair.key.range;
3691
+ out.push({
3692
+ format: "pact",
3693
+ file,
3694
+ line: range ? lc.linePos(range[0]).line : 1,
3695
+ consumer,
3696
+ provider,
3697
+ ...method ? { method: method.toUpperCase() } : {},
3698
+ path: safe
3699
+ });
3700
+ }
3701
+ return out;
3702
+ }
3703
+ function readConsumerOpenApi(text3, file, own) {
3704
+ let read;
3705
+ try {
3706
+ read = readOpenApiDocument(text3);
3707
+ } catch {
3708
+ return void 0;
3709
+ }
3710
+ if (!read)
3711
+ return void 0;
3712
+ const served = read.operations.some((op) => own.some((e) => (!e.method || e.method.toUpperCase() === op.method.toUpperCase()) && routeScore(op.path, e.path) >= 500));
3713
+ if (served)
3714
+ return [];
3715
+ const title = read.doc.getIn(["info", "title"]);
3716
+ const provider = typeof title === "string" && title.trim() ? title.trim() : void 0;
3717
+ const hosts = [...new Set(read.servers.map(safeServerUrl).filter((h) => !!h))];
3718
+ return read.operations.flatMap((op) => {
3719
+ const path = safePathOf(op.path);
3720
+ return path ? [
3721
+ {
3722
+ format: "openapi",
3723
+ file,
3724
+ line: op.methodLine ?? op.line ?? 1,
3725
+ ...provider ? { provider } : {},
3726
+ ...hosts.length ? { hosts } : {},
3727
+ method: op.method.toUpperCase(),
3728
+ path
3729
+ }
3730
+ ] : [];
3731
+ });
3732
+ }
3733
+ var SKIP2 = /* @__PURE__ */ new Set([
3734
+ ".git",
3735
+ "node_modules",
3736
+ "vendor",
3737
+ "target",
3738
+ "build",
3739
+ "dist",
3740
+ "out",
3741
+ ".venv",
3742
+ "venv",
3743
+ "__pycache__",
3744
+ ".gradle",
3745
+ ".idea",
3746
+ ".atticus"
3747
+ ]);
3748
+ var MAX_BYTES2 = 5 * 1024 * 1024;
3749
+ var PACT = /pact/i;
3750
+ var SPEC = /(openapi|swagger)/i;
3751
+ async function readContractFiles(dir, o) {
3752
+ const files = [];
3753
+ const walk2 = async (rel) => {
3754
+ const entries2 = await readdir6(join6(dir, ...rel.split("/").filter(Boolean)), {
3755
+ withFileTypes: true
3756
+ }).catch(() => []);
3757
+ for (const e of [...entries2].sort((a, b) => a.name < b.name ? -1 : 1)) {
3758
+ const p = rel ? `${rel}/${e.name}` : e.name;
3759
+ if (e.isDirectory()) {
3760
+ if (!SKIP2.has(e.name))
3761
+ await walk2(p);
3762
+ } else if (e.isFile()) {
3763
+ if (/\.json$/i.test(e.name) && PACT.test(p))
3764
+ files.push(p);
3765
+ else if (/\.(ya?ml|json)$/i.test(e.name) && SPEC.test(e.name))
3766
+ files.push(p);
3767
+ }
3768
+ }
3769
+ };
3770
+ await walk2("");
3771
+ const entries = [];
3772
+ for (const p of files) {
3773
+ const full = join6(dir, ...p.split("/"));
3774
+ const size = (await stat3(full).catch(() => void 0))?.size ?? 0;
3775
+ if (size === 0 || size > MAX_BYTES2)
3776
+ continue;
3777
+ const text3 = await readFile6(full, "utf8");
3778
+ const got = (/\.json$/i.test(p) && PACT.test(p) ? readPactFile(text3, p) : void 0) ?? (SPEC.test(p) ? readConsumerOpenApi(text3, p, o.own ?? []) : void 0);
3779
+ if (!got?.length)
3780
+ continue;
3781
+ if (o.denyHashes?.size) {
3782
+ const text4 = got.map((e) => [e.file, e.consumer, e.provider, ...e.hosts ?? [], e.method, e.path].join("\n")).join("\n");
3783
+ if (denyListHits(text4, o.denyHashes).length) {
3784
+ o.onRefused?.(`${p}: the deny-list names a word in it, so its requests are left out.`);
3785
+ continue;
3786
+ }
3787
+ }
3788
+ entries.push(...got);
3789
+ }
3790
+ entries.sort((a, b) => a.file < b.file ? -1 : a.file > b.file ? 1 : a.line - b.line);
3791
+ return {
3792
+ schemaVersion: 1,
3793
+ repo: o.repo,
3794
+ ...o.commit ? { commit: o.commit } : {},
3795
+ entries
3796
+ };
3797
+ }
3798
+
2570
3799
  export {
3800
+ joinServerVariables,
2571
3801
  classify,
2572
3802
  READERS,
2573
3803
  readOpenApiSpec,
@@ -2580,9 +3810,24 @@ export {
2580
3810
  sortItems,
2581
3811
  opt,
2582
3812
  screenFile,
3813
+ looksSensitive,
3814
+ segmentOf,
3815
+ safePathOf,
3816
+ pathTemplateOf,
3817
+ appLabelOf,
3818
+ denyListHits,
3819
+ aggregateTraffic,
2583
3820
  specEndpointIds,
2584
3821
  readVendorSpec,
2585
3822
  operationSchemas,
3823
+ readProtoSpecs,
3824
+ readAvroSpecs,
3825
+ readJsonSchemaSpecs,
3826
+ readAsyncApiSpecs,
3827
+ openApiContractSpecs,
3828
+ specFormatOf,
3829
+ readContractSpecs,
3830
+ readRepoSpecs,
2586
3831
  nameParts,
2587
3832
  compareVersions,
2588
3833
  scanInputs,
@@ -2605,5 +3850,9 @@ export {
2605
3850
  changeInputSources,
2606
3851
  diffVendorSpecs,
2607
3852
  MAX_UPSTREAM,
2608
- vendorImpact
3853
+ vendorImpact,
3854
+ safeServerUrl,
3855
+ readPactFile,
3856
+ readConsumerOpenApi,
3857
+ readContractFiles
2609
3858
  };