agentic-qe 3.15.6 → 3.15.7

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 (421) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/CHANGELOG.md +141 -0
  3. package/README.md +2 -0
  4. package/assets/skills/skills-manifest.json +1 -1
  5. package/dist/cli/bundle.js +8 -6
  6. package/dist/cli/chunks/adapter-PEOUNYXJ.js +2 -0
  7. package/dist/cli/chunks/{agent-booster-wasm-SY7UCLBL.js → agent-booster-wasm-OS5G7KMQ.js} +2 -2
  8. package/dist/cli/chunks/{agent-handler-KAMYBU3S.js → agent-handler-PI4I7PME.js} +2 -2
  9. package/dist/cli/chunks/{agent-memory-branch-2CAW3KUM.js → agent-memory-branch-J7TXHX4U.js} +2 -2
  10. package/dist/cli/chunks/aqe-learning-engine-DHKZI5RX.js +2 -0
  11. package/dist/cli/chunks/{arena-QCCVIOAH.js → arena-FXESDCFR.js} +4 -4
  12. package/dist/cli/chunks/{arena-4OFLJ3R2.js → arena-OWUGXKNT.js} +2 -2
  13. package/dist/cli/chunks/{audit-RBDQJQJB.js → audit-EPAWLYIZ.js} +3 -3
  14. package/dist/cli/chunks/base-QZWK3D5P.js +2 -0
  15. package/dist/cli/chunks/{better-sqlite3-5JRACCDQ.js → better-sqlite3-IYVR5EQY.js} +2 -2
  16. package/dist/cli/chunks/{brain-handler-W4QIIRT4.js → brain-handler-3W2E6TC6.js} +3 -3
  17. package/dist/cli/chunks/{branch-enumerator-IBNGI572.js → branch-enumerator-HU7VACJ4.js} +2 -2
  18. package/dist/cli/chunks/{browser-GMSCVAOI.js → browser-72XOR6E2.js} +2 -2
  19. package/dist/cli/chunks/browser-workflow-ITPX72RX.js +2 -0
  20. package/dist/cli/chunks/{chunk-CR66HNAE.js → chunk-2423JAA5.js} +1 -1
  21. package/dist/cli/chunks/{chunk-LAY7NCQK.js → chunk-24CENUT4.js} +3 -3
  22. package/dist/cli/chunks/{chunk-PEMSXSP2.js → chunk-2AYBYXOA.js} +2 -2
  23. package/dist/cli/chunks/{chunk-TUDENMAE.js → chunk-2E3XWKEU.js} +2 -2
  24. package/dist/cli/chunks/{chunk-KIDOBLUO.js → chunk-2RJYA6WK.js} +2 -2
  25. package/dist/cli/chunks/{chunk-2IWPJUVV.js → chunk-2YVJ5OUL.js} +5 -5
  26. package/dist/cli/chunks/{chunk-34MDMFET.js → chunk-34JLY3U6.js} +2 -2
  27. package/dist/cli/chunks/{chunk-SV5BUYHH.js → chunk-3JD2USUH.js} +2 -2
  28. package/dist/cli/chunks/{chunk-EF5UHDCG.js → chunk-3RM46XFP.js} +1 -1
  29. package/dist/cli/chunks/{chunk-7XTANLTN.js → chunk-44DPYNPE.js} +1 -1
  30. package/dist/cli/chunks/{chunk-ONPPBLRB.js → chunk-4DIZ5BT6.js} +2 -2
  31. package/dist/cli/chunks/{chunk-22OZIJAD.js → chunk-4G2VNW4C.js} +2 -2
  32. package/dist/cli/chunks/{chunk-LJCEDTUM.js → chunk-56ZKQYZY.js} +3 -3
  33. package/dist/cli/chunks/{chunk-HOEWMEF2.js → chunk-5KCBX225.js} +2 -2
  34. package/dist/cli/chunks/{chunk-V3OLS2NG.js → chunk-5KS7HA37.js} +2 -2
  35. package/dist/cli/chunks/{chunk-MQCTLTGE.js → chunk-5PBRBS7D.js} +2 -2
  36. package/dist/cli/chunks/{chunk-TVLOED6O.js → chunk-5Q22XPTH.js} +2 -2
  37. package/dist/cli/chunks/{chunk-B7RHBKHL.js → chunk-634D2ENF.js} +2 -2
  38. package/dist/cli/chunks/{chunk-7TVIX4WL.js → chunk-6AYRAOCA.js} +2 -2
  39. package/dist/cli/chunks/{chunk-4KOVHQXK.js → chunk-6BO3WCK7.js} +2 -2
  40. package/dist/cli/chunks/{chunk-5HAPS6VD.js → chunk-6FEQ73BF.js} +2 -2
  41. package/dist/cli/chunks/{chunk-FQ5N666N.js → chunk-6JT73S5B.js} +1 -1
  42. package/dist/cli/chunks/{chunk-6MXAJBEA.js → chunk-6OS7HREG.js} +1 -1
  43. package/dist/cli/chunks/{chunk-6R3FBFCJ.js → chunk-6PKCQXEW.js} +2 -2
  44. package/dist/cli/chunks/{chunk-DQNUPEY5.js → chunk-7EX4DEQR.js} +2 -2
  45. package/dist/cli/chunks/{chunk-KCB6P463.js → chunk-7UCVYYWL.js} +2 -2
  46. package/dist/cli/chunks/{chunk-RLB7K7QP.js → chunk-AAA4SHEG.js} +1 -1
  47. package/dist/cli/chunks/{chunk-ITIJ23K2.js → chunk-AXO7OOOA.js} +2 -2
  48. package/dist/cli/chunks/{chunk-6RDVY26I.js → chunk-B7M323VL.js} +2 -2
  49. package/dist/cli/chunks/{chunk-EJ4KZFZN.js → chunk-BB7OLQKO.js} +1 -1
  50. package/dist/cli/chunks/{chunk-5NC7QEJ6.js → chunk-BTIBXGVQ.js} +4 -4
  51. package/dist/cli/chunks/{chunk-RD5BYLN7.js → chunk-BTYKGVJ5.js} +1 -1
  52. package/dist/cli/chunks/{chunk-YXU35GGD.js → chunk-C2CUPJGR.js} +1 -1
  53. package/dist/cli/chunks/{chunk-XFPQIWEH.js → chunk-C2MDBBFF.js} +3 -3
  54. package/dist/cli/chunks/{chunk-QLKUCMZC.js → chunk-CG5DZCOZ.js} +1 -1
  55. package/dist/cli/chunks/{chunk-YLNYPQDR.js → chunk-CIFWOMNX.js} +1 -1
  56. package/dist/cli/chunks/{chunk-ORBODZSO.js → chunk-CWPRU7ZI.js} +2 -2
  57. package/dist/cli/chunks/{chunk-WKDWRRDT.js → chunk-CXTJ47QS.js} +2 -2
  58. package/dist/cli/chunks/{chunk-SOSJWM3E.js → chunk-DCJW2DPL.js} +4 -4
  59. package/dist/cli/chunks/{chunk-GVRFSXY6.js → chunk-DGK6GQMO.js} +2 -2
  60. package/dist/cli/chunks/{chunk-X33F7NXH.js → chunk-DVPGBDBP.js} +3 -3
  61. package/dist/cli/chunks/chunk-EB2PP6X2.js +2 -0
  62. package/dist/cli/chunks/{chunk-HZFK2Z2Z.js → chunk-ECSLJJOQ.js} +1 -1
  63. package/dist/cli/chunks/{chunk-JCE76MPP.js → chunk-ED32XJ5R.js} +2 -2
  64. package/dist/cli/chunks/{chunk-ULCHPPW2.js → chunk-EDU72RTW.js} +1 -1
  65. package/dist/cli/chunks/{chunk-ZOUEQ6DL.js → chunk-EL75G2A3.js} +1 -1
  66. package/dist/cli/chunks/{chunk-GNYOHZVV.js → chunk-EV2BYY6T.js} +1 -1
  67. package/dist/cli/chunks/{chunk-RUTO67PT.js → chunk-F62EKVVC.js} +2 -2
  68. package/dist/cli/chunks/{chunk-IVJIHZSM.js → chunk-FTTFJ7SJ.js} +1 -1
  69. package/dist/cli/chunks/{chunk-NYS2GUNO.js → chunk-FVBFASOD.js} +2 -2
  70. package/dist/cli/chunks/{chunk-5DH5QI7G.js → chunk-G762PEFO.js} +3 -3
  71. package/dist/cli/chunks/{chunk-JPJEAK4G.js → chunk-G7YTZTGU.js} +1 -1
  72. package/dist/cli/chunks/{chunk-5VUIXDY2.js → chunk-GY2SAIXP.js} +2 -2
  73. package/dist/cli/chunks/{chunk-7XUB7U6Z.js → chunk-H4WHDFB5.js} +2 -2
  74. package/dist/cli/chunks/{chunk-72MQCZSM.js → chunk-HLZATDD2.js} +2 -2
  75. package/dist/cli/chunks/{chunk-AX26QJ6T.js → chunk-HPG7354V.js} +2 -2
  76. package/dist/cli/chunks/{chunk-7SAMMQVS.js → chunk-HSDOOFV7.js} +1 -1
  77. package/dist/cli/chunks/{chunk-K55EAWZ5.js → chunk-HTWIGQL4.js} +2 -2
  78. package/dist/cli/chunks/{chunk-BXATKI5S.js → chunk-HXBAQKMH.js} +2 -2
  79. package/dist/cli/chunks/{chunk-46HBVDMU.js → chunk-HZFT3P5B.js} +1 -1
  80. package/dist/cli/chunks/{chunk-RFDFET3O.js → chunk-I7H4IP7T.js} +2 -2
  81. package/dist/cli/chunks/{chunk-AJT3XDRD.js → chunk-IARSGAG7.js} +2 -2
  82. package/dist/cli/chunks/{chunk-TL5GV3PR.js → chunk-IC2WSSD5.js} +3 -3
  83. package/dist/cli/chunks/{chunk-TLUIO37P.js → chunk-ICPALF4Q.js} +2 -2
  84. package/dist/cli/chunks/{chunk-ZSBD4FUX.js → chunk-IWQQIXHO.js} +2 -2
  85. package/dist/cli/chunks/{chunk-AUOSHM63.js → chunk-IYQ7XNE5.js} +2 -2
  86. package/dist/cli/chunks/{chunk-RHIQ6QO5.js → chunk-J26GADQE.js} +281 -281
  87. package/dist/cli/chunks/{chunk-AUN4FG7V.js → chunk-J43DV3ME.js} +1 -1
  88. package/dist/cli/chunks/{chunk-ALCIUWFC.js → chunk-JFPXCQNP.js} +1 -1
  89. package/dist/cli/chunks/{chunk-R363XXGH.js → chunk-JK6B3ULP.js} +2 -2
  90. package/dist/cli/chunks/{chunk-7VTKR44N.js → chunk-JPHDMHFG.js} +2 -2
  91. package/dist/cli/chunks/{chunk-FOJRPEIP.js → chunk-JVYPXW6Y.js} +2 -2
  92. package/dist/cli/chunks/{chunk-ZUTFHGEO.js → chunk-JY4AIEZ7.js} +1 -1
  93. package/dist/cli/chunks/{chunk-47Q7JL3V.js → chunk-JY4WLN3K.js} +2 -2
  94. package/dist/cli/chunks/{chunk-IEPWO4XP.js → chunk-JYXOFN3E.js} +2 -2
  95. package/dist/cli/chunks/{chunk-2CIDFR2H.js → chunk-K7W55B7Q.js} +2 -2
  96. package/dist/cli/chunks/{chunk-D5N2O5EH.js → chunk-KPOPBUUJ.js} +2 -2
  97. package/dist/cli/chunks/{chunk-OQ4S6B7P.js → chunk-LDXQRNTT.js} +1 -1
  98. package/dist/cli/chunks/{chunk-6T6AHVLF.js → chunk-LDZWIV2O.js} +1 -1
  99. package/dist/cli/chunks/{chunk-A7ANPS4E.js → chunk-LGBN7TKC.js} +2 -2
  100. package/dist/cli/chunks/{chunk-X2DR27AY.js → chunk-LMEU64TR.js} +2 -2
  101. package/dist/cli/chunks/{chunk-GI5HWS4H.js → chunk-LP4AS2E4.js} +1 -1
  102. package/dist/cli/chunks/{chunk-VVF337SV.js → chunk-LQOVA4YX.js} +2 -2
  103. package/dist/cli/chunks/{chunk-KYVIOC3C.js → chunk-LVEX4GID.js} +2 -2
  104. package/dist/cli/chunks/{chunk-BO7UFNYV.js → chunk-M63QB466.js} +2 -2
  105. package/dist/cli/chunks/{chunk-UHHMAKPE.js → chunk-MDC4G323.js} +1 -1
  106. package/dist/cli/chunks/{chunk-4CLDYT36.js → chunk-MHZPC4HJ.js} +2 -2
  107. package/dist/cli/chunks/{chunk-24ZSGYC6.js → chunk-MJJC6HUK.js} +1 -1
  108. package/dist/cli/chunks/{chunk-ZL5LJT7D.js → chunk-MKFQNCXI.js} +2 -2
  109. package/dist/cli/chunks/{chunk-XZ46CI35.js → chunk-MMXG3LL6.js} +2 -2
  110. package/dist/cli/chunks/{chunk-OPDZBRIL.js → chunk-MNCF643K.js} +2 -2
  111. package/dist/cli/chunks/{chunk-CEXNW5TR.js → chunk-MNZFEIE5.js} +1 -1
  112. package/dist/cli/chunks/{chunk-L4D3TPFP.js → chunk-MQ6OF6DU.js} +1 -1
  113. package/dist/cli/chunks/{chunk-UB6DQGWM.js → chunk-MRHM4COP.js} +2 -2
  114. package/dist/cli/chunks/{chunk-CLAMMGY3.js → chunk-N4PMPSJJ.js} +2 -2
  115. package/dist/cli/chunks/{chunk-XQ53PZEF.js → chunk-NZQPP533.js} +3 -3
  116. package/dist/cli/chunks/{chunk-FU7LNUD7.js → chunk-OA4GR3EZ.js} +2 -2
  117. package/dist/cli/chunks/{chunk-ORFL3YXB.js → chunk-OJEZNLB6.js} +2 -2
  118. package/dist/cli/chunks/{chunk-5LST62QR.js → chunk-ONVALAZN.js} +2 -2
  119. package/dist/cli/chunks/{chunk-DA7DGDTI.js → chunk-PEKDSJBC.js} +2 -2
  120. package/dist/cli/chunks/{chunk-3DJNKNBR.js → chunk-PG64YV6C.js} +57 -57
  121. package/dist/cli/chunks/{chunk-2ZTWPMTK.js → chunk-PQV7E7XH.js} +2 -2
  122. package/dist/cli/chunks/chunk-PTK66HEY.js +2 -0
  123. package/dist/cli/chunks/{chunk-CZBIREL5.js → chunk-PUECC4WI.js} +2 -2
  124. package/dist/cli/chunks/{chunk-JYKQVYX2.js → chunk-PXZKPUW6.js} +2 -2
  125. package/dist/cli/chunks/{chunk-I7WAW7TM.js → chunk-PYHYOKYT.js} +2 -2
  126. package/dist/cli/chunks/{chunk-LCCTJ2PC.js → chunk-PZG3542B.js} +2 -2
  127. package/dist/cli/chunks/{chunk-F7A2UBZO.js → chunk-Q2T5FXEA.js} +2 -2
  128. package/dist/cli/chunks/{chunk-PS6WFCA4.js → chunk-QJE6ZW2X.js} +2 -2
  129. package/dist/cli/chunks/{chunk-LZWJ5BMP.js → chunk-QNQSM2OG.js} +2 -2
  130. package/dist/cli/chunks/{chunk-QLYO3H7E.js → chunk-QQT6QENQ.js} +2 -2
  131. package/dist/cli/chunks/{chunk-VCONCVSY.js → chunk-QVG4ZDXX.js} +2 -2
  132. package/dist/cli/chunks/{chunk-NMY4KTWA.js → chunk-QWLTHFZW.js} +2 -2
  133. package/dist/cli/chunks/{chunk-NBUXM5X6.js → chunk-RCYLCA7E.js} +2 -2
  134. package/dist/cli/chunks/{chunk-P7DXVL2S.js → chunk-REEIFA6A.js} +2 -2
  135. package/dist/cli/chunks/{chunk-5MT7DMD7.js → chunk-RNYX4CPI.js} +2 -2
  136. package/dist/cli/chunks/{chunk-HAN4MS5T.js → chunk-RORZ5O5Z.js} +2 -2
  137. package/dist/cli/chunks/{chunk-ZCP4P6O2.js → chunk-RRPYWBFX.js} +2 -2
  138. package/dist/cli/chunks/{chunk-3NJ7O3OH.js → chunk-RXAFLK34.js} +2 -2
  139. package/dist/cli/chunks/{chunk-VAYZ5QIE.js → chunk-SQHLC6I5.js} +1 -1
  140. package/dist/cli/chunks/{chunk-Q2RBOC7V.js → chunk-SSP2B2WR.js} +2 -2
  141. package/dist/cli/chunks/{chunk-CCL436IU.js → chunk-SX2YSHE7.js} +14 -6
  142. package/dist/cli/chunks/{chunk-ZTB32K5N.js → chunk-T3ZDVU6F.js} +3 -3
  143. package/dist/cli/chunks/{chunk-624QRKQX.js → chunk-T6W5APYP.js} +1 -1
  144. package/dist/cli/chunks/{chunk-BAYGQRNP.js → chunk-TU4LIIOP.js} +2 -2
  145. package/dist/cli/chunks/{chunk-L2TDHJR3.js → chunk-UBYCR3O4.js} +2 -2
  146. package/dist/cli/chunks/{chunk-JAPBSSFY.js → chunk-UCLN6AME.js} +1 -1
  147. package/dist/cli/chunks/{chunk-66NW3ZB4.js → chunk-UIYKR2SA.js} +2 -2
  148. package/dist/cli/chunks/{chunk-BIXRTOH3.js → chunk-UUHIEM2M.js} +3 -3
  149. package/dist/cli/chunks/{chunk-ELI4GDQO.js → chunk-UY3REQOK.js} +2 -2
  150. package/dist/cli/chunks/{chunk-BUTGIVKW.js → chunk-V2SAEMZY.js} +1 -1
  151. package/dist/cli/chunks/{chunk-6WOZUSSN.js → chunk-V5NGBQAQ.js} +2 -2
  152. package/dist/cli/chunks/{chunk-7TJZDRDU.js → chunk-VCA6YYII.js} +1 -1
  153. package/dist/cli/chunks/chunk-VJRZFWR5.js +2 -0
  154. package/dist/cli/chunks/{chunk-5GIJU2ZY.js → chunk-VKPKYMCT.js} +2 -2
  155. package/dist/cli/chunks/{chunk-XPB5BVU6.js → chunk-VNW5Q2CX.js} +2 -2
  156. package/dist/cli/chunks/{chunk-7QVPMH25.js → chunk-VUFRTGML.js} +2 -2
  157. package/dist/cli/chunks/{chunk-MP3FSUNB.js → chunk-W4X2VTIY.js} +2 -2
  158. package/dist/cli/chunks/{chunk-GWM4M5NF.js → chunk-WTLIEBDH.js} +1 -1
  159. package/dist/cli/chunks/{chunk-QS5KZYUZ.js → chunk-WUV5RZUI.js} +2 -2
  160. package/dist/cli/chunks/{chunk-HEGGV2PT.js → chunk-WXI2STKQ.js} +2 -2
  161. package/dist/cli/chunks/{chunk-GFB6BZWU.js → chunk-XEWXYGJI.js} +2 -2
  162. package/dist/cli/chunks/{chunk-NHRF3V4B.js → chunk-XNSQZ3O7.js} +2 -2
  163. package/dist/cli/chunks/{chunk-4POOJYXA.js → chunk-XTJMY3KS.js} +1 -1
  164. package/dist/cli/chunks/{chunk-LMAEMVPA.js → chunk-XXAVQACL.js} +1 -1
  165. package/dist/cli/chunks/{chunk-RV6HSMKJ.js → chunk-Y4SAWE45.js} +1 -1
  166. package/dist/cli/chunks/{chunk-DLSFT6PO.js → chunk-Y6A46M3B.js} +2 -2
  167. package/dist/cli/chunks/{chunk-5UPIL62W.js → chunk-YDZJWDR6.js} +3 -3
  168. package/dist/cli/chunks/{chunk-F3KS3TAB.js → chunk-YFOBQSOW.js} +2 -2
  169. package/dist/cli/chunks/{chunk-XBEI2JBA.js → chunk-YK3NOC2R.js} +2 -2
  170. package/dist/cli/chunks/{chunk-MQTA6KIO.js → chunk-YUC7RJGR.js} +1 -1
  171. package/dist/cli/chunks/{chunk-A74J23QB.js → chunk-Z3VJLWRR.js} +2 -2
  172. package/dist/cli/chunks/{chunk-YNG7E26C.js → chunk-ZLVQSEZK.js} +2 -2
  173. package/dist/cli/chunks/{chunk-6HWARQWV.js → chunk-ZRLNACPY.js} +2 -2
  174. package/dist/cli/chunks/{chunk-XBFQJZWX.js → chunk-ZTMZFF25.js} +2 -2
  175. package/dist/cli/chunks/chunk-ZUMDDMDE.js +3 -0
  176. package/dist/cli/chunks/{ci-GEJCXMBK.js → ci-5HEXJZ2C.js} +2 -2
  177. package/dist/cli/chunks/{ci-config-2ZVV4OXL.js → ci-config-WU4NPDAM.js} +2 -2
  178. package/dist/cli/chunks/{ci-output-E45OGVPR.js → ci-output-BJQVXX5E.js} +2 -2
  179. package/dist/cli/chunks/{circuit-breaker-X73ITYZC.js → circuit-breaker-3BMGTQCB.js} +2 -2
  180. package/dist/cli/chunks/{claude-flow-setup-W4PPH46C.js → claude-flow-setup-GVDGJWMU.js} +2 -2
  181. package/dist/cli/chunks/client-S7GNYTZ5.js +2 -0
  182. package/dist/cli/chunks/{cline-installer-NUEPMWDE.js → cline-installer-V4MRGWVA.js} +2 -2
  183. package/dist/cli/chunks/{code-6WQHBS7G.js → code-A3TGQPEO.js} +3 -3
  184. package/dist/cli/chunks/{code-index-extractor-BXQIFIFT.js → code-index-extractor-YJQSYWD3.js} +2 -2
  185. package/dist/cli/chunks/{codex-installer-Z337R2KH.js → codex-installer-7N7UQPAH.js} +2 -2
  186. package/dist/cli/chunks/{completions-F5DMYFHV.js → completions-PPGVYLZS.js} +2 -2
  187. package/dist/cli/chunks/{complexity-analyzer-W2SYPZDI.js → complexity-analyzer-XZTFLYV5.js} +2 -2
  188. package/dist/cli/chunks/{continuedev-installer-ZCHUIFTN.js → continuedev-installer-Z5I57RAH.js} +2 -2
  189. package/dist/cli/chunks/{copilot-installer-M5JNODXF.js → copilot-installer-F5YZ6BHB.js} +2 -2
  190. package/dist/cli/chunks/core-handlers-CUEPOQIO.js +2 -0
  191. package/dist/cli/chunks/{cost-tracker-LSYTHBHV.js → cost-tracker-GO33ZQAP.js} +2 -2
  192. package/dist/cli/chunks/{coverage-PGMRS5SS.js → coverage-GSHKLY74.js} +3 -3
  193. package/dist/cli/chunks/cross-domain-router-CXN5QFEV.js +2 -0
  194. package/dist/cli/chunks/{cursor-installer-XPUA73UW.js → cursor-installer-JJ7IVJZB.js} +2 -2
  195. package/dist/cli/chunks/daemon-3DQCKRYO.js +10 -0
  196. package/dist/cli/chunks/{daemon-ITKDIYMW.js → daemon-IRL7QRNE.js} +3 -3
  197. package/dist/cli/chunks/{dag-attention-scheduler-T55AXLD6.js → dag-attention-scheduler-ORXSUHPA.js} +2 -2
  198. package/dist/cli/chunks/{detect-DR7J6K4O.js → detect-RHU62KRI.js} +2 -2
  199. package/dist/cli/chunks/{dist-node-LAJJBOUT.js → dist-node-3VKV4Z6C.js} +2 -2
  200. package/dist/cli/chunks/{domain-handler-OMSHCRMK.js → domain-handler-SFIML4FK.js} +2 -2
  201. package/dist/cli/chunks/{domain-plugins-EQXSKC5K.js → domain-plugins-CJ4FA3OC.js} +2 -2
  202. package/dist/cli/chunks/{domain-transfer-FKRAGVSW.js → domain-transfer-BCRKPCAA.js} +2 -2
  203. package/dist/cli/chunks/dream-5AUNJW24.js +2 -0
  204. package/dist/cli/chunks/{embed-and-insert-pattern-JZFPCNL3.js → embed-and-insert-pattern-VL3HFLPV.js} +2 -2
  205. package/dist/cli/chunks/{eval-JSNNASBW.js → eval-GGKRI4P5.js} +2 -2
  206. package/dist/cli/chunks/{experience-capture-middleware-UPD3IZBK.js → experience-capture-middleware-F72TIRQY.js} +3 -3
  207. package/dist/cli/chunks/{fast-paths-YNMIBS2E.js → fast-paths-7KOOF3MA.js} +2 -2
  208. package/dist/cli/chunks/{feature-flags-SRLXDKBI.js → feature-flags-FNHBTHBH.js} +2 -2
  209. package/dist/cli/chunks/{feature-flags-VIR7O4L7.js → feature-flags-IOZEWWFU.js} +2 -2
  210. package/dist/cli/chunks/file-discovery-AYWF357I.js +2 -0
  211. package/dist/cli/chunks/{fleet-K2ED46EL.js → fleet-QX5KXTRC.js} +3 -3
  212. package/dist/cli/chunks/{gnn-wrapper-QCU4ZRYW.js → gnn-wrapper-OH2DOQP7.js} +2 -2
  213. package/dist/cli/chunks/{heartbeat-handler-YYQI4WZM.js → heartbeat-handler-W67NXTNE.js} +4 -4
  214. package/dist/cli/chunks/heartbeat-scheduler-7ZIDVXIP.js +2 -0
  215. package/dist/cli/chunks/hnsw-adapter-P77OC7FM.js +2 -0
  216. package/dist/cli/chunks/hnsw-index-3LBOTQAW.js +2 -0
  217. package/dist/cli/chunks/{hnsw-legacy-bridge-C5TJSWTZ.js → hnsw-legacy-bridge-6MLLOGOE.js} +2 -2
  218. package/dist/cli/chunks/{hnswlib-node-SE3MJJYS.js → hnswlib-node-4UDISJ3G.js} +2 -2
  219. package/dist/cli/chunks/{hooks-C572SRDH.js → hooks-NOQJWQ4P.js} +10 -10
  220. package/dist/cli/chunks/hybrid-backend-LOM54PDD.js +2 -0
  221. package/dist/cli/chunks/{hypergraph-engine-35A6G3M5.js → hypergraph-engine-2OD3APVP.js} +2 -2
  222. package/dist/cli/chunks/{hypergraph-handler-U2756CWI.js → hypergraph-handler-5AZGMBUM.js} +3 -3
  223. package/dist/cli/chunks/impact-analyzer-QSDJVBPS.js +2 -0
  224. package/dist/cli/chunks/init-guard-SMGJ45PW.js +2 -0
  225. package/dist/cli/chunks/init-handler-5T4MP2NM.js +88 -0
  226. package/dist/cli/chunks/init-wizard-MK2325JJ.js +2 -0
  227. package/dist/cli/chunks/kernel-2NJQQ2KT.js +2 -0
  228. package/dist/cli/chunks/{kilocode-installer-32PX5YH7.js → kilocode-installer-RLZYLVQJ.js} +2 -2
  229. package/dist/cli/chunks/{kiro-installer-C4ROMMUS.js → kiro-installer-LFZOC7VD.js} +2 -2
  230. package/dist/cli/chunks/knowledge-graph-SDISHO62.js +2 -0
  231. package/dist/cli/chunks/{learning-GEPVZGJQ.js → learning-XRPGLUWR.js} +20 -20
  232. package/dist/cli/chunks/{llm-router-XRKTTJTX.js → llm-router-OMK5HYPH.js} +4 -4
  233. package/dist/cli/chunks/llm-router-service-YTCMRBAN.js +2 -0
  234. package/dist/cli/chunks/{load-XVH6HW7E.js → load-XADC7KCU.js} +2 -2
  235. package/dist/cli/chunks/load-test-RPKHLBCC.js +2 -0
  236. package/dist/cli/chunks/{mcp-IULSTM4Z.js → mcp-PIBKSSVU.js} +2 -2
  237. package/dist/cli/chunks/{memory-6K7IAU4T.js → memory-AP7EZERS.js} +5 -5
  238. package/dist/cli/chunks/memory-backend-BZXFO4JZ.js +2 -0
  239. package/dist/cli/chunks/{memory-handlers-CG6DRLAW.js → memory-handlers-MOFDNB6E.js} +2 -2
  240. package/dist/cli/chunks/{multi-model-executor-VZDUYPLX.js → multi-model-executor-7JJ2FZ33.js} +2 -2
  241. package/dist/cli/chunks/{opencode-installer-QUTXKNH4.js → opencode-installer-ZZZ6EBYJ.js} +2 -2
  242. package/dist/cli/chunks/{orchestrator-PCKKUWOP.js → orchestrator-2H2YKSGJ.js} +5 -5
  243. package/dist/cli/chunks/pattern-null-store-4PRPIOR6.js +2 -0
  244. package/dist/cli/chunks/{pattern-usage-recorder-PX5HQVRL.js → pattern-usage-recorder-7MJJWC2Z.js} +2 -2
  245. package/dist/cli/chunks/{pipeline-O562GTOG.js → pipeline-LIE5BWQY.js} +2 -2
  246. package/dist/cli/chunks/{platform-PM7Q2AZS.js → platform-SMYUNLGX.js} +2 -2
  247. package/dist/cli/chunks/{plugin-OTYTFGPY.js → plugin-LJDIXQNT.js} +2 -2
  248. package/dist/cli/chunks/{prime-radiant-advanced-wasm-6CFXTHC2.js → prime-radiant-advanced-wasm-RIDNE5D2.js} +2 -2
  249. package/dist/cli/chunks/project-root-NBIQF63D.js +2 -0
  250. package/dist/cli/chunks/protocol-executor-BRPGIYWQ.js +2 -0
  251. package/dist/cli/chunks/{protocol-handler-PPGNSAOS.js → protocol-handler-YVM66DLI.js} +2 -2
  252. package/dist/cli/chunks/{prove-WQ3BKRZG.js → prove-ZBDT52GD.js} +2 -2
  253. package/dist/cli/chunks/qe-reasoning-bank-GDZACWKW.js +2 -0
  254. package/dist/cli/chunks/{quality-C5WUU3AA.js → quality-DUKXGDDO.js} +2 -2
  255. package/dist/cli/chunks/{quality-gate-WSSRKD5U.js → quality-gate-SM3RXF4V.js} +3 -3
  256. package/dist/cli/chunks/queen-coordinator-LDKLBPD5.js +2 -0
  257. package/dist/cli/chunks/{real-embeddings-CFQE7IRQ.js → real-embeddings-4QLQZDB5.js} +2 -2
  258. package/dist/cli/chunks/{ref-validation-DHKHXVZT.js → ref-validation-M3EO32YQ.js} +2 -2
  259. package/dist/cli/chunks/{roocode-installer-3PPODABV.js → roocode-installer-S6Q5OLV5.js} +2 -2
  260. package/dist/cli/chunks/router-H5YSIRH2.js +2 -0
  261. package/dist/cli/chunks/routing-feedback-5R36TJDH.js +2 -0
  262. package/dist/cli/chunks/{routing-handler-JNXTGT6T.js → routing-handler-55FMUACP.js} +2 -2
  263. package/dist/cli/chunks/{ruvector-commands-6YLROPVP.js → ruvector-commands-QATKAAPK.js} +2 -2
  264. package/dist/cli/chunks/rvf-dual-writer-TT2DBQQQ.js +2 -0
  265. package/dist/cli/chunks/rvf-migration-adapter-BCLFJKSK.js +2 -0
  266. package/dist/cli/chunks/{rvf-migration-coordinator-4DWB4WRK.js → rvf-migration-coordinator-RFXFU6JD.js} +2 -2
  267. package/dist/cli/chunks/rvf-native-adapter-UXI66OQJ.js +2 -0
  268. package/dist/cli/chunks/{rvf-store-integrity-YKR2ZNBF.js → rvf-store-integrity-PKDVXQAW.js} +2 -2
  269. package/dist/cli/chunks/safe-db-MSTD2GDH.js +2 -0
  270. package/dist/cli/chunks/schedule-KST6KIFD.js +2 -0
  271. package/dist/cli/chunks/scheduler-FTQS6YK3.js +2 -0
  272. package/dist/cli/chunks/security-CMRB6WA3.js +18 -0
  273. package/dist/cli/chunks/{shared-rvf-adapter-LNRLFP5I.js → shared-rvf-adapter-YHLLNFHF.js} +2 -2
  274. package/dist/cli/chunks/{shared-rvf-dual-writer-GWU6YQNS.js → shared-rvf-dual-writer-4BGDVPQ7.js} +2 -2
  275. package/dist/cli/chunks/sqlite-persistence-ZX5QFDMR.js +2 -0
  276. package/dist/cli/chunks/{standalone-memory-46KKBSSV.js → standalone-memory-LUHKQAGM.js} +2 -2
  277. package/dist/cli/chunks/{status-handler-35T5FTDQ.js → status-handler-S6S5PNR7.js} +2 -2
  278. package/dist/cli/chunks/{structural-health-P7QPQWLO.js → structural-health-PQ7NZAJ4.js} +2 -2
  279. package/dist/cli/chunks/{sync-W6Z4R4PL.js → sync-Q6KRQXU6.js} +2 -2
  280. package/dist/cli/chunks/{sync-Y43EWBSY.js → sync-S744AEJC.js} +2 -2
  281. package/dist/cli/chunks/{task-handler-5CX3ZYT7.js → task-handler-GAMGEHUW.js} +2 -2
  282. package/dist/cli/chunks/{task-handlers-DQZGOJNE.js → task-handlers-6CRDEELN.js} +3 -3
  283. package/dist/cli/chunks/{test-TPP53VVV.js → test-FNH67DBK.js} +4 -4
  284. package/dist/cli/chunks/{test-scheduling-WBV4UMQH.js → test-scheduling-NZA5SHK6.js} +3 -3
  285. package/dist/cli/chunks/{token-bootstrap-GIIDXHLC.js → token-bootstrap-CXKG55JD.js} +2 -2
  286. package/dist/cli/chunks/{token-usage-AKK37RB7.js → token-usage-M7WWEDJX.js} +2 -2
  287. package/dist/cli/chunks/{transformers-7MASPELS.js → transformers-2IFMCK6A.js} +2 -2
  288. package/dist/cli/chunks/{tree-sitter-wasm-parser-YZKD6UGB.js → tree-sitter-wasm-parser-NMNA6RJC.js} +2 -2
  289. package/dist/cli/chunks/{types-AZ3BTXDP.js → types-N7FWTOLD.js} +2 -2
  290. package/dist/cli/chunks/unified-memory-2Z2F446J.js +2 -0
  291. package/dist/cli/chunks/unified-memory-hnsw-A4EWYPJQ.js +2 -0
  292. package/dist/cli/chunks/unified-persistence-Z6N6JZFA.js +2 -0
  293. package/dist/cli/chunks/{upgrade-L7OTDKEK.js → upgrade-KDB5RGL7.js} +2 -2
  294. package/dist/cli/chunks/{validate-O3QVFIGP.js → validate-KMUV5FUA.js} +2 -2
  295. package/dist/cli/chunks/{validate-swarm-2UGBGLTX.js → validate-swarm-ANZWRCJU.js} +2 -2
  296. package/dist/cli/chunks/visual-security-GXYZV7KR.js +2 -0
  297. package/dist/cli/chunks/{web-tree-sitter-J75IYPRO.js → web-tree-sitter-SXXC4NMS.js} +2 -2
  298. package/dist/cli/chunks/{windsurf-installer-FQ5DBFCG.js → windsurf-installer-2LWSKMBU.js} +2 -2
  299. package/dist/cli/chunks/witness-chain-52PEIEGK.js +2 -0
  300. package/dist/cli/chunks/{witness-chain-I7TN4MXZ.js → witness-chain-JJMSJFZP.js} +2 -2
  301. package/dist/cli/chunks/{witness-chain-repair-D3NE3NQK.js → witness-chain-repair-OX7VFW6T.js} +2 -2
  302. package/dist/cli/chunks/{witness-chain-verifier-RU2WOP5M.js → witness-chain-verifier-QLSMXHAZ.js} +2 -2
  303. package/dist/cli/chunks/{witness-key-manager-IHQB2FR5.js → witness-key-manager-3DS4L7LE.js} +2 -2
  304. package/dist/cli/chunks/{workflow-6BWTNVV6.js → workflow-ARWAMHD3.js} +4 -4
  305. package/dist/cli/chunks/workflow-orchestrator-DORMQMG7.js +2 -0
  306. package/dist/cli/chunks/{wrappers-URVP25VU.js → wrappers-J6KGTUSJ.js} +2 -2
  307. package/dist/cli/commands/learning.js +3 -2
  308. package/dist/cli/commands/security.d.ts +16 -0
  309. package/dist/cli/commands/security.js +76 -9
  310. package/dist/cli/handlers/init-guard.d.ts +21 -1
  311. package/dist/cli/handlers/init-guard.js +51 -8
  312. package/dist/cli/handlers/init-handler.js +57 -56
  313. package/dist/cli/index.js +11 -0
  314. package/dist/cli/utils/ci-output.d.ts +5 -0
  315. package/dist/cli/utils/ci-output.js +8 -0
  316. package/dist/coordination/handlers/security-handlers.js +22 -6
  317. package/dist/coordination/protocols/defect-investigation.js +7 -1
  318. package/dist/coordination/protocols/security-audit.js +11 -0
  319. package/dist/coordination/result-saver.d.ts +9 -0
  320. package/dist/coordination/result-saver.js +34 -4
  321. package/dist/domains/coverage-analysis/collected-metrics.d.ts +2 -0
  322. package/dist/domains/coverage-analysis/collected-metrics.js +6 -0
  323. package/dist/domains/defect-intelligence/services/defect-predictor.js +9 -6
  324. package/dist/domains/quality-assessment/interfaces.d.ts +4 -0
  325. package/dist/domains/quality-assessment/quality-evidence.d.ts +1 -1
  326. package/dist/domains/quality-assessment/services/quality-analyzer.js +7 -5
  327. package/dist/domains/quality-assessment/services/quality-gate.js +12 -3
  328. package/dist/domains/security-compliance/dependency-advisory-engine.d.ts +52 -0
  329. package/dist/domains/security-compliance/dependency-advisory-engine.js +113 -0
  330. package/dist/domains/security-compliance/interfaces.d.ts +30 -0
  331. package/dist/domains/security-compliance/plugin.d.ts +7 -1
  332. package/dist/domains/security-compliance/plugin.js +19 -0
  333. package/dist/domains/security-compliance/services/scanners/dependency-resolver.d.ts +71 -0
  334. package/dist/domains/security-compliance/services/scanners/dependency-resolver.js +232 -0
  335. package/dist/domains/security-compliance/services/scanners/dependency-scanner.d.ts +21 -6
  336. package/dist/domains/security-compliance/services/scanners/dependency-scanner.js +142 -64
  337. package/dist/domains/security-compliance/services/scanners/lockfile-versions.d.ts +43 -0
  338. package/dist/domains/security-compliance/services/scanners/lockfile-versions.js +248 -0
  339. package/dist/domains/security-compliance/services/scanners/scanner-types.d.ts +30 -2
  340. package/dist/domains/security-compliance/services/security-auditor.d.ts +19 -6
  341. package/dist/domains/security-compliance/services/security-auditor.js +133 -92
  342. package/dist/domains/test-execution/services/retry-handler.js +17 -6
  343. package/dist/domains/test-execution/services/test-executor.d.ts +1 -0
  344. package/dist/domains/test-execution/services/test-executor.js +87 -7
  345. package/dist/kernel/shared-dirs.js +17 -5
  346. package/dist/mcp/bundle.js +874 -874
  347. package/dist/mcp/handlers/domain-handler-configs.d.ts +4 -0
  348. package/dist/mcp/handlers/domain-handler-configs.js +5 -1
  349. package/dist/mcp/protocol-server.js +2 -1
  350. package/dist/mcp/types.d.ts +6 -0
  351. package/dist/shared/security/index.d.ts +2 -2
  352. package/dist/shared/security/index.js +1 -1
  353. package/dist/shared/security/osv-client.d.ts +79 -132
  354. package/dist/shared/security/osv-client.js +344 -167
  355. package/dist/shared/security/osv-lookup.d.ts +124 -0
  356. package/dist/shared/security/osv-lookup.js +246 -0
  357. package/dist/shared/security/osv-types.d.ts +119 -0
  358. package/dist/shared/security/osv-types.js +6 -0
  359. package/dist/workers/interfaces.d.ts +6 -1
  360. package/dist/workers/namespaced-keys.d.ts +16 -0
  361. package/dist/workers/namespaced-keys.js +24 -0
  362. package/dist/workers/quality-daemon/persistent-memory.d.ts +1 -1
  363. package/dist/workers/quality-daemon/persistent-memory.js +2 -2
  364. package/dist/workers/worker-manager.js +5 -2
  365. package/dist/workers/workers/defect-predictor.d.ts +25 -8
  366. package/dist/workers/workers/defect-predictor.js +223 -216
  367. package/dist/workers/workers/performance-baseline.d.ts +24 -9
  368. package/dist/workers/workers/performance-baseline.js +187 -230
  369. package/dist/workers/workers/quality-gate.d.ts +11 -9
  370. package/dist/workers/workers/quality-gate.js +125 -267
  371. package/dist/workers/workers/security-scan-records.d.ts +111 -0
  372. package/dist/workers/workers/security-scan-records.js +128 -0
  373. package/dist/workers/workers/security-scan.d.ts +25 -7
  374. package/dist/workers/workers/security-scan.js +187 -164
  375. package/package.json +2 -2
  376. package/dist/cli/chunks/adapter-PP3XIXDV.js +0 -2
  377. package/dist/cli/chunks/aqe-learning-engine-VDUQJKKY.js +0 -2
  378. package/dist/cli/chunks/base-QSYWWPCE.js +0 -2
  379. package/dist/cli/chunks/browser-workflow-WXXPBSCM.js +0 -2
  380. package/dist/cli/chunks/chunk-45MVRQG4.js +0 -2
  381. package/dist/cli/chunks/chunk-5VZVMO7B.js +0 -3
  382. package/dist/cli/chunks/chunk-EECF4CMA.js +0 -2
  383. package/dist/cli/chunks/client-6XKSQ4JT.js +0 -2
  384. package/dist/cli/chunks/core-handlers-OJYW4Y6M.js +0 -2
  385. package/dist/cli/chunks/cross-domain-router-QVUPQ2SC.js +0 -2
  386. package/dist/cli/chunks/daemon-QBYTCIMH.js +0 -10
  387. package/dist/cli/chunks/dream-3UABDRZJ.js +0 -2
  388. package/dist/cli/chunks/file-discovery-ZFGZTKZ4.js +0 -2
  389. package/dist/cli/chunks/heartbeat-scheduler-MJ6MTPDF.js +0 -2
  390. package/dist/cli/chunks/hnsw-adapter-FQWJCFVW.js +0 -2
  391. package/dist/cli/chunks/hnsw-index-NJYKJUHC.js +0 -2
  392. package/dist/cli/chunks/hybrid-backend-SL7RFID7.js +0 -2
  393. package/dist/cli/chunks/impact-analyzer-5ZJTXPVC.js +0 -2
  394. package/dist/cli/chunks/init-handler-PCLYQUSB.js +0 -88
  395. package/dist/cli/chunks/init-wizard-MQMDSIOF.js +0 -2
  396. package/dist/cli/chunks/kernel-MEJ5GMRH.js +0 -2
  397. package/dist/cli/chunks/knowledge-graph-XUBZSEZE.js +0 -2
  398. package/dist/cli/chunks/llm-router-service-QZAPAEPX.js +0 -2
  399. package/dist/cli/chunks/load-test-OVXIQ3AF.js +0 -2
  400. package/dist/cli/chunks/memory-backend-TRPOMPK4.js +0 -2
  401. package/dist/cli/chunks/pattern-null-store-JWYBRBZG.js +0 -2
  402. package/dist/cli/chunks/project-root-VVSTHIP4.js +0 -2
  403. package/dist/cli/chunks/protocol-executor-PXZCLZD3.js +0 -2
  404. package/dist/cli/chunks/qe-reasoning-bank-42FRS5V3.js +0 -2
  405. package/dist/cli/chunks/queen-coordinator-UI3B7DI6.js +0 -2
  406. package/dist/cli/chunks/router-HYRPWLAY.js +0 -2
  407. package/dist/cli/chunks/routing-feedback-BPZ5R6F3.js +0 -2
  408. package/dist/cli/chunks/rvf-dual-writer-DEKDQ6KO.js +0 -2
  409. package/dist/cli/chunks/rvf-migration-adapter-L53VBS7I.js +0 -2
  410. package/dist/cli/chunks/rvf-native-adapter-I6RUGD2D.js +0 -2
  411. package/dist/cli/chunks/safe-db-KS65XDCP.js +0 -2
  412. package/dist/cli/chunks/schedule-KD2VN6GB.js +0 -2
  413. package/dist/cli/chunks/scheduler-ZH3RMUHY.js +0 -2
  414. package/dist/cli/chunks/security-PWQTGDRU.js +0 -13
  415. package/dist/cli/chunks/sqlite-persistence-6DTVME5D.js +0 -2
  416. package/dist/cli/chunks/unified-memory-FCX7NLFZ.js +0 -2
  417. package/dist/cli/chunks/unified-memory-hnsw-VU5QJK37.js +0 -2
  418. package/dist/cli/chunks/unified-persistence-FM376LGE.js +0 -2
  419. package/dist/cli/chunks/visual-security-EU7Y3X46.js +0 -2
  420. package/dist/cli/chunks/witness-chain-CSEBT52D.js +0 -2
  421. package/dist/cli/chunks/workflow-orchestrator-ALNKOM3N.js +0 -2
package/dist/cli/index.js CHANGED
@@ -417,6 +417,17 @@ async function main() {
417
417
  const commandArgs = process.argv.slice(2).filter(arg => arg !== '--');
418
418
  const learningSnapshot = commandArgs[0] === 'learning'
419
419
  && (commandArgs[1] === 'backup' || commandArgs[1] === 'restore');
420
+ // `aqe init` must not create a mistyped AQE_PROJECT_ROOT: the token bootstrap
421
+ // below does `mkdir -p <root>/.agentic-qe`, so the check has to run first.
422
+ if (commandArgs[0] === 'init') {
423
+ const { explicitRootError } = await import('./handlers/init-guard.js');
424
+ const rootError = explicitRootError();
425
+ if (rootError) {
426
+ console.error(chalk.red(`\n ${rootError}\n`));
427
+ await cleanupAndExit(1);
428
+ return;
429
+ }
430
+ }
420
431
  if (!learningSnapshot) {
421
432
  const { bootstrapTokenTracking } = await import('../init/token-bootstrap.js');
422
433
  await bootstrapTokenTracking({
@@ -7,6 +7,7 @@
7
7
  import type { SecurityCoverage } from '../../domains/security-compliance/interfaces.js';
8
8
  import type { SecurityScanEvidence } from '../../domains/security-compliance/scan-evidence.js';
9
9
  import type { discoverSecurityFiles } from '../../domains/security-compliance/scan-discovery.js';
10
+ import type { DependencyScanReport } from '../../domains/security-compliance/dependency-advisory-engine.js';
10
11
  export type OutputFormat = 'text' | 'json' | 'sarif' | 'junit' | 'markdown';
11
12
  export interface CIOutputOptions {
12
13
  format: OutputFormat;
@@ -20,6 +21,8 @@ export interface SecurityVulnerability {
20
21
  message: string;
21
22
  ruleId?: string;
22
23
  cweId?: string;
24
+ /** CVE id of a dependency advisory, when the advisory has one (#1049). */
25
+ cveId?: string;
23
26
  }
24
27
  export interface SecurityScanResult {
25
28
  vulnerabilities: SecurityVulnerability[];
@@ -38,6 +41,8 @@ export interface SecurityScanResult {
38
41
  coverage?: SecurityCoverage;
39
42
  evidence?: SecurityScanEvidence;
40
43
  discovery?: Awaited<ReturnType<typeof discoverSecurityFiles>>['discovery'];
44
+ /** #1049: OSV dependency advisory scan; any status but 'complete' is not a clean result. */
45
+ dependencyScan?: DependencyScanReport;
41
46
  }
42
47
  export type SecurityExecutionStatus = 'complete' | 'partial' | 'none' | 'failed' | 'not-run' | 'unverified';
43
48
  export interface SecurityCheckResult {
@@ -297,6 +297,14 @@ export function securityToMarkdown(result) {
297
297
  if (result.evidence || result.discovery) {
298
298
  md += `## Execution receipts\n\n\`\`\`json\n${toJSON({ evidence: result.evidence, discovery: result.discovery })}\n\`\`\`\n\n`;
299
299
  }
300
+ if (result.dependencyScan) {
301
+ md += `## Dependency advisories (OSV)\n\n**Status:** ${result.dependencyScan.status}\n\n${result.dependencyScan.message}\n\n`;
302
+ for (const pkg of result.dependencyScan.uncheckedPackages) {
303
+ md += `- not checked: ${pkg.name}@${pkg.version} (${pkg.reason})\n`;
304
+ }
305
+ if (result.dependencyScan.uncheckedPackages.length > 0)
306
+ md += '\n';
307
+ }
300
308
  if (result.vulnerabilities.length > 0) {
301
309
  md += `## Vulnerabilities\n\n`;
302
310
  md += `| Severity | Type | File | Line | Message |\n`;
@@ -12,6 +12,7 @@ import { toError } from '../../shared/error-utils.js';
12
12
  import { FilePath } from '../../shared/value-objects/index.js';
13
13
  import { generateSecurityRecommendations } from './handler-utils.js';
14
14
  import { discoverSecurityFiles, isSecuritySourceFile } from '../../domains/security-compliance/scan-discovery.js';
15
+ import { runDependencyAdvisoryScan } from '../../domains/security-compliance/dependency-advisory-engine.js';
15
16
  export function registerSecurityHandlers(ctx) {
16
17
  // Register security scan handler - REAL IMPLEMENTATION
17
18
  ctx.registerHandler('scan-security', async (task) => {
@@ -257,6 +258,13 @@ export function registerSecurityHandlers(ctx) {
257
258
  status: payload.dast ? 'not-run' : 'disabled', scope: 'url', ruleCoverage: 'unknown',
258
259
  errors: payload.dast ? ['DAST was requested without targetUrl.'] : [], limitations: [] });
259
260
  }
261
+ // #1049: OSV dependency advisories. A failed or partial lookup is a
262
+ // failed/partial required engine, never a completed scan with no findings.
263
+ let dependencyScan = null;
264
+ if (payload.dependencies === true) {
265
+ dependencyScan = await runDependencyAdvisoryScan(ctx.getSecurityScanner(), targetPath);
266
+ engines.push(dependencyScan.engine);
267
+ }
260
268
  if (payload.compliance?.length) {
261
269
  engines.push({ id: 'compliance', requested: true, required: true, status: 'not-run',
262
270
  scope: 'requested-files', ruleCoverage: 'unknown', errors: [],
@@ -265,7 +273,7 @@ export function registerSecurityHandlers(ctx) {
265
273
  const requestedPaths = new Set(filesToScan);
266
274
  const analyzedPaths = new Set(fileEvidence.filter(file => file.status === 'analyzed' && requestedPaths.has(file.path)).map(file => file.path));
267
275
  const requiredEngines = engines.filter(engine => engine.requested && engine.required);
268
- const hasExecuted = analyzedPaths.size > 0;
276
+ const hasExecuted = analyzedPaths.size > 0 || (dependencyScan?.report.packagesChecked ?? 0) > 0;
269
277
  const complete = hasExecuted && requiredEngines.every(engine => engine.status === 'completed') &&
270
278
  (!discoveryResult || discoveryResult.discovery.status === 'complete');
271
279
  const evidence = {
@@ -286,18 +294,21 @@ export function registerSecurityHandlers(ctx) {
286
294
  low: crossLangVulns.filter(v => v.severity === 'low').length,
287
295
  informational: crossLangVulns.filter(v => v.severity === 'informational').length,
288
296
  };
297
+ const depVulns = dependencyScan?.vulnerabilities ?? [];
298
+ const depCount = (severity) => depVulns.filter(v => v.severity === severity).length;
289
299
  const summary = {
290
- critical: (sastResult?.summary?.critical || 0) + (dastResult?.summary?.critical || 0) + crossLangSeverityCounts.critical,
291
- high: (sastResult?.summary?.high || 0) + (dastResult?.summary?.high || 0) + crossLangSeverityCounts.high,
292
- medium: (sastResult?.summary?.medium || 0) + (dastResult?.summary?.medium || 0) + crossLangSeverityCounts.medium,
293
- low: (sastResult?.summary?.low || 0) + (dastResult?.summary?.low || 0) + crossLangSeverityCounts.low,
294
- informational: (sastResult?.summary?.informational || 0) + (dastResult?.summary?.informational || 0) + crossLangSeverityCounts.informational,
300
+ critical: (sastResult?.summary?.critical || 0) + (dastResult?.summary?.critical || 0) + crossLangSeverityCounts.critical + depCount('critical'),
301
+ high: (sastResult?.summary?.high || 0) + (dastResult?.summary?.high || 0) + crossLangSeverityCounts.high + depCount('high'),
302
+ medium: (sastResult?.summary?.medium || 0) + (dastResult?.summary?.medium || 0) + crossLangSeverityCounts.medium + depCount('medium'),
303
+ low: (sastResult?.summary?.low || 0) + (dastResult?.summary?.low || 0) + crossLangSeverityCounts.low + depCount('low'),
304
+ informational: (sastResult?.summary?.informational || 0) + (dastResult?.summary?.informational || 0) + crossLangSeverityCounts.informational + depCount('informational'),
295
305
  };
296
306
  // Extract top vulnerabilities from all sources
297
307
  const allVulns = [
298
308
  ...(sastResult?.vulnerabilities || []),
299
309
  ...(dastResult?.vulnerabilities || []),
300
310
  ...crossLangVulns,
311
+ ...depVulns,
301
312
  ];
302
313
  const topVulnerabilities = allVulns
303
314
  .sort((a, b) => {
@@ -316,6 +327,9 @@ export function registerSecurityHandlers(ctx) {
316
327
  const recommendations = allVulns.length === 0 && evidence.completeness !== 'complete'
317
328
  ? ['No findings reported; requested analysis is incomplete or unverified. Inspect execution receipts.']
318
329
  : generateSecurityRecommendations(allVulns);
330
+ if (dependencyScan && dependencyScan.report.status !== 'complete') {
331
+ recommendations.unshift(dependencyScan.report.message);
332
+ }
319
333
  return ok({
320
334
  vulnerabilities: allVulns.length,
321
335
  critical: summary.critical,
@@ -329,7 +343,9 @@ export function registerSecurityHandlers(ctx) {
329
343
  scanTypes: {
330
344
  sast: payload.sast !== false,
331
345
  dast: payload.dast || false,
346
+ dependencies: payload.dependencies === true,
332
347
  },
348
+ ...(dependencyScan ? { dependencyScan: dependencyScan.report } : {}),
333
349
  status: evidence.completeness === 'complete' ? 'completed' : evidence.completeness === 'partial' ? 'partial' : 'unavailable',
334
350
  evidence,
335
351
  limitations: evidence.limitations,
@@ -13,6 +13,7 @@ import { toError } from '../../shared/error-utils.js';
13
13
  import { LoggerFactory } from '../../logging/index.js';
14
14
  import { addToCount } from '../../shared/utils/safe-record.js';
15
15
  import { measuredFileCoverage } from '../../domains/quality-assessment/coverage-report-event.js';
16
+ import { fileCoverageLookupKeys } from '../../domains/coverage-analysis/collected-metrics.js';
16
17
  const logger = LoggerFactory.create('defect-investigation');
17
18
  export const DefectInvestigationEvents = {
18
19
  DefectInvestigationStarted: 'coordination.DefectInvestigationStarted',
@@ -607,7 +608,12 @@ export class DefectInvestigationProtocol {
607
608
  try {
608
609
  // Try per-file coverage (written by coverage-analyzer and test-executor)
609
610
  // #1014: only measured records; legacy unstamped estimates are ignored.
610
- const coverage = measuredFileCoverage(await this.memory.get(`coverage:file:${file}`));
611
+ let coverage = null;
612
+ for (const key of fileCoverageLookupKeys(file)) {
613
+ coverage = measuredFileCoverage(await this.memory.get(key));
614
+ if (coverage)
615
+ break;
616
+ }
611
617
  if (!coverage) {
612
618
  return null;
613
619
  }
@@ -137,6 +137,12 @@ export class SecurityAuditProtocol {
137
137
  if (depResult.success) {
138
138
  this.currentAudit = { ...this.currentAudit, dependencyResult: depResult.value };
139
139
  await this.publishDependencyVulnerabilities(depResult.value.vulnerabilities);
140
+ // #1049: a failed or partial advisory lookup (or a result without a
141
+ // status, which cannot show it was complete) is not a clean dependency scan.
142
+ if (depResult.value.status !== 'complete') {
143
+ this.recordIncompleteCheck(depResult.value.error
144
+ ?? `Dependency advisories could not be checked for ${depResult.value.uncheckedPackages?.length ?? 'unknown number of'} package(s)`);
145
+ }
140
146
  }
141
147
  else {
142
148
  this.recordIncompleteCheck('Dependency scan did not complete');
@@ -280,6 +286,11 @@ export class SecurityAuditProtocol {
280
286
  vulnerabilities: scanResult.value.vulnerabilities,
281
287
  outdatedPackages: [],
282
288
  summary: scanResult.value.summary,
289
+ status: scanResult.value.status,
290
+ measured: scanResult.value.measured,
291
+ packagesChecked: scanResult.value.packagesChecked,
292
+ uncheckedPackages: scanResult.value.uncheckedPackages,
293
+ ...(scanResult.value.error ? { error: scanResult.value.error } : {}),
283
294
  });
284
295
  }
285
296
  }
@@ -88,6 +88,15 @@ export declare class ResultSaver {
88
88
  * `name-1.ext`, `name-2.ext`, … instead of replacing the earlier file (#1007).
89
89
  */
90
90
  private writeNewFile;
91
+ /**
92
+ * File name for a generated test source: the sanitized name capped at
93
+ * MAX_GENERATED_STEM_LENGTH characters (a long source file name would
94
+ * otherwise exceed the filesystem's 255-byte limit once the temp-file suffix
95
+ * is added) plus a short hash of the source path and full name. The hash keeps
96
+ * `src/one/math.ts` and `src/two/math.ts` (or a truncated long name) from
97
+ * overwriting each other, while the same test still maps to the same file.
98
+ */
99
+ private generatedTestFilename;
91
100
  private sanitizeFilename;
92
101
  private getTestExtension;
93
102
  private createFileEntry;
@@ -7,6 +7,8 @@ import * as path from 'path';
7
7
  import { createHash, randomBytes } from 'crypto';
8
8
  import { safeJsonParse } from '../shared/safe-json.js';
9
9
  import { getProjectStorePath } from '../kernel/project-root.js';
10
+ /** Cap on the sanitized stem of a generated test file name (see generatedTestFilename). */
11
+ const MAX_GENERATED_STEM_LENGTH = 100;
10
12
  function securityReportExecution(data) {
11
13
  return data.evidence?.completeness === 'complete' ? 'completed'
12
14
  : data.evidence?.completeness === 'partial' ? 'partial'
@@ -174,14 +176,26 @@ export class ResultSaver {
174
176
  // Save individual test files if code is provided
175
177
  if (data.tests) {
176
178
  for (const test of data.tests) {
177
- if (test.code) {
179
+ // The test-generation domain returns `testCode`; retain `code` for
180
+ // older callers of ResultSaver that already use that field.
181
+ const code = test.testCode ?? test.code;
182
+ if (code) {
178
183
  const ext = this.getTestExtension(options.language || 'typescript', options.framework || 'vitest');
179
- const testFilename = this.sanitizeFilename(test.name) + ext;
184
+ const testFilename = this.generatedTestFilename(test, ext);
180
185
  const testPath = path.join(testDir, testFilename);
181
186
  // Review of #1026 N7: a generated test keeps one file per test name
182
187
  // (replaced atomically), unlike reports, so numbered copies never
183
188
  // pile up for a test runner to collect.
184
- files.push(await this.replaceFile(testPath, test.code, 'source'));
189
+ //
190
+ // One unwritable source file (e.g. a name the filesystem rejects)
191
+ // must not discard the manifest and report, so a per-file failure is
192
+ // skipped; `files` then lists only what is actually on disk.
193
+ try {
194
+ files.push(await this.replaceFile(testPath, code, 'source'));
195
+ }
196
+ catch (error) {
197
+ console.warn(`ResultSaver: could not write generated test ${testFilename}: ${error.message}`);
198
+ }
185
199
  }
186
200
  }
187
201
  }
@@ -504,7 +518,7 @@ ${data.recommendations.length === 0 ? noRecommendations : data.recommendations.m
504
518
  // ==========================================================================
505
519
  // Utilities
506
520
  // ==========================================================================
507
- async ensureDirectories(taskType) {
521
+ async ensureDirectories(_taskType) {
508
522
  const dirs = [
509
523
  this.resultsDir,
510
524
  path.join(this.resultsDir, 'security'),
@@ -563,6 +577,22 @@ ${data.recommendations.length === 0 ? noRecommendations : data.recommendations.m
563
577
  }
564
578
  throw new Error(`ResultSaver: no free file name for ${filePath}`);
565
579
  }
580
+ /**
581
+ * File name for a generated test source: the sanitized name capped at
582
+ * MAX_GENERATED_STEM_LENGTH characters (a long source file name would
583
+ * otherwise exceed the filesystem's 255-byte limit once the temp-file suffix
584
+ * is added) plus a short hash of the source path and full name. The hash keeps
585
+ * `src/one/math.ts` and `src/two/math.ts` (or a truncated long name) from
586
+ * overwriting each other, while the same test still maps to the same file.
587
+ */
588
+ generatedTestFilename(test, ext) {
589
+ const stem = this.sanitizeFilename(test.name).slice(0, MAX_GENERATED_STEM_LENGTH) || 'test';
590
+ const hash = createHash('sha256')
591
+ .update(`${test.file ?? ''}\0${test.name}`)
592
+ .digest('hex')
593
+ .slice(0, 8);
594
+ return `${stem}-${hash}${ext}`;
595
+ }
566
596
  sanitizeFilename(name) {
567
597
  return name.replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase();
568
598
  }
@@ -14,6 +14,8 @@ import type { CoverageSummary, FileCoverage } from './interfaces';
14
14
  * (or the cwd when none is known), so one file never has two records.
15
15
  */
16
16
  export declare function fileCoverageKey(filePath: string, projectRoot?: string): string;
17
+ /** Read the canonical key first, then a measured legacy relative key if present. */
18
+ export declare function fileCoverageLookupKeys(filePath: string, projectRoot?: string): string[];
17
19
  export interface CollectedMetrics {
18
20
  branch: boolean;
19
21
  function: boolean;
@@ -16,6 +16,12 @@ import * as path from 'path';
16
16
  export function fileCoverageKey(filePath, projectRoot) {
17
17
  return path.isAbsolute(filePath) ? path.normalize(filePath) : path.resolve(projectRoot ?? process.cwd(), filePath);
18
18
  }
19
+ /** Read the canonical key first, then a measured legacy relative key if present. */
20
+ export function fileCoverageLookupKeys(filePath, projectRoot) {
21
+ const canonical = `coverage:file:${fileCoverageKey(filePath, projectRoot)}`;
22
+ const legacy = `coverage:file:${filePath}`;
23
+ return canonical === legacy ? [canonical] : [canonical, legacy];
24
+ }
19
25
  /** Which optional metrics the files carry. Line coverage is always collected. */
20
26
  export function collectedMetrics(files) {
21
27
  return {
@@ -15,6 +15,7 @@ import { toError } from '../../../shared/error-utils.js';
15
15
  import { safeJsonParse } from '../../../shared/safe-json.js';
16
16
  import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
17
17
  import { measuredCoverageSummary, measuredFileCoverage } from '../../quality-assessment/coverage-report-event.js';
18
+ import { fileCoverageLookupKeys } from '../../coverage-analysis/collected-metrics.js';
18
19
  // LLMDefectAnalysis is imported from ../interfaces
19
20
  const DEFAULT_CONFIG = {
20
21
  defaultThreshold: 0.5,
@@ -161,7 +162,7 @@ Be specific and actionable. Focus on concrete issues, not generic advice.`,
161
162
  }
162
163
  return null;
163
164
  }
164
- catch (error) {
165
+ catch {
165
166
  logger.warn('LLM analysis failed, using heuristics only');
166
167
  return null;
167
168
  }
@@ -498,7 +499,7 @@ Be specific and actionable. Focus on concrete issues, not generic advice.`,
498
499
  // Count complexity indicators in code
499
500
  const content = fileResult.value;
500
501
  const ifCount = (content.match(/\bif\s*\(/g) || []).length;
501
- const loopCount = (content.match(/\b(for|while|do)\s*[\(\{]/g) || []).length;
502
+ const loopCount = (content.match(/\b(for|while|do)\s*[{(]/g) || []).length;
502
503
  const switchCount = (content.match(/\bswitch\s*\(/g) || []).length;
503
504
  const catchCount = (content.match(/\bcatch\s*\(/g) || []).length;
504
505
  const ternaryCount = (content.match(/\?[^?:]+:/g) || []).length;
@@ -592,10 +593,12 @@ Be specific and actionable. Focus on concrete issues, not generic advice.`,
592
593
  try {
593
594
  // Try per-file coverage (written by coverage-analyzer and test-executor)
594
595
  // #1014: only measured records; legacy unstamped estimates are ignored.
595
- const fileCoverage = measuredFileCoverage(await this.memory.get(`coverage:file:${file}`));
596
- if (fileCoverage) {
597
- // Invert: low coverage = high defect risk
598
- return 1 - fileCoverage.line / 100;
596
+ for (const key of fileCoverageLookupKeys(file)) {
597
+ const fileCoverage = measuredFileCoverage(await this.memory.get(key));
598
+ if (fileCoverage) {
599
+ // Invert: low coverage = high defect risk
600
+ return 1 - fileCoverage.line / 100;
601
+ }
599
602
  }
600
603
  // Fall back to project-wide coverage
601
604
  const summary = measuredCoverageSummary(await this.memory.get('coverage:latest'));
@@ -56,6 +56,10 @@ export interface GateResult {
56
56
  checks: GateCheck[];
57
57
  overallScore: number;
58
58
  failedChecks: string[];
59
+ /** Gate service evidence state; absent for other gate implementations. */
60
+ evidenceStatus?: 'measured' | 'insufficient-evidence';
61
+ /** Configured checks whose input was missing, negative, or non-finite. */
62
+ unmeasured?: string[];
59
63
  }
60
64
  export interface GateCheck {
61
65
  name: string;
@@ -98,7 +98,7 @@ export declare class InsufficientQualityEvidenceError extends Error {
98
98
  * Inspect every canonical metric with the same validation, collecting each
99
99
  * absent, stale, future-dated or malformed record instead of stopping at the first.
100
100
  */
101
- export declare function inspectQualityEvidence(memory: MemoryBackend, options?: {
101
+ export declare function inspectQualityEvidence(memory: Pick<MemoryBackend, 'get'>, options?: {
102
102
  now?: number;
103
103
  maxAgeMs?: number;
104
104
  }): Promise<{
@@ -10,6 +10,7 @@ import { toError } from '../../../shared/error-utils.js';
10
10
  import { safeJsonParse } from '../../../shared/safe-json.js';
11
11
  import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
12
12
  import { measuredCoverageSummary, measuredFileCoverage } from '../coverage-report-event.js';
13
+ import { fileCoverageLookupKeys } from '../../coverage-analysis/collected-metrics.js';
13
14
  /** Metrics the static analyzer produces when the caller asks for all of them. */
14
15
  const ANALYZER_METRICS = ['coverage', 'complexity', 'maintainability', 'duplication', 'testability'];
15
16
  /** Metrics computed from parsing each source file. */
@@ -157,7 +158,7 @@ Focus on:
157
158
  }
158
159
  return null;
159
160
  }
160
- catch (error) {
161
+ catch {
161
162
  logger.warn('LLM insights generation failed:');
162
163
  return null;
163
164
  }
@@ -226,7 +227,7 @@ Focus on:
226
227
  }
227
228
  return null;
228
229
  }
229
- catch (error) {
230
+ catch {
230
231
  logger.warn('Failed to parse LLM insights response:');
231
232
  return null;
232
233
  }
@@ -508,9 +509,10 @@ Focus on:
508
509
  // 1. Try per-file coverage stored by test executor
509
510
  // #1014: only measured records count. Legacy unstamped estimate
510
511
  // records (written by <= 3.15.4, never expiring) are ignored.
511
- const fileCoverage = measuredFileCoverage(await this.memory.get(`coverage:file:${file}`));
512
- if (fileCoverage) {
513
- return fileCoverage.line;
512
+ for (const key of fileCoverageLookupKeys(file)) {
513
+ const fileCoverage = measuredFileCoverage(await this.memory.get(key));
514
+ if (fileCoverage)
515
+ return fileCoverage.line;
514
516
  }
515
517
  // 2. Fall back to project-wide summary from coverage-analyzer
516
518
  const summary = measuredCoverageSummary(await this.memory.get('coverage:latest'));
@@ -5,6 +5,7 @@
5
5
  import { v4 as uuidv4 } from 'uuid';
6
6
  import { ok, err } from '../../../shared/types/index.js';
7
7
  import { toError } from '../../../shared/error-utils.js';
8
+ import { isMeasuredMetricValue } from '../evidence-sufficiency.js';
8
9
  const DEFAULT_CONFIG = {
9
10
  strictMode: false,
10
11
  enableWarnings: true,
@@ -80,6 +81,12 @@ export class QualityGateService {
80
81
  // Evaluate each threshold
81
82
  checks.push(...this.evaluateMinThresholds(metrics, thresholds));
82
83
  checks.push(...this.evaluateMaxThresholds(metrics, thresholds));
84
+ if (checks.length === 0) {
85
+ return err(new Error('No thresholds configured for gate evaluation'));
86
+ }
87
+ const unmeasured = checks
88
+ .filter((check) => !isMeasuredMetricValue(check.value))
89
+ .map((check) => check.name);
83
90
  // Collect failed checks
84
91
  for (const check of checks) {
85
92
  if (!check.passed) {
@@ -89,13 +96,15 @@ export class QualityGateService {
89
96
  // Calculate overall score (0-100)
90
97
  const overallScore = this.calculateOverallScore(checks);
91
98
  // Determine pass/fail based on critical checks
92
- const passed = this.determineGateStatus(checks);
99
+ const passed = unmeasured.length === 0 && this.determineGateStatus(checks);
93
100
  const result = {
94
101
  gateName,
95
102
  passed,
96
103
  checks,
97
104
  overallScore,
98
105
  failedChecks,
106
+ evidenceStatus: unmeasured.length === 0 ? 'measured' : 'insufficient-evidence',
107
+ unmeasured,
99
108
  };
100
109
  // Store evaluation result in memory
101
110
  await this.storeEvaluationResult(result);
@@ -188,9 +197,9 @@ export class QualityGateService {
188
197
  return checks;
189
198
  }
190
199
  createCheck(name, value, threshold, type, severity) {
191
- const passed = type === 'min'
200
+ const passed = isMeasuredMetricValue(value) && (type === 'min'
192
201
  ? value >= threshold
193
- : value <= threshold;
202
+ : value <= threshold);
194
203
  return {
195
204
  name,
196
205
  passed,
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Dependency advisory (OSV) engine for the scan-security task (#1049).
3
+ *
4
+ * Runs the security-compliance DependencyScanner on the project's package.json
5
+ * and turns its outcome into an execution receipt. A failed or partial OSV
6
+ * lookup is a failed/partial engine with the unchecked packages listed, never
7
+ * a completed engine with zero findings.
8
+ */
9
+ import type { SecurityEngineEvidence } from './scan-evidence.js';
10
+ import type { Vulnerability, UncheckedDependency, LocalDependency } from './interfaces.js';
11
+ import type { DependencyScanResult } from './services/scanners/scanner-types.js';
12
+ import type { Result } from '../../shared/types/index.js';
13
+ export declare const DEPENDENCY_ADVISORY_ENGINE_ID = "osv-dependency-advisories";
14
+ /** The dependency scan as reported to MCP and CLI consumers. */
15
+ export interface DependencyScanReport {
16
+ status: 'complete' | 'incomplete' | 'failed' | 'not-run';
17
+ measured: boolean;
18
+ manifest?: string;
19
+ /** Lockfile the checked versions were resolved from, or null (exact specs only). */
20
+ lockfile?: string | null;
21
+ packagesRequested: number;
22
+ packagesChecked: number;
23
+ uncheckedPackages: UncheckedDependency[];
24
+ /** Local workspace / linked packages: not OSV subjects, excluded from the counts. */
25
+ localPackages: LocalDependency[];
26
+ /** Why the scan is not complete beyond individual packages (malformed lockfile, workspace root #1057). */
27
+ resolutionErrors: string[];
28
+ /** Only direct dependencies are checked; transitive dependencies are not. */
29
+ scope: 'direct';
30
+ vulnerabilities: number;
31
+ scanId?: string;
32
+ error?: string;
33
+ /** One plain sentence for humans; says when advisories could not be checked. */
34
+ message: string;
35
+ }
36
+ export interface DependencyAdvisoryOutcome {
37
+ engine: SecurityEngineEvidence;
38
+ vulnerabilities: Vulnerability[];
39
+ report: DependencyScanReport;
40
+ }
41
+ interface PackageJsonScanner {
42
+ scanPackageJson(packageJsonPath: string): Promise<Result<DependencyScanResult>>;
43
+ }
44
+ /** The package.json for a scan target: the target directory's, else the project root's. */
45
+ export declare function findPackageJson(targetPath: string, env?: NodeJS.ProcessEnv): Promise<string | null>;
46
+ /** Human message for a dependency scan outcome. */
47
+ export declare const DEPENDENCY_SCOPE_NOTE = "direct dependencies of this package.json only; workspace members and transitive dependencies are not checked";
48
+ export declare function dependencyScanMessage(report: Omit<DependencyScanReport, 'message'>): string;
49
+ /** Run the OSV dependency scan for a target and describe it as an engine receipt. */
50
+ export declare function runDependencyAdvisoryScan(scanner: PackageJsonScanner, targetPath: string): Promise<DependencyAdvisoryOutcome>;
51
+ export {};
52
+ //# sourceMappingURL=dependency-advisory-engine.d.ts.map
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Dependency advisory (OSV) engine for the scan-security task (#1049).
3
+ *
4
+ * Runs the security-compliance DependencyScanner on the project's package.json
5
+ * and turns its outcome into an execution receipt. A failed or partial OSV
6
+ * lookup is a failed/partial engine with the unchecked packages listed, never
7
+ * a completed engine with zero findings.
8
+ */
9
+ import * as fs from 'fs/promises';
10
+ import * as path from 'path';
11
+ export const DEPENDENCY_ADVISORY_ENGINE_ID = 'osv-dependency-advisories';
12
+ /** The package.json for a scan target: the target directory's, else the project root's. */
13
+ export async function findPackageJson(targetPath, env = process.env) {
14
+ let dir = targetPath;
15
+ try {
16
+ if (!(await fs.stat(targetPath)).isDirectory())
17
+ dir = path.dirname(targetPath);
18
+ }
19
+ catch {
20
+ dir = path.dirname(targetPath);
21
+ }
22
+ const candidates = [dir, env.AQE_PROJECT_ROOT ? path.resolve(env.AQE_PROJECT_ROOT) : null];
23
+ for (const candidate of candidates) {
24
+ if (!candidate)
25
+ continue;
26
+ const manifest = path.join(candidate, 'package.json');
27
+ try {
28
+ if ((await fs.stat(manifest)).isFile())
29
+ return manifest;
30
+ }
31
+ catch { /* try next */ }
32
+ }
33
+ return null;
34
+ }
35
+ /** Human message for a dependency scan outcome. */
36
+ export const DEPENDENCY_SCOPE_NOTE = 'direct dependencies of this package.json only; workspace members and transitive dependencies are not checked';
37
+ export function dependencyScanMessage(report) {
38
+ return `${statusMessage(report)} Scope: ${DEPENDENCY_SCOPE_NOTE}.`;
39
+ }
40
+ function statusMessage(report) {
41
+ switch (report.status) {
42
+ case 'complete':
43
+ return report.packagesRequested === 0
44
+ ? `No registry dependencies to check${report.localPackages.length ? ` (${report.localPackages.length} local package(s) excluded)` : ' in package.json'}; nothing to check (complete).`
45
+ : `Dependency advisories checked for all ${report.packagesChecked} package(s): ${report.vulnerabilities} advisory finding(s).`;
46
+ case 'incomplete':
47
+ return (report.uncheckedPackages.length > 0
48
+ ? `Dependency advisories could not be checked for ${report.uncheckedPackages.length} of ${report.packagesRequested} package(s); ` : '') +
49
+ (report.resolutionErrors.length > 0 ? `${report.resolutionErrors.slice(0, 3).join('; ')}; ` : '') +
50
+ `${report.vulnerabilities} finding(s) from the ${report.packagesChecked} checked package(s). Dependency scan is INCOMPLETE, not clean.`;
51
+ case 'failed':
52
+ return `${report.error ?? `Dependency advisories could not be checked for ${report.uncheckedPackages.length} package(s)`}. ` +
53
+ 'Dependency vulnerabilities are UNMEASURED, not zero.';
54
+ default:
55
+ return report.error ?? 'Dependency advisory scan did not run.';
56
+ }
57
+ }
58
+ function notRun(reason, manifest) {
59
+ const base = { status: 'not-run', measured: false, ...(manifest ? { manifest } : {}),
60
+ packagesRequested: 0, packagesChecked: 0, uncheckedPackages: [], localPackages: [],
61
+ resolutionErrors: [], scope: 'direct',
62
+ vulnerabilities: 0, error: reason };
63
+ return {
64
+ engine: { id: DEPENDENCY_ADVISORY_ENGINE_ID, requested: true, required: true, status: 'failed', scope: 'parent-directory',
65
+ ...(manifest ? { target: manifest } : {}), analyzedFiles: 0, ruleCoverage: 'unknown', errors: [reason], limitations: [] },
66
+ vulnerabilities: [],
67
+ report: { ...base, message: dependencyScanMessage(base) },
68
+ };
69
+ }
70
+ /** Run the OSV dependency scan for a target and describe it as an engine receipt. */
71
+ export async function runDependencyAdvisoryScan(scanner, targetPath) {
72
+ const manifest = await findPackageJson(targetPath);
73
+ if (!manifest)
74
+ return notRun('No package.json found for the dependency advisory scan.');
75
+ let scan;
76
+ try {
77
+ scan = await scanner.scanPackageJson(manifest);
78
+ }
79
+ catch (error) {
80
+ return notRun(`Dependency advisory scan failed: ${error instanceof Error ? error.message : String(error)}`, manifest);
81
+ }
82
+ if (!scan.success)
83
+ return notRun(`Dependency advisory scan did not run: ${scan.error.message}`, manifest);
84
+ const value = scan.value;
85
+ const unchecked = value.uncheckedPackages.map((p) => `${p.name}@${p.version}: ${p.reason}`);
86
+ const base = {
87
+ status: value.status, measured: value.measured, manifest, lockfile: value.lockfile ?? null,
88
+ packagesRequested: value.packagesScanned, packagesChecked: value.packagesChecked,
89
+ uncheckedPackages: value.uncheckedPackages, localPackages: value.localPackages ?? [],
90
+ resolutionErrors: value.resolutionErrors ?? [], scope: 'direct',
91
+ vulnerabilities: value.vulnerabilities.length,
92
+ scanId: value.scanId, ...(value.error ? { error: value.error } : {}),
93
+ };
94
+ return {
95
+ engine: {
96
+ id: DEPENDENCY_ADVISORY_ENGINE_ID, requested: true, required: true,
97
+ status: value.status === 'complete' ? 'completed' : value.status === 'incomplete' ? 'partial' : 'failed',
98
+ scope: 'parent-directory', target: manifest, ruleCoverage: 'unknown',
99
+ errors: [...(value.error ? [value.error] : []), ...(value.resolutionErrors ?? []), ...unchecked.slice(0, 20),
100
+ ...(unchecked.length > 20 ? [`... and ${unchecked.length - 20} more unchecked package(s)`] : [])],
101
+ limitations: [
102
+ value.lockfile
103
+ ? `Direct dependencies are checked at the versions ${value.lockfile} resolves (when in sync with package.json); transitive dependencies are not checked.`
104
+ : 'No lockfile: only exact versions in package.json are checked; ranges are reported unchecked. Transitive dependencies are not checked.',
105
+ ...((value.localPackages ?? []).length > 0
106
+ ? [`${value.localPackages.length} local workspace/linked package(s) are not OSV subjects and were excluded.`] : []),
107
+ ],
108
+ },
109
+ vulnerabilities: value.vulnerabilities,
110
+ report: { ...base, message: dependencyScanMessage(base) },
111
+ };
112
+ }
113
+ //# sourceMappingURL=dependency-advisory-engine.js.map