agentic-qe 3.9.7 → 3.9.9

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 (335) hide show
  1. package/.claude/skills/README.md +4 -3
  2. package/.claude/skills/a11y-ally/SKILL.md +40 -18
  3. package/.claude/skills/accessibility-testing/SKILL.md +4 -0
  4. package/.claude/skills/compatibility-testing/SKILL.md +23 -0
  5. package/.claude/skills/e2e-flow-verifier/SKILL.md +87 -52
  6. package/.claude/skills/enterprise-integration-testing/SKILL.md +4 -0
  7. package/.claude/skills/localization-testing/SKILL.md +14 -0
  8. package/.claude/skills/observability-testing-patterns/SKILL.md +16 -0
  9. package/.claude/skills/qe-browser/SKILL.md +409 -0
  10. package/.claude/skills/qe-browser/evals/qe-browser.yaml +291 -0
  11. package/.claude/skills/qe-browser/fixtures/package.json +7 -0
  12. package/.claude/skills/qe-browser/fixtures/serve-skills.js +130 -0
  13. package/.claude/skills/qe-browser/references/assertion-kinds.md +132 -0
  14. package/.claude/skills/qe-browser/references/migration-from-playwright.md +195 -0
  15. package/.claude/skills/qe-browser/schemas/output.json +188 -0
  16. package/.claude/skills/qe-browser/scripts/assert.js +378 -0
  17. package/.claude/skills/qe-browser/scripts/batch.js +292 -0
  18. package/.claude/skills/qe-browser/scripts/check-injection.js +267 -0
  19. package/.claude/skills/qe-browser/scripts/intent-score.js +325 -0
  20. package/.claude/skills/qe-browser/scripts/lib/vibium.js +330 -0
  21. package/.claude/skills/qe-browser/scripts/package.json +7 -0
  22. package/.claude/skills/qe-browser/scripts/smoke-test.sh +212 -0
  23. package/.claude/skills/qe-browser/scripts/validate-config.json +46 -0
  24. package/.claude/skills/qe-browser/scripts/visual-diff.js +276 -0
  25. package/.claude/skills/qe-visual-accessibility/SKILL.md +31 -1
  26. package/.claude/skills/security-visual-testing/SKILL.md +18 -0
  27. package/.claude/skills/skills-manifest.json +20 -13
  28. package/.claude/skills/testability-scoring/SKILL.md +23 -0
  29. package/.claude/skills/trust-tier-manifest.json +14 -3
  30. package/.claude/skills/visual-testing-advanced/SKILL.md +41 -1
  31. package/CHANGELOG.md +79 -0
  32. package/README.md +5 -3
  33. package/assets/skills/README.md +4 -3
  34. package/assets/skills/a11y-ally/SKILL.md +40 -18
  35. package/assets/skills/accessibility-testing/SKILL.md +4 -0
  36. package/assets/skills/compatibility-testing/SKILL.md +23 -0
  37. package/assets/skills/e2e-flow-verifier/SKILL.md +87 -52
  38. package/assets/skills/enterprise-integration-testing/SKILL.md +4 -0
  39. package/assets/skills/localization-testing/SKILL.md +14 -0
  40. package/assets/skills/observability-testing-patterns/SKILL.md +16 -0
  41. package/assets/skills/qe-browser/SKILL.md +409 -0
  42. package/assets/skills/qe-browser/evals/qe-browser.yaml +291 -0
  43. package/assets/skills/qe-browser/fixtures/package.json +7 -0
  44. package/assets/skills/qe-browser/fixtures/serve-skills.js +130 -0
  45. package/assets/skills/qe-browser/references/assertion-kinds.md +132 -0
  46. package/assets/skills/qe-browser/references/migration-from-playwright.md +195 -0
  47. package/assets/skills/qe-browser/schemas/output.json +188 -0
  48. package/assets/skills/qe-browser/scripts/assert.js +378 -0
  49. package/assets/skills/qe-browser/scripts/batch.js +292 -0
  50. package/assets/skills/qe-browser/scripts/check-injection.js +267 -0
  51. package/assets/skills/qe-browser/scripts/intent-score.js +325 -0
  52. package/assets/skills/qe-browser/scripts/lib/vibium.js +330 -0
  53. package/assets/skills/qe-browser/scripts/package.json +7 -0
  54. package/assets/skills/qe-browser/scripts/smoke-test.sh +212 -0
  55. package/assets/skills/qe-browser/scripts/validate-config.json +46 -0
  56. package/assets/skills/qe-browser/scripts/visual-diff.js +276 -0
  57. package/assets/skills/qe-visual-accessibility/SKILL.md +31 -1
  58. package/assets/skills/security-visual-testing/SKILL.md +18 -0
  59. package/assets/skills/skills-manifest.json +211 -15
  60. package/assets/skills/testability-scoring/SKILL.md +23 -0
  61. package/assets/skills/trust-tier-manifest.json +14 -3
  62. package/assets/skills/visual-testing-advanced/SKILL.md +41 -1
  63. package/dist/cli/bundle.js +5 -5
  64. package/dist/cli/chunks/adapter-XKXEZEMM.js +2 -0
  65. package/dist/cli/chunks/{agent-booster-wasm-MXTWTD4D.js → agent-booster-wasm-QEN7W6VC.js} +2 -2
  66. package/dist/cli/chunks/{agent-handler-6NEP2BOA.js → agent-handler-F3RLG42J.js} +2 -2
  67. package/dist/cli/chunks/{agent-memory-branch-SAPEIGE2.js → agent-memory-branch-U3PZ3CPL.js} +2 -2
  68. package/dist/cli/chunks/aqe-learning-engine-K7XGBDMZ.js +2 -0
  69. package/dist/cli/chunks/{audit-53LCI6R3.js → audit-FF6SP7Q2.js} +2 -2
  70. package/dist/cli/chunks/base-NUF35LIJ.js +2 -0
  71. package/dist/cli/chunks/{better-sqlite3-UZSKFGCK.js → better-sqlite3-CVXRDGQX.js} +2 -2
  72. package/dist/cli/chunks/{brain-handler-67NDDXVO.js → brain-handler-AMTRZ35W.js} +3 -3
  73. package/dist/cli/chunks/{branch-enumerator-IUIGYEK5.js → branch-enumerator-Y4A34YFT.js} +2 -2
  74. package/dist/cli/chunks/{browser-UFUF65LQ.js → browser-ETSF5GZR.js} +2 -2
  75. package/dist/cli/chunks/browser-workflow-MWPELXFA.js +2 -0
  76. package/dist/cli/chunks/{chunk-XD4UFF2Y.js → chunk-22HQFULR.js} +1 -1
  77. package/dist/cli/chunks/{chunk-W4Y4GFRB.js → chunk-2BSVGL35.js} +1 -1
  78. package/dist/cli/chunks/{chunk-KHH5UJXY.js → chunk-2HFPJPQW.js} +2 -2
  79. package/dist/cli/chunks/{chunk-LPLCT2HH.js → chunk-2JAYDTSE.js} +2 -2
  80. package/dist/cli/chunks/{chunk-RGJ4RMUR.js → chunk-2KY5B4ON.js} +8 -8
  81. package/dist/cli/chunks/{chunk-XB2GVTY6.js → chunk-2O3WZ6E3.js} +1 -1
  82. package/dist/cli/chunks/{chunk-5EOM3W6Q.js → chunk-2UP3DYNH.js} +2 -2
  83. package/dist/cli/chunks/{chunk-DS3XAGGL.js → chunk-2X7LDTVD.js} +2 -2
  84. package/dist/cli/chunks/{chunk-NJ5IC6ZR.js → chunk-2ZHA6ORO.js} +1 -1
  85. package/dist/cli/chunks/{chunk-FKJ4XZ6E.js → chunk-3F666FYP.js} +2 -2
  86. package/dist/cli/chunks/{chunk-7TKZ6LK6.js → chunk-3FAEM5M7.js} +1 -1
  87. package/dist/cli/chunks/{chunk-TLTRL32T.js → chunk-3JCZTTFY.js} +1 -1
  88. package/dist/cli/chunks/{chunk-BPYWDM2Y.js → chunk-3NU4C62D.js} +3 -3
  89. package/dist/cli/chunks/{chunk-ZETZATNY.js → chunk-3XR7ARS6.js} +2 -2
  90. package/dist/cli/chunks/{chunk-FHBIJBZ3.js → chunk-4CDSEZD6.js} +2 -2
  91. package/dist/cli/chunks/{chunk-OURDPRGM.js → chunk-4CSINHCB.js} +1 -1
  92. package/dist/cli/chunks/{chunk-YTF5G3RQ.js → chunk-4HDG7OS4.js} +2 -2
  93. package/dist/cli/chunks/{chunk-PMZJ54WX.js → chunk-52RZZV4M.js} +3 -3
  94. package/dist/cli/chunks/{chunk-GOG6L2F7.js → chunk-5DU4YW2S.js} +2 -2
  95. package/dist/cli/chunks/{chunk-6MMRZYYS.js → chunk-5HM66R4W.js} +3 -3
  96. package/dist/cli/chunks/{chunk-BTZEKSWH.js → chunk-5L3EUZJA.js} +2 -2
  97. package/dist/cli/chunks/{chunk-TD2WOW75.js → chunk-5SWY75MJ.js} +2 -2
  98. package/dist/cli/chunks/{chunk-3DXO5CWI.js → chunk-65XCVUP7.js} +1 -1
  99. package/dist/cli/chunks/{chunk-VMWLVRJO.js → chunk-6KQLF3ZO.js} +2 -2
  100. package/dist/cli/chunks/{chunk-HVJXXGB4.js → chunk-6LTJP3DO.js} +4 -4
  101. package/dist/cli/chunks/{chunk-FJEIX3IS.js → chunk-6PJUDLCT.js} +2 -2
  102. package/dist/cli/chunks/{chunk-2TRWUJWG.js → chunk-74FBSJVC.js} +2 -2
  103. package/dist/cli/chunks/{chunk-D3KORDD5.js → chunk-A6GYFTIA.js} +1 -1
  104. package/dist/cli/chunks/{chunk-3KX7CQEM.js → chunk-ADJGMTIW.js} +1 -1
  105. package/dist/cli/chunks/{chunk-TT2YXNHH.js → chunk-AHOP227C.js} +4 -4
  106. package/dist/cli/chunks/{chunk-UXCEJ3AV.js → chunk-ANLFEGDG.js} +2 -2
  107. package/dist/cli/chunks/{chunk-SQQ57TSJ.js → chunk-AT2VD2ZP.js} +2 -2
  108. package/dist/cli/chunks/{chunk-KLLHSXIC.js → chunk-AYMIF4W5.js} +2 -2
  109. package/dist/cli/chunks/{chunk-JJSJSQNJ.js → chunk-B3DA4SCL.js} +1 -1
  110. package/dist/cli/chunks/{chunk-FBVEHGNE.js → chunk-BSES27JE.js} +3 -3
  111. package/dist/cli/chunks/{chunk-MUEFXLGX.js → chunk-BVKS3X2I.js} +1 -1
  112. package/dist/cli/chunks/{chunk-MR7V7QVL.js → chunk-BVOGMK6N.js} +2 -2
  113. package/dist/cli/chunks/{chunk-PHBE2VBN.js → chunk-BYJEK6LX.js} +2 -2
  114. package/dist/cli/chunks/{chunk-YV2PVXJE.js → chunk-BYPBKVTC.js} +1 -1
  115. package/dist/cli/chunks/{chunk-IQLFWO5U.js → chunk-C7YD7O74.js} +2 -2
  116. package/dist/cli/chunks/{chunk-ZEFDSMF4.js → chunk-CCCBGKVY.js} +2 -2
  117. package/dist/cli/chunks/{chunk-SIIYQLKH.js → chunk-CJQLJEO4.js} +2 -2
  118. package/dist/cli/chunks/{chunk-AT6LBLUV.js → chunk-CXWA34RL.js} +2 -2
  119. package/dist/cli/chunks/{chunk-HFPT7QXQ.js → chunk-CZYTPNUI.js} +2 -2
  120. package/dist/cli/chunks/{chunk-YIVZ5Z4V.js → chunk-DI6R2AVP.js} +1 -1
  121. package/dist/cli/chunks/{chunk-JNEG6DKU.js → chunk-DNS7DP2O.js} +1 -1
  122. package/dist/cli/chunks/{chunk-DKBXIBRS.js → chunk-ECNPBD4Y.js} +2 -2
  123. package/dist/cli/chunks/{chunk-7OPVTN5W.js → chunk-ENG5UF7M.js} +2 -2
  124. package/dist/cli/chunks/{chunk-EIGXGMOR.js → chunk-EV2NMWJV.js} +1 -1
  125. package/dist/cli/chunks/{chunk-426OO3RH.js → chunk-FGW5W3YK.js} +2 -2
  126. package/dist/cli/chunks/{chunk-SMKRBNO7.js → chunk-FTF34UME.js} +1 -1
  127. package/dist/cli/chunks/{chunk-VAKJOTGU.js → chunk-GYNGJHYF.js} +2 -2
  128. package/dist/cli/chunks/{chunk-AHB2F42G.js → chunk-HDM43P7H.js} +1 -1
  129. package/dist/cli/chunks/{chunk-ZWAJV4SN.js → chunk-HOWZFW7G.js} +2 -2
  130. package/dist/cli/chunks/{chunk-INJPS7RF.js → chunk-IZC5NPHD.js} +1 -1
  131. package/dist/cli/chunks/{chunk-HEENVPYF.js → chunk-J2DNMVB5.js} +3 -3
  132. package/dist/cli/chunks/{chunk-SP3X35XC.js → chunk-J62N66ZH.js} +1 -1
  133. package/dist/cli/chunks/{chunk-QKJ4LUAM.js → chunk-JIPU4YQK.js} +2 -2
  134. package/dist/cli/chunks/{chunk-4B5IYFKE.js → chunk-JK4K4EH3.js} +2 -2
  135. package/dist/cli/chunks/{chunk-LP6EQI2P.js → chunk-JQJHRQRX.js} +2 -2
  136. package/dist/cli/chunks/{chunk-FOCGOVIM.js → chunk-KSJCMXAJ.js} +2 -2
  137. package/dist/cli/chunks/{chunk-EFHR7LML.js → chunk-MDTF7LE6.js} +2 -2
  138. package/dist/cli/chunks/{chunk-PFTR6XAO.js → chunk-MUCFC3YG.js} +2 -2
  139. package/dist/cli/chunks/{chunk-JRHKFRUB.js → chunk-MUIJVPGB.js} +2 -2
  140. package/dist/cli/chunks/{chunk-WLYSZV5U.js → chunk-MWZN4PYF.js} +2 -2
  141. package/dist/cli/chunks/{chunk-JZYCZMHN.js → chunk-MXMKHI2I.js} +2 -2
  142. package/dist/cli/chunks/{chunk-XOHRM3M7.js → chunk-MZOYBHJ3.js} +3 -3
  143. package/dist/cli/chunks/{chunk-WV3R5JFE.js → chunk-NLKJI73E.js} +2 -2
  144. package/dist/cli/chunks/{chunk-D2C4XNF5.js → chunk-NQ3WHTLT.js} +4 -4
  145. package/dist/cli/chunks/{chunk-BJKRAFS2.js → chunk-NVVF5ROM.js} +2 -2
  146. package/dist/cli/chunks/{chunk-STASZVMY.js → chunk-OEZA7Q2Z.js} +2 -2
  147. package/dist/cli/chunks/{chunk-LHGZRKPO.js → chunk-OFOFXJ3M.js} +2 -2
  148. package/dist/cli/chunks/{chunk-2SJQ3CYN.js → chunk-OMRZUYXN.js} +9 -9
  149. package/dist/cli/chunks/{chunk-KHEAWN23.js → chunk-P6YMECV2.js} +2 -2
  150. package/dist/cli/chunks/{chunk-ZSXSUUBS.js → chunk-PEEN4AAK.js} +1 -1
  151. package/dist/cli/chunks/{chunk-6ULPQTIE.js → chunk-PRJUO2OQ.js} +2 -2
  152. package/dist/cli/chunks/{chunk-ECRYU5XG.js → chunk-PYTXZMXR.js} +2 -2
  153. package/dist/cli/chunks/{chunk-4NHE7AJE.js → chunk-Q2ZBPOUX.js} +1 -1
  154. package/dist/cli/chunks/{chunk-XY5FMZRA.js → chunk-QHATTMJC.js} +2 -2
  155. package/dist/cli/chunks/{chunk-HE5VY2BI.js → chunk-QMNAELZG.js} +2 -2
  156. package/dist/cli/chunks/{chunk-KZSZHP32.js → chunk-QQLQEQJM.js} +2 -2
  157. package/dist/cli/chunks/{chunk-7GPYOMVY.js → chunk-QSA23PJ6.js} +1 -1
  158. package/dist/cli/chunks/{chunk-GGPGY5QT.js → chunk-QTYTM7C7.js} +2 -2
  159. package/dist/cli/chunks/{chunk-YR5ZNQT2.js → chunk-QZMBJ67L.js} +2 -2
  160. package/dist/cli/chunks/{chunk-URBXUDY3.js → chunk-R23PJGH7.js} +2 -2
  161. package/dist/cli/chunks/{chunk-NKX2Z546.js → chunk-R5ZKFJ3H.js} +1 -1
  162. package/dist/cli/chunks/{chunk-KO5HO6MY.js → chunk-RLLDZNLF.js} +2 -2
  163. package/dist/cli/chunks/{chunk-ZLQYGO6N.js → chunk-RZYTJSQT.js} +1 -1
  164. package/dist/cli/chunks/{chunk-ZV7FGZNJ.js → chunk-S6VT7VAO.js} +2 -2
  165. package/dist/cli/chunks/{chunk-QI5VGEKC.js → chunk-SVLO2DVL.js} +2 -2
  166. package/dist/cli/chunks/{chunk-SURZYSSL.js → chunk-TTENF6AH.js} +1 -1
  167. package/dist/cli/chunks/{chunk-6OKXGDT3.js → chunk-UEKDDUGV.js} +2 -2
  168. package/dist/cli/chunks/{chunk-UEFAPTBV.js → chunk-UYKIPSRX.js} +1 -1
  169. package/dist/cli/chunks/{chunk-WS4OVAWU.js → chunk-VIIUJRKA.js} +2 -2
  170. package/dist/cli/chunks/chunk-VRH3YLO2.js +2 -0
  171. package/dist/cli/chunks/{chunk-YHZWNT45.js → chunk-VTX4NAWB.js} +2 -2
  172. package/dist/cli/chunks/{chunk-APPVAGD5.js → chunk-VWHALAEO.js} +1 -1
  173. package/dist/cli/chunks/{chunk-BWNH22V2.js → chunk-W4VDPHWC.js} +1 -1
  174. package/dist/cli/chunks/{chunk-CDFYF33M.js → chunk-W57I57M4.js} +2 -2
  175. package/dist/cli/chunks/{chunk-LZ34CKYE.js → chunk-WDWIJDQR.js} +2 -2
  176. package/dist/cli/chunks/{chunk-W4HUWBPK.js → chunk-WEJJWJ5M.js} +2 -2
  177. package/dist/cli/chunks/{chunk-A5VULTCD.js → chunk-WZR4CKR4.js} +1 -1
  178. package/dist/cli/chunks/{chunk-DL46KSFX.js → chunk-XZ2JYMFT.js} +2 -2
  179. package/dist/cli/chunks/{chunk-WAP7ROO5.js → chunk-YISXT54V.js} +2 -2
  180. package/dist/cli/chunks/{chunk-HWDE4RB3.js → chunk-YRORPSPA.js} +2 -2
  181. package/dist/cli/chunks/{chunk-T7R5NXJW.js → chunk-YXE67VME.js} +6 -6
  182. package/dist/cli/chunks/{chunk-UDBSEFUT.js → chunk-Z7AFNZMI.js} +2 -2
  183. package/dist/cli/chunks/{chunk-52MUZGZF.js → chunk-ZEUORIH2.js} +2 -2
  184. package/dist/cli/chunks/{chunk-SQZ3H6WR.js → chunk-ZKXA4VBK.js} +3 -3
  185. package/dist/cli/chunks/{chunk-EL2WLSUI.js → chunk-ZTI3BATG.js} +2 -2
  186. package/dist/cli/chunks/{ci-F4F3SDHP.js → ci-4QYE6JBM.js} +2 -2
  187. package/dist/cli/chunks/{ci-output-4SUMOQGO.js → ci-output-MV75HUK7.js} +2 -2
  188. package/dist/cli/chunks/{claude-flow-setup-NKXPDFMJ.js → claude-flow-setup-CZITY7SG.js} +2 -2
  189. package/dist/cli/chunks/client-VXVVUQDV.js +2 -0
  190. package/dist/cli/chunks/{cline-installer-3FMNXEKM.js → cline-installer-ZLQKCPFF.js} +2 -2
  191. package/dist/cli/chunks/{code-5QEDZNKI.js → code-NYEXOJVP.js} +2 -2
  192. package/dist/cli/chunks/{code-index-extractor-RD5EAOLE.js → code-index-extractor-TITXUC44.js} +2 -2
  193. package/dist/cli/chunks/{codex-installer-UU4O2FIE.js → codex-installer-TWT4LIL2.js} +2 -2
  194. package/dist/cli/chunks/{completions-CS6RJLYZ.js → completions-2KNV2MZG.js} +2 -2
  195. package/dist/cli/chunks/{complexity-analyzer-U4DE2QTP.js → complexity-analyzer-2U3OVRDX.js} +2 -2
  196. package/dist/cli/chunks/{continuedev-installer-E55EG2TB.js → continuedev-installer-BWQBRVTC.js} +2 -2
  197. package/dist/cli/chunks/{copilot-installer-TVJUX3AZ.js → copilot-installer-CYN33NMG.js} +2 -2
  198. package/dist/cli/chunks/{cost-tracker-IAKDLDJH.js → cost-tracker-2GUCBYLK.js} +2 -2
  199. package/dist/cli/chunks/{coverage-LX7UIEKV.js → coverage-BAVD66VL.js} +3 -3
  200. package/dist/cli/chunks/cross-domain-router-HUJG6CFC.js +2 -0
  201. package/dist/cli/chunks/{cursor-installer-2NJ7MK23.js → cursor-installer-ZQAUD47B.js} +2 -2
  202. package/dist/cli/chunks/{daemon-T4CPOFHM.js → daemon-VY2LZPIM.js} +3 -3
  203. package/dist/cli/chunks/{dag-attention-scheduler-GAPYYUHZ.js → dag-attention-scheduler-JNQWWXSW.js} +2 -2
  204. package/dist/cli/chunks/{detect-RU5LBCCI.js → detect-Y7BBW4LI.js} +2 -2
  205. package/dist/cli/chunks/{domain-handler-LKPDVPF6.js → domain-handler-473WNSR2.js} +2 -2
  206. package/dist/cli/chunks/{domain-transfer-Q76ITWBK.js → domain-transfer-R4VK7CRR.js} +2 -2
  207. package/dist/cli/chunks/dream-QQDRI2EQ.js +2 -0
  208. package/dist/cli/chunks/esm-node-Y3HIFLTX.js +2 -0
  209. package/dist/cli/chunks/{eval-TFFIZGTW.js → eval-TJAZGRCM.js} +2 -2
  210. package/dist/cli/chunks/{fast-paths-V6KA3VWH.js → fast-paths-LMN542IB.js} +2 -2
  211. package/dist/cli/chunks/{feature-flags-MYSY53UU.js → feature-flags-IMFZ7KED.js} +2 -2
  212. package/dist/cli/chunks/{feature-flags-DWS4XL2P.js → feature-flags-WMXIDTXL.js} +2 -2
  213. package/dist/cli/chunks/{file-discovery-AMKZRFLT.js → file-discovery-GXXWQJV3.js} +2 -2
  214. package/dist/cli/chunks/{fleet-B2BJFKEV.js → fleet-WIC7RHJV.js} +3 -3
  215. package/dist/cli/chunks/{gnn-wrapper-SOJHQ7VC.js → gnn-wrapper-PVKCXV25.js} +2 -2
  216. package/dist/cli/chunks/{heartbeat-handler-O7FF6NRE.js → heartbeat-handler-BJ6ZZP7Q.js} +4 -4
  217. package/dist/cli/chunks/{heartbeat-scheduler-WOGW5R7J.js → heartbeat-scheduler-3SQXTFYU.js} +2 -2
  218. package/dist/cli/chunks/hnsw-adapter-VKS7ORL2.js +2 -0
  219. package/dist/cli/chunks/hnsw-index-GPUBY6EQ.js +2 -0
  220. package/dist/cli/chunks/{hnsw-legacy-bridge-CC5YS47X.js → hnsw-legacy-bridge-23HFWIPK.js} +2 -2
  221. package/dist/cli/chunks/{hnswlib-node-FTWYRETS.js → hnswlib-node-4GRFMUPD.js} +2 -2
  222. package/dist/cli/chunks/{hooks-ETOFFBMV.js → hooks-IXH5454I.js} +6 -6
  223. package/dist/cli/chunks/{hypergraph-engine-FGAHFWFO.js → hypergraph-engine-TEQMJFJJ.js} +2 -2
  224. package/dist/cli/chunks/{hypergraph-handler-GNWJD7E3.js → hypergraph-handler-3ECUWIG3.js} +3 -3
  225. package/dist/cli/chunks/impact-analyzer-D6MBGRKX.js +2 -0
  226. package/dist/cli/chunks/{init-handler-BEYOLKQO.js → init-handler-TZRKW3NZ.js} +6 -6
  227. package/dist/cli/chunks/init-wizard-S6P2MFJF.js +2 -0
  228. package/dist/cli/chunks/kernel-EFDDMNXJ.js +2 -0
  229. package/dist/cli/chunks/{kilocode-installer-ED6LYSEM.js → kilocode-installer-IPH3O3ZS.js} +2 -2
  230. package/dist/cli/chunks/{kiro-installer-NG77T5YR.js → kiro-installer-VROMOOQO.js} +2 -2
  231. package/dist/cli/chunks/knowledge-graph-4PM4DFH3.js +2 -0
  232. package/dist/cli/chunks/{learning-P3WY3LTI.js → learning-JYQLD66S.js} +3 -3
  233. package/dist/cli/chunks/{llm-router-ETSFMOWS.js → llm-router-CIICNICY.js} +2 -2
  234. package/dist/cli/chunks/{load-PP3GVQT7.js → load-DMAQB4NC.js} +2 -2
  235. package/dist/cli/chunks/load-test-PPSWF3TO.js +2 -0
  236. package/dist/cli/chunks/{mcp-B2VX7EKL.js → mcp-K6CSUBMU.js} +2 -2
  237. package/dist/cli/chunks/{memory-SBZQ6MZ4.js → memory-5BSXKHSK.js} +5 -5
  238. package/dist/cli/chunks/memory-backend-3E6BA2JU.js +2 -0
  239. package/dist/cli/chunks/{memory-handlers-5RMGG2CR.js → memory-handlers-APOLXPNH.js} +2 -2
  240. package/dist/cli/chunks/{opencode-installer-PIDIFO2L.js → opencode-installer-IUWO2QV6.js} +2 -2
  241. package/dist/cli/chunks/{orchestrator-FSGUODZI.js → orchestrator-Z2EM76CR.js} +22 -19
  242. package/dist/cli/chunks/{pipeline-BQ5MWZPT.js → pipeline-OL5SI2RI.js} +2 -2
  243. package/dist/cli/chunks/{platform-6EJK4QMD.js → platform-VNJIKIHZ.js} +2 -2
  244. package/dist/cli/chunks/{plugin-EDGOMUJY.js → plugin-SJJUE47D.js} +2 -2
  245. package/dist/cli/chunks/{prime-radiant-advanced-wasm-4S6FYKPP.js → prime-radiant-advanced-wasm-ZLVTCNSH.js} +2 -2
  246. package/dist/cli/chunks/protocol-executor-2RD52J5J.js +2 -0
  247. package/dist/cli/chunks/{protocol-handler-ETM7PMQU.js → protocol-handler-HTX44YTW.js} +2 -2
  248. package/dist/cli/chunks/{prove-YUBORZAP.js → prove-MGFLVZNS.js} +2 -2
  249. package/dist/cli/chunks/qe-reasoning-bank-OGKT52EN.js +2 -0
  250. package/dist/cli/chunks/{quality-XPZDC5FJ.js → quality-FMFKPICZ.js} +2 -2
  251. package/dist/cli/chunks/queen-coordinator-B63YXNI6.js +2 -0
  252. package/dist/cli/chunks/{real-embeddings-KTDUTUJL.js → real-embeddings-2BMEEOA2.js} +2 -2
  253. package/dist/cli/chunks/{roocode-installer-WADVKI3P.js → roocode-installer-2PA3B5JI.js} +2 -2
  254. package/dist/cli/chunks/router-NDQCJQC6.js +2 -0
  255. package/dist/cli/chunks/routing-feedback-PSN2RLDO.js +2 -0
  256. package/dist/cli/chunks/{routing-handler-OOPOYHEV.js → routing-handler-SNGSQ757.js} +2 -2
  257. package/dist/cli/chunks/{ruvector-commands-UPEZL4OK.js → ruvector-commands-54MYLF63.js} +2 -2
  258. package/dist/cli/chunks/{rvf-dual-writer-TOBBCJ7K.js → rvf-dual-writer-6Q44XJOJ.js} +2 -2
  259. package/dist/cli/chunks/{rvf-migration-adapter-U7UM2U36.js → rvf-migration-adapter-JECN625C.js} +2 -2
  260. package/dist/cli/chunks/{rvf-migration-coordinator-CUX3EU2X.js → rvf-migration-coordinator-MEAVIHQY.js} +2 -2
  261. package/dist/cli/chunks/rvf-native-adapter-F56HQKLS.js +2 -0
  262. package/dist/cli/chunks/safe-db-LMRMNROL.js +2 -0
  263. package/dist/cli/chunks/schedule-OZSUYPPC.js +2 -0
  264. package/dist/cli/chunks/scheduler-GFXCQ6ZA.js +2 -0
  265. package/dist/cli/chunks/{security-AQ4N5YKV.js → security-CXLXTNIV.js} +3 -3
  266. package/dist/cli/chunks/shared-rvf-adapter-RZPF4WWK.js +2 -0
  267. package/dist/cli/chunks/{shared-rvf-dual-writer-OKRIHVSY.js → shared-rvf-dual-writer-SOQDKE6S.js} +2 -2
  268. package/dist/cli/chunks/sqlite-persistence-VP67CJPK.js +2 -0
  269. package/dist/cli/chunks/{status-handler-HSJLJPNG.js → status-handler-NNEF4SQV.js} +2 -2
  270. package/dist/cli/chunks/{structural-health-KWZAS7ON.js → structural-health-FY6QIA55.js} +2 -2
  271. package/dist/cli/chunks/{sync-6L5Z4IWH.js → sync-2QMSZ67Q.js} +2 -2
  272. package/dist/cli/chunks/{task-handler-KEAIPB6G.js → task-handler-GZJPE2QW.js} +2 -2
  273. package/dist/cli/chunks/{task-handlers-BPDN6OSM.js → task-handlers-AHM37D4I.js} +2 -2
  274. package/dist/cli/chunks/{test-PICO6RLU.js → test-JVA2S2R2.js} +4 -4
  275. package/dist/cli/chunks/{test-scheduling-BI3R3DX5.js → test-scheduling-PRMP4H6X.js} +3 -3
  276. package/dist/cli/chunks/{token-bootstrap-KMQC6ALU.js → token-bootstrap-YJEHCBV2.js} +2 -2
  277. package/dist/cli/chunks/{token-usage-QGDX7MLB.js → token-usage-G73L32OF.js} +2 -2
  278. package/dist/cli/chunks/{transformers-UNRYJSIU.js → transformers-U3TSLEGO.js} +2 -2
  279. package/dist/cli/chunks/{tree-sitter-wasm-parser-U22JYPOG.js → tree-sitter-wasm-parser-QXP2MNSX.js} +2 -2
  280. package/dist/cli/chunks/{types-CYXAGOY5.js → types-BIQ7O5VR.js} +2 -2
  281. package/dist/cli/chunks/unified-memory-JB4KPMPI.js +2 -0
  282. package/dist/cli/chunks/unified-memory-hnsw-RPSZZIWP.js +2 -0
  283. package/dist/cli/chunks/unified-persistence-L23T4C5C.js +2 -0
  284. package/dist/cli/chunks/{validate-IUY5BWAV.js → validate-CTBEA4BZ.js} +2 -2
  285. package/dist/cli/chunks/{validate-swarm-FXFKSEOI.js → validate-swarm-PHT6XW3A.js} +2 -2
  286. package/dist/cli/chunks/{vibium-DKZ64NR3.js → vibium-CRCYAH3V.js} +2 -2
  287. package/dist/cli/chunks/visual-security-F2I524IQ.js +2 -0
  288. package/dist/cli/chunks/{web-tree-sitter-WQDTN5CV.js → web-tree-sitter-2MH3G7K7.js} +2 -2
  289. package/dist/cli/chunks/{windsurf-installer-O5WOBFOQ.js → windsurf-installer-LBRNYFSI.js} +2 -2
  290. package/dist/cli/chunks/witness-chain-CN6FCWRY.js +2 -0
  291. package/dist/cli/chunks/{witness-chain-F7WXEVJA.js → witness-chain-HNFQLO7Q.js} +2 -2
  292. package/dist/cli/chunks/{workflow-47524I5G.js → workflow-DNAF6BQ2.js} +4 -4
  293. package/dist/cli/chunks/workflow-orchestrator-JJBCCNYI.js +2 -0
  294. package/dist/cli/chunks/{wrappers-MP2HWQD7.js → wrappers-U7AO6ZZN.js} +2 -2
  295. package/dist/init/browser-engine-installer.d.ts +60 -0
  296. package/dist/init/browser-engine-installer.js +92 -0
  297. package/dist/init/phases/09-assets.d.ts +2 -0
  298. package/dist/init/phases/09-assets.js +65 -0
  299. package/dist/init/skills-installer.js +1 -0
  300. package/dist/mcp/bundle.js +1 -1
  301. package/package.json +1 -1
  302. package/dist/cli/chunks/adapter-GE3RSG32.js +0 -2
  303. package/dist/cli/chunks/aqe-learning-engine-IYL6TK6E.js +0 -2
  304. package/dist/cli/chunks/base-L3G3GEZY.js +0 -2
  305. package/dist/cli/chunks/browser-workflow-7KTCY5FI.js +0 -2
  306. package/dist/cli/chunks/chunk-N5SLJOBK.js +0 -2
  307. package/dist/cli/chunks/client-3DPPDO2H.js +0 -2
  308. package/dist/cli/chunks/cross-domain-router-JOYTUBFT.js +0 -2
  309. package/dist/cli/chunks/dream-IF2HCRW4.js +0 -2
  310. package/dist/cli/chunks/esm-node-LNRP5BNU.js +0 -2
  311. package/dist/cli/chunks/hnsw-adapter-UPX4AXOQ.js +0 -2
  312. package/dist/cli/chunks/hnsw-index-CSI2EXXR.js +0 -2
  313. package/dist/cli/chunks/impact-analyzer-2YVBHMES.js +0 -2
  314. package/dist/cli/chunks/init-wizard-V6GZQMMR.js +0 -2
  315. package/dist/cli/chunks/kernel-EHJ4SP2Y.js +0 -2
  316. package/dist/cli/chunks/knowledge-graph-ZYXBWGKL.js +0 -2
  317. package/dist/cli/chunks/load-test-VDZEYGKV.js +0 -2
  318. package/dist/cli/chunks/memory-backend-IB3BU4VM.js +0 -2
  319. package/dist/cli/chunks/protocol-executor-H2ZG7JBJ.js +0 -2
  320. package/dist/cli/chunks/qe-reasoning-bank-ZCSHSKZU.js +0 -2
  321. package/dist/cli/chunks/queen-coordinator-NEC373VS.js +0 -2
  322. package/dist/cli/chunks/router-3PP5XRTD.js +0 -2
  323. package/dist/cli/chunks/routing-feedback-JNUFV2X3.js +0 -2
  324. package/dist/cli/chunks/rvf-native-adapter-PTOZXG4W.js +0 -2
  325. package/dist/cli/chunks/safe-db-CGYNYUES.js +0 -2
  326. package/dist/cli/chunks/schedule-NRN4WOHX.js +0 -2
  327. package/dist/cli/chunks/scheduler-DRAQGYLL.js +0 -2
  328. package/dist/cli/chunks/shared-rvf-adapter-6UVVDOHK.js +0 -2
  329. package/dist/cli/chunks/sqlite-persistence-3WG7PBPL.js +0 -2
  330. package/dist/cli/chunks/unified-memory-EXRANFUS.js +0 -2
  331. package/dist/cli/chunks/unified-memory-hnsw-GB752D44.js +0 -2
  332. package/dist/cli/chunks/unified-persistence-V2B3YWFD.js +0 -2
  333. package/dist/cli/chunks/visual-security-YMPI7X7V.js +0 -2
  334. package/dist/cli/chunks/witness-chain-7LIPUVMI.js +0 -2
  335. package/dist/cli/chunks/workflow-orchestrator-QPIAR4LI.js +0 -2
@@ -0,0 +1,330 @@
1
+ // Shared helpers for qe-browser scripts.
2
+ // Shells out to the `vibium` CLI and parses its --json output.
3
+ //
4
+ // Why shell-out instead of the vibium npm client:
5
+ // - Keeps this wrapper language-agnostic and truly thin
6
+ // - Matches how other AQE skills (a11y-ally, testability-scoring) invoke external tools
7
+ // - Lets us upgrade Vibium independently without touching our code
8
+
9
+ 'use strict';
10
+
11
+ const { spawnSync } = require('node:child_process');
12
+
13
+ const SKILL_NAME = 'qe-browser';
14
+ const SKILL_VERSION = '1.0.0';
15
+ const TRUST_TIER = 3;
16
+
17
+ // F1 (Phase 6): typed error so downstream skills can distinguish
18
+ // "vibium isn't installed" from "vibium ran but the test failed".
19
+ // The Fallback Policy in SKILL.md says scripts must surface this as a
20
+ // status: "skipped" envelope with reason: "browser-engine-unavailable"
21
+ // — see unavailableEnvelope() / runOrSkip() below.
22
+ class VibiumUnavailableError extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = 'VibiumUnavailableError';
26
+ // Stable contract field that downstream code can `instanceof`-check OR
27
+ // duck-type via this property when crossing module boundaries (e.g.
28
+ // when the helper is loaded from a different node_modules tree).
29
+ this.code = 'BROWSER_ENGINE_UNAVAILABLE';
30
+ }
31
+ }
32
+
33
+ // Inject `--headless` into every vibium call by default. The qe-browser
34
+ // helper scripts are designed for QE / CI use cases where there's no
35
+ // display server, and Vibium defaults to "visible by default" which fails
36
+ // in headless containers with "Missing X server or $DISPLAY". Users who
37
+ // want a visible browser for interactive debugging should call vibium
38
+ // directly, not through these helpers.
39
+ //
40
+ // Opt out by setting QE_BROWSER_HEADED=1 in the environment.
41
+ function injectHeadless(args) {
42
+ if (process.env.QE_BROWSER_HEADED === '1') return args;
43
+ if (args.includes('--headless') || args.includes('--headed')) return args;
44
+ return ['--headless', ...args];
45
+ }
46
+
47
+ function vibium(args, { input, timeoutMs = 30000 } = {}) {
48
+ const finalArgs = injectHeadless(args);
49
+ const result = spawnSync('vibium', finalArgs, {
50
+ encoding: 'utf8',
51
+ input,
52
+ timeout: timeoutMs,
53
+ maxBuffer: 64 * 1024 * 1024,
54
+ });
55
+
56
+ // F1: throw a TYPED error so the per-script main() can catch instanceof
57
+ // VibiumUnavailableError and emit the documented "skipped" envelope
58
+ // instead of a generic "failed" with the reason buried in `actual`.
59
+ if (result.error && result.error.code === 'ENOENT') {
60
+ throw new VibiumUnavailableError(
61
+ 'vibium binary not found on PATH. Install via `npm install -g vibium` or run `aqe init`.'
62
+ );
63
+ }
64
+
65
+ return {
66
+ status: result.status,
67
+ stdout: (result.stdout || '').toString(),
68
+ stderr: (result.stderr || '').toString(),
69
+ };
70
+ }
71
+
72
+ function vibiumJson(args, opts) {
73
+ const withJson = args.includes('--json') ? args : [...args, '--json'];
74
+ const res = vibium(withJson, opts);
75
+ if (res.status !== 0) {
76
+ const err = new Error(
77
+ `vibium ${args[0] || ''} exited ${res.status}: ${res.stderr.trim() || res.stdout.trim()}`
78
+ );
79
+ err.stdout = res.stdout;
80
+ err.stderr = res.stderr;
81
+ err.exitCode = res.status;
82
+ throw err;
83
+ }
84
+ const trimmed = res.stdout.trim();
85
+ if (!trimmed) return null;
86
+ try {
87
+ return JSON.parse(trimmed);
88
+ } catch (_err) {
89
+ // Some vibium commands emit non-JSON even with --json on error paths;
90
+ // return raw text so callers can decide what to do.
91
+ return { __raw: trimmed };
92
+ }
93
+ }
94
+
95
+ // Vibium's `eval` (with or without --stdin) returns the LAST EXPRESSION's
96
+ // value, NOT console.log output. With --json the response shape is:
97
+ // { ok: true, result: "<stringified value>" }
98
+ // where `result` is a STRING if the expression returned a string, or a
99
+ // Go-side serialization if it returned a non-string object. So our scripts
100
+ // MUST wrap their return value in JSON.stringify(...) and we parse the
101
+ // `result` field as JSON ourselves to get a real JS object back.
102
+ //
103
+ // Verified on Vibium v26.3.18 (2026-04-09).
104
+ function unwrapEvalResult(payload) {
105
+ if (payload === null || payload === undefined) return null;
106
+ // payload from vibiumJson is already a parsed object: { ok, result } or { __raw }
107
+ if (payload && typeof payload === 'object' && 'ok' in payload && 'result' in payload) {
108
+ if (payload.ok !== true) {
109
+ throw new Error(`vibium eval failed: ${JSON.stringify(payload)}`);
110
+ }
111
+ const result = payload.result;
112
+ if (typeof result === 'string') {
113
+ // The script wrapped its return value in JSON.stringify so parse it.
114
+ try {
115
+ return JSON.parse(result);
116
+ } catch (_e) {
117
+ return result;
118
+ }
119
+ }
120
+ return result;
121
+ }
122
+ return payload;
123
+ }
124
+
125
+ function vibiumEval(expression) {
126
+ const raw = vibiumJson(['eval', '--json', expression]);
127
+ return unwrapEvalResult(raw);
128
+ }
129
+
130
+ function vibiumEvalStdin(script) {
131
+ const raw = vibiumJson(['eval', '--stdin', '--json'], { input: script });
132
+ return unwrapEvalResult(raw);
133
+ }
134
+
135
+ function envelope({
136
+ operation,
137
+ summary,
138
+ status = 'success',
139
+ details = {},
140
+ metadata = {},
141
+ vibiumUnavailable = false,
142
+ reason = undefined,
143
+ }) {
144
+ const env = {
145
+ skillName: SKILL_NAME,
146
+ version: SKILL_VERSION,
147
+ timestamp: new Date().toISOString(),
148
+ status,
149
+ trustTier: TRUST_TIER,
150
+ output: {
151
+ operation,
152
+ summary,
153
+ ...details,
154
+ },
155
+ metadata,
156
+ };
157
+ // Top-level flag so downstream skills can branch on the contract without
158
+ // walking output.* sub-fields. Only set when true to keep the happy-path
159
+ // envelope shape unchanged for the 99% case.
160
+ if (vibiumUnavailable) env.vibiumUnavailable = true;
161
+ if (reason !== undefined) env.output.reason = reason;
162
+ return env;
163
+ }
164
+
165
+ // F1: produce the documented "skipped" envelope when vibium is missing.
166
+ // Contract per SKILL.md Fallback Policy:
167
+ // status: "skipped"
168
+ // output.reason: "browser-engine-unavailable"
169
+ // vibiumUnavailable: true (top-level)
170
+ // output.summary: actionable install guidance
171
+ function unavailableEnvelope(operation, message) {
172
+ return envelope({
173
+ operation,
174
+ summary: message,
175
+ status: 'skipped',
176
+ vibiumUnavailable: true,
177
+ reason: 'browser-engine-unavailable',
178
+ details: {
179
+ error: message,
180
+ remediation: [
181
+ 'Install vibium globally: `npm install -g vibium`',
182
+ 'Or re-run `aqe init` to install via the AQE bootstrap',
183
+ 'Set QE_BROWSER_HEADED=1 only for interactive debugging (not the cause here)',
184
+ ],
185
+ },
186
+ metadata: { executionTimeMs: 0 },
187
+ });
188
+ }
189
+
190
+ // Predicate so per-script catch blocks can decide whether to swallow an
191
+ // error (regular failure) or re-throw it so the outer runOrSkip can emit
192
+ // the skipped envelope. Cross-module-safe via the duck-typed `code` field.
193
+ function isVibiumUnavailable(err) {
194
+ return Boolean(
195
+ err &&
196
+ (err instanceof VibiumUnavailableError ||
197
+ err.code === 'BROWSER_ENGINE_UNAVAILABLE' ||
198
+ // The error string from vibium() also matches as a final fallback
199
+ // in case both the prototype and the code field were lost while
200
+ // crossing some serialization boundary.
201
+ (typeof err.message === 'string' &&
202
+ err.message.includes('vibium binary not found on PATH')))
203
+ );
204
+ }
205
+
206
+ // rethrowIfUnavailable: helper to use INSIDE per-script catch blocks so
207
+ // that the documented missing-vibium contract bubbles past lower-level
208
+ // "convert exception to failed envelope" handlers and reaches runOrSkip.
209
+ //
210
+ // Usage:
211
+ // try { ... vibium calls ... }
212
+ // catch (err) {
213
+ // rethrowIfUnavailable(err);
214
+ // return fail('myop', err.message);
215
+ // }
216
+ function rethrowIfUnavailable(err) {
217
+ if (isVibiumUnavailable(err)) {
218
+ if (err instanceof VibiumUnavailableError) throw err;
219
+ // Promote a duck-typed error to a real VibiumUnavailableError so
220
+ // downstream code only has to handle one type.
221
+ throw new VibiumUnavailableError(err.message || 'browser engine unavailable');
222
+ }
223
+ }
224
+
225
+ // runOrSkip wraps a per-script main() so that any VibiumUnavailableError
226
+ // thrown anywhere inside the operation is converted to the documented
227
+ // skipped envelope. Each helper script's main() is `() => fn()` returning
228
+ // the exit code from emit(). On unavailable, we emit() the skipped envelope
229
+ // and return its exit code (2).
230
+ function runOrSkip(operation, fn) {
231
+ try {
232
+ return fn();
233
+ } catch (err) {
234
+ if (isVibiumUnavailable(err)) {
235
+ return emit(unavailableEnvelope(operation, err.message));
236
+ }
237
+ throw err;
238
+ }
239
+ }
240
+
241
+ // parseArgs supports both `--key value` and `--key=value` forms.
242
+ //
243
+ // M5 (devil's-advocate finding): the previous implementation only handled
244
+ // the space-separated form. A user typing `--threshold=0.5` got
245
+ // `args['threshold=0.5'] = true` and a separate `args.threshold` was never
246
+ // set, so the value silently defaulted. The equals form is the dominant
247
+ // idiom in npm/node CLIs (`node --inspect=9229`), so we accept both. When
248
+ // the next token is itself a flag (`--include-hidden --json`) we treat the
249
+ // current flag as boolean — the same behavior as before.
250
+ function parseArgs(argv) {
251
+ const args = {};
252
+ for (let i = 0; i < argv.length; i += 1) {
253
+ const token = argv[i];
254
+ if (!token.startsWith('--')) continue;
255
+ const stripped = token.slice(2);
256
+ // --key=value form: split on first '=' only so values containing '='
257
+ // (URLs, regex with capture group names, base64) survive intact.
258
+ const eqIdx = stripped.indexOf('=');
259
+ if (eqIdx !== -1) {
260
+ const key = stripped.slice(0, eqIdx);
261
+ const value = stripped.slice(eqIdx + 1);
262
+ args[key] = value;
263
+ continue;
264
+ }
265
+ const key = stripped;
266
+ const next = argv[i + 1];
267
+ if (next === undefined || next.startsWith('--')) {
268
+ args[key] = true;
269
+ } else {
270
+ args[key] = next;
271
+ i += 1;
272
+ }
273
+ }
274
+ return args;
275
+ }
276
+
277
+ function readInlineOrFile(value) {
278
+ if (typeof value !== 'string') return value;
279
+ if (value.startsWith('@')) {
280
+ const fs = require('node:fs');
281
+ return fs.readFileSync(value.slice(1), 'utf8');
282
+ }
283
+ return value;
284
+ }
285
+
286
+ // Exit code contract (F1):
287
+ // 0 — success: every assertion passed / operation completed cleanly
288
+ // 1 — failed: genuine assertion failure or operation error
289
+ // 2 — skipped: vibium unavailable; environment problem, not a test result
290
+ //
291
+ // CI tooling can use this to distinguish "test legitimately failed" from
292
+ // "we couldn't run the test because the browser engine isn't installed."
293
+ function emit(env) {
294
+ process.stdout.write(`${JSON.stringify(env, null, 2)}\n`);
295
+ if (env.status === 'success') return 0;
296
+ if (env.status === 'skipped') return 2;
297
+ return 1;
298
+ }
299
+
300
+ function fail(operation, message, metadata = {}) {
301
+ return emit(
302
+ envelope({
303
+ operation,
304
+ summary: message,
305
+ status: 'failed',
306
+ details: { error: message },
307
+ metadata,
308
+ })
309
+ );
310
+ }
311
+
312
+ module.exports = {
313
+ SKILL_NAME,
314
+ SKILL_VERSION,
315
+ TRUST_TIER,
316
+ VibiumUnavailableError,
317
+ isVibiumUnavailable,
318
+ rethrowIfUnavailable,
319
+ vibium,
320
+ vibiumJson,
321
+ vibiumEval,
322
+ vibiumEvalStdin,
323
+ envelope,
324
+ unavailableEnvelope,
325
+ runOrSkip,
326
+ parseArgs,
327
+ readInlineOrFile,
328
+ emit,
329
+ fail,
330
+ };
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@aqe/qe-browser-scripts",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "commonjs",
6
+ "description": "Scoped package.json that keeps qe-browser helper scripts in CommonJS despite the repo root being ESM."
7
+ }
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env bash
2
+ # qe-browser smoke test
3
+ #
4
+ # Runs each helper script against pinned public fixtures (httpbin.org) and
5
+ # verifies the output structure. This is the script that gates PR-reopen
6
+ # per ADR-091 Phase 3 — it MUST be run on a machine with vibium installed
7
+ # before the qe-browser PR is considered safe to reopen.
8
+ #
9
+ # Exit codes:
10
+ # 0 — all smoke tests passed
11
+ # 1 — at least one smoke test failed
12
+ # 2 — vibium binary not on PATH (precondition unmet)
13
+ #
14
+ # Per feedback_no_unverified_failure_modes.md, this is the script we
15
+ # actually run, not just write. Per feedback_synthetic_fixtures_dont_count,
16
+ # all fixtures are pinned public endpoints (httpbin.org) — no synthetic
17
+ # stubs, no inline HTML.
18
+
19
+ set -uo pipefail
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
23
+ WORK_DIR="$(mktemp -d)"
24
+ trap 'rm -rf "$WORK_DIR"' EXIT
25
+
26
+ GREEN='\033[0;32m'
27
+ RED='\033[0;31m'
28
+ YELLOW='\033[1;33m'
29
+ NC='\033[0m'
30
+
31
+ PASS=0
32
+ FAIL=0
33
+ SKIPPED=0
34
+
35
+ ok() { echo -e "${GREEN}PASS${NC} $1"; PASS=$((PASS + 1)); }
36
+ bad() { echo -e "${RED}FAIL${NC} $1${2:+: $2}"; FAIL=$((FAIL + 1)); }
37
+ skip() { echo -e "${YELLOW}SKIP${NC} $1${2:+: $2}"; SKIPPED=$((SKIPPED + 1)); }
38
+
39
+ # ---------------------------------------------------------------------------
40
+ # Precondition: vibium on PATH
41
+ # ---------------------------------------------------------------------------
42
+ if ! command -v vibium >/dev/null 2>&1; then
43
+ echo -e "${RED}vibium binary not found on PATH${NC}"
44
+ echo "Install via: npm install -g vibium"
45
+ exit 2
46
+ fi
47
+
48
+ VIBIUM_VERSION=$(vibium --version 2>&1 | head -1)
49
+ echo "Smoke testing against $VIBIUM_VERSION"
50
+ echo "Skill dir: $SKILL_DIR"
51
+ echo "Work dir: $WORK_DIR"
52
+ echo ""
53
+
54
+ # ---------------------------------------------------------------------------
55
+ # tc001 — assert.js url_contains against pinned httpbin form
56
+ # ---------------------------------------------------------------------------
57
+ vibium --headless go https://httpbin.org/forms/post >/dev/null 2>&1 || true
58
+ RESULT=$(node "$SKILL_DIR/scripts/assert.js" --checks \
59
+ '[{"kind": "url_contains", "text": "httpbin.org/forms"}]' 2>&1)
60
+ EXIT=$?
61
+ if [ "$EXIT" = "0" ] && echo "$RESULT" | grep -q '"status": "success"'; then
62
+ ok "tc001 url_contains on httpbin form"
63
+ else
64
+ bad "tc001 url_contains on httpbin form" "exit=$EXIT, result=$RESULT"
65
+ fi
66
+
67
+ # ---------------------------------------------------------------------------
68
+ # tc002 — assert.js selector_visible against pinned httpbin /html
69
+ # ---------------------------------------------------------------------------
70
+ vibium --headless go https://httpbin.org/html >/dev/null 2>&1 || true
71
+ RESULT=$(node "$SKILL_DIR/scripts/assert.js" --checks \
72
+ '[{"kind": "selector_visible", "selector": "h1"}]' 2>&1)
73
+ EXIT=$?
74
+ if [ "$EXIT" = "0" ] && echo "$RESULT" | grep -q '"passed": true'; then
75
+ ok "tc002 selector_visible h1 on httpbin /html"
76
+ else
77
+ bad "tc002 selector_visible h1 on httpbin /html" "exit=$EXIT"
78
+ fi
79
+
80
+ # ---------------------------------------------------------------------------
81
+ # tc003 — assert.js failing assertion exits non-zero
82
+ # ---------------------------------------------------------------------------
83
+ RESULT=$(node "$SKILL_DIR/scripts/assert.js" --checks \
84
+ '[{"kind": "url_contains", "text": "this-does-not-exist"}]' 2>&1)
85
+ EXIT=$?
86
+ if [ "$EXIT" = "1" ] && echo "$RESULT" | grep -q '"status": "failed"'; then
87
+ ok "tc003 failing assertion exits 1"
88
+ else
89
+ bad "tc003 failing assertion exits 1" "exit=$EXIT (expected 1)"
90
+ fi
91
+
92
+ # ---------------------------------------------------------------------------
93
+ # tc004 — batch.js navigate + wait + assert in one call
94
+ # ---------------------------------------------------------------------------
95
+ RESULT=$(node "$SKILL_DIR/scripts/batch.js" --steps \
96
+ '[{"action":"go","url":"https://httpbin.org/html"},{"action":"wait_load"},{"action":"assert","checks":[{"kind":"url_contains","text":"/html"}]}]' \
97
+ --summary-only 2>&1)
98
+ EXIT=$?
99
+ if [ "$EXIT" = "0" ] && echo "$RESULT" | grep -q '"passedSteps": 3'; then
100
+ ok "tc004 batch 3-step happy path"
101
+ else
102
+ bad "tc004 batch 3-step happy path" "exit=$EXIT"
103
+ fi
104
+
105
+ # ---------------------------------------------------------------------------
106
+ # tc005 — batch.js stops on failure
107
+ # ---------------------------------------------------------------------------
108
+ RESULT=$(node "$SKILL_DIR/scripts/batch.js" --steps \
109
+ '[{"action":"go","url":"https://httpbin.org/html"},{"action":"click","selector":"#does-not-exist-selector"},{"action":"go","url":"https://httpbin.org/forms/post"}]' 2>&1)
110
+ EXIT=$?
111
+ if [ "$EXIT" = "1" ] && echo "$RESULT" | grep -q '"failedStep"'; then
112
+ ok "tc005 batch stops on first failure"
113
+ else
114
+ bad "tc005 batch stops on first failure" "exit=$EXIT"
115
+ fi
116
+
117
+ # ---------------------------------------------------------------------------
118
+ # tc006 — visual-diff.js creates baseline on first run
119
+ #
120
+ # Set explicit viewport BEFORE screenshot so the two visual-diff runs have
121
+ # the same dimensions. Without this the chromium headless window picks
122
+ # whatever size it likes per run, and httpbin.org/html renders at different
123
+ # sizes between runs (768×654 vs 765×672 observed), making pixel-diff
124
+ # spuriously fail. This is documented in references/assertion-kinds.md.
125
+ # ---------------------------------------------------------------------------
126
+ rm -rf "$PWD/.aqe/visual-baselines/smoke_test_baseline"*
127
+ vibium --headless viewport 1280 720 >/dev/null 2>&1 || true
128
+ vibium --headless go https://httpbin.org/html >/dev/null 2>&1 || true
129
+ RESULT=$(node "$SKILL_DIR/scripts/visual-diff.js" --name smoke_test_baseline 2>&1)
130
+ EXIT=$?
131
+ if [ "$EXIT" = "0" ] && echo "$RESULT" | grep -q '"baseline_created"'; then
132
+ ok "tc006 visual-diff baseline created"
133
+ else
134
+ bad "tc006 visual-diff baseline created" "exit=$EXIT"
135
+ fi
136
+
137
+ # ---------------------------------------------------------------------------
138
+ # tc007 — visual-diff.js matches second identical run
139
+ #
140
+ # Force the same viewport before re-shooting so dimensions match the baseline.
141
+ # ---------------------------------------------------------------------------
142
+ vibium --headless viewport 1280 720 >/dev/null 2>&1 || true
143
+ RESULT=$(node "$SKILL_DIR/scripts/visual-diff.js" --name smoke_test_baseline 2>&1)
144
+ EXIT=$?
145
+ if [ "$EXIT" = "0" ] && echo "$RESULT" | grep -qE '"(match|baseline_created)"'; then
146
+ ok "tc007 visual-diff second run matches"
147
+ else
148
+ bad "tc007 visual-diff second run matches" "exit=$EXIT"
149
+ fi
150
+
151
+ # ---------------------------------------------------------------------------
152
+ # tc008 — check-injection.js clean page
153
+ # ---------------------------------------------------------------------------
154
+ vibium --headless go https://httpbin.org/html >/dev/null 2>&1 || true
155
+ RESULT=$(node "$SKILL_DIR/scripts/check-injection.js" --include-hidden 2>&1)
156
+ EXIT=$?
157
+ if [ "$EXIT" = "0" ] && echo "$RESULT" | grep -q '"severity": "none"'; then
158
+ ok "tc008 check-injection clean page"
159
+ else
160
+ bad "tc008 check-injection clean page" "exit=$EXIT"
161
+ fi
162
+
163
+ # ---------------------------------------------------------------------------
164
+ # tc010 — intent-score.js submit_form on pinned httpbin form
165
+ # ---------------------------------------------------------------------------
166
+ vibium --headless go https://httpbin.org/forms/post >/dev/null 2>&1 || true
167
+ RESULT=$(node "$SKILL_DIR/scripts/intent-score.js" --intent submit_form 2>&1)
168
+ EXIT=$?
169
+ if [ "$EXIT" = "0" ] && echo "$RESULT" | grep -q '"intent": "submit_form"'; then
170
+ ok "tc010 intent-score submit_form on httpbin form"
171
+ else
172
+ bad "tc010 intent-score submit_form on httpbin form" "exit=$EXIT"
173
+ fi
174
+
175
+ # ---------------------------------------------------------------------------
176
+ # tc011 — F1 contract: vibium-missing → skipped envelope + exit code 2
177
+ # ---------------------------------------------------------------------------
178
+ # Build a fake bin dir that contains node (so the helper can run) but NOT
179
+ # vibium. The helper must:
180
+ # 1. Throw VibiumUnavailableError from lib/vibium.js
181
+ # 2. Have it caught by runOrSkip wrapping main()
182
+ # 3. Emit a status: "skipped" envelope with vibiumUnavailable: true
183
+ # 4. Exit with code 2 (not 1)
184
+ FAKE_BIN="$WORK_DIR/fake-bin"
185
+ mkdir -p "$FAKE_BIN"
186
+ ln -sf "$(command -v node)" "$FAKE_BIN/node"
187
+ RESULT=$(env -i PATH="$FAKE_BIN" HOME="$HOME" TERM=dumb \
188
+ node "$SKILL_DIR/scripts/assert.js" --checks '[{"kind":"url_contains","text":"foo"}]' 2>&1)
189
+ EXIT=$?
190
+ if [ "$EXIT" = "2" ] \
191
+ && echo "$RESULT" | grep -q '"status": "skipped"' \
192
+ && echo "$RESULT" | grep -q '"vibiumUnavailable": true' \
193
+ && echo "$RESULT" | grep -q '"reason": "browser-engine-unavailable"'; then
194
+ ok "tc011 F1 missing-vibium emits skipped envelope + exit 2"
195
+ else
196
+ bad "tc011 F1 missing-vibium emits skipped envelope + exit 2" "exit=$EXIT"
197
+ fi
198
+
199
+ # ---------------------------------------------------------------------------
200
+ # Summary
201
+ # ---------------------------------------------------------------------------
202
+ echo ""
203
+ echo "─────────────────────────────────"
204
+ echo "PASS: $PASS"
205
+ echo "FAIL: $FAIL"
206
+ echo "SKIPPED: $SKIPPED"
207
+ echo "─────────────────────────────────"
208
+
209
+ if [ "$FAIL" -gt 0 ]; then
210
+ exit 1
211
+ fi
212
+ exit 0
@@ -0,0 +1,46 @@
1
+ {
2
+ "skillName": "qe-browser",
3
+ "skillVersion": "1.0.0",
4
+ "requiredTools": [
5
+ "node",
6
+ "jq"
7
+ ],
8
+ "optionalTools": [
9
+ "vibium",
10
+ "pixelmatch",
11
+ "pngjs"
12
+ ],
13
+ "schemaPath": "schemas/output.json",
14
+ "requiredFields": [
15
+ "skillName",
16
+ "version",
17
+ "timestamp",
18
+ "status",
19
+ "trustTier",
20
+ "output"
21
+ ],
22
+ "requiredNonEmptyFields": [
23
+ ".output.operation",
24
+ ".output.summary"
25
+ ],
26
+ "mustContainTerms": [],
27
+ "mustNotContainTerms": [],
28
+ "enumValidations": {
29
+ ".status": [
30
+ "success",
31
+ "partial",
32
+ "failed",
33
+ "skipped"
34
+ ],
35
+ ".trustTier": [3],
36
+ ".output.operation": [
37
+ "assert",
38
+ "batch",
39
+ "visual-diff",
40
+ "check-injection",
41
+ "intent-score",
42
+ "navigate",
43
+ "capture"
44
+ ]
45
+ }
46
+ }