agentic-qe 3.15.17 → 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 (495) 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 +123 -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-6BUOFQZA.js → agent-booster-wasm-UFNJNF3M.js} +2 -2
  32. package/dist/cli/chunks/{agent-handler-HPDK3JI3.js → agent-handler-EAYVRJXN.js} +2 -2
  33. package/dist/cli/chunks/{agent-memory-branch-5QKUTWK5.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-HZ35LESR.js → arena-2GDICP6R.js} +4 -4
  36. package/dist/cli/chunks/{arena-7OKPMNHD.js → arena-CG3X67OE.js} +2 -2
  37. package/dist/cli/chunks/{audit-XI575SVK.js → audit-F4FSPJPL.js} +3 -3
  38. package/dist/cli/chunks/base-J2FXOE77.js +2 -0
  39. package/dist/cli/chunks/{better-sqlite3-YO5X7ZJS.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-N6G44UU2.js → branch-enumerator-KL7C535H.js} +2 -2
  42. package/dist/cli/chunks/{browser-EVKPTLOI.js → browser-SJEXDVHS.js} +2 -2
  43. package/dist/cli/chunks/browser-workflow-LXGER6ZD.js +2 -0
  44. package/dist/cli/chunks/{chunk-VLTDW7XJ.js → chunk-244RKAEP.js} +2 -2
  45. package/dist/cli/chunks/{chunk-CVPXHDQU.js → chunk-27TUMXPD.js} +1 -1
  46. package/dist/cli/chunks/{chunk-FBBPRVNF.js → chunk-2MBYDPCP.js} +2 -2
  47. package/dist/cli/chunks/{chunk-P3D7SEHW.js → chunk-2Q6DTBMT.js} +1 -1
  48. package/dist/cli/chunks/{chunk-NE3LRUNC.js → chunk-355MI7RV.js} +13 -13
  49. package/dist/cli/chunks/{chunk-YCVLKU6H.js → chunk-3LX5OKBD.js} +2 -2
  50. package/dist/cli/chunks/{chunk-74MDUIAZ.js → chunk-3RPDKJGV.js} +1 -1
  51. package/dist/cli/chunks/{chunk-OWIQR6N2.js → chunk-3YMIT73A.js} +2 -2
  52. package/dist/cli/chunks/{chunk-VKREKVFI.js → chunk-43KUVBSU.js} +2 -2
  53. package/dist/cli/chunks/chunk-477FKXSS.js +2 -0
  54. package/dist/cli/chunks/{chunk-XPTCQKVE.js → chunk-4BIMTRRX.js} +1 -1
  55. package/dist/cli/chunks/{chunk-HD6W6PHV.js → chunk-4CVNVBX5.js} +2 -2
  56. package/dist/cli/chunks/{chunk-CQER6IJ5.js → chunk-4HL3SD4A.js} +1 -1
  57. package/dist/cli/chunks/{chunk-ZNXM6WVL.js → chunk-4PEG4DU2.js} +2 -2
  58. package/dist/cli/chunks/{chunk-BSIWI4ES.js → chunk-4QSQKFED.js} +2 -2
  59. package/dist/cli/chunks/chunk-53ZBETYR.js +16 -0
  60. package/dist/cli/chunks/{chunk-BHQ2DLJU.js → chunk-544KDWL4.js} +1 -1
  61. package/dist/cli/chunks/chunk-54RCGMLB.js +8 -0
  62. package/dist/cli/chunks/{chunk-TDZ6N43D.js → chunk-5AGXIZQ5.js} +2 -2
  63. package/dist/cli/chunks/{chunk-RKCN4B26.js → chunk-5M24X6W7.js} +2 -2
  64. package/dist/cli/chunks/{chunk-GG7PMTHD.js → chunk-5O5T4LEU.js} +1 -1
  65. package/dist/cli/chunks/{chunk-OWIZBZLN.js → chunk-5RFXX4IF.js} +2 -2
  66. package/dist/cli/chunks/{chunk-VQFV2IPV.js → chunk-62MLAQRJ.js} +1 -1
  67. package/dist/cli/chunks/{chunk-PCL5JRKN.js → chunk-6D6TGL2E.js} +2 -2
  68. package/dist/cli/chunks/{chunk-WBDWHHKP.js → chunk-6IHZDSDL.js} +2 -2
  69. package/dist/cli/chunks/{chunk-UOVCTK5L.js → chunk-6P3Y45QL.js} +2 -2
  70. package/dist/cli/chunks/{chunk-45223KK6.js → chunk-6TEVM3X3.js} +10 -10
  71. package/dist/cli/chunks/{chunk-K7WAI662.js → chunk-7XTUKKRA.js} +1 -1
  72. package/dist/cli/chunks/chunk-A3GDX6UF.js +2 -0
  73. package/dist/cli/chunks/{chunk-GN6OE3JT.js → chunk-A5YTKKNA.js} +1 -1
  74. package/dist/cli/chunks/{chunk-KR2TAAF6.js → chunk-ADNGZAT2.js} +1 -1
  75. package/dist/cli/chunks/{chunk-J7Q5TXFZ.js → chunk-AWQAE3SW.js} +2 -2
  76. package/dist/cli/chunks/{chunk-ZN35XSKF.js → chunk-AXDBQFR4.js} +2 -2
  77. package/dist/cli/chunks/{chunk-ND72UDVH.js → chunk-AXVD7O3F.js} +2 -2
  78. package/dist/cli/chunks/{chunk-SAEECT23.js → chunk-B52ULNYO.js} +2 -2
  79. package/dist/cli/chunks/chunk-B6S4FC7M.js +3 -0
  80. package/dist/cli/chunks/{chunk-Z7SKUC6P.js → chunk-BDVFSMOQ.js} +1 -1
  81. package/dist/cli/chunks/{chunk-CXCMATZ6.js → chunk-BGXXMX3Y.js} +2 -2
  82. package/dist/cli/chunks/{chunk-R3KBOQ3O.js → chunk-BKMQQY5T.js} +2 -2
  83. package/dist/cli/chunks/{chunk-SAZ4PJBR.js → chunk-BN2FROBQ.js} +2 -2
  84. package/dist/cli/chunks/{chunk-G2X3OLMN.js → chunk-BO6EQNOC.js} +2 -2
  85. package/dist/cli/chunks/{chunk-776K4ZLE.js → chunk-BOVAKCDC.js} +2 -2
  86. package/dist/cli/chunks/{chunk-QSQNXBD2.js → chunk-BSXKZDKO.js} +2 -2
  87. package/dist/cli/chunks/{chunk-MGZ6XZHU.js → chunk-C5QVJ5XQ.js} +1 -1
  88. package/dist/cli/chunks/{chunk-LOLSZG5J.js → chunk-CFQLLF3D.js} +2 -2
  89. package/dist/cli/chunks/{chunk-J6QRNQJF.js → chunk-DUCVLT3F.js} +7 -7
  90. package/dist/cli/chunks/{chunk-QTQDX4TZ.js → chunk-E4RMJCGA.js} +3 -3
  91. package/dist/cli/chunks/{chunk-MLMD3I75.js → chunk-EONDCWY4.js} +1 -1
  92. package/dist/cli/chunks/{chunk-7BSOO3CY.js → chunk-F4AGNKL2.js} +2 -2
  93. package/dist/cli/chunks/{chunk-IKB3M7OF.js → chunk-F6YD3BOW.js} +1 -1
  94. package/dist/cli/chunks/{chunk-LIF6UWHV.js → chunk-FQRS7WVA.js} +2 -2
  95. package/dist/cli/chunks/{chunk-QJSSUBO3.js → chunk-FT24SSDG.js} +2 -2
  96. package/dist/cli/chunks/chunk-FV4YNSAJ.js +5 -0
  97. package/dist/cli/chunks/{chunk-VITV7AEC.js → chunk-FVDM3X42.js} +2 -2
  98. package/dist/cli/chunks/{chunk-LN7NKE3N.js → chunk-FVH7TXWU.js} +2 -2
  99. package/dist/cli/chunks/{chunk-FBSBXCZS.js → chunk-FWR5QY37.js} +2 -2
  100. package/dist/cli/chunks/{chunk-X2DWHGCC.js → chunk-FYINK2B7.js} +2 -2
  101. package/dist/cli/chunks/{chunk-ECKHDHR2.js → chunk-GGISVPOZ.js} +2 -2
  102. package/dist/cli/chunks/{chunk-SRBCBVSI.js → chunk-GPIJIZJQ.js} +2 -2
  103. package/dist/cli/chunks/{chunk-YR5QBUHZ.js → chunk-GXEVOT5F.js} +2 -2
  104. package/dist/cli/chunks/{chunk-ZTP3DQ5M.js → chunk-GZ4VB5RI.js} +1 -1
  105. package/dist/cli/chunks/{chunk-HWQPMUSN.js → chunk-HBDSCYSK.js} +2 -2
  106. package/dist/cli/chunks/{chunk-XBTGEYED.js → chunk-HGG4HR7C.js} +2 -2
  107. package/dist/cli/chunks/{chunk-YD2C6EPN.js → chunk-HSCKWWO2.js} +2 -2
  108. package/dist/cli/chunks/{chunk-LOMT4UC2.js → chunk-HSQ3GUYJ.js} +2 -2
  109. package/dist/cli/chunks/{chunk-ZC3KDNJW.js → chunk-HZQBW5EM.js} +3 -3
  110. package/dist/cli/chunks/{chunk-SUAZ5Z47.js → chunk-IGIYANVT.js} +2 -2
  111. package/dist/cli/chunks/{chunk-IHQGNDMX.js → chunk-IPWMSXBF.js} +2 -2
  112. package/dist/cli/chunks/{chunk-6V6BD6PH.js → chunk-IWVNC7VY.js} +1 -1
  113. package/dist/cli/chunks/{chunk-M2YI5YUR.js → chunk-IZODXKZD.js} +2 -2
  114. package/dist/cli/chunks/{chunk-LG5PPJT7.js → chunk-J2MT2OJV.js} +1 -1
  115. package/dist/cli/chunks/{chunk-6LSZCEW2.js → chunk-JKIJVVSP.js} +1 -1
  116. package/dist/cli/chunks/{chunk-REY52O7J.js → chunk-JMRDT2XK.js} +1 -1
  117. package/dist/cli/chunks/{chunk-XEYFZLIT.js → chunk-JR2UMTKG.js} +1 -1
  118. package/dist/cli/chunks/{chunk-DJDVD6RM.js → chunk-K6CH4CFF.js} +2 -2
  119. package/dist/cli/chunks/{chunk-2PCEMDIX.js → chunk-K7KW5QB5.js} +78 -87
  120. package/dist/cli/chunks/{chunk-EPVPXHL7.js → chunk-KFCQP434.js} +2 -2
  121. package/dist/cli/chunks/{chunk-TWBZONKT.js → chunk-KH4T6STG.js} +2 -2
  122. package/dist/cli/chunks/{chunk-JI33PMPZ.js → chunk-KJBYZO57.js} +1 -1
  123. package/dist/cli/chunks/{chunk-PK34KJH7.js → chunk-KP4OKOKV.js} +2 -2
  124. package/dist/cli/chunks/chunk-L2MBKVSE.js +2 -0
  125. package/dist/cli/chunks/{chunk-JVWZAE2H.js → chunk-L3IPUIT3.js} +2 -2
  126. package/dist/cli/chunks/{chunk-KT2QCXO6.js → chunk-L7PSU2YN.js} +2 -2
  127. package/dist/cli/chunks/{chunk-HAQJFUAQ.js → chunk-LA3JPGQA.js} +2 -2
  128. package/dist/cli/chunks/{chunk-LV7UIK4Q.js → chunk-LC2QRN7V.js} +14 -13
  129. package/dist/cli/chunks/{chunk-KTORRIX3.js → chunk-LHY7TMTM.js} +2 -2
  130. package/dist/cli/chunks/{chunk-IJSROBM6.js → chunk-LLQ2UMF6.js} +3 -3
  131. package/dist/cli/chunks/{chunk-NKUHMA4T.js → chunk-LOJ7OO6W.js} +2 -2
  132. package/dist/cli/chunks/{chunk-OJIUIEI4.js → chunk-LPUSH3VF.js} +1 -1
  133. package/dist/cli/chunks/{chunk-WAOEQA3W.js → chunk-LSEC2BU7.js} +2 -2
  134. package/dist/cli/chunks/{chunk-YMUY3TES.js → chunk-LTGB7OIU.js} +2 -2
  135. package/dist/cli/chunks/{chunk-CVYPMGUM.js → chunk-LUG7YNVZ.js} +2 -2
  136. package/dist/cli/chunks/{chunk-YAJOBZE5.js → chunk-LWAFRYKE.js} +2 -2
  137. package/dist/cli/chunks/{chunk-ZP5AWQRO.js → chunk-M24ZAZ4U.js} +2 -2
  138. package/dist/cli/chunks/{chunk-HFZD5KLR.js → chunk-MKRKRXTX.js} +1 -1
  139. package/dist/cli/chunks/{chunk-4YM45Z5B.js → chunk-MNNLONAD.js} +1 -1
  140. package/dist/cli/chunks/{chunk-CMN7PU2H.js → chunk-MQM37KAR.js} +2 -2
  141. package/dist/cli/chunks/{chunk-COTQ44YO.js → chunk-MSX2OHYT.js} +2 -2
  142. package/dist/cli/chunks/{chunk-4UKTIQDT.js → chunk-MVYQRVLP.js} +2 -2
  143. package/dist/cli/chunks/{chunk-HRUHHHVR.js → chunk-MZC5WM2P.js} +2 -2
  144. package/dist/cli/chunks/{chunk-YKRLUTK7.js → chunk-MZRBNBB3.js} +2 -2
  145. package/dist/cli/chunks/{chunk-XEMCHGAJ.js → chunk-N3KQU4UC.js} +2 -2
  146. package/dist/cli/chunks/{chunk-DS5IFRY6.js → chunk-NKU3FFM4.js} +2 -2
  147. package/dist/cli/chunks/chunk-O5EWFR76.js +2 -0
  148. package/dist/cli/chunks/{chunk-J3QFJI2Y.js → chunk-O5RDHD5T.js} +2 -2
  149. package/dist/cli/chunks/chunk-O6UWIXME.js +3 -0
  150. package/dist/cli/chunks/{chunk-Q6F3DYZN.js → chunk-OA4EQDC4.js} +2 -2
  151. package/dist/cli/chunks/{chunk-NQFDJ6BT.js → chunk-OBCXCRXK.js} +1 -1
  152. package/dist/cli/chunks/{chunk-S3TBOKAZ.js → chunk-OHU5P25N.js} +4 -4
  153. package/dist/cli/chunks/{chunk-DNVRTJKB.js → chunk-OOSV2RIA.js} +2 -2
  154. package/dist/cli/chunks/{chunk-NZJVDOUN.js → chunk-OW23N2Y5.js} +2 -2
  155. package/dist/cli/chunks/{chunk-ZWUF27P4.js → chunk-OXOO3YDL.js} +2 -2
  156. package/dist/cli/chunks/{chunk-4L6WX5KC.js → chunk-OYGKSSSI.js} +1 -1
  157. package/dist/cli/chunks/{chunk-DCDSN67A.js → chunk-PGO46IIW.js} +1 -1
  158. package/dist/cli/chunks/{chunk-C7QLLMYI.js → chunk-PZOYQHWS.js} +1 -1
  159. package/dist/cli/chunks/{chunk-BKHEQIRZ.js → chunk-Q2BZSG7Z.js} +2 -2
  160. package/dist/cli/chunks/{chunk-5FSPELOG.js → chunk-Q7V722K5.js} +2 -2
  161. package/dist/cli/chunks/{chunk-2EQK7B5L.js → chunk-QZU6M5IO.js} +2 -2
  162. package/dist/cli/chunks/{chunk-HVT7RMGV.js → chunk-R55Y76SJ.js} +1 -1
  163. package/dist/cli/chunks/{chunk-POPSZDI2.js → chunk-RMEQYJPU.js} +4 -4
  164. package/dist/cli/chunks/{chunk-H2LHWZRE.js → chunk-RTYXFXTI.js} +2 -2
  165. package/dist/cli/chunks/{chunk-QN7HP2UW.js → chunk-SJF3O4FX.js} +236 -236
  166. package/dist/cli/chunks/{chunk-2YWYW7NU.js → chunk-SOUS7Z2H.js} +2 -2
  167. package/dist/cli/chunks/{chunk-U5SMBJ6F.js → chunk-SRVNR3R3.js} +2 -2
  168. package/dist/cli/chunks/{chunk-ZAQMRFBB.js → chunk-SU3SXMVG.js} +2 -2
  169. package/dist/cli/chunks/chunk-SWGPLXWW.js +32 -0
  170. package/dist/cli/chunks/{chunk-S3DT5TPR.js → chunk-TRB3EVH3.js} +2 -2
  171. package/dist/cli/chunks/{chunk-IJZFJPHS.js → chunk-TVBDUMKT.js} +2 -2
  172. package/dist/cli/chunks/{chunk-7SNSI4VY.js → chunk-TWTXPSFU.js} +1 -1
  173. package/dist/cli/chunks/{chunk-ORQ2YBRR.js → chunk-ULYUVUL2.js} +2 -2
  174. package/dist/cli/chunks/{chunk-MVVVGQJ6.js → chunk-UNTBVJ5X.js} +2 -2
  175. package/dist/cli/chunks/{chunk-5WATBVU6.js → chunk-UQAA4PHU.js} +2 -2
  176. package/dist/cli/chunks/{chunk-5WYZVSL2.js → chunk-UWSJVKTE.js} +1 -1
  177. package/dist/cli/chunks/{chunk-JHKKIJT2.js → chunk-V2LJ54KP.js} +2 -2
  178. package/dist/cli/chunks/{chunk-2UUZCQSD.js → chunk-VCCTTKP3.js} +2 -2
  179. package/dist/cli/chunks/{chunk-P4OB6WDJ.js → chunk-VEGUYUVS.js} +1 -1
  180. package/dist/cli/chunks/{chunk-WX4PO65Q.js → chunk-VUQPVWNK.js} +2 -2
  181. package/dist/cli/chunks/{chunk-IQL6XRF5.js → chunk-VVGUE2T2.js} +2 -2
  182. package/dist/cli/chunks/{chunk-HZ5O7G2P.js → chunk-W5ASDHJQ.js} +1 -1
  183. package/dist/cli/chunks/{chunk-U4S74IIZ.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-AGCS5GSO.js → chunk-WQNLXUWA.js} +6 -6
  187. package/dist/cli/chunks/{chunk-LRY6UIRI.js → chunk-WZVRMKG2.js} +2 -2
  188. package/dist/cli/chunks/{chunk-KPIPVSIP.js → chunk-X27IUWTD.js} +2 -2
  189. package/dist/cli/chunks/{chunk-VDEKVIP5.js → chunk-X4B345B6.js} +2 -2
  190. package/dist/cli/chunks/{chunk-ERYADKMZ.js → chunk-X5I2Y4VO.js} +2 -2
  191. package/dist/cli/chunks/{chunk-EUWG2JG4.js → chunk-X7IQIFTS.js} +2 -2
  192. package/dist/cli/chunks/chunk-XJN3RKUD.js +3 -0
  193. package/dist/cli/chunks/{chunk-JRIJM4LE.js → chunk-XQMGXTHJ.js} +3 -3
  194. package/dist/cli/chunks/{chunk-VYPVU3JF.js → chunk-XTSAMB2Q.js} +2 -2
  195. package/dist/cli/chunks/{chunk-4NKZU2JZ.js → chunk-XZLIF4O2.js} +2 -2
  196. package/dist/cli/chunks/{chunk-XFTX3KLE.js → chunk-Y4LSEOZ3.js} +1 -1
  197. package/dist/cli/chunks/{chunk-ZVMSSCTH.js → chunk-Y4YN2RXR.js} +2 -2
  198. package/dist/cli/chunks/{chunk-X5QD76IU.js → chunk-YDI56L35.js} +2 -2
  199. package/dist/cli/chunks/{chunk-LRKLATSH.js → chunk-YFILS5D5.js} +2 -2
  200. package/dist/cli/chunks/{chunk-AVHYJ3XP.js → chunk-YISDX6WB.js} +2 -2
  201. package/dist/cli/chunks/{chunk-GPPTRKEM.js → chunk-YP2GHQSV.js} +2 -2
  202. package/dist/cli/chunks/{chunk-OO2M2QUV.js → chunk-YSX756AM.js} +4 -4
  203. package/dist/cli/chunks/{chunk-E7XIMOKW.js → chunk-YWANOASW.js} +2 -2
  204. package/dist/cli/chunks/{chunk-UHJVZEQA.js → chunk-YYIJLG7S.js} +2 -2
  205. package/dist/cli/chunks/{chunk-LCWEQRZI.js → chunk-Z7SD7LXM.js} +2 -2
  206. package/dist/cli/chunks/{chunk-TM75GAXG.js → chunk-ZDWD73UF.js} +2 -2
  207. package/dist/cli/chunks/{chunk-IRHXGCQR.js → chunk-ZFT3RLA4.js} +2 -2
  208. package/dist/cli/chunks/{chunk-ZGV7L4MW.js → chunk-ZNTHX5G3.js} +1 -1
  209. package/dist/cli/chunks/{chunk-D75GLKEL.js → chunk-ZS27R7VL.js} +2 -2
  210. package/dist/cli/chunks/{chunk-INI3Q4CN.js → chunk-ZXHHHR7K.js} +1 -1
  211. package/dist/cli/chunks/{ci-3RTTTS2D.js → ci-N5MOMNXH.js} +2 -2
  212. package/dist/cli/chunks/{ci-config-XRUR3I4K.js → ci-config-6L2ROQCW.js} +2 -2
  213. package/dist/cli/chunks/{ci-output-E5IAMU2U.js → ci-output-DSRBYEIK.js} +2 -2
  214. package/dist/cli/chunks/{circuit-breaker-SHR2P44P.js → circuit-breaker-VRPTNBL7.js} +2 -2
  215. package/dist/cli/chunks/{claude-flow-setup-ZDDILFMF.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-BGYVUM6G.js → cline-installer-7RGYJWGN.js} +2 -2
  218. package/dist/cli/chunks/{code-PJ4MC3MC.js → code-ISC6NW2K.js} +3 -3
  219. package/dist/cli/chunks/{code-index-extractor-IW2P22YG.js → code-index-extractor-2FID75YV.js} +2 -2
  220. package/dist/cli/chunks/{codex-installer-A7WZ6OGL.js → codex-installer-DZ7OG6KM.js} +2 -2
  221. package/dist/cli/chunks/{completions-KS23WD5J.js → completions-SM3LICWK.js} +2 -2
  222. package/dist/cli/chunks/{complexity-analyzer-Q7GLSR2E.js → complexity-analyzer-ZWD2CTAD.js} +2 -2
  223. package/dist/cli/chunks/{continuedev-installer-SK55BFW2.js → continuedev-installer-AGASOA26.js} +2 -2
  224. package/dist/cli/chunks/{copilot-installer-3N5J3WTM.js → copilot-installer-CLPZYTQC.js} +2 -2
  225. package/dist/cli/chunks/core-handlers-5EFOJ37H.js +2 -0
  226. package/dist/cli/chunks/{cost-tracker-NENVSO4A.js → cost-tracker-7PIGQYDV.js} +2 -2
  227. package/dist/cli/chunks/{coverage-5L7UQWDH.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-XXBO2ZE6.js → cursor-installer-KXBID4MB.js} +2 -2
  230. package/dist/cli/chunks/daemon-43MXIVH3.js +18 -0
  231. package/dist/cli/chunks/{daemon-CDCQU3LR.js → daemon-VAMJLQJ5.js} +3 -3
  232. package/dist/cli/chunks/{dag-attention-scheduler-HOMMF7FA.js → dag-attention-scheduler-UBP4VHTA.js} +2 -2
  233. package/dist/cli/chunks/{detect-FXCOUG6X.js → detect-QWFIQRKI.js} +2 -2
  234. package/dist/cli/chunks/{dist-node-GXQ7FMTY.js → dist-node-I2GICS3W.js} +2 -2
  235. package/dist/cli/chunks/{domain-handler-TI3JBAPC.js → domain-handler-Z66ISB2A.js} +2 -2
  236. package/dist/cli/chunks/{domain-plugins-R7LTUM32.js → domain-plugins-KHMD3FKT.js} +2 -2
  237. package/dist/cli/chunks/{domain-transfer-LBIAFHIQ.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-HHLWTBF5.js → embedding-space-KHG6TITM.js} +2 -2
  241. package/dist/cli/chunks/{eval-KDOZMAXJ.js → eval-43OHU7EI.js} +2 -2
  242. package/dist/cli/chunks/{experience-capture-middleware-X45PECQN.js → experience-capture-middleware-KXD47H6P.js} +3 -3
  243. package/dist/cli/chunks/{fast-paths-462V6UUB.js → fast-paths-6D75D5KD.js} +2 -2
  244. package/dist/cli/chunks/{feature-flags-NIRQ4YDM.js → feature-flags-IE35Y55N.js} +2 -2
  245. package/dist/cli/chunks/{feature-flags-G66OT3AS.js → feature-flags-OYYHY7LS.js} +2 -2
  246. package/dist/cli/chunks/file-discovery-LGBTY3ID.js +2 -0
  247. package/dist/cli/chunks/{fleet-PXWGB7CU.js → fleet-AGVJMFGD.js} +16 -16
  248. package/dist/cli/chunks/{gnn-wrapper-7MUW3M5M.js → gnn-wrapper-5L66A7LW.js} +2 -2
  249. package/dist/cli/chunks/{heartbeat-handler-5237PB35.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-OSQPW7JP.js → hnsw-legacy-bridge-RYMWFNAH.js} +2 -2
  254. package/dist/cli/chunks/{hnswlib-node-GX6WG2GB.js → hnswlib-node-GG47HP2P.js} +2 -2
  255. package/dist/cli/chunks/{hooks-GUWHL7VC.js → hooks-FQNACS24.js} +10 -10
  256. package/dist/cli/chunks/hybrid-backend-AS2PNHOD.js +2 -0
  257. package/dist/cli/chunks/{hypergraph-engine-SRWLLCU3.js → hypergraph-engine-6BYNJQEP.js} +2 -2
  258. package/dist/cli/chunks/{hypergraph-handler-AVOPRHHO.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-P4N6EVZS.js → init-guard-METTAV5O.js} +2 -2
  261. package/dist/cli/chunks/{init-handler-LRGWOJMD.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-7R2EPOQ6.js → kilocode-installer-GZV2D3FF.js} +2 -2
  265. package/dist/cli/chunks/{kiro-installer-QNM7DPOB.js → kiro-installer-Q4ZXUFC7.js} +2 -2
  266. package/dist/cli/chunks/knowledge-graph-CNL77CSZ.js +2 -0
  267. package/dist/cli/chunks/{learning-7OIZBPXZ.js → learning-WA2QEYL7.js} +35 -34
  268. package/dist/cli/chunks/{llm-router-SIDXES23.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-EI2E2C3S.js → load-WXN3Q7Y5.js} +2 -2
  271. package/dist/cli/chunks/load-test-PXLW4A5B.js +2 -0
  272. package/dist/cli/chunks/{mcp-IOE5WOCS.js → mcp-LIQCPSJN.js} +2 -2
  273. package/dist/cli/chunks/{memory-DLYGJAP7.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-WHH4YCHM.js → multi-model-executor-H54DEVRZ.js} +2 -2
  277. package/dist/cli/chunks/{opencode-installer-63FDZAMS.js → opencode-installer-BSQV6UAT.js} +2 -2
  278. package/dist/cli/chunks/{orchestrator-3LA776KK.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-NW54QUGI.js → pattern-usage-recorder-FOVS4M5L.js} +2 -2
  281. package/dist/cli/chunks/{pipeline-P3TYX6J6.js → pipeline-4AY2ZIC6.js} +2 -2
  282. package/dist/cli/chunks/{platform-FNA2WLI6.js → platform-FCSITYMR.js} +2 -2
  283. package/dist/cli/chunks/{plugin-NJS7BC2S.js → plugin-E56TV5S2.js} +2 -2
  284. package/dist/cli/chunks/{prime-radiant-advanced-wasm-NIAVL2OT.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-JU5C4JHY.js → protocol-handler-KRVXF4LS.js} +2 -2
  288. package/dist/cli/chunks/{prove-35VOSLYP.js → prove-KMFPSKGD.js} +2 -2
  289. package/dist/cli/chunks/qe-reasoning-bank-UEGQ3O7F.js +2 -0
  290. package/dist/cli/chunks/{quality-ET74X7HN.js → quality-6DBI3HLB.js} +2 -2
  291. package/dist/cli/chunks/{quality-gate-FEDQISNB.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-DTBPYCEB.js → ref-validation-EYIP7DHW.js} +2 -2
  295. package/dist/cli/chunks/{roocode-installer-LYQEMR4J.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-DJOJFPII.js → routing-handler-BWNHBYDC.js} +2 -2
  299. package/dist/cli/chunks/{ruvector-commands-VXYGJDPW.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-GA2ZYOEG.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-MM6YOECX.js → security-DCRGOTWU.js} +3 -3
  309. package/dist/cli/chunks/{shared-rvf-adapter-6AHPA3V5.js → shared-rvf-adapter-GKD74QUB.js} +2 -2
  310. package/dist/cli/chunks/{shared-rvf-dual-writer-EYAVY2GZ.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-A3PLB4CZ.js → standalone-memory-O7O2U5N4.js} +2 -2
  313. package/dist/cli/chunks/{status-handler-OSSFAP4Z.js → status-handler-BQTPJJTL.js} +2 -2
  314. package/dist/cli/chunks/{structural-health-PGY5XUNO.js → structural-health-4H6J4OHK.js} +2 -2
  315. package/dist/cli/chunks/sync-DJ4TF6QX.js +2 -0
  316. package/dist/cli/chunks/{sync-CWEHYGNN.js → sync-WW5TAVYW.js} +2 -2
  317. package/dist/cli/chunks/{task-handler-LHMQ75W4.js → task-handler-HEM4IEOW.js} +2 -2
  318. package/dist/cli/chunks/{task-handlers-S2TX5FTR.js → task-handlers-JRA3NXIR.js} +3 -3
  319. package/dist/cli/chunks/{test-4EGZZ6NJ.js → test-772ZXVG2.js} +4 -4
  320. package/dist/cli/chunks/test-runner-process-XGF2U3NG.js +2 -0
  321. package/dist/cli/chunks/{test-scheduling-YJQHH3XE.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-WPNOJR6H.js → token-usage-B7PEKE2G.js} +2 -2
  324. package/dist/cli/chunks/{transformers-4MRPXCPU.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-6P5FB4EB.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-4ICTN63Y.js → upgrade-DZ4DLUQ5.js} +2 -2
  331. package/dist/cli/chunks/{validate-HQF5GZ7L.js → validate-4DTLIDJE.js} +2 -2
  332. package/dist/cli/chunks/{validate-swarm-45JYG7VW.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-UOTWZLNH.js → web-tree-sitter-F2C7QRYT.js} +2 -2
  335. package/dist/cli/chunks/{windsurf-installer-WDWSBXGN.js → windsurf-installer-OOBTDA6W.js} +2 -2
  336. package/dist/cli/chunks/{witness-chain-DOYMNPC7.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-JB42X62J.js → witness-chain-verifier-OB7ZZOI3.js} +2 -2
  340. package/dist/cli/chunks/{witness-key-manager-LXXO6L2G.js → witness-key-manager-YCKGKGQI.js} +2 -2
  341. package/dist/cli/chunks/{workflow-6ARK47NF.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/handlers/brain-handler.js +32 -2
  347. package/dist/cli/handlers/heartbeat-handler.js +3 -1
  348. package/dist/cli/utils/coverage-data.js +5 -1
  349. package/dist/cli/utils/coverage-verdict.d.ts +10 -2
  350. package/dist/cli/utils/coverage-verdict.js +23 -8
  351. package/dist/cli/utils/fleet-operation.js +9 -3
  352. package/dist/coordination/handlers/code-intelligence-handlers.js +17 -3
  353. package/dist/coordination/handlers/coverage-handlers.js +22 -9
  354. package/dist/coordination/handlers/coverage-target.d.ts +22 -2
  355. package/dist/coordination/handlers/coverage-target.js +45 -9
  356. package/dist/coordination/handlers/handler-utils.d.ts +19 -0
  357. package/dist/coordination/handlers/handler-utils.js +22 -8
  358. package/dist/coordination/protocols/code-intelligence-index.js +6 -3
  359. package/dist/coordination/protocols/learning-consolidation-archive.d.ts +6 -3
  360. package/dist/coordination/protocols/learning-consolidation-archive.js +4 -3
  361. package/dist/coordination/workflow-builtin.js +1 -0
  362. package/dist/domains/defect-intelligence/interfaces.d.ts +2 -0
  363. package/dist/domains/defect-intelligence/prediction-history.d.ts +15 -1
  364. package/dist/domains/defect-intelligence/prediction-history.js +63 -7
  365. package/dist/domains/defect-intelligence/services/defect-predictor.d.ts +1 -0
  366. package/dist/domains/defect-intelligence/services/defect-predictor.js +33 -13
  367. package/dist/domains/learning-optimization/coordinator.js +17 -10
  368. package/dist/domains/learning-optimization/domain-ranking.d.ts +26 -0
  369. package/dist/domains/learning-optimization/domain-ranking.js +28 -0
  370. package/dist/domains/learning-optimization/interfaces.d.ts +5 -0
  371. package/dist/domains/learning-optimization/pattern-archive.d.ts +55 -8
  372. package/dist/domains/learning-optimization/pattern-archive.js +90 -17
  373. package/dist/domains/learning-optimization/pattern-consolidation.js +18 -2
  374. package/dist/domains/learning-optimization/pattern-merge.d.ts +26 -0
  375. package/dist/domains/learning-optimization/pattern-merge.js +127 -0
  376. package/dist/domains/learning-optimization/services/learning-coordinator.js +21 -35
  377. package/dist/domains/test-execution/services/test-executor.js +6 -2
  378. package/dist/init/init-wizard-steps.js +3 -1
  379. package/dist/init/phases/07-hooks.js +97 -10
  380. package/dist/integrations/embeddings/cache/EmbeddingCache.js +1 -1
  381. package/dist/integrations/ruvector/brain-rvf-exporter.d.ts +16 -1
  382. package/dist/integrations/ruvector/brain-rvf-exporter.js +18 -32
  383. package/dist/integrations/ruvector/brain-rvf-richness.d.ts +75 -0
  384. package/dist/integrations/ruvector/brain-rvf-richness.js +127 -0
  385. package/dist/kernel/unified-memory-migration.js +1 -1
  386. package/dist/learning/checkpoint-shrink-ack.d.ts +25 -0
  387. package/dist/learning/checkpoint-shrink-ack.js +57 -0
  388. package/dist/learning/dream/dream-engine.d.ts +44 -3
  389. package/dist/learning/dream/dream-engine.js +6 -2
  390. package/dist/learning/embedder-identity-store.js +3 -1
  391. package/dist/learning/embedding-space-legacy-adoption.d.ts +53 -0
  392. package/dist/learning/embedding-space-legacy-adoption.js +115 -0
  393. package/dist/learning/embedding-space-registry.d.ts +15 -0
  394. package/dist/learning/embedding-space-registry.js +50 -11
  395. package/dist/learning/experience-capture.d.ts +3 -1
  396. package/dist/learning/experience-capture.js +15 -5
  397. package/dist/learning/experience-space-verification.d.ts +2 -0
  398. package/dist/learning/experience-space-verification.js +3 -2
  399. package/dist/learning/learning-retention.js +4 -0
  400. package/dist/learning/pattern-promotion.d.ts +7 -0
  401. package/dist/learning/pattern-promotion.js +64 -12
  402. package/dist/learning/real-embeddings.js +31 -7
  403. package/dist/learning/rvf-pattern-store.js +6 -1
  404. package/dist/mcp/bundle.js +570 -558
  405. package/dist/mcp/handlers/domain-handler-configs.d.ts +3 -0
  406. package/dist/mcp/handlers/domain-handler-configs.js +1 -0
  407. package/dist/mcp/handlers/heartbeat-handlers.d.ts +4 -2
  408. package/dist/mcp/tools/learning-optimization/optimize.d.ts +6 -1
  409. package/dist/mcp/tools/learning-optimization/optimize.js +20 -11
  410. package/dist/planning/goap-planner.js +4 -0
  411. package/dist/planning/plan-executor.js +6 -2
  412. package/dist/shared/git/git-analyzer.d.ts +30 -11
  413. package/dist/shared/git/git-analyzer.js +95 -48
  414. package/dist/shared/io/confined-read.d.ts +32 -7
  415. package/dist/shared/io/confined-read.js +58 -25
  416. package/dist/shared/io/file-reader.js +4 -1
  417. package/dist/shared/safe-db.d.ts +1 -1
  418. package/dist/shared/safe-db.js +20 -5
  419. package/dist/shared/sqlite-journal-mode.d.ts +39 -0
  420. package/dist/shared/sqlite-journal-mode.js +53 -0
  421. package/dist/sync/claude-flow-bridge.js +1 -1
  422. package/dist/sync/readers/sqlite-reader.js +3 -4
  423. package/dist/sync/writers/sqlite-writer.js +1 -1
  424. package/dist/workers/interfaces.d.ts +2 -2
  425. package/dist/workers/quality-daemon/git-watcher.d.ts +8 -0
  426. package/dist/workers/quality-daemon/git-watcher.js +54 -12
  427. package/dist/workers/quality-daemon/index.js +1 -1
  428. package/dist/workers/quality-daemon/priority-queue.d.ts +2 -1
  429. package/dist/workers/workers/defect-predictor.d.ts +9 -4
  430. package/dist/workers/workers/defect-predictor.js +98 -37
  431. package/package.json +1 -1
  432. package/dist/cli/chunks/adapter-OMILP6KH.js +0 -2
  433. package/dist/cli/chunks/aqe-learning-engine-OXH5CCOS.js +0 -2
  434. package/dist/cli/chunks/base-MAK2BLTG.js +0 -2
  435. package/dist/cli/chunks/brain-handler-GCQZFZGQ.js +0 -95
  436. package/dist/cli/chunks/browser-workflow-IR3VF2TL.js +0 -2
  437. package/dist/cli/chunks/chunk-4EJLHNER.js +0 -12
  438. package/dist/cli/chunks/chunk-A4BVDYIL.js +0 -2
  439. package/dist/cli/chunks/chunk-BE7ZHM34.js +0 -3
  440. package/dist/cli/chunks/chunk-DHKSPOUQ.js +0 -16
  441. package/dist/cli/chunks/chunk-FAQ24UHB.js +0 -29
  442. package/dist/cli/chunks/chunk-IOWEBPXJ.js +0 -5
  443. package/dist/cli/chunks/chunk-KB34MTFZ.js +0 -3
  444. package/dist/cli/chunks/chunk-MCXW3DKE.js +0 -8
  445. package/dist/cli/chunks/chunk-O7VJ3VKD.js +0 -2
  446. package/dist/cli/chunks/chunk-PIWGKGWP.js +0 -3
  447. package/dist/cli/chunks/chunk-SFITYZLV.js +0 -7
  448. package/dist/cli/chunks/chunk-TIVKDIF7.js +0 -2
  449. package/dist/cli/chunks/client-NO5FOWT4.js +0 -2
  450. package/dist/cli/chunks/core-handlers-JNAZPXE2.js +0 -2
  451. package/dist/cli/chunks/cross-domain-router-HEBM767Z.js +0 -2
  452. package/dist/cli/chunks/daemon-JEBJGEUK.js +0 -18
  453. package/dist/cli/chunks/dream-GQDCEJMS.js +0 -2
  454. package/dist/cli/chunks/embed-and-insert-pattern-33KLHDD5.js +0 -3
  455. package/dist/cli/chunks/file-discovery-33USPLB5.js +0 -2
  456. package/dist/cli/chunks/heartbeat-scheduler-LIXLC5IH.js +0 -2
  457. package/dist/cli/chunks/hnsw-adapter-62D5UH27.js +0 -2
  458. package/dist/cli/chunks/hnsw-index-GSGUMQQC.js +0 -2
  459. package/dist/cli/chunks/hybrid-backend-FRWP4BOY.js +0 -2
  460. package/dist/cli/chunks/impact-analyzer-7KF3AQXV.js +0 -2
  461. package/dist/cli/chunks/init-wizard-XWWAXY25.js +0 -2
  462. package/dist/cli/chunks/kernel-ZEJPNDBW.js +0 -2
  463. package/dist/cli/chunks/knowledge-graph-RRZQS7KY.js +0 -2
  464. package/dist/cli/chunks/llm-router-service-3OSW67LC.js +0 -2
  465. package/dist/cli/chunks/load-test-7TRIH2WJ.js +0 -2
  466. package/dist/cli/chunks/memory-backend-G7ZW6Q2B.js +0 -2
  467. package/dist/cli/chunks/memory-handlers-TPF3KCO5.js +0 -2
  468. package/dist/cli/chunks/pattern-null-store-OU3ZC3NR.js +0 -2
  469. package/dist/cli/chunks/project-root-GMOFJEKD.js +0 -2
  470. package/dist/cli/chunks/protocol-executor-AD345XRO.js +0 -2
  471. package/dist/cli/chunks/qe-reasoning-bank-NLTP26RC.js +0 -2
  472. package/dist/cli/chunks/queen-coordinator-2TB4FWS6.js +0 -2
  473. package/dist/cli/chunks/real-embeddings-II6CXTCI.js +0 -2
  474. package/dist/cli/chunks/router-PLM3MWME.js +0 -2
  475. package/dist/cli/chunks/routing-feedback-I7VOX2HU.js +0 -2
  476. package/dist/cli/chunks/rvf-dual-writer-GQZHFWO2.js +0 -2
  477. package/dist/cli/chunks/rvf-migration-adapter-3TVKBCAM.js +0 -2
  478. package/dist/cli/chunks/rvf-migration-coordinator-XUHKLMT6.js +0 -2
  479. package/dist/cli/chunks/rvf-native-adapter-5GUTYOWS.js +0 -2
  480. package/dist/cli/chunks/safe-db-RZPQGLGQ.js +0 -2
  481. package/dist/cli/chunks/schedule-G7JMQDUX.js +0 -2
  482. package/dist/cli/chunks/scheduler-4SEGPCKD.js +0 -2
  483. package/dist/cli/chunks/sqlite-persistence-IVE4SQXR.js +0 -2
  484. package/dist/cli/chunks/sync-PM6D7EQF.js +0 -2
  485. package/dist/cli/chunks/test-runner-process-72YACW6M.js +0 -2
  486. package/dist/cli/chunks/token-bootstrap-DJNETMVW.js +0 -2
  487. package/dist/cli/chunks/tree-sitter-wasm-parser-UVWSDXFR.js +0 -2
  488. package/dist/cli/chunks/unified-memory-2VMGSGQL.js +0 -2
  489. package/dist/cli/chunks/unified-memory-hnsw-3KULVD3N.js +0 -2
  490. package/dist/cli/chunks/unified-persistence-QCSLU2SV.js +0 -2
  491. package/dist/cli/chunks/visual-security-ZYP2KPH7.js +0 -2
  492. package/dist/cli/chunks/witness-chain-5QRT7EMX.js +0 -2
  493. package/dist/cli/chunks/witness-chain-repair-CUF2AFQB.js +0 -2
  494. package/dist/cli/chunks/workflow-orchestrator-RYDDWIXN.js +0 -2
  495. package/dist/cli/chunks/wrappers-CYQBOMPL.js +0 -2
@@ -195,6 +195,9 @@ export interface DefectPredictResult {
195
195
  scanStatus?: 'partial' | 'complete';
196
196
  predictionMethod?: 'static-code-indicators';
197
197
  estimated?: boolean;
198
+ /** #1137: the run was stored, but pruning older runs failed. */
199
+ retention?: 'failed';
200
+ retentionError?: string;
198
201
  taskId: string;
199
202
  status: string;
200
203
  predictedDefects: Array<{
@@ -770,6 +770,7 @@ export const defectPredictConfig = {
770
770
  filesAnalyzed: data.filesAnalyzed, filesSkipped: data.filesSkipped,
771
771
  scanStatus: data.scanStatus,
772
772
  } : {}),
773
+ ...(data.retention === 'failed' ? { retention: 'failed', retentionError: String(data.retentionError ?? '') } : {}),
773
774
  predictedDefects: data.predictedDefects || [],
774
775
  riskScore: data.riskScore || 0,
775
776
  recommendations: data.recommendations || [],
@@ -20,7 +20,8 @@ export interface HeartbeatStatusResult {
20
20
  lastResult: {
21
21
  success: boolean;
22
22
  durationMs: number;
23
- healthScore: number;
23
+ /** `null` when the run measured nothing (#1137). */
24
+ healthScore: number | null;
24
25
  trend: string;
25
26
  domainMetrics: Record<string, number | string>;
26
27
  } | null;
@@ -32,7 +33,8 @@ export interface HeartbeatTriggerParams {
32
33
  export interface HeartbeatTriggerResult {
33
34
  success: boolean;
34
35
  durationMs: number;
35
- healthScore: number;
36
+ /** `null` when the run measured nothing (#1137). */
37
+ healthScore: number | null;
36
38
  trend: string;
37
39
  promoted: number;
38
40
  deprecated: number;
@@ -48,6 +48,8 @@ export interface LearnResult {
48
48
  experienceIdsNotFound?: number;
49
49
  evidenceStatus?: 'insufficient-evidence';
50
50
  patternsLearned: number;
51
+ /** #1147: why nothing was learned from the requested experiences. */
52
+ noPatternReason?: string;
51
53
  newPatterns: LearnedPattern[];
52
54
  /** No baseline is recorded to compare against, so improvement is not measured (#1109). */
53
55
  improvement: number | null;
@@ -128,7 +130,10 @@ export interface DashboardResult {
128
130
  assignedPatternsExcluded?: number;
129
131
  /** #1121: untagged patterns mined before #1120 (rate selected over successes), excluded likewise. */
130
132
  legacyPatternsExcluded?: number;
131
- /** Ranked by measured success rate; empty when no domain has a measured outcome. */
133
+ /**
134
+ * Ranked by measured success rate (#1147): domains with no measured outcome,
135
+ * or with 0% measured success, are left out.
136
+ */
132
137
  topPerformingDomains: DomainName[];
133
138
  evidenceStatus?: 'insufficient-evidence';
134
139
  unmeasured?: string[];
@@ -15,6 +15,7 @@ import { MetricsOptimizerService } from '../../../domains/learning-optimization/
15
15
  import { TransferSpecialistService } from '../../../domains/learning-optimization/services/transfer-specialist.js';
16
16
  import { toErrorMessage } from '../../../shared/error-utils.js';
17
17
  import { partitionByRewardSource } from '../../../domains/learning-optimization/reward-source.js';
18
+ import { rankTopPerformingDomains } from '../../../domains/learning-optimization/domain-ranking.js';
18
19
  // ============================================================================
19
20
  // Tool Implementation
20
21
  // ============================================================================
@@ -174,8 +175,21 @@ export class LearningOptimizeTool extends MCPToolBase {
174
175
  if (!readResult.success)
175
176
  throw readResult.error;
176
177
  const read = readResult.value;
178
+ const requested = new Set(experienceIds).size;
177
179
  const { measured, assignedExcluded } = partitionByRewardSource(read);
178
180
  const learned = measured.length > 0 ? await learningCoordinator.learnPattern(read) : null;
181
+ // #1147: say why nothing was learned instead of returning a bare 0.
182
+ let noPatternReason;
183
+ if (read.length === 0) {
184
+ noPatternReason = `None of the ${requested} requested experience ID(s) were found.`;
185
+ }
186
+ else if (measured.length === 0) {
187
+ noPatternReason = `None of the ${read.length} experience(s) read has a measured outcome` +
188
+ (assignedExcluded > 0 ? ` (${assignedExcluded} with an assigned reward excluded).` : '.');
189
+ }
190
+ else if (learned && !learned.success) {
191
+ noPatternReason = learned.error.message;
192
+ }
179
193
  const newPatterns = learned?.success
180
194
  ? [{
181
195
  id: learned.value.id,
@@ -190,11 +204,12 @@ export class LearningOptimizeTool extends MCPToolBase {
190
204
  this.markAsRealData();
191
205
  return {
192
206
  experiencesProcessed: read.length,
193
- experienceIdsNotFound: new Set(experienceIds).size - read.length,
207
+ experienceIdsNotFound: requested - read.length,
194
208
  measuredExperiences: measured.length,
195
209
  assignedRewardsExcluded: assignedExcluded,
196
210
  ...(measured.length === 0 ? { evidenceStatus: 'insufficient-evidence' } : {}),
197
211
  patternsLearned: newPatterns.length,
212
+ ...(noPatternReason ? { noPatternReason } : {}),
198
213
  newPatterns,
199
214
  improvement: null,
200
215
  unmeasured: ['improvement'],
@@ -464,17 +479,11 @@ export class LearningOptimizeTool extends MCPToolBase {
464
479
  experiencesLast24h += mineResult.value.experienceCount;
465
480
  assignedRewardsExcluded += mineResult.value.assignedRewardsExcluded ?? 0;
466
481
  // #1109: only a measured success rate can rank a domain.
467
- const { successRate } = mineResult.value;
468
- if (successRate !== null) {
469
- domainPerformance.push({ domain, successRate });
470
- }
482
+ domainPerformance.push({ domain, successRate: mineResult.value.successRate });
471
483
  }
472
484
  }
473
- // Calculate top performing domains
474
- domainPerformance.sort((a, b) => b.successRate - a.successRate);
475
- const topPerformingDomains = domainPerformance
476
- .slice(0, 3)
477
- .map(d => d.domain);
485
+ // #1147: rank by measured success; a domain at 0% is not top-performing.
486
+ const { topPerformingDomains, measuredDomains } = rankTopPerformingDomains(domainPerformance);
478
487
  // Calculate overall learning rate from pattern stats
479
488
  // getPatternStats already leaves out patterns learned from assigned rewards.
480
489
  const totalPatterns = statsResult.success ? statsResult.value.totalPatterns : 0;
@@ -528,7 +537,7 @@ export class LearningOptimizeTool extends MCPToolBase {
528
537
  const unmeasured = [];
529
538
  if (overallLearningRate === null)
530
539
  unmeasured.push('overallLearningRate');
531
- if (topPerformingDomains.length === 0)
540
+ if (measuredDomains === 0)
532
541
  unmeasured.push('topPerformingDomains');
533
542
  return {
534
543
  overallLearningRate,
@@ -656,6 +656,10 @@ export class GOAPPlanner {
656
656
  }
657
657
  // #1157: goal and condition keys can come from callers; an inherited
658
658
  // member such as `constructor` is not part of the world state.
659
+ // #1186: deliberately, a key resolves only through own properties of
660
+ // objects. An array's own `length` resolves (`items.length`), but a
661
+ // primitive has no world-state members, so `name.length` on a string
662
+ // is undefined and a condition on it is unmet.
659
663
  if (typeof current !== 'object' || !Object.hasOwn(current, part)) {
660
664
  return undefined;
661
665
  }
@@ -123,8 +123,8 @@ export class PlanExecutor {
123
123
  // This allows async unified storage initialization
124
124
  if (!this.config.useUnified) {
125
125
  // Legacy mode: create separate database immediately
126
- this.db = openDatabase(dbPath ?? ':memory:', { walMode: false });
127
- this.db.pragma('journal_mode = WAL');
126
+ // #1164: openDatabase() set the journal mode (retrying contention, honouring AQE_DISABLE_WAL).
127
+ this.db = openDatabase(dbPath ?? ':memory:');
128
128
  }
129
129
  }
130
130
  // ==========================================================================
@@ -911,6 +911,10 @@ export class PlanExecutor {
911
911
  }
912
912
  // #1157: goal and condition keys can come from callers; an inherited
913
913
  // member such as `constructor` is not part of the world state.
914
+ // #1186: deliberately, a key resolves only through own properties of
915
+ // objects. An array's own `length` resolves (`items.length`), but a
916
+ // primitive has no world-state members, so `name.length` on a string
917
+ // is undefined and a condition on it is unmet.
914
918
  if (typeof current !== 'object' || !Object.hasOwn(current, part)) {
915
919
  return undefined;
916
920
  }
@@ -71,23 +71,28 @@ export declare class GitAnalyzer {
71
71
  private isGitRepo;
72
72
  /** After a rev-parse timeout, when to ask git again (until then: "timeout"). */
73
73
  private repoRetryAt;
74
+ /** Files whose git data came back incomplete outside any withFileDeadline() call. */
74
75
  private readonly timedOutFiles;
75
- /** Files inside withFileDeadline() and when their git time runs out. */
76
- private readonly fileDeadlines;
76
+ /** The withFileDeadline() call each async context runs in, so concurrent calls on one file stay apart (#1165). */
77
+ private readonly fileScopes;
77
78
  constructor(config?: GitAnalyzerConfig);
78
79
  /**
79
80
  * Check if current directory is a git repository
80
81
  */
81
82
  isGitRepository(): Promise<boolean>;
82
83
  /**
83
- * True when git timed out while analysing `filePath` since the last call, so
84
- * the analysis returned its "git unavailable" default rather than a result.
84
+ * True when git timed out, or its output overflowed, while analysing
85
+ * `filePath` since the last call, so the analysis returned its "git
86
+ * unavailable" default rather than a result. Inside withFileDeadline() it
87
+ * reports only that call's analyses, not another caller's on the same file (#1165).
85
88
  */
86
89
  consumeTimeout(filePath: string): boolean;
87
90
  /**
88
91
  * Run `work`, during which every analysis of `filePath` also stops at one
89
92
  * shared `fileTimeoutMs` deadline. One file's analyses then wait for git at
90
- * most that long together, rather than `gitTimeoutMs` each (#1115).
93
+ * most that long together, rather than `gitTimeoutMs` each (#1115). Each
94
+ * call has its own deadline and timeout flag, even when calls on the same
95
+ * file overlap (#1165); call consumeTimeout() inside `work` to read the flag.
91
96
  */
92
97
  withFileDeadline<T>(filePath: string, work: () => Promise<T>): Promise<T>;
93
98
  /**
@@ -112,13 +117,16 @@ export declare class GitAnalyzer {
112
117
  getBugHistory(filePath: string): Promise<number>;
113
118
  /**
114
119
  * Get comprehensive file history analysis
120
+ * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`, and
121
+ * an ENOBUFS error when its output overflows; zero history would be a false answer (#1165)
115
122
  */
116
123
  getFileHistory(filePath: string): Promise<FileHistory>;
117
124
  /**
118
125
  * Get files changed since a specific date
119
126
  * @param since - Date to check changes from (default: 24 hours ago)
120
127
  * @returns Array of changed file paths relative to repo root
121
- * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`
128
+ * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`, and
129
+ * an Error when git fails; neither means "no changes" (#1165)
122
130
  */
123
131
  getChangedFiles(since?: Date): Promise<string[]>;
124
132
  /**
@@ -128,13 +136,15 @@ export declare class GitAnalyzer {
128
136
  * @throws Error when `commitHash` is option-shaped (starts with "-") or otherwise
129
137
  * not a safe revision argument; git would otherwise parse it as an option
130
138
  * (e.g. `--output=<path>` writes an arbitrary file). See issue #960.
131
- * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`
139
+ * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`, and
140
+ * an Error when git fails, e.g. on an unknown revision (#1165)
132
141
  */
133
142
  getCommitFiles(commitHash?: string): Promise<string[]>;
134
143
  /**
135
144
  * Get files with uncommitted changes (staged + unstaged)
136
145
  * @returns Array of modified file paths relative to repo root
137
- * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`
146
+ * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`, and
147
+ * an Error when git fails (#1165)
138
148
  */
139
149
  getUncommittedFiles(): Promise<string[]>;
140
150
  /**
@@ -143,13 +153,22 @@ export declare class GitAnalyzer {
143
153
  * never reach a shell.
144
154
  */
145
155
  private countBugFixCommits;
156
+ /**
157
+ * `query`'s paths, or none when the repository has no commit yet, which
158
+ * `git log` and `git diff HEAD` report as an error.
159
+ */
160
+ private unlessUnborn;
146
161
  /**
147
162
  * Run one file's analysis with every git call sharing one `gitTimeoutMs`
148
- * deadline (#1115). When git is unavailable or times out, the analysis
149
- * returns its default, which callers treat as "no git data", and a timeout
150
- * is recorded for consumeTimeout(). A timeout never yields a measured 0.
163
+ * deadline (#1115). When git is unavailable or fails, the analysis returns
164
+ * its default, which callers treat as "no git data", never a measured 0
165
+ * (#1165). A timeout or an output overflow is recorded for consumeTimeout(),
166
+ * or, with `strict`, rejects.
151
167
  */
152
168
  private analyze;
169
+ /** The withFileDeadline() call on `filePath` that the current async context runs in. */
170
+ private scopeFor;
171
+ private markIncomplete;
153
172
  /**
154
173
  * Whether the repo root is a git work tree. A timeout is not an answer: it
155
174
  * is remembered for `cacheTtl` so a hung git is not waited on for every
@@ -9,6 +9,7 @@
9
9
  * - Bug history from commit messages
10
10
  */
11
11
  import * as path from 'path';
12
+ import { AsyncLocalStorage } from 'async_hooks';
12
13
  import { assertSafeGitRef } from './ref-validation.js';
13
14
  import { GitTimeoutError, runGit } from './git-process.js';
14
15
  /**
@@ -35,6 +36,10 @@ const DEFAULT_CONFIG = {
35
36
  };
36
37
  /** Room for `git blame --line-porcelain` on large files (execFileSync allowed 1 MiB). */
37
38
  const GIT_MAX_BUFFER = 64 * 1024 * 1024;
39
+ /** Git had an answer that was not read: it timed out or overflowed the output limit. */
40
+ function isIncompleteRead(error) {
41
+ return error instanceof GitTimeoutError || error?.code === 'ENOBUFS';
42
+ }
38
43
  /**
39
44
  * Git Analyzer for defect prediction metrics
40
45
  */
@@ -44,9 +49,10 @@ export class GitAnalyzer {
44
49
  isGitRepo = null;
45
50
  /** After a rev-parse timeout, when to ask git again (until then: "timeout"). */
46
51
  repoRetryAt = 0;
52
+ /** Files whose git data came back incomplete outside any withFileDeadline() call. */
47
53
  timedOutFiles = new Set();
48
- /** Files inside withFileDeadline() and when their git time runs out. */
49
- fileDeadlines = new Map();
54
+ /** The withFileDeadline() call each async context runs in, so concurrent calls on one file stay apart (#1165). */
55
+ fileScopes = new AsyncLocalStorage();
50
56
  constructor(config = {}) {
51
57
  this.config = { ...DEFAULT_CONFIG, ...config };
52
58
  }
@@ -57,27 +63,31 @@ export class GitAnalyzer {
57
63
  return (await this.repoState()) === true;
58
64
  }
59
65
  /**
60
- * True when git timed out while analysing `filePath` since the last call, so
61
- * the analysis returned its "git unavailable" default rather than a result.
66
+ * True when git timed out, or its output overflowed, while analysing
67
+ * `filePath` since the last call, so the analysis returned its "git
68
+ * unavailable" default rather than a result. Inside withFileDeadline() it
69
+ * reports only that call's analyses, not another caller's on the same file (#1165).
62
70
  */
63
71
  consumeTimeout(filePath) {
64
- return this.timedOutFiles.delete(filePath);
72
+ const scope = this.scopeFor(filePath);
73
+ if (!scope)
74
+ return this.timedOutFiles.delete(filePath);
75
+ const incomplete = scope.incomplete;
76
+ scope.incomplete = false;
77
+ return incomplete;
65
78
  }
66
79
  /**
67
80
  * Run `work`, during which every analysis of `filePath` also stops at one
68
81
  * shared `fileTimeoutMs` deadline. One file's analyses then wait for git at
69
- * most that long together, rather than `gitTimeoutMs` each (#1115).
82
+ * most that long together, rather than `gitTimeoutMs` each (#1115). Each
83
+ * call has its own deadline and timeout flag, even when calls on the same
84
+ * file overlap (#1165); call consumeTimeout() inside `work` to read the flag.
70
85
  */
71
86
  async withFileDeadline(filePath, work) {
72
- if (this.fileDeadlines.has(filePath))
87
+ if (this.scopeFor(filePath))
73
88
  return work();
74
- this.fileDeadlines.set(filePath, Date.now() + this.config.fileTimeoutMs);
75
- try {
76
- return await work();
77
- }
78
- finally {
79
- this.fileDeadlines.delete(filePath);
80
- }
89
+ const scope = { filePath, deadline: Date.now() + this.config.fileTimeoutMs, incomplete: false };
90
+ return this.fileScopes.run(scope, work);
81
91
  }
82
92
  /**
83
93
  * Get file change frequency (commits in last 90 days / 3)
@@ -88,7 +98,7 @@ export class GitAnalyzer {
88
98
  const cached = this.getFromCache(cacheKey);
89
99
  if (cached !== undefined)
90
100
  return cached;
91
- return this.analyze(filePath, 0.4, async (git, relativePath) => {
101
+ return this.analyze(filePath, 0.4, {}, async (git, relativePath) => {
92
102
  // Literal pathspecs preserve route filenames such as app/[id].tsx.
93
103
  // Arguments go to git directly, without shell interpretation.
94
104
  const output = (await git.text(['--literal-pathspecs', 'log', '--oneline', '--since=90 days ago', '--', relativePath])).trim();
@@ -107,7 +117,7 @@ export class GitAnalyzer {
107
117
  const cached = this.getFromCache(cacheKey);
108
118
  if (cached !== undefined)
109
119
  return cached;
110
- return this.analyze(filePath, 0.5, async (git, relativePath) => {
120
+ return this.analyze(filePath, 0.5, {}, async (git, relativePath) => {
111
121
  const blameOutput = await git.text(['--literal-pathspecs', 'blame', '--line-porcelain', '--', relativePath]);
112
122
  // Parse blame output - count authors manually instead of piping through shell
113
123
  const authorCounts = new Map();
@@ -135,7 +145,7 @@ export class GitAnalyzer {
135
145
  const cached = this.getFromCache(cacheKey);
136
146
  if (cached !== undefined)
137
147
  return cached;
138
- return this.analyze(filePath, 0.4, async (git, relativePath) => {
148
+ return this.analyze(filePath, 0.4, {}, async (git, relativePath) => {
139
149
  // First commit: the last line (oldest) of the commits that added the file
140
150
  const added = await git.lines(['--literal-pathspecs', 'log', '--format=%at', '--follow', '--diff-filter=A', '--', relativePath]);
141
151
  const firstCommitTimestamp = parseInt(added[added.length - 1] ?? '', 10);
@@ -172,7 +182,7 @@ export class GitAnalyzer {
172
182
  const cached = this.getFromCache(cacheKey);
173
183
  if (cached !== undefined)
174
184
  return cached;
175
- return this.analyze(filePath, 0.2, async (git, relativePath) => {
185
+ return this.analyze(filePath, 0.2, {}, async (git, relativePath) => {
176
186
  const bugCommits = await this.countBugFixCommits(git, relativePath);
177
187
  const riskScore = Math.min(1, bugCommits / 10); // Normalize: 10+ bug fixes = 1.0
178
188
  this.setCache(cacheKey, riskScore);
@@ -181,14 +191,16 @@ export class GitAnalyzer {
181
191
  }
182
192
  /**
183
193
  * Get comprehensive file history analysis
194
+ * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`, and
195
+ * an ENOBUFS error when its output overflows; zero history would be a false answer (#1165)
184
196
  */
185
197
  async getFileHistory(filePath) {
186
198
  const cacheKey = `history:${filePath}`;
187
199
  const cached = this.getFromCache(cacheKey);
188
200
  if (cached)
189
201
  return cached;
190
- return this.analyze(filePath, this.getDefaultFileHistory(filePath), async (git, relativePath) => {
191
- // Each query yields no lines when the file is not in git
202
+ return this.analyze(filePath, this.getDefaultFileHistory(filePath), { strict: true }, async (git, relativePath) => {
203
+ // `git log` yields no lines when the file is not in git
192
204
  const totalCommits = (await git.lines(['--literal-pathspecs', 'log', '--oneline', '--', relativePath])).length;
193
205
  // Parse authors here instead of piping through sort/wc
194
206
  const uniqueAuthors = new Set(await git.lines(['--literal-pathspecs', 'log', '--format=%ae', '--', relativePath])).size;
@@ -224,14 +236,16 @@ export class GitAnalyzer {
224
236
  * Get files changed since a specific date
225
237
  * @param since - Date to check changes from (default: 24 hours ago)
226
238
  * @returns Array of changed file paths relative to repo root
227
- * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`
239
+ * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`, and
240
+ * an Error when git fails; neither means "no changes" (#1165)
228
241
  */
229
242
  async getChangedFiles(since) {
230
243
  if (!(await this.isGitRepository())) {
231
244
  return [];
232
245
  }
233
246
  const sinceDate = since || new Date(Date.now() - 24 * 60 * 60 * 1000);
234
- const files = await this.query().paths(['log', `--since=${sinceDate.toISOString()}`, '--name-only', '-z', '--format=']);
247
+ const git = this.query();
248
+ const files = await this.unlessUnborn(git, git.paths(['log', `--since=${sinceDate.toISOString()}`, '--name-only', '-z', '--format=']));
235
249
  return Array.from(new Set(files));
236
250
  }
237
251
  /**
@@ -241,7 +255,8 @@ export class GitAnalyzer {
241
255
  * @throws Error when `commitHash` is option-shaped (starts with "-") or otherwise
242
256
  * not a safe revision argument; git would otherwise parse it as an option
243
257
  * (e.g. `--output=<path>` writes an arbitrary file). See issue #960.
244
- * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`
258
+ * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`, and
259
+ * an Error when git fails, e.g. on an unknown revision (#1165)
245
260
  */
246
261
  async getCommitFiles(commitHash = 'HEAD') {
247
262
  // Validate before touching git: there is no shell, so stripping
@@ -255,7 +270,8 @@ export class GitAnalyzer {
255
270
  /**
256
271
  * Get files with uncommitted changes (staged + unstaged)
257
272
  * @returns Array of modified file paths relative to repo root
258
- * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`
273
+ * @throws GitTimeoutError when git does not answer within `gitTimeoutMs`, and
274
+ * an Error when git fails (#1165)
259
275
  */
260
276
  async getUncommittedFiles() {
261
277
  if (!(await this.isGitRepository())) {
@@ -263,7 +279,7 @@ export class GitAnalyzer {
263
279
  }
264
280
  // `diff HEAD` fails before the first commit; `--cached` still lists staged files.
265
281
  const git = this.query();
266
- const unstaged = await git.paths(['diff', '--name-only', '-z', 'HEAD']);
282
+ const unstaged = await this.unlessUnborn(git, git.paths(['diff', '--name-only', '-z', 'HEAD']));
267
283
  const staged = await git.paths(['diff', '--name-only', '-z', '--cached']);
268
284
  return Array.from(new Set([...unstaged, ...staged]));
269
285
  }
@@ -279,28 +295,69 @@ export class GitAnalyzer {
279
295
  const lines = await git.lines(['--literal-pathspecs', 'log', '--oneline', '-i', ...greps, '--', relativePath]);
280
296
  return new Set(lines.map((line) => line.split(' ')[0]).filter(Boolean)).size;
281
297
  }
298
+ /**
299
+ * `query`'s paths, or none when the repository has no commit yet, which
300
+ * `git log` and `git diff HEAD` report as an error.
301
+ */
302
+ async unlessUnborn(git, query) {
303
+ try {
304
+ return await query;
305
+ }
306
+ catch (error) {
307
+ if (error instanceof GitTimeoutError)
308
+ throw error;
309
+ try {
310
+ await git.text(['rev-parse', '--verify', '-q', 'HEAD']);
311
+ }
312
+ catch (headError) {
313
+ if (headError instanceof GitTimeoutError)
314
+ throw headError;
315
+ return [];
316
+ }
317
+ throw error;
318
+ }
319
+ }
282
320
  /**
283
321
  * Run one file's analysis with every git call sharing one `gitTimeoutMs`
284
- * deadline (#1115). When git is unavailable or times out, the analysis
285
- * returns its default, which callers treat as "no git data", and a timeout
286
- * is recorded for consumeTimeout(). A timeout never yields a measured 0.
322
+ * deadline (#1115). When git is unavailable or fails, the analysis returns
323
+ * its default, which callers treat as "no git data", never a measured 0
324
+ * (#1165). A timeout or an output overflow is recorded for consumeTimeout(),
325
+ * or, with `strict`, rejects.
287
326
  */
288
- async analyze(filePath, fallback, work) {
327
+ async analyze(filePath, fallback, options, work) {
328
+ const scope = this.scopeFor(filePath);
289
329
  const repo = await this.repoState();
290
- if (repo !== true) {
291
- if (repo === 'timeout')
292
- this.timedOutFiles.add(filePath);
293
- return fallback;
330
+ if (repo === 'timeout') {
331
+ if (options.strict)
332
+ throw new GitTimeoutError(['rev-parse', '--is-inside-work-tree'], this.config.gitTimeoutMs);
333
+ this.markIncomplete(filePath, scope);
294
334
  }
335
+ if (repo !== true)
336
+ return fallback;
295
337
  try {
296
- return await work(this.query(this.fileDeadlines.get(filePath)), this.getRelativePath(filePath));
338
+ return await work(this.query(scope?.deadline), this.getRelativePath(filePath));
297
339
  }
298
340
  catch (error) {
299
- if (error instanceof GitTimeoutError)
300
- this.timedOutFiles.add(filePath);
341
+ // Any other failure is git's answer for this file, e.g. `blame` of an untracked file.
342
+ if (!isIncompleteRead(error))
343
+ return fallback;
344
+ if (options.strict)
345
+ throw error;
346
+ this.markIncomplete(filePath, scope);
301
347
  return fallback;
302
348
  }
303
349
  }
350
+ /** The withFileDeadline() call on `filePath` that the current async context runs in. */
351
+ scopeFor(filePath) {
352
+ const scope = this.fileScopes.getStore();
353
+ return scope?.filePath === filePath ? scope : undefined;
354
+ }
355
+ markIncomplete(filePath, scope) {
356
+ if (scope)
357
+ scope.incomplete = true;
358
+ else
359
+ this.timedOutFiles.add(filePath);
360
+ }
304
361
  /**
305
362
  * Whether the repo root is a git work tree. A timeout is not an answer: it
306
363
  * is remembered for `cacheTtl` so a hung git is not waited on for every
@@ -335,20 +392,10 @@ export class GitAnalyzer {
335
392
  const text = (args) => runGit(args, {
336
393
  cwd: this.config.repoRoot, timeout: deadline - Date.now(), maxBuffer: GIT_MAX_BUFFER,
337
394
  });
338
- const orNothing = async (args, separator) => {
339
- try {
340
- return (await text(args)).split(separator);
341
- }
342
- catch (error) {
343
- if (error instanceof GitTimeoutError)
344
- throw error;
345
- return [];
346
- }
347
- };
348
395
  return {
349
396
  text,
350
- lines: async (args) => (await orNothing(args, '\n')).map((line) => line.trim()).filter(Boolean),
351
- paths: async (args) => (await orNothing(args, '\0')).filter(Boolean),
397
+ lines: async (args) => (await text(args)).split('\n').map((line) => line.trim()).filter(Boolean),
398
+ paths: async (args) => (await text(args)).split('\0').filter(Boolean),
352
399
  };
353
400
  }
354
401
  /**
@@ -5,24 +5,41 @@
5
5
  * it again later, so a file or symlink swapped in between could be read
6
6
  * unchecked. These readers OPEN first and validate what was opened:
7
7
  *
8
- * - the path's realpath is opened with O_NOFOLLOW (a symlink swapped onto the
9
- * final name fails the open) and O_NONBLOCK (a FIFO cannot hang the open);
8
+ * - the path is resolved the kernel's way (a symlink is followed before a
9
+ * later `..` is applied, as the payload guard does), and that realpath is
10
+ * opened with O_NOFOLLOW (a symlink swapped onto the final name fails the
11
+ * open) and O_NONBLOCK (a FIFO cannot hang the open);
10
12
  * - the descriptor must be a regular file within the size limit (fstat);
11
13
  * - the descriptor's real location (/proc/self/fd/N on Linux; elsewhere the
12
14
  * re-resolved realpath, which must be the same inode) must lie inside the
13
15
  * project root, so a directory component swapped for a symlink is caught;
16
+ * a file that was replaced or unlinked after the open is refused as
17
+ * 'changed-during-read';
14
18
  * - the content is read from that same descriptor, and never past the limit,
15
19
  * even if the file grows after the fstat.
16
20
  *
17
21
  * A path spelled outside the root is refused before any filesystem call,
18
22
  * unless the caller opts into `outsideRoot: 'allow'` for paths it accepts
19
23
  * from a trusted source (the other checks still apply).
24
+ *
25
+ * Hardlinks (#1186): no path check can see a hardlink, because every name of
26
+ * a hardlinked file is equally real and the kernel offers no way to list the
27
+ * other names. `hardlinks: 'refuse'` refuses any file with more than one link
28
+ * (st_nlink > 1), which also refuses a hardlink whose other name is inside
29
+ * the project (pnpm stores, `cp -al` snapshots). A file whose outside name
30
+ * was removed has one link and is read. The policy trusts the link count the
31
+ * filesystem reports: one that reports 1 for every file (FAT, some network
32
+ * shares) hides a hardlink from it. Verified on Linux only.
20
33
  */
21
34
  import { type Stats } from 'node:fs';
22
35
  import { CallerInputError } from '../error-utils.js';
23
36
  /** Default upper bound for a confined read when the caller names none. */
24
37
  export declare const DEFAULT_MAX_CONFINED_READ_BYTES: number;
25
- export type ConfinedReadReason = 'not-found' | 'not-a-file' | 'outside-project-root' | 'unreadable' | 'too-large';
38
+ export type ConfinedReadReason = 'not-found' | 'not-a-file' | 'outside-project-root' | 'unreadable' | 'too-large'
39
+ /** The opened file is no longer at the checked path (replaced or unlinked). */
40
+ | 'changed-during-read'
41
+ /** `hardlinks: 'refuse'` and the file has more than one link. */
42
+ | 'hardlinked';
26
43
  export interface ConfinedReadOptions {
27
44
  /** Project root; defaults to findProjectRoot(). */
28
45
  projectRoot?: string;
@@ -34,6 +51,11 @@ export interface ConfinedReadOptions {
34
51
  * trusts it. Paths spelled inside the root are always held to the root.
35
52
  */
36
53
  outsideRoot?: 'refuse' | 'allow';
54
+ /**
55
+ * 'refuse' refuses a file with more than one hardlink, which a path check
56
+ * cannot confine (see the module comment). Default 'allow'.
57
+ */
58
+ hardlinks?: 'allow' | 'refuse';
37
59
  }
38
60
  /**
39
61
  * A confined read that was refused; `reason` matches the payload guard's.
@@ -52,10 +74,13 @@ export declare const CONFINED_OPEN_FLAGS: number;
52
74
  /** True when `candidate` is `root` or lies beneath it (both absolute). */
53
75
  export declare function isWithinRoot(root: string, candidate: string): boolean;
54
76
  /**
55
- * Where an OPEN descriptor really points. On Linux, /proc/self/fd/N resolves
56
- * to the opened file itself. Elsewhere, re-resolve the path and accept it only
57
- * if it is the same inode as the descriptor, so a swap after the open is
58
- * detected. Returns null when it cannot be proven.
77
+ * Where an OPEN descriptor really points. On Linux, /proc/self/fd/N names the
78
+ * opened file itself; when /proc answers, its answer is final (#1186): a file
79
+ * unlinked or replaced since the open reads as "<path> (deleted)" or names
80
+ * another inode, and is not re-resolved by name. Without /proc (macOS,
81
+ * Windows, /proc not mounted), re-resolve the path and accept it only if it
82
+ * is the same inode as the descriptor, so a swap after the open is detected.
83
+ * Returns null when the opened file is no longer where it was checked.
59
84
  */
60
85
  export declare function openedLocation(fd: number, lexical: string, opened: Stats): Promise<string | null>;
61
86
  /** Synchronous openedLocation, for callers that read synchronously. */