agentic-qe 3.14.2 → 3.14.3

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 (372) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/CHANGELOG.md +72 -0
  3. package/assets/skills/skills-manifest.json +1 -1
  4. package/dist/cli/bundle.js +5 -5
  5. package/dist/cli/chunks/adapter-AKQYU6UH.js +2 -0
  6. package/dist/cli/chunks/{agent-booster-wasm-SD5N32MX.js → agent-booster-wasm-TQOMLWWX.js} +2 -2
  7. package/dist/cli/chunks/{agent-handler-OZRSJM7F.js → agent-handler-Q3SEMMI2.js} +2 -2
  8. package/dist/cli/chunks/{agent-memory-branch-NYTRANRN.js → agent-memory-branch-SJXAQSZI.js} +2 -2
  9. package/dist/cli/chunks/aqe-learning-engine-MICRPL3N.js +2 -0
  10. package/dist/cli/chunks/{arena-EX3SC2DP.js → arena-7RC7TBGW.js} +4 -4
  11. package/dist/cli/chunks/{arena-FOTVSRK4.js → arena-UPB7TKUY.js} +2 -2
  12. package/dist/cli/chunks/{audit-Q5GHSUQY.js → audit-IXN5R4WB.js} +3 -3
  13. package/dist/cli/chunks/base-DZK36ITB.js +2 -0
  14. package/dist/cli/chunks/{better-sqlite3-S7M5R2HS.js → better-sqlite3-RP4DEGK3.js} +2 -2
  15. package/dist/cli/chunks/{brain-handler-5FSA46R5.js → brain-handler-H5OVZ22L.js} +3 -3
  16. package/dist/cli/chunks/{branch-enumerator-RWAXTGEU.js → branch-enumerator-VPRWDGFJ.js} +2 -2
  17. package/dist/cli/chunks/{browser-IGDESJGF.js → browser-B6E7JPPJ.js} +2 -2
  18. package/dist/cli/chunks/browser-workflow-ADK54DOE.js +2 -0
  19. package/dist/cli/chunks/{chunk-E3Q7WNJD.js → chunk-26GM5CWD.js} +3 -3
  20. package/dist/cli/chunks/{chunk-BWRHOIYC.js → chunk-2GNRW3OD.js} +2 -2
  21. package/dist/cli/chunks/{chunk-ZCDXJ27H.js → chunk-2IGT5WNQ.js} +1 -1
  22. package/dist/cli/chunks/{chunk-7SK6IMGZ.js → chunk-2WT7AKKK.js} +2 -2
  23. package/dist/cli/chunks/{chunk-DVHWLAEO.js → chunk-33VPWGCM.js} +3 -3
  24. package/dist/cli/chunks/{chunk-NAZVPZJS.js → chunk-37BASGWC.js} +2 -2
  25. package/dist/cli/chunks/{chunk-Q335R4MR.js → chunk-3ABRGG3C.js} +2 -2
  26. package/dist/cli/chunks/{chunk-IWFL6EFI.js → chunk-3P6NCFI2.js} +2 -2
  27. package/dist/cli/chunks/{chunk-4AKGBUYD.js → chunk-42VSQ2MX.js} +3 -3
  28. package/dist/cli/chunks/{chunk-2LKAMMMI.js → chunk-44WISFTU.js} +2 -2
  29. package/dist/cli/chunks/{chunk-RFNEHNJV.js → chunk-4C6UJIHB.js} +1 -1
  30. package/dist/cli/chunks/{chunk-CTCQOYBS.js → chunk-4JBFJTHJ.js} +1 -1
  31. package/dist/cli/chunks/{chunk-GJAWEUIN.js → chunk-4OUPCTBS.js} +2 -2
  32. package/dist/cli/chunks/{chunk-2EHFEMRU.js → chunk-4Q35TI6Z.js} +2 -2
  33. package/dist/cli/chunks/{chunk-N3RN4QTC.js → chunk-4RP5VUBI.js} +2 -2
  34. package/dist/cli/chunks/{chunk-ZYLSOBOR.js → chunk-4TXAP3YH.js} +1 -1
  35. package/dist/cli/chunks/{chunk-KZOBLLXW.js → chunk-4UDZLD42.js} +2 -2
  36. package/dist/cli/chunks/{chunk-UYTWDS2R.js → chunk-4W7QVUNO.js} +2 -2
  37. package/dist/cli/chunks/{chunk-4ZUZDFAA.js → chunk-4XPPMADQ.js} +2 -2
  38. package/dist/cli/chunks/{chunk-TENYL5TI.js → chunk-527HQAY7.js} +2 -2
  39. package/dist/cli/chunks/chunk-5BLFXQEB.js +96 -0
  40. package/dist/cli/chunks/{chunk-OX6T26CD.js → chunk-5DFHE4H5.js} +3 -3
  41. package/dist/cli/chunks/{chunk-T46LOLW3.js → chunk-5F6DWHQG.js} +2 -2
  42. package/dist/cli/chunks/{chunk-FVGTINVR.js → chunk-5FOZO7KM.js} +81 -65
  43. package/dist/cli/chunks/{chunk-T4C56HBW.js → chunk-5IAB5NRZ.js} +2 -2
  44. package/dist/cli/chunks/{chunk-4MH22236.js → chunk-5P3G6ZW4.js} +1 -1
  45. package/dist/cli/chunks/{chunk-7AFBNU6K.js → chunk-5Y5TC6BY.js} +2 -2
  46. package/dist/cli/chunks/{chunk-VSYBMNIR.js → chunk-6F2RM6X2.js} +1 -1
  47. package/dist/cli/chunks/{chunk-ICKLBATY.js → chunk-72UJXEKQ.js} +2 -2
  48. package/dist/cli/chunks/{chunk-A7N3YUDJ.js → chunk-74PK3NEW.js} +2 -2
  49. package/dist/cli/chunks/{chunk-PMUBG2RU.js → chunk-7BUERZYL.js} +2 -2
  50. package/dist/cli/chunks/{chunk-HZMLNM2T.js → chunk-7FYMDKQH.js} +174 -169
  51. package/dist/cli/chunks/{chunk-67A6PEZM.js → chunk-7G6UX2QN.js} +2 -2
  52. package/dist/cli/chunks/{chunk-G2CLZVYI.js → chunk-7JQHPANT.js} +3 -3
  53. package/dist/cli/chunks/{chunk-TLPL3EQY.js → chunk-7SLAZAVU.js} +2 -2
  54. package/dist/cli/chunks/{chunk-4UCMTYFQ.js → chunk-7Y2CEXRS.js} +4 -4
  55. package/dist/cli/chunks/{chunk-2H5YJ5ZK.js → chunk-AB4U6ZNI.js} +2 -2
  56. package/dist/cli/chunks/chunk-AWNYEAGB.js +2 -0
  57. package/dist/cli/chunks/chunk-B2ZONZPZ.js +5 -0
  58. package/dist/cli/chunks/{chunk-6F4WHN7D.js → chunk-B5XFDFBT.js} +1 -1
  59. package/dist/cli/chunks/{chunk-5EHLGOWW.js → chunk-B7SWW5A6.js} +2 -2
  60. package/dist/cli/chunks/{chunk-P64DMQ2C.js → chunk-BN7DKW5D.js} +1 -1
  61. package/dist/cli/chunks/{chunk-CIESXO73.js → chunk-C46DMCWF.js} +1 -1
  62. package/dist/cli/chunks/{chunk-HZ6NEJMO.js → chunk-CB5JPRIZ.js} +2 -2
  63. package/dist/cli/chunks/{chunk-SEHCX4NH.js → chunk-CBOPBYPU.js} +1 -1
  64. package/dist/cli/chunks/{chunk-LWUJQGCS.js → chunk-CR3QGHVN.js} +2 -2
  65. package/dist/cli/chunks/{chunk-NHHWLJQF.js → chunk-D4Z2N74A.js} +1 -1
  66. package/dist/cli/chunks/{chunk-4K27ESCA.js → chunk-DBA3N742.js} +1 -1
  67. package/dist/cli/chunks/{chunk-2TG24LYQ.js → chunk-DX3C5HPN.js} +1 -1
  68. package/dist/cli/chunks/{chunk-S4MR6RTE.js → chunk-E3FBW6G2.js} +1 -1
  69. package/dist/cli/chunks/{chunk-GHUPID5E.js → chunk-ELU4IC3I.js} +1 -1
  70. package/dist/cli/chunks/{chunk-C7AXRI7E.js → chunk-EY4OQHU3.js} +1 -1
  71. package/dist/cli/chunks/{chunk-6LMLN5R2.js → chunk-F67AV5P2.js} +2 -2
  72. package/dist/cli/chunks/chunk-FD2JFEQC.js +2 -0
  73. package/dist/cli/chunks/chunk-FKG5OQFT.js +2 -0
  74. package/dist/cli/chunks/{chunk-UIGEUEBT.js → chunk-FUE6LL72.js} +2 -2
  75. package/dist/cli/chunks/{chunk-4RT7I7PI.js → chunk-G5C2XVZC.js} +1 -1
  76. package/dist/cli/chunks/{chunk-WVY22NHZ.js → chunk-G6DCESPU.js} +2 -2
  77. package/dist/cli/chunks/{chunk-3DFFFXXO.js → chunk-G6ZHTF42.js} +2 -2
  78. package/dist/cli/chunks/{chunk-CH2TQCV5.js → chunk-GNTVFN7D.js} +1 -1
  79. package/dist/cli/chunks/{chunk-WMW47QMR.js → chunk-H5ZRV5K5.js} +2 -2
  80. package/dist/cli/chunks/{chunk-4M6A3PVJ.js → chunk-H6XBM2LY.js} +2 -2
  81. package/dist/cli/chunks/{chunk-4N44UJGI.js → chunk-HOQQCY2K.js} +2 -2
  82. package/dist/cli/chunks/{chunk-D4RCV4LY.js → chunk-HRUU7E3D.js} +2 -2
  83. package/dist/cli/chunks/{chunk-EAJK25IS.js → chunk-HXE5NBJG.js} +1 -1
  84. package/dist/cli/chunks/{chunk-IUNMW454.js → chunk-I4NDQGKP.js} +2 -2
  85. package/dist/cli/chunks/{chunk-CJHVOBJY.js → chunk-IFFZR6GY.js} +1 -1
  86. package/dist/cli/chunks/{chunk-YN6W2XIT.js → chunk-IKIITGU5.js} +3 -3
  87. package/dist/cli/chunks/{chunk-JIUF6NV6.js → chunk-IP7NSFQQ.js} +2 -2
  88. package/dist/cli/chunks/{chunk-3C2K4YMS.js → chunk-IQEJGZV6.js} +3 -3
  89. package/dist/cli/chunks/{chunk-RGH3WGWD.js → chunk-IU4EBTA2.js} +3 -3
  90. package/dist/cli/chunks/{chunk-QW4LN5NK.js → chunk-JBB7E26R.js} +2 -2
  91. package/dist/cli/chunks/{chunk-RYJHREYS.js → chunk-JRYZKBY2.js} +2 -2
  92. package/dist/cli/chunks/{chunk-6EHN7Q2Q.js → chunk-JV4FZUE7.js} +2 -2
  93. package/dist/cli/chunks/{chunk-PZKZY6PB.js → chunk-KF63AYXD.js} +2 -2
  94. package/dist/cli/chunks/{chunk-ZFGND4QK.js → chunk-KPMGTVB4.js} +1 -1
  95. package/dist/cli/chunks/chunk-L2GKMBDP.js +2 -0
  96. package/dist/cli/chunks/{chunk-7FWP7CZY.js → chunk-LHGNNZ76.js} +3 -3
  97. package/dist/cli/chunks/{chunk-HSJ5FQCF.js → chunk-LKN7JQTW.js} +2 -2
  98. package/dist/cli/chunks/{chunk-EH5OCHAJ.js → chunk-LLVGTEHU.js} +1 -1
  99. package/dist/cli/chunks/{chunk-TYVQNYXX.js → chunk-LS3EUMBP.js} +6 -6
  100. package/dist/cli/chunks/{chunk-F2KRT2II.js → chunk-LTBCAFTZ.js} +3 -3
  101. package/dist/cli/chunks/{chunk-PVHO6KLB.js → chunk-LVLBIKJD.js} +1 -1
  102. package/dist/cli/chunks/{chunk-5WJUNRTY.js → chunk-MDZ6RRLX.js} +2 -2
  103. package/dist/cli/chunks/{chunk-W4OQYLYO.js → chunk-MWWAMDHI.js} +1 -1
  104. package/dist/cli/chunks/{chunk-N5ZRUOMR.js → chunk-MXMFGSWR.js} +2 -2
  105. package/dist/cli/chunks/{chunk-L2F7FVIU.js → chunk-N4H2QOT5.js} +2 -2
  106. package/dist/cli/chunks/{chunk-R5RNOLHI.js → chunk-NBWQBQO5.js} +1 -1
  107. package/dist/cli/chunks/{chunk-IVGVOGIZ.js → chunk-NN76NTOX.js} +1 -1
  108. package/dist/cli/chunks/{chunk-OBCKP3G4.js → chunk-NTSXHZTC.js} +2 -2
  109. package/dist/cli/chunks/{chunk-YF5OP6CR.js → chunk-OV5EZO3U.js} +2 -2
  110. package/dist/cli/chunks/{chunk-JQ2ZD3WO.js → chunk-OVDKWCD7.js} +2 -2
  111. package/dist/cli/chunks/{chunk-WBH4C4BG.js → chunk-OVPJQWHW.js} +2 -2
  112. package/dist/cli/chunks/{chunk-6SZKLWZT.js → chunk-OY7MLMEX.js} +5 -5
  113. package/dist/cli/chunks/{chunk-NG2UVPTW.js → chunk-OYMLHX2B.js} +1 -1
  114. package/dist/cli/chunks/{chunk-RVCWSAXI.js → chunk-PI74GOE4.js} +2 -2
  115. package/dist/cli/chunks/{chunk-42WUDDUU.js → chunk-PZTVH2AS.js} +2 -2
  116. package/dist/cli/chunks/{chunk-4PH7O5ZH.js → chunk-QLWNXBRU.js} +2 -2
  117. package/dist/cli/chunks/{chunk-FPHPP5TQ.js → chunk-R2AFVFRF.js} +1 -1
  118. package/dist/cli/chunks/{chunk-MWQTACNA.js → chunk-RKJZWWB7.js} +2 -2
  119. package/dist/cli/chunks/{chunk-FREF6Y4L.js → chunk-ROX7NLS4.js} +2 -2
  120. package/dist/cli/chunks/{chunk-K574FLVB.js → chunk-RTJ2M6V6.js} +2 -2
  121. package/dist/cli/chunks/{chunk-NWFIJNEB.js → chunk-SG47AXJG.js} +1 -1
  122. package/dist/cli/chunks/{chunk-UHTAI4ZB.js → chunk-SGXSB7YO.js} +1 -1
  123. package/dist/cli/chunks/{chunk-PWEIDHT7.js → chunk-SHGKY3QB.js} +2 -2
  124. package/dist/cli/chunks/{chunk-MH73D5TN.js → chunk-SJPZSCZP.js} +2 -2
  125. package/dist/cli/chunks/{chunk-3WV4H33V.js → chunk-SQ3PPISY.js} +1 -1
  126. package/dist/cli/chunks/{chunk-RCI64RIJ.js → chunk-STRDSVH3.js} +2 -2
  127. package/dist/cli/chunks/{chunk-GHQ5PUOV.js → chunk-T35GZXTU.js} +2 -2
  128. package/dist/cli/chunks/{chunk-DRO5NJZA.js → chunk-T62DH4GG.js} +2 -2
  129. package/dist/cli/chunks/{chunk-W2FLULF4.js → chunk-TFHQE6NK.js} +2 -2
  130. package/dist/cli/chunks/{chunk-LML5VTFK.js → chunk-TGLAWI62.js} +1 -1
  131. package/dist/cli/chunks/{chunk-KFXZDQ5J.js → chunk-TISSZFHO.js} +1 -1
  132. package/dist/cli/chunks/{chunk-KPFG4OIM.js → chunk-TJEIOE7F.js} +1 -1
  133. package/dist/cli/chunks/{chunk-57TNBR2P.js → chunk-TTMHIOQ3.js} +2 -2
  134. package/dist/cli/chunks/{chunk-ARMZYHYL.js → chunk-UHQY3GK7.js} +2 -2
  135. package/dist/cli/chunks/{chunk-ADK7DF3G.js → chunk-UMENRGHK.js} +2 -2
  136. package/dist/cli/chunks/{chunk-ZWRQ5VAU.js → chunk-UMNYF5EZ.js} +2 -2
  137. package/dist/cli/chunks/{chunk-G6AV2HGY.js → chunk-UTVRQEZM.js} +3 -3
  138. package/dist/cli/chunks/{chunk-VOYJJ3KA.js → chunk-UYJHYMEQ.js} +2 -2
  139. package/dist/cli/chunks/{chunk-KEEBUVGV.js → chunk-V4AOVDCJ.js} +2 -2
  140. package/dist/cli/chunks/{chunk-HBTC4L53.js → chunk-VIDBBB6F.js} +2 -2
  141. package/dist/cli/chunks/{chunk-PFXX5Q32.js → chunk-VWNHKYK7.js} +2 -2
  142. package/dist/cli/chunks/{chunk-DW6ZMNMR.js → chunk-WYMGK5DX.js} +2 -2
  143. package/dist/cli/chunks/{chunk-CJCT452S.js → chunk-XA7CG3LH.js} +2 -2
  144. package/dist/cli/chunks/{chunk-QFUX7ELG.js → chunk-XX7HUSX2.js} +2 -2
  145. package/dist/cli/chunks/{chunk-WXMSRBQF.js → chunk-XXCYQXK3.js} +2 -2
  146. package/dist/cli/chunks/{chunk-6VKJAMZY.js → chunk-Y2DVFVGI.js} +1 -1
  147. package/dist/cli/chunks/{chunk-JDXLCNKV.js → chunk-Y5SQBI2F.js} +2 -2
  148. package/dist/cli/chunks/{chunk-QXTW7XCS.js → chunk-YAKS3CAB.js} +2 -2
  149. package/dist/cli/chunks/{chunk-Q3JHS3UD.js → chunk-YCBDE2N7.js} +2 -2
  150. package/dist/cli/chunks/{chunk-VNAKBHJI.js → chunk-YDNSLLBS.js} +2 -2
  151. package/dist/cli/chunks/{chunk-S7N4BKI3.js → chunk-YEXPFHV6.js} +2 -2
  152. package/dist/cli/chunks/{chunk-CG2MUD7U.js → chunk-YGB6R5DW.js} +1 -1
  153. package/dist/cli/chunks/{chunk-NNOMDM4N.js → chunk-YL7T3VV7.js} +2 -2
  154. package/dist/cli/chunks/{chunk-U54OOA24.js → chunk-ZHXWGNYM.js} +1 -1
  155. package/dist/cli/chunks/{chunk-NRR23SJV.js → chunk-ZK5JKHP4.js} +1 -1
  156. package/dist/cli/chunks/{chunk-XPLSLHRB.js → chunk-ZN3J6TZD.js} +1 -1
  157. package/dist/cli/chunks/{chunk-RHJVDCLV.js → chunk-ZUG5MOUB.js} +2 -2
  158. package/dist/cli/chunks/{ci-NTRH7PAW.js → ci-YVKDQWIX.js} +2 -2
  159. package/dist/cli/chunks/ci-output-LK3MBXLZ.js +2 -0
  160. package/dist/cli/chunks/{circuit-breaker-4WST3QSA.js → circuit-breaker-7AIXACR7.js} +2 -2
  161. package/dist/cli/chunks/{claude-flow-setup-KB4TKMYI.js → claude-flow-setup-UA7EO6VN.js} +2 -2
  162. package/dist/cli/chunks/client-M72GXFVQ.js +2 -0
  163. package/dist/cli/chunks/{cline-installer-W2ZHQ6WM.js → cline-installer-YDDCKKEV.js} +2 -2
  164. package/dist/cli/chunks/{code-TF2AVR5D.js → code-URB7UAKW.js} +2 -2
  165. package/dist/cli/chunks/{code-index-extractor-RMDRUVQJ.js → code-index-extractor-BL6HWH4Q.js} +2 -2
  166. package/dist/cli/chunks/{codex-installer-VSTRHJHV.js → codex-installer-2AVEO4EA.js} +2 -2
  167. package/dist/cli/chunks/{completions-3Q37QVFR.js → completions-RCKBSSSS.js} +2 -2
  168. package/dist/cli/chunks/{complexity-analyzer-3FNFLACD.js → complexity-analyzer-LEDG62YK.js} +2 -2
  169. package/dist/cli/chunks/{continuedev-installer-VTEXM455.js → continuedev-installer-VOTCEBFH.js} +2 -2
  170. package/dist/cli/chunks/{copilot-installer-AGY7DQUS.js → copilot-installer-NVTGLZX3.js} +2 -2
  171. package/dist/cli/chunks/core-handlers-C32RAMVI.js +2 -0
  172. package/dist/cli/chunks/{cost-tracker-LTZAQBX7.js → cost-tracker-GJIFB2BM.js} +2 -2
  173. package/dist/cli/chunks/{coverage-TT64IOS4.js → coverage-ZTPJWXWE.js} +3 -3
  174. package/dist/cli/chunks/cross-domain-router-UGFUCPKC.js +2 -0
  175. package/dist/cli/chunks/{cursor-installer-OVOJIOHN.js → cursor-installer-CMGJQMHX.js} +2 -2
  176. package/dist/cli/chunks/{daemon-DMFZMXKA.js → daemon-V456IWR3.js} +3 -3
  177. package/dist/cli/chunks/{daemon-XCULEHWY.js → daemon-Y2I3YVIU.js} +4 -4
  178. package/dist/cli/chunks/{dag-attention-scheduler-WW2RX4B5.js → dag-attention-scheduler-ZCBBOD3D.js} +2 -2
  179. package/dist/cli/chunks/{detect-QNWIM232.js → detect-2GHEA4A3.js} +2 -2
  180. package/dist/cli/chunks/{dist-node-6GQIY3CG.js → dist-node-44AGYJCH.js} +2 -2
  181. package/dist/cli/chunks/{domain-handler-6RJPDELX.js → domain-handler-IDLIEP6X.js} +2 -2
  182. package/dist/cli/chunks/{domain-transfer-WK524LBS.js → domain-transfer-KLEXGIRF.js} +2 -2
  183. package/dist/cli/chunks/dream-UFBBXY5W.js +2 -0
  184. package/dist/cli/chunks/{embed-and-insert-pattern-SO6GWJW7.js → embed-and-insert-pattern-DUW6K35A.js} +2 -2
  185. package/dist/cli/chunks/{eval-GL544IPO.js → eval-PR6YWDFM.js} +2 -2
  186. package/dist/cli/chunks/{experience-capture-middleware-BCCJ35OX.js → experience-capture-middleware-CJJJN7CF.js} +3 -3
  187. package/dist/cli/chunks/{fast-paths-CATDDBEU.js → fast-paths-LGLLKX6P.js} +2 -2
  188. package/dist/cli/chunks/{feature-flags-BUXNAORY.js → feature-flags-33D3I4DD.js} +2 -2
  189. package/dist/cli/chunks/{feature-flags-KNNWWP5G.js → feature-flags-QL4NCEGW.js} +2 -2
  190. package/dist/cli/chunks/{file-discovery-S4HF3O7D.js → file-discovery-GKCYJPFZ.js} +2 -2
  191. package/dist/cli/chunks/{fleet-DQVQQONW.js → fleet-QNT6X2YI.js} +3 -3
  192. package/dist/cli/chunks/{gnn-wrapper-G7ABZUG7.js → gnn-wrapper-ELSGT67Z.js} +2 -2
  193. package/dist/cli/chunks/{heartbeat-handler-UFMELIWT.js → heartbeat-handler-ZUI3DOOP.js} +4 -4
  194. package/dist/cli/chunks/heartbeat-scheduler-VQWHSGTY.js +2 -0
  195. package/dist/cli/chunks/hnsw-adapter-BS3NXWGU.js +2 -0
  196. package/dist/cli/chunks/hnsw-index-JP26B4HW.js +2 -0
  197. package/dist/cli/chunks/{hnsw-legacy-bridge-YIILSRXI.js → hnsw-legacy-bridge-EZMM5JWL.js} +2 -2
  198. package/dist/cli/chunks/{hnswlib-node-TSVRMXDH.js → hnswlib-node-G4CE3EOS.js} +2 -2
  199. package/dist/cli/chunks/{hooks-OHQPNK74.js → hooks-LCVXXA55.js} +10 -10
  200. package/dist/cli/chunks/{hypergraph-engine-LY7PJDSL.js → hypergraph-engine-6Z7RQ3HI.js} +2 -2
  201. package/dist/cli/chunks/{hypergraph-handler-YGDYZO6H.js → hypergraph-handler-PLI2GYPK.js} +3 -3
  202. package/dist/cli/chunks/impact-analyzer-WRE4CWPJ.js +2 -0
  203. package/dist/cli/chunks/{init-handler-MTK65LI3.js → init-handler-7VH3QJ5Y.js} +6 -6
  204. package/dist/cli/chunks/init-wizard-OFOEYB75.js +2 -0
  205. package/dist/cli/chunks/kernel-MXNFWNUD.js +2 -0
  206. package/dist/cli/chunks/{kilocode-installer-3IICU4RS.js → kilocode-installer-U3MW62DE.js} +2 -2
  207. package/dist/cli/chunks/{kiro-installer-MXOVQYQA.js → kiro-installer-PPEAC44T.js} +2 -2
  208. package/dist/cli/chunks/knowledge-graph-7JE2TVKJ.js +2 -0
  209. package/dist/cli/chunks/{learning-EV5LSOOM.js → learning-7B5NITDV.js} +3 -3
  210. package/dist/cli/chunks/{llm-router-7LYDJUOT.js → llm-router-BNEPT5OB.js} +4 -4
  211. package/dist/cli/chunks/llm-router-service-GTDVDKSU.js +2 -0
  212. package/dist/cli/chunks/{load-F4PVAMXQ.js → load-VO7ABNHV.js} +2 -2
  213. package/dist/cli/chunks/load-test-JZ4CLSBF.js +2 -0
  214. package/dist/cli/chunks/{mcp-DUYJUEME.js → mcp-THXEINCL.js} +2 -2
  215. package/dist/cli/chunks/{memory-XTTYORAS.js → memory-FZTT7ADM.js} +5 -5
  216. package/dist/cli/chunks/memory-backend-Q54CC5A5.js +2 -0
  217. package/dist/cli/chunks/memory-handlers-IIBJXKHZ.js +2 -0
  218. package/dist/cli/chunks/{multi-model-executor-R6XCTMCF.js → multi-model-executor-HEDVOZ6X.js} +2 -2
  219. package/dist/cli/chunks/{opencode-installer-33ULBU2F.js → opencode-installer-GQ7J5SBG.js} +2 -2
  220. package/dist/cli/chunks/{orchestrator-34ZJEKTJ.js → orchestrator-66JK2OS5.js} +5 -5
  221. package/dist/cli/chunks/pattern-null-store-W33O7FYO.js +2 -0
  222. package/dist/cli/chunks/{pattern-usage-recorder-GZ2M3F2E.js → pattern-usage-recorder-O6XHM2G5.js} +2 -2
  223. package/dist/cli/chunks/{pipeline-SR5OTY45.js → pipeline-UOG6UO6D.js} +2 -2
  224. package/dist/cli/chunks/{platform-VKJFJIAW.js → platform-Q7UH7FZQ.js} +2 -2
  225. package/dist/cli/chunks/{plugin-5C5UBQUQ.js → plugin-7OFLNGOS.js} +2 -2
  226. package/dist/cli/chunks/{prime-radiant-advanced-wasm-KO2PQI3D.js → prime-radiant-advanced-wasm-OSRDK2FW.js} +2 -2
  227. package/dist/cli/chunks/protocol-executor-VGN4M7XY.js +2 -0
  228. package/dist/cli/chunks/{protocol-handler-ZF74NIKA.js → protocol-handler-WLYTX6FS.js} +2 -2
  229. package/dist/cli/chunks/{prove-MO5TQQU4.js → prove-QVNE4V3J.js} +2 -2
  230. package/dist/cli/chunks/qe-reasoning-bank-7VB5LJGS.js +2 -0
  231. package/dist/cli/chunks/{quality-EYIN6AER.js → quality-DNE2RKE5.js} +2 -2
  232. package/dist/cli/chunks/{quality-gate-V6OQM57O.js → quality-gate-2K35GCSI.js} +3 -3
  233. package/dist/cli/chunks/queen-coordinator-HIDMJMMG.js +2 -0
  234. package/dist/cli/chunks/{real-embeddings-AR7TZX7U.js → real-embeddings-SF42ML7G.js} +2 -2
  235. package/dist/cli/chunks/{roocode-installer-46E626VZ.js → roocode-installer-NCEZPF5L.js} +2 -2
  236. package/dist/cli/chunks/router-CTIJS4D7.js +2 -0
  237. package/dist/cli/chunks/routing-feedback-LFYYZS5J.js +2 -0
  238. package/dist/cli/chunks/{routing-handler-ZNRVW6QW.js → routing-handler-4MXXZRYP.js} +2 -2
  239. package/dist/cli/chunks/{ruvector-commands-4L2CQMWS.js → ruvector-commands-WDFMMCMK.js} +2 -2
  240. package/dist/cli/chunks/rvf-dual-writer-MNPMIWVM.js +2 -0
  241. package/dist/cli/chunks/rvf-migration-adapter-DXOKSSNW.js +2 -0
  242. package/dist/cli/chunks/{rvf-migration-coordinator-H4RVGBIA.js → rvf-migration-coordinator-JT7ZCJY7.js} +2 -2
  243. package/dist/cli/chunks/rvf-native-adapter-PZKUKA7R.js +2 -0
  244. package/dist/cli/chunks/{rvf-store-integrity-OJGWWPLL.js → rvf-store-integrity-Q3FGYKFT.js} +2 -2
  245. package/dist/cli/chunks/safe-db-73BLFV2C.js +2 -0
  246. package/dist/cli/chunks/schedule-YVTGTTI4.js +2 -0
  247. package/dist/cli/chunks/scheduler-5DSAFIRQ.js +2 -0
  248. package/dist/cli/chunks/security-CJJ3WJSB.js +13 -0
  249. package/dist/cli/chunks/{shared-rvf-adapter-M6NNIZ5W.js → shared-rvf-adapter-6RGCTLHD.js} +2 -2
  250. package/dist/cli/chunks/{shared-rvf-dual-writer-LHMFCYVE.js → shared-rvf-dual-writer-KIA6Q6MT.js} +2 -2
  251. package/dist/cli/chunks/sqlite-persistence-LRG4IPCU.js +2 -0
  252. package/dist/cli/chunks/{status-handler-GMIOXQIE.js → status-handler-BADQV2KA.js} +2 -2
  253. package/dist/cli/chunks/{structural-health-YZXHVHM6.js → structural-health-VMYEYRZG.js} +2 -2
  254. package/dist/cli/chunks/{sync-GMPCPV5L.js → sync-PXLROLHB.js} +2 -2
  255. package/dist/cli/chunks/{sync-N56UQGCS.js → sync-ULY7T5II.js} +2 -2
  256. package/dist/cli/chunks/{task-handler-VTNRGAXP.js → task-handler-L7E2I267.js} +2 -2
  257. package/dist/cli/chunks/{task-handlers-FYSDH55N.js → task-handlers-6DPKE4AK.js} +3 -3
  258. package/dist/cli/chunks/{test-GQNCKRSP.js → test-WCLURQUT.js} +11 -11
  259. package/dist/cli/chunks/test-scheduling-4CNJA6TW.js +15 -0
  260. package/dist/cli/chunks/{token-bootstrap-76SRNXGG.js → token-bootstrap-GTI24JAL.js} +2 -2
  261. package/dist/cli/chunks/{token-usage-O7CZDP5Q.js → token-usage-DRVG6PKO.js} +2 -2
  262. package/dist/cli/chunks/{transformers-LTU4LSSC.js → transformers-IMDDAMYQ.js} +2 -2
  263. package/dist/cli/chunks/{tree-sitter-wasm-parser-NQSQCMBM.js → tree-sitter-wasm-parser-WBZIHVFA.js} +2 -2
  264. package/dist/cli/chunks/{types-OP6IWE6N.js → types-TXMY5M2K.js} +2 -2
  265. package/dist/cli/chunks/unified-memory-VBQ572X4.js +2 -0
  266. package/dist/cli/chunks/unified-memory-hnsw-J3L74ZRY.js +2 -0
  267. package/dist/cli/chunks/unified-persistence-EM2VYRTQ.js +2 -0
  268. package/dist/cli/chunks/{upgrade-OQWRBZ3R.js → upgrade-6ALSDWDD.js} +2 -2
  269. package/dist/cli/chunks/{validate-TH5SRP3E.js → validate-XF4ZG3LC.js} +2 -2
  270. package/dist/cli/chunks/{validate-swarm-UITL2JUS.js → validate-swarm-P5TAFRDA.js} +2 -2
  271. package/dist/cli/chunks/{vibium-O6PRAG4J.js → vibium-2XDXKNKZ.js} +2 -2
  272. package/dist/cli/chunks/visual-security-GX4S7K6O.js +2 -0
  273. package/dist/cli/chunks/{web-tree-sitter-XBFBY4OF.js → web-tree-sitter-4JVRQPX5.js} +2 -2
  274. package/dist/cli/chunks/{windsurf-installer-DVT5NRNY.js → windsurf-installer-WYJXVDO5.js} +2 -2
  275. package/dist/cli/chunks/witness-chain-QGKMHCNW.js +2 -0
  276. package/dist/cli/chunks/{witness-chain-VRSH2F36.js → witness-chain-RPZ2SE2V.js} +2 -2
  277. package/dist/cli/chunks/{witness-key-manager-GFHRDKQ4.js → witness-key-manager-LXG2VBQQ.js} +2 -2
  278. package/dist/cli/chunks/{workflow-HAZ6YKOG.js → workflow-2OYNO7UU.js} +4 -4
  279. package/dist/cli/chunks/workflow-orchestrator-KWHIJMFV.js +2 -0
  280. package/dist/cli/chunks/{wrappers-5LLLT7GM.js → wrappers-DIJNNFU6.js} +2 -2
  281. package/dist/cli/commands/security.js +167 -100
  282. package/dist/cli/commands/test.js +1 -0
  283. package/dist/cli/utils/ci-output.d.ts +17 -0
  284. package/dist/cli/utils/ci-output.js +34 -2
  285. package/dist/coordination/handlers/handler-types.d.ts +3 -0
  286. package/dist/coordination/handlers/quality-handlers.js +10 -0
  287. package/dist/coordination/handlers/security-handlers.js +168 -72
  288. package/dist/coordination/handlers/test-execution-handlers.js +37 -43
  289. package/dist/coordination/protocols/security-audit.d.ts +3 -0
  290. package/dist/coordination/protocols/security-audit.js +61 -39
  291. package/dist/coordination/result-saver.js +36 -5
  292. package/dist/coordination/task-executor.d.ts +3 -1
  293. package/dist/coordination/task-executor.js +4 -0
  294. package/dist/domains/security-compliance/interfaces.d.ts +5 -0
  295. package/dist/domains/security-compliance/interfaces.js +0 -6
  296. package/dist/domains/security-compliance/scan-discovery.d.ts +12 -0
  297. package/dist/domains/security-compliance/scan-discovery.js +105 -0
  298. package/dist/domains/security-compliance/scan-evidence.d.ts +57 -0
  299. package/dist/domains/security-compliance/scan-evidence.js +2 -0
  300. package/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts +3 -2
  301. package/dist/domains/security-compliance/services/scanners/sast-scanner.js +109 -65
  302. package/dist/domains/security-compliance/services/semgrep-integration.d.ts +9 -2
  303. package/dist/domains/security-compliance/services/semgrep-integration.js +68 -20
  304. package/dist/domains/test-execution/services/flaky-detector.js +14 -3
  305. package/dist/domains/test-execution/services/retry-handler.js +18 -8
  306. package/dist/domains/test-execution/services/test-executor.js +46 -12
  307. package/dist/init/init-wizard-hooks.js +2 -2
  308. package/dist/integrations/agentic-flow/reasoning-bank/index.js +3 -20
  309. package/dist/integrations/coherence/engines/cohomology-adapter.js +100 -30
  310. package/dist/mcp/bundle.js +499 -478
  311. package/dist/mcp/handlers/domain-handler-configs.d.ts +22 -1
  312. package/dist/mcp/handlers/domain-handler-configs.js +50 -19
  313. package/dist/mcp/handlers/domain-handlers.d.ts +7 -5
  314. package/dist/mcp/handlers/domain-handlers.js +7 -5
  315. package/dist/mcp/protocol-server.js +9 -5
  316. package/dist/mcp/types.d.ts +5 -0
  317. package/dist/shared/llm/router/hybrid-router.d.ts +4 -0
  318. package/dist/shared/llm/router/hybrid-router.js +74 -26
  319. package/dist/shared/llm/router/types.d.ts +9 -2
  320. package/dist/shared/test-runner-verdict.d.ts +29 -0
  321. package/dist/shared/test-runner-verdict.js +43 -0
  322. package/dist/shared/vitest-json-report.d.ts +45 -0
  323. package/dist/shared/vitest-json-report.js +71 -0
  324. package/dist/test-scheduling/executors/vitest-executor.js +18 -6
  325. package/dist/validation/frontier-judge.d.ts +7 -4
  326. package/dist/validation/frontier-judge.js +11 -6
  327. package/package.json +6 -6
  328. package/dist/cli/chunks/adapter-OJF6LAJV.js +0 -2
  329. package/dist/cli/chunks/aqe-learning-engine-FGT474XB.js +0 -2
  330. package/dist/cli/chunks/base-HH765JFV.js +0 -2
  331. package/dist/cli/chunks/browser-workflow-NPM4FUPI.js +0 -2
  332. package/dist/cli/chunks/chunk-OC2CKU7I.js +0 -2
  333. package/dist/cli/chunks/chunk-PHHXHG2W.js +0 -2
  334. package/dist/cli/chunks/chunk-U2AY57XZ.js +0 -5
  335. package/dist/cli/chunks/chunk-WBMRADQP.js +0 -81
  336. package/dist/cli/chunks/ci-output-F57RSD35.js +0 -2
  337. package/dist/cli/chunks/client-GPZEC54E.js +0 -2
  338. package/dist/cli/chunks/core-handlers-YMGHYIBR.js +0 -2
  339. package/dist/cli/chunks/cross-domain-router-ECBNTGYJ.js +0 -2
  340. package/dist/cli/chunks/dream-EHGKCFWH.js +0 -2
  341. package/dist/cli/chunks/heartbeat-scheduler-UFEL2CBW.js +0 -2
  342. package/dist/cli/chunks/hnsw-adapter-BLSD45CX.js +0 -2
  343. package/dist/cli/chunks/hnsw-index-A3RZODEN.js +0 -2
  344. package/dist/cli/chunks/impact-analyzer-OXHD3FOH.js +0 -2
  345. package/dist/cli/chunks/init-wizard-PKZL7QBU.js +0 -2
  346. package/dist/cli/chunks/kernel-XWPM72UJ.js +0 -2
  347. package/dist/cli/chunks/knowledge-graph-FRKR5XWI.js +0 -2
  348. package/dist/cli/chunks/llm-router-service-R7A5HHDM.js +0 -2
  349. package/dist/cli/chunks/load-test-5IKDWSYL.js +0 -2
  350. package/dist/cli/chunks/memory-backend-7VW5QCMO.js +0 -2
  351. package/dist/cli/chunks/memory-handlers-VZH3R2TQ.js +0 -2
  352. package/dist/cli/chunks/pattern-null-store-BU6LCB2W.js +0 -2
  353. package/dist/cli/chunks/protocol-executor-BSP5LWJN.js +0 -2
  354. package/dist/cli/chunks/qe-reasoning-bank-J2RC7P25.js +0 -2
  355. package/dist/cli/chunks/queen-coordinator-XI5AJV2V.js +0 -2
  356. package/dist/cli/chunks/router-VXQYYA3D.js +0 -2
  357. package/dist/cli/chunks/routing-feedback-HZQTASFF.js +0 -2
  358. package/dist/cli/chunks/rvf-dual-writer-BDTLLJER.js +0 -2
  359. package/dist/cli/chunks/rvf-migration-adapter-IB343MDN.js +0 -2
  360. package/dist/cli/chunks/rvf-native-adapter-Y7SN7LHU.js +0 -2
  361. package/dist/cli/chunks/safe-db-2VTKKBJU.js +0 -2
  362. package/dist/cli/chunks/schedule-QJ4CFGJY.js +0 -2
  363. package/dist/cli/chunks/scheduler-2NHDQPC3.js +0 -2
  364. package/dist/cli/chunks/security-JF3BVNRO.js +0 -14
  365. package/dist/cli/chunks/sqlite-persistence-NVVAPZN3.js +0 -2
  366. package/dist/cli/chunks/test-scheduling-GPRXSIRP.js +0 -15
  367. package/dist/cli/chunks/unified-memory-DSTIEDSH.js +0 -2
  368. package/dist/cli/chunks/unified-memory-hnsw-KBV3P4OS.js +0 -2
  369. package/dist/cli/chunks/unified-persistence-XKCOUBKY.js +0 -2
  370. package/dist/cli/chunks/visual-security-TTWSPZTZ.js +0 -2
  371. package/dist/cli/chunks/witness-chain-2KY73HPN.js +0 -2
  372. package/dist/cli/chunks/workflow-orchestrator-UK56AVOT.js +0 -2
@@ -2,6 +2,9 @@
2
2
  * Agentic QE v3 - SAST (Static Application Security Testing) Scanner
3
3
  * Performs static code analysis to detect security vulnerabilities
4
4
  */
5
+ import { createHash } from 'node:crypto';
6
+ import * as path from 'node:path';
7
+ import { FilePath } from '../../../../shared/value-objects/index.js';
5
8
  import { LoggerFactory } from '../../../../logging/index.js';
6
9
  import { v4 as uuidv4 } from 'uuid';
7
10
  import { ok, err } from '../../../../shared/types/index.js';
@@ -48,30 +51,61 @@ export class SASTScanner {
48
51
  if (files.length === 0) {
49
52
  return err(new Error('No files provided for scanning'));
50
53
  }
51
- this.activeScans.set(scanId, 'running');
52
54
  const startTime = Date.now();
53
55
  // Get applicable rule sets
54
56
  const ruleSets = BUILT_IN_RULE_SETS.filter((rs) => ruleSetIds.includes(rs.id));
55
57
  if (ruleSets.length === 0) {
56
58
  return err(new Error(`No valid rule sets found: ${ruleSetIds.join(', ')}`));
57
59
  }
58
- // Run pattern-based scanning and semgrep in parallel
59
- const [patternResult, semgrepVulns] = await Promise.all([
60
- this.runPatternScanning(files, ruleSets),
61
- this.runSemgrepScanning(files, ruleSetIds),
60
+ const unknownRuleSets = ruleSetIds.filter(id => !BUILT_IN_RULE_SETS.some(ruleSet => ruleSet.id === id));
61
+ if (unknownRuleSets.length > 0) {
62
+ return err(new Error('Unknown rule sets requested; no scan executed.'));
63
+ }
64
+ this.activeScans.set(scanId, 'running');
65
+ // Deduplicate lexical absolute paths; do not follow symlinks to invent identity.
66
+ const requestedPaths = [...new Set(files.map(file => path.resolve(file.value)))];
67
+ const uniqueFiles = requestedPaths.map(value => FilePath.create(value));
68
+ // Run independent engines while retaining each engine's execution outcome.
69
+ const [patternResult, semgrepResult] = await Promise.all([
70
+ this.runPatternScanning(uniqueFiles, ruleSets),
71
+ this.runSemgrepScanning(uniqueFiles, ruleSetIds),
62
72
  ]);
63
73
  // Merge pattern-based and semgrep findings, deduplicating by file+line
64
- const vulnerabilities = this.mergeVulnerabilities(patternResult.vulnerabilities, semgrepVulns);
65
- const linesScanned = patternResult.linesScanned;
74
+ const vulnerabilities = this.mergeVulnerabilities(patternResult.vulnerabilities, semgrepResult.vulnerabilities);
75
+ const analyzedFiles = patternResult.files.filter(file => file.status === 'analyzed');
76
+ const linesScanned = analyzedFiles.reduce((total, file) => total + file.analyzedLines, 0);
66
77
  const scanDurationMs = Date.now() - startTime;
67
78
  // Calculate summary
68
- const summary = this.calculateSummary(vulnerabilities, files.length, scanDurationMs);
69
- // Calculate coverage — include semgrep rules when they ran
70
- const patternRules = ruleSets.reduce((acc, rs) => acc + rs.ruleCount, 0);
79
+ const summary = this.calculateSummary(vulnerabilities, analyzedFiles.length, scanDurationMs);
80
+ const patterns = this.getApplicablePatterns(ruleSets);
81
+ const ruleIds = analyzedFiles.length > 0 ? [...new Set(patterns.map(pattern => pattern.id))] : [];
71
82
  const coverage = {
72
- filesScanned: files.length,
83
+ filesScanned: analyzedFiles.length,
73
84
  linesScanned,
74
- rulesApplied: patternRules + (semgrepVulns.length > 0 ? semgrepVulns.length : 0),
85
+ rulesApplied: ruleIds.length,
86
+ rulesAppliedScope: 'built-in-patterns',
87
+ };
88
+ const patternEngine = {
89
+ id: 'patterns', requested: true, required: true, scope: 'requested-files',
90
+ status: analyzedFiles.length === uniqueFiles.length ? 'completed' : analyzedFiles.length > 0 ? 'partial' : 'failed',
91
+ analyzedFiles: analyzedFiles.length,
92
+ ruleIds,
93
+ rulesetDigest: createHash('sha256').update(JSON.stringify(patterns.map(pattern => ({
94
+ id: pattern.id, category: pattern.category, expression: pattern.pattern.source, flags: pattern.pattern.flags,
95
+ })))).digest('hex'),
96
+ ruleCoverage: 'known',
97
+ errors: patternResult.files.filter(file => file.status === 'unreadable').map(file => file.reason || 'File unreadable'),
98
+ limitations: ['Built-in pattern matching covers supported JavaScript and TypeScript inputs only.'],
99
+ };
100
+ const evidence = {
101
+ schemaVersion: 1,
102
+ completeness: analyzedFiles.length === uniqueFiles.length ? 'complete' : analyzedFiles.length > 0 ? 'partial' : 'none',
103
+ requestedFiles: uniqueFiles.length,
104
+ requestedPaths,
105
+ duplicateInputs: files.length - uniqueFiles.length,
106
+ files: patternResult.files,
107
+ engines: [patternEngine, semgrepResult.evidence],
108
+ limitations: [...patternEngine.limitations, ...semgrepResult.evidence.limitations],
75
109
  };
76
110
  // Store scan results in memory
77
111
  await this.storeScanResults(scanId, 'sast', vulnerabilities, summary);
@@ -81,6 +115,7 @@ export class SASTScanner {
81
115
  vulnerabilities,
82
116
  summary,
83
117
  coverage,
118
+ evidence,
84
119
  });
85
120
  }
86
121
  catch (error) {
@@ -93,36 +128,48 @@ export class SASTScanner {
93
128
  */
94
129
  async runPatternScanning(files, ruleSets) {
95
130
  const vulnerabilities = [];
96
- let linesScanned = 0;
131
+ const receipts = [];
97
132
  for (const file of files) {
98
- const fileVulns = await this.analyzeFile(file, ruleSets);
99
- vulnerabilities.push(...fileVulns.vulnerabilities);
100
- linesScanned += fileVulns.linesScanned;
133
+ const result = await this.analyzeFile(file, ruleSets);
134
+ vulnerabilities.push(...result.vulnerabilities);
135
+ receipts.push(result.evidence);
101
136
  }
102
- return { vulnerabilities, linesScanned };
137
+ return { vulnerabilities, files: receipts };
103
138
  }
104
139
  /**
105
140
  * Run semgrep scanning when enabled and available.
106
- * Returns converted vulnerabilities or empty array on failure/unavailability.
141
+ * Optional engine failure preserves completed pattern analysis and its findings.
107
142
  */
108
143
  async runSemgrepScanning(files, ruleSetIds) {
144
+ const targetDir = this.resolveTargetDirectory(files);
145
+ const base = {
146
+ id: 'semgrep', requested: !!this.config.enableSemgrep, required: false,
147
+ status: 'disabled', scope: 'parent-directory', target: targetDir,
148
+ ruleCoverage: 'unknown', errors: [], limitations: [],
149
+ };
109
150
  if (!this.config.enableSemgrep) {
110
- return [];
151
+ return { vulnerabilities: [], evidence: base };
111
152
  }
153
+ const limitations = [
154
+ 'Optional Semgrep scans a parent directory; requested-file membership and executed-rule coverage are unverified.',
155
+ ];
112
156
  try {
113
- const available = await isSemgrepAvailable();
114
- if (!available) {
115
- return [];
157
+ if (!await isSemgrepAvailable()) {
158
+ return { vulnerabilities: [], evidence: { ...base, status: 'unavailable', limitations,
159
+ errors: ['Semgrep is unavailable.'] } };
116
160
  }
117
- // Determine target directory from files (use common parent)
118
- const targetDir = this.resolveTargetDirectory(files);
119
161
  const semgrepResult = await runSemgrepWithRules(targetDir, ruleSetIds);
120
- if (!semgrepResult.success || semgrepResult.findings.length === 0) {
121
- return [];
122
- }
162
+ const evidence = {
163
+ ...base,
164
+ status: semgrepResult.status || 'unverified',
165
+ version: semgrepResult.version,
166
+ errors: semgrepResult.errors.length > 0 ? [`Semgrep reported ${semgrepResult.errors.length} execution error(s).`] : [],
167
+ limitations: [...limitations, ...(semgrepResult.diagnostics ?? []),
168
+ ...(!semgrepResult.status ? ['Legacy Semgrep adapter returned no execution disposition.'] : [])],
169
+ };
123
170
  // Convert semgrep findings to our Vulnerability format
124
171
  const converted = convertSemgrepFindings(semgrepResult.findings);
125
- return converted.map(f => ({
172
+ const vulnerabilities = converted.map(f => ({
126
173
  id: uuidv4(),
127
174
  cveId: undefined,
128
175
  title: f.title,
@@ -142,10 +189,11 @@ export class SASTScanner {
142
189
  },
143
190
  references: f.references,
144
191
  }));
192
+ return { vulnerabilities, evidence };
145
193
  }
146
194
  catch {
147
- // Semgrep failure is non-fatal — pattern scanning still covers us
148
- return [];
195
+ return { vulnerabilities: [], evidence: { ...base, status: 'failed', limitations,
196
+ errors: ['Semgrep execution failed.'] } };
149
197
  }
150
198
  }
151
199
  /**
@@ -153,25 +201,18 @@ export class SASTScanner {
153
201
  */
154
202
  resolveTargetDirectory(files) {
155
203
  if (files.length === 0)
156
- return '.';
157
- if (files.length === 1)
158
- return files[0].directory || '.';
159
- // Find common prefix of all directories
160
- const dirs = files.map(f => f.directory || '.');
161
- const first = dirs[0];
162
- let commonLen = first.length;
163
- for (let i = 1; i < dirs.length; i++) {
164
- const dir = dirs[i];
165
- const maxLen = Math.min(commonLen, dir.length);
166
- let j = 0;
167
- while (j < maxLen && first[j] === dir[j])
168
- j++;
169
- commonLen = j;
204
+ return process.cwd();
205
+ let common = path.dirname(path.resolve(files[0].value));
206
+ for (const file of files.slice(1)) {
207
+ const directory = path.dirname(path.resolve(file.value));
208
+ while (directory !== common && !directory.startsWith(common.endsWith(path.sep) ? common : common + path.sep)) {
209
+ const parent = path.dirname(common);
210
+ if (parent === common)
211
+ break;
212
+ common = parent;
213
+ }
170
214
  }
171
- const common = first.substring(0, commonLen);
172
- // Trim to last path separator
173
- const lastSep = common.lastIndexOf('/');
174
- return lastSep > 0 ? common.substring(0, lastSep) : common || '.';
215
+ return common;
175
216
  }
176
217
  /**
177
218
  * Map semgrep OWASP category string to VulnerabilityCategory
@@ -250,32 +291,35 @@ export class SASTScanner {
250
291
  /**
251
292
  * Analyze a file for security vulnerabilities using pattern-based detection
252
293
  */
294
+ getApplicablePatterns(ruleSets) {
295
+ const categories = new Set(ruleSets.flatMap(ruleSet => ruleSet.categories));
296
+ return ALL_SECURITY_PATTERNS.filter(pattern => categories.has(pattern.category));
297
+ }
253
298
  async analyzeFile(file, ruleSets) {
254
299
  const vulnerabilities = [];
255
300
  const filePath = file.value;
256
- const extension = file.extension;
257
- // Read file content
301
+ const receipt = { path: filePath, engineId: 'patterns', readLines: 0, analyzedLines: 0 };
258
302
  let content;
259
- let lines;
303
+ let sourceDigest;
260
304
  try {
261
305
  const fs = await import('fs/promises');
262
- content = await fs.readFile(filePath, 'utf-8');
263
- lines = content.split('\n');
306
+ const bytes = await fs.readFile(filePath);
307
+ sourceDigest = createHash('sha256').update(bytes).digest('hex');
308
+ content = bytes.toString('utf8');
264
309
  }
265
- catch {
266
- // File not accessible - return empty results
267
- return { vulnerabilities: [], linesScanned: 0 };
310
+ catch (error) {
311
+ const code = error.code;
312
+ return { vulnerabilities: [], evidence: { ...receipt, status: 'unreadable',
313
+ reason: typeof code === 'string' && /^[A-Z0-9_]{1,32}$/.test(code) ? code : 'File unreadable' } };
268
314
  }
269
- const linesScanned = lines.length;
270
- // Only scan supported file types
315
+ const lines = content.split('\n');
316
+ const readReceipt = { ...receipt, sourceDigest, readLines: lines.length };
271
317
  const supportedExtensions = ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'];
272
- if (!supportedExtensions.includes(extension)) {
273
- return { vulnerabilities: [], linesScanned };
318
+ if (!supportedExtensions.includes(file.extension)) {
319
+ return { vulnerabilities: [], evidence: { ...readReceipt, status: 'unsupported',
320
+ reason: 'Unsupported language for built-in SAST patterns' } };
274
321
  }
275
- // Get applicable categories from rule sets
276
- const applicableCategories = new Set(ruleSets.flatMap((rs) => rs.categories));
277
- // Filter patterns to only those matching applicable categories
278
- const applicablePatterns = ALL_SECURITY_PATTERNS.filter((pattern) => applicableCategories.has(pattern.category));
322
+ const applicablePatterns = this.getApplicablePatterns(ruleSets);
279
323
  // Scan content for each pattern
280
324
  for (const securityPattern of applicablePatterns) {
281
325
  const matches = this.findPatternMatches(content, lines, securityPattern);
@@ -291,7 +335,7 @@ export class SASTScanner {
291
335
  vulnerabilities.push(this.createVulnerabilityFromPattern(securityPattern, filePath, match));
292
336
  }
293
337
  }
294
- return { vulnerabilities, linesScanned };
338
+ return { vulnerabilities, evidence: { ...readReceipt, status: 'analyzed', analyzedLines: lines.length } };
295
339
  }
296
340
  /**
297
341
  * Find all matches of a security pattern in the file content
@@ -9,6 +9,8 @@
9
9
  *
10
10
  * @module security-compliance/semgrep-integration
11
11
  */
12
+ declare const SEMGREP_SEVERITIES: readonly ["ERROR", "WARNING", "INFO", "CRITICAL", "HIGH", "MEDIUM", "LOW", "EXPERIMENT", "INVENTORY"];
13
+ export type SemgrepSeverity = typeof SEMGREP_SEVERITIES[number];
12
14
  export interface SemgrepFinding {
13
15
  check_id: string;
14
16
  path: string;
@@ -22,7 +24,7 @@ export interface SemgrepFinding {
22
24
  };
23
25
  extra: {
24
26
  message: string;
25
- severity: 'ERROR' | 'WARNING' | 'INFO';
27
+ severity: SemgrepSeverity;
26
28
  lines: string;
27
29
  metadata?: {
28
30
  cwe?: string[];
@@ -37,8 +39,12 @@ export interface SemgrepFinding {
37
39
  }
38
40
  export interface SemgrepResult {
39
41
  success: boolean;
42
+ /** Optional only for compatibility with legacy adapters. */
43
+ status?: 'completed' | 'partial' | 'failed' | 'unavailable';
40
44
  findings: SemgrepFinding[];
41
45
  errors: string[];
46
+ /** Sanitized non-fatal diagnostics, separate from analysis failures. */
47
+ diagnostics?: string[];
42
48
  version?: string;
43
49
  }
44
50
  export interface SemgrepConfig {
@@ -74,7 +80,7 @@ export declare function runSemgrepWithRules(target: string, rules: string[], opt
74
80
  /**
75
81
  * Map semgrep severity to standard severity
76
82
  */
77
- export declare function mapSemgrepSeverity(severity: 'ERROR' | 'WARNING' | 'INFO'): 'critical' | 'high' | 'medium' | 'low';
83
+ export declare function mapSemgrepSeverity(severity: SemgrepSeverity): 'critical' | 'high' | 'medium' | 'low';
78
84
  /**
79
85
  * Convert semgrep findings to a generic format
80
86
  */
@@ -92,4 +98,5 @@ export declare function convertSemgrepFindings(findings: SemgrepFinding[]): Arra
92
98
  remediation: string;
93
99
  references: string[];
94
100
  }>;
101
+ export {};
95
102
  //# sourceMappingURL=semgrep-integration.d.ts.map
@@ -12,10 +12,15 @@
12
12
  import { execFile } from 'child_process';
13
13
  import { promisify } from 'util';
14
14
  import * as path from 'path';
15
- import { toErrorMessage } from '../../../shared/error-utils.js';
16
15
  import { safeJsonParse } from '../../../shared/safe-json.js';
17
16
  const execFileAsync = promisify(execFile);
18
17
  // ============================================================================
18
+ // Types
19
+ // ============================================================================
20
+ // Semgrep's match_severity schema retains legacy/deprecated values as well as
21
+ // CRITICAL/HIGH/MEDIUM/LOW introduced in 1.72.0.
22
+ const SEMGREP_SEVERITIES = ['ERROR', 'WARNING', 'INFO', 'CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'EXPERIMENT', 'INVENTORY'];
23
+ // ============================================================================
19
24
  // Semgrep Integration
20
25
  // ============================================================================
21
26
  /**
@@ -59,8 +64,9 @@ export async function runSemgrep(config) {
59
64
  if (!available) {
60
65
  return {
61
66
  success: false,
67
+ status: 'unavailable',
62
68
  findings: [],
63
- errors: ['Semgrep is not installed. Install with: pip install semgrep'],
69
+ errors: ['Semgrep is unavailable.'],
64
70
  };
65
71
  }
66
72
  try {
@@ -87,28 +93,26 @@ export async function runSemgrep(config) {
87
93
  });
88
94
  const result = parseSemgrepOutput(stdout);
89
95
  if (stderr && fullConfig.verbose) {
90
- result.errors.push(stderr);
96
+ result.diagnostics = ['Semgrep emitted diagnostic output.'];
91
97
  }
92
98
  result.version = await getSemgrepVersion() || undefined;
93
99
  return result;
94
100
  }
95
101
  catch (error) {
96
- // Semgrep exits with non-zero if findings exist
97
102
  const execError = error;
98
- if (execError.stdout) {
99
- try {
100
- const result = parseSemgrepOutput(execError.stdout);
101
- result.version = await getSemgrepVersion() || undefined;
103
+ if (typeof execError.stdout === 'string' && execError.stdout.length > 0) {
104
+ const result = parseSemgrepOutput(execError.stdout);
105
+ // Exit 1 can represent findings with --error. Other process failures cannot
106
+ // be converted into success just because stdout contains valid JSON.
107
+ if (execError.code === 1 && !execError.killed && !execError.signal && result.success && result.findings.length > 0) {
102
108
  return result;
103
109
  }
104
- catch {
105
- // Parse failed, return error
106
- }
110
+ return { ...result, success: false, status: 'failed',
111
+ errors: [...result.errors, 'Semgrep process did not complete successfully.'] };
107
112
  }
108
113
  return {
109
- success: false,
110
- findings: [],
111
- errors: [execError.message ?? String(error)],
114
+ success: false, status: 'failed', findings: [],
115
+ errors: ['Semgrep execution failed.'],
112
116
  };
113
117
  }
114
118
  }
@@ -118,11 +122,47 @@ export async function runSemgrep(config) {
118
122
  function parseSemgrepOutput(stdout) {
119
123
  try {
120
124
  const parsed = safeJsonParse(stdout);
121
- // Handle different output formats
122
- const results = parsed.results || parsed.findings || [];
123
- const errors = parsed.errors?.map(e => e.message || String(e)) || [];
125
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
126
+ throw new Error('Expected a JSON object');
127
+ }
128
+ const rawResults = parsed.results ?? parsed.findings;
129
+ if (!Array.isArray(rawResults) || (parsed.errors !== undefined && !Array.isArray(parsed.errors))) {
130
+ throw new Error('Missing or invalid result collection');
131
+ }
132
+ const isRecord = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
133
+ const optionalText = (value) => value === undefined || typeof value === 'string';
134
+ const validSeverity = (value) => value === undefined
135
+ || (typeof value === 'string' && SEMGREP_SEVERITIES.includes(value));
136
+ const validPosition = (value) => value === undefined || (isRecord(value)
137
+ && ['line', 'col'].every(key => value[key] === undefined
138
+ || (typeof value[key] === 'number' && Number.isSafeInteger(value[key]) && value[key] > 0)));
139
+ const validMetadata = (value) => value === undefined || (isRecord(value)
140
+ && ['cwe', 'owasp', 'references'].every(key => value[key] === undefined
141
+ || (Array.isArray(value[key]) && value[key].every(item => typeof item === 'string')))
142
+ && ['category', 'description', 'fix', 'confidence'].every(key => optionalText(value[key])));
143
+ const validFinding = (value) => {
144
+ if (!isRecord(value))
145
+ return false;
146
+ const id = value.check_id ?? value.rule_id;
147
+ if (typeof value.path !== 'string' || value.path.length === 0 || typeof id !== 'string' || id.length === 0
148
+ || !validPosition(value.start) || !validPosition(value.end)
149
+ || !optionalText(value.message) || !validSeverity(value.severity) || !validMetadata(value.metadata))
150
+ return false;
151
+ const extra = value.extra;
152
+ return extra === undefined || (isRecord(extra)
153
+ && ['message', 'lines', 'fix'].every(key => optionalText(extra[key]))
154
+ && validSeverity(extra.severity) && validMetadata(extra.metadata));
155
+ };
156
+ const results = rawResults.filter(validFinding);
157
+ const malformed = rawResults.length - results.length;
158
+ const errors = [];
159
+ if (parsed.errors?.length)
160
+ errors.push(`Semgrep reported ${parsed.errors.length} analysis error(s).`);
161
+ if (malformed)
162
+ errors.push(`Semgrep returned ${malformed} malformed finding(s).`);
124
163
  return {
125
- success: true,
164
+ success: errors.length === 0,
165
+ status: errors.length === 0 ? 'completed' : 'partial',
126
166
  findings: results.map(r => ({
127
167
  check_id: r.check_id || r.rule_id || 'unknown',
128
168
  path: r.path,
@@ -146,11 +186,12 @@ function parseSemgrepOutput(stdout) {
146
186
  errors,
147
187
  };
148
188
  }
149
- catch (error) {
189
+ catch {
150
190
  return {
151
191
  success: false,
192
+ status: 'failed',
152
193
  findings: [],
153
- errors: [`Failed to parse semgrep output: ${toErrorMessage(error)}`],
194
+ errors: ['Invalid Semgrep output.'],
154
195
  };
155
196
  }
156
197
  }
@@ -191,6 +232,13 @@ export function mapSemgrepSeverity(severity) {
191
232
  ERROR: 'high',
192
233
  WARNING: 'medium',
193
234
  INFO: 'low',
235
+ CRITICAL: 'critical',
236
+ HIGH: 'high',
237
+ MEDIUM: 'medium',
238
+ LOW: 'low',
239
+ // Retain the existing non-risky INFO mapping for deprecated categories.
240
+ EXPERIMENT: 'low',
241
+ INVENTORY: 'low',
194
242
  };
195
243
  return mapping[severity] || 'medium';
196
244
  }
@@ -11,6 +11,7 @@ import { ok, err } from '../../../shared/types/index.js';
11
11
  import { TEST_EXECUTION_CONSTANTS, RETRY_CONSTANTS } from '../../constants.js';
12
12
  import { toError } from '../../../shared/error-utils.js';
13
13
  import { safeJsonParse } from '../../../shared/safe-json.js';
14
+ import { createVitestJsonReport, needsVitestJsonReportFile } from '../../../shared/vitest-json-report.js';
14
15
  import { secureRandom } from '../../../shared/utils/crypto-random.js';
15
16
  const DEFAULT_FLAKY_CONFIG = {
16
17
  simulateForTesting: false,
@@ -254,7 +255,13 @@ export class FlakyDetectorService {
254
255
  const runId = uuidv4();
255
256
  const startTime = Date.now();
256
257
  return new Promise((resolve, reject) => {
257
- const args = [...this.config.testRunnerArgs, file];
258
+ const baseArgs = [...this.config.testRunnerArgs, file];
259
+ // Vitest 5 writes --reporter=json output to a file, not stdout. Detect
260
+ // Vitest from the runner command too (testRunner: 'vitest', args: ['run', ...]).
261
+ const report = needsVitestJsonReportFile([this.config.testRunner, ...baseArgs])
262
+ ? createVitestJsonReport()
263
+ : undefined;
264
+ const args = report ? [...baseArgs, ...report.args] : baseArgs;
258
265
  const cwd = this.config.cwd ?? process.cwd();
259
266
  const child = spawn(this.config.testRunner, args, {
260
267
  cwd,
@@ -272,19 +279,23 @@ export class FlakyDetectorService {
272
279
  // Set timeout
273
280
  const timeout = setTimeout(() => {
274
281
  child.kill('SIGTERM');
282
+ report?.cleanup();
275
283
  reject(new Error(`Test execution timed out after ${this.config.runTimeout}ms for ${file}`));
276
284
  }, this.config.runTimeout);
277
285
  child.on('error', (error) => {
278
286
  clearTimeout(timeout);
287
+ report?.cleanup();
279
288
  reject(new Error(`Failed to execute test runner: ${error.message}. ` +
280
289
  `Ensure ${this.config.testRunner} is installed and accessible.`));
281
290
  });
282
291
  child.on('close', (code) => {
283
292
  clearTimeout(timeout);
284
293
  const duration = Date.now() - startTime;
294
+ const reportText = report ? report.read(stdout) : stdout;
295
+ report?.cleanup();
285
296
  try {
286
- // Parse the test results from stdout
287
- const parsedResults = this.parseTestOutput(stdout, stderr, code ?? 0, file, runId, runIndex, duration);
297
+ // Parse the test results from the JSON report (or stdout for other runners)
298
+ const parsedResults = this.parseTestOutput(reportText, stderr, code ?? 0, file, runId, runIndex, duration);
288
299
  // If parsing fails but we have an exit code, create a single result for the file
289
300
  if (parsedResults.size === 0) {
290
301
  const testId = this.generateTestId(file, 'main');
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { LoggerFactory } from '../../../logging/index.js';
6
6
  import { spawn } from 'node:child_process';
7
+ import { createVitestJsonReport } from '../../../shared/vitest-json-report.js';
7
8
  import { existsSync, readFileSync } from 'node:fs';
8
9
  import { ok, err } from '../../../shared/types/index.js';
9
10
  import { TEST_EXECUTION_CONSTANTS, RETRY_CONSTANTS } from '../../constants.js';
@@ -262,9 +263,9 @@ export class RetryHandlerService {
262
263
  `or configure testRunner in RetryHandlerConfig. Cannot execute retry for: ${testFile}`);
263
264
  }
264
265
  // Build command based on runner
265
- const { command, args } = this.buildTestCommand(runner, testFile, testName);
266
+ const { command, args, report } = this.buildTestCommand(runner, testFile, testName);
266
267
  // Execute the test
267
- return this.spawnTestProcess(command, args, cwd);
268
+ return this.spawnTestProcess(command, args, cwd, report);
268
269
  }
269
270
  /**
270
271
  * Detect which test runner is available in the project
@@ -337,12 +338,15 @@ export class RetryHandlerService {
337
338
  switch (runner) {
338
339
  case 'vitest':
339
340
  // vitest run --reporter=json testFile -t "testName"
341
+ // --outputFile: Vitest 5 no longer prints the JSON report to stdout.
340
342
  {
343
+ const report = createVitestJsonReport();
341
344
  const vitestArgs = ['vitest', 'run', '--reporter=json', testFile];
342
345
  if (testName && testName !== testFile) {
343
346
  vitestArgs.push('-t', testName);
344
347
  }
345
- return { command: npx, args: vitestArgs };
348
+ vitestArgs.push(...report.args);
349
+ return { command: npx, args: vitestArgs, report };
346
350
  }
347
351
  case 'jest':
348
352
  // jest --json testFile -t "testName"
@@ -369,12 +373,16 @@ export class RetryHandlerService {
369
373
  /**
370
374
  * Spawn a test process and parse the result
371
375
  */
372
- spawnTestProcess(command, args, cwd) {
376
+ spawnTestProcess(command, args, cwd, report) {
373
377
  return new Promise((resolve, reject) => {
374
378
  const timeout = this.config.testTimeout;
375
379
  let stdout = '';
376
380
  let stderr = '';
377
381
  let timedOut = false;
382
+ const settle = (fn, value) => {
383
+ report?.cleanup();
384
+ fn(value);
385
+ };
378
386
  // Note: shell: false (default) to prevent command injection (CWE-78)
379
387
  // Arguments are passed as array to avoid shell interpretation
380
388
  const proc = spawn(command, args, {
@@ -396,15 +404,17 @@ export class RetryHandlerService {
396
404
  proc.on('close', (code) => {
397
405
  clearTimeout(timeoutHandle);
398
406
  if (timedOut) {
399
- reject(new Error(`Test execution timed out after ${timeout}ms for command: ${command} ${args.join(' ')}`));
407
+ settle(reject, new Error(`Test execution timed out after ${timeout}ms for command: ${command} ${args.join(' ')}`));
400
408
  return;
401
409
  }
402
- // Parse result based on exit code and output
403
- const result = this.parseTestResult(code, stdout, stderr);
404
- resolve(result);
410
+ // Parse result based on exit code and output (Vitest writes the JSON
411
+ // report to the --outputFile; read it back rather than trusting stdout).
412
+ const result = this.parseTestResult(code, report ? report.read(stdout) : stdout, stderr);
413
+ settle(resolve, result);
405
414
  });
406
415
  proc.on('error', (err) => {
407
416
  clearTimeout(timeoutHandle);
417
+ report?.cleanup();
408
418
  reject(new Error(`Failed to spawn test process: ${err.message}. ` +
409
419
  `Command: ${command} ${args.join(' ')}. ` +
410
420
  `Ensure the test runner is installed and accessible.`));