agentic-qe 3.9.8 → 3.9.10

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 (394) hide show
  1. package/.claude/agents/_shared/executor-preamble.md +86 -0
  2. package/.claude/agents/v3/qe-coverage-specialist.md +20 -1
  3. package/.claude/agents/v3/qe-fleet-commander.md +20 -1
  4. package/.claude/agents/v3/qe-pentest-validator.md +20 -1
  5. package/.claude/agents/v3/qe-queen-coordinator.md +20 -1
  6. package/.claude/agents/v3/qe-risk-assessor.md +20 -1
  7. package/.claude/agents/v3/qe-root-cause-analyzer.md +19 -0
  8. package/.claude/agents/v3/qe-security-auditor.md +20 -1
  9. package/.claude/agents/v3/qe-test-architect.md +33 -1
  10. package/.claude/helpers/advisor-call.cjs +283 -0
  11. package/.claude/skills/README.md +4 -3
  12. package/.claude/skills/a11y-ally/SKILL.md +40 -18
  13. package/.claude/skills/accessibility-testing/SKILL.md +4 -0
  14. package/.claude/skills/compatibility-testing/SKILL.md +23 -0
  15. package/.claude/skills/e2e-flow-verifier/SKILL.md +87 -52
  16. package/.claude/skills/enterprise-integration-testing/SKILL.md +4 -0
  17. package/.claude/skills/localization-testing/SKILL.md +14 -0
  18. package/.claude/skills/observability-testing-patterns/SKILL.md +16 -0
  19. package/.claude/skills/qe-browser/SKILL.md +409 -0
  20. package/.claude/skills/qe-browser/evals/qe-browser.yaml +291 -0
  21. package/.claude/skills/qe-browser/fixtures/package.json +7 -0
  22. package/.claude/skills/qe-browser/fixtures/serve-skills.js +130 -0
  23. package/.claude/skills/qe-browser/references/assertion-kinds.md +132 -0
  24. package/.claude/skills/qe-browser/references/migration-from-playwright.md +195 -0
  25. package/.claude/skills/qe-browser/schemas/output.json +188 -0
  26. package/.claude/skills/qe-browser/scripts/assert.js +378 -0
  27. package/.claude/skills/qe-browser/scripts/batch.js +292 -0
  28. package/.claude/skills/qe-browser/scripts/check-injection.js +267 -0
  29. package/.claude/skills/qe-browser/scripts/intent-score.js +325 -0
  30. package/.claude/skills/qe-browser/scripts/lib/vibium.js +330 -0
  31. package/.claude/skills/qe-browser/scripts/package.json +7 -0
  32. package/.claude/skills/qe-browser/scripts/smoke-test.sh +212 -0
  33. package/.claude/skills/qe-browser/scripts/validate-config.json +46 -0
  34. package/.claude/skills/qe-browser/scripts/visual-diff.js +276 -0
  35. package/.claude/skills/qe-visual-accessibility/SKILL.md +31 -1
  36. package/.claude/skills/security-visual-testing/SKILL.md +18 -0
  37. package/.claude/skills/skills-manifest.json +20 -13
  38. package/.claude/skills/testability-scoring/SKILL.md +23 -0
  39. package/.claude/skills/trust-tier-manifest.json +14 -3
  40. package/.claude/skills/visual-testing-advanced/SKILL.md +41 -1
  41. package/CHANGELOG.md +75 -0
  42. package/README.md +5 -3
  43. package/assets/agents/v3/helpers/advisor-call.cjs +283 -0
  44. package/assets/agents/v3/qe-coverage-specialist.md +20 -1
  45. package/assets/agents/v3/qe-fleet-commander.md +20 -1
  46. package/assets/agents/v3/qe-pentest-validator.md +20 -1
  47. package/assets/agents/v3/qe-queen-coordinator.md +20 -1
  48. package/assets/agents/v3/qe-risk-assessor.md +20 -1
  49. package/assets/agents/v3/qe-root-cause-analyzer.md +19 -0
  50. package/assets/agents/v3/qe-security-auditor.md +20 -1
  51. package/assets/agents/v3/qe-test-architect.md +33 -1
  52. package/assets/skills/README.md +4 -3
  53. package/assets/skills/a11y-ally/SKILL.md +40 -18
  54. package/assets/skills/accessibility-testing/SKILL.md +4 -0
  55. package/assets/skills/compatibility-testing/SKILL.md +23 -0
  56. package/assets/skills/e2e-flow-verifier/SKILL.md +87 -52
  57. package/assets/skills/enterprise-integration-testing/SKILL.md +4 -0
  58. package/assets/skills/localization-testing/SKILL.md +14 -0
  59. package/assets/skills/observability-testing-patterns/SKILL.md +16 -0
  60. package/assets/skills/qe-browser/SKILL.md +409 -0
  61. package/assets/skills/qe-browser/evals/qe-browser.yaml +291 -0
  62. package/assets/skills/qe-browser/fixtures/package.json +7 -0
  63. package/assets/skills/qe-browser/fixtures/serve-skills.js +130 -0
  64. package/assets/skills/qe-browser/references/assertion-kinds.md +132 -0
  65. package/assets/skills/qe-browser/references/migration-from-playwright.md +195 -0
  66. package/assets/skills/qe-browser/schemas/output.json +188 -0
  67. package/assets/skills/qe-browser/scripts/assert.js +378 -0
  68. package/assets/skills/qe-browser/scripts/batch.js +292 -0
  69. package/assets/skills/qe-browser/scripts/check-injection.js +267 -0
  70. package/assets/skills/qe-browser/scripts/intent-score.js +325 -0
  71. package/assets/skills/qe-browser/scripts/lib/vibium.js +330 -0
  72. package/assets/skills/qe-browser/scripts/package.json +7 -0
  73. package/assets/skills/qe-browser/scripts/smoke-test.sh +212 -0
  74. package/assets/skills/qe-browser/scripts/validate-config.json +46 -0
  75. package/assets/skills/qe-browser/scripts/visual-diff.js +276 -0
  76. package/assets/skills/qe-visual-accessibility/SKILL.md +31 -1
  77. package/assets/skills/security-visual-testing/SKILL.md +18 -0
  78. package/assets/skills/skills-manifest.json +211 -15
  79. package/assets/skills/testability-scoring/SKILL.md +23 -0
  80. package/assets/skills/trust-tier-manifest.json +14 -3
  81. package/assets/skills/visual-testing-advanced/SKILL.md +41 -1
  82. package/dist/cli/bundle.js +5 -5
  83. package/dist/cli/chunks/adapter-IKCDCMSI.js +2 -0
  84. package/dist/cli/chunks/{agent-booster-wasm-LAE4NTVX.js → agent-booster-wasm-HM4XSABF.js} +2 -2
  85. package/dist/cli/chunks/{agent-handler-FVXHR6XN.js → agent-handler-UDBDLLO4.js} +2 -2
  86. package/dist/cli/chunks/{agent-memory-branch-Q7LLBA7C.js → agent-memory-branch-VIXQ3DAR.js} +2 -2
  87. package/dist/cli/chunks/aqe-learning-engine-W4WW7SQW.js +2 -0
  88. package/dist/cli/chunks/{audit-YRLKHJLX.js → audit-FWTGLQHH.js} +2 -2
  89. package/dist/cli/chunks/base-UQKFTHOY.js +2 -0
  90. package/dist/cli/chunks/{better-sqlite3-XFGOGICB.js → better-sqlite3-TYI3CCWU.js} +2 -2
  91. package/dist/cli/chunks/{brain-handler-KIUSNVSS.js → brain-handler-45ZGBLSB.js} +3 -3
  92. package/dist/cli/chunks/{branch-enumerator-VKZ4L3FH.js → branch-enumerator-ZBXELCQA.js} +2 -2
  93. package/dist/cli/chunks/{browser-GZVIYFIB.js → browser-2KM5IKEX.js} +2 -2
  94. package/dist/cli/chunks/browser-workflow-NMOEM3HW.js +2 -0
  95. package/dist/cli/chunks/{chunk-7PHNHFZI.js → chunk-226DSROQ.js} +3 -3
  96. package/dist/cli/chunks/{chunk-MGX2BZWE.js → chunk-27B575K6.js} +2 -2
  97. package/dist/cli/chunks/{chunk-P7APAQD6.js → chunk-2IJFZW3N.js} +12 -12
  98. package/dist/cli/chunks/{chunk-TWDWDKOI.js → chunk-32OB4ZYQ.js} +1 -1
  99. package/dist/cli/chunks/{chunk-E4D36LGH.js → chunk-335CCAOL.js} +1 -1
  100. package/dist/cli/chunks/{chunk-Q5PARJC6.js → chunk-34WI4QNF.js} +2 -2
  101. package/dist/cli/chunks/chunk-3A4BL62O.js +2 -0
  102. package/dist/cli/chunks/{chunk-6ZMM7MXA.js → chunk-3AG647MY.js} +2 -2
  103. package/dist/cli/chunks/{chunk-LPRHYSXN.js → chunk-3HIDCXW3.js} +1 -1
  104. package/dist/cli/chunks/{chunk-HN7HYUW6.js → chunk-4EKWEDHA.js} +9 -9
  105. package/dist/cli/chunks/{chunk-JCROLOP6.js → chunk-4FU6YNDP.js} +2 -2
  106. package/dist/cli/chunks/{chunk-A4DJMFDM.js → chunk-4LOJJ4VX.js} +1 -1
  107. package/dist/cli/chunks/{chunk-I25KIHQE.js → chunk-4VOGUZW5.js} +1 -1
  108. package/dist/cli/chunks/{chunk-KJZU3E5G.js → chunk-4ZR5G4MZ.js} +2 -2
  109. package/dist/cli/chunks/{chunk-W45FANJG.js → chunk-52ZHPZVX.js} +2 -2
  110. package/dist/cli/chunks/{chunk-LOANEFGZ.js → chunk-53G3OCGS.js} +2 -2
  111. package/dist/cli/chunks/{chunk-TZMKO6PC.js → chunk-54TZA65H.js} +2 -2
  112. package/dist/cli/chunks/{chunk-GHJRX7PV.js → chunk-5QKTLOGO.js} +1 -1
  113. package/dist/cli/chunks/{chunk-76UL224Z.js → chunk-5TATJQ3Z.js} +2 -2
  114. package/dist/cli/chunks/{chunk-OGFGNAKQ.js → chunk-5V6DRRLO.js} +2 -2
  115. package/dist/cli/chunks/{chunk-BXMIQRF3.js → chunk-6X7WKNDF.js} +2 -2
  116. package/dist/cli/chunks/chunk-7FWZHYYE.js +2 -0
  117. package/dist/cli/chunks/{chunk-R2LWLZ3Y.js → chunk-A2ULGMMG.js} +1 -1
  118. package/dist/cli/chunks/{chunk-AVKDT3UL.js → chunk-A53XKLEA.js} +8 -8
  119. package/dist/cli/chunks/{chunk-GOPE5OB5.js → chunk-A5OIXFFL.js} +1 -1
  120. package/dist/cli/chunks/{chunk-I7OH6RAC.js → chunk-ACNL4NFI.js} +2 -2
  121. package/dist/cli/chunks/{chunk-PBPOSPTY.js → chunk-AE6Y5CNJ.js} +2 -2
  122. package/dist/cli/chunks/{chunk-TN72MXLI.js → chunk-AO4HDN62.js} +2 -2
  123. package/dist/cli/chunks/{chunk-IHJXFWUL.js → chunk-AOA454FC.js} +2 -2
  124. package/dist/cli/chunks/{chunk-N2L7RWNX.js → chunk-B2QVWL5R.js} +2 -2
  125. package/dist/cli/chunks/{chunk-7CFEGUEH.js → chunk-B3L3CT4X.js} +2 -2
  126. package/dist/cli/chunks/{chunk-XVXSQOQG.js → chunk-B4AFVIOA.js} +2 -2
  127. package/dist/cli/chunks/{chunk-S72TSJS4.js → chunk-BCSCJBYQ.js} +2 -2
  128. package/dist/cli/chunks/{chunk-UAI5NPPQ.js → chunk-BIV6HWMT.js} +2 -2
  129. package/dist/cli/chunks/{chunk-XPL3BXLM.js → chunk-BNNH3KZP.js} +1 -1
  130. package/dist/cli/chunks/{chunk-JK6JBNGL.js → chunk-C234RGWZ.js} +2 -2
  131. package/dist/cli/chunks/{chunk-4EAAHMVM.js → chunk-C55GEYDA.js} +2 -2
  132. package/dist/cli/chunks/{chunk-Y67OXEUM.js → chunk-CEBZHZ4O.js} +1 -1
  133. package/dist/cli/chunks/{chunk-A2QLTNN5.js → chunk-CFQHIWWH.js} +1 -1
  134. package/dist/cli/chunks/{chunk-KMGAJRQ6.js → chunk-CJO2V2FB.js} +1 -1
  135. package/dist/cli/chunks/{chunk-5TGK7VTS.js → chunk-CQNXIYQW.js} +2 -2
  136. package/dist/cli/chunks/{chunk-IP2Z4Z6X.js → chunk-D2A4TGZY.js} +1 -1
  137. package/dist/cli/chunks/{chunk-VVNR4R22.js → chunk-DG2OYKUQ.js} +2 -2
  138. package/dist/cli/chunks/{chunk-ELZ5SKEN.js → chunk-DPYCHODC.js} +2 -2
  139. package/dist/cli/chunks/{chunk-WUCWFDBE.js → chunk-E4YKNKQL.js} +2 -2
  140. package/dist/cli/chunks/{chunk-ZCKNGICX.js → chunk-EEWTTYRC.js} +1 -1
  141. package/dist/cli/chunks/{chunk-IFIYNCT2.js → chunk-EGIYLRW5.js} +2 -2
  142. package/dist/cli/chunks/{chunk-DLKRK2GU.js → chunk-EHGTNSJ2.js} +1 -1
  143. package/dist/cli/chunks/{chunk-IIYXSWJN.js → chunk-EJNASXOY.js} +2 -2
  144. package/dist/cli/chunks/{chunk-ZJ4PMOIZ.js → chunk-F7HRGQRS.js} +2 -2
  145. package/dist/cli/chunks/{chunk-2QI5RYVR.js → chunk-FF7TSDO4.js} +2 -2
  146. package/dist/cli/chunks/{chunk-DDDEGBBJ.js → chunk-FIQNVPYY.js} +2 -2
  147. package/dist/cli/chunks/{chunk-F5VLJFVU.js → chunk-FJOBKT7N.js} +1 -1
  148. package/dist/cli/chunks/{chunk-JNJYWWBG.js → chunk-FYI52MFF.js} +6 -6
  149. package/dist/cli/chunks/{chunk-UOSKMAAY.js → chunk-GCNTU3QJ.js} +1 -1
  150. package/dist/cli/chunks/{chunk-4GMV6Z7Y.js → chunk-H56YBNXW.js} +2 -2
  151. package/dist/cli/chunks/{chunk-HTL2WT64.js → chunk-HJMLJNCB.js} +1 -1
  152. package/dist/cli/chunks/chunk-I3IRIJOT.js +2 -0
  153. package/dist/cli/chunks/chunk-IEQ2VYMO.js +3 -0
  154. package/dist/cli/chunks/{chunk-PG7CZ6Q4.js → chunk-IGRKFVFD.js} +2 -2
  155. package/dist/cli/chunks/{chunk-SQ6XZGR4.js → chunk-IJPE6OGD.js} +10 -10
  156. package/dist/cli/chunks/{chunk-AYKMWP7F.js → chunk-IJUL2UMO.js} +1 -1
  157. package/dist/cli/chunks/{chunk-JVH7753D.js → chunk-ISZJAZ2D.js} +1 -1
  158. package/dist/cli/chunks/{chunk-NCXVOOA7.js → chunk-ITDYTODU.js} +2 -2
  159. package/dist/cli/chunks/{chunk-RGCCSAHI.js → chunk-JHUEBBSX.js} +2 -2
  160. package/dist/cli/chunks/{chunk-TDPHLQ2M.js → chunk-JN3CC2TX.js} +2 -2
  161. package/dist/cli/chunks/{chunk-TSDTRJOG.js → chunk-JOEEGNNX.js} +2 -2
  162. package/dist/cli/chunks/{chunk-QVGSD25D.js → chunk-JQX2DHQT.js} +1 -1
  163. package/dist/cli/chunks/{chunk-VHZ653XS.js → chunk-JRG4AFUR.js} +3 -3
  164. package/dist/cli/chunks/{chunk-SP3ZBJ63.js → chunk-JRMNQWRL.js} +3 -3
  165. package/dist/cli/chunks/{chunk-EKDFIYV5.js → chunk-JXDJMVIG.js} +2 -2
  166. package/dist/cli/chunks/{chunk-3WOQMFTD.js → chunk-JYPW22JV.js} +2 -2
  167. package/dist/cli/chunks/{chunk-WJDOOT2M.js → chunk-KK3KVYE7.js} +2 -2
  168. package/dist/cli/chunks/{chunk-4KX6TMKB.js → chunk-KSRAA6ZD.js} +3 -3
  169. package/dist/cli/chunks/chunk-KUCU5ML6.js +6 -0
  170. package/dist/cli/chunks/{chunk-MVW7AACO.js → chunk-KXXLMLMJ.js} +2 -2
  171. package/dist/cli/chunks/{chunk-HE2NWYHK.js → chunk-LKCFJC4Q.js} +1 -1
  172. package/dist/cli/chunks/{chunk-237NNDKL.js → chunk-LODXDV4G.js} +2 -2
  173. package/dist/cli/chunks/{chunk-W4IRWGGR.js → chunk-M4CYXAVP.js} +4 -4
  174. package/dist/cli/chunks/{chunk-R4VOIXJQ.js → chunk-MOLMS6MA.js} +2 -2
  175. package/dist/cli/chunks/{chunk-SDMGF3KD.js → chunk-NBTM2J4B.js} +2 -2
  176. package/dist/cli/chunks/{chunk-X66IXWSO.js → chunk-NIFVFUCU.js} +2 -2
  177. package/dist/cli/chunks/{chunk-266SKKFM.js → chunk-OOHKW3UE.js} +2 -2
  178. package/dist/cli/chunks/{chunk-WXEDVKJS.js → chunk-ORA6NIXN.js} +2 -2
  179. package/dist/cli/chunks/{chunk-ECYDMBDA.js → chunk-OSD55UO7.js} +2 -2
  180. package/dist/cli/chunks/{chunk-SSURIMCL.js → chunk-OWQRMH3G.js} +2 -2
  181. package/dist/cli/chunks/chunk-QFUINEBN.js +2 -0
  182. package/dist/cli/chunks/{chunk-HYACMUUR.js → chunk-RE2IBX7Z.js} +2 -2
  183. package/dist/cli/chunks/{chunk-2V5VKOJ2.js → chunk-RMQQ5UHM.js} +2 -2
  184. package/dist/cli/chunks/{chunk-U62WL3WZ.js → chunk-ROEMVTXC.js} +3 -3
  185. package/dist/cli/chunks/{chunk-YOKRSFGA.js → chunk-SMTAZQJ3.js} +2 -2
  186. package/dist/cli/chunks/{chunk-OZTSMI7P.js → chunk-TO4NGP3E.js} +1 -1
  187. package/dist/cli/chunks/{chunk-LFEBTWFS.js → chunk-TTXYZUTQ.js} +2 -2
  188. package/dist/cli/chunks/{chunk-IZTUAI5T.js → chunk-U4NODKRR.js} +2 -2
  189. package/dist/cli/chunks/{chunk-JD3GH47Z.js → chunk-U635PSAW.js} +2 -2
  190. package/dist/cli/chunks/{chunk-6DBYVKGA.js → chunk-UBT7VCKQ.js} +2 -2
  191. package/dist/cli/chunks/{chunk-YSUMQBMY.js → chunk-UETM5XDO.js} +1 -1
  192. package/dist/cli/chunks/{chunk-BZB5D4BO.js → chunk-URXG7FMO.js} +4 -3
  193. package/dist/cli/chunks/{chunk-M2JBQVBP.js → chunk-VIWDVS24.js} +2 -2
  194. package/dist/cli/chunks/{chunk-6A4FEIE2.js → chunk-VNKCUKUJ.js} +3 -3
  195. package/dist/cli/chunks/{chunk-6KWX7A3R.js → chunk-VXIXHZCN.js} +2 -2
  196. package/dist/cli/chunks/{chunk-YIJDCZVX.js → chunk-WFEXEDMC.js} +2 -2
  197. package/dist/cli/chunks/{chunk-CG3HIYF4.js → chunk-WLX57ULC.js} +2 -2
  198. package/dist/cli/chunks/{chunk-FKODRXOU.js → chunk-WVQZGLCT.js} +2 -2
  199. package/dist/cli/chunks/{chunk-677V67MR.js → chunk-WW5DZ6BU.js} +1 -1
  200. package/dist/cli/chunks/{chunk-7L64UC5U.js → chunk-X364AIY6.js} +1 -1
  201. package/dist/cli/chunks/{chunk-UGJNR52C.js → chunk-XH7D6EGE.js} +1 -1
  202. package/dist/cli/chunks/{chunk-66DCG6RO.js → chunk-XICRAXUR.js} +4 -4
  203. package/dist/cli/chunks/{chunk-ETXK25IY.js → chunk-XMAV7AIC.js} +1 -1
  204. package/dist/cli/chunks/{chunk-NHXFAXEV.js → chunk-XSUPK7FI.js} +1 -1
  205. package/dist/cli/chunks/{chunk-3ZAGYTEC.js → chunk-XSWOB74I.js} +2 -2
  206. package/dist/cli/chunks/chunk-YPIZMTTA.js +14 -0
  207. package/dist/cli/chunks/{chunk-YDW522M7.js → chunk-YT6KBEXE.js} +2 -2
  208. package/dist/cli/chunks/{chunk-P2H5ARHM.js → chunk-ZENLP5LF.js} +1 -1
  209. package/dist/cli/chunks/{ci-A5ZXOEC4.js → ci-WS32HBBS.js} +2 -2
  210. package/dist/cli/chunks/{ci-output-S47BMRYC.js → ci-output-67R5MSLL.js} +2 -2
  211. package/dist/cli/chunks/circuit-breaker-MA562FT7.js +2 -0
  212. package/dist/cli/chunks/{claude-flow-setup-F5WBEBVK.js → claude-flow-setup-4QKGSRS7.js} +2 -2
  213. package/dist/cli/chunks/client-XQGZKXOB.js +2 -0
  214. package/dist/cli/chunks/{cline-installer-HLKR4QDR.js → cline-installer-6VSROHRY.js} +2 -2
  215. package/dist/cli/chunks/{code-MTZWS6JT.js → code-FBPBHVV3.js} +2 -2
  216. package/dist/cli/chunks/{code-index-extractor-BALTZ2WQ.js → code-index-extractor-62F622V2.js} +2 -2
  217. package/dist/cli/chunks/{codex-installer-LI2VIGET.js → codex-installer-LSR6DVCU.js} +2 -2
  218. package/dist/cli/chunks/{completions-TOF4GTNF.js → completions-56QOICBN.js} +2 -2
  219. package/dist/cli/chunks/{complexity-analyzer-IPFXIT6T.js → complexity-analyzer-SDH4NWIS.js} +2 -2
  220. package/dist/cli/chunks/{continuedev-installer-KWI66RBI.js → continuedev-installer-S7ZPL3VC.js} +2 -2
  221. package/dist/cli/chunks/{copilot-installer-REFOE6UF.js → copilot-installer-25GNNKNL.js} +2 -2
  222. package/dist/cli/chunks/{cost-tracker-M2MZQXCN.js → cost-tracker-73J4Y2RS.js} +2 -2
  223. package/dist/cli/chunks/{coverage-UR2XSJCR.js → coverage-WEE2AZ5F.js} +3 -3
  224. package/dist/cli/chunks/cross-domain-router-C2ZFCSXJ.js +2 -0
  225. package/dist/cli/chunks/{cursor-installer-X4PXCVYH.js → cursor-installer-DHQ644T3.js} +2 -2
  226. package/dist/cli/chunks/{daemon-5R6ZEEBB.js → daemon-3WUJ5E3X.js} +3 -3
  227. package/dist/cli/chunks/{dag-attention-scheduler-RUY2RJZA.js → dag-attention-scheduler-IRLAM43H.js} +2 -2
  228. package/dist/cli/chunks/{detect-PX2AYBHM.js → detect-DTSB4T4R.js} +2 -2
  229. package/dist/cli/chunks/{domain-handler-5JXWEO3E.js → domain-handler-DDN2Z5XC.js} +2 -2
  230. package/dist/cli/chunks/{domain-transfer-6M2YLBJY.js → domain-transfer-3RRG4S6R.js} +2 -2
  231. package/dist/cli/chunks/dream-JSZZ67OO.js +2 -0
  232. package/dist/cli/chunks/esm-node-X4TES6NX.js +2 -0
  233. package/dist/cli/chunks/{eval-L6ZBG462.js → eval-UXEP425X.js} +2 -2
  234. package/dist/cli/chunks/{fast-paths-WIFDALFK.js → fast-paths-4XLHS2VN.js} +2 -2
  235. package/dist/cli/chunks/{feature-flags-YLBXFUCN.js → feature-flags-6C2HD76K.js} +2 -2
  236. package/dist/cli/chunks/{feature-flags-GRHF5MTK.js → feature-flags-KXXHAEYF.js} +2 -2
  237. package/dist/cli/chunks/{file-discovery-4HXUB4HN.js → file-discovery-YSDUIZO4.js} +2 -2
  238. package/dist/cli/chunks/{fleet-RPLJXOEP.js → fleet-TYDG5DWK.js} +3 -3
  239. package/dist/cli/chunks/{gnn-wrapper-2D5IOGAT.js → gnn-wrapper-GJVYRPHB.js} +2 -2
  240. package/dist/cli/chunks/{heartbeat-handler-D5SWZZGA.js → heartbeat-handler-X63CM35O.js} +4 -4
  241. package/dist/cli/chunks/{heartbeat-scheduler-WSG4Y3M2.js → heartbeat-scheduler-NYH4CMVM.js} +2 -2
  242. package/dist/cli/chunks/hnsw-adapter-SQCVEHB5.js +2 -0
  243. package/dist/cli/chunks/hnsw-index-UGVC5IDK.js +2 -0
  244. package/dist/cli/chunks/{hnsw-legacy-bridge-UH6RWE74.js → hnsw-legacy-bridge-YDVUZTJI.js} +2 -2
  245. package/dist/cli/chunks/{hnswlib-node-BJ4ZJPMP.js → hnswlib-node-TLBDFWA6.js} +2 -2
  246. package/dist/cli/chunks/{hooks-KGDQNB5T.js → hooks-B6PVGP7D.js} +6 -6
  247. package/dist/cli/chunks/hybrid-router-YZEBKUZJ.js +2 -0
  248. package/dist/cli/chunks/{hypergraph-engine-LARQCK7V.js → hypergraph-engine-OQ2ZEG53.js} +2 -2
  249. package/dist/cli/chunks/{hypergraph-handler-RACF4AOX.js → hypergraph-handler-VPD424MI.js} +3 -3
  250. package/dist/cli/chunks/impact-analyzer-ZIXSRWED.js +2 -0
  251. package/dist/cli/chunks/{init-handler-64AOFMJD.js → init-handler-5WYP6NJW.js} +6 -6
  252. package/dist/cli/chunks/init-wizard-MO6PCXPX.js +2 -0
  253. package/dist/cli/chunks/kernel-P54KQB2F.js +2 -0
  254. package/dist/cli/chunks/{kilocode-installer-4ICIP6QN.js → kilocode-installer-YVY4EVMY.js} +2 -2
  255. package/dist/cli/chunks/{kiro-installer-J2GOV2OB.js → kiro-installer-GNT4BN3A.js} +2 -2
  256. package/dist/cli/chunks/knowledge-graph-GU57FQAQ.js +2 -0
  257. package/dist/cli/chunks/{learning-QD4JVH3K.js → learning-LD2RSBRS.js} +3 -3
  258. package/dist/cli/chunks/llm-router-ALKXFKLQ.js +36 -0
  259. package/dist/cli/chunks/{load-EXKUJMBK.js → load-XAOTGZYB.js} +2 -2
  260. package/dist/cli/chunks/load-test-5RFBTSS7.js +2 -0
  261. package/dist/cli/chunks/{mcp-NSNDZSMH.js → mcp-WDAJHGH4.js} +2 -2
  262. package/dist/cli/chunks/{memory-63JTNVZN.js → memory-M7QD57JD.js} +5 -5
  263. package/dist/cli/chunks/memory-backend-GPOP3IR4.js +2 -0
  264. package/dist/cli/chunks/memory-handlers-2NHGZLQM.js +2 -0
  265. package/dist/cli/chunks/multi-model-executor-2XZQK2IN.js +14 -0
  266. package/dist/cli/chunks/{opencode-installer-244LFSPN.js → opencode-installer-ASCVY3GG.js} +2 -2
  267. package/dist/cli/chunks/{orchestrator-TZB457J6.js → orchestrator-GOZICWN3.js} +22 -19
  268. package/dist/cli/chunks/{pipeline-YLBD2Z5Q.js → pipeline-YHQRJWV3.js} +2 -2
  269. package/dist/cli/chunks/{platform-53PWFZSE.js → platform-4NESYFHN.js} +2 -2
  270. package/dist/cli/chunks/{plugin-6GUQEFJU.js → plugin-E24I2RVB.js} +2 -2
  271. package/dist/cli/chunks/{prime-radiant-advanced-wasm-VCOK7FV5.js → prime-radiant-advanced-wasm-CDVSLR7R.js} +2 -2
  272. package/dist/cli/chunks/protocol-executor-M5IONISJ.js +2 -0
  273. package/dist/cli/chunks/{protocol-handler-25UEGTE2.js → protocol-handler-TGTDKSZB.js} +2 -2
  274. package/dist/cli/chunks/{prove-CTOU5F6G.js → prove-WUKDAMSE.js} +2 -2
  275. package/dist/cli/chunks/provider-manager-BTKK6W7M.js +24 -0
  276. package/dist/cli/chunks/qe-reasoning-bank-WIEXCBVE.js +2 -0
  277. package/dist/cli/chunks/{quality-PB7H5UEF.js → quality-RTIOIS2K.js} +2 -2
  278. package/dist/cli/chunks/queen-coordinator-ZFK6DANW.js +2 -0
  279. package/dist/cli/chunks/{real-embeddings-RWWYCIE5.js → real-embeddings-4JJKAEMO.js} +2 -2
  280. package/dist/cli/chunks/{roocode-installer-U4AGYVKL.js → roocode-installer-XU2IXRBM.js} +2 -2
  281. package/dist/cli/chunks/router-TOFBEI2Q.js +2 -0
  282. package/dist/cli/chunks/routing-feedback-RC2VDP6W.js +2 -0
  283. package/dist/cli/chunks/{routing-handler-NTDKDEBE.js → routing-handler-3KBOCIEN.js} +2 -2
  284. package/dist/cli/chunks/{ruvector-commands-RQKOLQSW.js → ruvector-commands-HHE2ZPX7.js} +2 -2
  285. package/dist/cli/chunks/{rvf-dual-writer-6EZ7S7OG.js → rvf-dual-writer-GAWM2BUZ.js} +2 -2
  286. package/dist/cli/chunks/{rvf-migration-adapter-EBTV6FV2.js → rvf-migration-adapter-HQPEC4BN.js} +2 -2
  287. package/dist/cli/chunks/{rvf-migration-coordinator-MERU7VLY.js → rvf-migration-coordinator-A4K45EFU.js} +2 -2
  288. package/dist/cli/chunks/rvf-native-adapter-ZOQDH3JY.js +2 -0
  289. package/dist/cli/chunks/safe-db-RIP3X32S.js +2 -0
  290. package/dist/cli/chunks/schedule-Q6KZRLWS.js +2 -0
  291. package/dist/cli/chunks/scheduler-SJO5QPAU.js +2 -0
  292. package/dist/cli/chunks/{security-JPDLGHMC.js → security-UIKUNOXB.js} +3 -3
  293. package/dist/cli/chunks/shared-rvf-adapter-JJCR3AWU.js +2 -0
  294. package/dist/cli/chunks/{shared-rvf-dual-writer-7OGLQE5Y.js → shared-rvf-dual-writer-ZUWSLFPH.js} +2 -2
  295. package/dist/cli/chunks/sqlite-persistence-HK2S6XAI.js +2 -0
  296. package/dist/cli/chunks/{status-handler-3TI3DHEL.js → status-handler-E3VSWGA6.js} +2 -2
  297. package/dist/cli/chunks/{structural-health-WCZKXVWS.js → structural-health-Y22H4BOU.js} +2 -2
  298. package/dist/cli/chunks/{sync-AM5T4GYO.js → sync-CA4KWZFS.js} +2 -2
  299. package/dist/cli/chunks/{task-handler-VHDTXPVP.js → task-handler-3EZPIAMD.js} +2 -2
  300. package/dist/cli/chunks/task-handlers-6UVAQAGP.js +2 -0
  301. package/dist/cli/chunks/{test-G6P5XGHM.js → test-Q5DOFSJI.js} +4 -4
  302. package/dist/cli/chunks/{test-scheduling-37RBUN4E.js → test-scheduling-BSXWCIMQ.js} +3 -3
  303. package/dist/cli/chunks/token-bootstrap-XGEZU2CS.js +2 -0
  304. package/dist/cli/chunks/{token-usage-5XGVBLFR.js → token-usage-BZX5TCG6.js} +2 -2
  305. package/dist/cli/chunks/{transformers-JTKWAZJU.js → transformers-7ITQPXAU.js} +2 -2
  306. package/dist/cli/chunks/{tree-sitter-wasm-parser-KW2GWIIQ.js → tree-sitter-wasm-parser-ZYBBNYR3.js} +2 -2
  307. package/dist/cli/chunks/{types-7R72BACI.js → types-ACZ5VVRC.js} +2 -2
  308. package/dist/cli/chunks/unified-memory-EXO6WK33.js +2 -0
  309. package/dist/cli/chunks/unified-memory-hnsw-7HPSTFVV.js +2 -0
  310. package/dist/cli/chunks/unified-persistence-WC3O4WOJ.js +2 -0
  311. package/dist/cli/chunks/{validate-TYB4ZTUL.js → validate-IQL6OVXD.js} +2 -2
  312. package/dist/cli/chunks/{validate-swarm-3TFI6PLT.js → validate-swarm-J52J2K5X.js} +2 -2
  313. package/dist/cli/chunks/{vibium-3YELURJT.js → vibium-XSE76PXE.js} +2 -2
  314. package/dist/cli/chunks/visual-security-COW3OCEE.js +2 -0
  315. package/dist/cli/chunks/{web-tree-sitter-7Q77A27Y.js → web-tree-sitter-YM6QXUIY.js} +2 -2
  316. package/dist/cli/chunks/{windsurf-installer-ASARRM2X.js → windsurf-installer-M27DVL4H.js} +2 -2
  317. package/dist/cli/chunks/{witness-chain-WZ6PNXEY.js → witness-chain-NB5LP73S.js} +2 -2
  318. package/dist/cli/chunks/witness-chain-XQXF3RSP.js +2 -0
  319. package/dist/cli/chunks/{workflow-JDTEE6TY.js → workflow-5DODQ6XS.js} +4 -4
  320. package/dist/cli/chunks/workflow-orchestrator-HSIZEKZM.js +2 -0
  321. package/dist/cli/chunks/{wrappers-X7WZLBZD.js → wrappers-K7HHCIYD.js} +2 -2
  322. package/dist/cli/commands/llm-router.js +252 -0
  323. package/dist/coordination/queen-task-management.js +8 -1
  324. package/dist/init/browser-engine-installer.d.ts +60 -0
  325. package/dist/init/browser-engine-installer.js +92 -0
  326. package/dist/init/init-wizard-steps.js +9 -0
  327. package/dist/init/phases/09-assets.d.ts +2 -0
  328. package/dist/init/phases/09-assets.js +65 -0
  329. package/dist/init/phases/12-verification.js +8 -0
  330. package/dist/init/skills-installer.js +1 -0
  331. package/dist/kernel/unified-memory-schemas.d.ts +1 -1
  332. package/dist/kernel/unified-memory-schemas.js +2 -1
  333. package/dist/mcp/bundle.js +47 -44
  334. package/dist/mcp/protocol-server.js +87 -0
  335. package/dist/routing/advisor/circuit-breaker.d.ts +56 -0
  336. package/dist/routing/advisor/circuit-breaker.js +128 -0
  337. package/dist/routing/advisor/domain-prompts.d.ts +14 -0
  338. package/dist/routing/advisor/domain-prompts.js +53 -0
  339. package/dist/routing/advisor/index.d.ts +10 -0
  340. package/dist/routing/advisor/index.js +9 -0
  341. package/dist/routing/advisor/multi-model-executor.d.ts +60 -0
  342. package/dist/routing/advisor/multi-model-executor.js +176 -0
  343. package/dist/routing/advisor/redaction.d.ts +40 -0
  344. package/dist/routing/advisor/redaction.js +187 -0
  345. package/dist/routing/advisor/types.d.ts +101 -0
  346. package/dist/routing/advisor/types.js +9 -0
  347. package/dist/routing/queen-integration.d.ts +3 -0
  348. package/dist/routing/queen-integration.js +7 -1
  349. package/dist/routing/routing-feedback.d.ts +7 -1
  350. package/dist/routing/routing-feedback.js +57 -11
  351. package/dist/routing/tiny-dancer-router.d.ts +35 -1
  352. package/dist/routing/tiny-dancer-router.js +33 -0
  353. package/dist/routing/types.d.ts +12 -0
  354. package/package.json +1 -1
  355. package/dist/cli/chunks/adapter-D4XQUIJD.js +0 -2
  356. package/dist/cli/chunks/aqe-learning-engine-CGIWYLIP.js +0 -2
  357. package/dist/cli/chunks/base-BYVP2STR.js +0 -2
  358. package/dist/cli/chunks/browser-workflow-PC4N5TKL.js +0 -2
  359. package/dist/cli/chunks/chunk-2K3DJ3EK.js +0 -7
  360. package/dist/cli/chunks/chunk-JBQ4WGB4.js +0 -14
  361. package/dist/cli/chunks/chunk-OT4JADWW.js +0 -2
  362. package/dist/cli/chunks/client-56BU3GAX.js +0 -2
  363. package/dist/cli/chunks/cross-domain-router-XQT52BTB.js +0 -2
  364. package/dist/cli/chunks/dream-LFZCN5WK.js +0 -2
  365. package/dist/cli/chunks/esm-node-EBDIEPKS.js +0 -2
  366. package/dist/cli/chunks/hnsw-adapter-BMXTVGZB.js +0 -2
  367. package/dist/cli/chunks/hnsw-index-YX6XLICT.js +0 -2
  368. package/dist/cli/chunks/impact-analyzer-MGSI2WBK.js +0 -2
  369. package/dist/cli/chunks/init-wizard-TBDWRRMC.js +0 -2
  370. package/dist/cli/chunks/kernel-NV7TO2FK.js +0 -2
  371. package/dist/cli/chunks/knowledge-graph-7REGYH6A.js +0 -2
  372. package/dist/cli/chunks/llm-router-4K4IT2PQ.js +0 -30
  373. package/dist/cli/chunks/load-test-RYQK44TT.js +0 -2
  374. package/dist/cli/chunks/memory-backend-3EBE2DEX.js +0 -2
  375. package/dist/cli/chunks/memory-handlers-2335MVQJ.js +0 -2
  376. package/dist/cli/chunks/protocol-executor-MR37S7GX.js +0 -2
  377. package/dist/cli/chunks/qe-reasoning-bank-DANGLPTH.js +0 -2
  378. package/dist/cli/chunks/queen-coordinator-4YJPYF5F.js +0 -2
  379. package/dist/cli/chunks/router-F4IPY4RQ.js +0 -2
  380. package/dist/cli/chunks/routing-feedback-VGHFIJ5S.js +0 -2
  381. package/dist/cli/chunks/rvf-native-adapter-2P75WF5A.js +0 -2
  382. package/dist/cli/chunks/safe-db-47NEO2RS.js +0 -2
  383. package/dist/cli/chunks/schedule-L5GJW25Z.js +0 -2
  384. package/dist/cli/chunks/scheduler-NGGGSZMO.js +0 -2
  385. package/dist/cli/chunks/shared-rvf-adapter-NKNTYGHO.js +0 -2
  386. package/dist/cli/chunks/sqlite-persistence-TE2ZRHKA.js +0 -2
  387. package/dist/cli/chunks/task-handlers-GEJ36WNB.js +0 -2
  388. package/dist/cli/chunks/token-bootstrap-JPE3LWXQ.js +0 -2
  389. package/dist/cli/chunks/unified-memory-KSBLUZT4.js +0 -2
  390. package/dist/cli/chunks/unified-memory-hnsw-V3EOMQIZ.js +0 -2
  391. package/dist/cli/chunks/unified-persistence-URIRJ4BM.js +0 -2
  392. package/dist/cli/chunks/visual-security-DJOOVCBZ.js +0 -2
  393. package/dist/cli/chunks/witness-chain-ZWJUCXCJ.js +0 -2
  394. package/dist/cli/chunks/workflow-orchestrator-5CKA6Q74.js +0 -2
@@ -0,0 +1,276 @@
1
+ #!/usr/bin/env node
2
+ // qe-browser: visual regression against stored PNG baselines.
3
+ //
4
+ // Usage:
5
+ // node visual-diff.js --name homepage
6
+ // node visual-diff.js --name homepage --threshold 0.02
7
+ // node visual-diff.js --name hero --selector "#hero" # not supported in v26.3.x
8
+ // node visual-diff.js --name homepage --update-baseline
9
+ //
10
+ // THRESHOLD SEMANTICS (M1 — devil's-advocate finding):
11
+ // --threshold is the MAX FRACTION of pixels allowed to differ before the
12
+ // check fails. The default is 0.10 (10% of pixels may differ).
13
+ // - threshold 0.00 → require pixel-perfect match
14
+ // - threshold 0.02 → allow up to 2% pixel difference
15
+ // - threshold 0.50 → allow up to 50% pixel difference (very lax)
16
+ // Internally we compute `similarity = 1 - diffPixels / totalPixels` and
17
+ // pass when `similarity >= 1 - threshold`. This is the standard convention
18
+ // used by Playwright's `maxDiffPixelRatio` and BackstopJS.
19
+ //
20
+ // Baselines live in .aqe/visual-baselines/<sanitized-name>.png
21
+ // Diff images (if pixelmatch available) go to .aqe/visual-baselines/<name>.diff.png
22
+
23
+ 'use strict';
24
+
25
+ const fs = require('node:fs');
26
+ const path = require('node:path');
27
+ const crypto = require('node:crypto');
28
+ const {
29
+ vibium,
30
+ envelope,
31
+ parseArgs,
32
+ emit,
33
+ fail,
34
+ runOrSkip,
35
+ rethrowIfUnavailable,
36
+ } = require('./lib/vibium');
37
+
38
+ const BASELINE_DIR = path.join(process.cwd(), '.aqe', 'visual-baselines');
39
+
40
+ function sanitize(name) {
41
+ return String(name).replace(/[^A-Za-z0-9_-]/g, '_');
42
+ }
43
+
44
+ function ensureDir(dir) {
45
+ fs.mkdirSync(dir, { recursive: true });
46
+ }
47
+
48
+ // Vibium screenshot quirks (verified against v26.3.18 on 2026-04-09):
49
+ // 1. `vibium screenshot -o <path>` IGNORES the directory in <path>.
50
+ // Only the basename is used, and the file is saved to
51
+ // `~/Pictures/Vibium/<basename>`. We work around this by reading from
52
+ // Vibium's actual output dir and copying to the requested location.
53
+ // 2. `--selector` flag does NOT exist on `vibium screenshot`. Selector-
54
+ // scoped baselines are not supported in v26.3.x. We surface a clear
55
+ // error if a caller passes one. Future Vibium versions may add it.
56
+ function vibiumPicturesDir() {
57
+ // Vibium hardcodes ~/Pictures/Vibium as the screenshot output directory.
58
+ return path.join(process.env.HOME || '/home/vscode', 'Pictures', 'Vibium');
59
+ }
60
+
61
+ function captureScreenshot(selector, outputPath) {
62
+ if (selector) {
63
+ throw new Error(
64
+ 'vibium screenshot --selector is not supported in Vibium v26.3.x. ' +
65
+ 'Drop the --selector argument and crop the resulting full-page PNG with ' +
66
+ 'a separate image-processing step (e.g. ImageMagick `convert -crop`). ' +
67
+ 'Tracking upstream — if Vibium adds --selector support, this script ' +
68
+ 'should switch to passing it through.'
69
+ );
70
+ }
71
+ const basename = path.basename(outputPath);
72
+ const args = ['screenshot', '-o', basename, '--full-page'];
73
+ const res = vibium(args);
74
+ if (res.status !== 0) {
75
+ throw new Error(`vibium screenshot failed: ${res.stderr.trim() || res.stdout.trim()}`);
76
+ }
77
+ // Vibium wrote the file to ~/Pictures/Vibium/<basename>, not outputPath.
78
+ // Copy it to where the caller asked. Use copy-then-unlink so we leave
79
+ // Vibium's own dir clean for the next run.
80
+ const vibiumPath = path.join(vibiumPicturesDir(), basename);
81
+ if (!fs.existsSync(vibiumPath)) {
82
+ throw new Error(`screenshot output not created at ${vibiumPath} (vibium said: ${res.stdout.trim()})`);
83
+ }
84
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
85
+ fs.copyFileSync(vibiumPath, outputPath);
86
+ fs.unlinkSync(vibiumPath);
87
+ return outputPath;
88
+ }
89
+
90
+ function tryLoadPixelmatch() {
91
+ try {
92
+ const pixelmatch = require('pixelmatch');
93
+ const { PNG } = require('pngjs');
94
+ return { pixelmatch, PNG };
95
+ } catch (_err) {
96
+ return null;
97
+ }
98
+ }
99
+
100
+ function parsePngSize(buffer) {
101
+ // PNG header: 8 bytes signature + 8 bytes IHDR chunk length/type + 4 width + 4 height
102
+ if (buffer.length < 24) return null;
103
+ const sig = buffer.slice(0, 8);
104
+ const expected = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
105
+ if (!sig.equals(expected)) return null;
106
+ const width = buffer.readUInt32BE(16);
107
+ const height = buffer.readUInt32BE(20);
108
+ return { width, height };
109
+ }
110
+
111
+ function hashBuffer(buf) {
112
+ return crypto.createHash('sha256').update(buf).digest('hex');
113
+ }
114
+
115
+ function compareWithPixelmatch(baselineBuf, currentBuf, diffPath) {
116
+ const mod = tryLoadPixelmatch();
117
+ if (!mod) return null;
118
+ const { pixelmatch, PNG } = mod;
119
+ const baseline = PNG.sync.read(baselineBuf);
120
+ const current = PNG.sync.read(currentBuf);
121
+ if (baseline.width !== current.width || baseline.height !== current.height) {
122
+ return {
123
+ similarity: 0,
124
+ diffPixelCount: Math.max(
125
+ baseline.width * baseline.height,
126
+ current.width * current.height
127
+ ),
128
+ width: current.width,
129
+ height: current.height,
130
+ sizeMismatch: true,
131
+ };
132
+ }
133
+ const { width, height } = baseline;
134
+ const diff = new PNG({ width, height });
135
+ const diffCount = pixelmatch(baseline.data, current.data, diff.data, width, height, {
136
+ threshold: 0.1,
137
+ });
138
+ if (diffPath) {
139
+ fs.writeFileSync(diffPath, PNG.sync.write(diff));
140
+ }
141
+ const totalPixels = width * height;
142
+ return {
143
+ similarity: 1 - diffCount / totalPixels,
144
+ diffPixelCount: diffCount,
145
+ width,
146
+ height,
147
+ sizeMismatch: false,
148
+ };
149
+ }
150
+
151
+ function compareFallback(baselineBuf, currentBuf) {
152
+ // Exact-match fallback when pixelmatch is not installed.
153
+ // Same hash = identical; otherwise we only know width/height and rough similarity from byte diff.
154
+ const bSize = parsePngSize(baselineBuf);
155
+ const cSize = parsePngSize(currentBuf);
156
+ if (!bSize || !cSize) {
157
+ return {
158
+ similarity: 0,
159
+ diffPixelCount: 0,
160
+ width: cSize ? cSize.width : 0,
161
+ height: cSize ? cSize.height : 0,
162
+ sizeMismatch: true,
163
+ note: 'pixelmatch not installed and PNG header unreadable',
164
+ };
165
+ }
166
+ if (bSize.width !== cSize.width || bSize.height !== cSize.height) {
167
+ return {
168
+ similarity: 0,
169
+ diffPixelCount: 0,
170
+ width: cSize.width,
171
+ height: cSize.height,
172
+ sizeMismatch: true,
173
+ note: 'pixelmatch not installed; size mismatch',
174
+ };
175
+ }
176
+ const same = hashBuffer(baselineBuf) === hashBuffer(currentBuf);
177
+ return {
178
+ similarity: same ? 1 : 0,
179
+ diffPixelCount: same ? 0 : bSize.width * bSize.height,
180
+ width: cSize.width,
181
+ height: cSize.height,
182
+ sizeMismatch: false,
183
+ note: same ? undefined : 'pixelmatch not installed; exact-hash fallback reports 0 similarity',
184
+ };
185
+ }
186
+
187
+ function main() {
188
+ const args = parseArgs(process.argv.slice(2));
189
+ const name = args.name;
190
+ if (!name) return fail('visual-diff', 'missing --name argument');
191
+
192
+ const threshold = args.threshold !== undefined ? parseFloat(args.threshold) : 0.1;
193
+ if (Number.isNaN(threshold) || threshold < 0 || threshold > 1) {
194
+ return fail('visual-diff', '--threshold must be between 0 and 1');
195
+ }
196
+ const updateBaseline = Boolean(args['update-baseline']);
197
+ const selector = args.selector;
198
+
199
+ try {
200
+ ensureDir(BASELINE_DIR);
201
+ const sanitized = sanitize(name);
202
+ const baselinePath = path.join(BASELINE_DIR, `${sanitized}.png`);
203
+ const currentPath = path.join(BASELINE_DIR, `${sanitized}.current.png`);
204
+ const diffPath = path.join(BASELINE_DIR, `${sanitized}.diff.png`);
205
+
206
+ const startedAt = Date.now();
207
+ captureScreenshot(selector, currentPath);
208
+ const currentBuf = fs.readFileSync(currentPath);
209
+
210
+ if (!fs.existsSync(baselinePath) || updateBaseline) {
211
+ fs.writeFileSync(baselinePath, currentBuf);
212
+ const size = parsePngSize(currentBuf) || { width: 0, height: 0 };
213
+ return emit(
214
+ envelope({
215
+ operation: 'visual-diff',
216
+ summary: updateBaseline
217
+ ? `Baseline "${name}" updated`
218
+ : `Baseline "${name}" created`,
219
+ status: 'success',
220
+ details: {
221
+ visualDiff: {
222
+ name,
223
+ status: updateBaseline ? 'baseline_updated' : 'baseline_created',
224
+ similarity: 1,
225
+ diffPixelCount: 0,
226
+ width: size.width,
227
+ height: size.height,
228
+ threshold,
229
+ baselinePath,
230
+ },
231
+ },
232
+ metadata: { executionTimeMs: Date.now() - startedAt },
233
+ })
234
+ );
235
+ }
236
+
237
+ const baselineBuf = fs.readFileSync(baselinePath);
238
+ let cmp = compareWithPixelmatch(baselineBuf, currentBuf, diffPath);
239
+ if (cmp === null) cmp = compareFallback(baselineBuf, currentBuf);
240
+
241
+ const passed = cmp.similarity >= 1 - threshold && !cmp.sizeMismatch;
242
+ return emit(
243
+ envelope({
244
+ operation: 'visual-diff',
245
+ summary: passed
246
+ ? `Visual match for "${name}" (similarity ${cmp.similarity.toFixed(4)})`
247
+ : `Visual mismatch for "${name}" (similarity ${cmp.similarity.toFixed(4)} below threshold ${1 - threshold})`,
248
+ status: passed ? 'success' : 'failed',
249
+ details: {
250
+ visualDiff: {
251
+ name,
252
+ status: passed ? 'match' : 'mismatch',
253
+ similarity: cmp.similarity,
254
+ diffPixelCount: cmp.diffPixelCount,
255
+ width: cmp.width,
256
+ height: cmp.height,
257
+ threshold,
258
+ baselinePath,
259
+ diffPath: fs.existsSync(diffPath) ? diffPath : undefined,
260
+ note: cmp.note,
261
+ },
262
+ },
263
+ metadata: { executionTimeMs: Date.now() - startedAt },
264
+ })
265
+ );
266
+ } catch (err) {
267
+ rethrowIfUnavailable(err); // F1
268
+ return fail('visual-diff', err.message);
269
+ }
270
+ }
271
+
272
+ if (require.main === module) {
273
+ process.exit(runOrSkip('visual-diff', main));
274
+ }
275
+
276
+ module.exports = { compareWithPixelmatch, compareFallback, parsePngSize };
@@ -61,9 +61,39 @@ Task("Audit accessibility", `
61
61
  `, "qe-accessibility-agent")
62
62
  ```
63
63
 
64
+ ## Browser engine
65
+
66
+ All browser automation in this skill uses the **qe-browser** fleet skill (Vibium engine). See `.claude/skills/qe-browser/SKILL.md`. The `vibium` binary is installed by `aqe init`.
67
+
64
68
  ## Visual Testing Operations
65
69
 
66
- ### 1. Visual Regression
70
+ ### 1. Visual Regression (via qe-browser)
71
+
72
+ ```bash
73
+ # Establish baselines for the pages we care about
74
+ for path in / /login /dashboard /settings; do
75
+ slug=$(echo "$path" | tr '/' '_' | sed 's/^_//' || echo root)
76
+ vibium go "https://production.example.com$path" && vibium wait load
77
+ node .claude/skills/qe-browser/scripts/visual-diff.js --name "baseline_${slug:-root}"
78
+ done
79
+
80
+ # Compare staging against those baselines
81
+ for path in / /login /dashboard /settings; do
82
+ slug=$(echo "$path" | tr '/' '_' | sed 's/^_//' || echo root)
83
+ vibium go "https://staging.example.com$path" && vibium wait load
84
+ node .claude/skills/qe-browser/scripts/visual-diff.js \
85
+ --name "baseline_${slug:-root}" --threshold 0.001 # 0.1% pixel diff
86
+ done
87
+ ```
88
+
89
+ Ignore dynamic regions (timestamps, live counts) by scoping the diff to a selector that excludes them:
90
+
91
+ ```bash
92
+ node .claude/skills/qe-browser/scripts/visual-diff.js \
93
+ --name hero --selector "main > .content"
94
+ ```
95
+
96
+ Legacy programmatic TypeScript API (still available for tests that prefer it over shelling out):
67
97
 
68
98
  ```typescript
69
99
  await visualTester.compareScreenshots({
@@ -20,6 +20,24 @@ validation:
20
20
 
21
21
  # Security Visual Testing
22
22
 
23
+ ## Browser engine
24
+
25
+ Uses the **qe-browser** fleet skill (`.claude/skills/qe-browser/`) for all browser automation. The Vibium engine (10MB Go binary, WebDriver BiDi) is installed automatically by `aqe init`. For security-visual workflows, qe-browser adds two things on top of stock visual testing: `check-injection.js` (scans page content for prompt-injection patterns before screenshots are stored) and `assert.js` (16 typed checks including `no_failed_requests` for detecting data-leak requests).
26
+
27
+ ```bash
28
+ # Before storing any screenshot, scan the page
29
+ vibium go "$TARGET_URL"
30
+ vibium wait load
31
+ node .claude/skills/qe-browser/scripts/check-injection.js --include-hidden
32
+ INJ=$?
33
+ if [ $INJ -ne 0 ]; then
34
+ echo "Prompt-injection findings — do NOT store screenshot"
35
+ exit $INJ
36
+ fi
37
+ # Safe to proceed with visual-diff
38
+ node .claude/skills/qe-browser/scripts/visual-diff.js --name "${PAGE_NAME}"
39
+ ```
40
+
23
41
  <default_to_action>
24
42
  When performing security-aware visual testing:
25
43
  1. VALIDATE URLs before navigation (check for malicious patterns)
@@ -1,9 +1,9 @@
1
1
  {
2
- "version": "1.3.0",
3
- "generated": "2026-02-04T00:00:00.000Z",
4
- "totalSkills": 48,
5
- "totalQESkills": 80,
6
- "description": "Agentic QE Fleet skills manifest - 48 Tier 3 verified QE skills. Total 80 QE skills on disk (48 Tier 3 + 32 additional including QCSD swarms, n8n testing, enterprise integration, pentest validation, qe-* domains).",
2
+ "version": "1.4.0",
3
+ "generated": "2026-04-09T00:00:00.000Z",
4
+ "totalSkills": 49,
5
+ "totalQESkills": 81,
6
+ "description": "Agentic QE Fleet skills manifest - 49 Tier 3 verified QE skills. Total 81 QE skills on disk (49 Tier 3 + 32 additional including QCSD swarms, n8n testing, enterprise integration, pentest validation, qe-* domains, qe-browser via ADR-091).",
7
7
  "categories": {
8
8
  "qcsd-phases": {
9
9
  "description": "QCSD (Quality Conscious Software Delivery) phase swarms for shift-left quality",
@@ -49,6 +49,13 @@
49
49
  "regression-testing"
50
50
  ]
51
51
  },
52
+ "browser-automation": {
53
+ "description": "Browser automation fleet skill using Vibium (WebDriver BiDi) with typed assertions, batch execution, visual diff, prompt-injection scanning, and semantic intents. Supersedes per-skill browser glue across a11y-ally, e2e-flow-verifier, visual-testing-advanced, and others. See ADR-091.",
54
+ "priority": "high",
55
+ "skills": [
56
+ "qe-browser"
57
+ ]
58
+ },
52
59
  "analysis-review": {
53
60
  "description": "Code and quality analysis skills",
54
61
  "priority": "medium",
@@ -905,7 +912,7 @@
905
912
  "optimizationTracking": {
906
913
  "targetReduction": "40-50%",
907
914
  "optimizedSkills": 7,
908
- "totalSkills": 46,
915
+ "totalSkills": 47,
909
916
  "progress": "15.2%",
910
917
  "tokensSaved": 10200,
911
918
  "optimizedList": [
@@ -932,9 +939,9 @@
932
939
  },
933
940
  "metadata": {
934
941
  "generatedBy": "Agentic QE Fleet",
935
- "fleetVersion": "3.9.8",
936
- "manifestVersion": "1.3.0",
937
- "lastUpdated": "2026-04-08T00:00:00.000Z",
942
+ "fleetVersion": "3.9.10",
943
+ "manifestVersion": "1.4.0",
944
+ "lastUpdated": "2026-04-13T00:00:00.000Z",
938
945
  "contributors": [
939
946
  {
940
947
  "name": "@fndlalit",
@@ -942,13 +949,13 @@
942
949
  "url": "https://github.com/fndlalit"
943
950
  }
944
951
  ],
945
- "notes": "This manifest tracks 48 Tier 3 verified QE skills. Total 80 QE skills on disk (48 Tier 3 + 32 additional). Claude Flow platform skills (33) are managed separately.",
952
+ "notes": "This manifest tracks 49 Tier 3 verified QE skills. Total 81 QE skills on disk (49 Tier 3 + 32 additional). qe-browser added 2026-04-09 per ADR-091. Claude Flow platform skills (33) are managed separately.",
946
953
  "skillBreakdown": {
947
- "qeSkillsTier3": 48,
954
+ "qeSkillsTier3": 49,
948
955
  "qeSkillsAdditional": 32,
949
- "totalQESkills": 80,
956
+ "totalQESkills": 81,
950
957
  "platformSkills": 36,
951
- "totalOnDisk": 113
958
+ "totalOnDisk": 114
952
959
  },
953
960
  "excludedCategories": {
954
961
  "reason": "Platform skills are available but not tracked in this QE-focused manifest",
@@ -22,6 +22,29 @@ validation:
22
22
 
23
23
  # Testability Scoring
24
24
 
25
+ ## Browser engine
26
+
27
+ Uses the **qe-browser** fleet skill (`.claude/skills/qe-browser/`) as the primary browser engine. Vibium is installed by `aqe init`. The legacy `scripts/run-assessment.sh` + Playwright path remains as a fallback when a team already has a Playwright test suite configured, but new runs should prefer:
28
+
29
+ ```bash
30
+ vibium go "$TARGET_URL"
31
+ vibium wait load
32
+ vibium a11y-tree --json > /tmp/testability/tree.json
33
+ vibium eval --stdin --json <<'EOF' > /tmp/testability/signals.json
34
+ JSON.stringify({
35
+ headings: document.querySelectorAll('h1,h2,h3,h4,h5,h6').length,
36
+ testIds: document.querySelectorAll('[data-testid]').length,
37
+ forms: document.querySelectorAll('form').length,
38
+ ariaLabels: document.querySelectorAll('[aria-label]').length,
39
+ links: document.querySelectorAll('a[href]').length,
40
+ });
41
+ EOF
42
+ node .claude/skills/qe-browser/scripts/assert.js --checks '[
43
+ {"kind": "no_console_errors"},
44
+ {"kind": "no_failed_requests"}
45
+ ]'
46
+ ```
47
+
25
48
  <default_to_action>
26
49
  When assessing testability:
27
50
  1. RUN assessment against target URL
@@ -8,11 +8,11 @@
8
8
  "tier0": 51,
9
9
  "tier1": 5,
10
10
  "tier2": 7,
11
- "tier3": 49,
12
- "total": 112
11
+ "tier3": 50,
12
+ "total": 113
13
13
  },
14
14
  "validationStatus": {
15
- "passing": 49,
15
+ "passing": 50,
16
16
  "failing": 0,
17
17
  "unknown": 12,
18
18
  "skipped": 51
@@ -294,6 +294,17 @@
294
294
  },
295
295
  "file": "qcsd-ideation-swarm/SKILL.md"
296
296
  },
297
+ {
298
+ "name": "qe-browser",
299
+ "category": "browser-automation",
300
+ "validation": {
301
+ "status": "passing",
302
+ "schemaPath": "schemas/output.json",
303
+ "validatorPath": "scripts/validate-config.json",
304
+ "evalPath": "evals/qe-browser.yaml"
305
+ },
306
+ "file": "qe-browser/SKILL.md"
307
+ },
297
308
  {
298
309
  "name": "qe-chaos-resilience",
299
310
  "validation": {
@@ -68,7 +68,47 @@ When detecting visual regressions or validating UI:
68
68
 
69
69
  ---
70
70
 
71
- ## Visual Regression with Playwright
71
+ ## PRIMARY PATH: qe-browser visual-diff
72
+
73
+ **Most visual regression work should go through the `qe-browser` fleet skill.** It wraps Vibium (WebDriver BiDi) and provides pixel-diff against stored baselines with threshold enforcement and diff-image output. See `.claude/skills/qe-browser/SKILL.md`.
74
+
75
+ ```bash
76
+ # Navigate
77
+ vibium go https://example.com
78
+ vibium wait load
79
+
80
+ # First run — creates baseline in .aqe/visual-baselines/homepage.png
81
+ node .claude/skills/qe-browser/scripts/visual-diff.js --name homepage
82
+
83
+ # Subsequent runs — compare, non-zero exit on mismatch
84
+ node .claude/skills/qe-browser/scripts/visual-diff.js --name homepage --threshold 0.02
85
+
86
+ # Scope to a single region
87
+ node .claude/skills/qe-browser/scripts/visual-diff.js --name hero --selector "#hero"
88
+
89
+ # Responsive — run diff at each breakpoint
90
+ for viewport in "375 667" "768 1024" "1920 1080"; do
91
+ read w h <<< "$viewport"
92
+ vibium viewport $w $h
93
+ node .claude/skills/qe-browser/scripts/visual-diff.js --name "homepage-${w}x${h}"
94
+ done
95
+
96
+ # Reset baseline after an intentional design change
97
+ node .claude/skills/qe-browser/scripts/visual-diff.js --name homepage --update-baseline
98
+ ```
99
+
100
+ Baselines live in `.aqe/visual-baselines/`. The script uses `pixelmatch` when installed, with a hash-based exact-match fallback otherwise. Non-zero exit when similarity < `1 - threshold`, so CI gating is `$?`-based.
101
+
102
+ ### When to keep Playwright visual regression
103
+
104
+ Use the Playwright recipe below only when you need:
105
+ - **AI semantic comparison** (Percy, Applitools) to ignore insignificant pixel drift
106
+ - **Cross-browser rendering checks** in Firefox/WebKit (Vibium is Chrome-only today)
107
+ - **Tight integration with an existing Playwright test suite**
108
+
109
+ ---
110
+
111
+ ## LEGACY: Visual Regression with Playwright (fallback)
72
112
 
73
113
  ```javascript
74
114
  import { test, expect } from '@playwright/test';
package/CHANGELOG.md CHANGED
@@ -5,6 +5,81 @@ All notable changes to the Agentic QE project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.9.10] - 2026-04-13
9
+
10
+ **Use any LLM provider for QE advisory tasks.** Route simple questions to cheaper models, keep complex reasoning on premium providers, and let the fleet automatically route around outages. Sensitive data is scrubbed before prompts leave your environment. ([ADR-092](docs/implementation/adrs/ADR-092-provider-agnostic-advisor-strategy.md))
11
+
12
+ ### Added
13
+
14
+ - **Multi-provider advisor routing** — Distribute advisory tasks across Claude, OpenAI, Ollama, OpenRouter, or any compatible provider. Route by task complexity, cost, or provider health. If one provider goes down, the fleet routes around it automatically.
15
+ - **Automatic PII redaction** — API keys, credentials, secrets, and PII are stripped from prompts before they reach any external advisor. Three modes: `strict` (credentials + PII), `balanced` (credentials only), `off` (for self-hosted like Ollama).
16
+ - **Per-provider circuit breakers** — Detect provider degradation and stop sending requests before they time out. Automatic recovery probes re-enable providers when they come back.
17
+ - **`aqe llm-router` CLI command** — Inspect provider health, circuit breaker state, routing weights, and configuration.
18
+ - **8 QE agents upgraded** — coverage-specialist, fleet-commander, pentest-validator, queen-coordinator, risk-assessor, root-cause-analyzer, security-auditor, and test-architect all support multi-provider routing out of the box.
19
+
20
+ ### Fixed
21
+
22
+ - Distribution pipeline edge cases when multiple providers respond simultaneously
23
+ - Error handling in routing-feedback collection
24
+
25
+ ### Changed
26
+
27
+ - Queen coordinator now delegates advisory tasks through the advisor routing layer
28
+ - Tiny-dancer router gains an advisor fallback path for when primary routing is unavailable
29
+
30
+ ## [3.9.9] - 2026-04-09
31
+
32
+ This release ships **`qe-browser`** — a new fleet skill that gives every QE agent a real browser through a ~10MB Go binary instead of a 300MB Playwright install. Built on [Vibium](https://github.com/VibiumDev/vibium) (WebDriver BiDi) and shipped under [ADR-091](docs/implementation/adrs/ADR-091-qe-browser-skill-vibium-engine.md).
33
+
34
+ ### Added
35
+
36
+ - **`qe-browser` fleet skill** ([ADR-091](docs/implementation/adrs/ADR-091-qe-browser-skill-vibium-engine.md)) — Browser automation for QE agents with 5 helper scripts:
37
+ - `assert.js` — 16 typed assertion kinds (`url_contains`, `selector_visible`, `no_console_errors`, `element_count`, `title_matches`, etc.)
38
+ - `batch.js` — Multi-step execution with pre-validation, stop-on-failure, and delegation to `assert.js`
39
+ - `visual-diff.js` — Pixel-perfect baseline comparison with `pixelmatch`, hash fallback, configurable threshold
40
+ - `check-injection.js` — 14-pattern prompt-injection scanner ported from `gsd-browser` (MIT/Apache-2.0) with `--exclude-selector` for docs sites
41
+ - `intent-score.js` — 15 semantic intents (`submit_form`, `accept_cookies`, `fill_email`, `primary_cta`, etc.) ported from `gsd-browser`
42
+ - **Vibium auto-install** — `aqe init` now installs the `vibium` CLI globally via npm during phase 09 with a pre-flight short-circuit when it's already on PATH (no banner on the common case).
43
+ - **Typed missing-browser contract** — When vibium is not on PATH, helpers emit a structured `status: "skipped"` envelope with top-level `vibiumUnavailable: true`, `output.reason: "browser-engine-unavailable"`, and exit code **2** (distinct from 0=success and 1=failed). Downstream skills can branch on the flag instead of grepping error strings.
44
+ - **Linux ARM64 workaround documentation** — Chromium symlink recipe for aarch64 Debian/codespace hosts where Google doesn't publish Chrome for Testing (verified against `chromium 146.0.7680.177-1~deb12u1`).
45
+ - **7-gotcha migration guide** (`references/migration-from-playwright.md`) — Covers headless default, screenshot output directory quirk, absent `--selector` flag, `eval --stdin` last-expression contract, ARM64 install, viewport determinism, and first-install download time.
46
+ - **End-to-end smoke test** (`scripts/smoke-test.sh`) — 10 test cases against pinned `httpbin.org` fixtures, including a tc011 that spawns helpers with a stripped `PATH` to verify the missing-vibium contract.
47
+ - **103 unit tests** across 8 files covering assertion kinds, batch validation, check-injection patterns, intent-score whitelist, fixture server path traversal, and the missing-vibium end-to-end contract.
48
+
49
+ ### Fixed
50
+
51
+ All fixes below are from a devil's-advocate review of the initial `qe-browser` implementation, captured in ADR-091 Phases 1 through 4:
52
+
53
+ - **Assertion fail-closed on missing telemetry** — `runConsoleCheck`/`runNetworkCheck` used to fail-OPEN when the underlying `vibium console`/`vibium network` JSON was unavailable (silently reporting `no_console_errors: pass` when we couldn't tell). Now returns a typed `unavailable` sentinel that `runCheck` surfaces as `passed: false, unavailable: true`, per `feedback_no_unverified_failure_modes.md`.
54
+ - **`intent-score.js` special-character corruption** — The script builder used `String.prototype.replace` with a raw substitution string, so scopes containing `$&`, `` $` ``, `$'`, or `$1-$9` corrupted the generated browser-side code. Switched to `split/join` for literal substitution.
55
+ - **`visual-diff.js` unsupported `--selector`** — The `vibium screenshot --selector` flag does not exist in v26.3.x. Replaced the dead fallback path with an explicit error pointing at ImageMagick `convert -crop`.
56
+ - **`vibium screenshot -o` directory ignored** — Vibium hardcodes `~/Pictures/Vibium/<basename>` regardless of the `-o` argument's directory. `visual-diff.js` now reads from Vibium's actual output path and copies to the caller's requested location.
57
+ - **`vibium eval --stdin` return contract** — Vibium eval returns the LAST EXPRESSION value via `{"ok":true,"result":"<stringified>"}`, not `console.log` output. Added `unwrapEvalResult()` that parses the result string back, and removed `console.log` wrappers from all helper scripts.
58
+ - **Headless container support** — Vibium defaults to "visible browser" and fails with `Missing X server or $DISPLAY` on headless containers. All helper scripts now auto-inject `--headless` into every `vibium` invocation (opt out via `QE_BROWSER_HEADED=1`).
59
+ - **`parseArgs` `--key=value` form** — Previously only `--key value` (space-separated) was parsed. A user typing `--threshold=0.05` got `args["threshold=0.05"] = true` and the real `threshold` key stayed undefined. Now splits on the first `=` so both forms work and URL/base64 values containing `=` survive intact.
60
+ - **`batch.js` no pre-validation** — A typo in step 17 used to surface AFTER steps 1-16 had executed with side effects. Added `validateAllSteps()` that walks every step's required fields before the first vibium call and aborts with a consolidated error listing all typos.
61
+ - **`check-injection.js` ANSI escape passthrough** — Finding snippets included raw page text verbatim, so malicious pages could inject terminal control sequences that trigger on `cat findings.json`. Added `sanitizeSnippet()` that strips C0 controls (0x00-0x1F except `\t\n`) and DEL (0x7F).
62
+ - **`check-injection.js` doc false positives** — Running the scanner on docs that talk about prompt injection self-flagged every heading. New `--exclude-selector "main, .docs-content"` strips subtrees from a cloned `<body>` before scanning; live page unchanged.
63
+ - **`intent-score.js` bare-`x` false positives** — The `close_dialog` regex used a bare `/x/` that matched "fix", "exit", "extra", "sixteen". Anchored with `\bx\b`; Unicode `×` and `✕` unchanged.
64
+ - **Fixture HTTP server bound to `0.0.0.0`** — Codespaces auto-forward 0.0.0.0 ports to the public preview URL, so running `fixtures/serve-skills.js` was silently exposing the skills tree. Default is now `127.0.0.1`; `QE_BROWSER_FIXTURE_HOST=0.0.0.0` is explicit opt-in.
65
+ - **Fixture server path-traversal guard** — The `startsWith(SKILLS_ROOT)` check false-passes on sibling dirs that share a prefix and is fragile on Windows mixed separators. Replaced with `path.relative()` + `..` check (the canonical guard).
66
+ - **`detectVibium` stderr-only semver** — `vibium --version` emits to stderr on some platforms. `detectVibium` now reads both stdout and stderr and extracts the semver with a regex that handles prerelease/build metadata.
67
+ - **`installBrowserEngine` silent 1-3 minute freeze** — `spawnSync('npm install -g vibium')` blocks for 1-3 minutes on cold caches while Chrome for Testing downloads. Phase 09 now runs a pre-flight detect that short-circuits when vibium is already on PATH (no banner) and logs a "this can take 1-3 minutes on first run" message BEFORE the spawn on the cold path.
68
+ - **`09-assets.ts` dead error catch** — The `installBrowserEngine` try/catch re-emitted raw errors with no recovery path. Wrapped with actionable guidance pointing at `npm install -g vibium` and a re-run of `aqe init`.
69
+
70
+ ### Changed
71
+
72
+ - **`.gitignore`** — Added `.aqe/` for per-project qe-browser state (visual baselines and helper caches), with `!.aqe/visual-baselines/.gitkeep` carve-out so projects that opt in to committing baselines can do so by removing the ignore.
73
+ - **11 skills migrated to reference `qe-browser`** — `a11y-ally`, `e2e-flow-verifier`, `qe-visual-accessibility`, `security-visual-testing`, `visual-testing-advanced`, `testability-scoring`, `compatibility-testing`, `accessibility-testing`, `localization-testing`, `observability-testing-patterns`, `enterprise-integration-testing`. Each SKILL.md now points at `.claude/skills/qe-browser/` instead of embedding Playwright snippets.
74
+ - **Skill counts bumped across user-facing docs** — README headline `74 → 75`, Tier 3 `48 → 49`, `.claude/skills/README.md` total `84 → 85`, V3 Domain Skills `23 → 24`. `skills-manifest.json` bumped to manifest version `1.4.0` with a new `browser-automation` category, `fleetVersion: "3.9.9"`. `trust-tier-manifest.json` bumped `tier3: 49 → 50`, `total: 112 → 113`.
75
+
76
+ ### Verified
77
+
78
+ - **Fresh `aqe init --auto`** in `/tmp/qe-browser-uat` against the local build — 85 skills / 60 agents installed, `Browser engine: vibium 26.3.18 (already installed)` logged cleanly.
79
+ - **12 user-perspective checks** against the installed skill — navigate + assert on httpbin, `--threshold=0.42` form, `batch.js` pre-validation aborting on typos, `intent-score.js submit_form`, `check-injection.js --exclude-selector` (visibleChars 3595 → 35), fixture server banner (`127.0.0.1`), path traversal returns 404, missing-vibium fallback, installed `smoke-test.sh` 10/10, idempotent re-init, JSON envelope contract.
80
+ - **Unit tests** — 103 tests across 8 files, all passing: `qe-browser-assert`, `qe-browser-batch`, `qe-browser-check-injection`, `qe-browser-intent-score`, `qe-browser-vibium-lib`, `qe-browser-fixtures-server`, `qe-browser-unavailable-e2e`, `browser-engine-installer`.
81
+ - **Smoke test** — 10/10 against real Vibium v26.3.18 + Chromium 146.0.7680.177 + `httpbin.org` pinned fixtures.
82
+
8
83
  ## [3.9.8] - 2026-04-08
9
84
 
10
85
  This is a release-process release. **No source code changes** — every commit since v3.9.7 lands in CI, fixtures, scripts, or docs. The published package is functionally identical to v3.9.7 except for a refreshed lockfile with two transitive security patches.
package/README.md CHANGED
@@ -159,24 +159,26 @@ Plus **7 TDD subagents** (red, green, refactor, code/integration/performance/sec
159
159
 
160
160
  ---
161
161
 
162
- ## 74 QE Skills
162
+ ## 75 QE Skills
163
163
 
164
164
  Agents automatically apply relevant skills from the skill library. Skills are rated by **trust tier**:
165
165
 
166
166
  | Tier | Count | Meaning |
167
167
  |------|-------|---------|
168
- | **Tier 3 — Verified** | 48 | Full evaluation test suite, production-ready |
168
+ | **Tier 3 — Verified** | 49 | Full evaluation test suite, production-ready |
169
169
  | **Tier 2 — Validated** | 7 | Has executable validator |
170
170
  | **Tier 1 — Structured** | 5 | Has JSON output schema |
171
171
  | **Tier 0 — Advisory** | 5 | Guidance only |
172
172
 
173
173
  <details>
174
- <summary><b>View all 74 skills</b></summary>
174
+ <summary><b>View all 75 skills</b></summary>
175
175
 
176
176
  **Core Testing (12):** agentic-quality-engineering, holistic-testing-pact, context-driven-testing, tdd-london-chicago, xp-practices, risk-based-testing, test-automation-strategy, refactoring-patterns, shift-left-testing, shift-right-testing, regression-testing, verification-quality
177
177
 
178
178
  **Specialized Testing (13):** accessibility-testing, mobile-testing, database-testing, contract-testing, chaos-engineering-resilience, visual-testing-advanced, security-visual-testing, compliance-testing, compatibility-testing, localization-testing, mutation-testing, performance-testing, security-testing
179
179
 
180
+ **Browser Automation (1):** qe-browser (Vibium engine — assert, batch, visual-diff, prompt-injection scanning, semantic intents; see [ADR-091](docs/implementation/adrs/ADR-091-qe-browser-skill-vibium-engine.md))
181
+
180
182
  **Domain Skills (11):** qe-test-generation, qe-test-execution, qe-coverage-analysis, qe-quality-assessment, qe-defect-intelligence, qe-requirements-validation, qe-code-intelligence, qe-visual-accessibility, qe-chaos-resilience, qe-learning-optimization, qe-iterative-loop
181
183
 
182
184
  **Strategic (8):** six-thinking-hats, brutal-honesty-review, sherlock-review, cicd-pipeline-qe-orchestrator, bug-reporting-excellence, consultancy-practices, quality-metrics, pair-programming