qa360 2.1.7 → 2.2.1

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 (909) hide show
  1. package/.BETA_TESTING_FEEDBACK.md +256 -0
  2. package/.claude/settings.local.json +154 -0
  3. package/.editorconfig +21 -0
  4. package/.github/CODEOWNERS +23 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +108 -0
  6. package/.github/ISSUE_TEMPLATE/feedback_dx.yml +121 -0
  7. package/.github/dependabot.yml +35 -0
  8. package/.github/workflows/mcp-dx.yml +106 -0
  9. package/.github/workflows/release.yml +26 -0
  10. package/.github/workflows/test.yml +93 -0
  11. package/.nvmrc +1 -0
  12. package/.qa360/vault.db +0 -0
  13. package/.qa360/vault.db-shm +0 -0
  14. package/.qa360/vault.db-wal +0 -0
  15. package/.qa360-artifacts/.gitkeep +0 -0
  16. package/.qa360-artifacts/baselines/.gitkeep +0 -0
  17. package/.qa360-artifacts/cache/.gitkeep +0 -0
  18. package/.qa360-artifacts/reports/.gitkeep +0 -0
  19. package/.qa360-artifacts/screenshots/.gitkeep +0 -0
  20. package/.qa360-baselines/www_xyqo_ai.baseline.json +33 -0
  21. package/CHANGELOG.md +234 -0
  22. package/CODEOWNERS +43 -0
  23. package/CONTRIBUTING.md +273 -0
  24. package/NOVICE_USER_GUIDE.md +272 -0
  25. package/QUICK_START.md +191 -0
  26. package/README.md +191 -163
  27. package/adapters/README.md +46 -0
  28. package/check-branches.sh +32 -0
  29. package/cli/.qa360/keys/ed25519.key +1 -0
  30. package/cli/.qa360/keys/ed25519.pub +1 -0
  31. package/cli/CHANGELOG.md +84 -0
  32. package/cli/LICENSE +24 -0
  33. package/cli/README.md +222 -0
  34. package/cli/examples/README.md +160 -0
  35. package/cli/package.json +76 -0
  36. package/cli/scripts/bundle-for-npm.sh +51 -0
  37. package/cli/scripts/validate-package.js +116 -0
  38. package/cli/src/__tests__/commands/doctor.test.ts +108 -0
  39. package/cli/src/__tests__/index.test.ts +15 -0
  40. package/cli/src/cli-minimal.ts +44 -0
  41. package/cli/src/commands/__tests__/crawl.test.ts +412 -0
  42. package/cli/src/commands/__tests__/doctor-qa360-home.test.ts +156 -0
  43. package/cli/src/commands/__tests__/e2e-ui-tests.test.ts +494 -0
  44. package/cli/src/commands/__tests__/e2e.test.ts +187 -0
  45. package/cli/src/commands/__tests__/flakiness.test.ts +528 -0
  46. package/cli/src/commands/__tests__/generate.test.ts +507 -0
  47. package/cli/src/commands/__tests__/history.integration.test.ts +358 -0
  48. package/cli/src/commands/__tests__/history.test.ts +433 -0
  49. package/cli/src/commands/__tests__/monitor-realworld.test.ts +199 -0
  50. package/cli/src/commands/__tests__/monitor.test.ts +81 -0
  51. package/cli/src/commands/__tests__/ollama.test.ts +529 -0
  52. package/cli/src/commands/__tests__/repair.test.ts +225 -0
  53. package/cli/src/commands/__tests__/report.integration.test.ts +167 -0
  54. package/cli/src/commands/__tests__/report.test.ts +294 -0
  55. package/cli/src/commands/__tests__/report.vitest.ts +288 -0
  56. package/cli/src/commands/__tests__/retry.test.ts +78 -0
  57. package/cli/src/commands/__tests__/run.integration.test.ts +240 -0
  58. package/cli/src/commands/__tests__/run.test.ts +346 -0
  59. package/cli/src/commands/__tests__/run.vitest.ts +301 -0
  60. package/cli/src/commands/__tests__/secrets.test.ts +114 -0
  61. package/cli/src/commands/__tests__/serve.test.ts +80 -0
  62. package/cli/src/commands/__tests__/verify.test.ts +103 -0
  63. package/cli/src/commands/ai.ts +702 -0
  64. package/cli/src/commands/ask.ts +678 -0
  65. package/cli/src/commands/coverage.ts +305 -0
  66. package/cli/src/commands/crawl.ts +155 -0
  67. package/cli/src/commands/doctor.ts +610 -0
  68. package/cli/src/commands/examples.ts +248 -0
  69. package/cli/src/commands/explain.ts +710 -0
  70. package/cli/src/commands/flakiness.ts +560 -0
  71. package/cli/src/commands/generate.ts +566 -0
  72. package/cli/src/commands/history.ts +914 -0
  73. package/cli/src/commands/init.ts +777 -0
  74. package/cli/src/commands/monitor.ts +270 -0
  75. package/cli/src/commands/ollama.ts +337 -0
  76. package/cli/src/commands/pack.ts +497 -0
  77. package/cli/src/commands/regression.ts +400 -0
  78. package/cli/src/commands/repair.ts +356 -0
  79. package/cli/src/commands/report.ts +463 -0
  80. package/cli/src/commands/retry.ts +380 -0
  81. package/cli/src/commands/run.ts +220 -0
  82. package/cli/src/commands/scan.ts +177 -0
  83. package/cli/src/commands/secrets.ts +340 -0
  84. package/cli/src/commands/serve.ts +194 -0
  85. package/cli/src/commands/slo.ts +387 -0
  86. package/cli/src/commands/verify-temp-note.md +11 -0
  87. package/cli/src/commands/verify.ts +322 -0
  88. package/cli/src/generators/index.ts +6 -0
  89. package/cli/src/generators/json-reporter.ts +15 -0
  90. package/cli/src/generators/test-generator.ts +90 -0
  91. package/cli/src/index.ts +289 -0
  92. package/cli/src/scanners/dom-scanner.ts +360 -0
  93. package/cli/src/scanners/index.ts +5 -0
  94. package/cli/src/types/scan.ts +84 -0
  95. package/cli/src/utils/config.ts +145 -0
  96. package/cli/tsconfig.bundle.json +12 -0
  97. package/cli/tsconfig.json +23 -0
  98. package/cli/vitest.config.ts +59 -0
  99. package/core/LICENSE +24 -0
  100. package/core/README.md +64 -0
  101. package/core/package.json +81 -0
  102. package/core/src/__tests__/adapters-contract/adapters-contract.test.md +156 -0
  103. package/core/src/__tests__/index.test.ts +31 -0
  104. package/core/src/__tests__/integration/phase3.test.ts +405 -0
  105. package/core/src/__tests__/pack/validator.test.ts +312 -0
  106. package/core/src/__tests__/secrets/crypto.test.ts +190 -0
  107. package/core/src/__tests__/secrets/manager.test.ts +316 -0
  108. package/core/src/__tests__/security/redactor-phase3.test.ts +233 -0
  109. package/core/src/__tests__/serve/health-checker.test.ts +155 -0
  110. package/core/src/__tests__/serve/process-manager.test.ts +213 -0
  111. package/core/src/__tests__/serve/server.test.ts +103 -0
  112. package/core/src/__tests__/vault/cas.test.ts +178 -0
  113. package/core/src/__tests__/vault/vault.test.ts +296 -0
  114. package/core/src/adapters/__tests__/fixtures/jest-coverage.json +8 -0
  115. package/core/src/adapters/__tests__/fixtures/jest-results.json +41 -0
  116. package/core/src/adapters/__tests__/fixtures/pytest-junit.xml +16 -0
  117. package/core/src/adapters/__tests__/fixtures/vitest-coverage.json +8 -0
  118. package/core/src/adapters/__tests__/fixtures/vitest-results.json +50 -0
  119. package/core/src/adapters/__tests__/gitleaks-secrets.test.ts +452 -0
  120. package/core/src/adapters/__tests__/jest-adapter.test.ts +276 -0
  121. package/core/src/adapters/__tests__/k6-perf.test.ts +538 -0
  122. package/core/src/adapters/__tests__/osv-deps.test.ts +471 -0
  123. package/core/src/adapters/__tests__/playwright-native-api.test.ts +792 -0
  124. package/core/src/adapters/__tests__/playwright-ui-e2e.test.ts +431 -0
  125. package/core/src/adapters/__tests__/playwright-ui.test.ts +1073 -0
  126. package/core/src/adapters/__tests__/pytest-adapter.test.ts +207 -0
  127. package/core/src/adapters/__tests__/semgrep-sast.test.ts +436 -0
  128. package/core/src/adapters/__tests__/vitest-adapter.test.ts +208 -0
  129. package/core/src/adapters/__tests__/zap-dast.test.ts +453 -0
  130. package/core/src/adapters/gitleaks-secrets.ts +521 -0
  131. package/core/src/adapters/jest-adapter.ts +306 -0
  132. package/core/src/adapters/k6-perf.ts +479 -0
  133. package/core/src/adapters/osv-deps.ts +467 -0
  134. package/core/src/adapters/playwright-native-adapter.ts +472 -0
  135. package/core/src/adapters/playwright-native-api.ts +619 -0
  136. package/core/src/adapters/playwright-ui.ts +1088 -0
  137. package/core/src/adapters/pytest-adapter.ts +472 -0
  138. package/core/src/adapters/semgrep-sast.ts +410 -0
  139. package/core/src/adapters/unit-test-types.ts +106 -0
  140. package/core/src/adapters/vitest-adapter.ts +295 -0
  141. package/core/src/adapters/zap-dast.ts +551 -0
  142. package/core/src/ai/__tests__/deepseek-provider.test.ts +586 -0
  143. package/core/src/ai/__tests__/ollama-provider.test.ts +641 -0
  144. package/core/src/ai/anthropic-provider.ts +262 -0
  145. package/core/src/ai/deepseek-provider.ts +315 -0
  146. package/core/src/ai/index.ts +87 -0
  147. package/core/src/ai/llm-client.ts +52 -0
  148. package/core/src/ai/mock-provider.ts +146 -0
  149. package/core/src/ai/ollama-provider.ts +269 -0
  150. package/core/src/ai/openai-provider.ts +240 -0
  151. package/core/src/ai/provider-factory.ts +408 -0
  152. package/core/src/artifacts/README.md +78 -0
  153. package/core/src/artifacts/index.ts +16 -0
  154. package/core/src/artifacts/ui-artifacts.ts +412 -0
  155. package/core/src/assertions/__tests__/engine.test.ts +360 -0
  156. package/core/src/assertions/engine.ts +577 -0
  157. package/core/src/assertions/index.ts +13 -0
  158. package/core/src/assertions/types.ts +229 -0
  159. package/core/src/auth/__tests__/api-key-provider.test.ts +282 -0
  160. package/core/src/auth/__tests__/auth-manager.test.ts +430 -0
  161. package/core/src/auth/__tests__/basic-auth-provider.test.ts +364 -0
  162. package/core/src/auth/__tests__/cloud-providers.test.ts +751 -0
  163. package/core/src/auth/__tests__/jwt-provider.test.ts +400 -0
  164. package/core/src/auth/__tests__/oauth2-provider.test.ts +383 -0
  165. package/core/src/auth/__tests__/totp-provider.test.ts +294 -0
  166. package/core/src/auth/__tests__/ui-login-provider.test.ts +323 -0
  167. package/core/src/auth/api-key-provider.ts +75 -0
  168. package/core/src/auth/aws-iam-provider.ts +212 -0
  169. package/core/src/auth/azure-ad-provider.ts +126 -0
  170. package/core/src/auth/basic-auth-provider.ts +133 -0
  171. package/core/src/auth/gcp-adc-provider.ts +146 -0
  172. package/core/src/auth/index.ts +342 -0
  173. package/core/src/auth/jwt-provider.ts +193 -0
  174. package/core/src/auth/manager.ts +281 -0
  175. package/core/src/auth/oauth2-provider.ts +141 -0
  176. package/core/src/auth/totp-provider.ts +163 -0
  177. package/core/src/auth/ui-login-provider.ts +242 -0
  178. package/core/src/cache/__tests__/lru-cache.test.ts +564 -0
  179. package/core/src/cache/index.ts +13 -0
  180. package/core/src/cache/lru-cache.ts +536 -0
  181. package/core/src/crawler/__tests__/journey-generator.test.ts +344 -0
  182. package/core/src/crawler/__tests__/selector-generator.test.ts +211 -0
  183. package/core/src/crawler/index.ts +335 -0
  184. package/core/src/crawler/journey-generator.ts +471 -0
  185. package/core/src/crawler/page-analyzer.ts +857 -0
  186. package/core/src/crawler/selector-generator.ts +280 -0
  187. package/core/src/crawler/types.ts +475 -0
  188. package/core/src/dashboard/__tests__/real-world.test.ts +430 -0
  189. package/core/src/dashboard/__tests__/server.test.ts +283 -0
  190. package/core/src/dashboard/__tests__/types.test.ts +208 -0
  191. package/core/src/dashboard/assets.ts +692 -0
  192. package/core/src/dashboard/index.ts +17 -0
  193. package/core/src/dashboard/server.ts +401 -0
  194. package/core/src/dashboard/types.ts +78 -0
  195. package/core/src/discoverer/__tests__/test-discoverer.test.ts +444 -0
  196. package/core/src/discoverer/index.ts +374 -0
  197. package/core/src/fixtures/__tests__/loader.test.ts +246 -0
  198. package/core/src/fixtures/__tests__/resolver.test.ts +334 -0
  199. package/core/src/fixtures/index.ts +9 -0
  200. package/core/src/fixtures/loader.ts +200 -0
  201. package/core/src/fixtures/resolver.ts +221 -0
  202. package/core/src/fixtures/types.ts +86 -0
  203. package/core/src/flakiness/__tests__/flakiness.test.ts +554 -0
  204. package/core/src/flakiness/index.ts +536 -0
  205. package/core/src/generation/__tests__/code-formatter.test.ts +170 -0
  206. package/core/src/generation/__tests__/code-generator-contract.test.ts +207 -0
  207. package/core/src/generation/__tests__/code-generator.test.ts +586 -0
  208. package/core/src/generation/__tests__/crawler-pack-generator.test.ts +479 -0
  209. package/core/src/generation/__tests__/generation-e2e-b2bshop.test.ts +718 -0
  210. package/core/src/generation/__tests__/generation-integration.test.ts +655 -0
  211. package/core/src/generation/__tests__/pack-generator.test.ts +408 -0
  212. package/core/src/generation/__tests__/prompt-builder.test.ts +200 -0
  213. package/core/src/generation/__tests__/real-provider-integration.test.ts +414 -0
  214. package/core/src/generation/__tests__/source-analyzer.test.ts +774 -0
  215. package/core/src/generation/__tests__/test-optimizer.test.ts +255 -0
  216. package/core/src/generation/code-formatter.ts +408 -0
  217. package/core/src/generation/code-generator.ts +470 -0
  218. package/core/src/generation/crawler-pack-generator.ts +289 -0
  219. package/core/src/generation/generator.ts +113 -0
  220. package/core/src/generation/index.ts +59 -0
  221. package/core/src/generation/pack-generator.ts +527 -0
  222. package/core/src/generation/prompt-builder.ts +772 -0
  223. package/core/src/generation/source-analyzer.ts +830 -0
  224. package/core/src/generation/test-optimizer.ts +474 -0
  225. package/core/src/generation/types.ts +217 -0
  226. package/core/src/hooks/__tests__/compose.test.ts +636 -0
  227. package/core/src/hooks/__tests__/runner.test.ts +478 -0
  228. package/core/src/hooks/compose.ts +268 -0
  229. package/core/src/hooks/runner.ts +364 -0
  230. package/core/src/index.ts +255 -0
  231. package/core/src/pack/__tests__/migrator.test.ts +594 -0
  232. package/core/src/pack/__tests__/validator.test.ts +759 -0
  233. package/core/src/pack/migrator.ts +353 -0
  234. package/core/src/pack/validator.ts +359 -0
  235. package/core/src/pack-v2/__tests__/loader.test.ts +533 -0
  236. package/core/src/pack-v2/__tests__/migrator.test.ts +455 -0
  237. package/core/src/pack-v2/__tests__/validator.test.ts +609 -0
  238. package/core/src/pack-v2/index.ts +41 -0
  239. package/core/src/pack-v2/loader.ts +358 -0
  240. package/core/src/pack-v2/migrator.ts +540 -0
  241. package/core/src/pack-v2/validator.ts +731 -0
  242. package/core/src/parallel/README.md +143 -0
  243. package/core/src/parallel/index.ts +16 -0
  244. package/core/src/parallel/parallel-runner.ts +282 -0
  245. package/core/src/pom/__tests__/loader.test.ts +378 -0
  246. package/core/src/pom/base-page.ts +425 -0
  247. package/core/src/pom/index.ts +45 -0
  248. package/core/src/pom/loader.ts +480 -0
  249. package/core/src/pom/types.ts +146 -0
  250. package/core/src/proof/__tests__/proof-roundtrip.test.ts +149 -0
  251. package/core/src/proof/__tests__/schema-validation-manual.mjs +211 -0
  252. package/core/src/proof/__tests__/schema-validation.test.ts +336 -0
  253. package/core/src/proof/__tests__/signer.test.ts +486 -0
  254. package/core/src/proof/__tests__/temporal-regression.test.ts +537 -0
  255. package/core/src/proof/__tests__/verifier-advanced.test.ts +588 -0
  256. package/core/src/proof/__tests__/verifier.test.ts +413 -0
  257. package/core/src/proof/bundle.ts +290 -0
  258. package/core/src/proof/canonicalize.ts +116 -0
  259. package/core/src/proof/index.ts +74 -0
  260. package/core/src/proof/schema.ts +285 -0
  261. package/core/src/proof/signer.ts +293 -0
  262. package/core/src/proof/verifier.ts +380 -0
  263. package/core/src/regression/__tests__/detector.test.ts +396 -0
  264. package/core/src/regression/__tests__/trend-analyzer.test.ts +300 -0
  265. package/core/src/regression/detector.ts +629 -0
  266. package/core/src/regression/index.ts +34 -0
  267. package/core/src/regression/trend-analyzer.ts +468 -0
  268. package/core/src/regression/types.ts +295 -0
  269. package/core/src/regression/vault.ts +419 -0
  270. package/core/src/repair/__tests__/repairer.test.ts +572 -0
  271. package/core/src/repair/__tests__/types.test.ts +302 -0
  272. package/core/src/repair/engine/__tests__/fixer.test.ts +482 -0
  273. package/core/src/repair/engine/__tests__/suggestion-engine.test.ts +395 -0
  274. package/core/src/repair/engine/fixer.ts +271 -0
  275. package/core/src/repair/engine/suggestion-engine.ts +234 -0
  276. package/core/src/repair/index.ts +53 -0
  277. package/core/src/repair/repairer.ts +376 -0
  278. package/core/src/repair/types.ts +119 -0
  279. package/core/src/repair/utils/__tests__/error-analyzer.test.ts +454 -0
  280. package/core/src/repair/utils/error-analyzer.ts +308 -0
  281. package/core/src/reporting/README.md +144 -0
  282. package/core/src/reporting/html-reporter.ts +835 -0
  283. package/core/src/reporting/index.ts +16 -0
  284. package/core/src/retry/README.md +192 -0
  285. package/core/src/retry/__tests__/flakiness-integration.test.ts +475 -0
  286. package/core/src/retry/__tests__/retry-engine.test.ts +424 -0
  287. package/core/src/retry/flakiness-integration.ts +267 -0
  288. package/core/src/retry/index.ts +48 -0
  289. package/core/src/retry/retry-engine.ts +368 -0
  290. package/core/src/retry/types.ts +208 -0
  291. package/core/src/retry/vault.ts +413 -0
  292. package/core/src/runner/__tests__/flakiness-integration.test.ts +566 -0
  293. package/core/src/runner/__tests__/phase3-e2e-b2bshop.test.ts +218 -0
  294. package/core/src/runner/__tests__/phase3-e2e-reqres.test.ts +199 -0
  295. package/core/src/runner/__tests__/phase3-runner.test.ts +1118 -0
  296. package/core/src/runner/e2e-helpers.ts +216 -0
  297. package/core/src/runner/phase3-runner.ts +1536 -0
  298. package/core/src/schemas/gherkin-report.json +122 -0
  299. package/core/src/secrets/__tests__/crypto.test.ts +180 -0
  300. package/core/src/secrets/crypto.ts +289 -0
  301. package/core/src/secrets/manager.ts +272 -0
  302. package/core/src/security/__tests__/hardening.test.ts +480 -0
  303. package/core/src/security/redaction-patterns-extended.ts +278 -0
  304. package/core/src/security/redactor.ts +326 -0
  305. package/core/src/self-healing/assertion-healer.ts +485 -0
  306. package/core/src/self-healing/engine.ts +626 -0
  307. package/core/src/self-healing/index.ts +33 -0
  308. package/core/src/self-healing/selector-healer.ts +488 -0
  309. package/core/src/self-healing/types.ts +193 -0
  310. package/core/src/serve/diagnostics-collector.ts +201 -0
  311. package/core/src/serve/health-checker.ts +274 -0
  312. package/core/src/serve/index.ts +9 -0
  313. package/core/src/serve/metrics-collector.ts +386 -0
  314. package/core/src/serve/process-manager.ts +265 -0
  315. package/core/src/serve/server.ts +230 -0
  316. package/core/src/slo/config.ts +408 -0
  317. package/core/src/slo/index.ts +68 -0
  318. package/core/src/slo/sli-calculator.ts +474 -0
  319. package/core/src/slo/slo-tracker.ts +481 -0
  320. package/core/src/slo/types.ts +408 -0
  321. package/core/src/slo/vault.ts +600 -0
  322. package/core/src/tui/__tests__/monitor.test.ts +336 -0
  323. package/core/src/tui/__tests__/real-world.test.ts +376 -0
  324. package/core/src/tui/__tests__/renderer.test.ts +201 -0
  325. package/core/src/tui/__tests__/types.test.ts +295 -0
  326. package/core/src/tui/index.ts +19 -0
  327. package/core/src/tui/monitor.ts +331 -0
  328. package/core/src/tui/renderer.ts +269 -0
  329. package/core/src/tui/types.ts +68 -0
  330. package/core/src/types/pack-v1.ts +305 -0
  331. package/core/src/types/pack-v2.ts +525 -0
  332. package/core/src/types/trust-score.ts +258 -0
  333. package/core/src/vault/__tests__/flakiness-vault.test.ts +562 -0
  334. package/core/src/vault/__tests__/vault.test.ts +259 -0
  335. package/core/src/vault/cas.ts +323 -0
  336. package/core/src/vault/index.ts +1361 -0
  337. package/core/src/vault/schema.sql +168 -0
  338. package/core/src/visual/README.md +185 -0
  339. package/core/src/visual/index.ts +14 -0
  340. package/core/src/visual/visual-regression.ts +347 -0
  341. package/core/src/watch/__tests__/watch-mode.test.ts +192 -0
  342. package/core/src/watch/index.ts +14 -0
  343. package/core/src/watch/watch-mode.ts +565 -0
  344. package/core/tsconfig.json +12 -0
  345. package/core/vitest.config.ts +52 -0
  346. package/docs/ARCHITECTURE.md +901 -0
  347. package/docs/AUDIT-GLOBAL-DEC2025.md +271 -0
  348. package/docs/BETA_TESTING.md +257 -0
  349. package/docs/BETA_TESTING_PLAN.md +727 -0
  350. package/docs/CERTIFICATION-REPORT.md +142 -0
  351. package/docs/COMPLETE_AUDIT_REFACTORING.md +965 -0
  352. package/docs/DEVELOPMENT.md +545 -0
  353. package/docs/DEVELOPMENT_HISTORY.md +345 -0
  354. package/docs/LIMITATIONS.md +176 -0
  355. package/docs/MIGRATION.md +303 -0
  356. package/docs/OPTION_3_4_EXPLORATION.md +1257 -0
  357. package/docs/PHASE1_PERFORMANCE.md +144 -0
  358. package/docs/QA360_Cloud.postman_collection.json +89 -0
  359. package/docs/QA360_TESTING_PHILOSOPHY.md +769 -0
  360. package/docs/QA_TEST_PLAN.md +727 -0
  361. package/docs/README.md +50 -0
  362. package/docs/STATUS.md +198 -0
  363. package/docs/STRATEGIC_STUDY_GOOSE_INTEGRATION.md +615 -0
  364. package/docs/USER_GUIDE.md +687 -0
  365. package/docs/WORK-DONE-ADAPTER-TESTS.md +136 -0
  366. package/docs/adapters-security.md +485 -0
  367. package/docs/architecture-diagram.mmd +168 -0
  368. package/docs/archive/ARCH-01-DAY6-BUILD-FIXES.md +396 -0
  369. package/docs/archive/ARCH-01-DAY6-FINAL-STATUS.md +324 -0
  370. package/docs/archive/ARCH-01_MCP_MERGE_ANALYSIS.md +644 -0
  371. package/docs/archive/ARCH-01_NEXT_STEPS.md +60 -0
  372. package/docs/archive/BRANCH_PROTECTION.md +183 -0
  373. package/docs/archive/CI_LOCKDOWN_CHECKLIST.md +222 -0
  374. package/docs/archive/HANDOFF_TEST-01.md +669 -0
  375. package/docs/archive/LEGAL_READY_PLACEHOLDERS.md +372 -0
  376. package/docs/archive/NODE_UPGRADE_GUIDE.md +188 -0
  377. package/docs/archive/PHASE1_COMPLETION.md +386 -0
  378. package/docs/archive/PHASE2_COMPLETION.md +404 -0
  379. package/docs/archive/PHASE3_AND_4_FINAL.md +360 -0
  380. package/docs/archive/PHASE3_COMPLETE.md +301 -0
  381. package/docs/archive/PHASE3_STATUS.md +255 -0
  382. package/docs/archive/PRE-WEEK2-AUDIT.md +364 -0
  383. package/docs/archive/README.md +16 -0
  384. package/docs/archive/SCHEMA_AJV_2020_FIX.md +245 -0
  385. package/docs/archive/TEST-01_AUDIT_REPORT.md +240 -0
  386. package/docs/archive/TEST-01_COVERAGE_PLAN.md +423 -0
  387. package/docs/archive/obsolete-proposals/dom-element-discovery-mode.md +250 -0
  388. package/docs/archive/obsolete-proposals/qa360-comprehensive-test-plan.md +1249 -0
  389. package/docs/archive/obsolete-proposals/qa360-quick-start-guide.md +298 -0
  390. package/docs/archive/obsolete-proposals/technical-plan-dom-discovery.md +870 -0
  391. package/docs/budgets-advanced.md +308 -0
  392. package/docs/examples/history-export-gc.md +285 -0
  393. package/docs/examples/pack-v2-complete.yaml +158 -0
  394. package/docs/examples/pack-v2-quickstart.yaml +24 -0
  395. package/docs/examples/pack-v2-ui-login.yaml +81 -0
  396. package/docs/examples/qa360-report.json +50 -0
  397. package/docs/history.md +565 -0
  398. package/docs/hooks.md +304 -0
  399. package/docs/llm-providers.md +512 -0
  400. package/docs/mcp-server.md +651 -0
  401. package/docs/mcp-tools.md +1131 -0
  402. package/docs/pack-v1.md +383 -0
  403. package/docs/pack-v2.md +558 -0
  404. package/docs/page-objects.md +366 -0
  405. package/docs/proofs.md +670 -0
  406. package/docs/quickstart-5min.md +257 -0
  407. package/docs/readiness-ci.md +654 -0
  408. package/docs/rfc/README.md +20 -0
  409. package/docs/rfc/proof-bundle-v1.md +787 -0
  410. package/docs/secrets.md +392 -0
  411. package/docs/serve.md +494 -0
  412. package/docs/unit-test-adapters.md +168 -0
  413. package/docs/vault.md +491 -0
  414. package/e2e/qa360-e2e.test.ts +696 -0
  415. package/e2e/vitest.config.ts +18 -0
  416. package/examples/README.md +30 -140
  417. package/examples/ci/docker-compose-serve.yml +375 -0
  418. package/examples/ci/github-actions-serve.yml +345 -0
  419. package/examples/ci/gitlab-ci-serve.yml +407 -0
  420. package/examples/datasets/README.md +101 -0
  421. package/examples/datasets/b2bshop.ts +155 -0
  422. package/examples/datasets/index.ts +57 -0
  423. package/examples/datasets/reqres.ts +195 -0
  424. package/examples/fixtures-demo/fixtures/users.yml +39 -0
  425. package/examples/fixtures-demo/pack.yml +71 -0
  426. package/examples/future-api/README.md +16 -0
  427. package/examples/future-api/diag.js +7 -0
  428. package/examples/future-api/health.js +4 -0
  429. package/examples/future-api/packs.js +13 -0
  430. package/examples/future-api/runpack.js +10 -0
  431. package/examples/generation/README.md +148 -0
  432. package/examples/generation/pack-generator-example.js +115 -0
  433. package/examples/generation/source-analyzer-example.js +115 -0
  434. package/examples/httpbin/pack.yml +59 -0
  435. package/examples/load-testing/mcp-load.yml +115 -0
  436. package/examples/load-testing/mcp-stdio.yml +95 -0
  437. package/examples/mcp/claude-desktop-config.json +33 -0
  438. package/examples/mcp/claude-desktop.json +16 -0
  439. package/examples/mcp/conversation-sample.md +131 -0
  440. package/examples/mcp/demo-60s.md +330 -0
  441. package/examples/mcp/sample-conversation.jsonl +21 -0
  442. package/examples/mcp/vscode-settings.json +22 -0
  443. package/examples/pack-v2-complete.yml +242 -0
  444. package/examples/pack-v2-examples.md +244 -0
  445. package/examples/pack-v2-quickstart.yml +55 -0
  446. package/examples/packs-business/ecommerce-api.yml +121 -0
  447. package/examples/packs-business/saas-dashboard-ui.yml +133 -0
  448. package/examples/packs-conformance/compose-multi.yml +174 -0
  449. package/examples/packs-conformance/full.yml +152 -0
  450. package/examples/packs-conformance/heavy-artifacts.yml +152 -0
  451. package/examples/packs-conformance/minimal.yml +71 -0
  452. package/examples/packs-conformance/secrets-missing.yml +97 -0
  453. package/examples/packs-conformance/timeouts.yml +77 -0
  454. package/examples/pom-demo/README.md +104 -0
  455. package/examples/pom-demo/pack.yml +60 -0
  456. package/examples/pom-demo/pages/DashboardPage.page.ts +73 -0
  457. package/examples/pom-demo/pages/LoginPage.page.ts +76 -0
  458. package/examples/proofs/e2e-playwright-proof.json +75 -0
  459. package/examples/proofs/httpbin-proof.json +69 -0
  460. package/examples/proofs/multi-adapter-proof.json +117 -0
  461. package/examples/proofs/test-proof.json +26 -0
  462. package/examples/restful-api-dev/README.md +102 -0
  463. package/examples/restful-api-dev/restful-api-advanced.yml +29 -0
  464. package/examples/restful-api-dev/restful-api-basic.yml +29 -0
  465. package/examples/web-lite/.github/workflows/qa360-phase3.yml +73 -0
  466. package/examples/web-lite/api-mock/server.js +258 -0
  467. package/examples/web-lite/pack.yml +71 -0
  468. package/examples/web-lite/services.yml +43 -0
  469. package/examples/web-lite/web-content/healthz +1 -0
  470. package/examples/web-lite/web-content/index.html +259 -0
  471. package/package.json +56 -45
  472. package/packages/mcp/CHANGELOG.md +109 -0
  473. package/packages/mcp/IMPLEMENTATION_SUMMARY.md +350 -0
  474. package/packages/mcp/LICENSE +21 -0
  475. package/packages/mcp/QUICK_START.md +291 -0
  476. package/packages/mcp/README.md +294 -0
  477. package/packages/mcp/TELEMETRY.md +220 -0
  478. package/packages/mcp/package.json +91 -0
  479. package/packages/mcp/scripts/generate-sbom-fallback.cjs +84 -0
  480. package/packages/mcp/scripts/safe-postinstall.cjs +32 -0
  481. package/packages/mcp/src/__tests__/contract.test.ts +902 -0
  482. package/packages/mcp/src/cli/cli.ts +137 -0
  483. package/packages/mcp/src/cli/doctor.ts +286 -0
  484. package/packages/mcp/src/cli/fix.ts +99 -0
  485. package/packages/mcp/src/cli/init.ts +233 -0
  486. package/packages/mcp/src/cli/postinstall.ts +14 -0
  487. package/packages/mcp/src/cli/reset.ts +44 -0
  488. package/packages/mcp/src/cli/telemetry.ts +166 -0
  489. package/packages/mcp/src/cli/test-dx.ts +94 -0
  490. package/packages/mcp/src/cli/uninstall.ts +80 -0
  491. package/packages/mcp/src/cli/up.ts +178 -0
  492. package/packages/mcp/src/index.ts +12 -0
  493. package/packages/mcp/src/scripts/e2e-local.ts +337 -0
  494. package/packages/mcp/src/scripts/verify-settings.ts +242 -0
  495. package/packages/mcp/src/security/audit.ts +244 -0
  496. package/packages/mcp/src/security/manager.ts +242 -0
  497. package/packages/mcp/src/server/full-server.ts +212 -0
  498. package/packages/mcp/src/server/minimal-server.ts +134 -0
  499. package/packages/mcp/src/tools/history.ts +388 -0
  500. package/packages/mcp/src/tools/pack.ts +449 -0
  501. package/packages/mcp/src/tools/registry.ts +638 -0
  502. package/packages/mcp/src/tools/report.ts +100 -0
  503. package/packages/mcp/src/tools/run.ts +268 -0
  504. package/packages/mcp/src/tools/secrets.ts +198 -0
  505. package/packages/mcp/src/tools/serve.ts +221 -0
  506. package/packages/mcp/src/tools/triage.ts +532 -0
  507. package/packages/mcp/src/tools/types.ts +26 -0
  508. package/packages/mcp/src/tools/vault.ts +164 -0
  509. package/packages/mcp/src/tools/verify.ts +166 -0
  510. package/packages/mcp/src/types/index.ts +311 -0
  511. package/packages/mcp/src/types/mcp-stubs.ts +83 -0
  512. package/packages/mcp/tsconfig.json +16 -0
  513. package/playwright.config.ts +20 -0
  514. package/pnpm-workspace.yaml +4 -0
  515. package/run-test-and-push.sh +20 -0
  516. package/scripts/build-proof-cli.sh +110 -0
  517. package/scripts/ci/check-windows-paths.js +92 -0
  518. package/scripts/ci/invariants.sh +124 -0
  519. package/scripts/ci/make-final-bundle.js +106 -0
  520. package/scripts/ci/mcp-run-multipack.js +305 -0
  521. package/scripts/ci/run-pack-suite.sh +103 -0
  522. package/scripts/ci/run-phase7-final.sh +190 -0
  523. package/scripts/ci/slo-assert.js +158 -0
  524. package/scripts/ci/test-fault-tolerance.sh +301 -0
  525. package/scripts/install-mcp.sh +66 -0
  526. package/scripts/mcp-smoke.mjs +27 -0
  527. package/scripts/smoke.sh +26 -0
  528. package/scripts/stress-test.js +288 -0
  529. package/scripts/sync-version.mjs +50 -0
  530. package/scripts/validate-examples.mjs +404 -0
  531. package/scripts/validation/simple-pack-check.sh +51 -0
  532. package/scripts/validation/validate-universal-pack.mjs +77 -0
  533. package/scripts/verify-persistence.js +127 -0
  534. package/test-pack.yaml +43 -0
  535. package/test-results/.last-run.json +4 -0
  536. package/test-runner.mjs +87 -0
  537. package/tests/artifacts.spec.js +147 -0
  538. package/tests/contracts.spec.js +239 -0
  539. package/tests/e2e/assertions.test.mjs +370 -0
  540. package/tests/e2e/crawler.test.mjs +451 -0
  541. package/tests/e2e/playwright-plus-plus.test.mjs +604 -0
  542. package/tests/e2e/proof-bundle.test.mjs +258 -0
  543. package/tests/e2e/real-world/saucedemo.test.mjs +714 -0
  544. package/tests/e2e/real-world/the-internet-herokuapp.test.mjs +760 -0
  545. package/tests/e2e/ui-actions.test.mjs +546 -0
  546. package/tests/gherkin.e2e.spec.ts +310 -0
  547. package/tests/no-console-errors.spec.js +136 -0
  548. package/tests/pdf.spec.ts +252 -0
  549. package/tests/run-pack.spec.ts +58 -0
  550. package/tsconfig.base.json +15 -0
  551. package/tsconfig.build.json +8 -0
  552. package/tsconfig.json +37 -0
  553. package/tsconfig.test.json +18 -0
  554. package/typedoc.json +37 -0
  555. package/ui/README.md +50 -0
  556. package/verify-proof.mjs +60 -0
  557. package/dist/cli-minimal.d.ts +0 -6
  558. package/dist/cli-minimal.js +0 -36
  559. package/dist/commands/ai.d.ts +0 -43
  560. package/dist/commands/ai.js +0 -616
  561. package/dist/commands/ask.d.ts +0 -94
  562. package/dist/commands/ask.js +0 -582
  563. package/dist/commands/coverage.d.ts +0 -8
  564. package/dist/commands/coverage.js +0 -252
  565. package/dist/commands/crawl.d.ts +0 -24
  566. package/dist/commands/crawl.js +0 -121
  567. package/dist/commands/doctor.d.ts +0 -54
  568. package/dist/commands/doctor.js +0 -513
  569. package/dist/commands/examples.d.ts +0 -33
  570. package/dist/commands/examples.js +0 -193
  571. package/dist/commands/explain.d.ts +0 -27
  572. package/dist/commands/explain.js +0 -630
  573. package/dist/commands/flakiness.d.ts +0 -73
  574. package/dist/commands/flakiness.js +0 -435
  575. package/dist/commands/generate.d.ts +0 -66
  576. package/dist/commands/generate.js +0 -438
  577. package/dist/commands/history.d.ts +0 -76
  578. package/dist/commands/history.js +0 -755
  579. package/dist/commands/init.d.ts +0 -106
  580. package/dist/commands/init.js +0 -616
  581. package/dist/commands/monitor.d.ts +0 -27
  582. package/dist/commands/monitor.js +0 -225
  583. package/dist/commands/ollama.d.ts +0 -40
  584. package/dist/commands/ollama.js +0 -301
  585. package/dist/commands/pack.d.ts +0 -70
  586. package/dist/commands/pack.js +0 -413
  587. package/dist/commands/regression.d.ts +0 -8
  588. package/dist/commands/regression.js +0 -340
  589. package/dist/commands/repair.d.ts +0 -26
  590. package/dist/commands/repair.js +0 -307
  591. package/dist/commands/report.d.ts +0 -62
  592. package/dist/commands/report.js +0 -378
  593. package/dist/commands/retry.d.ts +0 -43
  594. package/dist/commands/retry.js +0 -275
  595. package/dist/commands/run.d.ts +0 -41
  596. package/dist/commands/run.js +0 -169
  597. package/dist/commands/scan.d.ts +0 -5
  598. package/dist/commands/scan.js +0 -155
  599. package/dist/commands/secrets.d.ts +0 -58
  600. package/dist/commands/secrets.js +0 -289
  601. package/dist/commands/serve.d.ts +0 -13
  602. package/dist/commands/serve.js +0 -156
  603. package/dist/commands/slo.d.ts +0 -8
  604. package/dist/commands/slo.js +0 -327
  605. package/dist/commands/verify.d.ts +0 -32
  606. package/dist/commands/verify.js +0 -278
  607. package/dist/core/adapters/gitleaks-secrets.d.ts +0 -114
  608. package/dist/core/adapters/gitleaks-secrets.js +0 -410
  609. package/dist/core/adapters/k6-perf.d.ts +0 -85
  610. package/dist/core/adapters/k6-perf.js +0 -398
  611. package/dist/core/adapters/osv-deps.d.ts +0 -123
  612. package/dist/core/adapters/osv-deps.js +0 -372
  613. package/dist/core/adapters/playwright-native-adapter.d.ts +0 -121
  614. package/dist/core/adapters/playwright-native-adapter.js +0 -339
  615. package/dist/core/adapters/playwright-native-api.d.ts +0 -183
  616. package/dist/core/adapters/playwright-native-api.js +0 -465
  617. package/dist/core/adapters/playwright-ui.d.ts +0 -197
  618. package/dist/core/adapters/playwright-ui.js +0 -840
  619. package/dist/core/adapters/semgrep-sast.d.ts +0 -99
  620. package/dist/core/adapters/semgrep-sast.js +0 -322
  621. package/dist/core/adapters/zap-dast.d.ts +0 -133
  622. package/dist/core/adapters/zap-dast.js +0 -424
  623. package/dist/core/ai/anthropic-provider.d.ts +0 -50
  624. package/dist/core/ai/anthropic-provider.js +0 -223
  625. package/dist/core/ai/deepseek-provider.d.ts +0 -81
  626. package/dist/core/ai/deepseek-provider.js +0 -266
  627. package/dist/core/ai/index.d.ts +0 -60
  628. package/dist/core/ai/index.js +0 -18
  629. package/dist/core/ai/llm-client.d.ts +0 -45
  630. package/dist/core/ai/llm-client.js +0 -7
  631. package/dist/core/ai/mock-provider.d.ts +0 -49
  632. package/dist/core/ai/mock-provider.js +0 -121
  633. package/dist/core/ai/ollama-provider.d.ts +0 -78
  634. package/dist/core/ai/ollama-provider.js +0 -204
  635. package/dist/core/ai/openai-provider.d.ts +0 -48
  636. package/dist/core/ai/openai-provider.js +0 -200
  637. package/dist/core/ai/provider-factory.d.ts +0 -160
  638. package/dist/core/ai/provider-factory.js +0 -269
  639. package/dist/core/artifacts/index.d.ts +0 -6
  640. package/dist/core/artifacts/index.js +0 -6
  641. package/dist/core/artifacts/ui-artifacts.d.ts +0 -133
  642. package/dist/core/artifacts/ui-artifacts.js +0 -304
  643. package/dist/core/assertions/engine.d.ts +0 -51
  644. package/dist/core/assertions/engine.js +0 -530
  645. package/dist/core/assertions/index.d.ts +0 -11
  646. package/dist/core/assertions/index.js +0 -11
  647. package/dist/core/assertions/types.d.ts +0 -121
  648. package/dist/core/assertions/types.js +0 -37
  649. package/dist/core/auth/api-key-provider.d.ts +0 -16
  650. package/dist/core/auth/api-key-provider.js +0 -63
  651. package/dist/core/auth/aws-iam-provider.d.ts +0 -35
  652. package/dist/core/auth/aws-iam-provider.js +0 -177
  653. package/dist/core/auth/azure-ad-provider.d.ts +0 -15
  654. package/dist/core/auth/azure-ad-provider.js +0 -99
  655. package/dist/core/auth/basic-auth-provider.d.ts +0 -26
  656. package/dist/core/auth/basic-auth-provider.js +0 -111
  657. package/dist/core/auth/gcp-adc-provider.d.ts +0 -27
  658. package/dist/core/auth/gcp-adc-provider.js +0 -126
  659. package/dist/core/auth/index.d.ts +0 -238
  660. package/dist/core/auth/index.js +0 -82
  661. package/dist/core/auth/jwt-provider.d.ts +0 -19
  662. package/dist/core/auth/jwt-provider.js +0 -160
  663. package/dist/core/auth/manager.d.ts +0 -84
  664. package/dist/core/auth/manager.js +0 -230
  665. package/dist/core/auth/oauth2-provider.d.ts +0 -17
  666. package/dist/core/auth/oauth2-provider.js +0 -114
  667. package/dist/core/auth/totp-provider.d.ts +0 -31
  668. package/dist/core/auth/totp-provider.js +0 -134
  669. package/dist/core/auth/ui-login-provider.d.ts +0 -26
  670. package/dist/core/auth/ui-login-provider.js +0 -198
  671. package/dist/core/cache/index.d.ts +0 -7
  672. package/dist/core/cache/index.js +0 -6
  673. package/dist/core/cache/lru-cache.d.ts +0 -203
  674. package/dist/core/cache/lru-cache.js +0 -397
  675. package/dist/core/core/coverage/analyzer.d.ts +0 -101
  676. package/dist/core/core/coverage/analyzer.js +0 -415
  677. package/dist/core/core/coverage/collector.d.ts +0 -74
  678. package/dist/core/core/coverage/collector.js +0 -459
  679. package/dist/core/core/coverage/config.d.ts +0 -37
  680. package/dist/core/core/coverage/config.js +0 -156
  681. package/dist/core/core/coverage/index.d.ts +0 -11
  682. package/dist/core/core/coverage/index.js +0 -15
  683. package/dist/core/core/coverage/types.d.ts +0 -267
  684. package/dist/core/core/coverage/types.js +0 -6
  685. package/dist/core/core/coverage/vault.d.ts +0 -95
  686. package/dist/core/core/coverage/vault.js +0 -405
  687. package/dist/core/coverage/analyzer.d.ts +0 -101
  688. package/dist/core/coverage/analyzer.js +0 -415
  689. package/dist/core/coverage/collector.d.ts +0 -74
  690. package/dist/core/coverage/collector.js +0 -459
  691. package/dist/core/coverage/config.d.ts +0 -37
  692. package/dist/core/coverage/config.js +0 -156
  693. package/dist/core/coverage/index.d.ts +0 -11
  694. package/dist/core/coverage/index.js +0 -15
  695. package/dist/core/coverage/types.d.ts +0 -267
  696. package/dist/core/coverage/types.js +0 -6
  697. package/dist/core/coverage/vault.d.ts +0 -95
  698. package/dist/core/coverage/vault.js +0 -405
  699. package/dist/core/crawler/index.d.ts +0 -57
  700. package/dist/core/crawler/index.js +0 -281
  701. package/dist/core/crawler/journey-generator.d.ts +0 -49
  702. package/dist/core/crawler/journey-generator.js +0 -412
  703. package/dist/core/crawler/page-analyzer.d.ts +0 -88
  704. package/dist/core/crawler/page-analyzer.js +0 -709
  705. package/dist/core/crawler/selector-generator.d.ts +0 -34
  706. package/dist/core/crawler/selector-generator.js +0 -240
  707. package/dist/core/crawler/types.d.ts +0 -353
  708. package/dist/core/crawler/types.js +0 -6
  709. package/dist/core/dashboard/assets.d.ts +0 -6
  710. package/dist/core/dashboard/assets.js +0 -690
  711. package/dist/core/dashboard/index.d.ts +0 -6
  712. package/dist/core/dashboard/index.js +0 -5
  713. package/dist/core/dashboard/server.d.ts +0 -72
  714. package/dist/core/dashboard/server.js +0 -354
  715. package/dist/core/dashboard/types.d.ts +0 -70
  716. package/dist/core/dashboard/types.js +0 -5
  717. package/dist/core/discoverer/index.d.ts +0 -115
  718. package/dist/core/discoverer/index.js +0 -250
  719. package/dist/core/flakiness/index.d.ts +0 -228
  720. package/dist/core/flakiness/index.js +0 -384
  721. package/dist/core/generation/code-formatter.d.ts +0 -111
  722. package/dist/core/generation/code-formatter.js +0 -307
  723. package/dist/core/generation/code-generator.d.ts +0 -144
  724. package/dist/core/generation/code-generator.js +0 -293
  725. package/dist/core/generation/crawler-pack-generator.d.ts +0 -44
  726. package/dist/core/generation/crawler-pack-generator.js +0 -231
  727. package/dist/core/generation/generator.d.ts +0 -40
  728. package/dist/core/generation/generator.js +0 -76
  729. package/dist/core/generation/index.d.ts +0 -32
  730. package/dist/core/generation/index.js +0 -30
  731. package/dist/core/generation/pack-generator.d.ts +0 -107
  732. package/dist/core/generation/pack-generator.js +0 -416
  733. package/dist/core/generation/prompt-builder.d.ts +0 -132
  734. package/dist/core/generation/prompt-builder.js +0 -672
  735. package/dist/core/generation/source-analyzer.d.ts +0 -213
  736. package/dist/core/generation/source-analyzer.js +0 -657
  737. package/dist/core/generation/test-optimizer.d.ts +0 -117
  738. package/dist/core/generation/test-optimizer.js +0 -328
  739. package/dist/core/generation/types.d.ts +0 -214
  740. package/dist/core/generation/types.js +0 -4
  741. package/dist/core/hooks/compose.d.ts +0 -61
  742. package/dist/core/hooks/compose.js +0 -225
  743. package/dist/core/hooks/runner.d.ts +0 -68
  744. package/dist/core/hooks/runner.js +0 -303
  745. package/dist/core/index.d.ts +0 -104
  746. package/dist/core/index.js +0 -91
  747. package/dist/core/pack/migrator.d.ts +0 -51
  748. package/dist/core/pack/migrator.js +0 -304
  749. package/dist/core/pack/validator.d.ts +0 -42
  750. package/dist/core/pack/validator.js +0 -322
  751. package/dist/core/pack-v2/index.d.ts +0 -9
  752. package/dist/core/pack-v2/index.js +0 -8
  753. package/dist/core/pack-v2/loader.d.ts +0 -63
  754. package/dist/core/pack-v2/loader.js +0 -292
  755. package/dist/core/pack-v2/migrator.d.ts +0 -61
  756. package/dist/core/pack-v2/migrator.js +0 -480
  757. package/dist/core/pack-v2/validator.d.ts +0 -61
  758. package/dist/core/pack-v2/validator.js +0 -577
  759. package/dist/core/parallel/index.d.ts +0 -6
  760. package/dist/core/parallel/index.js +0 -6
  761. package/dist/core/parallel/parallel-runner.d.ts +0 -107
  762. package/dist/core/parallel/parallel-runner.js +0 -192
  763. package/dist/core/proof/bundle.d.ts +0 -137
  764. package/dist/core/proof/bundle.js +0 -160
  765. package/dist/core/proof/canonicalize.d.ts +0 -47
  766. package/dist/core/proof/canonicalize.js +0 -105
  767. package/dist/core/proof/index.d.ts +0 -13
  768. package/dist/core/proof/index.js +0 -18
  769. package/dist/core/proof/schema.d.ts +0 -217
  770. package/dist/core/proof/schema.js +0 -263
  771. package/dist/core/proof/signer.d.ts +0 -111
  772. package/dist/core/proof/signer.js +0 -226
  773. package/dist/core/proof/verifier.d.ts +0 -97
  774. package/dist/core/proof/verifier.js +0 -308
  775. package/dist/core/regression/detector.d.ts +0 -107
  776. package/dist/core/regression/detector.js +0 -497
  777. package/dist/core/regression/index.d.ts +0 -9
  778. package/dist/core/regression/index.js +0 -11
  779. package/dist/core/regression/trend-analyzer.d.ts +0 -102
  780. package/dist/core/regression/trend-analyzer.js +0 -345
  781. package/dist/core/regression/types.d.ts +0 -222
  782. package/dist/core/regression/types.js +0 -7
  783. package/dist/core/regression/vault.d.ts +0 -87
  784. package/dist/core/regression/vault.js +0 -289
  785. package/dist/core/repair/engine/fixer.d.ts +0 -24
  786. package/dist/core/repair/engine/fixer.js +0 -226
  787. package/dist/core/repair/engine/suggestion-engine.d.ts +0 -18
  788. package/dist/core/repair/engine/suggestion-engine.js +0 -187
  789. package/dist/core/repair/index.d.ts +0 -10
  790. package/dist/core/repair/index.js +0 -13
  791. package/dist/core/repair/repairer.d.ts +0 -90
  792. package/dist/core/repair/repairer.js +0 -284
  793. package/dist/core/repair/types.d.ts +0 -91
  794. package/dist/core/repair/types.js +0 -6
  795. package/dist/core/repair/utils/error-analyzer.d.ts +0 -28
  796. package/dist/core/repair/utils/error-analyzer.js +0 -264
  797. package/dist/core/reporting/html-reporter.d.ts +0 -119
  798. package/dist/core/reporting/html-reporter.js +0 -737
  799. package/dist/core/reporting/index.d.ts +0 -6
  800. package/dist/core/reporting/index.js +0 -6
  801. package/dist/core/retry/flakiness-integration.d.ts +0 -60
  802. package/dist/core/retry/flakiness-integration.js +0 -228
  803. package/dist/core/retry/index.d.ts +0 -14
  804. package/dist/core/retry/index.js +0 -16
  805. package/dist/core/retry/retry-engine.d.ts +0 -80
  806. package/dist/core/retry/retry-engine.js +0 -296
  807. package/dist/core/retry/types.d.ts +0 -178
  808. package/dist/core/retry/types.js +0 -52
  809. package/dist/core/retry/vault.d.ts +0 -77
  810. package/dist/core/retry/vault.js +0 -304
  811. package/dist/core/runner/e2e-helpers.d.ts +0 -102
  812. package/dist/core/runner/e2e-helpers.js +0 -153
  813. package/dist/core/runner/phase3-runner.d.ts +0 -200
  814. package/dist/core/runner/phase3-runner.js +0 -1041
  815. package/dist/core/secrets/crypto.d.ts +0 -75
  816. package/dist/core/secrets/crypto.js +0 -223
  817. package/dist/core/secrets/manager.d.ts +0 -76
  818. package/dist/core/secrets/manager.js +0 -219
  819. package/dist/core/security/redaction-patterns-extended.d.ts +0 -27
  820. package/dist/core/security/redaction-patterns-extended.js +0 -247
  821. package/dist/core/security/redactor.d.ts +0 -71
  822. package/dist/core/security/redactor.js +0 -279
  823. package/dist/core/self-healing/assertion-healer.d.ts +0 -97
  824. package/dist/core/self-healing/assertion-healer.js +0 -371
  825. package/dist/core/self-healing/engine.d.ts +0 -122
  826. package/dist/core/self-healing/engine.js +0 -538
  827. package/dist/core/self-healing/index.d.ts +0 -10
  828. package/dist/core/self-healing/index.js +0 -11
  829. package/dist/core/self-healing/selector-healer.d.ts +0 -103
  830. package/dist/core/self-healing/selector-healer.js +0 -372
  831. package/dist/core/self-healing/types.d.ts +0 -152
  832. package/dist/core/self-healing/types.js +0 -6
  833. package/dist/core/serve/diagnostics-collector.d.ts +0 -32
  834. package/dist/core/serve/diagnostics-collector.js +0 -149
  835. package/dist/core/serve/health-checker.d.ts +0 -44
  836. package/dist/core/serve/health-checker.js +0 -219
  837. package/dist/core/serve/index.d.ts +0 -8
  838. package/dist/core/serve/index.js +0 -8
  839. package/dist/core/serve/metrics-collector.d.ts +0 -24
  840. package/dist/core/serve/metrics-collector.js +0 -322
  841. package/dist/core/serve/process-manager.d.ts +0 -36
  842. package/dist/core/serve/process-manager.js +0 -213
  843. package/dist/core/serve/server.d.ts +0 -36
  844. package/dist/core/serve/server.js +0 -191
  845. package/dist/core/slo/config.d.ts +0 -107
  846. package/dist/core/slo/config.js +0 -360
  847. package/dist/core/slo/index.d.ts +0 -11
  848. package/dist/core/slo/index.js +0 -15
  849. package/dist/core/slo/sli-calculator.d.ts +0 -92
  850. package/dist/core/slo/sli-calculator.js +0 -364
  851. package/dist/core/slo/slo-tracker.d.ts +0 -148
  852. package/dist/core/slo/slo-tracker.js +0 -379
  853. package/dist/core/slo/types.d.ts +0 -281
  854. package/dist/core/slo/types.js +0 -7
  855. package/dist/core/slo/vault.d.ts +0 -102
  856. package/dist/core/slo/vault.js +0 -427
  857. package/dist/core/tui/index.d.ts +0 -7
  858. package/dist/core/tui/index.js +0 -6
  859. package/dist/core/tui/monitor.d.ts +0 -92
  860. package/dist/core/tui/monitor.js +0 -271
  861. package/dist/core/tui/renderer.d.ts +0 -33
  862. package/dist/core/tui/renderer.js +0 -218
  863. package/dist/core/tui/types.d.ts +0 -63
  864. package/dist/core/tui/types.js +0 -5
  865. package/dist/core/types/pack-v1.d.ts +0 -251
  866. package/dist/core/types/pack-v1.js +0 -5
  867. package/dist/core/types/pack-v2.d.ts +0 -425
  868. package/dist/core/types/pack-v2.js +0 -8
  869. package/dist/core/types/trust-score.d.ts +0 -69
  870. package/dist/core/types/trust-score.js +0 -191
  871. package/dist/core/vault/cas.d.ts +0 -90
  872. package/dist/core/vault/cas.js +0 -261
  873. package/dist/core/vault/index.d.ts +0 -326
  874. package/dist/core/vault/index.js +0 -1042
  875. package/dist/core/visual/index.d.ts +0 -6
  876. package/dist/core/visual/index.js +0 -6
  877. package/dist/core/visual/visual-regression.d.ts +0 -113
  878. package/dist/core/visual/visual-regression.js +0 -236
  879. package/dist/core/watch/index.d.ts +0 -7
  880. package/dist/core/watch/index.js +0 -6
  881. package/dist/core/watch/watch-mode.d.ts +0 -213
  882. package/dist/core/watch/watch-mode.js +0 -389
  883. package/dist/generators/index.d.ts +0 -5
  884. package/dist/generators/index.js +0 -5
  885. package/dist/generators/json-reporter.d.ts +0 -10
  886. package/dist/generators/json-reporter.js +0 -12
  887. package/dist/generators/test-generator.d.ts +0 -18
  888. package/dist/generators/test-generator.js +0 -78
  889. package/dist/index.d.ts +0 -8
  890. package/dist/index.js +0 -246
  891. package/dist/scanners/dom-scanner.d.ts +0 -52
  892. package/dist/scanners/dom-scanner.js +0 -296
  893. package/dist/scanners/index.d.ts +0 -4
  894. package/dist/scanners/index.js +0 -4
  895. package/dist/schemas/pack.schema.json +0 -236
  896. package/dist/types/scan.d.ts +0 -68
  897. package/dist/types/scan.js +0 -4
  898. package/dist/utils/config.d.ts +0 -5
  899. package/dist/utils/config.js +0 -136
  900. /package/{bin → cli/bin}/qa360.js +0 -0
  901. /package/{examples → cli/examples}/accessibility.yml +0 -0
  902. /package/{examples → cli/examples}/api-basic.yml +0 -0
  903. /package/{examples → cli/examples}/complete.yml +0 -0
  904. /package/{examples → cli/examples}/crawler.yml +0 -0
  905. /package/{examples → cli/examples}/fullstack.yml +0 -0
  906. /package/{examples → cli/examples}/security.yml +0 -0
  907. /package/{examples → cli/examples}/ui-advanced.yml +0 -0
  908. /package/{examples → cli/examples}/ui-basic.yml +0 -0
  909. /package/{dist/core → core}/schemas/pack.schema.json +0 -0
@@ -1,1041 +0,0 @@
1
- /**
2
- * QA360 Phase 3 Runner
3
- * Orchestrates hooks, adapters, and proof generation
4
- * Supports both Pack v1 and Pack v2 configurations
5
- */
6
- import { existsSync, writeFileSync, mkdirSync } from 'fs';
7
- import { join } from 'path';
8
- import { createHash } from 'crypto';
9
- import chalk from 'chalk';
10
- import { HooksRunner } from '../hooks/runner.js';
11
- import { PlaywrightNativeApiAdapter } from '../adapters/playwright-native-api.js';
12
- import { PlaywrightUiAdapter } from '../adapters/playwright-ui.js';
13
- import { K6PerfAdapter } from '../adapters/k6-perf.js';
14
- import { SemgrepSastAdapter } from '../adapters/semgrep-sast.js';
15
- import { SecurityRedactor } from '../security/redactor.js';
16
- import { initializeKeys, sign } from '../proof/signer.js';
17
- import { canonicalize } from '../proof/canonicalize.js';
18
- import { EvidenceVault } from '../vault/index.js';
19
- import { AuthManager } from '../auth/index.js';
20
- import { FlakinessDetector, FlakinessCategory, formatFlakinessScore, generateTestId, DEFAULT_FLAKINESS_OPTIONS } from '../flakiness/index.js';
21
- export class Phase3Runner {
22
- workingDir;
23
- pack;
24
- outputDir;
25
- redactor;
26
- hooksRunner;
27
- keyPair;
28
- vault;
29
- authManager;
30
- authCredentialsCache = new Map();
31
- flakyDetect;
32
- flakyRuns;
33
- flakinessDetector;
34
- constructor(options) {
35
- this.workingDir = options.workingDir;
36
- this.pack = options.pack;
37
- this.outputDir = options.outputDir || join(this.workingDir, '.qa360', 'runs');
38
- this.redactor = SecurityRedactor.forLogs();
39
- this.authManager = new AuthManager();
40
- this.flakyDetect = options.flakyDetect || false;
41
- this.flakyRuns = options.flakyRuns || DEFAULT_FLAKINESS_OPTIONS.consecutiveRuns;
42
- this.flakinessDetector = new FlakinessDetector({
43
- consecutiveRuns: this.flakyRuns,
44
- minRuns: 2,
45
- enablePatternDetection: true
46
- });
47
- // Initialize hooks runner (convert v2 hooks to v1 format if needed)
48
- const hooks = this.isPackV2(options.pack)
49
- ? this.convertV2HooksToV1(options.pack.hooks)
50
- : options.pack.hooks;
51
- this.hooksRunner = new HooksRunner({
52
- workingDir: this.workingDir,
53
- hooks: hooks || {},
54
- execution: this.isPackV2(options.pack) ? this.convertV2ExecutionToV1(options.pack.execution) : options.pack.execution,
55
- redactor: this.redactor
56
- });
57
- // Register auth profiles from pack v2
58
- if (this.isPackV2(options.pack) && options.pack.auth?.profiles) {
59
- this.registerAuthProfiles(options.pack.auth.profiles);
60
- }
61
- }
62
- /**
63
- * Type guard to check if pack is v2
64
- */
65
- isPackV2(pack) {
66
- return pack.version === 2;
67
- }
68
- /**
69
- * Register authentication profiles from pack config
70
- */
71
- registerAuthProfiles(profiles) {
72
- for (const [name, profile] of Object.entries(profiles)) {
73
- // Convert v2 auth profile to auth module format
74
- const authConfig = {
75
- type: profile.type || 'none',
76
- ...profile.config
77
- };
78
- this.authManager.registerProfile(name, authConfig);
79
- }
80
- }
81
- /**
82
- * Get auth profile name for a specific gate
83
- */
84
- getAuthProfileForGate(gateName) {
85
- if (!this.isPackV2(this.pack) || !this.pack.auth) {
86
- return undefined;
87
- }
88
- const authConfig = this.pack.auth;
89
- // Check if gate has specific auth override
90
- const gateConfig = this.pack.gates[gateName];
91
- if (gateConfig?.auth) {
92
- return gateConfig.auth;
93
- }
94
- // Use default based on gate type
95
- if (gateName === 'api_smoke' || gateName === 'api') {
96
- return authConfig.api;
97
- }
98
- if (gateName === 'ui' || gateName === 'a11y') {
99
- return authConfig.ui;
100
- }
101
- return undefined;
102
- }
103
- /**
104
- * Authenticate and get credentials for a gate
105
- */
106
- async getCredentialsForGate(gateName) {
107
- const profileName = this.getAuthProfileForGate(gateName);
108
- if (!profileName) {
109
- return undefined;
110
- }
111
- // Check cache first
112
- if (this.authCredentialsCache.has(profileName)) {
113
- return this.authCredentialsCache.get(profileName);
114
- }
115
- // Authenticate
116
- const result = await this.authManager.authenticate(profileName);
117
- if (result.success && result.credentials) {
118
- this.authCredentialsCache.set(profileName, result.credentials);
119
- return result.credentials;
120
- }
121
- console.log(chalk.yellow(` ⚠️ Auth failed for profile '${profileName}': ${result.error}`));
122
- return undefined;
123
- }
124
- /**
125
- * Convert v2 hooks to v1 format
126
- */
127
- convertV2HooksToV1(hooks) {
128
- if (!hooks)
129
- return undefined;
130
- // v2 hooks use { type, command, ... } format
131
- // v1 hooks use { run, timeout } format
132
- const converted = {
133
- beforeAll: [],
134
- afterAll: [],
135
- beforeEach: [],
136
- afterEach: []
137
- };
138
- for (const [phase, phaseHooks] of Object.entries(hooks)) {
139
- if (Array.isArray(phaseHooks)) {
140
- converted[phase] = phaseHooks.map((h) => {
141
- if (h.type === 'run' || h.type === 'script') {
142
- return { run: h.command, timeout: h.timeout, cwd: h.cwd, env: h.env };
143
- }
144
- if (h.type === 'wait_on') {
145
- return { run: `npx wait-on ${h.wait_for?.resource || h.command}`, timeout: h.timeout };
146
- }
147
- if (h.type === 'docker') {
148
- return { run: `docker compose ${h.compose?.command || 'up -d'}`, timeout: h.timeout };
149
- }
150
- return h;
151
- });
152
- }
153
- }
154
- return converted;
155
- }
156
- /**
157
- * Convert v2 execution config to v1 format
158
- */
159
- convertV2ExecutionToV1(execution) {
160
- if (!execution)
161
- return undefined;
162
- return {
163
- timeout: execution.default_timeout || execution.timeout,
164
- max_retries: execution.default_retries || execution.retries,
165
- on_failure: execution.on_failure || 'continue'
166
- };
167
- }
168
- /**
169
- * Get gates array from pack (handles v1 and v2)
170
- */
171
- getGatesArray() {
172
- if (this.isPackV2(this.pack)) {
173
- return Object.keys(this.pack.gates).filter(gateName => {
174
- const gateConfig = this.pack.gates[gateName];
175
- return gateConfig?.enabled !== false;
176
- });
177
- }
178
- return this.pack.gates || [];
179
- }
180
- /**
181
- * Execute complete Phase 3 workflow
182
- */
183
- async run() {
184
- const startTime = Date.now();
185
- const gatesArray = this.getGatesArray();
186
- console.log(chalk.bold.blue(`\n🚀 QA360 Phase 3 Runner - ${this.pack.name}`));
187
- console.log(chalk.gray(`Gates: ${gatesArray.join(', ')}`));
188
- try {
189
- // Ensure output directory exists
190
- this.ensureOutputDir();
191
- // Initialize cryptographic keys
192
- console.log(chalk.blue('\n🔑 Initializing Ed25519 keys...'));
193
- this.keyPair = await initializeKeys();
194
- console.log(chalk.green(' ✅ Keys ready'));
195
- // Initialize Evidence Vault
196
- console.log(chalk.blue('\n🗄️ Initializing Evidence Vault...'));
197
- const vaultDir = join(this.workingDir, '.qa360');
198
- this.vault = await EvidenceVault.open(vaultDir);
199
- console.log(chalk.green(' ✅ Vault ready'));
200
- // Execute beforeAll hooks
201
- console.log(chalk.blue('\n🔗 Phase 1: Setup Hooks'));
202
- const beforeAllResults = await this.hooksRunner.executeHooks('beforeAll');
203
- // Check if setup failed and should stop
204
- const setupFailed = beforeAllResults.some(r => !r.success);
205
- if (setupFailed && this.pack.execution?.on_failure === 'stop') {
206
- throw new Error('Setup hooks failed, stopping execution');
207
- }
208
- // Execute gates
209
- console.log(chalk.blue('\n🎯 Phase 2: Quality Gates'));
210
- const gateResults = [];
211
- for (const gate of gatesArray) {
212
- const gateResult = await this.executeGate(gate);
213
- gateResults.push(gateResult);
214
- // Check if gate failed and should stop
215
- if (!gateResult.success && this.pack.execution?.on_failure === 'stop') {
216
- console.log(chalk.yellow(`🛑 Gate ${gate} failed, stopping execution`));
217
- break;
218
- }
219
- }
220
- // Flakiness Detection Phase (Vision 2.0)
221
- let flakinessResults;
222
- if (this.flakyDetect) {
223
- console.log(chalk.blue(`\n🎲 Phase 2.5: Flakiness Detection (${this.flakyRuns} consecutive runs)`));
224
- flakinessResults = await this.detectFlakiness(gateResults);
225
- // Display flakiness summary
226
- const unstableCount = flakinessResults.filter(f => f.category === FlakinessCategory.UNSTABLE || f.category === FlakinessCategory.SHAKY).length;
227
- if (unstableCount > 0) {
228
- console.log(chalk.yellow(` ⚠️ ${unstableCount} test(s) show flaky behavior`));
229
- }
230
- else {
231
- console.log(chalk.green(' ✅ All tests stable - no flakiness detected'));
232
- }
233
- }
234
- // Execute afterAll hooks
235
- console.log(chalk.blue('\n🔗 Phase 3: Cleanup Hooks'));
236
- const afterAllResults = await this.hooksRunner.executeHooks('afterAll');
237
- // Calculate results
238
- const duration = Date.now() - startTime;
239
- const summary = this.calculateSummary(gateResults);
240
- const success = summary.failed === 0;
241
- // Generate proof
242
- console.log(chalk.blue('\n📋 Phase 4: Proof Generation'));
243
- const proofPath = await this.generateProof({
244
- success,
245
- pack: this.pack,
246
- duration,
247
- gates: gateResults,
248
- hooks: {
249
- beforeAll: beforeAllResults,
250
- beforeEach: [],
251
- afterEach: [],
252
- afterAll: afterAllResults
253
- },
254
- summary
255
- });
256
- // Save to Evidence Vault
257
- console.log(chalk.blue('\n💾 Phase 5: Evidence Storage'));
258
- const proofRunId = proofPath.split('/').pop()?.replace('-proof.json', '') || 'unknown';
259
- const vaultRunId = await this.saveToVault(proofRunId, {
260
- success,
261
- pack: this.pack,
262
- duration,
263
- gates: gateResults,
264
- hooks: {
265
- beforeAll: beforeAllResults,
266
- beforeEach: [],
267
- afterEach: [],
268
- afterAll: afterAllResults
269
- },
270
- summary,
271
- proofPath
272
- }, proofPath, flakinessResults, startTime);
273
- // Final summary
274
- console.log(chalk.blue('\n📊 Execution Summary'));
275
- console.log(` Duration: ${duration}ms`);
276
- console.log(` Gates: ${summary.passed}/${summary.total} passed`);
277
- console.log(` Trust Score: ${summary.trustScore}%`);
278
- console.log(` Proof: ${proofPath}`);
279
- // Display flakiness details if enabled
280
- if (flakinessResults && flakinessResults.length > 0) {
281
- console.log(chalk.blue('\n🎲 Flakiness Scores:'));
282
- for (const f of flakinessResults) {
283
- const scoreFormatted = formatFlakinessScore(f.score);
284
- const categoryMeta = {
285
- [FlakinessCategory.LEGENDARY]: { emoji: '🟢', color: chalk.green },
286
- [FlakinessCategory.SOLID]: { emoji: '🟢', color: chalk.green },
287
- [FlakinessCategory.GOOD]: { emoji: '🟡', color: chalk.yellow },
288
- [FlakinessCategory.SHAKY]: { emoji: '🟠', color: chalk.hex('#F97316') },
289
- [FlakinessCategory.UNSTABLE]: { emoji: '🔴', color: chalk.red }
290
- }[f.category];
291
- console.log(` ${categoryMeta.color(`${f.testName}: ${scoreFormatted}`)} (${f.successfulRuns}/${f.totalRuns} passes)`);
292
- if (f.suggestedFix) {
293
- console.log(chalk.gray(` 💡 ${f.suggestedFix}`));
294
- }
295
- }
296
- }
297
- if (success) {
298
- console.log(chalk.green('\n✅ All quality gates passed!'));
299
- }
300
- else {
301
- console.log(chalk.red(`\n❌ ${summary.failed} quality gate(s) failed`));
302
- }
303
- return {
304
- success,
305
- pack: this.pack,
306
- duration,
307
- gates: gateResults,
308
- hooks: {
309
- beforeAll: beforeAllResults,
310
- beforeEach: [],
311
- afterEach: [],
312
- afterAll: afterAllResults
313
- },
314
- summary,
315
- flakiness: flakinessResults,
316
- proofPath,
317
- runId: vaultRunId
318
- };
319
- }
320
- catch (error) {
321
- const duration = Date.now() - startTime;
322
- // Ensure cleanup even on error
323
- try {
324
- await this.hooksRunner.executeHooks('afterAll');
325
- }
326
- catch {
327
- // Ignore cleanup errors
328
- }
329
- return {
330
- success: false,
331
- pack: this.pack,
332
- duration,
333
- gates: [],
334
- hooks: { beforeAll: [], beforeEach: [], afterEach: [], afterAll: [] },
335
- summary: { total: 0, passed: 0, failed: 0, trustScore: 0 },
336
- error: this.redactor.redact(error instanceof Error ? error.message : 'Unknown error')
337
- };
338
- }
339
- }
340
- /**
341
- * Execute a single quality gate
342
- */
343
- async executeGate(gate) {
344
- const startTime = Date.now();
345
- console.log(chalk.cyan(`\n 🎯 Gate: ${gate}`));
346
- try {
347
- let result;
348
- let adapter;
349
- // Check if this is a v2 pack with dynamic gate configuration
350
- if (this.isPackV2(this.pack)) {
351
- const gateConfig = this.pack.gates[gate];
352
- if (gateConfig) {
353
- return await this.executeDynamicGate(gate, gateConfig);
354
- }
355
- }
356
- // Legacy v1 gates or predefined gates
357
- switch (gate) {
358
- case 'api_smoke':
359
- adapter = 'playwright-native-api';
360
- result = await this.runApiSmokeGate();
361
- break;
362
- case 'ui':
363
- adapter = 'playwright-ui';
364
- result = await this.runUiGate();
365
- break;
366
- case 'a11y':
367
- adapter = 'playwright-ui';
368
- result = await this.runA11yGate();
369
- break;
370
- case 'perf':
371
- adapter = 'k6';
372
- result = await this.runPerfGate();
373
- break;
374
- case 'sast':
375
- adapter = 'semgrep';
376
- result = await this.runSastGate();
377
- break;
378
- case 'dast':
379
- adapter = 'zap';
380
- result = await this.runDastGate();
381
- break;
382
- default:
383
- throw new Error(`Unknown gate: ${gate}`);
384
- }
385
- const duration = Date.now() - startTime;
386
- if (result.success) {
387
- console.log(chalk.green(` ✅ ${gate} passed (${duration}ms)`));
388
- }
389
- else {
390
- console.log(chalk.red(` ❌ ${gate} failed (${duration}ms)`));
391
- if (result.error) {
392
- console.log(chalk.red(` 🔍 ${result.error}`));
393
- }
394
- }
395
- return {
396
- gate,
397
- success: result.success,
398
- duration,
399
- adapter,
400
- results: result,
401
- junit: result.junit,
402
- error: result.error
403
- };
404
- }
405
- catch (error) {
406
- const duration = Date.now() - startTime;
407
- const errorMessage = this.redactor.redact(error instanceof Error ? error.message : 'Unknown error');
408
- console.log(chalk.red(` 💥 ${gate} crashed (${duration}ms): ${errorMessage}`));
409
- return {
410
- gate,
411
- success: false,
412
- duration,
413
- adapter: 'unknown',
414
- results: null,
415
- error: errorMessage
416
- };
417
- }
418
- }
419
- /**
420
- * Execute a dynamic v2 gate
421
- */
422
- async executeDynamicGate(gateName, gateConfig) {
423
- const startTime = Date.now();
424
- const adapterType = gateConfig.adapter || gateConfig.type;
425
- if (!adapterType) {
426
- throw new Error(`Gate '${gateName}' must specify an adapter`);
427
- }
428
- // Get auth credentials for this gate
429
- const credentials = await this.getCredentialsForGate(gateName);
430
- // Map adapter type to implementation
431
- let result;
432
- switch (adapterType) {
433
- case 'playwright-api':
434
- result = await this.executePlaywrightApiGate(gateName, gateConfig, credentials);
435
- break;
436
- case 'playwright-ui':
437
- result = await this.executePlaywrightUiGate(gateName, gateConfig, credentials);
438
- break;
439
- case 'k6':
440
- case 'k6-perf':
441
- result = await this.executeK6PerfGate(gateName, gateConfig);
442
- break;
443
- case 'semgrep':
444
- case 'sast':
445
- result = await this.executeSemgrepSastGate(gateName, gateConfig);
446
- break;
447
- default:
448
- throw new Error(`Unsupported adapter: '${adapterType}' for gate '${gateName}'`);
449
- }
450
- // Set duration
451
- result.duration = Date.now() - startTime;
452
- // Log result
453
- if (result.success) {
454
- console.log(chalk.green(` ✅ ${gateName} passed (${result.duration}ms)`));
455
- }
456
- else {
457
- console.log(chalk.red(` ❌ ${gateName} failed (${result.duration}ms)`));
458
- if (result.error) {
459
- console.log(chalk.red(` 🔍 ${result.error}`));
460
- }
461
- }
462
- return result;
463
- }
464
- /**
465
- * Execute Playwright API gate with v2 config
466
- * Uses PlaywrightNativeApiAdapter for zero-overhead HTTP testing
467
- */
468
- async executePlaywrightApiGate(gateName, gateConfig, credentials) {
469
- const { PlaywrightNativeApiAdapter } = await import('../adapters/playwright-native-api.js');
470
- const adapter = new PlaywrightNativeApiAdapter();
471
- // Transform v2 config to adapter format
472
- const gateConfigData = gateConfig.config || {};
473
- const gateOptions = gateConfig.options || {};
474
- const config = {
475
- target: {
476
- baseUrl: gateConfigData.baseUrl,
477
- smoke: gateConfigData.smoke
478
- },
479
- budgets: gateConfigData.budgets,
480
- timeout: gateOptions.timeout || gateConfigData.timeout,
481
- retries: gateOptions.retries || gateConfigData.retries,
482
- auth: credentials
483
- };
484
- const result = await adapter.runSmokeTests(config);
485
- return {
486
- gate: gateName,
487
- success: result.success,
488
- duration: 0, // Will be set by caller
489
- adapter: 'playwright-native-api',
490
- results: result,
491
- junit: result.junit
492
- };
493
- }
494
- /**
495
- * Execute Playwright UI gate with v2 config
496
- */
497
- async executePlaywrightUiGate(gateName, gateConfig, credentials) {
498
- const { PlaywrightUiAdapter } = await import('../adapters/playwright-ui.js');
499
- const adapter = new PlaywrightUiAdapter();
500
- // Transform v2 config to adapter format
501
- // v2: { baseUrl, pages: [{ url: '/', expectedElements: [...] }] }
502
- // adapter expects: { target: { baseUrl, pages: ['https://.../'] } }
503
- const gateConfigData = gateConfig.config || {};
504
- const gateOptions = gateConfig.options || {};
505
- // Transform page objects to full URLs
506
- // v2 pages format: [{ url: '/', expectedElements: [...] }] or ['/', '/about']
507
- const rawPages = gateConfigData.pages;
508
- let pages;
509
- if (rawPages && Array.isArray(rawPages) && rawPages.length > 0) {
510
- const baseUrl = gateConfigData.baseUrl || '';
511
- pages = rawPages.map((p) => {
512
- if (typeof p === 'string') {
513
- // Already a URL string - make it absolute if relative
514
- return p.startsWith('http') ? p : `${baseUrl.replace(/\/$/, '')}${p}`;
515
- }
516
- else if (p && typeof p === 'object' && p.url) {
517
- // Page object { url: '/', ... } - convert to full URL
518
- const url = p.url;
519
- return url.startsWith('http') ? url : `${baseUrl.replace(/\/$/, '')}${url}`;
520
- }
521
- return p;
522
- });
523
- }
524
- else if (gateConfigData.baseUrl) {
525
- pages = [gateConfigData.baseUrl];
526
- }
527
- const config = {
528
- target: {
529
- baseUrl: gateConfigData.baseUrl,
530
- pages: pages
531
- },
532
- budgets: gateConfigData.budgets,
533
- timeout: gateOptions.timeout || gateConfigData.timeout,
534
- auth: credentials,
535
- // Playwright++ features
536
- artifacts: gateConfigData.artifacts,
537
- htmlReport: gateConfigData.htmlReport,
538
- bail: gateConfigData.bail
539
- };
540
- const result = await adapter.runSmokeTests(config);
541
- return {
542
- gate: gateName,
543
- success: result.success,
544
- duration: 0, // Will be set by caller
545
- adapter: 'playwright-ui',
546
- results: result,
547
- junit: result.junit
548
- };
549
- }
550
- /**
551
- * Execute K6 Performance gate with v2 config
552
- */
553
- async executeK6PerfGate(gateName, gateConfig) {
554
- const { K6PerfAdapter } = await import('../adapters/k6-perf.js');
555
- const adapter = new K6PerfAdapter(this.workingDir);
556
- const config = {
557
- baseUrl: gateConfig.config?.baseUrl,
558
- ...gateConfig.config
559
- };
560
- const result = await adapter.runPerfTest(config);
561
- return {
562
- gate: gateName,
563
- success: result.success,
564
- duration: 0,
565
- adapter: 'k6',
566
- results: result,
567
- junit: result.junit
568
- };
569
- }
570
- /**
571
- * Execute Semgrep SAST gate with v2 config
572
- */
573
- async executeSemgrepSastGate(gateName, gateConfig) {
574
- const { SemgrepSastAdapter } = await import('../adapters/semgrep-sast.js');
575
- const adapter = new SemgrepSastAdapter();
576
- const config = {
577
- workingDir: this.workingDir,
578
- ...gateConfig.config
579
- };
580
- const result = await adapter.runSastScan(config);
581
- return {
582
- gate: gateName,
583
- success: result.success,
584
- duration: 0,
585
- adapter: 'semgrep',
586
- results: result,
587
- junit: result.junit
588
- };
589
- }
590
- /**
591
- * Run API smoke gate
592
- * Uses PlaywrightNativeApiAdapter for zero-overhead HTTP testing
593
- */
594
- async runApiSmokeGate() {
595
- const target = this.getTargetApi();
596
- if (!target) {
597
- throw new Error('API smoke gate requires targets.api configuration or gate config with baseUrl');
598
- }
599
- const credentials = await this.getCredentialsForGate('api_smoke');
600
- const adapter = new PlaywrightNativeApiAdapter();
601
- return await adapter.runSmokeTests({
602
- target,
603
- budgets: this.getBudgets(),
604
- timeout: this.getExecutionTimeout() || 10000,
605
- retries: this.getExecutionRetries() || 1,
606
- auth: credentials
607
- });
608
- }
609
- /**
610
- * Run UI gate (includes basic accessibility)
611
- */
612
- async runUiGate() {
613
- const target = this.getTargetWeb();
614
- if (!target) {
615
- throw new Error('UI gate requires targets.web configuration or gate config with baseUrl');
616
- }
617
- const credentials = await this.getCredentialsForGate('ui');
618
- const adapter = new PlaywrightUiAdapter();
619
- return await adapter.runSmokeTests({
620
- target,
621
- budgets: this.getBudgets(),
622
- timeout: this.getExecutionTimeout() || 30000,
623
- auth: credentials
624
- });
625
- }
626
- /**
627
- * Run A11y gate (focused accessibility testing)
628
- */
629
- async runA11yGate() {
630
- // Same as UI gate but focused on accessibility
631
- return await this.runUiGate();
632
- }
633
- /**
634
- * Run performance gate
635
- */
636
- async runPerfGate() {
637
- const baseUrl = this.pack.targets?.web?.baseUrl || this.pack.targets?.api?.baseUrl;
638
- if (!baseUrl) {
639
- throw new Error('Performance gate requires web or api target');
640
- }
641
- const adapter = new K6PerfAdapter(this.workingDir);
642
- return await adapter.runPerfTest({
643
- baseUrl,
644
- budgets: this.pack.budgets,
645
- duration: '30s',
646
- vus: 5,
647
- timeout: 120000
648
- });
649
- }
650
- /**
651
- * Run SAST gate
652
- */
653
- async runSastGate() {
654
- const adapter = new SemgrepSastAdapter();
655
- return await adapter.runSastScan({
656
- workingDir: this.workingDir,
657
- security: this.pack.security,
658
- rules: ['auto'],
659
- paths: ['src/', 'lib/', '.'],
660
- timeout: 120000
661
- });
662
- }
663
- /**
664
- * Run DAST gate (mock implementation)
665
- */
666
- async runDastGate() {
667
- // Mock DAST implementation for Phase 3
668
- console.log(chalk.yellow(' ⚠️ DAST gate: Mock implementation (ZAP integration in Phase 4)'));
669
- return {
670
- success: true,
671
- findings: [],
672
- summary: { total: 0, high: 0, medium: 0, low: 0 },
673
- junit: `<?xml version="1.0" encoding="UTF-8"?>
674
- <testsuite name="DAST Mock" tests="1" failures="0" time="0">
675
- <testcase name="Mock DAST Scan" time="0"></testcase>
676
- </testsuite>`
677
- };
678
- }
679
- /**
680
- * Calculate execution summary
681
- */
682
- calculateSummary(gateResults) {
683
- const total = gateResults.length;
684
- const passed = gateResults.filter(g => g.success).length;
685
- const failed = total - passed;
686
- // Calculate trust score (weighted by gate importance)
687
- const gateWeights = {
688
- 'api_smoke': 20,
689
- 'ui': 15,
690
- 'perf': 15,
691
- 'sast': 20,
692
- 'dast': 20,
693
- 'a11y': 10
694
- };
695
- let totalWeight = 0;
696
- let passedWeight = 0;
697
- for (const gate of gateResults) {
698
- const weight = gateWeights[gate.gate] || 10;
699
- totalWeight += weight;
700
- if (gate.success) {
701
- passedWeight += weight;
702
- }
703
- }
704
- const trustScore = totalWeight > 0 ? Math.round((passedWeight / totalWeight) * 100) : 0;
705
- return { total, passed, failed, trustScore };
706
- }
707
- /**
708
- * Generate cryptographically signed proof document
709
- */
710
- async generateProof(result) {
711
- const timestamp = new Date().toISOString();
712
- const runId = `run-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
713
- // Build proof payload (without signature)
714
- const proofPayload = {
715
- version: '3.0.0',
716
- runId,
717
- timestamp,
718
- pack: {
719
- name: result.pack.name,
720
- version: result.pack.version,
721
- gates: result.pack.gates
722
- },
723
- execution: {
724
- duration: result.duration,
725
- success: result.success,
726
- trustScore: result.summary.trustScore
727
- },
728
- gates: result.gates.map(g => {
729
- const gateObj = {
730
- gate: g.gate,
731
- adapter: g.adapter,
732
- success: g.success,
733
- duration: g.duration
734
- };
735
- // Only include error if it exists (avoid undefined fields)
736
- if (g.error !== undefined) {
737
- gateObj.error = g.error;
738
- }
739
- return gateObj;
740
- }),
741
- hooks: {
742
- beforeAll: result.hooks.beforeAll.length,
743
- afterAll: result.hooks.afterAll.length
744
- }
745
- };
746
- // Canonicalize the payload for signing (must match verification: canonical + newline)
747
- const canonicalPayload = canonicalize(proofPayload) + '\n';
748
- // Sign with Ed25519
749
- let signatureValue;
750
- let algorithm;
751
- let publicKeyB64;
752
- if (this.keyPair) {
753
- signatureValue = sign(canonicalPayload, this.keyPair.secretKey);
754
- algorithm = 'ed25519';
755
- publicKeyB64 = Buffer.from(this.keyPair.publicKey).toString('base64');
756
- console.log(chalk.green(' 🔏 Proof signed with Ed25519'));
757
- }
758
- else {
759
- signatureValue = `unsigned-${runId}`;
760
- algorithm = 'none';
761
- publicKeyB64 = '';
762
- console.log(chalk.yellow(' ⚠️ Proof unsigned (no keys available)'));
763
- }
764
- // Build complete proof with signature
765
- const proof = {
766
- ...proofPayload,
767
- signature: {
768
- algorithm,
769
- publicKey: publicKeyB64,
770
- value: signatureValue,
771
- timestamp
772
- }
773
- };
774
- // Save proof
775
- const proofPath = join(this.outputDir, `${runId}-proof.json`);
776
- writeFileSync(proofPath, JSON.stringify(proof, null, 2));
777
- return proofPath;
778
- }
779
- /**
780
- * Save run results to Evidence Vault
781
- * @returns The vault run ID
782
- */
783
- async saveToVault(runId, result, proofPath, flakinessResults, startTime) {
784
- if (!this.vault) {
785
- console.log(chalk.yellow(' ⚠️ Vault not initialized, skipping storage'));
786
- return undefined;
787
- }
788
- try {
789
- // Begin run in vault (returns actual runId used)
790
- // Use startTime if provided to correctly calculate duration
791
- const { runId: vaultRunId } = await this.vault.beginRun({
792
- pack_path: `${this.pack.name || 'pack'}.yaml`,
793
- pack_hash: this.hashPack(result.pack),
794
- started_at: startTime // Use actual run start time for accurate duration
795
- });
796
- // Finish run with final status
797
- await this.vault.finishRun(vaultRunId, {
798
- status: result.success ? 'passed' : 'failed',
799
- trust_score: result.summary.trustScore,
800
- signature: this.keyPair ? 'ed25519-signed' : undefined
801
- });
802
- // Record gate executions
803
- for (const gate of result.gates) {
804
- await this.vault.recordGate(vaultRunId, {
805
- name: gate.gate,
806
- status: gate.success ? 'passed' : 'failed',
807
- duration_ms: gate.duration,
808
- metrics_json: JSON.stringify(gate.results?.summary || {})
809
- });
810
- // Record finding if gate has error
811
- if (gate.error) {
812
- await this.vault.recordFinding(vaultRunId, {
813
- gate: gate.gate,
814
- severity: 'high',
815
- rule: 'gate-failure',
816
- message: gate.error
817
- });
818
- }
819
- }
820
- // Record flakiness results if available
821
- if (flakinessResults && flakinessResults.length > 0) {
822
- for (const flaky of flakinessResults) {
823
- // Record unstable/shaky tests as findings
824
- if (flaky.category === FlakinessCategory.UNSTABLE || flaky.category === FlakinessCategory.SHAKY) {
825
- await this.vault.recordFinding(vaultRunId, {
826
- gate: flaky.gate,
827
- severity: flaky.category === FlakinessCategory.UNSTABLE ? 'high' : 'medium',
828
- rule: 'flaky-test-detected',
829
- message: `Test "${flaky.testName}" is ${flaky.category}: ${flaky.score}% reliability (${flaky.successfulRuns}/${flaky.totalRuns} passes)`
830
- });
831
- }
832
- }
833
- console.log(chalk.green(` 💾 ${flakinessResults.length} flakiness analysis(es) saved`));
834
- }
835
- console.log(chalk.green(' 💾 Run saved to Evidence Vault'));
836
- return vaultRunId;
837
- }
838
- catch (error) {
839
- console.log(chalk.yellow(` ⚠️ Failed to save to vault: ${error}`));
840
- return undefined;
841
- }
842
- }
843
- /**
844
- * Detect flakiness by running tests multiple times consecutively
845
- * @param gateResults Original gate results from first run
846
- * @returns Flakiness analysis results
847
- */
848
- async detectFlakiness(gateResults) {
849
- const flakinessMap = new Map();
850
- const timestamp = Date.now();
851
- // First, collect results from the initial run
852
- for (const gateResult of gateResults) {
853
- for (const [testId, testResult] of this.extractTestResults(gateResult, timestamp)) {
854
- if (!flakinessMap.has(testId)) {
855
- flakinessMap.set(testId, []);
856
- }
857
- flakinessMap.get(testId).push(testResult);
858
- }
859
- }
860
- // Run additional consecutive runs
861
- for (let run = 1; run < this.flakyRuns; run++) {
862
- console.log(chalk.gray(` 🔄 Consecutive run ${run + 1}/${this.flakyRuns}...`));
863
- for (const gateResult of gateResults) {
864
- // Re-run all gates to detect flakiness
865
- try {
866
- const retryResult = await this.executeGate(gateResult.gate);
867
- // Extract and store test results
868
- for (const [testId, testResult] of this.extractTestResults(retryResult, timestamp)) {
869
- if (!flakinessMap.has(testId)) {
870
- flakinessMap.set(testId, []);
871
- }
872
- flakinessMap.get(testId).push(testResult);
873
- }
874
- }
875
- catch (error) {
876
- console.log(chalk.yellow(` ⚠️ Failed to re-run ${gateResult.gate}: ${error}`));
877
- }
878
- }
879
- }
880
- // Analyze all collected results
881
- return this.flakinessDetector.analyzeAll(flakinessMap);
882
- }
883
- /**
884
- * Extract test results from a gate result
885
- * Returns a map of testId to TestResult for flakiness tracking
886
- */
887
- extractTestResults(gateResult, timestamp) {
888
- const results = new Map();
889
- // Extract test results from adapter output
890
- const adapterResults = gateResult.results;
891
- if (adapterResults?.results && Array.isArray(adapterResults.results)) {
892
- // Check for Playwright Native API adapter format
893
- const firstResult = adapterResults.results[0];
894
- if (firstResult && 'endpoint' in firstResult && 'method' in firstResult) {
895
- // PlaywrightNativeApiAdapter format: { endpoint, method, status, success, error, ... }
896
- for (const test of adapterResults.results) {
897
- // Extract just the path from full URL for cleaner test names
898
- const url = new URL(test.endpoint);
899
- const path = url.pathname + url.search;
900
- const testName = `${test.method} ${path} -> ${test.status}`;
901
- const testId = generateTestId(testName, gateResult.gate);
902
- results.set(testId, {
903
- testId,
904
- testName,
905
- filePath: gateResult.gate,
906
- gate: gateResult.gate,
907
- success: test.success,
908
- durationMs: test.responseTime || 0,
909
- errorMessage: test.error,
910
- timestamp: timestamp + Math.random(), // Small offset for ordering
911
- environment: process.env.NODE_ENV || 'local'
912
- });
913
- }
914
- }
915
- else {
916
- // Generic adapter format with results array
917
- for (const test of adapterResults.results) {
918
- const testName = test.name || gateResult.gate;
919
- const testId = generateTestId(testName, gateResult.gate);
920
- results.set(testId, {
921
- testId,
922
- testName,
923
- filePath: gateResult.gate,
924
- gate: gateResult.gate,
925
- success: test.passed || test.status === 'passed',
926
- durationMs: test.duration || 0,
927
- errorType: test.error?.type,
928
- errorMessage: test.error?.message,
929
- timestamp: timestamp + Math.random(),
930
- environment: process.env.NODE_ENV || 'local'
931
- });
932
- }
933
- }
934
- }
935
- else if (adapterResults?.summary) {
936
- // Generic adapter with summary only (no detailed results)
937
- const testId = generateTestId(gateResult.gate, gateResult.gate);
938
- results.set(testId, {
939
- testId,
940
- testName: gateResult.gate,
941
- filePath: gateResult.gate,
942
- gate: gateResult.gate,
943
- success: gateResult.success,
944
- durationMs: gateResult.duration,
945
- errorMessage: gateResult.error,
946
- timestamp,
947
- environment: process.env.NODE_ENV || 'local'
948
- });
949
- }
950
- else {
951
- // Fallback: create single test result from gate
952
- const testId = generateTestId(gateResult.gate, gateResult.gate);
953
- results.set(testId, {
954
- testId,
955
- testName: gateResult.gate,
956
- filePath: gateResult.gate,
957
- gate: gateResult.gate,
958
- success: gateResult.success,
959
- durationMs: gateResult.duration,
960
- errorMessage: gateResult.error,
961
- timestamp,
962
- environment: process.env.NODE_ENV || 'local'
963
- });
964
- }
965
- return results;
966
- }
967
- /**
968
- * Generate hash of pack configuration
969
- */
970
- hashPack(pack) {
971
- return createHash('sha256')
972
- .update(JSON.stringify(pack))
973
- .digest('hex')
974
- .substring(0, 16);
975
- }
976
- /**
977
- * Get API target (v1 or v2 format)
978
- */
979
- getTargetApi() {
980
- if (this.isPackV2(this.pack)) {
981
- // In v2, target is in the gate config
982
- const gateConfig = this.pack.gates['api_smoke'] || this.pack.gates['api'];
983
- if (gateConfig && gateConfig.config?.baseUrl) {
984
- return gateConfig.config;
985
- }
986
- return undefined;
987
- }
988
- return this.pack.targets?.api;
989
- }
990
- /**
991
- * Get Web target (v1 or v2 format)
992
- */
993
- getTargetWeb() {
994
- if (this.isPackV2(this.pack)) {
995
- // In v2, target is in the gate config
996
- const gateConfig = this.pack.gates['ui'] || this.pack.gates['a11y'];
997
- if (gateConfig && gateConfig.config?.baseUrl) {
998
- return gateConfig.config;
999
- }
1000
- return undefined;
1001
- }
1002
- return this.pack.targets?.web;
1003
- }
1004
- /**
1005
- * Get budgets (v1 or v2 format)
1006
- */
1007
- getBudgets() {
1008
- if (this.isPackV2(this.pack)) {
1009
- // In v2, budgets can be in gate config or global
1010
- // For now, return undefined - budgets are gate-specific in v2
1011
- return undefined;
1012
- }
1013
- return this.pack.budgets;
1014
- }
1015
- /**
1016
- * Get execution timeout (v1 or v2 format)
1017
- */
1018
- getExecutionTimeout() {
1019
- if (this.isPackV2(this.pack)) {
1020
- return this.pack.execution?.default_timeout;
1021
- }
1022
- return this.pack.execution?.timeout;
1023
- }
1024
- /**
1025
- * Get execution retries (v1 or v2 format)
1026
- */
1027
- getExecutionRetries() {
1028
- if (this.isPackV2(this.pack)) {
1029
- return this.pack.execution?.default_retries;
1030
- }
1031
- return this.pack.execution?.max_retries;
1032
- }
1033
- /**
1034
- * Ensure output directory exists
1035
- */
1036
- ensureOutputDir() {
1037
- if (!existsSync(this.outputDir)) {
1038
- mkdirSync(this.outputDir, { recursive: true });
1039
- }
1040
- }
1041
- }