agentic-qe 3.15.2 → 3.15.4

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 (445) hide show
  1. package/.claude/helpers/brain-checkpoint.cjs +46 -6
  2. package/.claude/hooks/aqe-hook.cjs +280 -51
  3. package/.claude/skills/skills-manifest.json +1 -1
  4. package/CHANGELOG.md +155 -0
  5. package/assets/skills/skills-manifest.json +1 -1
  6. package/dist/adapters/ag-ui/state-delta-cache.js +14 -5
  7. package/dist/adapters/trajectory-adapter.js +3 -1
  8. package/dist/cli/bundle.js +5 -5
  9. package/dist/cli/chunks/adapter-T54G3TBK.js +2 -0
  10. package/dist/cli/chunks/{agent-booster-wasm-664M7426.js → agent-booster-wasm-MHJBRXMK.js} +2 -2
  11. package/dist/cli/chunks/{agent-handler-E47ITH45.js → agent-handler-G64SD7J2.js} +2 -2
  12. package/dist/cli/chunks/{agent-memory-branch-CFWVOJX3.js → agent-memory-branch-G4UXFPKH.js} +2 -2
  13. package/dist/cli/chunks/aqe-learning-engine-HLCJJ3JM.js +2 -0
  14. package/dist/cli/chunks/{arena-ZU5CGBGH.js → arena-63M3M6EW.js} +2 -2
  15. package/dist/cli/chunks/{arena-JM3OY263.js → arena-QJMKYPHS.js} +4 -4
  16. package/dist/cli/chunks/{audit-HVBRC5AS.js → audit-UDFVTWSX.js} +3 -3
  17. package/dist/cli/chunks/base-VLD755UU.js +2 -0
  18. package/dist/cli/chunks/{better-sqlite3-45JLBQX3.js → better-sqlite3-JLX2G56I.js} +2 -2
  19. package/dist/cli/chunks/{brain-handler-FKDONZYA.js → brain-handler-PWF32LLW.js} +3 -3
  20. package/dist/cli/chunks/{branch-enumerator-M3DPS3D5.js → branch-enumerator-PB7QWXDP.js} +2 -2
  21. package/dist/cli/chunks/{browser-TG2TV6NR.js → browser-CYNV2F3U.js} +2 -2
  22. package/dist/cli/chunks/browser-workflow-6M6VLWRF.js +2 -0
  23. package/dist/cli/chunks/{chunk-JFFVYCTV.js → chunk-2534PXIV.js} +2 -2
  24. package/dist/cli/chunks/{chunk-GHXNRF63.js → chunk-2DRMTRBM.js} +2 -2
  25. package/dist/cli/chunks/{chunk-L77Z3Q6L.js → chunk-2ICC4H6K.js} +2 -2
  26. package/dist/cli/chunks/{chunk-EATZW5T2.js → chunk-2LL35V3A.js} +2 -2
  27. package/dist/cli/chunks/{chunk-MEUJWTOX.js → chunk-2MU4WCMQ.js} +2 -2
  28. package/dist/cli/chunks/{chunk-3RC5UMRJ.js → chunk-33IUCP34.js} +2 -2
  29. package/dist/cli/chunks/{chunk-UX4BOI6K.js → chunk-35A22AUL.js} +1 -1
  30. package/dist/cli/chunks/{chunk-Z7XCXHEB.js → chunk-3BDDOFYW.js} +2 -2
  31. package/dist/cli/chunks/chunk-3C2BFLYC.js +54 -0
  32. package/dist/cli/chunks/{chunk-56CE7UO4.js → chunk-3MSBVOYW.js} +6 -6
  33. package/dist/cli/chunks/{chunk-EDRIROCG.js → chunk-3ZIVBTX6.js} +2 -2
  34. package/dist/cli/chunks/{chunk-CRYZXTSQ.js → chunk-4GLR2S2M.js} +2 -2
  35. package/dist/cli/chunks/{chunk-DHSGCI6H.js → chunk-54ITMOFM.js} +6 -6
  36. package/dist/cli/chunks/{chunk-2AWU2E6R.js → chunk-54XTJBHV.js} +1 -1
  37. package/dist/cli/chunks/{chunk-JSTKSPYT.js → chunk-5B5D5KCV.js} +1 -1
  38. package/dist/cli/chunks/{chunk-NP2WWIZ3.js → chunk-5GWTJJEO.js} +1 -1
  39. package/dist/cli/chunks/{chunk-D75HDHX3.js → chunk-5H7MR6HP.js} +1 -1
  40. package/dist/cli/chunks/{chunk-NWYAV2UG.js → chunk-5SS2Z7JC.js} +2 -2
  41. package/dist/cli/chunks/chunk-5XXLWJU7.js +2 -0
  42. package/dist/cli/chunks/{chunk-B4H66LPR.js → chunk-6EHVPFHW.js} +1 -1
  43. package/dist/cli/chunks/{chunk-HSXLHNSS.js → chunk-6HO3XRXE.js} +2 -2
  44. package/dist/cli/chunks/chunk-6HTO4BLV.js +2 -0
  45. package/dist/cli/chunks/{chunk-SVHFSOGT.js → chunk-6QPW4OVH.js} +1 -1
  46. package/dist/cli/chunks/{chunk-BKZSTZDB.js → chunk-6TMUZGM2.js} +1 -1
  47. package/dist/cli/chunks/{chunk-2AOAEMJG.js → chunk-73MTUM6F.js} +2 -2
  48. package/dist/cli/chunks/{chunk-ANI3KPB7.js → chunk-73PCVMGA.js} +2 -2
  49. package/dist/cli/chunks/{chunk-HADOG2PT.js → chunk-76PRW2KY.js} +2 -2
  50. package/dist/cli/chunks/{chunk-NL6HKEPR.js → chunk-7INP6HZH.js} +3 -3
  51. package/dist/cli/chunks/{chunk-QB7H62A4.js → chunk-7X2IVMXN.js} +2 -2
  52. package/dist/cli/chunks/{chunk-ZVQSIH7Y.js → chunk-A4OPQJ4A.js} +8 -8
  53. package/dist/cli/chunks/{chunk-SKQTRYE7.js → chunk-ADF6LGHZ.js} +2 -2
  54. package/dist/cli/chunks/{chunk-5YS2DF5G.js → chunk-AHVN3UQZ.js} +2 -2
  55. package/dist/cli/chunks/{chunk-3XF7YTQC.js → chunk-AOKSLWON.js} +54 -54
  56. package/dist/cli/chunks/{chunk-CFDIYZGA.js → chunk-ASKPTGUU.js} +2 -2
  57. package/dist/cli/chunks/{chunk-LH3H4V7C.js → chunk-B7GJXQD2.js} +2 -2
  58. package/dist/cli/chunks/{chunk-HOBBYORR.js → chunk-B7J3O2WM.js} +1 -1
  59. package/dist/cli/chunks/{chunk-J4EJMAH3.js → chunk-BBKLVHDQ.js} +1 -1
  60. package/dist/cli/chunks/{chunk-WMNVFCKY.js → chunk-BND6M2JX.js} +2 -2
  61. package/dist/cli/chunks/{chunk-LRVR56PD.js → chunk-BPGFCUDO.js} +1 -1
  62. package/dist/cli/chunks/{chunk-O6QTCUSL.js → chunk-BY3IL56R.js} +1 -1
  63. package/dist/cli/chunks/{chunk-3KXKJSKS.js → chunk-BY5PLEPZ.js} +32 -32
  64. package/dist/cli/chunks/{chunk-DGKPGRBT.js → chunk-BZWZTGMF.js} +2 -2
  65. package/dist/cli/chunks/{chunk-AS27JP67.js → chunk-C5EN5WB6.js} +1 -1
  66. package/dist/cli/chunks/chunk-CFXFGQEN.js +15 -0
  67. package/dist/cli/chunks/{chunk-X4CADOSD.js → chunk-CQ3WSTJ2.js} +2 -2
  68. package/dist/cli/chunks/{chunk-HFF5ERIE.js → chunk-D7RVZ5C2.js} +2 -2
  69. package/dist/cli/chunks/{chunk-HS3O763N.js → chunk-DAYMT7TH.js} +21 -21
  70. package/dist/cli/chunks/{chunk-W6PLBRRS.js → chunk-DBIK4OFX.js} +1 -1
  71. package/dist/cli/chunks/{chunk-OWZ3F7DJ.js → chunk-DEJM2P5K.js} +1 -1
  72. package/dist/cli/chunks/{chunk-TC4B5D4Z.js → chunk-DF4Y3HPO.js} +1 -1
  73. package/dist/cli/chunks/{chunk-7UA7SMM4.js → chunk-DFJGXXCL.js} +1 -1
  74. package/dist/cli/chunks/{chunk-SZYK5JL7.js → chunk-DPL4ZXTE.js} +1 -1
  75. package/dist/cli/chunks/{chunk-6WVEICL2.js → chunk-DVE5SM5G.js} +4 -4
  76. package/dist/cli/chunks/{chunk-QR5ILM34.js → chunk-EGHK6NMH.js} +2 -2
  77. package/dist/cli/chunks/{chunk-E6GANSLP.js → chunk-EWUFVWRT.js} +2 -2
  78. package/dist/cli/chunks/{chunk-HBMBO4FD.js → chunk-EY5IUF7U.js} +2 -2
  79. package/dist/cli/chunks/{chunk-JCB6K24D.js → chunk-FDK2GF4G.js} +2 -2
  80. package/dist/cli/chunks/{chunk-QZNFZ5IQ.js → chunk-FRBCX46J.js} +2 -2
  81. package/dist/cli/chunks/{chunk-FCMCQ6OX.js → chunk-G3ZUB3HD.js} +2 -2
  82. package/dist/cli/chunks/{chunk-QGCFMACF.js → chunk-GAXTPQCZ.js} +2 -2
  83. package/dist/cli/chunks/{chunk-6O4KVU4K.js → chunk-GJVRQBLI.js} +2 -2
  84. package/dist/cli/chunks/{chunk-NLY5NUHZ.js → chunk-GLKLEHK3.js} +2 -2
  85. package/dist/cli/chunks/{chunk-IM67YHDK.js → chunk-HCDTLV5J.js} +2 -2
  86. package/dist/cli/chunks/{chunk-MY2XZHW3.js → chunk-HEDLZWPM.js} +1 -1
  87. package/dist/cli/chunks/{chunk-WUSSZ2S6.js → chunk-HEKCN5XQ.js} +2 -2
  88. package/dist/cli/chunks/{chunk-FRZVLRVR.js → chunk-HFSBONCS.js} +2 -2
  89. package/dist/cli/chunks/{chunk-IAOB2G3X.js → chunk-HX5KQK7I.js} +2 -2
  90. package/dist/cli/chunks/{chunk-BT6TZTCL.js → chunk-I43QRLLB.js} +2 -2
  91. package/dist/cli/chunks/{chunk-QJN5RW2U.js → chunk-I53365HG.js} +3 -3
  92. package/dist/cli/chunks/{chunk-55T7PDYP.js → chunk-I5A3HGO6.js} +2 -2
  93. package/dist/cli/chunks/{chunk-AR5V7VNC.js → chunk-I6E4X3L3.js} +1 -1
  94. package/dist/cli/chunks/chunk-IKWAPHJA.js +2 -0
  95. package/dist/cli/chunks/{chunk-UKRK3IE3.js → chunk-ISASRHZP.js} +2 -2
  96. package/dist/cli/chunks/{chunk-IHKRKRAV.js → chunk-J3RNVHDH.js} +1 -1
  97. package/dist/cli/chunks/{chunk-T75PWWK4.js → chunk-JFQDWAU3.js} +2 -2
  98. package/dist/cli/chunks/{chunk-3KTAMNKI.js → chunk-JL3TI43V.js} +2 -2
  99. package/dist/cli/chunks/{chunk-3DCRAW43.js → chunk-K2VUYRMG.js} +2 -2
  100. package/dist/cli/chunks/{chunk-RIAKRZCZ.js → chunk-KOLHZSEC.js} +2 -2
  101. package/dist/cli/chunks/{chunk-HXT4XDQO.js → chunk-LGA6J4I4.js} +2 -2
  102. package/dist/cli/chunks/{chunk-MDDECCAC.js → chunk-LJRZAALA.js} +169 -168
  103. package/dist/cli/chunks/{chunk-2B2MGJ2W.js → chunk-LOLAEDZD.js} +2 -2
  104. package/dist/cli/chunks/{chunk-2JEPRQMT.js → chunk-LPSE6DOQ.js} +1 -1
  105. package/dist/cli/chunks/{chunk-6KEYA4EH.js → chunk-LRTF5RMG.js} +4 -4
  106. package/dist/cli/chunks/{chunk-CV7E627D.js → chunk-LXYTC62V.js} +2 -2
  107. package/dist/cli/chunks/{chunk-YYVLMW65.js → chunk-LY53L6NH.js} +2 -2
  108. package/dist/cli/chunks/{chunk-HMDSBWF6.js → chunk-LZSLJJII.js} +2 -2
  109. package/dist/cli/chunks/{chunk-IT753IPZ.js → chunk-M6SJALLA.js} +2 -2
  110. package/dist/cli/chunks/{chunk-GDSLQTJC.js → chunk-MBV57LKC.js} +2 -2
  111. package/dist/cli/chunks/{chunk-I7J2ESGR.js → chunk-MGH4XIHH.js} +2 -2
  112. package/dist/cli/chunks/{chunk-Q32UGPWK.js → chunk-MVTUFPM2.js} +2 -2
  113. package/dist/cli/chunks/{chunk-UZL4JYVW.js → chunk-N6CRIUTO.js} +2 -2
  114. package/dist/cli/chunks/{chunk-326V7N25.js → chunk-NBMQOP2R.js} +1 -1
  115. package/dist/cli/chunks/{chunk-ZIKH7U5A.js → chunk-NIJMLEAX.js} +2 -2
  116. package/dist/cli/chunks/{chunk-MYDZBABD.js → chunk-O7TMY4GS.js} +2 -2
  117. package/dist/cli/chunks/{chunk-LVDZ25VX.js → chunk-OFQDM73J.js} +2 -2
  118. package/dist/cli/chunks/{chunk-WBZIOTY6.js → chunk-OG4KHX7S.js} +2 -2
  119. package/dist/cli/chunks/{chunk-GJTH6VBH.js → chunk-OHH6BUZK.js} +1 -1
  120. package/dist/cli/chunks/{chunk-T5N2PIPS.js → chunk-OOK6GPJR.js} +2 -2
  121. package/dist/cli/chunks/{chunk-AXJ75X6I.js → chunk-P7GM3EE7.js} +1 -1
  122. package/dist/cli/chunks/{chunk-IQB5ZBYO.js → chunk-PB2WSCBW.js} +3 -3
  123. package/dist/cli/chunks/{chunk-M36DAETL.js → chunk-PCWZCXBD.js} +2 -2
  124. package/dist/cli/chunks/{chunk-Z3PANQUT.js → chunk-PEA4DVXW.js} +1 -1
  125. package/dist/cli/chunks/{chunk-WBCE6V2N.js → chunk-PJAXWCFC.js} +1 -1
  126. package/dist/cli/chunks/{chunk-V67UQRQN.js → chunk-PMXWDTDK.js} +2 -2
  127. package/dist/cli/chunks/chunk-QIAX3JJB.js +3 -0
  128. package/dist/cli/chunks/chunk-R47LNH5W.js +2 -0
  129. package/dist/cli/chunks/{chunk-A6L2OCMO.js → chunk-RA3MI5WK.js} +2 -2
  130. package/dist/cli/chunks/{chunk-ITM26I6O.js → chunk-RB2SL5GD.js} +2 -2
  131. package/dist/cli/chunks/{chunk-XQBH3366.js → chunk-RG67RZIX.js} +2 -2
  132. package/dist/cli/chunks/{chunk-NBV37CEK.js → chunk-RI4JPBZD.js} +2 -2
  133. package/dist/cli/chunks/{chunk-2Q4Y3VQ6.js → chunk-RJ5CZ7B6.js} +2 -2
  134. package/dist/cli/chunks/{chunk-ATGIGJSL.js → chunk-RJMBHZYL.js} +1 -1
  135. package/dist/cli/chunks/{chunk-MOSXT6AO.js → chunk-RWZ4F44Y.js} +2 -2
  136. package/dist/cli/chunks/{chunk-URWT3EQT.js → chunk-S5D3HCGN.js} +2 -2
  137. package/dist/cli/chunks/{chunk-KQMCCHPO.js → chunk-SCL2OYN7.js} +2 -2
  138. package/dist/cli/chunks/{chunk-Y5VPLOA7.js → chunk-SIUUAKCE.js} +1 -1
  139. package/dist/cli/chunks/{chunk-JIRX6KUR.js → chunk-SJB4KMZS.js} +3 -3
  140. package/dist/cli/chunks/{chunk-TZH2QAFZ.js → chunk-SOSJFEFB.js} +2 -2
  141. package/dist/cli/chunks/{chunk-IBAXNCR2.js → chunk-SZWXUG36.js} +2 -2
  142. package/dist/cli/chunks/{chunk-KTLYL3BS.js → chunk-T3BMCEQR.js} +2 -2
  143. package/dist/cli/chunks/chunk-TB22Y3WW.js +4 -0
  144. package/dist/cli/chunks/{chunk-GJ7DON5S.js → chunk-TVQPYP2Z.js} +3 -3
  145. package/dist/cli/chunks/chunk-U2E5F3VZ.js +14 -0
  146. package/dist/cli/chunks/{chunk-ZSKQPXRW.js → chunk-UK5HY6LC.js} +1 -1
  147. package/dist/cli/chunks/{chunk-RO6HAZLV.js → chunk-UORI2CZ4.js} +1 -1
  148. package/dist/cli/chunks/{chunk-VTGAPHJE.js → chunk-V3NZ23X6.js} +2 -2
  149. package/dist/cli/chunks/{chunk-W7P7EOJ4.js → chunk-VAXQUD5G.js} +1 -1
  150. package/dist/cli/chunks/{chunk-EQG3JYSV.js → chunk-VMSO6DMF.js} +2 -2
  151. package/dist/cli/chunks/{chunk-6UO5YSNN.js → chunk-W3PPYNHF.js} +2 -2
  152. package/dist/cli/chunks/{chunk-FH6N2LKG.js → chunk-W6TJXK5Y.js} +2 -2
  153. package/dist/cli/chunks/{chunk-WJ7657IX.js → chunk-WEDVLKRB.js} +2 -2
  154. package/dist/cli/chunks/{chunk-N653RGT3.js → chunk-WI5AEB7Q.js} +2 -2
  155. package/dist/cli/chunks/{chunk-W5EKSBS4.js → chunk-WO4NSPLX.js} +2 -2
  156. package/dist/cli/chunks/{chunk-YH7VOLBP.js → chunk-WW6WUMS7.js} +2 -2
  157. package/dist/cli/chunks/{chunk-6OL2WES5.js → chunk-WYO5VN2L.js} +1 -1
  158. package/dist/cli/chunks/{chunk-PZK7O445.js → chunk-X5S5UEM6.js} +2 -2
  159. package/dist/cli/chunks/{chunk-NKWMTXBL.js → chunk-XHCCH7UC.js} +3 -3
  160. package/dist/cli/chunks/{chunk-GSC6JXDE.js → chunk-XKIFNKHV.js} +1 -1
  161. package/dist/cli/chunks/{chunk-FNPZINHV.js → chunk-XZ5Z56OP.js} +1 -1
  162. package/dist/cli/chunks/{chunk-6XLCFDIB.js → chunk-YQ6BK7QC.js} +2 -2
  163. package/dist/cli/chunks/{chunk-DNS37AHW.js → chunk-YUWUFYHK.js} +1 -1
  164. package/dist/cli/chunks/{chunk-YJSKT6G6.js → chunk-YZ2AGC7O.js} +1 -1
  165. package/dist/cli/chunks/{chunk-5TEPPW4J.js → chunk-Z56QTRRB.js} +2 -2
  166. package/dist/cli/chunks/{chunk-4MCO43NX.js → chunk-ZAOQIVHG.js} +4 -4
  167. package/dist/cli/chunks/{chunk-TMYGGYRY.js → chunk-ZF5JTQEE.js} +1 -1
  168. package/dist/cli/chunks/{chunk-HYWW4A2E.js → chunk-ZKXZTIVF.js} +2 -2
  169. package/dist/cli/chunks/{chunk-N4MNSEKY.js → chunk-ZP6ANUP7.js} +1 -1
  170. package/dist/cli/chunks/{chunk-5DFPAJ5O.js → chunk-ZURYZEHX.js} +2 -2
  171. package/dist/cli/chunks/{ci-JNBOR6FP.js → ci-NGMGB43T.js} +3 -3
  172. package/dist/cli/chunks/{ci-output-FYNKONEQ.js → ci-output-BMJABAEX.js} +2 -2
  173. package/dist/cli/chunks/{circuit-breaker-KOIXRDAD.js → circuit-breaker-GYD5CMJQ.js} +2 -2
  174. package/dist/cli/chunks/{claude-flow-setup-4CO7KHRN.js → claude-flow-setup-MMOYVBVD.js} +2 -2
  175. package/dist/cli/chunks/client-FUHNNK5O.js +2 -0
  176. package/dist/cli/chunks/{cline-installer-CMYAPKK5.js → cline-installer-B2SOZ44R.js} +2 -2
  177. package/dist/cli/chunks/{code-WFIAEP3H.js → code-V3FIRAXD.js} +3 -3
  178. package/dist/cli/chunks/{code-index-extractor-IYM6HWJN.js → code-index-extractor-CV6A756Z.js} +2 -2
  179. package/dist/cli/chunks/{codex-installer-DORVWRSU.js → codex-installer-EUC6J47Y.js} +2 -2
  180. package/dist/cli/chunks/{completions-54VM2MX2.js → completions-DQQIBAHR.js} +2 -2
  181. package/dist/cli/chunks/{complexity-analyzer-EGZDP5N4.js → complexity-analyzer-HPXMXP5I.js} +2 -2
  182. package/dist/cli/chunks/{continuedev-installer-4SDVDD4T.js → continuedev-installer-RCIYXH6V.js} +2 -2
  183. package/dist/cli/chunks/{copilot-installer-7FJQ7PCL.js → copilot-installer-VUH32SHF.js} +2 -2
  184. package/dist/cli/chunks/core-handlers-F7TLX4LM.js +2 -0
  185. package/dist/cli/chunks/cost-tracker-YLCKLOAL.js +2 -0
  186. package/dist/cli/chunks/{coverage-DI5LDRJ7.js → coverage-IVKDV236.js} +3 -3
  187. package/dist/cli/chunks/cross-domain-router-EGWPY67O.js +2 -0
  188. package/dist/cli/chunks/{cursor-installer-RTSZP5YD.js → cursor-installer-B42FN62K.js} +2 -2
  189. package/dist/cli/chunks/{daemon-SP3APEZY.js → daemon-DECQRQII.js} +3 -3
  190. package/dist/cli/chunks/{daemon-LM7LETPV.js → daemon-IPTOSCHM.js} +4 -4
  191. package/dist/cli/chunks/{dag-attention-scheduler-C3QBODFE.js → dag-attention-scheduler-RY7CDYSC.js} +2 -2
  192. package/dist/cli/chunks/{detect-I4RBUFFJ.js → detect-NW53BMJN.js} +2 -2
  193. package/dist/cli/chunks/{dist-node-PT6TCBCO.js → dist-node-LE6KHXAB.js} +2 -2
  194. package/dist/cli/chunks/{domain-handler-MJMTMB5X.js → domain-handler-JGXFT4LW.js} +2 -2
  195. package/dist/cli/chunks/{domain-plugins-Y4A2WYJW.js → domain-plugins-GY3RYKKK.js} +2 -2
  196. package/dist/cli/chunks/{domain-transfer-DUO42TLA.js → domain-transfer-CGBRXNTC.js} +2 -2
  197. package/dist/cli/chunks/dream-V4QN6OF5.js +2 -0
  198. package/dist/cli/chunks/{embed-and-insert-pattern-66ZQK4AI.js → embed-and-insert-pattern-65H4XHWR.js} +2 -2
  199. package/dist/cli/chunks/{eval-NQ7H27UF.js → eval-YPYIZQUR.js} +2 -2
  200. package/dist/cli/chunks/{experience-capture-middleware-MHEYPTIG.js → experience-capture-middleware-4JXVF5PL.js} +3 -3
  201. package/dist/cli/chunks/{fast-paths-YYDGN6ZC.js → fast-paths-HYQTAF2S.js} +2 -2
  202. package/dist/cli/chunks/{feature-flags-FY4DOYS2.js → feature-flags-HNSAFFX2.js} +2 -2
  203. package/dist/cli/chunks/{feature-flags-YFGUORHY.js → feature-flags-YACUH6OW.js} +2 -2
  204. package/dist/cli/chunks/{file-discovery-TOMDY7TK.js → file-discovery-R73BYEXB.js} +2 -2
  205. package/dist/cli/chunks/{fleet-MO3UCWB4.js → fleet-6M3BP4OO.js} +3 -3
  206. package/dist/cli/chunks/{gnn-wrapper-SLW4PPXQ.js → gnn-wrapper-QLD7KHXV.js} +2 -2
  207. package/dist/cli/chunks/{heartbeat-handler-36RFCP4E.js → heartbeat-handler-EZP333X4.js} +4 -4
  208. package/dist/cli/chunks/heartbeat-scheduler-3N3L6CRM.js +2 -0
  209. package/dist/cli/chunks/hnsw-adapter-2BXJYDXI.js +2 -0
  210. package/dist/cli/chunks/hnsw-index-2DLI5OVO.js +2 -0
  211. package/dist/cli/chunks/{hnsw-legacy-bridge-BJLWBKHE.js → hnsw-legacy-bridge-47CUCSAU.js} +2 -2
  212. package/dist/cli/chunks/{hnswlib-node-RAYNVJCJ.js → hnswlib-node-SVNYDJZH.js} +2 -2
  213. package/dist/cli/chunks/{hooks-JMHFWVEQ.js → hooks-6V5LMWP6.js} +10 -10
  214. package/dist/cli/chunks/hybrid-backend-OW4J65YH.js +2 -0
  215. package/dist/cli/chunks/{hypergraph-engine-JUDBKPOX.js → hypergraph-engine-L2FOBIFF.js} +2 -2
  216. package/dist/cli/chunks/{hypergraph-handler-AXTWXOZU.js → hypergraph-handler-DU6Z57EE.js} +3 -3
  217. package/dist/cli/chunks/impact-analyzer-ZH5I2RG6.js +2 -0
  218. package/dist/cli/chunks/{init-handler-PARJNZFF.js → init-handler-HETPWU67.js} +6 -6
  219. package/dist/cli/chunks/init-wizard-NIKM3ZOK.js +2 -0
  220. package/dist/cli/chunks/kernel-2EOSVM6X.js +2 -0
  221. package/dist/cli/chunks/{kilocode-installer-22HX2E4V.js → kilocode-installer-NHKYGJ7Q.js} +2 -2
  222. package/dist/cli/chunks/{kiro-installer-OVPBLY7J.js → kiro-installer-24UK6GGR.js} +2 -2
  223. package/dist/cli/chunks/knowledge-graph-D3BPWNNO.js +2 -0
  224. package/dist/cli/chunks/{learning-DWXPJ3R6.js → learning-QLVRZNHT.js} +3 -3
  225. package/dist/cli/chunks/{llm-router-7PPVVKNG.js → llm-router-XRMI2VMG.js} +4 -4
  226. package/dist/cli/chunks/llm-router-service-TJPPZFUN.js +2 -0
  227. package/dist/cli/chunks/{load-VI5XHNZA.js → load-W5UWL5C7.js} +2 -2
  228. package/dist/cli/chunks/load-test-RFT7IDOL.js +2 -0
  229. package/dist/cli/chunks/{mcp-UW4Z3Z64.js → mcp-N7ALQ4BL.js} +2 -2
  230. package/dist/cli/chunks/{memory-UD2KCB5M.js → memory-WV52DLSA.js} +5 -5
  231. package/dist/cli/chunks/memory-backend-O2O4CFKZ.js +2 -0
  232. package/dist/cli/chunks/memory-handlers-DAEGUDBD.js +2 -0
  233. package/dist/cli/chunks/{multi-model-executor-5O4WWU5Z.js → multi-model-executor-3FVTZCSO.js} +2 -2
  234. package/dist/cli/chunks/{opencode-installer-DTRFDGM7.js → opencode-installer-NTPWGHUW.js} +2 -2
  235. package/dist/cli/chunks/{orchestrator-ENJIKV6Z.js → orchestrator-ORGJ6VAA.js} +85 -26
  236. package/dist/cli/chunks/pattern-null-store-TUBNXS34.js +2 -0
  237. package/dist/cli/chunks/{pattern-usage-recorder-QPNIU5PD.js → pattern-usage-recorder-WWXHUH5U.js} +2 -2
  238. package/dist/cli/chunks/{pipeline-G3JYDNPE.js → pipeline-ZOKZFXTH.js} +2 -2
  239. package/dist/cli/chunks/{platform-P4WR6N3D.js → platform-CDNL322F.js} +2 -2
  240. package/dist/cli/chunks/{plugin-C7763Q5W.js → plugin-ZVLFNZZ4.js} +2 -2
  241. package/dist/cli/chunks/{prime-radiant-advanced-wasm-DH6R3XSZ.js → prime-radiant-advanced-wasm-FVJDU2JY.js} +2 -2
  242. package/dist/cli/chunks/{project-root-7DTXDLEG.js → project-root-UCHQH3QL.js} +2 -2
  243. package/dist/cli/chunks/protocol-executor-6FQTTO3Y.js +2 -0
  244. package/dist/cli/chunks/{protocol-handler-EODULGOZ.js → protocol-handler-4YBN5R23.js} +2 -2
  245. package/dist/cli/chunks/{prove-A7G3SIOF.js → prove-BHDHY664.js} +2 -2
  246. package/dist/cli/chunks/qe-reasoning-bank-TKPND56C.js +2 -0
  247. package/dist/cli/chunks/{quality-JTURFUX3.js → quality-46AK277P.js} +2 -2
  248. package/dist/cli/chunks/{quality-gate-M2EI754V.js → quality-gate-WANE7TCN.js} +3 -3
  249. package/dist/cli/chunks/queen-coordinator-DWMXLPJG.js +2 -0
  250. package/dist/cli/chunks/{real-embeddings-DI7JMCG7.js → real-embeddings-56MNGJGJ.js} +2 -2
  251. package/dist/cli/chunks/{ref-validation-MSFMNKDR.js → ref-validation-S7UWXQIP.js} +2 -2
  252. package/dist/cli/chunks/{roocode-installer-XIMFFHOH.js → roocode-installer-TEYOQYL6.js} +2 -2
  253. package/dist/cli/chunks/router-QIMUYRCC.js +2 -0
  254. package/dist/cli/chunks/routing-feedback-4OH5ZNF4.js +2 -0
  255. package/dist/cli/chunks/{routing-handler-MCDKNBQW.js → routing-handler-KDTLMRWD.js} +2 -2
  256. package/dist/cli/chunks/{ruvector-commands-OBSYAK2X.js → ruvector-commands-AOUDXCYE.js} +2 -2
  257. package/dist/cli/chunks/rvf-dual-writer-S6JBZL54.js +2 -0
  258. package/dist/cli/chunks/rvf-migration-adapter-TSGMLMYR.js +2 -0
  259. package/dist/cli/chunks/{rvf-migration-coordinator-4DTRIHY6.js → rvf-migration-coordinator-V74MVBHS.js} +2 -2
  260. package/dist/cli/chunks/rvf-native-adapter-Z7QOW47S.js +2 -0
  261. package/dist/cli/chunks/{rvf-store-integrity-CWAVMRC4.js → rvf-store-integrity-QI47Y354.js} +2 -2
  262. package/dist/cli/chunks/safe-db-JLOVBJNC.js +2 -0
  263. package/dist/cli/chunks/schedule-IM6XOBGR.js +2 -0
  264. package/dist/cli/chunks/scheduler-XL2SVVK5.js +2 -0
  265. package/dist/cli/chunks/{security-74TWSO74.js → security-SN6MWOJT.js} +3 -3
  266. package/dist/cli/chunks/{shared-rvf-adapter-ZHNAGE5H.js → shared-rvf-adapter-2LB56LP4.js} +2 -2
  267. package/dist/cli/chunks/{shared-rvf-dual-writer-BS5WAVCC.js → shared-rvf-dual-writer-WU7PFKQM.js} +2 -2
  268. package/dist/cli/chunks/sqlite-persistence-LWMIIC4U.js +2 -0
  269. package/dist/cli/chunks/{standalone-memory-3HGHTE7S.js → standalone-memory-F6FSRFWC.js} +2 -2
  270. package/dist/cli/chunks/{status-handler-XWEEGNGH.js → status-handler-DHD5MS4G.js} +2 -2
  271. package/dist/cli/chunks/{structural-health-TB5JGMVS.js → structural-health-P6HPSQMR.js} +2 -2
  272. package/dist/cli/chunks/{sync-T4VLBURM.js → sync-LISJGDSE.js} +2 -2
  273. package/dist/cli/chunks/sync-SNAXAVCN.js +2 -0
  274. package/dist/cli/chunks/{task-handler-RQ65QKXX.js → task-handler-ZT44NT5Z.js} +2 -2
  275. package/dist/cli/chunks/{task-handlers-USYWJ4H2.js → task-handlers-R6DQ5324.js} +3 -3
  276. package/dist/cli/chunks/test-MUFHR4JQ.js +34 -0
  277. package/dist/cli/chunks/test-scheduling-TAUSLZJP.js +15 -0
  278. package/dist/cli/chunks/token-bootstrap-UGRH7OPU.js +2 -0
  279. package/dist/cli/chunks/{token-usage-CISTB5K5.js → token-usage-IX65ECBR.js} +2 -2
  280. package/dist/cli/chunks/{transformers-C7LV763N.js → transformers-QKPSVW2W.js} +2 -2
  281. package/dist/cli/chunks/{tree-sitter-wasm-parser-P26JC3YV.js → tree-sitter-wasm-parser-Z7PPA2JO.js} +2 -2
  282. package/dist/cli/chunks/{types-YMVMKIWB.js → types-ULNNGGGH.js} +2 -2
  283. package/dist/cli/chunks/unified-memory-F5IJY7W7.js +2 -0
  284. package/dist/cli/chunks/unified-memory-hnsw-C3WAMAQL.js +2 -0
  285. package/dist/cli/chunks/unified-persistence-EWXXOTCB.js +2 -0
  286. package/dist/cli/chunks/{upgrade-U2REOPAW.js → upgrade-ECI3YUYA.js} +2 -2
  287. package/dist/cli/chunks/{validate-NDTCKN7P.js → validate-3JKRUW2S.js} +2 -2
  288. package/dist/cli/chunks/{validate-swarm-OJUGVH5Q.js → validate-swarm-LZWANCIE.js} +2 -2
  289. package/dist/cli/chunks/visual-security-CKLTAIAB.js +2 -0
  290. package/dist/cli/chunks/{web-tree-sitter-2CLRSA7K.js → web-tree-sitter-N5V4A6XG.js} +2 -2
  291. package/dist/cli/chunks/{windsurf-installer-DSUJJ4PG.js → windsurf-installer-5TBM5B3C.js} +2 -2
  292. package/dist/cli/chunks/{witness-chain-TEGL4ZWB.js → witness-chain-MFP3HBWQ.js} +2 -2
  293. package/dist/cli/chunks/witness-chain-Z6LWFEZS.js +2 -0
  294. package/dist/cli/chunks/witness-chain-repair-5QWRFVUK.js +2 -0
  295. package/dist/cli/chunks/{witness-chain-verifier-SPXKFC67.js → witness-chain-verifier-SRAT7LVY.js} +2 -2
  296. package/dist/cli/chunks/{witness-key-manager-EALOV4OV.js → witness-key-manager-FYZXQTLJ.js} +2 -2
  297. package/dist/cli/chunks/{workflow-PYI6HCAG.js → workflow-M7TUYYXY.js} +5 -5
  298. package/dist/cli/chunks/workflow-orchestrator-OFTAR2NA.js +2 -0
  299. package/dist/cli/chunks/wrappers-COU73OQ6.js +2 -0
  300. package/dist/cli/commands/test.js +30 -12
  301. package/dist/cli/commands/workflow.js +3 -0
  302. package/dist/cli/scheduler/persistent-scheduler.d.ts +2 -0
  303. package/dist/cli/scheduler/persistent-scheduler.js +12 -2
  304. package/dist/cli/utils/generated-test-writer.d.ts +35 -0
  305. package/dist/cli/utils/generated-test-writer.js +44 -0
  306. package/dist/context/compiler.js +4 -1
  307. package/dist/coordination/consensus/providers/ollama-provider.js +16 -27
  308. package/dist/coordination/consensus/providers/openrouter-provider.js +13 -24
  309. package/dist/coordination/handlers/test-execution-handlers.js +4 -2
  310. package/dist/coordination/protocols/defect-investigation.js +4 -1
  311. package/dist/domains/code-intelligence/services/metric-collector/listing-process-owner.d.ts +3 -0
  312. package/dist/domains/code-intelligence/services/metric-collector/listing-process-owner.js +57 -0
  313. package/dist/domains/code-intelligence/services/metric-collector/test-counter.js +127 -39
  314. package/dist/domains/coverage-analysis/services/gap-detector.js +3 -1
  315. package/dist/domains/learning-optimization/services/learning-coordinator.js +4 -2
  316. package/dist/domains/test-execution/services/flaky-detector.js +8 -2
  317. package/dist/domains/test-execution/services/retry-handler.js +23 -20
  318. package/dist/domains/test-execution/services/test-executor.js +5 -2
  319. package/dist/domains/test-generation/services/test-generator.js +5 -2
  320. package/dist/governance/compliance-reporter.js +8 -7
  321. package/dist/governance/proof-envelope-integration.js +3 -1
  322. package/dist/init/phases/07-hooks.js +30 -4
  323. package/dist/init/phases/10-workers.js +42 -6
  324. package/dist/integrations/agentic-flow/onnx-embeddings/embedding-generator.d.ts +4 -1
  325. package/dist/integrations/agentic-flow/onnx-embeddings/embedding-generator.js +6 -2
  326. package/dist/integrations/browser/qe-dashboard/wasm-vector-store.js +2 -1
  327. package/dist/integrations/ruvector/coverage-router.d.ts +3 -1
  328. package/dist/integrations/ruvector/coverage-router.js +7 -6
  329. package/dist/integrations/ruvector/diff-risk-classifier.js +5 -4
  330. package/dist/integrations/ruvector/rvf-dual-writer.js +10 -1
  331. package/dist/integrations/vibium/runtime.js +2 -6
  332. package/dist/learning/dream/dream-engine.d.ts +5 -0
  333. package/dist/learning/dream/dream-engine.js +20 -3
  334. package/dist/learning/embedding-space.d.ts +18 -0
  335. package/dist/learning/embedding-space.js +33 -0
  336. package/dist/learning/rvf-pattern-store.js +19 -5
  337. package/dist/mcp/bundle.js +442 -441
  338. package/dist/mcp/handlers/domain-handler-configs.d.ts +42 -0
  339. package/dist/mcp/handlers/handler-factory.js +3 -1
  340. package/dist/mcp/handlers/save-results-option.d.ts +62 -0
  341. package/dist/mcp/handlers/save-results-option.js +35 -0
  342. package/dist/mcp/protocol-server.js +22 -11
  343. package/dist/mcp/security/rate-limiter.d.ts +8 -1
  344. package/dist/mcp/security/rate-limiter.js +33 -4
  345. package/dist/mcp/services/session-resume.js +11 -0
  346. package/dist/mcp/services/session-store.d.ts +31 -2
  347. package/dist/mcp/services/session-store.js +95 -16
  348. package/dist/mcp/services/session-write-buffer.d.ts +55 -0
  349. package/dist/mcp/services/session-write-buffer.js +144 -0
  350. package/dist/mcp/types.d.ts +18 -0
  351. package/dist/memory/crdt/convergence-tracker.js +14 -24
  352. package/dist/memory/crdt/crdt-store.js +15 -0
  353. package/dist/memory/crdt/g-counter.js +10 -8
  354. package/dist/memory/crdt/lww-register.js +3 -3
  355. package/dist/memory/crdt/or-set.js +18 -0
  356. package/dist/planning/goap-planner.js +18 -10
  357. package/dist/shared/embeddings/embedding-cache.d.ts +3 -3
  358. package/dist/shared/embeddings/embedding-cache.js +8 -8
  359. package/dist/shared/embeddings/nomic-embedder.js +9 -6
  360. package/dist/shared/embeddings/ollama-client.d.ts +1 -1
  361. package/dist/shared/embeddings/ollama-client.js +30 -31
  362. package/dist/shared/git/git-analyzer.d.ts +4 -1
  363. package/dist/shared/git/git-analyzer.js +9 -4
  364. package/dist/shared/llm/cache.js +1 -1
  365. package/dist/shared/llm/cost-tracker.js +8 -6
  366. package/dist/shared/llm/providers/azure-openai.js +5 -21
  367. package/dist/shared/llm/providers/bedrock.js +5 -21
  368. package/dist/shared/llm/providers/claude.js +5 -21
  369. package/dist/shared/llm/providers/cognitum.js +5 -17
  370. package/dist/shared/llm/providers/gemini.js +9 -23
  371. package/dist/shared/llm/providers/ollama.js +5 -21
  372. package/dist/shared/llm/providers/openai.js +5 -21
  373. package/dist/shared/llm/providers/openrouter.js +9 -23
  374. package/dist/shared/llm/providers/response-deadline.d.ts +3 -0
  375. package/dist/shared/llm/providers/response-deadline.js +100 -0
  376. package/dist/shared/llm/spend-ledger.js +3 -2
  377. package/dist/shared/metrics/code-metrics.d.ts +1 -0
  378. package/dist/shared/metrics/code-metrics.js +3 -44
  379. package/dist/shared/metrics/cognitive-complexity.d.ts +17 -0
  380. package/dist/shared/metrics/cognitive-complexity.js +108 -0
  381. package/dist/shared/npm-cli-invocation.d.ts +21 -0
  382. package/dist/shared/npm-cli-invocation.js +28 -0
  383. package/dist/shared/optional-module.js +24 -0
  384. package/dist/shared/test-runner-args.d.ts +42 -0
  385. package/dist/shared/test-runner-args.js +74 -0
  386. package/dist/shared/utils/safe-record.d.ts +18 -0
  387. package/dist/shared/utils/safe-record.js +28 -0
  388. package/dist/test-scheduling/executors/vitest-executor.js +23 -5
  389. package/dist/workers/quality-daemon/git-watcher.js +5 -0
  390. package/package.json +1 -1
  391. package/dist/adapters/ag-ui/json-patch-utils.d.ts +0 -136
  392. package/dist/adapters/ag-ui/json-patch-utils.js +0 -575
  393. package/dist/cli/chunks/adapter-EUIELRLI.js +0 -2
  394. package/dist/cli/chunks/aqe-learning-engine-LXRKHASR.js +0 -2
  395. package/dist/cli/chunks/base-4DSLX33Y.js +0 -2
  396. package/dist/cli/chunks/browser-workflow-AWCQLQZK.js +0 -2
  397. package/dist/cli/chunks/chunk-E2QHUMCR.js +0 -2
  398. package/dist/cli/chunks/chunk-I7ECEOFV.js +0 -2
  399. package/dist/cli/chunks/chunk-LW4BCFIV.js +0 -15
  400. package/dist/cli/chunks/chunk-QJGKL67W.js +0 -54
  401. package/dist/cli/chunks/chunk-RLQ4MYB6.js +0 -3
  402. package/dist/cli/chunks/chunk-X43HA3RF.js +0 -14
  403. package/dist/cli/chunks/chunk-Z3K4JZXQ.js +0 -4
  404. package/dist/cli/chunks/client-UJVHZXNQ.js +0 -2
  405. package/dist/cli/chunks/core-handlers-AFXZOSH3.js +0 -2
  406. package/dist/cli/chunks/cost-tracker-D6YSKTQC.js +0 -2
  407. package/dist/cli/chunks/cross-domain-router-ZLNVKLIR.js +0 -2
  408. package/dist/cli/chunks/dream-4OPJXXEG.js +0 -2
  409. package/dist/cli/chunks/heartbeat-scheduler-J5KLHO6C.js +0 -2
  410. package/dist/cli/chunks/hnsw-adapter-56P6XSFR.js +0 -2
  411. package/dist/cli/chunks/hnsw-index-GFZ6XCEW.js +0 -2
  412. package/dist/cli/chunks/hybrid-backend-TUBWJDDN.js +0 -2
  413. package/dist/cli/chunks/impact-analyzer-FXVGKS6B.js +0 -2
  414. package/dist/cli/chunks/init-wizard-LK73HQ7W.js +0 -2
  415. package/dist/cli/chunks/kernel-TCZDKRSI.js +0 -2
  416. package/dist/cli/chunks/knowledge-graph-TWMB2GH2.js +0 -2
  417. package/dist/cli/chunks/llm-router-service-HPDH3P77.js +0 -2
  418. package/dist/cli/chunks/load-test-HTYOUYSN.js +0 -2
  419. package/dist/cli/chunks/memory-backend-X5BE2MPK.js +0 -2
  420. package/dist/cli/chunks/memory-handlers-SQXMFX5X.js +0 -2
  421. package/dist/cli/chunks/pattern-null-store-OCQGQZU6.js +0 -2
  422. package/dist/cli/chunks/protocol-executor-CYEQHQCL.js +0 -2
  423. package/dist/cli/chunks/qe-reasoning-bank-GSTA5WJ4.js +0 -2
  424. package/dist/cli/chunks/queen-coordinator-Y2Q5RQL7.js +0 -2
  425. package/dist/cli/chunks/router-4QB5L4IW.js +0 -2
  426. package/dist/cli/chunks/routing-feedback-YBVHJY5L.js +0 -2
  427. package/dist/cli/chunks/rvf-dual-writer-T5B456SW.js +0 -2
  428. package/dist/cli/chunks/rvf-migration-adapter-2O2NL7ZF.js +0 -2
  429. package/dist/cli/chunks/rvf-native-adapter-RDB3GWTW.js +0 -2
  430. package/dist/cli/chunks/safe-db-YXVMLFU4.js +0 -2
  431. package/dist/cli/chunks/schedule-K6XWCCSK.js +0 -2
  432. package/dist/cli/chunks/scheduler-4MW22D6Q.js +0 -2
  433. package/dist/cli/chunks/sqlite-persistence-UVDHUSAU.js +0 -2
  434. package/dist/cli/chunks/sync-LSPNSVDI.js +0 -2
  435. package/dist/cli/chunks/test-M2XTKD62.js +0 -33
  436. package/dist/cli/chunks/test-scheduling-GYXJQHJL.js +0 -15
  437. package/dist/cli/chunks/token-bootstrap-OTEMRUFR.js +0 -2
  438. package/dist/cli/chunks/unified-memory-UUK77NSE.js +0 -2
  439. package/dist/cli/chunks/unified-memory-hnsw-JOUE6WNF.js +0 -2
  440. package/dist/cli/chunks/unified-persistence-3DRJGNQE.js +0 -2
  441. package/dist/cli/chunks/visual-security-EM7FQG5X.js +0 -2
  442. package/dist/cli/chunks/witness-chain-7NZ6IIUN.js +0 -2
  443. package/dist/cli/chunks/witness-chain-repair-ZWS5WXFL.js +0 -2
  444. package/dist/cli/chunks/workflow-orchestrator-3C3S5FIM.js +0 -2
  445. package/dist/cli/chunks/wrappers-NXJHGK3W.js +0 -2
@@ -12,11 +12,14 @@
12
12
  *
13
13
  * @see docs/plans/AQE_V3_IMPROVEMENTS_PLAN.md - Phase 5, RM-003
14
14
  */
15
- import { execSync, spawnSync } from 'child_process';
16
- import { existsSync, readFileSync, readdirSync } from 'fs';
17
- import { join, extname } from 'path';
15
+ import { execSync, spawn, spawnSync } from 'child_process';
16
+ import { createRequire } from 'module';
17
+ import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync } from 'fs';
18
+ import { tmpdir } from 'os';
19
+ import { join, extname, resolve } from 'path';
18
20
  import { DEFAULT_METRIC_CONFIG, } from './interfaces.js';
19
21
  import { safeJsonParse } from '../../../../shared/safe-json.js';
22
+ import { ownListingProcess } from './listing-process-owner.js';
20
23
  // ============================================================================
21
24
  // Main Test Counting Function
22
25
  // ============================================================================
@@ -177,53 +180,138 @@ export function checkTestRunners(projectPath) {
177
180
  // ============================================================================
178
181
  /**
179
182
  * Count tests using Vitest
180
- * Uses `vitest list` for accurate test discovery WITHOUT execution.
183
+ * Uses `vitest list` for accurate test discovery without executing test callbacks.
181
184
  *
182
185
  * IMPORTANT: We use `vitest list` (not `vitest --run`) because:
183
186
  * - `vitest --run` EXECUTES tests, causing OOM in test-of-tests scenarios
184
- * - `vitest list` only enumerates tests without running them
187
+ * - Collection imports test modules but does not run test callbacks
185
188
  */
186
- function countVitestTests(projectPath, config) {
189
+ async function countVitestTests(projectPath, config) {
190
+ let listingDirectory;
187
191
  try {
188
- // Use vitest list for safe enumeration (NO execution). --json emits one
189
- // entry per discovered test in Vitest 4 and 5; --reporter=json does not.
190
- const output = execSync('npx vitest list --json', {
191
- cwd: projectPath,
192
- encoding: 'utf-8',
193
- timeout: Math.min(config.timeout, 30000), // Cap at 30s for listing
194
- maxBuffer: 10 * 1024 * 1024, // 10MB buffer (reduced from 50MB)
195
- });
192
+ let supportsStaticParse = false;
196
193
  try {
197
- const data = safeJsonParse(output);
198
- // Vitest list --json returns a flat array of { name, file, location? }.
199
- if (Array.isArray(data) && data.every(test => test && typeof test.name === 'string' && typeof test.file === 'string')) {
200
- return classifyTests(data.length, 'vitest', projectPath);
201
- }
202
- // Preserve compatibility with older structured runner output.
203
- if (data && typeof data.numTotalTests === 'number') {
204
- return classifyTests(data.numTotalTests, 'vitest', projectPath);
205
- }
194
+ const projectRequire = createRequire(resolve(projectPath, 'package.json'));
195
+ const pkg = safeJsonParse(readFileSync(projectRequire.resolve('vitest/package.json'), 'utf-8'));
196
+ const [major, minor] = String(pkg.version).split('.').map(Number);
197
+ supportsStaticParse = major > 4 || (major === 4 && minor >= 1);
206
198
  }
207
199
  catch {
208
- // JSON parse failed, try line counting
200
+ // Retain native listing without new flags for unresolved/older runners.
201
+ }
202
+ listingDirectory = mkdtempSync(join(tmpdir(), 'aqe-vitest-list-'));
203
+ const readListing = (file) => {
204
+ try {
205
+ if (statSync(file).size > 10 * 1024 * 1024)
206
+ return undefined;
207
+ const data = safeJsonParse(readFileSync(file, 'utf-8'));
208
+ if (Array.isArray(data) && data.every(test => test && typeof test.name === 'string' && typeof test.file === 'string'))
209
+ return data.length;
210
+ if (data && typeof data.numTotalTests === 'number')
211
+ return data.numTotalTests;
212
+ }
213
+ catch { /* Missing/invalid artifacts are not authoritative counts. */ }
214
+ return undefined;
215
+ };
216
+ const listTests = async (mode) => {
217
+ // Separate artifacts prevent a failed attempt from contaminating recovery.
218
+ const file = join(listingDirectory, `${mode}.json`);
219
+ const args = ['vitest', 'list', `--json=${file}`];
220
+ if (mode !== 'legacy')
221
+ args.push(mode === 'static' ? '--static-parse' : '--no-static-parse');
222
+ const succeeded = await new Promise((resolveAttempt) => {
223
+ const windows = process.platform === 'win32';
224
+ // Keep Windows artifact paths in a quoted environment expansion;
225
+ // interpolating a caller-controlled temporary path into cmd is unsafe.
226
+ const flag = mode === 'legacy' ? ''
227
+ : mode === 'static' ? ' --static-parse' : ' --no-static-parse';
228
+ const command = windows ? `npx vitest list --json="%AQE_VITEST_LIST_JSON%"${flag}` : 'npx';
229
+ const child = spawn(command, windows ? [] : args, {
230
+ cwd: projectPath, detached: !windows, shell: windows,
231
+ env: { ...process.env, AQE_VITEST_LIST_JSON: file },
232
+ stdio: ['ignore', 'pipe', 'pipe'],
233
+ });
234
+ let stopped = false;
235
+ let bytes = 0;
236
+ const stopTree = () => {
237
+ if (!child.pid)
238
+ return;
239
+ try {
240
+ if (windows) {
241
+ // Windows has no POSIX process groups; terminate this owned tree.
242
+ spawnSync('taskkill', ['/PID', String(child.pid), '/T', '/F'], {
243
+ stdio: 'ignore', timeout: 5000,
244
+ });
245
+ }
246
+ else {
247
+ process.kill(-child.pid, 'SIGKILL');
248
+ }
249
+ }
250
+ catch { /* The process group may already have exited. */ }
251
+ };
252
+ const releaseOwnership = ownListingProcess(listingDirectory, stopTree);
253
+ const timer = setTimeout(() => { stopped = true; stopTree(); }, Math.min(config.timeout, 30000));
254
+ const consume = (chunk) => {
255
+ bytes += chunk.length;
256
+ if (bytes > 10 * 1024 * 1024) {
257
+ stopped = true;
258
+ stopTree();
259
+ }
260
+ };
261
+ child.stdout?.on('data', consume);
262
+ child.stderr?.on('data', consume);
263
+ child.once('error', () => { clearTimeout(timer); stopTree(); releaseOwnership(); resolveAttempt(false); });
264
+ child.once('close', (code) => {
265
+ clearTimeout(timer);
266
+ // A wrapper may exit while its descendants are still importing modules.
267
+ stopTree();
268
+ releaseOwnership();
269
+ resolveAttempt(!stopped && code === 0);
270
+ });
271
+ });
272
+ return succeeded ? readListing(file) : undefined;
273
+ };
274
+ if (!supportsStaticParse) {
275
+ const total = await listTests('legacy');
276
+ return total === undefined ? countTestsByFilePattern(projectPath, config)
277
+ : classifyTests(total, 'vitest', projectPath);
209
278
  }
210
- // Fallback: count test entries from text output
211
- // vitest list outputs lines like "✓ test name" or "○ test name"
212
- const lines = output.split('\n');
213
- const testLines = lines.filter(line => line.trim().startsWith('✓') ||
214
- line.trim().startsWith('○') ||
215
- line.includes(' > ') // nested test format: "describe > test name"
216
- );
217
- if (testLines.length > 0) {
218
- return classifyTests(testLines.length, 'vitest', projectPath);
279
+ // Inspect cheap static discovery before importing project test modules.
280
+ // Above 1,000 static declarations or 100 files, retain the native static
281
+ // count instead of paying the collection timeout for every metrics call.
282
+ const staticTotal = await listTests('static');
283
+ const staticFile = join(listingDirectory, 'static.json');
284
+ let staticFiles = 0;
285
+ if (staticTotal !== undefined) {
286
+ try {
287
+ const data = safeJsonParse(readFileSync(staticFile, 'utf-8'));
288
+ if (Array.isArray(data))
289
+ staticFiles = new Set(data.map(test => test.file)).size;
290
+ }
291
+ catch { /* The validated count remains usable. */ }
292
+ if (staticTotal > 1000 || staticFiles > 100) {
293
+ return classifyTests(staticTotal, 'vitest', projectPath);
294
+ }
219
295
  }
220
- // If vitest list produced no usable output, fall back to file pattern
221
- return countTestsByFilePattern(projectPath, config);
296
+ // Collection expands parameterized/computed declarations but imports every
297
+ // test module (with setup/describe side effects). One throwing import loses
298
+ // expansion for the whole suite; preserve its static count when available.
299
+ const collectedTotal = await listTests('collection');
300
+ const total = collectedTotal ?? staticTotal;
301
+ return total === undefined ? countTestsByFilePattern(projectPath, config)
302
+ : classifyTests(total, 'vitest', projectPath);
222
303
  }
223
304
  catch {
224
- // vitest list failed (not installed, timeout, etc.) - fall back to file pattern
225
305
  return countTestsByFilePattern(projectPath, config);
226
306
  }
307
+ finally {
308
+ if (listingDirectory) {
309
+ try {
310
+ rmSync(listingDirectory, { recursive: true, force: true });
311
+ }
312
+ catch { /* Cleanup failure must not change an otherwise valid count. */ }
313
+ }
314
+ }
227
315
  }
228
316
  /**
229
317
  * Count tests using Jest
@@ -274,10 +362,10 @@ function countCargoTests(projectPath, config) {
274
362
  // Count lines ending with ": test"
275
363
  const testLines = output.split('\n').filter(line => line.endsWith(': test'));
276
364
  const total = testLines.length;
277
- // Classify by test path patterns
278
- const unit = testLines.filter(t => !t.includes('integration') && !t.includes('e2e')).length;
279
- const integration = testLines.filter(t => t.includes('integration')).length;
365
+ // Disjoint categories, e2e before integration: `tests::integration::e2e_x` counts once.
280
366
  const e2e = testLines.filter(t => t.includes('e2e')).length;
367
+ const integration = testLines.filter(t => !t.includes('e2e') && t.includes('integration')).length;
368
+ const unit = total - integration - e2e;
281
369
  return {
282
370
  total,
283
371
  unit,
@@ -9,6 +9,7 @@ import { ok, err } from '../../../shared/types/index.js';
9
9
  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
+ import { createSafeRecord } from '../../../shared/utils/safe-record.js';
12
13
  const DEFAULT_CONFIG = {
13
14
  minCoverage: 80,
14
15
  enableLLMAnalysis: true, // On by default - opt-out
@@ -212,7 +213,8 @@ Return JSON in this exact format:
212
213
  * Calculate effort breakdown by file
213
214
  */
214
215
  calculateEffortBreakdown(gaps) {
215
- const breakdown = {};
216
+ // File paths are data, so the buckets must not inherit from Object.prototype (#914).
217
+ const breakdown = createSafeRecord();
216
218
  for (const gap of gaps) {
217
219
  const effort = Math.ceil(gap.lines.length / 15);
218
220
  breakdown[gap.file] = (breakdown[gap.file] || 0) + effort;
@@ -9,6 +9,7 @@ import { rehydrateDates } from '../../../shared/utils/kv-date-rehydrate.js';
9
9
  import { toError } from '../../../shared/error-utils.js';
10
10
  import { createQEFlashAttention, } from '../../../integrations/ruvector/wrappers.js';
11
11
  import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
12
+ import { createSafeRecord } from '../../../shared/utils/safe-record.js';
12
13
  const DEFAULT_CONFIG = {
13
14
  minExperiencesForPattern: 5,
14
15
  patternConfidenceThreshold: 0.7,
@@ -943,8 +944,9 @@ Provide:
943
944
  return false;
944
945
  }
945
946
  calculateCentroid(experiences) {
946
- const avgMetrics = {};
947
- const metricCounts = {};
947
+ // Metric names come from stored experiences (#914).
948
+ const avgMetrics = createSafeRecord();
949
+ const metricCounts = createSafeRecord();
948
950
  for (const exp of experiences) {
949
951
  for (const [key, value] of Object.entries(exp.state.metrics)) {
950
952
  avgMetrics[key] = (avgMetrics[key] || 0) + value;
@@ -13,6 +13,7 @@ import { toError } from '../../../shared/error-utils.js';
13
13
  import { safeJsonParse } from '../../../shared/safe-json.js';
14
14
  import { getTestRunnerExecutionError } from '../../../shared/test-runner-verdict.js';
15
15
  import { createVitestJsonReport, needsVitestJsonReportFile } from '../../../shared/vitest-json-report.js';
16
+ import { isJestCommand, jestExactPathPattern, runnerFilePath } from '../../../shared/test-runner-args.js';
16
17
  import { secureRandom } from '../../../shared/utils/crypto-random.js';
17
18
  const DEFAULT_FLAKY_CONFIG = {
18
19
  simulateForTesting: false,
@@ -256,14 +257,19 @@ export class FlakyDetectorService {
256
257
  const runId = uuidv4();
257
258
  const startTime = Date.now();
258
259
  return new Promise((resolve, reject) => {
259
- const baseArgs = [...this.config.testRunnerArgs, file];
260
+ const cwd = this.config.cwd ?? process.cwd();
261
+ // #909: pass an absolute path (never read as a flag); Jest reads it as a
262
+ // regex, so escape and anchor it to select exactly this file.
263
+ const fileArg = isJestCommand([this.config.testRunner, ...this.config.testRunnerArgs])
264
+ ? jestExactPathPattern(file, cwd)
265
+ : runnerFilePath(file, cwd);
266
+ const baseArgs = [...this.config.testRunnerArgs, fileArg];
260
267
  // Vitest 5 writes --reporter=json output to a file, not stdout. Detect
261
268
  // Vitest from the runner command too (testRunner: 'vitest', args: ['run', ...]).
262
269
  const report = needsVitestJsonReportFile([this.config.testRunner, ...baseArgs])
263
270
  ? createVitestJsonReport()
264
271
  : undefined;
265
272
  const args = report ? [...baseArgs, ...report.args] : baseArgs;
266
- const cwd = this.config.cwd ?? process.cwd();
267
273
  const child = spawn(this.config.testRunner, args, {
268
274
  cwd,
269
275
  env: { ...process.env, ...this.config.env },
@@ -5,6 +5,7 @@
5
5
  import { LoggerFactory } from '../../../logging/index.js';
6
6
  import { spawn } from 'node:child_process';
7
7
  import { createVitestJsonReport } from '../../../shared/vitest-json-report.js';
8
+ import { jestExactPathPattern, nameFilterArg, runnerFilePath } from '../../../shared/test-runner-args.js';
8
9
  import { existsSync, readFileSync } from 'node:fs';
9
10
  import { ok, err } from '../../../shared/types/index.js';
10
11
  import { TEST_EXECUTION_CONSTANTS, RETRY_CONSTANTS } from '../../constants.js';
@@ -264,7 +265,7 @@ export class RetryHandlerService {
264
265
  `or configure testRunner in RetryHandlerConfig. Cannot execute retry for: ${testFile}`);
265
266
  }
266
267
  // Build command based on runner
267
- const { command, args, report } = this.buildTestCommand(runner, testFile, testName);
268
+ const { command, args, report } = this.buildTestCommand(runner, testFile, testName, cwd);
268
269
  // Execute the test
269
270
  return this.spawnTestProcess(command, args, cwd, report);
270
271
  }
@@ -334,40 +335,42 @@ export class RetryHandlerService {
334
335
  /**
335
336
  * Build the command and arguments for the test runner
336
337
  */
337
- buildTestCommand(runner, testFile, testName) {
338
+ buildTestCommand(runner, testFile, testName, cwd = this.config.cwd ?? process.cwd()) {
338
339
  const npx = this.config.npxPath;
339
- // These runners interpret name filters as regular expressions, but a
340
- // FailedTest contains the literal assertion name from the previous run.
341
- const namePattern = testName?.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') ?? '';
340
+ // A FailedTest holds the literal assertion name and path from the previous
341
+ // run. Name filters are regex-escaped and passed as --flag=value; file
342
+ // filters are absolute (Jest: escaped and anchored), so neither can be
343
+ // misread as a regex or as a flag when it starts with '-' (#886, #909).
344
+ const filterByName = Boolean(testName) && testName !== testFile;
342
345
  switch (runner) {
343
346
  case 'vitest':
344
- // vitest run --reporter=json testFile -t "testName"
347
+ // vitest run --reporter=json <abs file> --testNamePattern=<name>
345
348
  // --outputFile: Vitest 5 no longer prints the JSON report to stdout.
346
349
  {
347
350
  const report = createVitestJsonReport();
348
- const vitestArgs = ['vitest', 'run', '--reporter=json', testFile];
349
- if (testName && testName !== testFile) {
350
- vitestArgs.push('-t', namePattern);
351
- }
351
+ const vitestArgs = ['vitest', 'run', '--reporter=json', runnerFilePath(testFile, cwd)];
352
+ if (filterByName)
353
+ vitestArgs.push(nameFilterArg('vitest', testName));
352
354
  vitestArgs.push(...report.args);
353
355
  return { command: npx, args: vitestArgs, report };
354
356
  }
355
357
  case 'jest':
356
- // jest --json testFile -t "testName"
358
+ // jest --json --testNamePattern=<name> ^<escaped abs file>$
359
+ // Positional TestPathPatterns work on Jest 29 and 30 (Jest 30 rejects
360
+ // the old --testPathPattern flag).
357
361
  {
358
- const jestArgs = ['jest', '--json', '--testPathPattern', testFile];
359
- if (testName && testName !== testFile) {
360
- jestArgs.push('-t', namePattern);
361
- }
362
+ const jestArgs = ['jest', '--json'];
363
+ if (filterByName)
364
+ jestArgs.push(nameFilterArg('jest', testName));
365
+ jestArgs.push(jestExactPathPattern(testFile, cwd));
362
366
  return { command: npx, args: jestArgs };
363
367
  }
364
368
  case 'mocha':
365
- // mocha --reporter json testFile --grep "testName"
369
+ // mocha --reporter json <abs file> --grep=<name>
366
370
  {
367
- const mochaArgs = ['mocha', '--reporter', 'json', testFile];
368
- if (testName && testName !== testFile) {
369
- mochaArgs.push('--grep', namePattern);
370
- }
371
+ const mochaArgs = ['mocha', '--reporter', 'json', runnerFilePath(testFile, cwd)];
372
+ if (filterByName)
373
+ mochaArgs.push(nameFilterArg('mocha', testName));
371
374
  return { command: npx, args: mochaArgs };
372
375
  }
373
376
  default:
@@ -16,6 +16,7 @@ import { secureRandom, secureRandomInt } from '../../../shared/utils/crypto-rand
16
16
  import { writeQualityEvidence } from '../../quality-assessment/quality-evidence.js';
17
17
  import { getTestRunnerExecutionError, TestRunnerExecutionError } from '../../../shared/test-runner-verdict.js';
18
18
  import { createVitestJsonReport } from '../../../shared/vitest-json-report.js';
19
+ import { jestExactPathPattern, runnerFilePath } from '../../../shared/test-runner-args.js';
19
20
  import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
20
21
  import { terminateTestRunner, trackTestRunnerExit } from '../../../shared/test-runner-process.js';
21
22
  const DEFAULT_CONFIG = {
@@ -481,7 +482,9 @@ Provide:
481
482
  * Build test command based on framework
482
483
  */
483
484
  buildTestCommand(fileOrFiles, framework) {
484
- const files = Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles];
485
+ // #909: absolute paths never start with '-', so a file cannot be read as a
486
+ // flag; Jest's positional patterns are regexes, so escape and anchor them.
487
+ const files = (Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles]).map(file => runnerFilePath(file));
485
488
  const createCoverageDirectory = () => mkdtempSync(join(tmpdir(), 'aqe-test-coverage-'));
486
489
  switch (framework.toLowerCase()) {
487
490
  case 'vitest': {
@@ -507,7 +510,7 @@ Provide:
507
510
  const coverageDirectory = createCoverageDirectory();
508
511
  return {
509
512
  command: 'npx',
510
- args: ['jest', ...files, '--json', '--no-colors', '--testLocationInResults', `--coverageDirectory=${coverageDirectory}`],
513
+ args: ['jest', ...files.map(file => jestExactPathPattern(file)), '--json', '--no-colors', '--testLocationInResults', `--coverageDirectory=${coverageDirectory}`],
511
514
  coverageDirectory,
512
515
  };
513
516
  }
@@ -993,8 +993,11 @@ Return a JSON array of test suggestions, each with: { "name": "test name", "desc
993
993
  if (lang && lang !== 'typescript' && lang !== 'javascript') {
994
994
  return resolveTestFilePath(sourceFile, lang);
995
995
  }
996
- const ext = sourceFile.split('.').pop() || 'ts';
997
- const base = sourceFile.replace(`.${ext}`, '');
996
+ // #936 follow-up: strip only the trailing extension. A first-match
997
+ // replace turned /home/u/my.ts-app/src/a.ts into /home/u/my-app/src/a.ts,
998
+ // pointing the test file at a sibling directory outside the project.
999
+ const ext = fileExt ? fileExt.slice(1) : 'ts';
1000
+ const base = fileExt ? sourceFile.slice(0, -fileExt.length) : sourceFile;
998
1001
  if (framework === 'pytest') {
999
1002
  return `test_${base.split('/').pop()}.py`;
1000
1003
  }
@@ -19,6 +19,7 @@ import { governanceFlags, } from './feature-flags.js';
19
19
  import { proofEnvelopeIntegration, } from './proof-envelope-integration.js';
20
20
  import { getUnifiedMemory } from '../kernel/unified-memory.js';
21
21
  import { toErrorMessage } from '../shared/error-utils.js';
22
+ import { createSafeRecord } from '../shared/utils/safe-record.js';
22
23
  // ============================================================================
23
24
  // Default Configuration
24
25
  // ============================================================================
@@ -274,14 +275,14 @@ export class ComplianceReporter {
274
275
  });
275
276
  // Calculate overall score
276
277
  const overall = this.calculateOverallScore(violations);
277
- // Calculate score by gate
278
- const byGate = {};
278
+ // Calculate score by gate. Gate and agent names are data (#914).
279
+ const byGate = createSafeRecord();
279
280
  const gateViolations = this.groupBy(violations, 'gate');
280
281
  for (const [gate, gateViols] of Object.entries(gateViolations)) {
281
282
  byGate[gate] = this.calculateOverallScore(gateViols);
282
283
  }
283
284
  // Calculate score by agent
284
- const byAgent = {};
285
+ const byAgent = createSafeRecord();
285
286
  const agentViolations = this.groupBy(violations, 'agentId');
286
287
  for (const [agentId, agentViols] of Object.entries(agentViolations)) {
287
288
  if (agentId !== 'undefined') {
@@ -572,13 +573,13 @@ export class ComplianceReporter {
572
573
  for (const v of allViolations) {
573
574
  bySeverity[v.severity]++;
574
575
  }
575
- // Count by gate
576
- const byGate = {};
576
+ // Count by gate. Gate and agent names are data (#914).
577
+ const byGate = createSafeRecord();
577
578
  for (const v of allViolations) {
578
579
  byGate[v.gate] = (byGate[v.gate] || 0) + 1;
579
580
  }
580
581
  // Count by agent
581
- const byAgent = {};
582
+ const byAgent = createSafeRecord();
582
583
  for (const v of allViolations) {
583
584
  if (v.agentId) {
584
585
  byAgent[v.agentId] = (byAgent[v.agentId] || 0) + 1;
@@ -984,7 +985,7 @@ export class ComplianceReporter {
984
985
  * Group violations by a field
985
986
  */
986
987
  groupBy(violations, field) {
987
- const groups = {};
988
+ const groups = createSafeRecord();
988
989
  for (const v of violations) {
989
990
  const key = String(v[field]);
990
991
  if (!groups[key]) {
@@ -19,6 +19,7 @@ import { safeJsonParse } from '../shared/safe-json.js';
19
19
  */
20
20
  import { wasmKernelIntegration, } from './wasm-kernel-integration.js';
21
21
  import { governanceFlags, } from './feature-flags.js';
22
+ import { createSafeRecord } from '../shared/utils/safe-record.js';
22
23
  /**
23
24
  * Genesis envelope hash constant
24
25
  */
@@ -514,7 +515,8 @@ export class ProofEnvelopeIntegration {
514
515
  * Get chain statistics
515
516
  */
516
517
  getProofStats() {
517
- const actionCounts = {};
518
+ // Action names are data, so the buckets must not inherit from Object.prototype (#914).
519
+ const actionCounts = createSafeRecord();
518
520
  const agents = new Set();
519
521
  for (const envelope of this.chain) {
520
522
  agents.add(envelope.agentId);
@@ -259,10 +259,13 @@ export class HooksPhase extends BasePhase {
259
259
  mkdirSync(helpersDir, { recursive: true });
260
260
  }
261
261
  const destPath = join(helpersDir, 'brain-checkpoint.cjs');
262
- // Try to copy from our own installation first
262
+ // Try to copy from our own installation first. The last candidate is this
263
+ // package's own copy (relative to the compiled init module), so a GLOBAL
264
+ // install also refreshes an existing project's helper on re-init (#872).
263
265
  const sourcePaths = [
264
266
  join(projectRoot, '.claude', 'helpers', 'brain-checkpoint.cjs'),
265
267
  join(projectRoot, 'node_modules', 'agentic-qe', '.claude', 'helpers', 'brain-checkpoint.cjs'),
268
+ join(__dirname, '..', '..', '..', '.claude', 'helpers', 'brain-checkpoint.cjs'),
266
269
  ];
267
270
  for (const src of sourcePaths) {
268
271
  if (existsSync(src) && src !== destPath) {
@@ -399,16 +402,39 @@ const AQE_DIR = path.join(PROJECT_ROOT, '.agentic-qe');
399
402
  const RVF_PATH = path.join(AQE_DIR, 'aqe.rvf');
400
403
  const DB_PATH = path.join(AQE_DIR, 'memory.db');
401
404
  const MAX_AGE_HOURS = 24;
402
- const AQE_BIN = process.env.AQE_HOOK_BIN || (process.platform === 'win32' ? 'aqe.cmd' : 'aqe');
405
+ // Windows (#872): never execFile aqe.cmd (EINVAL without a shell); reuse the
406
+ // hook shim's resolver, which runs the AQE bundle via node instead.
407
+ function aqeInvocation() {
408
+ if (process.platform !== 'win32') return { cmd: process.env.AQE_HOOK_BIN || 'aqe', args: [] };
409
+ const shimPath = path.join(__dirname, '..', 'hooks', 'aqe-hook.cjs');
410
+ let src = '';
411
+ try { src = fs.readFileSync(shimPath, 'utf8'); } catch { /* missing */ }
412
+ // An older shim runs its hook main (spawn + exit) when required.
413
+ if (!src.includes('resolveAqeInvocation') || !src.includes('require.main === module')) {
414
+ return { cmd: null, args: [], reason: '.claude/hooks/aqe-hook.cjs is missing or predates #872; re-run aqe init' };
415
+ }
416
+ try {
417
+ return require(shimPath).resolveAqeInvocation({ project: PROJECT_ROOT });
418
+ } catch (e) {
419
+ return { cmd: null, args: [], reason: 'aqe-hook.cjs failed to load: ' + e.message };
420
+ }
421
+ }
403
422
 
404
423
  function log(msg) { process.stderr.write('[brain-checkpoint] ' + msg + '\\n'); }
405
424
 
406
425
  function exportBrain() {
407
426
  if (!fs.existsSync(DB_PATH)) { log('No memory.db, skipping'); return { exported: false }; }
427
+ const aqe = aqeInvocation();
428
+ if (!aqe.cmd) { log('Export skipped: ' + aqe.reason); return { exported: false, reason: aqe.reason }; }
429
+ // Never write through a committed symlink: .agentic-qe must be a real dir, and
430
+ // unlink (not existsSync) drops a planted aqe.rvf link, even a dangling one.
431
+ let st; try { st = fs.lstatSync(AQE_DIR); } catch { /* missing */ }
432
+ if (!st || !st.isDirectory()) { log('Export skipped: .agentic-qe is a symlink'); return { exported: false }; }
433
+ for (const f of [RVF_PATH, RVF_PATH + '.idmap.json']) { try { fs.unlinkSync(f); } catch { /* absent */ } }
408
434
  try {
409
435
  const result = execFileSync(
410
- AQE_BIN, ['brain', 'export', '-o', RVF_PATH, '--format', 'rvf'],
411
- { timeout: 60000, encoding: 'utf-8' }
436
+ aqe.cmd, [...aqe.args, 'brain', 'export', '-o', RVF_PATH, '--format', 'rvf'],
437
+ { timeout: 60000, encoding: 'utf-8', windowsHide: true }
412
438
  );
413
439
  const m = result.match(/Patterns:\\s+(\\d+)/);
414
440
  const p = m ? m[1] : '0';
@@ -109,8 +109,9 @@ export class WorkersPhase extends BasePhase {
109
109
  // Generated by aqe init
110
110
  // Starts the MCP server with background workers enabled
111
111
 
112
- const { existsSync, readFileSync, writeFileSync, appendFileSync } = require('fs');
113
- const { join } = require('path');
112
+ const fs = require('fs');
113
+ const { existsSync, readFileSync } = fs;
114
+ const { join, dirname } = require('path');
114
115
  const { spawn } = require('child_process');
115
116
 
116
117
  const projectRoot = join(__dirname, '..', '..');
@@ -118,8 +119,33 @@ const workersDir = join(projectRoot, '.agentic-qe', 'workers');
118
119
  const pidFile = join(workersDir, 'daemon.pid');
119
120
  const logFile = join(workersDir, 'daemon.log');
120
121
 
121
- // Check if already running
122
- if (existsSync(pidFile)) {
122
+ // A repository can commit .agentic-qe, workers/ or a file in it as a symlink.
123
+ // Never write through one (#970): real directories only, appends only to a
124
+ // regular file (lstat + O_NOFOLLOW where the platform has it), and the pid file
125
+ // is replaced by rename instead of being written in place.
126
+ function isRealDir(d) { try { const s = fs.lstatSync(d); return s.isDirectory() && !s.isSymbolicLink(); } catch { return false; } }
127
+ function isRegularOrAbsent(f) { try { return fs.lstatSync(f).isFile(); } catch (e) { return !!e && e.code === 'ENOENT'; } }
128
+ if (!isRealDir(join(projectRoot, '.agentic-qe')) || !isRealDir(workersDir)) {
129
+ console.error('AQE v3 Worker Daemon not started: .agentic-qe/workers must be a real directory, not a symlink');
130
+ process.exit(1);
131
+ }
132
+ function appendFileSync(file, data) {
133
+ if (!isRegularOrAbsent(file)) return;
134
+ const c = fs.constants;
135
+ let fd;
136
+ try {
137
+ fd = fs.openSync(file, c.O_APPEND | c.O_CREAT | c.O_WRONLY | (c.O_NOFOLLOW || 0), 0o644);
138
+ fs.writeSync(fd, data);
139
+ } catch {} finally { if (fd !== undefined) { try { fs.closeSync(fd); } catch {} } }
140
+ }
141
+ function writeFileSync(file, data) {
142
+ const tmp = file + '.' + process.pid + '.' + Date.now() + '.tmp';
143
+ try { fs.writeFileSync(tmp, data, { flag: 'wx' }); fs.renameSync(tmp, file); }
144
+ catch { try { fs.unlinkSync(tmp); } catch {} }
145
+ }
146
+
147
+ // Check if already running (only trust a regular pid file, never a link target)
148
+ if (existsSync(pidFile) && isRegularOrAbsent(pidFile)) {
123
149
  const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);
124
150
  try { process.kill(pid, 0); console.log('Daemon already running (PID: ' + pid + ')'); process.exit(0); } catch {}
125
151
  }
@@ -161,8 +187,18 @@ if (binCandidate && binCandidate.endsWith('bundle.js')) {
161
187
  mcpCmd = binCandidate;
162
188
  mcpArgs = [];
163
189
  } else {
164
- mcpCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
165
- mcpArgs = ['--yes', 'agentic-qe', 'mcp'];
190
+ // Windows (#872): npx is npx.cmd, which spawn() refuses to start without a
191
+ // shell (EINVAL since CVE-2024-27980). Run npm's bundled npx CLI via node.
192
+ const npxCli = join(dirname(process.execPath), 'node_modules', 'npm', 'bin', 'npx-cli.js');
193
+ if (process.platform === 'win32' && !existsSync(npxCli)) {
194
+ appendFileSync(logFile, '[' + ts + '] ERROR: no AQE MCP bundle found and npx-cli.js is missing next to node.exe; install agentic-qe locally (npm install -D agentic-qe).\\n');
195
+ console.error('AQE v3 Worker Daemon not started: agentic-qe MCP bundle not found (see ' + logFile + ')');
196
+ process.exit(1);
197
+ }
198
+ mcpCmd = process.platform === 'win32' ? process.execPath : 'npx';
199
+ mcpArgs = process.platform === 'win32'
200
+ ? [npxCli, '--yes', 'agentic-qe', 'mcp']
201
+ : ['--yes', 'agentic-qe', 'mcp'];
166
202
  appendFileSync(logFile, '[' + ts + '] WARNING: using npx fallback — daemon.pid will point at the npx wrapper, not the MCP server. \`aqe daemon status\` may misreport liveness after the wrapper exits.\\n');
167
203
  }
168
204
 
@@ -43,7 +43,10 @@ export declare class EmbeddingGenerator {
43
43
  */
44
44
  updateConfig(config: Partial<EmbeddingConfig>): void;
45
45
  /**
46
- * Generate cache key from text and config
46
+ * Generate cache key from text and every config field that changes the vector.
47
+ * A JSON tuple keeps field boundaries intact when the model or text contains
48
+ * ':' (#914, as #863 did for the shared embedding cache). The cache is
49
+ * in-memory only, so no persisted keys need migrating.
47
50
  */
48
51
  private getCacheKey;
49
52
  /**
@@ -240,10 +240,14 @@ export class EmbeddingGenerator {
240
240
  }
241
241
  }
242
242
  /**
243
- * Generate cache key from text and config
243
+ * Generate cache key from text and every config field that changes the vector.
244
+ * A JSON tuple keeps field boundaries intact when the model or text contains
245
+ * ':' (#914, as #863 did for the shared embedding cache). The cache is
246
+ * in-memory only, so no persisted keys need migrating.
244
247
  */
245
248
  getCacheKey(text) {
246
- return `${this.config.model}:${this.config.hyperbolic}:${text}`;
249
+ const { model, hyperbolic, normalize, curvature } = this.config;
250
+ return JSON.stringify([model, hyperbolic, normalize, curvature, text]);
247
251
  }
248
252
  /**
249
253
  * Convert Euclidean embedding to Poincaré ball