qa360 2.1.2 → 2.1.4

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