agentic-qe 3.15.16 → 3.15.18

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 (539) hide show
  1. package/.claude/helpers/brain-checkpoint.cjs +107 -10
  2. package/.claude/skills/agentic-quality-engineering/SKILL.md +67 -44
  3. package/.claude/skills/brutal-honesty-review/SKILL.md +12 -7
  4. package/.claude/skills/brutal-honesty-review/evals/brutal-honesty-review.yaml +120 -0
  5. package/.claude/skills/brutal-honesty-review/schemas/output.json +9 -3
  6. package/.claude/skills/code-review-quality/SKILL.md +2 -2
  7. package/.claude/skills/holistic-testing-pact/SKILL.md +11 -11
  8. package/.claude/skills/sherlock-review/SKILL.md +4 -2
  9. package/.claude/skills/sherlock-review/evals/sherlock-review.yaml +124 -0
  10. package/.claude/skills/skills-manifest.json +1 -1
  11. package/.claude/skills/technical-writing/SKILL.md +12 -6
  12. package/.claude/skills/technical-writing/evals/technical-writing.yaml +96 -0
  13. package/.opencode/skills/qe-agentic-quality-engineering.yaml +2 -2
  14. package/.opencode/skills/qe-holistic-testing-pact.yaml +2 -2
  15. package/CHANGELOG.md +201 -0
  16. package/assets/skills/agentic-quality-engineering/SKILL.md +67 -44
  17. package/assets/skills/brutal-honesty-review/SKILL.md +12 -8
  18. package/assets/skills/brutal-honesty-review/evals/brutal-honesty-review.yaml +120 -0
  19. package/assets/skills/brutal-honesty-review/schemas/output.json +9 -3
  20. package/assets/skills/code-review-quality/SKILL.md +2 -2
  21. package/assets/skills/holistic-testing-pact/SKILL.md +11 -11
  22. package/assets/skills/sherlock-review/SKILL.md +4 -3
  23. package/assets/skills/sherlock-review/evals/sherlock-review.yaml +124 -0
  24. package/assets/skills/skills-manifest.json +1 -1
  25. package/assets/skills/technical-writing/SKILL.md +12 -6
  26. package/assets/skills/technical-writing/evals/technical-writing.yaml +96 -0
  27. package/dist/cli/brain-commands.d.ts +5 -0
  28. package/dist/cli/brain-commands.js +4 -0
  29. package/dist/cli/bundle.js +6 -6
  30. package/dist/cli/chunks/adapter-WRSDXLOT.js +2 -0
  31. package/dist/cli/chunks/{agent-booster-wasm-45NWEKVS.js → agent-booster-wasm-UFNJNF3M.js} +2 -2
  32. package/dist/cli/chunks/{agent-handler-LVHMYFEF.js → agent-handler-EAYVRJXN.js} +2 -2
  33. package/dist/cli/chunks/{agent-memory-branch-YDWOJFEQ.js → agent-memory-branch-M65C6WAQ.js} +2 -2
  34. package/dist/cli/chunks/aqe-learning-engine-O6NJBCCM.js +2 -0
  35. package/dist/cli/chunks/{arena-ELDZH3CZ.js → arena-2GDICP6R.js} +4 -4
  36. package/dist/cli/chunks/{arena-CZKHXDDS.js → arena-CG3X67OE.js} +2 -2
  37. package/dist/cli/chunks/{audit-5MT4T47Z.js → audit-F4FSPJPL.js} +3 -3
  38. package/dist/cli/chunks/base-J2FXOE77.js +2 -0
  39. package/dist/cli/chunks/{better-sqlite3-6TGYPC2B.js → better-sqlite3-2MCFXW4J.js} +2 -2
  40. package/dist/cli/chunks/brain-handler-WGTJNYNB.js +95 -0
  41. package/dist/cli/chunks/{branch-enumerator-WVILM4SO.js → branch-enumerator-KL7C535H.js} +2 -2
  42. package/dist/cli/chunks/{browser-RX5ALU3H.js → browser-SJEXDVHS.js} +2 -2
  43. package/dist/cli/chunks/browser-workflow-LXGER6ZD.js +2 -0
  44. package/dist/cli/chunks/{chunk-2H4XH6FT.js → chunk-244RKAEP.js} +2 -2
  45. package/dist/cli/chunks/{chunk-SI6DPU5D.js → chunk-27TUMXPD.js} +1 -1
  46. package/dist/cli/chunks/{chunk-YNMJEDN5.js → chunk-2MBYDPCP.js} +2 -2
  47. package/dist/cli/chunks/{chunk-24QHCVX6.js → chunk-2Q6DTBMT.js} +1 -1
  48. package/dist/cli/chunks/{chunk-XWUWX7BV.js → chunk-355MI7RV.js} +13 -13
  49. package/dist/cli/chunks/{chunk-NQXXI77K.js → chunk-3LX5OKBD.js} +2 -2
  50. package/dist/cli/chunks/{chunk-63GMRQ25.js → chunk-3RPDKJGV.js} +1 -1
  51. package/dist/cli/chunks/chunk-3YMIT73A.js +4 -0
  52. package/dist/cli/chunks/{chunk-P3EYRILV.js → chunk-43KUVBSU.js} +2 -2
  53. package/dist/cli/chunks/chunk-477FKXSS.js +2 -0
  54. package/dist/cli/chunks/{chunk-HGWXF45W.js → chunk-4BIMTRRX.js} +1 -1
  55. package/dist/cli/chunks/{chunk-SSUAAX3F.js → chunk-4CVNVBX5.js} +2 -2
  56. package/dist/cli/chunks/{chunk-5V3TI2LG.js → chunk-4HL3SD4A.js} +1 -1
  57. package/dist/cli/chunks/{chunk-KKU2QGSJ.js → chunk-4PEG4DU2.js} +2 -2
  58. package/dist/cli/chunks/{chunk-J4ELZNLY.js → chunk-4QSQKFED.js} +2 -2
  59. package/dist/cli/chunks/chunk-53ZBETYR.js +16 -0
  60. package/dist/cli/chunks/{chunk-7TE5ONQQ.js → chunk-544KDWL4.js} +1 -1
  61. package/dist/cli/chunks/chunk-54RCGMLB.js +8 -0
  62. package/dist/cli/chunks/{chunk-KU2AUFGX.js → chunk-5AGXIZQ5.js} +2 -2
  63. package/dist/cli/chunks/{chunk-LQLPB2T6.js → chunk-5M24X6W7.js} +2 -2
  64. package/dist/cli/chunks/{chunk-YU2BDRSD.js → chunk-5O5T4LEU.js} +1 -1
  65. package/dist/cli/chunks/{chunk-NAEWCFQT.js → chunk-5RFXX4IF.js} +2 -2
  66. package/dist/cli/chunks/{chunk-MD43XRX5.js → chunk-62MLAQRJ.js} +1 -1
  67. package/dist/cli/chunks/{chunk-PEQDY4BO.js → chunk-6D6TGL2E.js} +2 -2
  68. package/dist/cli/chunks/{chunk-IOYG4VFL.js → chunk-6IHZDSDL.js} +2 -2
  69. package/dist/cli/chunks/{chunk-C5FP5GW3.js → chunk-6P3Y45QL.js} +2 -2
  70. package/dist/cli/chunks/{chunk-4LQFBY5L.js → chunk-6TEVM3X3.js} +10 -10
  71. package/dist/cli/chunks/{chunk-YPBSUGMI.js → chunk-7XTUKKRA.js} +1 -1
  72. package/dist/cli/chunks/chunk-A3GDX6UF.js +2 -0
  73. package/dist/cli/chunks/{chunk-HLUXXCHF.js → chunk-A5YTKKNA.js} +1 -1
  74. package/dist/cli/chunks/{chunk-Y4PFUMOU.js → chunk-ADNGZAT2.js} +1 -1
  75. package/dist/cli/chunks/{chunk-KNSRL6NO.js → chunk-AWQAE3SW.js} +2 -2
  76. package/dist/cli/chunks/{chunk-BY5OF7OH.js → chunk-AXDBQFR4.js} +2 -2
  77. package/dist/cli/chunks/{chunk-525CFDUE.js → chunk-AXVD7O3F.js} +2 -2
  78. package/dist/cli/chunks/{chunk-JHQCRRJI.js → chunk-B52ULNYO.js} +2 -2
  79. package/dist/cli/chunks/chunk-B6S4FC7M.js +3 -0
  80. package/dist/cli/chunks/{chunk-AJMJNQMP.js → chunk-BDVFSMOQ.js} +1 -1
  81. package/dist/cli/chunks/{chunk-DXD6K2ZP.js → chunk-BGXXMX3Y.js} +2 -2
  82. package/dist/cli/chunks/{chunk-EK7OLYOZ.js → chunk-BKMQQY5T.js} +2 -2
  83. package/dist/cli/chunks/{chunk-VWPM27GU.js → chunk-BN2FROBQ.js} +2 -2
  84. package/dist/cli/chunks/{chunk-J7I6PABJ.js → chunk-BO6EQNOC.js} +2 -2
  85. package/dist/cli/chunks/{chunk-4D4DENG6.js → chunk-BOVAKCDC.js} +2 -2
  86. package/dist/cli/chunks/{chunk-ZFL436FN.js → chunk-BSXKZDKO.js} +2 -2
  87. package/dist/cli/chunks/{chunk-J442IZLE.js → chunk-C5QVJ5XQ.js} +1 -1
  88. package/dist/cli/chunks/{chunk-ZB3LEFYG.js → chunk-CFQLLF3D.js} +2 -2
  89. package/dist/cli/chunks/{chunk-UHEOGZLX.js → chunk-DUCVLT3F.js} +7 -7
  90. package/dist/cli/chunks/{chunk-TVGI32MB.js → chunk-E4RMJCGA.js} +3 -3
  91. package/dist/cli/chunks/{chunk-TIUKLYAI.js → chunk-EONDCWY4.js} +1 -1
  92. package/dist/cli/chunks/{chunk-ZJH5MU2I.js → chunk-F4AGNKL2.js} +2 -2
  93. package/dist/cli/chunks/{chunk-N7HL5PHH.js → chunk-F6YD3BOW.js} +1 -1
  94. package/dist/cli/chunks/{chunk-5VZL4UVN.js → chunk-FQRS7WVA.js} +2 -2
  95. package/dist/cli/chunks/{chunk-SHKOCGNK.js → chunk-FT24SSDG.js} +2 -2
  96. package/dist/cli/chunks/chunk-FV4YNSAJ.js +5 -0
  97. package/dist/cli/chunks/{chunk-KXCLACFG.js → chunk-FVDM3X42.js} +2 -2
  98. package/dist/cli/chunks/{chunk-32BPDLRZ.js → chunk-FVH7TXWU.js} +2 -2
  99. package/dist/cli/chunks/{chunk-72XSEQMW.js → chunk-FWR5QY37.js} +2 -2
  100. package/dist/cli/chunks/chunk-FYINK2B7.js +6 -0
  101. package/dist/cli/chunks/{chunk-5JZRZI4S.js → chunk-GGISVPOZ.js} +2 -2
  102. package/dist/cli/chunks/{chunk-5LAVKGLH.js → chunk-GPIJIZJQ.js} +2 -2
  103. package/dist/cli/chunks/{chunk-5QO3R3TU.js → chunk-GXEVOT5F.js} +2 -2
  104. package/dist/cli/chunks/{chunk-IHRXZZQM.js → chunk-GZ4VB5RI.js} +1 -1
  105. package/dist/cli/chunks/chunk-HBDSCYSK.js +2 -0
  106. package/dist/cli/chunks/{chunk-GSKMOPL7.js → chunk-HGG4HR7C.js} +2 -2
  107. package/dist/cli/chunks/{chunk-AR67RJPY.js → chunk-HSCKWWO2.js} +2 -2
  108. package/dist/cli/chunks/{chunk-6XXZDV2C.js → chunk-HSQ3GUYJ.js} +2 -2
  109. package/dist/cli/chunks/{chunk-AAMLQ2LF.js → chunk-HZQBW5EM.js} +3 -3
  110. package/dist/cli/chunks/{chunk-O5W3FIO6.js → chunk-IGIYANVT.js} +2 -2
  111. package/dist/cli/chunks/{chunk-C6D5AHBO.js → chunk-IPWMSXBF.js} +2 -2
  112. package/dist/cli/chunks/{chunk-NDJ7P2EP.js → chunk-IWVNC7VY.js} +1 -1
  113. package/dist/cli/chunks/{chunk-FDDC72IA.js → chunk-IZODXKZD.js} +2 -2
  114. package/dist/cli/chunks/{chunk-NO3IV5Q5.js → chunk-J2MT2OJV.js} +1 -1
  115. package/dist/cli/chunks/{chunk-GQ6TUIKY.js → chunk-JKIJVVSP.js} +1 -1
  116. package/dist/cli/chunks/{chunk-LE4QJREF.js → chunk-JMRDT2XK.js} +1 -1
  117. package/dist/cli/chunks/{chunk-2YZ4G6NW.js → chunk-JR2UMTKG.js} +1 -1
  118. package/dist/cli/chunks/{chunk-RJIEG3NA.js → chunk-K6CH4CFF.js} +2 -2
  119. package/dist/cli/chunks/{chunk-5NNNEWLS.js → chunk-K7KW5QB5.js} +81 -88
  120. package/dist/cli/chunks/chunk-KFCQP434.js +2 -0
  121. package/dist/cli/chunks/{chunk-A5GBXCP5.js → chunk-KH4T6STG.js} +2 -2
  122. package/dist/cli/chunks/{chunk-VMDFFTCK.js → chunk-KJBYZO57.js} +1 -1
  123. package/dist/cli/chunks/{chunk-GJYHWYXR.js → chunk-KP4OKOKV.js} +2 -2
  124. package/dist/cli/chunks/chunk-L2MBKVSE.js +2 -0
  125. package/dist/cli/chunks/{chunk-XIQW7EFL.js → chunk-L3IPUIT3.js} +2 -2
  126. package/dist/cli/chunks/{chunk-W5HQUIML.js → chunk-L7PSU2YN.js} +2 -2
  127. package/dist/cli/chunks/{chunk-6DPYNAOK.js → chunk-LA3JPGQA.js} +2 -2
  128. package/dist/cli/chunks/{chunk-5PBLPQ5T.js → chunk-LC2QRN7V.js} +14 -13
  129. package/dist/cli/chunks/{chunk-SSYAQZXA.js → chunk-LHY7TMTM.js} +2 -2
  130. package/dist/cli/chunks/{chunk-QQWBWEJS.js → chunk-LLQ2UMF6.js} +3 -3
  131. package/dist/cli/chunks/{chunk-DTMAS2GB.js → chunk-LOJ7OO6W.js} +2 -2
  132. package/dist/cli/chunks/{chunk-32GN3JKR.js → chunk-LPUSH3VF.js} +1 -1
  133. package/dist/cli/chunks/{chunk-SDLWKRVL.js → chunk-LSEC2BU7.js} +2 -2
  134. package/dist/cli/chunks/{chunk-IOKYCMTJ.js → chunk-LTGB7OIU.js} +2 -2
  135. package/dist/cli/chunks/{chunk-6ZBXSOX6.js → chunk-LUG7YNVZ.js} +2 -2
  136. package/dist/cli/chunks/{chunk-CAKMOVZ6.js → chunk-LWAFRYKE.js} +2 -2
  137. package/dist/cli/chunks/{chunk-FLNAW7C4.js → chunk-M24ZAZ4U.js} +2 -2
  138. package/dist/cli/chunks/{chunk-L2DWPVNJ.js → chunk-MKRKRXTX.js} +1 -1
  139. package/dist/cli/chunks/{chunk-YTHTQPWR.js → chunk-MNNLONAD.js} +1 -1
  140. package/dist/cli/chunks/{chunk-V5NHZV7S.js → chunk-MQM37KAR.js} +2 -2
  141. package/dist/cli/chunks/{chunk-PPUZWYUG.js → chunk-MSX2OHYT.js} +2 -2
  142. package/dist/cli/chunks/{chunk-YRAX7SFJ.js → chunk-MVYQRVLP.js} +2 -2
  143. package/dist/cli/chunks/{chunk-QVDCVD5D.js → chunk-MZC5WM2P.js} +2 -2
  144. package/dist/cli/chunks/{chunk-S75SOOZL.js → chunk-MZRBNBB3.js} +2 -2
  145. package/dist/cli/chunks/{chunk-FL64OUBA.js → chunk-N3KQU4UC.js} +2 -2
  146. package/dist/cli/chunks/{chunk-G5RHFBAY.js → chunk-NKU3FFM4.js} +2 -2
  147. package/dist/cli/chunks/chunk-O5EWFR76.js +2 -0
  148. package/dist/cli/chunks/{chunk-63ZKI4PX.js → chunk-O5RDHD5T.js} +2 -2
  149. package/dist/cli/chunks/chunk-O6UWIXME.js +3 -0
  150. package/dist/cli/chunks/{chunk-HCH4Y6XX.js → chunk-OA4EQDC4.js} +2 -2
  151. package/dist/cli/chunks/{chunk-QPEOLAAS.js → chunk-OBCXCRXK.js} +1 -1
  152. package/dist/cli/chunks/{chunk-6ICX3FEG.js → chunk-OHU5P25N.js} +22 -22
  153. package/dist/cli/chunks/{chunk-GFWHUQSF.js → chunk-OOSV2RIA.js} +2 -2
  154. package/dist/cli/chunks/{chunk-MO55CVMT.js → chunk-OW23N2Y5.js} +14 -14
  155. package/dist/cli/chunks/{chunk-M7WJCTG3.js → chunk-OXOO3YDL.js} +2 -2
  156. package/dist/cli/chunks/{chunk-KQYJ4VQ5.js → chunk-OYGKSSSI.js} +1 -1
  157. package/dist/cli/chunks/chunk-PGO46IIW.js +2 -0
  158. package/dist/cli/chunks/{chunk-NVEWF4JV.js → chunk-PZOYQHWS.js} +1 -1
  159. package/dist/cli/chunks/{chunk-IESR7TNB.js → chunk-Q2BZSG7Z.js} +2 -2
  160. package/dist/cli/chunks/{chunk-XIIQ5QTT.js → chunk-Q7V722K5.js} +2 -2
  161. package/dist/cli/chunks/{chunk-F742SZAX.js → chunk-QZU6M5IO.js} +2 -2
  162. package/dist/cli/chunks/{chunk-PINSJCM3.js → chunk-R55Y76SJ.js} +1 -1
  163. package/dist/cli/chunks/{chunk-5B5QPCNU.js → chunk-RMEQYJPU.js} +4 -4
  164. package/dist/cli/chunks/{chunk-ZQ2XW3IP.js → chunk-RTYXFXTI.js} +2 -2
  165. package/dist/cli/chunks/{chunk-DVYHMDFR.js → chunk-SJF3O4FX.js} +374 -371
  166. package/dist/cli/chunks/{chunk-AG2EWGXS.js → chunk-SOUS7Z2H.js} +2 -2
  167. package/dist/cli/chunks/{chunk-3HD7E6HN.js → chunk-SRVNR3R3.js} +2 -2
  168. package/dist/cli/chunks/{chunk-KITOPKRG.js → chunk-SU3SXMVG.js} +2 -2
  169. package/dist/cli/chunks/chunk-SWGPLXWW.js +32 -0
  170. package/dist/cli/chunks/{chunk-ZR2TKVXQ.js → chunk-TRB3EVH3.js} +2 -2
  171. package/dist/cli/chunks/{chunk-OCV2XEWQ.js → chunk-TVBDUMKT.js} +2 -2
  172. package/dist/cli/chunks/{chunk-IOQ6ZQ5W.js → chunk-TWTXPSFU.js} +1 -1
  173. package/dist/cli/chunks/{chunk-CJSHWQXP.js → chunk-ULYUVUL2.js} +2 -2
  174. package/dist/cli/chunks/{chunk-PHT5N7SC.js → chunk-UNTBVJ5X.js} +2 -2
  175. package/dist/cli/chunks/{chunk-LKTTUHLF.js → chunk-UQAA4PHU.js} +2 -2
  176. package/dist/cli/chunks/{chunk-SR52XP5F.js → chunk-UWSJVKTE.js} +1 -1
  177. package/dist/cli/chunks/{chunk-L6QSTQME.js → chunk-V2LJ54KP.js} +2 -2
  178. package/dist/cli/chunks/{chunk-FBDVGRSC.js → chunk-VCCTTKP3.js} +7 -7
  179. package/dist/cli/chunks/{chunk-YLMNVLDK.js → chunk-VEGUYUVS.js} +1 -1
  180. package/dist/cli/chunks/{chunk-ASEOFRIG.js → chunk-VUQPVWNK.js} +2 -2
  181. package/dist/cli/chunks/{chunk-VXFLJNCA.js → chunk-VVGUE2T2.js} +2 -2
  182. package/dist/cli/chunks/{chunk-4NFQLP6R.js → chunk-W5ASDHJQ.js} +1 -1
  183. package/dist/cli/chunks/{chunk-I7MQIM2U.js → chunk-WGXT5NWQ.js} +1 -1
  184. package/dist/cli/chunks/chunk-WJN3V7QB.js +7 -0
  185. package/dist/cli/chunks/chunk-WPCRQIIF.js +29 -0
  186. package/dist/cli/chunks/{chunk-SASBO5Y5.js → chunk-WQNLXUWA.js} +6 -6
  187. package/dist/cli/chunks/{chunk-5SPCGMBB.js → chunk-WZVRMKG2.js} +2 -2
  188. package/dist/cli/chunks/{chunk-MI5MFHRA.js → chunk-X27IUWTD.js} +2 -2
  189. package/dist/cli/chunks/{chunk-HJ6ZGVTB.js → chunk-X4B345B6.js} +2 -2
  190. package/dist/cli/chunks/{chunk-HVRRLYX6.js → chunk-X5I2Y4VO.js} +2 -2
  191. package/dist/cli/chunks/{chunk-SUDMM5SO.js → chunk-X7IQIFTS.js} +2 -2
  192. package/dist/cli/chunks/chunk-XJN3RKUD.js +3 -0
  193. package/dist/cli/chunks/{chunk-E3D4GPLP.js → chunk-XQMGXTHJ.js} +3 -3
  194. package/dist/cli/chunks/{chunk-67Z5R7RJ.js → chunk-XTSAMB2Q.js} +2 -2
  195. package/dist/cli/chunks/{chunk-KVF4NXGQ.js → chunk-XZLIF4O2.js} +2 -2
  196. package/dist/cli/chunks/{chunk-EA4YQVKS.js → chunk-Y4LSEOZ3.js} +1 -1
  197. package/dist/cli/chunks/{chunk-OAEE6JWQ.js → chunk-Y4YN2RXR.js} +2 -2
  198. package/dist/cli/chunks/{chunk-CEYSYSK5.js → chunk-YDI56L35.js} +2 -2
  199. package/dist/cli/chunks/{chunk-JDIYMZCQ.js → chunk-YFILS5D5.js} +2 -2
  200. package/dist/cli/chunks/{chunk-GAHNO6JJ.js → chunk-YISDX6WB.js} +2 -2
  201. package/dist/cli/chunks/{chunk-AGRV5B3T.js → chunk-YP2GHQSV.js} +2 -2
  202. package/dist/cli/chunks/{chunk-UNGBRZDK.js → chunk-YSX756AM.js} +4 -4
  203. package/dist/cli/chunks/{chunk-BEKDKVQT.js → chunk-YWANOASW.js} +2 -2
  204. package/dist/cli/chunks/{chunk-JQ3DYUMS.js → chunk-YYIJLG7S.js} +2 -2
  205. package/dist/cli/chunks/{chunk-CRPIYUTJ.js → chunk-Z7SD7LXM.js} +2 -2
  206. package/dist/cli/chunks/{chunk-U2A7NHZA.js → chunk-ZDWD73UF.js} +2 -2
  207. package/dist/cli/chunks/{chunk-WP4RETKG.js → chunk-ZFT3RLA4.js} +2 -2
  208. package/dist/cli/chunks/{chunk-VJCIEHEF.js → chunk-ZNTHX5G3.js} +1 -1
  209. package/dist/cli/chunks/{chunk-PF7RBAYL.js → chunk-ZS27R7VL.js} +2 -2
  210. package/dist/cli/chunks/{chunk-24OX5TQJ.js → chunk-ZXHHHR7K.js} +1 -1
  211. package/dist/cli/chunks/{ci-MFUR4CWV.js → ci-N5MOMNXH.js} +2 -2
  212. package/dist/cli/chunks/{ci-config-PNDLQ6XV.js → ci-config-6L2ROQCW.js} +2 -2
  213. package/dist/cli/chunks/{ci-output-PFZ4M7NC.js → ci-output-DSRBYEIK.js} +2 -2
  214. package/dist/cli/chunks/{circuit-breaker-5HH6NLZN.js → circuit-breaker-VRPTNBL7.js} +2 -2
  215. package/dist/cli/chunks/{claude-flow-setup-QCKYLGLC.js → claude-flow-setup-4YFG3FU5.js} +2 -2
  216. package/dist/cli/chunks/client-I3L6BKRQ.js +2 -0
  217. package/dist/cli/chunks/{cline-installer-EASVPFXR.js → cline-installer-7RGYJWGN.js} +2 -2
  218. package/dist/cli/chunks/{code-UJXDVYRK.js → code-ISC6NW2K.js} +3 -3
  219. package/dist/cli/chunks/{code-index-extractor-BZJ3UDP4.js → code-index-extractor-2FID75YV.js} +2 -2
  220. package/dist/cli/chunks/{codex-installer-XSQZUVOZ.js → codex-installer-DZ7OG6KM.js} +2 -2
  221. package/dist/cli/chunks/{completions-OWOOJFI2.js → completions-SM3LICWK.js} +2 -2
  222. package/dist/cli/chunks/{complexity-analyzer-KP5TOHDT.js → complexity-analyzer-ZWD2CTAD.js} +2 -2
  223. package/dist/cli/chunks/{continuedev-installer-IFKQXLHM.js → continuedev-installer-AGASOA26.js} +2 -2
  224. package/dist/cli/chunks/copilot-installer-CLPZYTQC.js +3 -0
  225. package/dist/cli/chunks/core-handlers-5EFOJ37H.js +2 -0
  226. package/dist/cli/chunks/{cost-tracker-MMDDNKZB.js → cost-tracker-7PIGQYDV.js} +2 -2
  227. package/dist/cli/chunks/{coverage-LUH2B7NT.js → coverage-T2GEBTYS.js} +9 -9
  228. package/dist/cli/chunks/cross-domain-router-65WJAKVD.js +2 -0
  229. package/dist/cli/chunks/{cursor-installer-4YLM5GWM.js → cursor-installer-KXBID4MB.js} +2 -2
  230. package/dist/cli/chunks/daemon-43MXIVH3.js +18 -0
  231. package/dist/cli/chunks/{daemon-MZKVM4CJ.js → daemon-VAMJLQJ5.js} +3 -3
  232. package/dist/cli/chunks/{dag-attention-scheduler-X4CYW665.js → dag-attention-scheduler-UBP4VHTA.js} +2 -2
  233. package/dist/cli/chunks/{detect-7BM2XINO.js → detect-QWFIQRKI.js} +2 -2
  234. package/dist/cli/chunks/{dist-node-Y5APLEYB.js → dist-node-I2GICS3W.js} +2 -2
  235. package/dist/cli/chunks/{domain-handler-X3ZRJNAH.js → domain-handler-Z66ISB2A.js} +2 -2
  236. package/dist/cli/chunks/{domain-plugins-2UW5KQJB.js → domain-plugins-KHMD3FKT.js} +2 -2
  237. package/dist/cli/chunks/{domain-transfer-35W4CIBV.js → domain-transfer-JWGNNA6K.js} +2 -2
  238. package/dist/cli/chunks/dream-VQ2PZCVR.js +2 -0
  239. package/dist/cli/chunks/embed-and-insert-pattern-F5P5B6JX.js +3 -0
  240. package/dist/cli/chunks/{embedding-space-SBM2MZD2.js → embedding-space-KHG6TITM.js} +2 -2
  241. package/dist/cli/chunks/{eval-4QA2SROK.js → eval-43OHU7EI.js} +2 -2
  242. package/dist/cli/chunks/{experience-capture-middleware-Z6BF6KYM.js → experience-capture-middleware-KXD47H6P.js} +3 -3
  243. package/dist/cli/chunks/{fast-paths-FIORX6GN.js → fast-paths-6D75D5KD.js} +2 -2
  244. package/dist/cli/chunks/{feature-flags-6LYI2T4G.js → feature-flags-IE35Y55N.js} +2 -2
  245. package/dist/cli/chunks/{feature-flags-ZOO7LMIC.js → feature-flags-OYYHY7LS.js} +2 -2
  246. package/dist/cli/chunks/file-discovery-LGBTY3ID.js +2 -0
  247. package/dist/cli/chunks/{fleet-7WF53H4F.js → fleet-AGVJMFGD.js} +16 -16
  248. package/dist/cli/chunks/{gnn-wrapper-KJ6B7BRM.js → gnn-wrapper-5L66A7LW.js} +2 -2
  249. package/dist/cli/chunks/{heartbeat-handler-DEKKMOVW.js → heartbeat-handler-2BY6YYOT.js} +5 -5
  250. package/dist/cli/chunks/heartbeat-scheduler-3DU3M5AT.js +2 -0
  251. package/dist/cli/chunks/hnsw-adapter-N2IMSRPV.js +2 -0
  252. package/dist/cli/chunks/hnsw-index-DVU7TTJE.js +2 -0
  253. package/dist/cli/chunks/{hnsw-legacy-bridge-L27WS27N.js → hnsw-legacy-bridge-RYMWFNAH.js} +2 -2
  254. package/dist/cli/chunks/{hnswlib-node-4YOQC6L4.js → hnswlib-node-GG47HP2P.js} +2 -2
  255. package/dist/cli/chunks/{hooks-TAOKV4EJ.js → hooks-FQNACS24.js} +10 -10
  256. package/dist/cli/chunks/hybrid-backend-AS2PNHOD.js +2 -0
  257. package/dist/cli/chunks/{hypergraph-engine-BODRJLHL.js → hypergraph-engine-6BYNJQEP.js} +2 -2
  258. package/dist/cli/chunks/{hypergraph-handler-RKMYJNTU.js → hypergraph-handler-CYTAXZKJ.js} +3 -3
  259. package/dist/cli/chunks/impact-analyzer-Y4OONLFP.js +2 -0
  260. package/dist/cli/chunks/{init-guard-MXHSLSB2.js → init-guard-METTAV5O.js} +2 -2
  261. package/dist/cli/chunks/{init-handler-HUE57IFW.js → init-handler-GFT74U5Y.js} +6 -6
  262. package/dist/cli/chunks/init-wizard-HLNUBJQN.js +2 -0
  263. package/dist/cli/chunks/kernel-XKFWCL7Y.js +2 -0
  264. package/dist/cli/chunks/{kilocode-installer-S333IKYQ.js → kilocode-installer-GZV2D3FF.js} +2 -2
  265. package/dist/cli/chunks/{kiro-installer-WM5DLQWC.js → kiro-installer-Q4ZXUFC7.js} +2 -2
  266. package/dist/cli/chunks/knowledge-graph-CNL77CSZ.js +2 -0
  267. package/dist/cli/chunks/{learning-LNHMQLH5.js → learning-WA2QEYL7.js} +35 -34
  268. package/dist/cli/chunks/{llm-router-EWFXYZZR.js → llm-router-GRTCHWH7.js} +4 -4
  269. package/dist/cli/chunks/llm-router-service-UIYTYKP6.js +2 -0
  270. package/dist/cli/chunks/{load-FGYGWVDK.js → load-WXN3Q7Y5.js} +2 -2
  271. package/dist/cli/chunks/load-test-PXLW4A5B.js +2 -0
  272. package/dist/cli/chunks/{mcp-2FHNAAOM.js → mcp-LIQCPSJN.js} +2 -2
  273. package/dist/cli/chunks/{memory-DZMQ73AB.js → memory-OP6CHRFH.js} +5 -5
  274. package/dist/cli/chunks/memory-backend-XYOSO73Q.js +2 -0
  275. package/dist/cli/chunks/memory-handlers-PQFYVNVG.js +2 -0
  276. package/dist/cli/chunks/{multi-model-executor-6F2UAEUW.js → multi-model-executor-H54DEVRZ.js} +2 -2
  277. package/dist/cli/chunks/{opencode-installer-XY3BGOTZ.js → opencode-installer-BSQV6UAT.js} +2 -2
  278. package/dist/cli/chunks/{orchestrator-B4CNKUOS.js → orchestrator-TJDPQ4VL.js} +122 -35
  279. package/dist/cli/chunks/pattern-null-store-BKGTQFNF.js +2 -0
  280. package/dist/cli/chunks/{pattern-usage-recorder-R4GUFNMD.js → pattern-usage-recorder-FOVS4M5L.js} +2 -2
  281. package/dist/cli/chunks/{pipeline-FG5RKVRO.js → pipeline-4AY2ZIC6.js} +2 -2
  282. package/dist/cli/chunks/{platform-3BT4KEVJ.js → platform-FCSITYMR.js} +2 -2
  283. package/dist/cli/chunks/{plugin-WI4RIN7O.js → plugin-E56TV5S2.js} +2 -2
  284. package/dist/cli/chunks/{prime-radiant-advanced-wasm-7ECDNQFS.js → prime-radiant-advanced-wasm-ACOPC533.js} +2 -2
  285. package/dist/cli/chunks/project-root-MPX7CN2C.js +2 -0
  286. package/dist/cli/chunks/protocol-executor-CRQOCC4A.js +2 -0
  287. package/dist/cli/chunks/{protocol-handler-WNODKPGW.js → protocol-handler-KRVXF4LS.js} +2 -2
  288. package/dist/cli/chunks/{prove-5RHAEPYZ.js → prove-KMFPSKGD.js} +2 -2
  289. package/dist/cli/chunks/qe-reasoning-bank-UEGQ3O7F.js +2 -0
  290. package/dist/cli/chunks/{quality-WPHR7BGQ.js → quality-6DBI3HLB.js} +2 -2
  291. package/dist/cli/chunks/{quality-gate-4RKTEZMX.js → quality-gate-3ROZMEIL.js} +3 -3
  292. package/dist/cli/chunks/queen-coordinator-32574XSG.js +2 -0
  293. package/dist/cli/chunks/real-embeddings-MIGZNKK3.js +2 -0
  294. package/dist/cli/chunks/{ref-validation-TPAWHOHH.js → ref-validation-EYIP7DHW.js} +2 -2
  295. package/dist/cli/chunks/{roocode-installer-7AVHFNDI.js → roocode-installer-IGGZHR2Y.js} +2 -2
  296. package/dist/cli/chunks/router-CZJY5WX6.js +2 -0
  297. package/dist/cli/chunks/routing-feedback-RC3UBNFX.js +2 -0
  298. package/dist/cli/chunks/{routing-handler-YKEDVJSH.js → routing-handler-BWNHBYDC.js} +2 -2
  299. package/dist/cli/chunks/{ruvector-commands-JUAMM354.js → ruvector-commands-PXIHF432.js} +2 -2
  300. package/dist/cli/chunks/rvf-dual-writer-OG7OV2AK.js +2 -0
  301. package/dist/cli/chunks/rvf-migration-adapter-THYMW7ZO.js +2 -0
  302. package/dist/cli/chunks/rvf-migration-coordinator-3H6CLFU7.js +2 -0
  303. package/dist/cli/chunks/rvf-native-adapter-6JQJIKKW.js +2 -0
  304. package/dist/cli/chunks/{rvf-store-integrity-VJDUIRTX.js → rvf-store-integrity-CVB3NMSL.js} +2 -2
  305. package/dist/cli/chunks/safe-db-QFKCVTIJ.js +2 -0
  306. package/dist/cli/chunks/schedule-6JLVMMYB.js +2 -0
  307. package/dist/cli/chunks/scheduler-3MPZRMJD.js +2 -0
  308. package/dist/cli/chunks/{security-ORDN3RD2.js → security-DCRGOTWU.js} +3 -3
  309. package/dist/cli/chunks/{shared-rvf-adapter-CF4BCIO7.js → shared-rvf-adapter-GKD74QUB.js} +2 -2
  310. package/dist/cli/chunks/{shared-rvf-dual-writer-C32UBR6D.js → shared-rvf-dual-writer-HVAAVEOH.js} +2 -2
  311. package/dist/cli/chunks/sqlite-persistence-LGTIKAEX.js +2 -0
  312. package/dist/cli/chunks/{standalone-memory-OXRJYZXN.js → standalone-memory-O7O2U5N4.js} +2 -2
  313. package/dist/cli/chunks/{status-handler-BCX5D4HY.js → status-handler-BQTPJJTL.js} +2 -2
  314. package/dist/cli/chunks/{structural-health-LFG7RUU6.js → structural-health-4H6J4OHK.js} +2 -2
  315. package/dist/cli/chunks/sync-DJ4TF6QX.js +2 -0
  316. package/dist/cli/chunks/{sync-YJEE2K2L.js → sync-WW5TAVYW.js} +2 -2
  317. package/dist/cli/chunks/{task-handler-6LXKPTXJ.js → task-handler-HEM4IEOW.js} +2 -2
  318. package/dist/cli/chunks/{task-handlers-CILP36I7.js → task-handlers-JRA3NXIR.js} +3 -3
  319. package/dist/cli/chunks/test-772ZXVG2.js +34 -0
  320. package/dist/cli/chunks/test-runner-process-XGF2U3NG.js +2 -0
  321. package/dist/cli/chunks/{test-scheduling-ISI2O4Q5.js → test-scheduling-4TRB7LZ7.js} +3 -3
  322. package/dist/cli/chunks/token-bootstrap-CICBIJ7T.js +2 -0
  323. package/dist/cli/chunks/{token-usage-XOC5KG7S.js → token-usage-B7PEKE2G.js} +2 -2
  324. package/dist/cli/chunks/{transformers-LSLQAARK.js → transformers-V7X7BDZX.js} +2 -2
  325. package/dist/cli/chunks/tree-sitter-wasm-parser-OXPFKFZS.js +2 -0
  326. package/dist/cli/chunks/{types-5BLCGLCR.js → types-AHHTUY3I.js} +2 -2
  327. package/dist/cli/chunks/unified-memory-GUR3IUI6.js +2 -0
  328. package/dist/cli/chunks/unified-memory-hnsw-NJP2F2RY.js +2 -0
  329. package/dist/cli/chunks/unified-persistence-NILBWXDP.js +2 -0
  330. package/dist/cli/chunks/{upgrade-RQJYLK3J.js → upgrade-DZ4DLUQ5.js} +2 -2
  331. package/dist/cli/chunks/{validate-QBHWXXCK.js → validate-4DTLIDJE.js} +2 -2
  332. package/dist/cli/chunks/{validate-swarm-IKXBKFB5.js → validate-swarm-A26UFVIS.js} +2 -2
  333. package/dist/cli/chunks/visual-security-YECYZ27X.js +2 -0
  334. package/dist/cli/chunks/{web-tree-sitter-ZF6FIE5R.js → web-tree-sitter-F2C7QRYT.js} +2 -2
  335. package/dist/cli/chunks/{windsurf-installer-HQGDZT5D.js → windsurf-installer-OOBTDA6W.js} +2 -2
  336. package/dist/cli/chunks/{witness-chain-DCHCAMSQ.js → witness-chain-KGFZJP32.js} +2 -2
  337. package/dist/cli/chunks/witness-chain-LYBXFLJB.js +2 -0
  338. package/dist/cli/chunks/witness-chain-repair-CNTXOGPN.js +2 -0
  339. package/dist/cli/chunks/{witness-chain-verifier-PX2OQ6XT.js → witness-chain-verifier-OB7ZZOI3.js} +2 -2
  340. package/dist/cli/chunks/{witness-key-manager-RXYQNFJB.js → witness-key-manager-YCKGKGQI.js} +2 -2
  341. package/dist/cli/chunks/{workflow-FBKCA4H6.js → workflow-PRERHWKY.js} +4 -4
  342. package/dist/cli/chunks/workflow-orchestrator-UIBGWCU3.js +2 -0
  343. package/dist/cli/chunks/wrappers-L4UY4V63.js +2 -0
  344. package/dist/cli/commands/coverage.js +4 -1
  345. package/dist/cli/commands/learning-prune.js +9 -1
  346. package/dist/cli/commands/test.js +26 -4
  347. package/dist/cli/handlers/brain-handler.js +32 -2
  348. package/dist/cli/handlers/heartbeat-handler.js +3 -1
  349. package/dist/cli/utils/coverage-data.js +5 -1
  350. package/dist/cli/utils/coverage-verdict.d.ts +10 -2
  351. package/dist/cli/utils/coverage-verdict.js +23 -8
  352. package/dist/cli/utils/fleet-operation.js +9 -3
  353. package/dist/coordination/handlers/code-intelligence-handlers.js +17 -3
  354. package/dist/coordination/handlers/coverage-handlers.js +22 -9
  355. package/dist/coordination/handlers/coverage-target.d.ts +22 -2
  356. package/dist/coordination/handlers/coverage-target.js +45 -9
  357. package/dist/coordination/handlers/handler-utils.d.ts +19 -0
  358. package/dist/coordination/handlers/handler-utils.js +22 -8
  359. package/dist/coordination/handlers/test-execution-handlers.js +64 -20
  360. package/dist/coordination/protocols/code-intelligence-index.js +6 -3
  361. package/dist/coordination/protocols/learning-consolidation-archive.d.ts +6 -3
  362. package/dist/coordination/protocols/learning-consolidation-archive.js +4 -3
  363. package/dist/coordination/workflow-builtin.js +1 -0
  364. package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts +8 -3
  365. package/dist/domains/code-intelligence/services/semantic-analyzer.js +39 -25
  366. package/dist/domains/code-intelligence/services/text-relevance.d.ts +32 -0
  367. package/dist/domains/code-intelligence/services/text-relevance.js +63 -0
  368. package/dist/domains/defect-intelligence/interfaces.d.ts +2 -0
  369. package/dist/domains/defect-intelligence/prediction-history.d.ts +15 -1
  370. package/dist/domains/defect-intelligence/prediction-history.js +63 -7
  371. package/dist/domains/defect-intelligence/services/defect-predictor.d.ts +1 -0
  372. package/dist/domains/defect-intelligence/services/defect-predictor.js +33 -13
  373. package/dist/domains/learning-optimization/coordinator.js +17 -10
  374. package/dist/domains/learning-optimization/domain-ranking.d.ts +26 -0
  375. package/dist/domains/learning-optimization/domain-ranking.js +28 -0
  376. package/dist/domains/learning-optimization/interfaces.d.ts +5 -0
  377. package/dist/domains/learning-optimization/pattern-archive.d.ts +55 -8
  378. package/dist/domains/learning-optimization/pattern-archive.js +90 -17
  379. package/dist/domains/learning-optimization/pattern-consolidation.js +18 -2
  380. package/dist/domains/learning-optimization/pattern-merge.d.ts +26 -0
  381. package/dist/domains/learning-optimization/pattern-merge.js +127 -0
  382. package/dist/domains/learning-optimization/services/learning-coordinator.js +21 -35
  383. package/dist/domains/test-execution/coordinator.d.ts +3 -1
  384. package/dist/domains/test-execution/coordinator.js +13 -4
  385. package/dist/domains/test-execution/interfaces.d.ts +5 -0
  386. package/dist/domains/test-execution/plugin.js +2 -0
  387. package/dist/domains/test-execution/services/flaky-detector.d.ts +9 -1
  388. package/dist/domains/test-execution/services/flaky-detector.js +26 -8
  389. package/dist/domains/test-execution/services/retry-handler.d.ts +7 -1
  390. package/dist/domains/test-execution/services/retry-handler.js +44 -5
  391. package/dist/domains/test-execution/services/runner-test-cases.d.ts +2 -0
  392. package/dist/domains/test-execution/services/runner-test-cases.js +7 -3
  393. package/dist/domains/test-execution/services/test-executor.d.ts +5 -1
  394. package/dist/domains/test-execution/services/test-executor.js +85 -17
  395. package/dist/init/copilot-installer.d.ts +6 -0
  396. package/dist/init/copilot-installer.js +37 -17
  397. package/dist/init/init-wizard-steps.js +3 -1
  398. package/dist/init/phases/07-hooks.js +97 -10
  399. package/dist/init/platform-config-generator.d.ts +10 -0
  400. package/dist/init/platform-config-generator.js +26 -1
  401. package/dist/integrations/embeddings/cache/EmbeddingCache.js +1 -1
  402. package/dist/integrations/ruvector/brain-rvf-exporter.d.ts +16 -1
  403. package/dist/integrations/ruvector/brain-rvf-exporter.js +18 -32
  404. package/dist/integrations/ruvector/brain-rvf-richness.d.ts +75 -0
  405. package/dist/integrations/ruvector/brain-rvf-richness.js +127 -0
  406. package/dist/kernel/unified-memory-migration.js +1 -1
  407. package/dist/kernel/unified-memory.d.ts +8 -0
  408. package/dist/kernel/unified-memory.js +13 -0
  409. package/dist/learning/checkpoint-shrink-ack.d.ts +25 -0
  410. package/dist/learning/checkpoint-shrink-ack.js +57 -0
  411. package/dist/learning/dream/dream-engine.d.ts +44 -3
  412. package/dist/learning/dream/dream-engine.js +6 -2
  413. package/dist/learning/embedder-endpoint-client.d.ts +45 -0
  414. package/dist/learning/embedder-endpoint-client.js +98 -3
  415. package/dist/learning/embedder-identity-store.js +3 -1
  416. package/dist/learning/embedding-space-legacy-adoption.d.ts +53 -0
  417. package/dist/learning/embedding-space-legacy-adoption.js +115 -0
  418. package/dist/learning/embedding-space-registry.d.ts +90 -0
  419. package/dist/learning/embedding-space-registry.js +181 -0
  420. package/dist/learning/experience-capture.d.ts +3 -1
  421. package/dist/learning/experience-capture.js +15 -5
  422. package/dist/learning/experience-space-verification.d.ts +2 -0
  423. package/dist/learning/experience-space-verification.js +3 -2
  424. package/dist/learning/learning-retention.js +4 -0
  425. package/dist/learning/pattern-promotion.d.ts +7 -0
  426. package/dist/learning/pattern-promotion.js +64 -12
  427. package/dist/learning/real-embeddings.d.ts +3 -0
  428. package/dist/learning/real-embeddings.js +73 -11
  429. package/dist/learning/rvf-pattern-store.js +6 -1
  430. package/dist/mcp/bundle.js +558 -537
  431. package/dist/mcp/handlers/domain-handler-configs.d.ts +3 -0
  432. package/dist/mcp/handlers/domain-handler-configs.js +1 -0
  433. package/dist/mcp/handlers/heartbeat-handlers.d.ts +4 -2
  434. package/dist/mcp/protocol-server.js +1 -1
  435. package/dist/mcp/tools/learning-optimization/optimize.d.ts +6 -1
  436. package/dist/mcp/tools/learning-optimization/optimize.js +20 -11
  437. package/dist/planning/goap-planner.js +4 -0
  438. package/dist/planning/plan-executor.js +6 -2
  439. package/dist/shared/embeddings/index.d.ts +2 -2
  440. package/dist/shared/embeddings/index.js +1 -1
  441. package/dist/shared/embeddings/nomic-embedder.d.ts +8 -2
  442. package/dist/shared/embeddings/nomic-embedder.js +19 -11
  443. package/dist/shared/embeddings/ollama-client.d.ts +28 -2
  444. package/dist/shared/embeddings/ollama-client.js +84 -22
  445. package/dist/shared/embeddings/types.d.ts +15 -0
  446. package/dist/shared/embeddings/types.js +4 -0
  447. package/dist/shared/git/git-analyzer.d.ts +30 -11
  448. package/dist/shared/git/git-analyzer.js +95 -48
  449. package/dist/shared/io/confined-read.d.ts +32 -7
  450. package/dist/shared/io/confined-read.js +58 -25
  451. package/dist/shared/io/file-reader.js +4 -1
  452. package/dist/shared/pytest-junit-report.d.ts +93 -0
  453. package/dist/shared/pytest-junit-report.js +241 -0
  454. package/dist/shared/safe-db.d.ts +1 -1
  455. package/dist/shared/safe-db.js +20 -5
  456. package/dist/shared/sqlite-journal-mode.d.ts +39 -0
  457. package/dist/shared/sqlite-journal-mode.js +53 -0
  458. package/dist/shared/test-runner-project.d.ts +51 -1
  459. package/dist/shared/test-runner-project.js +140 -25
  460. package/dist/sync/claude-flow-bridge.js +1 -1
  461. package/dist/sync/readers/sqlite-reader.js +3 -4
  462. package/dist/sync/writers/sqlite-writer.js +1 -1
  463. package/dist/workers/interfaces.d.ts +2 -2
  464. package/dist/workers/quality-daemon/git-watcher.d.ts +8 -0
  465. package/dist/workers/quality-daemon/git-watcher.js +54 -12
  466. package/dist/workers/quality-daemon/index.js +1 -1
  467. package/dist/workers/quality-daemon/priority-queue.d.ts +2 -1
  468. package/dist/workers/workers/defect-predictor.d.ts +9 -4
  469. package/dist/workers/workers/defect-predictor.js +98 -37
  470. package/package.json +1 -1
  471. package/dist/cli/chunks/adapter-6CQ2PIP5.js +0 -2
  472. package/dist/cli/chunks/aqe-learning-engine-73RR52VS.js +0 -2
  473. package/dist/cli/chunks/base-SMCMMVGP.js +0 -2
  474. package/dist/cli/chunks/brain-handler-HQWZFO52.js +0 -95
  475. package/dist/cli/chunks/browser-workflow-A2MEZ66K.js +0 -2
  476. package/dist/cli/chunks/chunk-CGGUM2YJ.js +0 -3
  477. package/dist/cli/chunks/chunk-D6COXLYE.js +0 -8
  478. package/dist/cli/chunks/chunk-EGYE5UPQ.js +0 -2
  479. package/dist/cli/chunks/chunk-IUBJVHNB.js +0 -3
  480. package/dist/cli/chunks/chunk-KL7OKSU2.js +0 -4
  481. package/dist/cli/chunks/chunk-KPRCB5LT.js +0 -7
  482. package/dist/cli/chunks/chunk-LRSX2FJM.js +0 -2
  483. package/dist/cli/chunks/chunk-M4FRQ4TE.js +0 -12
  484. package/dist/cli/chunks/chunk-MAFQV4U4.js +0 -16
  485. package/dist/cli/chunks/chunk-NZU4ACBZ.js +0 -2
  486. package/dist/cli/chunks/chunk-RV74I3YO.js +0 -3
  487. package/dist/cli/chunks/chunk-SJ6Y4725.js +0 -5
  488. package/dist/cli/chunks/chunk-UE5ZOZR2.js +0 -2
  489. package/dist/cli/chunks/chunk-VSIKHWZ4.js +0 -29
  490. package/dist/cli/chunks/chunk-YAPLJR7K.js +0 -2
  491. package/dist/cli/chunks/client-MHQRTZM4.js +0 -2
  492. package/dist/cli/chunks/copilot-installer-IGJ6KGQY.js +0 -3
  493. package/dist/cli/chunks/core-handlers-UAK3LLJE.js +0 -2
  494. package/dist/cli/chunks/cross-domain-router-WTRZQPNQ.js +0 -2
  495. package/dist/cli/chunks/daemon-CAVZ7OFV.js +0 -18
  496. package/dist/cli/chunks/dream-EJY24JN6.js +0 -2
  497. package/dist/cli/chunks/embed-and-insert-pattern-COG4C7ZI.js +0 -3
  498. package/dist/cli/chunks/file-discovery-UZSFSS4V.js +0 -2
  499. package/dist/cli/chunks/heartbeat-scheduler-NVR356I7.js +0 -2
  500. package/dist/cli/chunks/hnsw-adapter-LFMPLUJU.js +0 -2
  501. package/dist/cli/chunks/hnsw-index-POCPMVJH.js +0 -2
  502. package/dist/cli/chunks/hybrid-backend-4STAO7CV.js +0 -2
  503. package/dist/cli/chunks/impact-analyzer-3VIIISBQ.js +0 -2
  504. package/dist/cli/chunks/init-wizard-PL6QN6RQ.js +0 -2
  505. package/dist/cli/chunks/kernel-CCDWT7KS.js +0 -2
  506. package/dist/cli/chunks/knowledge-graph-KFOMEN3H.js +0 -2
  507. package/dist/cli/chunks/llm-router-service-7NBE2EX6.js +0 -2
  508. package/dist/cli/chunks/load-test-UNZUWY3F.js +0 -2
  509. package/dist/cli/chunks/memory-backend-DFGKWA2Q.js +0 -2
  510. package/dist/cli/chunks/memory-handlers-MP426XRJ.js +0 -2
  511. package/dist/cli/chunks/pattern-null-store-SSVF5TE5.js +0 -2
  512. package/dist/cli/chunks/project-root-BEANNYWU.js +0 -2
  513. package/dist/cli/chunks/protocol-executor-FQVIHXZ7.js +0 -2
  514. package/dist/cli/chunks/qe-reasoning-bank-5TFYSE24.js +0 -2
  515. package/dist/cli/chunks/queen-coordinator-Y2OUL7IN.js +0 -2
  516. package/dist/cli/chunks/real-embeddings-OXLYU7JW.js +0 -2
  517. package/dist/cli/chunks/router-EP34O3KB.js +0 -2
  518. package/dist/cli/chunks/routing-feedback-FJCRKXNG.js +0 -2
  519. package/dist/cli/chunks/rvf-dual-writer-ILITJSFG.js +0 -2
  520. package/dist/cli/chunks/rvf-migration-adapter-XF6W4C2N.js +0 -2
  521. package/dist/cli/chunks/rvf-migration-coordinator-CMKG56AR.js +0 -2
  522. package/dist/cli/chunks/rvf-native-adapter-7YFW6S4Y.js +0 -2
  523. package/dist/cli/chunks/safe-db-TCAU4FUT.js +0 -2
  524. package/dist/cli/chunks/schedule-NB5KV435.js +0 -2
  525. package/dist/cli/chunks/scheduler-JKXGKVK6.js +0 -2
  526. package/dist/cli/chunks/sqlite-persistence-IXCNZRTW.js +0 -2
  527. package/dist/cli/chunks/sync-OSF7C2NL.js +0 -2
  528. package/dist/cli/chunks/test-SD457QJ6.js +0 -34
  529. package/dist/cli/chunks/test-runner-process-VKD65QQU.js +0 -2
  530. package/dist/cli/chunks/token-bootstrap-VUELSBOS.js +0 -2
  531. package/dist/cli/chunks/tree-sitter-wasm-parser-YAIPHRIL.js +0 -2
  532. package/dist/cli/chunks/unified-memory-GI76TXFV.js +0 -2
  533. package/dist/cli/chunks/unified-memory-hnsw-GXJ5BTZO.js +0 -2
  534. package/dist/cli/chunks/unified-persistence-OP7FDQPD.js +0 -2
  535. package/dist/cli/chunks/visual-security-GZ2MOKWB.js +0 -2
  536. package/dist/cli/chunks/witness-chain-P3XXXA62.js +0 -2
  537. package/dist/cli/chunks/witness-chain-repair-PUX2NFDL.js +0 -2
  538. package/dist/cli/chunks/workflow-orchestrator-P2APAJAA.js +0 -2
  539. package/dist/cli/chunks/wrappers-TWSKBTWD.js +0 -2
@@ -0,0 +1,93 @@
1
+ /**
2
+ * #1248: running pytest and reading its JUnit XML report.
3
+ *
4
+ * pytest is started as `<python> -m pytest <files> --junitxml=<file>`, with
5
+ * the report in a temporary directory owned by the run, so the result never
6
+ * depends on the console summary. The interpreter is `AQE_PYTHON` when set,
7
+ * otherwise `python` when it is on PATH, otherwise `python3`.
8
+ *
9
+ * The report is read with a small parser for the XML pytest writes (one or
10
+ * more `<testsuite>` elements holding `<testcase>` elements, each with an
11
+ * optional `<failure>`, `<error>` or `<skipped>` child). Counts come from the
12
+ * test cases themselves, so they always match the per-test list. An expected
13
+ * failure (xfail) is reported by pytest as skipped and counted as skipped.
14
+ *
15
+ * A run is only a result when pytest finished its tests: exit code 5 (no
16
+ * tests collected), 2 (interrupted, for example by a collection error),
17
+ * 3 (internal error) and 4 (usage error), or a missing report (pytest not
18
+ * installed for the interpreter), are runner errors, never a pass.
19
+ */
20
+ import { TestRunnerExecutionError } from './test-runner-verdict.js';
21
+ import { Result } from './types';
22
+ /** True for a Python test file, which only pytest can run. */
23
+ export declare function isPythonTestFile(file: string): boolean;
24
+ /** The Python interpreter that runs pytest. */
25
+ export declare function resolvePythonCommand(env?: NodeJS.ProcessEnv): string;
26
+ /** Environment for a pytest process: no ANSI colour in its output or report. */
27
+ export declare const PYTEST_ENV: Readonly<Record<string, string>>;
28
+ /** Command and arguments that run `targets` (paths or node ids) with pytest. */
29
+ export declare function pytestCommand(targets: readonly string[], reportPath: string, env?: NodeJS.ProcessEnv): {
30
+ command: string;
31
+ args: string[];
32
+ };
33
+ /** A per-run JUnit report location, read back after pytest exits. */
34
+ export interface PytestJunitReport {
35
+ /** Absolute path pytest writes the report to. */
36
+ readonly path: string;
37
+ /** Arguments that point pytest at the report (already in pytestCommand). */
38
+ readonly args: readonly string[];
39
+ /** The report text; undefined when pytest wrote none. Malformed reports throw. */
40
+ read(stdout?: string): string | undefined;
41
+ /** Remove the temporary report directory. Safe to call more than once. */
42
+ cleanup(): void;
43
+ }
44
+ export declare function createPytestJunitReport(): PytestJunitReport;
45
+ export type PytestCaseStatus = 'passed' | 'failed' | 'error' | 'skipped';
46
+ /** One `<testcase>` of a pytest JUnit report. */
47
+ export interface PytestJunitCase {
48
+ classname: string;
49
+ name: string;
50
+ status: PytestCaseStatus;
51
+ /** Duration in milliseconds, when reported. */
52
+ duration?: number;
53
+ /** The failure, error or skip message attribute. */
54
+ message?: string;
55
+ /** The failure or error body (traceback). */
56
+ details?: string;
57
+ }
58
+ /** The test cases of a pytest JUnit XML report, in report order. */
59
+ export declare function parsePytestJunitXml(xml: string): PytestJunitCase[];
60
+ /**
61
+ * The run file a test case belongs to, and its name inside that file
62
+ * (`TestClass::test_name[param]`, the node id without the file). The class
63
+ * name is the module's dotted path relative to pytest's rootdir followed by
64
+ * any classes, so the file is the one whose path ends with the longest
65
+ * leading part of it.
66
+ */
67
+ export declare function locatePytestCase(testCase: Pick<PytestJunitCase, 'classname' | 'name'>, files: readonly string[]): {
68
+ file: string;
69
+ name: string;
70
+ };
71
+ /** One test of a finished pytest run. */
72
+ export interface PytestTest {
73
+ name: string;
74
+ file: string;
75
+ status: 'passed' | 'failed' | 'skipped';
76
+ duration?: number;
77
+ /** Failure or error text for a failed test. */
78
+ failureMessage?: string;
79
+ }
80
+ export interface PytestRun {
81
+ total: number;
82
+ passed: number;
83
+ failed: number;
84
+ skipped: number;
85
+ tests: PytestTest[];
86
+ }
87
+ /**
88
+ * The result of a finished pytest run, or the runner error that kept it from
89
+ * being one. `report` is the JUnit XML text, undefined when pytest wrote none.
90
+ * A test case that errored (in a fixture, say) counts as a failed test.
91
+ */
92
+ export declare function pytestRunFromReport(report: string | undefined, files: readonly string[], exitCode: number | null, output: string, python?: string): Result<PytestRun, TestRunnerExecutionError>;
93
+ //# sourceMappingURL=pytest-junit-report.d.ts.map
@@ -0,0 +1,241 @@
1
+ /**
2
+ * #1248: running pytest and reading its JUnit XML report.
3
+ *
4
+ * pytest is started as `<python> -m pytest <files> --junitxml=<file>`, with
5
+ * the report in a temporary directory owned by the run, so the result never
6
+ * depends on the console summary. The interpreter is `AQE_PYTHON` when set,
7
+ * otherwise `python` when it is on PATH, otherwise `python3`.
8
+ *
9
+ * The report is read with a small parser for the XML pytest writes (one or
10
+ * more `<testsuite>` elements holding `<testcase>` elements, each with an
11
+ * optional `<failure>`, `<error>` or `<skipped>` child). Counts come from the
12
+ * test cases themselves, so they always match the per-test list. An expected
13
+ * failure (xfail) is reported by pytest as skipped and counted as skipped.
14
+ *
15
+ * A run is only a result when pytest finished its tests: exit code 5 (no
16
+ * tests collected), 2 (interrupted, for example by a collection error),
17
+ * 3 (internal error) and 4 (usage error), or a missing report (pytest not
18
+ * installed for the interpreter), are runner errors, never a pass.
19
+ */
20
+ import { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from 'node:fs';
21
+ import { tmpdir } from 'node:os';
22
+ import * as path from 'node:path';
23
+ import { capDiagnostics, getTestRunnerExecutionError, TestRunnerExecutionError } from './test-runner-verdict.js';
24
+ import { ok, err } from './types/index.js';
25
+ /** True for a Python test file, which only pytest can run. */
26
+ export function isPythonTestFile(file) {
27
+ return /\.py$/i.test(file);
28
+ }
29
+ function onPath(command, env) {
30
+ const names = process.platform === 'win32' ? [`${command}.exe`, `${command}.cmd`, command] : [command];
31
+ for (const dir of (env.PATH ?? env.Path ?? '').split(path.delimiter)) {
32
+ if (!dir)
33
+ continue;
34
+ for (const name of names) {
35
+ try {
36
+ if (statSync(path.join(dir, name)).isFile())
37
+ return true;
38
+ }
39
+ catch {
40
+ // Not in this directory.
41
+ }
42
+ }
43
+ }
44
+ return false;
45
+ }
46
+ /** The Python interpreter that runs pytest. */
47
+ export function resolvePythonCommand(env = process.env) {
48
+ const configured = env.AQE_PYTHON?.trim();
49
+ if (configured)
50
+ return configured;
51
+ if (onPath('python', env))
52
+ return 'python';
53
+ return onPath('python3', env) ? 'python3' : 'python';
54
+ }
55
+ /** Environment for a pytest process: no ANSI colour in its output or report. */
56
+ export const PYTEST_ENV = { PY_COLORS: '0' };
57
+ /** Command and arguments that run `targets` (paths or node ids) with pytest. */
58
+ export function pytestCommand(targets, reportPath, env = process.env) {
59
+ return {
60
+ command: resolvePythonCommand(env),
61
+ // No colour: runners are started with FORCE_COLOR set, which pytest reads
62
+ // as "force colour" (even in its report). PY_COLORS=0 (PYTEST_ENV) wins
63
+ // over FORCE_COLOR; --color=no covers the console output.
64
+ args: ['-m', 'pytest', ...targets, `--junitxml=${reportPath}`, '--color=no'],
65
+ };
66
+ }
67
+ export function createPytestJunitReport() {
68
+ const dir = mkdtempSync(path.join(tmpdir(), 'aqe-pytest-report-'));
69
+ const reportPath = path.join(dir, 'junit.xml');
70
+ let cleaned = false;
71
+ return {
72
+ path: reportPath,
73
+ args: [],
74
+ read: () => {
75
+ if (!existsSync(reportPath))
76
+ return undefined;
77
+ const text = readFileSync(reportPath, 'utf-8');
78
+ if (!/<testsuite\b/.test(text))
79
+ throw new TestRunnerExecutionError('The current pytest JUnit report is malformed.');
80
+ return text;
81
+ },
82
+ cleanup: () => {
83
+ if (cleaned)
84
+ return;
85
+ cleaned = true;
86
+ try {
87
+ rmSync(dir, { recursive: true, force: true });
88
+ }
89
+ catch {
90
+ // Best effort: a leftover temp dir is not worth failing a test run over.
91
+ }
92
+ },
93
+ };
94
+ }
95
+ function unescapeXml(text) {
96
+ return text.replace(/&(#x[0-9a-f]+|#\d+|lt|gt|amp|quot|apos);/gi, (_, entity) => {
97
+ const lower = entity.toLowerCase();
98
+ if (lower === 'lt')
99
+ return '<';
100
+ if (lower === 'gt')
101
+ return '>';
102
+ if (lower === 'amp')
103
+ return '&';
104
+ if (lower === 'quot')
105
+ return '"';
106
+ if (lower === 'apos')
107
+ return '\'';
108
+ const code = lower.startsWith('#x') ? parseInt(lower.slice(2), 16) : parseInt(lower.slice(1), 10);
109
+ return Number.isFinite(code) && code >= 0 && code <= 0x10ffff ? String.fromCodePoint(code) : '';
110
+ });
111
+ }
112
+ function attributes(text) {
113
+ const attrs = {};
114
+ for (const match of text.matchAll(/([\w:.-]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g)) {
115
+ attrs[match[1]] = unescapeXml(match[2] ?? match[3] ?? '');
116
+ }
117
+ return attrs;
118
+ }
119
+ /** The test cases of a pytest JUnit XML report, in report order. */
120
+ export function parsePytestJunitXml(xml) {
121
+ if (!/<testsuite\b/.test(xml))
122
+ throw new Error('Not a JUnit XML report: no <testsuite> element.');
123
+ const cases = [];
124
+ const testcase = /<testcase\b((?:[^>"']|"[^"]*"|'[^']*')*?)(?:\/>|>([\s\S]*?)<\/testcase>)/g;
125
+ for (const match of xml.matchAll(testcase)) {
126
+ const attrs = attributes(match[1]);
127
+ const body = match[2] ?? '';
128
+ // An error (setup/teardown) outranks a failure in the same test case.
129
+ const child = (tag) => body.match(new RegExp(`<${tag}\\b((?:[^>"']|"[^"]*"|'[^']*')*?)(?:\\/>|>([\\s\\S]*?)<\\/${tag}>)`));
130
+ const error = child('error');
131
+ const failure = child('failure');
132
+ const skipped = child('skipped');
133
+ const outcome = error ?? failure ?? skipped;
134
+ const status = error ? 'error' : failure ? 'failed' : skipped ? 'skipped' : 'passed';
135
+ const seconds = Number.parseFloat(attrs.time ?? '');
136
+ const message = outcome ? attributes(outcome[1]).message : undefined;
137
+ const details = outcome?.[2] !== undefined ? unescapeXml(outcome[2]).trim() : undefined;
138
+ cases.push({
139
+ classname: attrs.classname ?? '',
140
+ name: attrs.name ?? '',
141
+ status,
142
+ ...(Number.isFinite(seconds) ? { duration: Math.round(seconds * 1000) } : {}),
143
+ ...(message ? { message } : {}),
144
+ ...(details ? { details } : {}),
145
+ });
146
+ }
147
+ return cases;
148
+ }
149
+ /** A collection error is reported as an error case with no class name. */
150
+ function isCollectionError(testCase) {
151
+ return testCase.status === 'error' && (testCase.classname === '' || testCase.message === 'collection failure');
152
+ }
153
+ function pathSegments(file) {
154
+ return file.replace(/\.py$/i, '').split(/[\\/]+/).filter(Boolean);
155
+ }
156
+ /**
157
+ * The run file a test case belongs to, and its name inside that file
158
+ * (`TestClass::test_name[param]`, the node id without the file). The class
159
+ * name is the module's dotted path relative to pytest's rootdir followed by
160
+ * any classes, so the file is the one whose path ends with the longest
161
+ * leading part of it.
162
+ */
163
+ export function locatePytestCase(testCase, files) {
164
+ const dotted = testCase.classname ? testCase.classname.split('.') : [];
165
+ let best;
166
+ for (const file of files) {
167
+ const segments = pathSegments(file);
168
+ for (let length = Math.min(dotted.length, segments.length); length > 0; length--) {
169
+ const tail = segments.slice(segments.length - length);
170
+ if (tail.every((segment, index) => segment === dotted[index])) {
171
+ if (!best || length > best.matched)
172
+ best = { file, matched: length };
173
+ break;
174
+ }
175
+ }
176
+ }
177
+ if (!best) {
178
+ return {
179
+ file: files.length === 1 ? files[0] : files.join(', '),
180
+ name: testCase.classname ? `${testCase.classname}::${testCase.name}` : testCase.name,
181
+ };
182
+ }
183
+ return { file: best.file, name: [...dotted.slice(best.matched), testCase.name].join('::') };
184
+ }
185
+ const PYTEST_EXIT_REASONS = {
186
+ 2: 'was interrupted (for example by a collection error)',
187
+ 3: 'hit an internal error',
188
+ 4: 'rejected its command line',
189
+ 5: 'collected no tests',
190
+ };
191
+ /**
192
+ * The result of a finished pytest run, or the runner error that kept it from
193
+ * being one. `report` is the JUnit XML text, undefined when pytest wrote none.
194
+ * A test case that errored (in a fixture, say) counts as a failed test.
195
+ */
196
+ export function pytestRunFromReport(report, files, exitCode, output, python = resolvePythonCommand()) {
197
+ const label = files.join(', ');
198
+ if (report === undefined) {
199
+ const notInstalled = /No module named pytest/.test(output);
200
+ return err(new TestRunnerExecutionError(`pytest wrote no JUnit report for ${label} (exit code ${exitCode ?? 'unknown'}).` +
201
+ (notInstalled
202
+ ? ` pytest is not installed for '${python}'; install it, or set AQE_PYTHON to an interpreter that has it.`
203
+ : ` Check that '${python} -m pytest' runs; set AQE_PYTHON to choose the interpreter.`) +
204
+ (output.trim() ? `\n${capDiagnostics(output.trim())}` : '')));
205
+ }
206
+ let cases;
207
+ try {
208
+ cases = parsePytestJunitXml(report);
209
+ }
210
+ catch (error) {
211
+ return err(new TestRunnerExecutionError(`Could not read the pytest JUnit report for ${label}: ${error instanceof Error ? error.message : String(error)}`));
212
+ }
213
+ const collectionErrors = cases.filter(isCollectionError);
214
+ const exitReason = exitCode !== null ? PYTEST_EXIT_REASONS[exitCode] : undefined;
215
+ if (exitReason || collectionErrors.length > 0) {
216
+ const reasons = collectionErrors.map(c => `${c.name}: ${c.details ?? c.message ?? 'collection failure'}`);
217
+ return err(new TestRunnerExecutionError(`pytest ${exitReason ?? 'reported a collection error'} for ${label} (exit code ${exitCode ?? 'unknown'}).` +
218
+ `\n${capDiagnostics([...reasons, output.trim()].filter(Boolean).join('\n'))}`));
219
+ }
220
+ const tests = cases.map(testCase => {
221
+ const { file, name } = locatePytestCase(testCase, files);
222
+ const failed = testCase.status === 'failed' || testCase.status === 'error';
223
+ const failureMessage = failed
224
+ ? [testCase.message, testCase.details].filter(Boolean).join('\n') || 'Test failed'
225
+ : undefined;
226
+ return {
227
+ name, file,
228
+ status: failed ? 'failed' : testCase.status === 'skipped' ? 'skipped' : 'passed',
229
+ ...(testCase.duration !== undefined ? { duration: testCase.duration } : {}),
230
+ ...(failureMessage ? { failureMessage } : {}),
231
+ };
232
+ });
233
+ const passed = tests.filter(t => t.status === 'passed').length;
234
+ const failed = tests.filter(t => t.status === 'failed').length;
235
+ const skipped = tests.filter(t => t.status === 'skipped').length;
236
+ const executionError = getTestRunnerExecutionError('pytest', label, exitCode, { passed, failed, skipped }, output);
237
+ if (executionError)
238
+ return err(executionError);
239
+ return ok({ total: tests.length, passed, failed, skipped, tests });
240
+ }
241
+ //# sourceMappingURL=pytest-junit-report.js.map
@@ -16,7 +16,7 @@ export interface SafeDbOptions {
16
16
  fileMustExist?: boolean;
17
17
  /** Busy timeout in ms (default: 5000) */
18
18
  busyTimeout?: number;
19
- /** Enable WAL mode (default: true for writable, false for readonly) */
19
+ /** Enable WAL mode (default: true for writable; always ignored for readonly) */
20
20
  walMode?: boolean;
21
21
  /**
22
22
  * M3.2: on a malformed/corrupt existing DB, auto-restore the newest verified
@@ -12,6 +12,7 @@ import Database from 'better-sqlite3';
12
12
  import { basename } from 'node:path';
13
13
  import { attemptAutoRestore } from './db-recovery.js';
14
14
  import { withNativeModuleRemedy } from './native-module-errors.js';
15
+ import { setJournalModeWithRetry } from './sqlite-journal-mode.js';
15
16
  /**
16
17
  * Open a SQLite database with safe defaults that prevent corruption.
17
18
  *
@@ -95,8 +96,11 @@ export function openDatabase(dbPath, opts) {
95
96
  // 2026-07-07), so continuing to write in WAL would trade a loud outage for
96
97
  // silent corruption. Availability is not worth that; the message below
97
98
  // carries the exact command that finds the real holder.
99
+ //
100
+ // Concurrent openers racing the same one-time switch (#1164) are retried
101
+ // within busyTimeout first; only contention that outlasts it fails closed.
98
102
  try {
99
- db.pragma(`journal_mode = ${desired}`);
103
+ setJournalModeWithRetry(db, desired, busyTimeout);
100
104
  }
101
105
  catch (err) {
102
106
  const code = err?.code;
@@ -135,11 +139,22 @@ export function openDatabase(dbPath, opts) {
135
139
  }
136
140
  }
137
141
  }
138
- else if (walMode) {
142
+ else if (walMode && !readonly) {
139
143
  // WAL mode for writable connections prevents corruption from concurrent
140
- // writers. Readonly connections inherit WAL from the DB file but we set it
141
- // explicitly to be safe in case the DB was created without WAL.
142
- db.pragma('journal_mode = WAL');
144
+ // writers. Readonly connections inherit the file's journal mode and must
145
+ // not switch it: that is a write and fails with SQLITE_READONLY on a
146
+ // rollback-journal file (#1320), so `walMode` is ignored for readonly opens.
147
+ //
148
+ // #1164: switching a rollback-journal file to WAL upgrades a read lock to a
149
+ // write lock, and SQLite returns SQLITE_BUSY for that at once instead of
150
+ // waiting on busy_timeout. Concurrent first opens retry within busyTimeout.
151
+ try {
152
+ setJournalModeWithRetry(db, 'WAL', busyTimeout);
153
+ }
154
+ catch (err) {
155
+ db.close();
156
+ throw err;
157
+ }
143
158
  }
144
159
  return db;
145
160
  }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Switch a SQLite connection's journal mode, retrying lock contention (#1164).
3
+ *
4
+ * `PRAGMA journal_mode = WAL` on a rollback-journal database reads page 1
5
+ * under a SHARED lock and then upgrades to a write lock to rewrite the header.
6
+ * SQLite does not run the busy handler for that upgrade (an upgrade from a
7
+ * held read lock could deadlock), so when several processes open the same
8
+ * non-WAL database at once, all but one can get SQLITE_BUSY in well under a
9
+ * millisecond even with busy_timeout set. Leaving WAL needs an EXCLUSIVE lock
10
+ * and fails the same way.
11
+ *
12
+ * This retries the switch with a short, growing sleep until `budgetMs` has
13
+ * passed, then throws the last error. Once another process has switched the
14
+ * file, the retry finds the mode already set, which needs no write lock.
15
+ *
16
+ * Dependency-free (no better-sqlite3 import) so optional-dependency callers can
17
+ * use it with a connection they loaded themselves.
18
+ */
19
+ /** The part of a better-sqlite3 connection this needs. */
20
+ export interface JournalModeConnection {
21
+ pragma(source: string, options?: {
22
+ simple?: boolean;
23
+ }): unknown;
24
+ }
25
+ export interface JournalModeRetryOptions {
26
+ /** Synchronous sleep, injectable for tests. */
27
+ sleep?: (ms: number) => void;
28
+ /** Clock in ms, injectable for tests. */
29
+ now?: () => number;
30
+ }
31
+ /** True for SQLITE_BUSY / SQLITE_LOCKED, including extended codes such as SQLITE_BUSY_RECOVERY. */
32
+ export declare function isJournalLockContention(err: unknown): boolean;
33
+ /**
34
+ * Set `journal_mode` to `mode`, retrying SQLITE_BUSY / SQLITE_LOCKED for up to
35
+ * `budgetMs`. Returns the mode SQLite reports afterwards, lower-cased. Any
36
+ * other error is thrown at once.
37
+ */
38
+ export declare function setJournalModeWithRetry(db: JournalModeConnection, mode: string, budgetMs: number, options?: JournalModeRetryOptions): string;
39
+ //# sourceMappingURL=sqlite-journal-mode.d.ts.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Switch a SQLite connection's journal mode, retrying lock contention (#1164).
3
+ *
4
+ * `PRAGMA journal_mode = WAL` on a rollback-journal database reads page 1
5
+ * under a SHARED lock and then upgrades to a write lock to rewrite the header.
6
+ * SQLite does not run the busy handler for that upgrade (an upgrade from a
7
+ * held read lock could deadlock), so when several processes open the same
8
+ * non-WAL database at once, all but one can get SQLITE_BUSY in well under a
9
+ * millisecond even with busy_timeout set. Leaving WAL needs an EXCLUSIVE lock
10
+ * and fails the same way.
11
+ *
12
+ * This retries the switch with a short, growing sleep until `budgetMs` has
13
+ * passed, then throws the last error. Once another process has switched the
14
+ * file, the retry finds the mode already set, which needs no write lock.
15
+ *
16
+ * Dependency-free (no better-sqlite3 import) so optional-dependency callers can
17
+ * use it with a connection they loaded themselves.
18
+ */
19
+ const FIRST_BACKOFF_MS = 2;
20
+ const MAX_BACKOFF_MS = 50;
21
+ /** True for SQLITE_BUSY / SQLITE_LOCKED, including extended codes such as SQLITE_BUSY_RECOVERY. */
22
+ export function isJournalLockContention(err) {
23
+ const code = err?.code;
24
+ return typeof code === 'string' && (code.startsWith('SQLITE_BUSY') || code.startsWith('SQLITE_LOCKED'));
25
+ }
26
+ function sleepSync(ms) {
27
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
28
+ }
29
+ /**
30
+ * Set `journal_mode` to `mode`, retrying SQLITE_BUSY / SQLITE_LOCKED for up to
31
+ * `budgetMs`. Returns the mode SQLite reports afterwards, lower-cased. Any
32
+ * other error is thrown at once.
33
+ */
34
+ export function setJournalModeWithRetry(db, mode, budgetMs, options = {}) {
35
+ const sleep = options.sleep ?? sleepSync;
36
+ const now = options.now ?? Date.now;
37
+ const deadline = now() + Math.max(0, budgetMs);
38
+ let backoff = FIRST_BACKOFF_MS;
39
+ for (;;) {
40
+ try {
41
+ return String(db.pragma(`journal_mode = ${mode}`, { simple: true }) ?? '').toLowerCase();
42
+ }
43
+ catch (err) {
44
+ const remaining = deadline - now();
45
+ if (!isJournalLockContention(err) || remaining <= 0)
46
+ throw err;
47
+ // Jitter so processes that collided do not retry in lockstep.
48
+ sleep(Math.min(remaining, backoff / 2 + Math.random() * backoff / 2));
49
+ backoff = Math.min(backoff * 2, MAX_BACKOFF_MS);
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=sqlite-journal-mode.js.map
@@ -14,6 +14,26 @@
14
14
  * A run from the current working directory is kept whenever that directory is
15
15
  * already inside the file's runner project (a single-project repository, or a
16
16
  * server started inside the package), so those runs behave as before.
17
+ *
18
+ * #1272: a package with its own config runs from that package, even when the
19
+ * root config also lists it in `test.projects` (or a `vitest.workspace.*`).
20
+ * Settings that only the root config adds to that project (its setup files,
21
+ * aliases or environment) are then not applied; the package's own config is
22
+ * what runs. A package without its own config still runs from the root.
23
+ *
24
+ * #1272: `vite.config.*` counts only when its text contains `test:`. The
25
+ * config is code, and reading what it exports would mean running it, so a
26
+ * `test` block built some other way (spread from another module, say) is not
27
+ * seen and a `test:` that only appears in a comment is. Name the runner config
28
+ * `vitest.config.*` for an exact match.
29
+ *
30
+ * #1248: a Python test file belongs to the nearest directory with pytest
31
+ * configuration instead (`pytest.ini`, `pyproject.toml` with
32
+ * `[tool.pytest.ini_options]`, `setup.cfg` with `[tool:pytest]`, `tox.ini`
33
+ * with `[pytest]`), and JavaScript files ignore that configuration. A
34
+ * `conftest.py` marks a pytest project for detection but is not a directory
35
+ * to run from: it is often in `tests/`, and pytest started there would not
36
+ * have the project root on `sys.path`.
17
37
  */
18
38
  import { Result } from './types';
19
39
  /**
@@ -34,8 +54,30 @@ export interface RunnerProjectGroup {
34
54
  cwd: string;
35
55
  files: string[];
36
56
  }
57
+ /** A runner whose project configuration can be recognised from its files. */
58
+ export type RunnerFramework = 'vitest' | 'jest';
37
59
  /** True when `dir` holds a Vitest or Jest configuration. */
38
60
  export declare function isRunnerProjectDir(dir: string): boolean;
61
+ /**
62
+ * #1248: true when `dir` holds pytest configuration; with `conftest`, a
63
+ * `conftest.py` counts too (see the header note).
64
+ */
65
+ export declare function isPytestProjectDir(dir: string, conftest?: boolean): boolean;
66
+ /**
67
+ * #1248: true when `dir`, or a directory above it no higher than `boundary`,
68
+ * is configured for pytest (including a `conftest.py`).
69
+ */
70
+ export declare function isPytestProject(dir: string, boundary?: string): boolean;
71
+ /**
72
+ * #1272: the runner configured by the runner project that `dir` belongs to:
73
+ * the nearest directory at or above `dir`, no higher than `boundary`, with
74
+ * runner configuration. Jest config (`jest.config.*`, or a `jest` key in
75
+ * package.json) means jest; Vitest config (`vitest.config.*`,
76
+ * `vitest.workspace.*`, a `vite.config.*` with `test`, or a `vitest` key)
77
+ * means vitest. Undefined when no project is found or it configures both, so
78
+ * the caller keeps its own choice.
79
+ */
80
+ export declare function runnerFrameworkFor(dir: string, boundary?: string): RunnerFramework | undefined;
39
81
  /**
40
82
  * The nearest directory at or above `file` with runner configuration, searching no
41
83
  * higher than `boundary`. Undefined when the file lies outside the boundary or
@@ -50,7 +92,8 @@ export declare function findRunnerProjectDir(file: string, boundary: string, cwd
50
92
  export declare function runnerCwdFor(file: string, options?: RunnerProjectOptions): string;
51
93
  /**
52
94
  * Group `files` by the directory each must run from, in first-seen order.
53
- * Files keep the spelling they were given.
95
+ * Files keep the spelling they were given. #1248: Python files never share a
96
+ * group with other files, since only pytest runs them.
54
97
  */
55
98
  export declare function groupByRunnerProject(files: readonly string[], options?: RunnerProjectOptions): RunnerProjectGroup[];
56
99
  /** Test files to run, and the directory to run them from when the caller named one. */
@@ -66,4 +109,11 @@ export interface TestRunTargets {
66
109
  * files are then read from it, and every path is returned absolute.
67
110
  */
68
111
  export declare function requireTestRunTargets(taskType: string, testFiles: unknown, projectRoot: unknown): Promise<Result<TestRunTargets, Error>>;
112
+ /**
113
+ * An explicit `projectRoot` (MCP `test_execute_parallel`, CLI
114
+ * `aqe test execute --project-root`): a directory inside the project, checked
115
+ * by realpath so `..`, an outside absolute path or a symlink pointing out is
116
+ * refused. Returns the absolute directory.
117
+ */
118
+ export declare function requireRunProjectRoot(taskType: string, projectRoot: unknown): Promise<Result<string, Error>>;
69
119
  //# sourceMappingURL=test-runner-project.d.ts.map