agentic-qe 3.14.8 → 3.15.0

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 (375) hide show
  1. package/.claude/skills/release/SKILL.md +6 -0
  2. package/.claude/skills/skills-manifest.json +1 -1
  3. package/CHANGELOG.md +145 -0
  4. package/README.md +143 -366
  5. package/assets/readme/credit-ruflo.svg +1 -0
  6. package/assets/readme/credit-ruvector.svg +1 -0
  7. package/assets/readme/project-header.svg +1 -0
  8. package/assets/readme/quality-loop.svg +1 -0
  9. package/assets/skills/skills-manifest.json +1 -1
  10. package/dist/adapters/a2a/notifications/retry-queue.js +5 -1
  11. package/dist/adapters/ag-ui/json-patch.js +14 -7
  12. package/dist/adapters/ag-ui/state-delta-cache.js +20 -12
  13. package/dist/cli/bundle.js +5 -5
  14. package/dist/cli/chunks/adapter-D7G5MIDQ.js +2 -0
  15. package/dist/cli/chunks/{agent-booster-wasm-67OKGDGZ.js → agent-booster-wasm-GDHJ6QUN.js} +2 -2
  16. package/dist/cli/chunks/{agent-handler-4HZEQ3WQ.js → agent-handler-MPYYQ2RZ.js} +2 -2
  17. package/dist/cli/chunks/{agent-memory-branch-IBHZQSRN.js → agent-memory-branch-QBSHKLA2.js} +2 -2
  18. package/dist/cli/chunks/aqe-learning-engine-G6TUFGHC.js +2 -0
  19. package/dist/cli/chunks/{arena-LCLRGUIK.js → arena-UJE2FROF.js} +4 -4
  20. package/dist/cli/chunks/{arena-EJBIGSF4.js → arena-WIGSL37B.js} +2 -2
  21. package/dist/cli/chunks/{audit-PY4JNDQQ.js → audit-VT7Y2Z7V.js} +3 -3
  22. package/dist/cli/chunks/base-B45BOC7E.js +2 -0
  23. package/dist/cli/chunks/{better-sqlite3-2JG5K6XT.js → better-sqlite3-DSL7LFRK.js} +2 -2
  24. package/dist/cli/chunks/{brain-handler-3UYK55GA.js → brain-handler-N3C2MDMK.js} +3 -3
  25. package/dist/cli/chunks/{branch-enumerator-GOSWOX46.js → branch-enumerator-B6NSQ3PZ.js} +2 -2
  26. package/dist/cli/chunks/{browser-DC2JV47Z.js → browser-KQ3YNRGW.js} +2 -2
  27. package/dist/cli/chunks/browser-workflow-MIBU4XMV.js +2 -0
  28. package/dist/cli/chunks/{chunk-RM6OC35G.js → chunk-2ORTL5WG.js} +1 -1
  29. package/dist/cli/chunks/{chunk-B2QKBQYD.js → chunk-2ZEV3O24.js} +1 -1
  30. package/dist/cli/chunks/{chunk-H5UH234L.js → chunk-32YSI6OT.js} +1 -1
  31. package/dist/cli/chunks/{chunk-GQJ4QDEN.js → chunk-3DKYBHNA.js} +4 -4
  32. package/dist/cli/chunks/{chunk-BFIXUKOR.js → chunk-3Y24VTZ3.js} +1 -1
  33. package/dist/cli/chunks/{chunk-G36RZF2Y.js → chunk-4BWDCUZZ.js} +1 -1
  34. package/dist/cli/chunks/{chunk-JRLZ7LZ3.js → chunk-4DCDIKBX.js} +2 -2
  35. package/dist/cli/chunks/{chunk-BHPTHC5O.js → chunk-4EEY23JS.js} +2 -2
  36. package/dist/cli/chunks/{chunk-NJEEKYEP.js → chunk-4FOKHGP5.js} +2 -2
  37. package/dist/cli/chunks/{chunk-NEXBTLN6.js → chunk-4OQSAUKR.js} +2 -2
  38. package/dist/cli/chunks/{chunk-KNSQWM2E.js → chunk-4YPL3OXS.js} +2 -2
  39. package/dist/cli/chunks/{chunk-QQVE65ER.js → chunk-5DJGP4TA.js} +2 -2
  40. package/dist/cli/chunks/{chunk-7TNCEVWX.js → chunk-5KN4QL3G.js} +2 -2
  41. package/dist/cli/chunks/{chunk-T6W2EYHC.js → chunk-5LN7FQZI.js} +2 -2
  42. package/dist/cli/chunks/{chunk-KKXH25IH.js → chunk-5PNRUMRV.js} +2 -2
  43. package/dist/cli/chunks/{chunk-G3C7Z6FO.js → chunk-62IEVKN3.js} +2 -2
  44. package/dist/cli/chunks/{chunk-3576QGPP.js → chunk-6GTIJNRO.js} +1 -1
  45. package/dist/cli/chunks/{chunk-SKJQKOFJ.js → chunk-6MN4L6BS.js} +2 -2
  46. package/dist/cli/chunks/{chunk-JTOFLDU7.js → chunk-7D6NVIGP.js} +6 -6
  47. package/dist/cli/chunks/{chunk-M7QKCHLQ.js → chunk-7JABIXP3.js} +2 -2
  48. package/dist/cli/chunks/chunk-7JC3LHA6.js +742 -0
  49. package/dist/cli/chunks/{chunk-LQVS5IWH.js → chunk-7WUHVGGT.js} +2 -2
  50. package/dist/cli/chunks/{chunk-I6NZFBT3.js → chunk-A37YYHUD.js} +2 -2
  51. package/dist/cli/chunks/{chunk-FRC7AFB4.js → chunk-AAQNRZKT.js} +2 -2
  52. package/dist/cli/chunks/{chunk-SPS472C5.js → chunk-AGYPPPXR.js} +2 -2
  53. package/dist/cli/chunks/chunk-AIE6OKCD.js +2 -0
  54. package/dist/cli/chunks/{chunk-5X4HDW5W.js → chunk-ANUZGOLQ.js} +2 -2
  55. package/dist/cli/chunks/{chunk-XFT4FYTC.js → chunk-AQZSF32Y.js} +2 -2
  56. package/dist/cli/chunks/{chunk-BITFGVZ4.js → chunk-ATXAMGVE.js} +2 -2
  57. package/dist/cli/chunks/{chunk-VAXTPLO3.js → chunk-AV3RX2L5.js} +2 -2
  58. package/dist/cli/chunks/{chunk-GHMJFICO.js → chunk-AW5OWYQ4.js} +2 -2
  59. package/dist/cli/chunks/{chunk-GA63ESNT.js → chunk-B6QTNTCU.js} +2 -2
  60. package/dist/cli/chunks/{chunk-HHANMCD2.js → chunk-BAPMEDWC.js} +1 -1
  61. package/dist/cli/chunks/{chunk-EKO5QL2B.js → chunk-BH2SQQ2N.js} +1 -1
  62. package/dist/cli/chunks/{chunk-W7JUD4EZ.js → chunk-C6M27NQE.js} +2 -2
  63. package/dist/cli/chunks/{chunk-4PY44TKH.js → chunk-CMYZWIXS.js} +2 -2
  64. package/dist/cli/chunks/{chunk-3FCHH4VP.js → chunk-CZWWC7GC.js} +1 -1
  65. package/dist/cli/chunks/{chunk-DSJJHPPS.js → chunk-D7NOHASX.js} +3 -3
  66. package/dist/cli/chunks/{chunk-N3ASALOL.js → chunk-DGRE6ZAA.js} +2 -2
  67. package/dist/cli/chunks/{chunk-U2QTL5T2.js → chunk-DSGRXW6K.js} +3 -3
  68. package/dist/cli/chunks/{chunk-F2WAB4WK.js → chunk-DXA7RLYU.js} +2 -2
  69. package/dist/cli/chunks/{chunk-C647D42G.js → chunk-DZHIE5UW.js} +2 -2
  70. package/dist/cli/chunks/{chunk-EMOZ5O5S.js → chunk-EBK6CUBD.js} +1 -1
  71. package/dist/cli/chunks/{chunk-PVJLQ2YZ.js → chunk-EPEKEUCF.js} +1 -1
  72. package/dist/cli/chunks/{chunk-UHLZKH6B.js → chunk-EQ4SDE4L.js} +25 -25
  73. package/dist/cli/chunks/{chunk-HE3BDBAO.js → chunk-EZPWSS3B.js} +2 -2
  74. package/dist/cli/chunks/{chunk-TCQWVVSR.js → chunk-F76SYOBT.js} +1 -1
  75. package/dist/cli/chunks/{chunk-7X3LMTRA.js → chunk-F7JVDLOI.js} +2 -2
  76. package/dist/cli/chunks/{chunk-CLUHGBLN.js → chunk-FCSETOWZ.js} +1 -1
  77. package/dist/cli/chunks/{chunk-77WL5HQW.js → chunk-FFE4XAQA.js} +1 -1
  78. package/dist/cli/chunks/{chunk-4HXFPBAA.js → chunk-FPTZP7W5.js} +1 -1
  79. package/dist/cli/chunks/{chunk-6GNWVPMR.js → chunk-FTFIA4I5.js} +2 -2
  80. package/dist/cli/chunks/{chunk-YHX74M7C.js → chunk-FTS6NGBP.js} +2 -2
  81. package/dist/cli/chunks/{chunk-UNFE4RPV.js → chunk-FZ3TQAPW.js} +1 -1
  82. package/dist/cli/chunks/{chunk-UIWXKRTK.js → chunk-G35KP72N.js} +2 -2
  83. package/dist/cli/chunks/{chunk-D2Y36V5J.js → chunk-GCHDMO5V.js} +2 -2
  84. package/dist/cli/chunks/{chunk-ES7TAJRJ.js → chunk-GRN47ANK.js} +2 -2
  85. package/dist/cli/chunks/{chunk-OVMG6EEF.js → chunk-GV7P5JYF.js} +2 -2
  86. package/dist/cli/chunks/{chunk-XAESN54Q.js → chunk-GX5RFGW2.js} +1 -1
  87. package/dist/cli/chunks/{chunk-SUNXA2UR.js → chunk-H77AUJNW.js} +2 -2
  88. package/dist/cli/chunks/{chunk-T4WQPE77.js → chunk-HBIV7PQH.js} +1 -1
  89. package/dist/cli/chunks/{chunk-VCSNNLWL.js → chunk-HOPXHZA3.js} +2 -2
  90. package/dist/cli/chunks/{chunk-GK5WLUX3.js → chunk-I3BH3KIF.js} +1 -1
  91. package/dist/cli/chunks/{chunk-RTD4U7IW.js → chunk-ILKMNDUM.js} +2 -2
  92. package/dist/cli/chunks/{chunk-LMAI74EP.js → chunk-IRHBR56R.js} +1 -1
  93. package/dist/cli/chunks/{chunk-DZHXCOSK.js → chunk-ISAMM7QA.js} +1 -1
  94. package/dist/cli/chunks/{chunk-6VTC3OHD.js → chunk-ISGFAMHZ.js} +2 -2
  95. package/dist/cli/chunks/{chunk-QPACHVDI.js → chunk-J46XGXPS.js} +1 -1
  96. package/dist/cli/chunks/{chunk-T53ZN4NO.js → chunk-J4XCBOPA.js} +2 -2
  97. package/dist/cli/chunks/{chunk-LKFBW2QM.js → chunk-JIWMFLHV.js} +2 -2
  98. package/dist/cli/chunks/{chunk-A5CLVZC3.js → chunk-JJ7WAU4I.js} +2 -2
  99. package/dist/cli/chunks/{chunk-CQEWL32R.js → chunk-JLPNYHJJ.js} +1 -1
  100. package/dist/cli/chunks/{chunk-6F7MFHTY.js → chunk-JO2YLIZH.js} +2 -2
  101. package/dist/cli/chunks/{chunk-VSPNIDQK.js → chunk-JSYNSJDQ.js} +2 -2
  102. package/dist/cli/chunks/{chunk-AJMAKUS3.js → chunk-JYRBOSOF.js} +2 -2
  103. package/dist/cli/chunks/{chunk-3S5IIK32.js → chunk-KEZ4PXVF.js} +1 -1
  104. package/dist/cli/chunks/{chunk-TT45RCLN.js → chunk-KLGFEHEN.js} +2 -2
  105. package/dist/cli/chunks/{chunk-673XJBGW.js → chunk-KU4WLKDK.js} +2 -2
  106. package/dist/cli/chunks/{chunk-EXQGHTPD.js → chunk-KUTMQBV4.js} +4 -4
  107. package/dist/cli/chunks/{chunk-A53MMSGC.js → chunk-L6PUBB6L.js} +2 -2
  108. package/dist/cli/chunks/{chunk-F6JJNBE5.js → chunk-LDJ5DZT5.js} +1 -1
  109. package/dist/cli/chunks/{chunk-25EEIAHS.js → chunk-LLS6JYPN.js} +2 -2
  110. package/dist/cli/chunks/{chunk-NWUFTLSF.js → chunk-LPCFIFZF.js} +2 -2
  111. package/dist/cli/chunks/{chunk-SMBGK7XI.js → chunk-M5EKZA7Q.js} +1 -1
  112. package/dist/cli/chunks/{chunk-YIWBJ637.js → chunk-MEYSIVMP.js} +2 -2
  113. package/dist/cli/chunks/{chunk-BUVJIVFG.js → chunk-MFGLRMO4.js} +1 -1
  114. package/dist/cli/chunks/{chunk-HBAFXWSO.js → chunk-MM57SD2F.js} +1 -1
  115. package/dist/cli/chunks/{chunk-UQGIC5OX.js → chunk-MO3QXLF2.js} +1 -1
  116. package/dist/cli/chunks/{chunk-WFKE7NZ5.js → chunk-MRIZY6HB.js} +2 -2
  117. package/dist/cli/chunks/{chunk-O4QB2GFL.js → chunk-N2MDNEF7.js} +2 -2
  118. package/dist/cli/chunks/{chunk-GVLRE3BV.js → chunk-N5ZHIQAV.js} +3 -3
  119. package/dist/cli/chunks/{chunk-6GJWT2OY.js → chunk-NZ556KZN.js} +2 -2
  120. package/dist/cli/chunks/{chunk-K6EOHGKS.js → chunk-O5AUOBGU.js} +2 -2
  121. package/dist/cli/chunks/{chunk-RJJIPTVH.js → chunk-OBSX3I4Y.js} +2 -2
  122. package/dist/cli/chunks/{chunk-3X2JSW3R.js → chunk-OLD2CIDI.js} +1 -1
  123. package/dist/cli/chunks/{chunk-AJ5PCJQ2.js → chunk-OTJ22IO2.js} +3 -3
  124. package/dist/cli/chunks/{chunk-J5HTQHJK.js → chunk-OYVDTD3A.js} +2 -2
  125. package/dist/cli/chunks/{chunk-JDOVO4E4.js → chunk-P2PPJUGD.js} +126 -130
  126. package/dist/cli/chunks/{chunk-TUZNWRYC.js → chunk-P4FRYNHL.js} +1 -1
  127. package/dist/cli/chunks/{chunk-56M4QNXU.js → chunk-P4WE6VRR.js} +2 -2
  128. package/dist/cli/chunks/{chunk-QDRFLM77.js → chunk-P725KXHX.js} +2 -2
  129. package/dist/cli/chunks/{chunk-AOD2ES44.js → chunk-P7MNF2SK.js} +2 -2
  130. package/dist/cli/chunks/{chunk-EBV3WFIR.js → chunk-PJU5HVWV.js} +2 -2
  131. package/dist/cli/chunks/{chunk-LTHV4PIG.js → chunk-PN3FYSQ6.js} +2 -2
  132. package/dist/cli/chunks/{chunk-CIEXUYY7.js → chunk-PPFW3H7E.js} +1 -1
  133. package/dist/cli/chunks/{chunk-L5T32SRF.js → chunk-Q4RCUCHD.js} +1 -1
  134. package/dist/cli/chunks/{chunk-Z5UZOYQS.js → chunk-QRALXNNX.js} +2 -2
  135. package/dist/cli/chunks/{chunk-CBWM5NOO.js → chunk-QVX22EIM.js} +2 -2
  136. package/dist/cli/chunks/{chunk-JQAJUXRE.js → chunk-R6CZCMKD.js} +2 -2
  137. package/dist/cli/chunks/chunk-ROK5YQ5P.js +3 -0
  138. package/dist/cli/chunks/{chunk-QP7EKLWU.js → chunk-S2GNFAOC.js} +2 -2
  139. package/dist/cli/chunks/{chunk-JRK5GX56.js → chunk-S644OORE.js} +1 -1
  140. package/dist/cli/chunks/{chunk-TGRHO4ES.js → chunk-S7CROKX4.js} +2 -2
  141. package/dist/cli/chunks/{chunk-BT3MI2BW.js → chunk-S7QUHLXV.js} +1 -1
  142. package/dist/cli/chunks/{chunk-SVP3BP52.js → chunk-UGYXUPGN.js} +2 -2
  143. package/dist/cli/chunks/{chunk-ISBOHF6Y.js → chunk-URRPJ3M7.js} +1 -1
  144. package/dist/cli/chunks/{chunk-R6I5I724.js → chunk-URUOTHPO.js} +2 -2
  145. package/dist/cli/chunks/{chunk-QKM4XT2F.js → chunk-VCYOFWMG.js} +2 -2
  146. package/dist/cli/chunks/{chunk-BCCSV3RH.js → chunk-VQVFGFYK.js} +1 -1
  147. package/dist/cli/chunks/{chunk-QH7C4PTX.js → chunk-VT5SMBEM.js} +1 -1
  148. package/dist/cli/chunks/{chunk-WVEHKAIH.js → chunk-VTGRGYY4.js} +3 -3
  149. package/dist/cli/chunks/{chunk-TP7L4EX6.js → chunk-VWCFXCSV.js} +2 -2
  150. package/dist/cli/chunks/{chunk-OZJQN7YE.js → chunk-VY4557VF.js} +2 -2
  151. package/dist/cli/chunks/{chunk-4RNCVSVN.js → chunk-VYERAOQL.js} +2 -2
  152. package/dist/cli/chunks/{chunk-VV2JVYOI.js → chunk-W6H2SOIK.js} +2 -2
  153. package/dist/cli/chunks/{chunk-VW7AXJQS.js → chunk-WBR4VRQE.js} +2 -2
  154. package/dist/cli/chunks/{chunk-T7YCNOW5.js → chunk-WDV6CBED.js} +2 -2
  155. package/dist/cli/chunks/{chunk-Z6G3QVZ4.js → chunk-WO7NPGUD.js} +19 -19
  156. package/dist/cli/chunks/{chunk-AEYJ4ZLA.js → chunk-WPOYFV4X.js} +1 -1
  157. package/dist/cli/chunks/{chunk-3EKG7HFV.js → chunk-WPSGMTI4.js} +3 -3
  158. package/dist/cli/chunks/{chunk-XECZYQT5.js → chunk-WQMXQO3O.js} +2 -2
  159. package/dist/cli/chunks/{chunk-QYCZYJH7.js → chunk-WR54SKKL.js} +2 -2
  160. package/dist/cli/chunks/{chunk-BTBJ2NLH.js → chunk-X4OESN7M.js} +2 -2
  161. package/dist/cli/chunks/{chunk-HPVYJ6JH.js → chunk-X5RELRY7.js} +2 -2
  162. package/dist/cli/chunks/{chunk-BOIUENWW.js → chunk-X7JEBPEW.js} +1 -1
  163. package/dist/cli/chunks/{chunk-OX7MJFLC.js → chunk-XEABMIUH.js} +2 -2
  164. package/dist/cli/chunks/{chunk-BL6273KR.js → chunk-XELFJC77.js} +3 -3
  165. package/dist/cli/chunks/{chunk-775WGWLL.js → chunk-XPUY3ZKD.js} +2 -2
  166. package/dist/cli/chunks/{chunk-BZIPW2PA.js → chunk-XZDPR6I2.js} +2 -2
  167. package/dist/cli/chunks/{chunk-OA75C4HY.js → chunk-Y63DADOR.js} +2 -2
  168. package/dist/cli/chunks/{chunk-F57FTFWS.js → chunk-YFRZVNE4.js} +2 -2
  169. package/dist/cli/chunks/{chunk-CXUC7YKA.js → chunk-YIDZ3TEN.js} +2 -2
  170. package/dist/cli/chunks/{chunk-LRGTPUJA.js → chunk-Z6CRROLU.js} +2 -2
  171. package/dist/cli/chunks/{chunk-J24AJEDE.js → chunk-ZPH2YT3J.js} +2 -2
  172. package/dist/cli/chunks/{chunk-AUFV2G2J.js → chunk-ZV7LJPSI.js} +5 -5
  173. package/dist/cli/chunks/{chunk-AR2S4DOB.js → chunk-ZXIIB3QE.js} +1 -1
  174. package/dist/cli/chunks/{ci-5LIV2HW5.js → ci-63JINRNB.js} +3 -3
  175. package/dist/cli/chunks/{ci-output-UO5BDFU4.js → ci-output-CRFWLUAA.js} +2 -2
  176. package/dist/cli/chunks/{circuit-breaker-UQDPXYRD.js → circuit-breaker-PJLG3WYL.js} +2 -2
  177. package/dist/cli/chunks/{claude-flow-setup-62QES3QX.js → claude-flow-setup-UKHSQMJU.js} +2 -2
  178. package/dist/cli/chunks/client-A4FTITK3.js +2 -0
  179. package/dist/cli/chunks/{cline-installer-X7VZTSZG.js → cline-installer-PYQ27AS3.js} +2 -2
  180. package/dist/cli/chunks/{code-H3BF4L4H.js → code-K7VGLZ3W.js} +3 -3
  181. package/dist/cli/chunks/{code-index-extractor-BJGFZGGL.js → code-index-extractor-NNWAVWSL.js} +2 -2
  182. package/dist/cli/chunks/{codex-installer-KVZWKU6S.js → codex-installer-U4VJIKRN.js} +2 -2
  183. package/dist/cli/chunks/{completions-YMILE6V7.js → completions-DOCI3P4W.js} +2 -2
  184. package/dist/cli/chunks/{complexity-analyzer-J26N2PWG.js → complexity-analyzer-RFW2QRFR.js} +2 -2
  185. package/dist/cli/chunks/{continuedev-installer-MAR42OV7.js → continuedev-installer-S5WXXOBU.js} +2 -2
  186. package/dist/cli/chunks/{copilot-installer-CVOJF6OT.js → copilot-installer-AAQ6YLVJ.js} +2 -2
  187. package/dist/cli/chunks/core-handlers-FO3QTNWI.js +2 -0
  188. package/dist/cli/chunks/{cost-tracker-SXLWXE55.js → cost-tracker-R4VOHTWQ.js} +2 -2
  189. package/dist/cli/chunks/{coverage-D7HCHFP3.js → coverage-P54HPCLV.js} +3 -3
  190. package/dist/cli/chunks/cross-domain-router-LIV6SRWF.js +2 -0
  191. package/dist/cli/chunks/{cursor-installer-X37VHIKW.js → cursor-installer-VHBWZE5A.js} +2 -2
  192. package/dist/cli/chunks/{daemon-JN7SOH6F.js → daemon-BTRSWNB4.js} +3 -3
  193. package/dist/cli/chunks/{daemon-LIW47IDM.js → daemon-JLH5TTWZ.js} +4 -4
  194. package/dist/cli/chunks/{dag-attention-scheduler-QCHHIZBT.js → dag-attention-scheduler-5Z6DCRFK.js} +2 -2
  195. package/dist/cli/chunks/{detect-WRFCWAX5.js → detect-NWGASRJJ.js} +2 -2
  196. package/dist/cli/chunks/{dist-node-6FWT4XZO.js → dist-node-XMNNSEFJ.js} +2 -2
  197. package/dist/cli/chunks/{domain-handler-SNFPNMRT.js → domain-handler-BWVBZTNR.js} +2 -2
  198. package/dist/cli/chunks/{domain-plugins-MXKHH62P.js → domain-plugins-YAD4USA4.js} +2 -2
  199. package/dist/cli/chunks/{domain-transfer-47UJNERX.js → domain-transfer-Z3MRPZEZ.js} +2 -2
  200. package/dist/cli/chunks/dream-DNLGHYXY.js +2 -0
  201. package/dist/cli/chunks/{embed-and-insert-pattern-LZFAUNBQ.js → embed-and-insert-pattern-5CCO45WC.js} +2 -2
  202. package/dist/cli/chunks/{eval-AMUXTMJB.js → eval-JEMLTGY4.js} +2 -2
  203. package/dist/cli/chunks/{experience-capture-middleware-3D65TR2C.js → experience-capture-middleware-FKVYBBAN.js} +3 -3
  204. package/dist/cli/chunks/{fast-paths-Y7BBMM56.js → fast-paths-TFL32H3C.js} +2 -2
  205. package/dist/cli/chunks/{feature-flags-VESRRQ6V.js → feature-flags-CNGAUUMT.js} +2 -2
  206. package/dist/cli/chunks/{feature-flags-JMQQ7JW4.js → feature-flags-OHGD2NCW.js} +2 -2
  207. package/dist/cli/chunks/{file-discovery-JJKQQUV6.js → file-discovery-IHGDYW34.js} +2 -2
  208. package/dist/cli/chunks/{fleet-WIGHICJF.js → fleet-OGTSDGJ2.js} +3 -3
  209. package/dist/cli/chunks/{gnn-wrapper-BFNPETTT.js → gnn-wrapper-QYTTKNCE.js} +2 -2
  210. package/dist/cli/chunks/{heartbeat-handler-HDXKTGUI.js → heartbeat-handler-R5OD2SKN.js} +4 -4
  211. package/dist/cli/chunks/heartbeat-scheduler-DL4LXXJF.js +2 -0
  212. package/dist/cli/chunks/hnsw-adapter-Y64M43J4.js +2 -0
  213. package/dist/cli/chunks/hnsw-index-5V6DDMTA.js +2 -0
  214. package/dist/cli/chunks/{hnsw-legacy-bridge-6A7OTAPT.js → hnsw-legacy-bridge-ULJWYXBQ.js} +2 -2
  215. package/dist/cli/chunks/{hnswlib-node-LKV2H47B.js → hnswlib-node-SYKJXGE2.js} +2 -2
  216. package/dist/cli/chunks/{hooks-KDSFYQQG.js → hooks-XAJXPXTU.js} +10 -10
  217. package/dist/cli/chunks/hybrid-backend-JWT2V4FQ.js +2 -0
  218. package/dist/cli/chunks/{hypergraph-engine-GDLPEPUC.js → hypergraph-engine-GIBPGW4N.js} +2 -2
  219. package/dist/cli/chunks/{hypergraph-handler-4UMFA2EW.js → hypergraph-handler-ENFK6IDN.js} +3 -3
  220. package/dist/cli/chunks/impact-analyzer-XUZQSZZC.js +2 -0
  221. package/dist/cli/chunks/{init-handler-4GCHPQHD.js → init-handler-CSA62LGT.js} +6 -6
  222. package/dist/cli/chunks/init-wizard-KDJKHEPN.js +2 -0
  223. package/dist/cli/chunks/kernel-MUDYPGFR.js +2 -0
  224. package/dist/cli/chunks/{kilocode-installer-HJZMT2G5.js → kilocode-installer-YXFIRTSA.js} +2 -2
  225. package/dist/cli/chunks/{kiro-installer-WUPY67HG.js → kiro-installer-JW3BG2MQ.js} +2 -2
  226. package/dist/cli/chunks/knowledge-graph-GR52N7PU.js +2 -0
  227. package/dist/cli/chunks/{learning-AXKIS7IG.js → learning-BDBZ7ZVG.js} +3 -3
  228. package/dist/cli/chunks/{llm-router-HUDPNZLJ.js → llm-router-CCX2DYTC.js} +4 -4
  229. package/dist/cli/chunks/llm-router-service-QL6LVKZ4.js +2 -0
  230. package/dist/cli/chunks/{load-RM44POD7.js → load-UJTTEOOK.js} +2 -2
  231. package/dist/cli/chunks/load-test-76V75WZ5.js +2 -0
  232. package/dist/cli/chunks/{mcp-5JVQRBOP.js → mcp-2NAJYREC.js} +2 -2
  233. package/dist/cli/chunks/{memory-VGZ2V6PL.js → memory-C3UQSN5F.js} +5 -5
  234. package/dist/cli/chunks/memory-backend-SMQRS5QN.js +2 -0
  235. package/dist/cli/chunks/{memory-handlers-EI537Z32.js → memory-handlers-ESFIJENU.js} +2 -2
  236. package/dist/cli/chunks/{multi-model-executor-WPRKCSCM.js → multi-model-executor-SIHSHAD7.js} +2 -2
  237. package/dist/cli/chunks/{opencode-installer-YAJMRCQO.js → opencode-installer-KDYHUGPG.js} +2 -2
  238. package/dist/cli/chunks/{orchestrator-MUGWBUYP.js → orchestrator-MJHIQEHD.js} +5 -5
  239. package/dist/cli/chunks/pattern-null-store-MWAJMOYU.js +2 -0
  240. package/dist/cli/chunks/{pattern-usage-recorder-ZQJJ2YNG.js → pattern-usage-recorder-OLBE4UIF.js} +2 -2
  241. package/dist/cli/chunks/{pipeline-F4DXDUDC.js → pipeline-IOK2CV3U.js} +2 -2
  242. package/dist/cli/chunks/{platform-HI3A3OWF.js → platform-53JQ7JXN.js} +2 -2
  243. package/dist/cli/chunks/{plugin-XRITPTR7.js → plugin-L5SDIWDI.js} +2 -2
  244. package/dist/cli/chunks/{prime-radiant-advanced-wasm-HHNJP7CQ.js → prime-radiant-advanced-wasm-2DS67JFS.js} +2 -2
  245. package/dist/cli/chunks/{project-root-2VN4WO2A.js → project-root-LQMOFO2Z.js} +2 -2
  246. package/dist/cli/chunks/protocol-executor-32X3GAJT.js +2 -0
  247. package/dist/cli/chunks/{protocol-handler-ZEVHSEBG.js → protocol-handler-NXG2M43B.js} +2 -2
  248. package/dist/cli/chunks/{prove-C4BLZWBS.js → prove-7K7PFSSX.js} +2 -2
  249. package/dist/cli/chunks/qe-reasoning-bank-KAFV3TGI.js +2 -0
  250. package/dist/cli/chunks/{quality-M3DTE4KK.js → quality-ATILUGMJ.js} +2 -2
  251. package/dist/cli/chunks/{quality-gate-V6KS7ML3.js → quality-gate-MPZMDPIZ.js} +3 -3
  252. package/dist/cli/chunks/queen-coordinator-L3SODGRX.js +2 -0
  253. package/dist/cli/chunks/{real-embeddings-YWSE3IRT.js → real-embeddings-VZN3KIAI.js} +2 -2
  254. package/dist/cli/chunks/{ref-validation-ZWOTFA3T.js → ref-validation-EUATPVXX.js} +2 -2
  255. package/dist/cli/chunks/{roocode-installer-GJBIWETD.js → roocode-installer-7M2GOUNZ.js} +2 -2
  256. package/dist/cli/chunks/router-DDCSSXYQ.js +2 -0
  257. package/dist/cli/chunks/routing-feedback-RFASKYCD.js +2 -0
  258. package/dist/cli/chunks/{routing-handler-CFYLGNAR.js → routing-handler-VWANE652.js} +2 -2
  259. package/dist/cli/chunks/{ruvector-commands-EDKG456B.js → ruvector-commands-B2YIPGOV.js} +2 -2
  260. package/dist/cli/chunks/rvf-dual-writer-HCIF2G56.js +2 -0
  261. package/dist/cli/chunks/rvf-migration-adapter-UVAHQ7SV.js +2 -0
  262. package/dist/cli/chunks/{rvf-migration-coordinator-ZMEYMAI6.js → rvf-migration-coordinator-RQXOQJ5T.js} +2 -2
  263. package/dist/cli/chunks/rvf-native-adapter-F2I5FFHK.js +2 -0
  264. package/dist/cli/chunks/{rvf-store-integrity-AH6PNJP6.js → rvf-store-integrity-7P5YDXRH.js} +2 -2
  265. package/dist/cli/chunks/safe-db-6ZAA4S23.js +2 -0
  266. package/dist/cli/chunks/schedule-SM5Q6UVP.js +2 -0
  267. package/dist/cli/chunks/scheduler-4EYP4EZ6.js +2 -0
  268. package/dist/cli/chunks/{security-ZU2GW3ZM.js → security-VJ7TVSQF.js} +3 -3
  269. package/dist/cli/chunks/{shared-rvf-adapter-5FOVSL3T.js → shared-rvf-adapter-63NXQFBX.js} +2 -2
  270. package/dist/cli/chunks/{shared-rvf-dual-writer-IO4DC4XV.js → shared-rvf-dual-writer-JQRP7P5A.js} +2 -2
  271. package/dist/cli/chunks/sqlite-persistence-KLN2K266.js +2 -0
  272. package/dist/cli/chunks/{standalone-memory-3UXDZ7HI.js → standalone-memory-WJ72PH5P.js} +2 -2
  273. package/dist/cli/chunks/{status-handler-264CHTWS.js → status-handler-G72ZSLAX.js} +2 -2
  274. package/dist/cli/chunks/{structural-health-E2QPUOZE.js → structural-health-HYBGP4BD.js} +2 -2
  275. package/dist/cli/chunks/{sync-N2L2OST4.js → sync-5YMZZIF4.js} +2 -2
  276. package/dist/cli/chunks/{sync-2ACMWM7D.js → sync-O5FQAHT7.js} +2 -2
  277. package/dist/cli/chunks/{task-handler-IB5CVOTY.js → task-handler-E6IFNHZG.js} +2 -2
  278. package/dist/cli/chunks/{task-handlers-QBMYNJHE.js → task-handlers-P3GC2L5L.js} +3 -3
  279. package/dist/cli/chunks/{test-7RGLRDSP.js → test-OU6ERW67.js} +4 -4
  280. package/dist/cli/chunks/{test-scheduling-RJABJT2W.js → test-scheduling-3HY4I3HY.js} +7 -7
  281. package/dist/cli/chunks/{token-bootstrap-JVHMHB72.js → token-bootstrap-A5QA4CWK.js} +2 -2
  282. package/dist/cli/chunks/{token-usage-3ECHQVCY.js → token-usage-MUNQVPFT.js} +2 -2
  283. package/dist/cli/chunks/{transformers-KJH3IJWI.js → transformers-IEO25W5V.js} +2 -2
  284. package/dist/cli/chunks/{tree-sitter-wasm-parser-XN6PFI32.js → tree-sitter-wasm-parser-T2EQHEAY.js} +2 -2
  285. package/dist/cli/chunks/{types-5BAPXOLS.js → types-ODCPGCID.js} +2 -2
  286. package/dist/cli/chunks/unified-memory-B5IA2KKQ.js +2 -0
  287. package/dist/cli/chunks/unified-memory-hnsw-YF74LL3Z.js +2 -0
  288. package/dist/cli/chunks/unified-persistence-VZMGNGWY.js +2 -0
  289. package/dist/cli/chunks/{upgrade-S5NFQZID.js → upgrade-4DN6EIW2.js} +2 -2
  290. package/dist/cli/chunks/{validate-BIBWOLJD.js → validate-TBNAPDE3.js} +2 -2
  291. package/dist/cli/chunks/{validate-swarm-WAA3LBHH.js → validate-swarm-ZN7XXUY4.js} +2 -2
  292. package/dist/cli/chunks/visual-security-ZV3BLLSH.js +2 -0
  293. package/dist/cli/chunks/{web-tree-sitter-OTBQTHAV.js → web-tree-sitter-DWAWVD2X.js} +2 -2
  294. package/dist/cli/chunks/{windsurf-installer-NNQ22EW6.js → windsurf-installer-U6EROS5S.js} +2 -2
  295. package/dist/cli/chunks/{witness-chain-E7MUBOJW.js → witness-chain-EQEJS2P4.js} +2 -2
  296. package/dist/cli/chunks/witness-chain-OA24MQWX.js +2 -0
  297. package/dist/cli/chunks/{witness-chain-repair-FW4QSN4C.js → witness-chain-repair-KBXDRXS3.js} +2 -2
  298. package/dist/cli/chunks/{witness-chain-verifier-YMROEBVL.js → witness-chain-verifier-HSQGZ4R4.js} +2 -2
  299. package/dist/cli/chunks/{witness-key-manager-4CGRNDMJ.js → witness-key-manager-RAODG73T.js} +2 -2
  300. package/dist/cli/chunks/{workflow-4VRSTRAN.js → workflow-KNFJNNKG.js} +4 -4
  301. package/dist/cli/chunks/workflow-orchestrator-IMX2LSVE.js +2 -0
  302. package/dist/cli/chunks/{wrappers-4M4UTGEU.js → wrappers-NIJBA22T.js} +2 -2
  303. package/dist/cli/utils/workflow-parser.js +73 -57
  304. package/dist/domains/code-intelligence/services/metric-collector/test-counter.d.ts +1 -1
  305. package/dist/domains/code-intelligence/services/metric-collector/test-counter.js +17 -15
  306. package/dist/domains/test-execution/services/retry-handler.js +6 -3
  307. package/dist/governance/ab-benchmarking.d.ts +5 -1
  308. package/dist/governance/ab-benchmarking.js +64 -29
  309. package/dist/mcp/bundle.js +414 -412
  310. package/dist/mcp/security/rate-limiter.d.ts +1 -0
  311. package/dist/mcp/security/rate-limiter.js +22 -5
  312. package/dist/mcp/services/session-store.js +17 -17
  313. package/dist/mcp/tools/planning/goap-status.d.ts +2 -0
  314. package/dist/mcp/tools/planning/goap-status.js +8 -2
  315. package/dist/planning/goap-planner.d.ts +3 -0
  316. package/dist/planning/goap-planner.js +80 -37
  317. package/dist/shared/embeddings/embedding-cache.js +1 -1
  318. package/dist/shared/embeddings/nomic-embedder.js +17 -7
  319. package/dist/shared/embeddings/ollama-client.js +5 -3
  320. package/dist/shared/git/git-analyzer.js +31 -30
  321. package/dist/shared/http/http-client.js +20 -13
  322. package/dist/shared/io/file-reader.js +11 -8
  323. package/dist/shared/llm/cache.d.ts +8 -29
  324. package/dist/shared/llm/cache.js +6 -2
  325. package/dist/shared/llm/cost-tracker.js +2 -1
  326. package/dist/shared/llm/provider-manager.js +4 -22
  327. package/dist/shared/llm/providers/gemini.d.ts +1 -0
  328. package/dist/shared/llm/providers/gemini.js +14 -5
  329. package/dist/shared/llm/providers/openrouter.js +6 -3
  330. package/dist/shared/metrics/code-metrics.js +1 -1
  331. package/dist/shared/metrics/system-metrics.js +8 -2
  332. package/dist/shared/retry-engine.js +2 -12
  333. package/dist/test-scheduling/executors/vitest-executor.js +26 -17
  334. package/package.json +3 -1
  335. package/dist/cli/chunks/adapter-XYCOXQCC.js +0 -2
  336. package/dist/cli/chunks/aqe-learning-engine-DTJCROTG.js +0 -2
  337. package/dist/cli/chunks/base-5TQ34GMD.js +0 -2
  338. package/dist/cli/chunks/browser-workflow-KWX4ESTJ.js +0 -2
  339. package/dist/cli/chunks/chunk-7STWD4KJ.js +0 -3
  340. package/dist/cli/chunks/chunk-PFXCRRR6.js +0 -736
  341. package/dist/cli/chunks/chunk-U64QORFO.js +0 -2
  342. package/dist/cli/chunks/client-AJZKCP4I.js +0 -2
  343. package/dist/cli/chunks/core-handlers-MQHEMGDV.js +0 -2
  344. package/dist/cli/chunks/cross-domain-router-3QNMZV5R.js +0 -2
  345. package/dist/cli/chunks/dream-OSWAITPT.js +0 -2
  346. package/dist/cli/chunks/heartbeat-scheduler-BVRVVIE2.js +0 -2
  347. package/dist/cli/chunks/hnsw-adapter-MZTHXULS.js +0 -2
  348. package/dist/cli/chunks/hnsw-index-KHEX4VDG.js +0 -2
  349. package/dist/cli/chunks/hybrid-backend-2B3LCLR4.js +0 -2
  350. package/dist/cli/chunks/impact-analyzer-4R4VWOGQ.js +0 -2
  351. package/dist/cli/chunks/init-wizard-TAOPXHHD.js +0 -2
  352. package/dist/cli/chunks/kernel-6I6VZUWY.js +0 -2
  353. package/dist/cli/chunks/knowledge-graph-KFMTTUR5.js +0 -2
  354. package/dist/cli/chunks/llm-router-service-2D74XVM3.js +0 -2
  355. package/dist/cli/chunks/load-test-53FWOWNS.js +0 -2
  356. package/dist/cli/chunks/memory-backend-KFJDDPEZ.js +0 -2
  357. package/dist/cli/chunks/pattern-null-store-7DMU5CJ4.js +0 -2
  358. package/dist/cli/chunks/protocol-executor-2EMTBTMG.js +0 -2
  359. package/dist/cli/chunks/qe-reasoning-bank-VZHZZPHE.js +0 -2
  360. package/dist/cli/chunks/queen-coordinator-7MYTTUHI.js +0 -2
  361. package/dist/cli/chunks/router-ZD4LXAWA.js +0 -2
  362. package/dist/cli/chunks/routing-feedback-FSLMDVGD.js +0 -2
  363. package/dist/cli/chunks/rvf-dual-writer-LTKTDRFS.js +0 -2
  364. package/dist/cli/chunks/rvf-migration-adapter-IF24EVC5.js +0 -2
  365. package/dist/cli/chunks/rvf-native-adapter-E6JNBKMZ.js +0 -2
  366. package/dist/cli/chunks/safe-db-F6TRB5KZ.js +0 -2
  367. package/dist/cli/chunks/schedule-HBD4BYTE.js +0 -2
  368. package/dist/cli/chunks/scheduler-6FYWPMQC.js +0 -2
  369. package/dist/cli/chunks/sqlite-persistence-DOU72F5Z.js +0 -2
  370. package/dist/cli/chunks/unified-memory-GHAYAXWZ.js +0 -2
  371. package/dist/cli/chunks/unified-memory-hnsw-CCC63YXT.js +0 -2
  372. package/dist/cli/chunks/unified-persistence-HKRHI5PG.js +0 -2
  373. package/dist/cli/chunks/visual-security-APOXJ3Q3.js +0 -2
  374. package/dist/cli/chunks/witness-chain-7IP5IJGT.js +0 -2
  375. package/dist/cli/chunks/workflow-orchestrator-2HNW5ZMQ.js +0 -2
@@ -135,6 +135,7 @@ export declare class RateLimiter {
135
135
  private createBucket;
136
136
  private getBucket;
137
137
  private getEndpointKey;
138
+ private matchesEndpoint;
138
139
  private getConfig;
139
140
  private refillBucket;
140
141
  private buildHeaders;
@@ -86,6 +86,9 @@ export class RateLimiter {
86
86
  * Consume tokens (blocks if not available in sync mode)
87
87
  */
88
88
  consume(clientId, endpoint, tokens = 1) {
89
+ if (!Number.isFinite(tokens) || tokens < 0) {
90
+ throw new RangeError('Token cost must be finite and nonnegative');
91
+ }
89
92
  this.stats.totalRequests++;
90
93
  const now = Date.now();
91
94
  // Get configuration (endpoint-specific or default)
@@ -144,7 +147,10 @@ export class RateLimiter {
144
147
  * Reset a client's bucket
145
148
  */
146
149
  resetClient(clientId) {
147
- this.clientBuckets.delete(clientId);
150
+ for (const key of this.clientBuckets.keys()) {
151
+ if (JSON.parse(key)[0] === clientId)
152
+ this.clientBuckets.delete(key);
153
+ }
148
154
  }
149
155
  /**
150
156
  * Reset all buckets
@@ -177,7 +183,7 @@ export class RateLimiter {
177
183
  * Get client-specific statistics
178
184
  */
179
185
  getClientStats(clientId) {
180
- const bucket = this.clientBuckets.get(clientId);
186
+ const bucket = this.clientBuckets.get(JSON.stringify([clientId, null]));
181
187
  return bucket ? { ...bucket } : null;
182
188
  }
183
189
  /**
@@ -209,7 +215,8 @@ export class RateLimiter {
209
215
  }
210
216
  // Create a composite key for client + endpoint-specific limits
211
217
  const endpointKey = this.getEndpointKey(endpoint);
212
- const bucketKey = endpointKey ? `${clientId}:${endpointKey}` : clientId;
218
+ // Encode boundaries so an endpoint bucket cannot alias another client ID.
219
+ const bucketKey = JSON.stringify([clientId, endpointKey]);
213
220
  let bucket = this.clientBuckets.get(bucketKey);
214
221
  if (!bucket) {
215
222
  bucket = {
@@ -231,19 +238,29 @@ export class RateLimiter {
231
238
  const pattern = typeof limit.pattern === 'string'
232
239
  ? createSafeRegex(limit.pattern)
233
240
  : limit.pattern;
234
- if (pattern && pattern.test(endpoint)) {
241
+ if (pattern && this.matchesEndpoint(pattern, endpoint)) {
235
242
  return `ep${i}`;
236
243
  }
237
244
  }
238
245
  return null;
239
246
  }
247
+ matchesEndpoint(pattern, endpoint) {
248
+ const previousIndex = pattern.lastIndex;
249
+ try {
250
+ pattern.lastIndex = 0;
251
+ return pattern.test(endpoint);
252
+ }
253
+ finally {
254
+ pattern.lastIndex = previousIndex;
255
+ }
256
+ }
240
257
  getConfig(endpoint) {
241
258
  if (endpoint) {
242
259
  for (const limit of this.endpointLimits) {
243
260
  const pattern = typeof limit.pattern === 'string'
244
261
  ? createSafeRegex(limit.pattern)
245
262
  : limit.pattern;
246
- if (pattern && pattern.test(endpoint)) {
263
+ if (pattern && this.matchesEndpoint(pattern, endpoint)) {
247
264
  return {
248
265
  tokensPerSecond: limit.tokensPerSecond,
249
266
  maxBurst: limit.maxBurst,
@@ -80,26 +80,26 @@ export class SessionStore {
80
80
  uuid,
81
81
  parentUuid: this.lastUuid,
82
82
  };
83
+ // Database-free mode keeps bookkeeping without serialization or disk I/O.
84
+ if (!this.persistDisabled) {
85
+ const line = JSON.stringify(fullEntry) + '\n';
86
+ if (!this.fileCreated) {
87
+ // First write: synchronous for write-ahead guarantee
88
+ this.ensureDirectory();
89
+ fs.appendFileSync(this.filePath, line, 'utf-8');
90
+ this.fileCreated = true;
91
+ }
92
+ else {
93
+ // Subsequent writes: buffer and batch
94
+ this.writeBuffer.push(line);
95
+ this.scheduleBatchFlush();
96
+ }
97
+ }
98
+ // Only advance the chain and metadata after the entry has been accepted.
83
99
  this.lastUuid = uuid;
84
100
  this.entryCount++;
85
101
  this.lastActivityAt = fullEntry.timestamp;
86
102
  this.currentState = fullEntry.state;
87
- // Database-free mode: bookkeeping done above; skip all disk I/O.
88
- if (this.persistDisabled) {
89
- return uuid;
90
- }
91
- const line = JSON.stringify(fullEntry) + '\n';
92
- if (!this.fileCreated) {
93
- // First write: synchronous for write-ahead guarantee
94
- this.ensureDirectory();
95
- fs.appendFileSync(this.filePath, line, 'utf-8');
96
- this.fileCreated = true;
97
- }
98
- else {
99
- // Subsequent writes: buffer and batch
100
- this.writeBuffer.push(line);
101
- this.scheduleBatchFlush();
102
- }
103
103
  return uuid;
104
104
  }
105
105
  /**
@@ -112,8 +112,8 @@ export class SessionStore {
112
112
  }
113
113
  if (this.writeBuffer.length > 0 && this.filePath && this.fileCreated) {
114
114
  const batch = this.writeBuffer.join('');
115
- this.writeBuffer = [];
116
115
  fs.appendFileSync(this.filePath, batch, 'utf-8');
116
+ this.writeBuffer = [];
117
117
  }
118
118
  }
119
119
  /**
@@ -109,6 +109,8 @@ export interface PlansResult {
109
109
  createdAt?: string;
110
110
  }>;
111
111
  count: number;
112
+ /** Stored rows omitted from this page because their action sequence is invalid. */
113
+ invalidPlanIds?: string[];
112
114
  reuseStats?: {
113
115
  totalPlans: number;
114
116
  reusedPlans: number;
@@ -11,6 +11,7 @@ import { MCPToolBase, } from '../base.js';
11
11
  import { toErrorMessage } from '../../../shared/error-utils.js';
12
12
  import { getSharedGOAPPlanner, createMockExecutor, getAllQEActions, } from '../../../planning/index.js';
13
13
  import { detectWorldState, defaultedFields, } from './world-state.js';
14
+ const PLAN_STATUSES = ['pending', 'executing', 'completed', 'failed', 'cancelled'];
14
15
  // ============================================================================
15
16
  // Tool Implementation
16
17
  // ============================================================================
@@ -54,7 +55,8 @@ export class GOAPStatusTool extends MCPToolBase {
54
55
  },
55
56
  status: {
56
57
  type: 'string',
57
- description: 'Filter plans by status (pending, executing, completed, failed)',
58
+ description: 'Filter plans by status (pending, executing, completed, failed, cancelled)',
59
+ enum: [...PLAN_STATUSES],
58
60
  },
59
61
  limit: {
60
62
  type: 'number',
@@ -252,8 +254,11 @@ export class GOAPStatusTool extends MCPToolBase {
252
254
  * Get plans
253
255
  */
254
256
  async getPlans(status, limit = 20) {
257
+ if (status !== undefined && !PLAN_STATUSES.includes(status)) {
258
+ return { success: false, error: `filter.status must be one of: ${PLAN_STATUSES.join(', ')}` };
259
+ }
255
260
  const planner = await this.getPlanner();
256
- const [{ plans, count }, reuseStats] = await Promise.all([
261
+ const [{ plans, count, invalidPlanIds }, reuseStats] = await Promise.all([
257
262
  planner.listPlanSummaries(status, limit),
258
263
  planner.getPlanReuseStats(),
259
264
  ]);
@@ -265,6 +270,7 @@ export class GOAPStatusTool extends MCPToolBase {
265
270
  data: {
266
271
  plans,
267
272
  count,
273
+ ...(invalidPlanIds ? { invalidPlanIds } : {}),
268
274
  reuseStats: {
269
275
  totalPlans: reuseStats.totalPlans,
270
276
  reusedPlans: reuseStats.reusedPlans,
@@ -75,6 +75,8 @@ export declare class GOAPPlanner {
75
75
  * bindings on already-seeded databases without requiring a full re-seed.
76
76
  */
77
77
  private backfillActionMethodBindings;
78
+ /** Restore missing estimates only for unchanged legacy library definitions. */
79
+ private backfillActionDurationEstimates;
78
80
  /**
79
81
  * Find an optimal plan using A* search
80
82
  *
@@ -222,6 +224,7 @@ export declare class GOAPPlanner {
222
224
  createdAt: string;
223
225
  }>;
224
226
  count: number;
227
+ invalidPlanIds?: string[];
225
228
  }>;
226
229
  /**
227
230
  * Find a similar plan by goal conditions
@@ -157,6 +157,7 @@ export class GOAPPlanner {
157
157
  // for databases seeded before this feature existed, or before a given
158
158
  // action's binding was added to the library.
159
159
  this.backfillActionMethodBindings();
160
+ this.backfillActionDurationEstimates();
160
161
  await this.loadActions();
161
162
  this.initialized = true;
162
163
  console.log(`[GOAPPlanner] Initialized: ${this.persistence.getDbPath()}`);
@@ -170,12 +171,12 @@ export class GOAPPlanner {
170
171
  const allActions = getAllQEActions();
171
172
  const db = this.ensureDb();
172
173
  const insertAction = db.prepare(`
173
- INSERT INTO goap_actions (id, name, description, category, preconditions, effects, cost, qe_domain, agent_type, method, params, implemented)
174
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
174
+ INSERT INTO goap_actions (id, name, description, category, preconditions, effects, cost, qe_domain, agent_type, method, params, implemented, estimated_duration_ms)
175
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
175
176
  `);
176
177
  for (const action of allActions) {
177
178
  const id = `action-${Date.now()}-${randomUUID().slice(0, 8)}`;
178
- insertAction.run(id, action.name, action.description, action.category, JSON.stringify(action.preconditions), JSON.stringify(action.effects), action.cost, action.qeDomain ?? null, action.agentType ?? null, action.method ?? null, action.params ? JSON.stringify(action.params) : null, action.implemented ? 1 : 0);
179
+ insertAction.run(id, action.name, action.description, action.category, JSON.stringify(action.preconditions), JSON.stringify(action.effects), action.cost, action.qeDomain ?? null, action.agentType ?? null, action.method ?? null, action.params ? JSON.stringify(action.params) : null, action.implemented ? 1 : 0, action.estimatedDurationMs ?? null);
179
180
  }
180
181
  // Seed QE goals using direct insertion
181
182
  const insertGoal = db.prepare(`
@@ -212,6 +213,21 @@ export class GOAPPlanner {
212
213
  update.run(action.method, action.params ? JSON.stringify(action.params) : '{}', action.name);
213
214
  }
214
215
  }
216
+ /** Restore missing estimates only for unchanged legacy library definitions. */
217
+ backfillActionDurationEstimates() {
218
+ const update = this.ensureDb().prepare(`
219
+ UPDATE goap_actions SET estimated_duration_ms = ?
220
+ WHERE estimated_duration_ms IS NULL AND name = ?
221
+ AND agent_type IS ? AND category = ? AND qe_domain IS ?
222
+ AND preconditions = ? AND effects = ?
223
+ AND method IS ? AND params IS ? AND implemented = ?
224
+ `);
225
+ for (const action of getAllQEActions()) {
226
+ if (action.estimatedDurationMs === undefined)
227
+ continue;
228
+ update.run(action.estimatedDurationMs, action.name, action.agentType ?? null, action.category, action.qeDomain ?? null, JSON.stringify(action.preconditions), JSON.stringify(action.effects), action.method ?? null, action.params ? JSON.stringify(action.params) : null, action.implemented ? 1 : 0);
229
+ }
230
+ }
215
231
  // ==========================================================================
216
232
  // Core Planning - A* Search
217
233
  // ==========================================================================
@@ -242,6 +258,7 @@ export class GOAPPlanner {
242
258
  this.recordPlanReuse(reusedPlan.id, true);
243
259
  const clonedPlan = {
244
260
  ...reusedPlan,
261
+ estimatedDurationMs: reusedPlan.actions.reduce((sum, action) => sum + (action.estimatedDurationMs ?? 0), 0),
245
262
  id: `plan-${Date.now()}-${randomUUID().slice(0, 8)}`,
246
263
  initialState: this.cloneState(currentState),
247
264
  reusedFrom: reusedPlan.id,
@@ -306,6 +323,9 @@ export class GOAPPlanner {
306
323
  // Entries are added on insert, updated when a better path is found, and
307
324
  // removed when the node is popped (moved to the closed set).
308
325
  const openSetCosts = new Map();
326
+ // Under a duration budget, cheaper paths can be slower or deeper. Keep
327
+ // nondominated labels rather than closing the entire state at its first cost.
328
+ const durationLabels = new Map();
309
329
  // Issue #535: cost-unit heuristic built once per search from the
310
330
  // actions that can actually move each goal key (see buildHeuristic).
311
331
  const heuristic = this.buildHeuristic(goal, availableActions);
@@ -322,34 +342,39 @@ export class GOAPPlanner {
322
342
  h: startH,
323
343
  f: 0,
324
344
  depth: 0,
345
+ estimatedDurationMs: 0,
325
346
  };
326
347
  startNode.f = startNode.g + startNode.h;
327
348
  openHeap.push(startNode);
328
349
  openSetCosts.set(this.hashState(start), 0);
350
+ durationLabels.set(this.hashState(start), [startNode]);
329
351
  // Constraint defaults
330
352
  const maxIterations = 10000;
331
353
  // Issue #535: constraints.maxSteps caps the search depth (= plan length).
332
354
  const maxPlanLength = constraints?.maxSteps ?? DEFAULT_MAX_PLAN_STEPS;
333
355
  const maxCost = constraints?.maxCost ?? Infinity;
334
356
  const maxDuration = constraints?.maxDurationMs ?? Infinity;
357
+ const boundedDuration = Number.isFinite(maxDuration);
335
358
  let iterations = 0;
336
359
  while (openHeap.length > 0 && iterations < maxIterations) {
337
360
  iterations++;
338
361
  // Get node with lowest f score — O(log n)
339
362
  const current = openHeap.pop();
363
+ const stateKey = this.hashState(current.state);
364
+ if (boundedDuration && !durationLabels.get(stateKey)?.includes(current)) {
365
+ continue; // a later label dominates this queued path
366
+ }
340
367
  // Check if goal reached
341
368
  if (this.meetsConditions(current.state, goal)) {
342
369
  return this.reconstructPlan(current);
343
370
  }
344
- // Generate state hash for closed set
345
- const stateKey = this.hashState(current.state);
346
- if (closedSet.has(stateKey)) {
347
- // Lazy deletion: skip stale duplicate nodes
348
- continue;
371
+ if (!boundedDuration) {
372
+ if (closedSet.has(stateKey)) {
373
+ continue; // lazy deletion for the existing cost-only search
374
+ }
375
+ closedSet.add(stateKey);
376
+ openSetCosts.delete(stateKey);
349
377
  }
350
- closedSet.add(stateKey);
351
- // Node is now closed — remove from open set cost tracker
352
- openSetCosts.delete(stateKey);
353
378
  // Check depth limit
354
379
  if (current.depth >= maxPlanLength) {
355
380
  continue;
@@ -364,7 +389,7 @@ export class GOAPPlanner {
364
389
  const newState = this.applyAction(current.state, action);
365
390
  const newStateKey = this.hashState(newState);
366
391
  // Skip if already visited
367
- if (closedSet.has(newStateKey)) {
392
+ if (!boundedDuration && closedSet.has(newStateKey)) {
368
393
  continue;
369
394
  }
370
395
  // Calculate costs
@@ -379,26 +404,33 @@ export class GOAPPlanner {
379
404
  continue;
380
405
  }
381
406
  // Check duration constraints
382
- const estimatedDuration = current.depth * 1000 + (action.estimatedDurationMs ?? 0);
407
+ const estimatedDuration = current.estimatedDurationMs + (action.estimatedDurationMs ?? 0);
383
408
  if (estimatedDuration > maxDuration) {
384
409
  continue;
385
410
  }
386
- // Only push if this is a better path than any previously seen in the open set
387
- const prevG = openSetCosts.get(newStateKey);
388
- if (prevG !== undefined && g >= prevG) {
389
- continue;
411
+ const next = {
412
+ state: newState, action, parent: current, g, h, f,
413
+ depth: current.depth + 1, estimatedDurationMs: estimatedDuration,
414
+ };
415
+ if (boundedDuration) {
416
+ const labels = durationLabels.get(newStateKey) ?? [];
417
+ if (labels.some((label) => label.g <= g &&
418
+ label.estimatedDurationMs <= estimatedDuration && label.depth <= next.depth)) {
419
+ continue;
420
+ }
421
+ durationLabels.set(newStateKey, [
422
+ ...labels.filter((label) => !(g <= label.g &&
423
+ estimatedDuration <= label.estimatedDurationMs && next.depth <= label.depth)),
424
+ next,
425
+ ]);
426
+ }
427
+ else {
428
+ const prevG = openSetCosts.get(newStateKey);
429
+ if (prevG !== undefined && g >= prevG)
430
+ continue;
431
+ openSetCosts.set(newStateKey, g);
390
432
  }
391
- openSetCosts.set(newStateKey, g);
392
- // Add new node — O(log n)
393
- openHeap.push({
394
- state: newState,
395
- action,
396
- parent: current,
397
- g,
398
- h,
399
- f,
400
- depth: current.depth + 1,
401
- });
433
+ openHeap.push(next);
402
434
  }
403
435
  }
404
436
  // No plan found
@@ -896,20 +928,30 @@ export class GOAPPlanner {
896
928
  ORDER BY created_at DESC, id DESC
897
929
  LIMIT ?
898
930
  `).all(...args, boundedLimit);
899
- const plans = rows.map((row) => {
900
- const actionIds = safeJsonParse(row.action_sequence);
901
- if (!Array.isArray(actionIds)) {
902
- throw new Error(`Invalid action sequence in GOAP plan ${row.id}`);
931
+ const plans = [];
932
+ const invalidPlanIds = [];
933
+ for (const row of rows) {
934
+ let actionIds;
935
+ try {
936
+ actionIds = safeJsonParse(row.action_sequence);
937
+ }
938
+ catch {
939
+ invalidPlanIds.push(row.id);
940
+ continue;
941
+ }
942
+ if (!Array.isArray(actionIds) || !actionIds.every((id) => typeof id === 'string')) {
943
+ invalidPlanIds.push(row.id);
944
+ continue;
903
945
  }
904
- return {
946
+ plans.push({
905
947
  id: row.id,
906
948
  status: row.status,
907
949
  stepCount: actionIds.length,
908
950
  totalCost: row.total_cost,
909
951
  createdAt: row.created_at,
910
- };
911
- });
912
- return { plans, count };
952
+ });
953
+ }
954
+ return { plans, count, ...(invalidPlanIds.length ? { invalidPlanIds } : {}) };
913
955
  }
914
956
  /**
915
957
  * Find a similar plan by goal conditions
@@ -998,7 +1040,8 @@ export class GOAPPlanner {
998
1040
  if (plan.actions.length > maxSteps)
999
1041
  return false;
1000
1042
  if (constraints?.maxDurationMs !== undefined &&
1001
- plan.estimatedDurationMs > constraints.maxDurationMs) {
1043
+ plan.actions.reduce((sum, action) => sum + (action.estimatedDurationMs ?? 0), 0)
1044
+ > constraints.maxDurationMs) {
1002
1045
  return false;
1003
1046
  }
1004
1047
  const allowed = new Set(this.getAvailableActions(constraints).map((a) => a.id));
@@ -22,7 +22,7 @@ export class EmbeddingCache {
22
22
  */
23
23
  hashContent(content, model) {
24
24
  return createHash('sha256')
25
- .update(`${model}:${content}`)
25
+ .update(JSON.stringify([model, content]))
26
26
  .digest('hex');
27
27
  }
28
28
  /**
@@ -14,6 +14,7 @@ import { OllamaClient } from './ollama-client.js';
14
14
  import { EmbeddingCache } from './embedding-cache.js';
15
15
  import { toErrorMessage } from '../error-utils.js';
16
16
  import { EMBEDDING_CONFIG, } from './types.js';
17
+ const PSEUDO_EMBEDDING_MODEL = 'pseudo-embedding';
17
18
  /**
18
19
  * Nomic Embedder for generating code embeddings via Ollama
19
20
  */
@@ -50,17 +51,23 @@ export class NomicEmbedder {
50
51
  * Generate embedding for a single text string
51
52
  */
52
53
  async embed(text) {
53
- // Check cache first
54
- const cached = this.cache.get(text, EMBEDDING_CONFIG.MODEL);
54
+ // Prefer genuine cached vectors, then select the active backend before a
55
+ // single counted lookup so alternate namespaces do not inflate misses.
56
+ let model = this.cache.has(text, EMBEDDING_CONFIG.MODEL) ||
57
+ await this.isOllamaAvailable() || !this.enableFallback
58
+ ? EMBEDDING_CONFIG.MODEL : PSEUDO_EMBEDDING_MODEL;
59
+ const cached = this.cache.get(text, model);
55
60
  if (cached) {
56
61
  return cached;
57
62
  }
58
63
  // Try Ollama first, fall back to pseudo-embedding if unavailable
59
64
  let embedding;
60
65
  if (await this.isOllamaAvailable()) {
66
+ model = EMBEDDING_CONFIG.MODEL;
61
67
  embedding = await this.client.generateEmbedding(text);
62
68
  }
63
69
  else if (this.enableFallback) {
70
+ model = PSEUDO_EMBEDDING_MODEL;
64
71
  embedding = this.generatePseudoEmbedding(text);
65
72
  }
66
73
  else {
@@ -68,7 +75,7 @@ export class NomicEmbedder {
68
75
  `Please run: ollama pull ${EMBEDDING_CONFIG.MODEL}`);
69
76
  }
70
77
  // Cache result
71
- this.cache.set(text, EMBEDDING_CONFIG.MODEL, embedding);
78
+ this.cache.set(text, model, embedding);
72
79
  return embedding;
73
80
  }
74
81
  /**
@@ -181,12 +188,14 @@ export class NomicEmbedder {
181
188
  const formattedText = this.formatForEmbedding(chunk);
182
189
  const chunkStartTime = Date.now();
183
190
  // Check cache
184
- const cachedEmbedding = this.cache.get(formattedText, EMBEDDING_CONFIG.MODEL);
191
+ const cachedModel = useOllama || this.cache.has(formattedText, EMBEDDING_CONFIG.MODEL)
192
+ ? EMBEDDING_CONFIG.MODEL : PSEUDO_EMBEDDING_MODEL;
193
+ const cachedEmbedding = this.cache.get(formattedText, cachedModel);
185
194
  if (cachedEmbedding) {
186
195
  return {
187
196
  chunkId: chunk.id,
188
197
  embedding: cachedEmbedding,
189
- model: EMBEDDING_CONFIG.MODEL,
198
+ model: cachedModel,
190
199
  cached: true,
191
200
  computeTimeMs: Date.now() - chunkStartTime,
192
201
  };
@@ -201,11 +210,12 @@ export class NomicEmbedder {
201
210
  embedding = this.generatePseudoEmbedding(formattedText);
202
211
  }
203
212
  // Cache the result
204
- this.cache.set(formattedText, EMBEDDING_CONFIG.MODEL, embedding);
213
+ const model = useOllama ? EMBEDDING_CONFIG.MODEL : PSEUDO_EMBEDDING_MODEL;
214
+ this.cache.set(formattedText, model, embedding);
205
215
  return {
206
216
  chunkId: chunk.id,
207
217
  embedding,
208
- model: useOllama ? EMBEDDING_CONFIG.MODEL : 'pseudo-embedding',
218
+ model,
209
219
  cached: false,
210
220
  computeTimeMs: Date.now() - chunkStartTime,
211
221
  };
@@ -34,10 +34,12 @@ export class OllamaClient {
34
34
  }
35
35
  const data = await response.json();
36
36
  // Check if configured embedding model is available
37
- // Model names may include tags like ":latest", so use startsWith for matching
37
+ // Match the configured model exactly, allowing its existing tag suffix.
38
38
  if (data.models) {
39
- return data.models.some((model) => model.name?.startsWith(EMBEDDING_CONFIG.MODEL) ||
40
- model.model?.startsWith(EMBEDDING_CONFIG.MODEL));
39
+ return data.models.some((model) => model.name === EMBEDDING_CONFIG.MODEL ||
40
+ model.name?.startsWith(`${EMBEDDING_CONFIG.MODEL}:`) ||
41
+ model.model === EMBEDDING_CONFIG.MODEL ||
42
+ model.model?.startsWith(`${EMBEDDING_CONFIG.MODEL}:`));
41
43
  }
42
44
  return false;
43
45
  }