@yasserkhanorg/impact-gate 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/LICENSE +168 -0
  2. package/README.md +520 -0
  3. package/dist/adapters/cypress.d.ts +10 -0
  4. package/dist/adapters/cypress.d.ts.map +1 -0
  5. package/dist/adapters/cypress.js +86 -0
  6. package/dist/adapters/framework_adapter.d.ts +41 -0
  7. package/dist/adapters/framework_adapter.d.ts.map +1 -0
  8. package/dist/adapters/framework_adapter.js +152 -0
  9. package/dist/adapters/playwright.d.ts +10 -0
  10. package/dist/adapters/playwright.d.ts.map +1 -0
  11. package/dist/adapters/playwright.js +86 -0
  12. package/dist/adapters/pytest.d.ts +10 -0
  13. package/dist/adapters/pytest.d.ts.map +1 -0
  14. package/dist/adapters/pytest.js +96 -0
  15. package/dist/adapters/supertest.d.ts +12 -0
  16. package/dist/adapters/supertest.d.ts.map +1 -0
  17. package/dist/adapters/supertest.js +85 -0
  18. package/dist/agent/api_catalog.d.ts +11 -0
  19. package/dist/agent/api_catalog.d.ts.map +1 -0
  20. package/dist/agent/api_catalog.js +210 -0
  21. package/dist/agent/config.d.ts +193 -0
  22. package/dist/agent/config.d.ts.map +1 -0
  23. package/dist/agent/config.js +875 -0
  24. package/dist/agent/feedback.d.ts +91 -0
  25. package/dist/agent/feedback.d.ts.map +1 -0
  26. package/dist/agent/feedback.js +323 -0
  27. package/dist/agent/git.d.ts +19 -0
  28. package/dist/agent/git.d.ts.map +1 -0
  29. package/dist/agent/git.js +257 -0
  30. package/dist/agent/handoff.d.ts +22 -0
  31. package/dist/agent/handoff.d.ts.map +1 -0
  32. package/dist/agent/handoff.js +180 -0
  33. package/dist/agent/llm_agents_flow.d.ts +15 -0
  34. package/dist/agent/llm_agents_flow.d.ts.map +1 -0
  35. package/dist/agent/llm_agents_flow.js +434 -0
  36. package/dist/agent/native_flow.d.ts +6 -0
  37. package/dist/agent/native_flow.d.ts.map +1 -0
  38. package/dist/agent/native_flow.js +179 -0
  39. package/dist/agent/pipeline.d.ts +7 -0
  40. package/dist/agent/pipeline.d.ts.map +1 -0
  41. package/dist/agent/pipeline.js +260 -0
  42. package/dist/agent/pipeline_types.d.ts +54 -0
  43. package/dist/agent/pipeline_types.d.ts.map +1 -0
  44. package/dist/agent/pipeline_types.js +4 -0
  45. package/dist/agent/pipeline_utils.d.ts +12 -0
  46. package/dist/agent/pipeline_utils.d.ts.map +1 -0
  47. package/dist/agent/pipeline_utils.js +156 -0
  48. package/dist/agent/plan.d.ts +170 -0
  49. package/dist/agent/plan.d.ts.map +1 -0
  50. package/dist/agent/plan.js +86 -0
  51. package/dist/agent/playwright_report.d.ts +8 -0
  52. package/dist/agent/playwright_report.d.ts.map +1 -0
  53. package/dist/agent/playwright_report.js +126 -0
  54. package/dist/agent/process_runner.d.ts +10 -0
  55. package/dist/agent/process_runner.d.ts.map +1 -0
  56. package/dist/agent/process_runner.js +92 -0
  57. package/dist/agent/spec_generator.d.ts +5 -0
  58. package/dist/agent/spec_generator.d.ts.map +1 -0
  59. package/dist/agent/spec_generator.js +253 -0
  60. package/dist/agent/test_path.d.ts +2 -0
  61. package/dist/agent/test_path.d.ts.map +1 -0
  62. package/dist/agent/test_path.js +23 -0
  63. package/dist/agent/traceability_capture.d.ts +18 -0
  64. package/dist/agent/traceability_capture.d.ts.map +1 -0
  65. package/dist/agent/traceability_capture.js +313 -0
  66. package/dist/agent/traceability_ingest.d.ts +21 -0
  67. package/dist/agent/traceability_ingest.d.ts.map +1 -0
  68. package/dist/agent/traceability_ingest.js +237 -0
  69. package/dist/agent/types.d.ts +42 -0
  70. package/dist/agent/types.d.ts.map +1 -0
  71. package/dist/agent/types.js +4 -0
  72. package/dist/agent/utils.d.ts +13 -0
  73. package/dist/agent/utils.d.ts.map +1 -0
  74. package/dist/agent/utils.js +152 -0
  75. package/dist/agent/validation_runner.d.ts +5 -0
  76. package/dist/agent/validation_runner.d.ts.map +1 -0
  77. package/dist/agent/validation_runner.js +77 -0
  78. package/dist/agentic/fix_loop.d.ts +26 -0
  79. package/dist/agentic/fix_loop.d.ts.map +1 -0
  80. package/dist/agentic/fix_loop.js +96 -0
  81. package/dist/agentic/playwright_runner.d.ts +43 -0
  82. package/dist/agentic/playwright_runner.d.ts.map +1 -0
  83. package/dist/agentic/playwright_runner.js +165 -0
  84. package/dist/agentic/runner.d.ts +27 -0
  85. package/dist/agentic/runner.d.ts.map +1 -0
  86. package/dist/agentic/runner.js +210 -0
  87. package/dist/agentic/types.d.ts +62 -0
  88. package/dist/agentic/types.d.ts.map +1 -0
  89. package/dist/agentic/types.js +4 -0
  90. package/dist/agents/coverage-evaluator.d.ts +8 -0
  91. package/dist/agents/coverage-evaluator.d.ts.map +1 -0
  92. package/dist/agents/coverage-evaluator.js +41 -0
  93. package/dist/agents/cross-impact.d.ts +13 -0
  94. package/dist/agents/cross-impact.d.ts.map +1 -0
  95. package/dist/agents/cross-impact.js +140 -0
  96. package/dist/agents/executor.d.ts +8 -0
  97. package/dist/agents/executor.d.ts.map +1 -0
  98. package/dist/agents/executor.js +75 -0
  99. package/dist/agents/explorer.d.ts +12 -0
  100. package/dist/agents/explorer.d.ts.map +1 -0
  101. package/dist/agents/explorer.js +43 -0
  102. package/dist/agents/generator.d.ts +8 -0
  103. package/dist/agents/generator.d.ts.map +1 -0
  104. package/dist/agents/generator.js +77 -0
  105. package/dist/agents/healer.d.ts +8 -0
  106. package/dist/agents/healer.d.ts.map +1 -0
  107. package/dist/agents/healer.js +31 -0
  108. package/dist/agents/impact-analyst.d.ts +8 -0
  109. package/dist/agents/impact-analyst.d.ts.map +1 -0
  110. package/dist/agents/impact-analyst.js +38 -0
  111. package/dist/agents/regression-advisor.d.ts +8 -0
  112. package/dist/agents/regression-advisor.d.ts.map +1 -0
  113. package/dist/agents/regression-advisor.js +116 -0
  114. package/dist/agents/strategist.d.ts +9 -0
  115. package/dist/agents/strategist.d.ts.map +1 -0
  116. package/dist/agents/strategist.js +92 -0
  117. package/dist/agents/test-designer.d.ts +8 -0
  118. package/dist/agents/test-designer.d.ts.map +1 -0
  119. package/dist/agents/test-designer.js +111 -0
  120. package/dist/anthropic_provider.d.ts +65 -0
  121. package/dist/anthropic_provider.d.ts.map +1 -0
  122. package/dist/anthropic_provider.js +334 -0
  123. package/dist/api.d.ts +48 -0
  124. package/dist/api.d.ts.map +1 -0
  125. package/dist/api.js +151 -0
  126. package/dist/base_provider.d.ts +109 -0
  127. package/dist/base_provider.d.ts.map +1 -0
  128. package/dist/base_provider.js +203 -0
  129. package/dist/budget_ledger.d.ts +28 -0
  130. package/dist/budget_ledger.d.ts.map +1 -0
  131. package/dist/budget_ledger.js +62 -0
  132. package/dist/cache/cached_provider.d.ts +49 -0
  133. package/dist/cache/cached_provider.d.ts.map +1 -0
  134. package/dist/cache/cached_provider.js +91 -0
  135. package/dist/cache/response_cache.d.ts +79 -0
  136. package/dist/cache/response_cache.d.ts.map +1 -0
  137. package/dist/cache/response_cache.js +177 -0
  138. package/dist/cli/commands/analyze.d.ts +3 -0
  139. package/dist/cli/commands/analyze.d.ts.map +1 -0
  140. package/dist/cli/commands/analyze.js +77 -0
  141. package/dist/cli/commands/bootstrap.d.ts +3 -0
  142. package/dist/cli/commands/bootstrap.d.ts.map +1 -0
  143. package/dist/cli/commands/bootstrap.js +109 -0
  144. package/dist/cli/commands/cost_report.d.ts +3 -0
  145. package/dist/cli/commands/cost_report.d.ts.map +1 -0
  146. package/dist/cli/commands/cost_report.js +115 -0
  147. package/dist/cli/commands/crew.d.ts +3 -0
  148. package/dist/cli/commands/crew.d.ts.map +1 -0
  149. package/dist/cli/commands/crew.js +255 -0
  150. package/dist/cli/commands/feedback.d.ts +3 -0
  151. package/dist/cli/commands/feedback.d.ts.map +1 -0
  152. package/dist/cli/commands/feedback.js +39 -0
  153. package/dist/cli/commands/finalize.d.ts +3 -0
  154. package/dist/cli/commands/finalize.d.ts.map +1 -0
  155. package/dist/cli/commands/finalize.js +41 -0
  156. package/dist/cli/commands/gate.d.ts +3 -0
  157. package/dist/cli/commands/gate.d.ts.map +1 -0
  158. package/dist/cli/commands/gate.js +89 -0
  159. package/dist/cli/commands/generate.d.ts +4 -0
  160. package/dist/cli/commands/generate.d.ts.map +1 -0
  161. package/dist/cli/commands/generate.js +108 -0
  162. package/dist/cli/commands/heal.d.ts +3 -0
  163. package/dist/cli/commands/heal.d.ts.map +1 -0
  164. package/dist/cli/commands/heal.js +60 -0
  165. package/dist/cli/commands/impact.d.ts +4 -0
  166. package/dist/cli/commands/impact.d.ts.map +1 -0
  167. package/dist/cli/commands/impact.js +33 -0
  168. package/dist/cli/commands/init.d.ts +2 -0
  169. package/dist/cli/commands/init.d.ts.map +1 -0
  170. package/dist/cli/commands/init.js +169 -0
  171. package/dist/cli/commands/llm_health.d.ts +2 -0
  172. package/dist/cli/commands/llm_health.d.ts.map +1 -0
  173. package/dist/cli/commands/llm_health.js +22 -0
  174. package/dist/cli/commands/plan.d.ts +4 -0
  175. package/dist/cli/commands/plan.d.ts.map +1 -0
  176. package/dist/cli/commands/plan.js +120 -0
  177. package/dist/cli/commands/plan_crew.d.ts +17 -0
  178. package/dist/cli/commands/plan_crew.d.ts.map +1 -0
  179. package/dist/cli/commands/plan_crew.js +316 -0
  180. package/dist/cli/commands/traceability.d.ts +4 -0
  181. package/dist/cli/commands/traceability.d.ts.map +1 -0
  182. package/dist/cli/commands/traceability.js +77 -0
  183. package/dist/cli/commands/train.d.ts +3 -0
  184. package/dist/cli/commands/train.d.ts.map +1 -0
  185. package/dist/cli/commands/train.js +391 -0
  186. package/dist/cli/defaults.d.ts +35 -0
  187. package/dist/cli/defaults.d.ts.map +1 -0
  188. package/dist/cli/defaults.js +172 -0
  189. package/dist/cli/errors.d.ts +27 -0
  190. package/dist/cli/errors.d.ts.map +1 -0
  191. package/dist/cli/errors.js +57 -0
  192. package/dist/cli/parse_args.d.ts +6 -0
  193. package/dist/cli/parse_args.d.ts.map +1 -0
  194. package/dist/cli/parse_args.js +257 -0
  195. package/dist/cli/types.d.ts +87 -0
  196. package/dist/cli/types.d.ts.map +1 -0
  197. package/dist/cli/types.js +4 -0
  198. package/dist/cli/usage.d.ts +2 -0
  199. package/dist/cli/usage.d.ts.map +1 -0
  200. package/dist/cli/usage.js +109 -0
  201. package/dist/cli.d.ts +3 -0
  202. package/dist/cli.d.ts.map +1 -0
  203. package/dist/cli.js +194 -0
  204. package/dist/crew/context.d.ts +55 -0
  205. package/dist/crew/context.d.ts.map +1 -0
  206. package/dist/crew/context.js +36 -0
  207. package/dist/crew/orchestrator.d.ts +50 -0
  208. package/dist/crew/orchestrator.d.ts.map +1 -0
  209. package/dist/crew/orchestrator.js +329 -0
  210. package/dist/crew/protocol.d.ts +46 -0
  211. package/dist/crew/protocol.d.ts.map +1 -0
  212. package/dist/crew/protocol.js +4 -0
  213. package/dist/crew/provider.d.ts +17 -0
  214. package/dist/crew/provider.d.ts.map +1 -0
  215. package/dist/crew/provider.js +36 -0
  216. package/dist/crew/sanitize.d.ts +3 -0
  217. package/dist/crew/sanitize.d.ts.map +1 -0
  218. package/dist/crew/sanitize.js +31 -0
  219. package/dist/crew/types.d.ts +52 -0
  220. package/dist/crew/types.d.ts.map +1 -0
  221. package/dist/crew/types.js +4 -0
  222. package/dist/crew/workflows.d.ts +52 -0
  223. package/dist/crew/workflows.d.ts.map +1 -0
  224. package/dist/crew/workflows.js +36 -0
  225. package/dist/custom_provider.d.ts +20 -0
  226. package/dist/custom_provider.d.ts.map +1 -0
  227. package/dist/custom_provider.js +277 -0
  228. package/dist/engine/ai_enrichment.d.ts +44 -0
  229. package/dist/engine/ai_enrichment.d.ts.map +1 -0
  230. package/dist/engine/ai_enrichment.js +267 -0
  231. package/dist/engine/diff_loader.d.ts +11 -0
  232. package/dist/engine/diff_loader.d.ts.map +1 -0
  233. package/dist/engine/diff_loader.js +63 -0
  234. package/dist/engine/impact_engine.d.ts +72 -0
  235. package/dist/engine/impact_engine.d.ts.map +1 -0
  236. package/dist/engine/impact_engine.js +298 -0
  237. package/dist/engine/plan_builder.d.ts +11 -0
  238. package/dist/engine/plan_builder.d.ts.map +1 -0
  239. package/dist/engine/plan_builder.js +599 -0
  240. package/dist/esm/adapters/cypress.js +49 -0
  241. package/dist/esm/adapters/framework_adapter.js +114 -0
  242. package/dist/esm/adapters/playwright.js +49 -0
  243. package/dist/esm/adapters/pytest.js +59 -0
  244. package/dist/esm/adapters/supertest.js +48 -0
  245. package/dist/esm/agent/api_catalog.js +199 -0
  246. package/dist/esm/agent/config.js +872 -0
  247. package/dist/esm/agent/feedback.js +317 -0
  248. package/dist/esm/agent/git.js +252 -0
  249. package/dist/esm/agent/handoff.js +177 -0
  250. package/dist/esm/agent/llm_agents_flow.js +421 -0
  251. package/dist/esm/agent/native_flow.js +175 -0
  252. package/dist/esm/agent/pipeline.js +256 -0
  253. package/dist/esm/agent/pipeline_types.js +3 -0
  254. package/dist/esm/agent/pipeline_utils.js +146 -0
  255. package/dist/esm/agent/plan.js +83 -0
  256. package/dist/esm/agent/playwright_report.js +123 -0
  257. package/dist/esm/agent/process_runner.js +83 -0
  258. package/dist/esm/agent/spec_generator.js +249 -0
  259. package/dist/esm/agent/test_path.js +20 -0
  260. package/dist/esm/agent/traceability_capture.js +310 -0
  261. package/dist/esm/agent/traceability_ingest.js +234 -0
  262. package/dist/esm/agent/types.js +3 -0
  263. package/dist/esm/agent/utils.js +138 -0
  264. package/dist/esm/agent/validation_runner.js +73 -0
  265. package/dist/esm/agentic/fix_loop.js +91 -0
  266. package/dist/esm/agentic/playwright_runner.js +161 -0
  267. package/dist/esm/agentic/runner.js +207 -0
  268. package/dist/esm/agentic/types.js +3 -0
  269. package/dist/esm/agents/coverage-evaluator.js +37 -0
  270. package/dist/esm/agents/cross-impact.js +136 -0
  271. package/dist/esm/agents/executor.js +71 -0
  272. package/dist/esm/agents/explorer.js +39 -0
  273. package/dist/esm/agents/generator.js +73 -0
  274. package/dist/esm/agents/healer.js +27 -0
  275. package/dist/esm/agents/impact-analyst.js +34 -0
  276. package/dist/esm/agents/regression-advisor.js +112 -0
  277. package/dist/esm/agents/strategist.js +88 -0
  278. package/dist/esm/agents/test-designer.js +107 -0
  279. package/dist/esm/anthropic_provider.js +326 -0
  280. package/dist/esm/api.js +143 -0
  281. package/dist/esm/base_provider.js +198 -0
  282. package/dist/esm/budget_ledger.js +58 -0
  283. package/dist/esm/cache/cached_provider.js +85 -0
  284. package/dist/esm/cache/response_cache.js +140 -0
  285. package/dist/esm/cli/commands/analyze.js +74 -0
  286. package/dist/esm/cli/commands/bootstrap.js +106 -0
  287. package/dist/esm/cli/commands/cost_report.js +112 -0
  288. package/dist/esm/cli/commands/crew.js +252 -0
  289. package/dist/esm/cli/commands/feedback.js +36 -0
  290. package/dist/esm/cli/commands/finalize.js +38 -0
  291. package/dist/esm/cli/commands/gate.js +86 -0
  292. package/dist/esm/cli/commands/generate.js +105 -0
  293. package/dist/esm/cli/commands/heal.js +57 -0
  294. package/dist/esm/cli/commands/impact.js +30 -0
  295. package/dist/esm/cli/commands/init.js +133 -0
  296. package/dist/esm/cli/commands/llm_health.js +19 -0
  297. package/dist/esm/cli/commands/plan.js +117 -0
  298. package/dist/esm/cli/commands/plan_crew.js +309 -0
  299. package/dist/esm/cli/commands/traceability.js +73 -0
  300. package/dist/esm/cli/commands/train.js +355 -0
  301. package/dist/esm/cli/defaults.js +165 -0
  302. package/dist/esm/cli/errors.js +52 -0
  303. package/dist/esm/cli/parse_args.js +251 -0
  304. package/dist/esm/cli/types.js +3 -0
  305. package/dist/esm/cli/usage.js +106 -0
  306. package/dist/esm/cli.js +192 -0
  307. package/dist/esm/crew/context.js +32 -0
  308. package/dist/esm/crew/orchestrator.js +325 -0
  309. package/dist/esm/crew/protocol.js +3 -0
  310. package/dist/esm/crew/provider.js +33 -0
  311. package/dist/esm/crew/sanitize.js +27 -0
  312. package/dist/esm/crew/types.js +3 -0
  313. package/dist/esm/crew/workflows.js +33 -0
  314. package/dist/esm/custom_provider.js +273 -0
  315. package/dist/esm/engine/ai_enrichment.js +264 -0
  316. package/dist/esm/engine/diff_loader.js +59 -0
  317. package/dist/esm/engine/impact_engine.js +291 -0
  318. package/dist/esm/engine/plan_builder.js +593 -0
  319. package/dist/esm/index.js +72 -0
  320. package/dist/esm/knowledge/api_surface.js +408 -0
  321. package/dist/esm/knowledge/cluster_utils.js +60 -0
  322. package/dist/esm/knowledge/context_loader.js +85 -0
  323. package/dist/esm/knowledge/failure_history.js +121 -0
  324. package/dist/esm/knowledge/kg_bridge.js +381 -0
  325. package/dist/esm/knowledge/kg_types.js +3 -0
  326. package/dist/esm/knowledge/route_families.js +393 -0
  327. package/dist/esm/knowledge/spec_index.js +122 -0
  328. package/dist/esm/logger.js +115 -0
  329. package/dist/esm/mcp-server.js +621 -0
  330. package/dist/esm/metrics/prometheus.js +149 -0
  331. package/dist/esm/model_router.js +59 -0
  332. package/dist/esm/ollama_provider.js +301 -0
  333. package/dist/esm/openai_provider.js +243 -0
  334. package/dist/esm/package.json +3 -0
  335. package/dist/esm/pipeline/orchestrator.js +228 -0
  336. package/dist/esm/pipeline/spec_verifier.js +75 -0
  337. package/dist/esm/pipeline/stage0_preprocess.js +102 -0
  338. package/dist/esm/pipeline/stage1_impact.js +140 -0
  339. package/dist/esm/pipeline/stage2_coverage.js +153 -0
  340. package/dist/esm/pipeline/stage3_generation.js +284 -0
  341. package/dist/esm/pipeline/stage4_heal.js +288 -0
  342. package/dist/esm/progress.js +112 -0
  343. package/dist/esm/prompts/coverage.js +57 -0
  344. package/dist/esm/prompts/cross-impact.js +53 -0
  345. package/dist/esm/prompts/generation.js +297 -0
  346. package/dist/esm/prompts/generation_profile.js +147 -0
  347. package/dist/esm/prompts/heal.js +91 -0
  348. package/dist/esm/prompts/impact.js +63 -0
  349. package/dist/esm/prompts/json_extract.js +36 -0
  350. package/dist/esm/prompts/strategist.js +61 -0
  351. package/dist/esm/prompts/test-designer.js +92 -0
  352. package/dist/esm/provider_factory.js +366 -0
  353. package/dist/esm/provider_interface.js +23 -0
  354. package/dist/esm/provider_utils.js +96 -0
  355. package/dist/esm/qa-agent/cli.js +205 -0
  356. package/dist/esm/qa-agent/orchestrator.js +120 -0
  357. package/dist/esm/qa-agent/phase1/runner.js +139 -0
  358. package/dist/esm/qa-agent/phase1/scope.js +126 -0
  359. package/dist/esm/qa-agent/phase2/agent_browser.js +95 -0
  360. package/dist/esm/qa-agent/phase2/agent_loop.js +351 -0
  361. package/dist/esm/qa-agent/phase2/exploration_state.js +97 -0
  362. package/dist/esm/qa-agent/phase2/tools.js +386 -0
  363. package/dist/esm/qa-agent/phase2/vision.js +75 -0
  364. package/dist/esm/qa-agent/phase3/feedback.js +34 -0
  365. package/dist/esm/qa-agent/phase3/reporter.js +145 -0
  366. package/dist/esm/qa-agent/phase3/spec_generator.js +62 -0
  367. package/dist/esm/qa-agent/phase3/verdict.js +66 -0
  368. package/dist/esm/qa-agent/safe_env.js +23 -0
  369. package/dist/esm/qa-agent/types.js +3 -0
  370. package/dist/esm/reporters/junit.js +86 -0
  371. package/dist/esm/reporters/reporter.js +3 -0
  372. package/dist/esm/reporters/sarif.js +132 -0
  373. package/dist/esm/resilience/circuit_breaker.js +78 -0
  374. package/dist/esm/resilience/retry.js +56 -0
  375. package/dist/esm/sanitize.js +66 -0
  376. package/dist/esm/training/enricher.js +345 -0
  377. package/dist/esm/training/kg_scanner.js +115 -0
  378. package/dist/esm/training/merger.js +204 -0
  379. package/dist/esm/training/scanner.js +923 -0
  380. package/dist/esm/training/types.js +6 -0
  381. package/dist/esm/training/validator.js +254 -0
  382. package/dist/esm/validation/guardrails.js +101 -0
  383. package/dist/esm/validation/output_schema.js +80 -0
  384. package/dist/esm/version.js +33 -0
  385. package/dist/index.d.ts +99 -0
  386. package/dist/index.d.ts.map +1 -0
  387. package/dist/index.js +169 -0
  388. package/dist/knowledge/api_surface.d.ts +37 -0
  389. package/dist/knowledge/api_surface.d.ts.map +1 -0
  390. package/dist/knowledge/api_surface.js +418 -0
  391. package/dist/knowledge/cluster_utils.d.ts +28 -0
  392. package/dist/knowledge/cluster_utils.d.ts.map +1 -0
  393. package/dist/knowledge/cluster_utils.js +67 -0
  394. package/dist/knowledge/context_loader.d.ts +13 -0
  395. package/dist/knowledge/context_loader.d.ts.map +1 -0
  396. package/dist/knowledge/context_loader.js +90 -0
  397. package/dist/knowledge/failure_history.d.ts +39 -0
  398. package/dist/knowledge/failure_history.d.ts.map +1 -0
  399. package/dist/knowledge/failure_history.js +128 -0
  400. package/dist/knowledge/kg_bridge.d.ts +31 -0
  401. package/dist/knowledge/kg_bridge.d.ts.map +1 -0
  402. package/dist/knowledge/kg_bridge.js +388 -0
  403. package/dist/knowledge/kg_types.d.ts +75 -0
  404. package/dist/knowledge/kg_types.d.ts.map +1 -0
  405. package/dist/knowledge/kg_types.js +4 -0
  406. package/dist/knowledge/route_families.d.ts +98 -0
  407. package/dist/knowledge/route_families.d.ts.map +1 -0
  408. package/dist/knowledge/route_families.js +410 -0
  409. package/dist/knowledge/spec_index.d.ts +18 -0
  410. package/dist/knowledge/spec_index.d.ts.map +1 -0
  411. package/dist/knowledge/spec_index.js +128 -0
  412. package/dist/logger.d.ts +31 -0
  413. package/dist/logger.d.ts.map +1 -0
  414. package/dist/logger.js +119 -0
  415. package/dist/mcp-server.d.ts +68 -0
  416. package/dist/mcp-server.d.ts.map +1 -0
  417. package/dist/mcp-server.js +629 -0
  418. package/dist/metrics/prometheus.d.ts +37 -0
  419. package/dist/metrics/prometheus.d.ts.map +1 -0
  420. package/dist/metrics/prometheus.js +153 -0
  421. package/dist/model_router.d.ts +28 -0
  422. package/dist/model_router.d.ts.map +1 -0
  423. package/dist/model_router.js +63 -0
  424. package/dist/ollama_provider.d.ts +65 -0
  425. package/dist/ollama_provider.d.ts.map +1 -0
  426. package/dist/ollama_provider.js +309 -0
  427. package/dist/openai_provider.d.ts +23 -0
  428. package/dist/openai_provider.d.ts.map +1 -0
  429. package/dist/openai_provider.js +251 -0
  430. package/dist/pipeline/orchestrator.d.ts +33 -0
  431. package/dist/pipeline/orchestrator.d.ts.map +1 -0
  432. package/dist/pipeline/orchestrator.js +231 -0
  433. package/dist/pipeline/spec_verifier.d.ts +20 -0
  434. package/dist/pipeline/spec_verifier.d.ts.map +1 -0
  435. package/dist/pipeline/spec_verifier.js +79 -0
  436. package/dist/pipeline/stage0_preprocess.d.ts +31 -0
  437. package/dist/pipeline/stage0_preprocess.d.ts.map +1 -0
  438. package/dist/pipeline/stage0_preprocess.js +105 -0
  439. package/dist/pipeline/stage1_impact.d.ts +19 -0
  440. package/dist/pipeline/stage1_impact.d.ts.map +1 -0
  441. package/dist/pipeline/stage1_impact.js +143 -0
  442. package/dist/pipeline/stage2_coverage.d.ts +19 -0
  443. package/dist/pipeline/stage2_coverage.d.ts.map +1 -0
  444. package/dist/pipeline/stage2_coverage.js +156 -0
  445. package/dist/pipeline/stage3_generation.d.ts +43 -0
  446. package/dist/pipeline/stage3_generation.d.ts.map +1 -0
  447. package/dist/pipeline/stage3_generation.js +287 -0
  448. package/dist/pipeline/stage4_heal.d.ts +62 -0
  449. package/dist/pipeline/stage4_heal.d.ts.map +1 -0
  450. package/dist/pipeline/stage4_heal.js +294 -0
  451. package/dist/progress.d.ts +22 -0
  452. package/dist/progress.d.ts.map +1 -0
  453. package/dist/progress.js +116 -0
  454. package/dist/prompts/coverage.d.ts +39 -0
  455. package/dist/prompts/coverage.d.ts.map +1 -0
  456. package/dist/prompts/coverage.js +61 -0
  457. package/dist/prompts/cross-impact.d.ts +23 -0
  458. package/dist/prompts/cross-impact.d.ts.map +1 -0
  459. package/dist/prompts/cross-impact.js +57 -0
  460. package/dist/prompts/generation.d.ts +25 -0
  461. package/dist/prompts/generation.d.ts.map +1 -0
  462. package/dist/prompts/generation.js +302 -0
  463. package/dist/prompts/generation_profile.d.ts +29 -0
  464. package/dist/prompts/generation_profile.d.ts.map +1 -0
  465. package/dist/prompts/generation_profile.js +151 -0
  466. package/dist/prompts/heal.d.ts +23 -0
  467. package/dist/prompts/heal.d.ts.map +1 -0
  468. package/dist/prompts/heal.js +95 -0
  469. package/dist/prompts/impact.d.ts +31 -0
  470. package/dist/prompts/impact.d.ts.map +1 -0
  471. package/dist/prompts/impact.js +67 -0
  472. package/dist/prompts/json_extract.d.ts +14 -0
  473. package/dist/prompts/json_extract.d.ts.map +1 -0
  474. package/dist/prompts/json_extract.js +39 -0
  475. package/dist/prompts/strategist.d.ts +25 -0
  476. package/dist/prompts/strategist.d.ts.map +1 -0
  477. package/dist/prompts/strategist.js +65 -0
  478. package/dist/prompts/test-designer.d.ts +35 -0
  479. package/dist/prompts/test-designer.d.ts.map +1 -0
  480. package/dist/prompts/test-designer.js +96 -0
  481. package/dist/provider_factory.d.ts +104 -0
  482. package/dist/provider_factory.d.ts.map +1 -0
  483. package/dist/provider_factory.js +371 -0
  484. package/dist/provider_interface.d.ts +365 -0
  485. package/dist/provider_interface.d.ts.map +1 -0
  486. package/dist/provider_interface.js +28 -0
  487. package/dist/provider_utils.d.ts +39 -0
  488. package/dist/provider_utils.d.ts.map +1 -0
  489. package/dist/provider_utils.js +103 -0
  490. package/dist/qa-agent/cli.d.ts +3 -0
  491. package/dist/qa-agent/cli.d.ts.map +1 -0
  492. package/dist/qa-agent/cli.js +207 -0
  493. package/dist/qa-agent/orchestrator.d.ts +3 -0
  494. package/dist/qa-agent/orchestrator.d.ts.map +1 -0
  495. package/dist/qa-agent/orchestrator.js +123 -0
  496. package/dist/qa-agent/phase1/runner.d.ts +3 -0
  497. package/dist/qa-agent/phase1/runner.d.ts.map +1 -0
  498. package/dist/qa-agent/phase1/runner.js +142 -0
  499. package/dist/qa-agent/phase1/scope.d.ts +6 -0
  500. package/dist/qa-agent/phase1/scope.d.ts.map +1 -0
  501. package/dist/qa-agent/phase1/scope.js +129 -0
  502. package/dist/qa-agent/phase2/agent_browser.d.ts +35 -0
  503. package/dist/qa-agent/phase2/agent_browser.d.ts.map +1 -0
  504. package/dist/qa-agent/phase2/agent_browser.js +99 -0
  505. package/dist/qa-agent/phase2/agent_loop.d.ts +3 -0
  506. package/dist/qa-agent/phase2/agent_loop.d.ts.map +1 -0
  507. package/dist/qa-agent/phase2/agent_loop.js +357 -0
  508. package/dist/qa-agent/phase2/exploration_state.d.ts +12 -0
  509. package/dist/qa-agent/phase2/exploration_state.d.ts.map +1 -0
  510. package/dist/qa-agent/phase2/exploration_state.js +109 -0
  511. package/dist/qa-agent/phase2/tools.d.ts +28 -0
  512. package/dist/qa-agent/phase2/tools.d.ts.map +1 -0
  513. package/dist/qa-agent/phase2/tools.js +390 -0
  514. package/dist/qa-agent/phase2/vision.d.ts +3 -0
  515. package/dist/qa-agent/phase2/vision.d.ts.map +1 -0
  516. package/dist/qa-agent/phase2/vision.js +78 -0
  517. package/dist/qa-agent/phase3/feedback.d.ts +3 -0
  518. package/dist/qa-agent/phase3/feedback.d.ts.map +1 -0
  519. package/dist/qa-agent/phase3/feedback.js +37 -0
  520. package/dist/qa-agent/phase3/reporter.d.ts +3 -0
  521. package/dist/qa-agent/phase3/reporter.d.ts.map +1 -0
  522. package/dist/qa-agent/phase3/reporter.js +148 -0
  523. package/dist/qa-agent/phase3/spec_generator.d.ts +3 -0
  524. package/dist/qa-agent/phase3/spec_generator.d.ts.map +1 -0
  525. package/dist/qa-agent/phase3/spec_generator.js +65 -0
  526. package/dist/qa-agent/phase3/verdict.d.ts +3 -0
  527. package/dist/qa-agent/phase3/verdict.d.ts.map +1 -0
  528. package/dist/qa-agent/phase3/verdict.js +69 -0
  529. package/dist/qa-agent/safe_env.d.ts +3 -0
  530. package/dist/qa-agent/safe_env.d.ts.map +1 -0
  531. package/dist/qa-agent/safe_env.js +26 -0
  532. package/dist/qa-agent/types.d.ts +130 -0
  533. package/dist/qa-agent/types.d.ts.map +1 -0
  534. package/dist/qa-agent/types.js +4 -0
  535. package/dist/reporters/junit.d.ts +6 -0
  536. package/dist/reporters/junit.d.ts.map +1 -0
  537. package/dist/reporters/junit.js +89 -0
  538. package/dist/reporters/reporter.d.ts +42 -0
  539. package/dist/reporters/reporter.d.ts.map +1 -0
  540. package/dist/reporters/reporter.js +4 -0
  541. package/dist/reporters/sarif.d.ts +7 -0
  542. package/dist/reporters/sarif.d.ts.map +1 -0
  543. package/dist/reporters/sarif.js +135 -0
  544. package/dist/resilience/circuit_breaker.d.ts +36 -0
  545. package/dist/resilience/circuit_breaker.d.ts.map +1 -0
  546. package/dist/resilience/circuit_breaker.js +82 -0
  547. package/dist/resilience/retry.d.ts +11 -0
  548. package/dist/resilience/retry.d.ts.map +1 -0
  549. package/dist/resilience/retry.js +59 -0
  550. package/dist/sanitize.d.ts +15 -0
  551. package/dist/sanitize.d.ts.map +1 -0
  552. package/dist/sanitize.js +71 -0
  553. package/dist/training/enricher.d.ts +17 -0
  554. package/dist/training/enricher.d.ts.map +1 -0
  555. package/dist/training/enricher.js +350 -0
  556. package/dist/training/kg_scanner.d.ts +13 -0
  557. package/dist/training/kg_scanner.d.ts.map +1 -0
  558. package/dist/training/kg_scanner.js +118 -0
  559. package/dist/training/merger.d.ts +15 -0
  560. package/dist/training/merger.d.ts.map +1 -0
  561. package/dist/training/merger.js +208 -0
  562. package/dist/training/scanner.d.ts +36 -0
  563. package/dist/training/scanner.d.ts.map +1 -0
  564. package/dist/training/scanner.js +932 -0
  565. package/dist/training/types.d.ts +117 -0
  566. package/dist/training/types.d.ts.map +1 -0
  567. package/dist/training/types.js +9 -0
  568. package/dist/training/validator.d.ts +21 -0
  569. package/dist/training/validator.d.ts.map +1 -0
  570. package/dist/training/validator.js +262 -0
  571. package/dist/validation/guardrails.d.ts +31 -0
  572. package/dist/validation/guardrails.d.ts.map +1 -0
  573. package/dist/validation/guardrails.js +112 -0
  574. package/dist/validation/output_schema.d.ts +67 -0
  575. package/dist/validation/output_schema.d.ts.map +1 -0
  576. package/dist/validation/output_schema.js +84 -0
  577. package/dist/version.d.ts +6 -0
  578. package/dist/version.d.ts.map +1 -0
  579. package/dist/version.js +36 -0
  580. package/package.json +126 -0
  581. package/schemas/flow-decision.schema.json +83 -0
  582. package/schemas/gap.schema.json +18 -0
  583. package/schemas/impact.schema.json +455 -0
  584. package/schemas/plan.schema.json +491 -0
  585. package/schemas/route-families.schema.json +137 -0
  586. package/schemas/subsystem-risk-map.schema.json +62 -0
  587. package/schemas/traceability-input.schema.json +122 -0
@@ -0,0 +1,391 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
17
+ }) : function(o, v) {
18
+ o["default"] = v;
19
+ });
20
+ var __importStar = (this && this.__importStar) || (function () {
21
+ var ownKeys = function(o) {
22
+ ownKeys = Object.getOwnPropertyNames || function (o) {
23
+ var ar = [];
24
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
25
+ return ar;
26
+ };
27
+ return ownKeys(o);
28
+ };
29
+ return function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ })();
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.runTrainCommand = runTrainCommand;
39
+ const child_process_1 = require("child_process");
40
+ const fs_1 = require("fs");
41
+ const path_1 = require("path");
42
+ const readline = __importStar(require("readline"));
43
+ const config_js_1 = require("../../agent/config.js");
44
+ const route_families_js_1 = require("../../knowledge/route_families.js");
45
+ const provider_factory_js_1 = require("../../provider_factory.js");
46
+ const logger_js_1 = require("../../logger.js");
47
+ const version_js_1 = require("../../version.js");
48
+ const scanner_js_1 = require("../../training/scanner.js");
49
+ const kg_scanner_js_1 = require("../../training/kg_scanner.js");
50
+ const merger_js_1 = require("../../training/merger.js");
51
+ const enricher_js_1 = require("../../training/enricher.js");
52
+ const validator_js_1 = require("../../training/validator.js");
53
+ const kg_bridge_js_1 = require("../../knowledge/kg_bridge.js");
54
+ class TrainError extends Error {
55
+ constructor(message) {
56
+ super(message);
57
+ this.name = 'TrainError';
58
+ }
59
+ }
60
+ const MAX_BUDGET_USD = 10;
61
+ /**
62
+ * Resolves train-specific options from CLI args.
63
+ * Unlike other commands (analyze, plan, heal) that use the shared resolveConfig()
64
+ * for full pipeline configuration, train only needs appPath and testsRoot.
65
+ * We call resolveConfig() solely to extract testsRoot from the config file.
66
+ */
67
+ function resolveTrainOptions(args, autoConfig) {
68
+ const appPath = args.path || '.';
69
+ let testsRoot = args.testsRoot || appPath;
70
+ // Try to resolve testsRoot from config
71
+ if (autoConfig) {
72
+ try {
73
+ const { config } = (0, config_js_1.resolveConfig)(process.cwd(), autoConfig, {
74
+ path: appPath,
75
+ testsRoot: args.testsRoot,
76
+ });
77
+ testsRoot = config.testsRoot || config.path || appPath;
78
+ }
79
+ catch {
80
+ // use defaults
81
+ }
82
+ }
83
+ const outputPath = args.trainOutput ||
84
+ (0, path_1.join)(testsRoot, '.e2e-ai-agents', 'route-families.json');
85
+ // Validate --pr is a positive integer
86
+ if (args.trainPr !== undefined && (!Number.isInteger(args.trainPr) || args.trainPr <= 0)) {
87
+ throw new TrainError('--pr must be a positive integer');
88
+ }
89
+ // Validate --pr and --since are mutually exclusive
90
+ if (args.trainPr && args.gitSince) {
91
+ throw new TrainError('--pr and --since are mutually exclusive.');
92
+ }
93
+ // Validate --since format (reject leading '-' to prevent git flag injection)
94
+ const since = args.gitSince || 'HEAD~20';
95
+ if (/^-/.test(since) || !/^[a-zA-Z0-9_.~^@\/-]+$/.test(since)) {
96
+ throw new TrainError(`Invalid git ref: ${since}`);
97
+ }
98
+ // Validate budget bounds
99
+ const budget = args.budgetUSD || 0.50;
100
+ if (budget <= 0) {
101
+ throw new TrainError('--budget-usd must be a positive number');
102
+ }
103
+ if (budget > MAX_BUDGET_USD) {
104
+ throw new TrainError(`Budget exceeds maximum of $${MAX_BUDGET_USD}. Use a lower --budget-usd value.`);
105
+ }
106
+ const resolvedAppPath = (0, path_1.resolve)(appPath);
107
+ const resolvedTestsRoot = (0, path_1.resolve)(testsRoot);
108
+ const resolvedOutputPath = (0, path_1.resolve)(outputPath);
109
+ // Validate --path is a real project
110
+ if (!(0, fs_1.existsSync)(resolvedAppPath)) {
111
+ throw new TrainError(`Project root not found: ${resolvedAppPath}`);
112
+ }
113
+ // Validate --output is within project boundary (append separator to prevent prefix attacks)
114
+ const inApp = resolvedOutputPath === resolvedAppPath || resolvedOutputPath.startsWith(resolvedAppPath + '/');
115
+ const inTests = resolvedOutputPath === resolvedTestsRoot || resolvedOutputPath.startsWith(resolvedTestsRoot + '/');
116
+ if (!inApp && !inTests) {
117
+ throw new TrainError(`Output path must be within the project root or tests root: ${resolvedOutputPath}`);
118
+ }
119
+ // Discover git repo root for monorepo-aware scanning and validation
120
+ let gitRepoRoot;
121
+ try {
122
+ gitRepoRoot = (0, child_process_1.execFileSync)('git', ['rev-parse', '--show-toplevel'], {
123
+ cwd: resolvedAppPath,
124
+ encoding: 'utf-8',
125
+ stdio: ['pipe', 'pipe', 'pipe'],
126
+ }).trim();
127
+ }
128
+ catch {
129
+ // Not a git repo or git not available
130
+ }
131
+ // Resolve serverRoot: explicit flag, or auto-detect from git repo root
132
+ let serverRoot = args.serverPath;
133
+ if (!serverRoot && gitRepoRoot) {
134
+ const serverDir = (0, path_1.join)(gitRepoRoot, 'server');
135
+ if ((0, fs_1.existsSync)(serverDir)) {
136
+ serverRoot = serverDir;
137
+ }
138
+ }
139
+ const resolvedServerRoot = serverRoot ? (0, path_1.resolve)(serverRoot) : undefined;
140
+ return {
141
+ appPath: resolvedAppPath,
142
+ testsRoot: resolvedTestsRoot,
143
+ serverRoot: resolvedServerRoot,
144
+ gitRepoRoot: gitRepoRoot ? (0, path_1.resolve)(gitRepoRoot) : undefined,
145
+ enrich: args.trainEnrich !== false,
146
+ validate: args.trainValidate || false,
147
+ since,
148
+ pr: args.trainPr,
149
+ outputPath: resolvedOutputPath,
150
+ dryRun: args.dryRun || false,
151
+ yes: args.trainYes || false,
152
+ budgetUSD: budget,
153
+ };
154
+ }
155
+ function ask(rl, question, defaultValue) {
156
+ const suffix = defaultValue ? ` (${defaultValue})` : '';
157
+ return new Promise((res) => {
158
+ rl.question(`${question}${suffix}: `, (answer) => {
159
+ res(answer.trim() || defaultValue || '');
160
+ });
161
+ });
162
+ }
163
+ async function runTrainCommand(args, autoConfig) {
164
+ const opts = resolveTrainOptions(args, autoConfig);
165
+ const totalTimer = logger_js_1.logger.timer('train-total');
166
+ const timings = {};
167
+ // Configure observability from CLI flags
168
+ if (args.verbose)
169
+ logger_js_1.logger.setLevel(logger_js_1.LogLevel.DEBUG);
170
+ if (args.jsonOutput)
171
+ logger_js_1.logger.setJsonMode(true);
172
+ logger_js_1.logger.info('impact-gate train');
173
+ logger_js_1.logger.info('===================');
174
+ // ---------- Phase 1: Deterministic scan ----------
175
+ // Prefer knowledge graph when available
176
+ const kg = (0, kg_bridge_js_1.loadKnowledgeGraph)(opts.appPath);
177
+ logger_js_1.logger.info('Scanning project structure...');
178
+ if (opts.serverRoot) {
179
+ logger_js_1.logger.info(`Server root: ${opts.serverRoot}`);
180
+ }
181
+ const scanTimer = logger_js_1.logger.timer('scan');
182
+ let scanResult;
183
+ if (kg) {
184
+ logger_js_1.logger.info('Using knowledge graph for scanning (found .understand-anything/knowledge-graph.json)');
185
+ scanResult = (0, kg_scanner_js_1.scanFromKnowledgeGraph)(kg);
186
+ logger_js_1.logger.info(`KG: ${kg.nodes.length} nodes, ${kg.edges.length} edges`);
187
+ }
188
+ else {
189
+ scanResult = (0, scanner_js_1.scanProject)(opts.appPath, opts.testsRoot !== opts.appPath ? opts.testsRoot : undefined, opts.serverRoot, opts.gitRepoRoot);
190
+ }
191
+ timings.scan = scanTimer.end();
192
+ logger_js_1.logger.info(`Found ${scanResult.stats.totalSourceFiles} source files, ${scanResult.stats.totalTestFiles} test files`);
193
+ logger_js_1.logger.info(`Discovered ${scanResult.families.length} candidate families`);
194
+ if (scanResult.families.length === 0) {
195
+ logger_js_1.logger.info('No families discovered. Make sure your project has recognizable');
196
+ logger_js_1.logger.info('source directories (src/, server/, app/) and test directories');
197
+ logger_js_1.logger.info('(tests/, e2e/, specs/) with matching names.');
198
+ return;
199
+ }
200
+ // ---------- Phase 2: Merge with existing ----------
201
+ const mergeTimer = logger_js_1.logger.timer('merge');
202
+ const existing = (0, route_families_js_1.loadRouteFamilyManifest)(opts.testsRoot);
203
+ if (existing) {
204
+ logger_js_1.logger.info(`Found existing manifest with ${existing.families.length} families`);
205
+ }
206
+ let mergeResult = (0, merger_js_1.mergeFamilies)(existing, scanResult.families);
207
+ timings.merge = mergeTimer.end();
208
+ logger_js_1.logger.info(`Merge: ${mergeResult.summary}`);
209
+ // ---------- Phase 3: Stale detection ----------
210
+ if (mergeResult.manifest.families.length > 0) {
211
+ const stale = (0, merger_js_1.detectStaleFamilies)(mergeResult.manifest, opts.appPath, opts.testsRoot);
212
+ if (stale.length > 0) {
213
+ logger_js_1.logger.info(`Stale families detected (${stale.length}):`);
214
+ for (const id of stale) {
215
+ logger_js_1.logger.info(` ${id} — paths no longer exist`);
216
+ }
217
+ if (!opts.yes && !opts.dryRun && process.stdin.isTTY) {
218
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
219
+ try {
220
+ const answer = await ask(rl, ' Remove stale families? [y/N]', 'N');
221
+ if (answer.toLowerCase() === 'y') {
222
+ const staleSet = new Set(stale);
223
+ mergeResult.manifest.families = mergeResult.manifest.families.filter((f) => !staleSet.has(f.id));
224
+ mergeResult.staleFamilies = stale;
225
+ logger_js_1.logger.info(`Removed ${stale.length} stale families`);
226
+ }
227
+ }
228
+ finally {
229
+ rl.close();
230
+ }
231
+ }
232
+ }
233
+ }
234
+ // ---------- Phase 4: LLM Enrichment ----------
235
+ let enrichTokens = 0;
236
+ let enrichCost = 0;
237
+ let enrichRequests = 0;
238
+ let enrichAvgResponseMs = 0;
239
+ if (opts.enrich) {
240
+ logger_js_1.logger.info('Enriching with LLM...');
241
+ const enrichTimer = logger_js_1.logger.timer('enrich');
242
+ try {
243
+ const provider = await provider_factory_js_1.LLMProviderFactory.createFromEnv();
244
+ const enrichResult = await (0, enricher_js_1.enrichFamilies)(mergeResult.manifest.families, scanResult.families, opts.appPath, provider, opts.budgetUSD, opts.testsRoot !== opts.appPath ? opts.testsRoot : undefined);
245
+ mergeResult.manifest.families = enrichResult.enrichedFamilies;
246
+ enrichTokens = enrichResult.tokensUsed;
247
+ enrichCost = enrichResult.costUSD;
248
+ enrichRequests = enrichResult.requestCount ?? 0;
249
+ enrichAvgResponseMs = enrichResult.avgResponseMs ?? 0;
250
+ logger_js_1.logger.info(`Enriched ${enrichResult.enrichedFamilies.length} families`, {
251
+ tokens: enrichResult.tokensUsed,
252
+ cost: enrichResult.costUSD,
253
+ requests: enrichRequests,
254
+ avgResponseMs: enrichAvgResponseMs,
255
+ });
256
+ if (enrichResult.skippedFamilies.length > 0) {
257
+ logger_js_1.logger.info(`Skipped ${enrichResult.skippedFamilies.length} families (budget limit)`);
258
+ }
259
+ }
260
+ catch (error) {
261
+ logger_js_1.logger.warn(`LLM enrichment failed: ${error instanceof Error ? error.message : String(error)}`);
262
+ logger_js_1.logger.warn('Continuing with deterministic results. Use --no-enrich to skip LLM.');
263
+ }
264
+ timings.enrich = enrichTimer.end();
265
+ }
266
+ // ---------- Phase 5: Write manifest ----------
267
+ const json = (0, route_families_js_1.serializeManifest)(mergeResult.manifest);
268
+ if (opts.dryRun) {
269
+ logger_js_1.logger.info('Dry run — proposed manifest:');
270
+ console.log(json);
271
+ }
272
+ else {
273
+ const dir = (0, path_1.dirname)(opts.outputPath);
274
+ if (!(0, fs_1.existsSync)(dir)) {
275
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
276
+ }
277
+ const tmpPath = `${opts.outputPath}.tmp`;
278
+ (0, fs_1.writeFileSync)(tmpPath, json, 'utf-8');
279
+ (0, fs_1.renameSync)(tmpPath, opts.outputPath);
280
+ logger_js_1.logger.info(`Wrote ${opts.outputPath}`);
281
+ logger_js_1.logger.info(`${mergeResult.manifest.families.length} families`);
282
+ }
283
+ // ---------- Phase 6: Report unmatched ----------
284
+ if (scanResult.unmatchedSourceDirs.length > 0 || scanResult.unmatchedTestDirs.length > 0) {
285
+ logger_js_1.logger.info('Unmatched (review manually):');
286
+ for (const dir of scanResult.unmatchedSourceDirs.slice(0, 10)) {
287
+ logger_js_1.logger.info(` source: ${dir.relativePath}`);
288
+ }
289
+ for (const dir of scanResult.unmatchedTestDirs.slice(0, 10)) {
290
+ logger_js_1.logger.info(` test: ${dir.relativePath}`);
291
+ }
292
+ if (scanResult.unmatchedSourceDirs.length + scanResult.unmatchedTestDirs.length > 20) {
293
+ logger_js_1.logger.info(' ... and more');
294
+ }
295
+ }
296
+ // ---------- Phase 7: Validation (optional) ----------
297
+ let validationReport;
298
+ if (opts.validate) {
299
+ const validateTimer = logger_js_1.logger.timer('validate');
300
+ // Build path prefixes for monorepo-aware path normalization.
301
+ // Git log returns repo-root-relative paths, but manifest globs are
302
+ // relative to appPath, testsRoot, or serverRoot.
303
+ const pathPrefixes = [];
304
+ if (opts.gitRepoRoot) {
305
+ const { relative: relPath } = await import('path');
306
+ for (const root of [opts.appPath, opts.testsRoot, opts.serverRoot].filter(Boolean)) {
307
+ const rel = relPath(opts.gitRepoRoot, root).replace(/\\/g, '/');
308
+ if (rel && !rel.startsWith('..') && rel !== '.') {
309
+ pathPrefixes.push(rel.endsWith('/') ? rel : rel + '/');
310
+ }
311
+ }
312
+ }
313
+ logger_js_1.logger.debug('Validation path prefixes', { prefixes: pathPrefixes });
314
+ if (opts.pr) {
315
+ logger_js_1.logger.info(`Validating against PR #${opts.pr}...`);
316
+ // Check for gh CLI
317
+ const { execFileSync } = await import('child_process');
318
+ try {
319
+ execFileSync('gh', ['--version'], { stdio: 'pipe' });
320
+ }
321
+ catch {
322
+ throw new TrainError('--pr requires the GitHub CLI (gh). Install: https://cli.github.com/');
323
+ }
324
+ // Fetch PR changed files via gh CLI
325
+ let prFiles;
326
+ try {
327
+ const output = execFileSync('gh', ['pr', 'view', String(opts.pr), '--json', 'files', '-q', '.files[].path'], {
328
+ cwd: opts.appPath,
329
+ encoding: 'utf-8',
330
+ stdio: ['pipe', 'pipe', 'pipe'],
331
+ });
332
+ prFiles = output.trim().split('\n').filter(Boolean);
333
+ }
334
+ catch (error) {
335
+ throw new TrainError(`Error fetching PR #${opts.pr}: ${error instanceof Error ? error.message : String(error)}`);
336
+ }
337
+ if (prFiles.length === 0) {
338
+ logger_js_1.logger.info('No files found in PR.');
339
+ }
340
+ else {
341
+ const validation = (0, validator_js_1.validateCommit)(mergeResult.manifest, prFiles, `PR#${opts.pr}`, `PR #${opts.pr}`, pathPrefixes);
342
+ validationReport = (0, validator_js_1.buildValidationReport)([validation], mergeResult.manifest);
343
+ logger_js_1.logger.info((0, validator_js_1.formatValidationReport)(validationReport));
344
+ }
345
+ }
346
+ else {
347
+ logger_js_1.logger.info(`Validating against git history (${opts.since})...`);
348
+ const commits = (0, validator_js_1.getCommitFiles)(opts.gitRepoRoot || opts.appPath, opts.since);
349
+ if (commits.length === 0) {
350
+ logger_js_1.logger.info('No commits found in range.');
351
+ }
352
+ else {
353
+ const validations = commits.map((c) => (0, validator_js_1.validateCommit)(mergeResult.manifest, c.files, c.hash, c.message, pathPrefixes));
354
+ validationReport = (0, validator_js_1.buildValidationReport)(validations, mergeResult.manifest);
355
+ logger_js_1.logger.info((0, validator_js_1.formatValidationReport)(validationReport));
356
+ }
357
+ }
358
+ timings.validate = validateTimer.end();
359
+ }
360
+ timings.total = totalTimer.end();
361
+ // ---------- Write train report ----------
362
+ if (!opts.dryRun) {
363
+ const reportDir = (0, path_1.dirname)(opts.outputPath);
364
+ const trainReport = {
365
+ timestamp: new Date().toISOString(),
366
+ version: (0, version_js_1.getVersion)(),
367
+ timings,
368
+ families: {
369
+ total: mergeResult.manifest.families.length,
370
+ new: mergeResult.newFamilies.length,
371
+ updated: mergeResult.updatedFamilies.length,
372
+ stale: mergeResult.staleFamilies.length,
373
+ },
374
+ coverage: validationReport ? {
375
+ percent: validationReport.coveragePercent,
376
+ boundFiles: validationReport.boundFiles,
377
+ totalFiles: validationReport.totalFiles,
378
+ } : undefined,
379
+ llm: opts.enrich ? {
380
+ tokensUsed: enrichTokens,
381
+ costUSD: enrichCost,
382
+ requests: enrichRequests,
383
+ avgResponseMs: enrichAvgResponseMs,
384
+ } : undefined,
385
+ };
386
+ const reportPath = (0, path_1.join)(reportDir, 'train-report.json');
387
+ (0, fs_1.writeFileSync)(reportPath, JSON.stringify(trainReport, null, 2) + '\n', 'utf-8');
388
+ logger_js_1.logger.debug('Wrote train report', { path: reportPath });
389
+ }
390
+ logger_js_1.logger.info('Done.');
391
+ }
@@ -0,0 +1,35 @@
1
+ import type { FrameworkType } from '../agent/config.js';
2
+ export interface ResolvedDefaults {
3
+ path: string;
4
+ testsRoot: string;
5
+ framework: FrameworkType;
6
+ since: string;
7
+ }
8
+ /**
9
+ * Detect the test framework from package.json dependencies.
10
+ */
11
+ export declare function detectFramework(appPath: string): FrameworkType;
12
+ /**
13
+ * Detect the tests root directory by scanning common conventions.
14
+ */
15
+ export declare function detectTestsRoot(appPath: string): string | undefined;
16
+ /**
17
+ * Detect the git default branch for diffing.
18
+ * Returns origin/<branch> format.
19
+ */
20
+ export declare function detectGitDefaultBranch(appPath: string): string;
21
+ /**
22
+ * Detect the project root by walking up to find package.json or .git.
23
+ */
24
+ export declare function detectProjectRoot(startDir: string): string;
25
+ /**
26
+ * Resolve defaults for CLI commands that need path/testsRoot/framework/since.
27
+ * Explicit values from CLI flags take precedence over detected values.
28
+ */
29
+ export declare function resolveDefaults(explicit: {
30
+ path?: string;
31
+ testsRoot?: string;
32
+ framework?: FrameworkType;
33
+ gitSince?: string;
34
+ }): ResolvedDefaults;
35
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/cli/defaults.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,aAAa,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACjB;AAyCD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAkC9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoBnE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA4B9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAa1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,gBAAgB,CAOnB"}
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.detectFramework = detectFramework;
6
+ exports.detectTestsRoot = detectTestsRoot;
7
+ exports.detectGitDefaultBranch = detectGitDefaultBranch;
8
+ exports.detectProjectRoot = detectProjectRoot;
9
+ exports.resolveDefaults = resolveDefaults;
10
+ const fs_1 = require("fs");
11
+ const child_process_1 = require("child_process");
12
+ const path_1 = require("path");
13
+ function detectPytestFramework(appPath) {
14
+ const resolvedPath = (0, path_1.resolve)(appPath);
15
+ const pytestIni = (0, path_1.join)(resolvedPath, 'pytest.ini');
16
+ if ((0, fs_1.existsSync)(pytestIni)) {
17
+ return 'pytest';
18
+ }
19
+ const conftest = (0, path_1.join)(resolvedPath, 'conftest.py');
20
+ if ((0, fs_1.existsSync)(conftest)) {
21
+ return 'pytest';
22
+ }
23
+ const pyproject = (0, path_1.join)(resolvedPath, 'pyproject.toml');
24
+ if ((0, fs_1.existsSync)(pyproject)) {
25
+ try {
26
+ const content = (0, fs_1.readFileSync)(pyproject, 'utf-8');
27
+ if (content.includes('pytest')) {
28
+ return 'pytest';
29
+ }
30
+ }
31
+ catch {
32
+ // ignore malformed or unreadable file
33
+ }
34
+ }
35
+ const setupCfg = (0, path_1.join)(resolvedPath, 'setup.cfg');
36
+ if ((0, fs_1.existsSync)(setupCfg)) {
37
+ try {
38
+ const content = (0, fs_1.readFileSync)(setupCfg, 'utf-8');
39
+ if (content.includes('[tool:pytest]') || content.includes('[pytest]')) {
40
+ return 'pytest';
41
+ }
42
+ }
43
+ catch {
44
+ // ignore malformed or unreadable file
45
+ }
46
+ }
47
+ return undefined;
48
+ }
49
+ /**
50
+ * Detect the test framework from package.json dependencies.
51
+ */
52
+ function detectFramework(appPath) {
53
+ const resolvedPath = (0, path_1.resolve)(appPath);
54
+ const pkgPath = (0, path_1.join)(resolvedPath, 'package.json');
55
+ if (!(0, fs_1.existsSync)(pkgPath)) {
56
+ const pytestFramework = detectPytestFramework(resolvedPath);
57
+ if (pytestFramework) {
58
+ return pytestFramework;
59
+ }
60
+ return 'auto';
61
+ }
62
+ try {
63
+ const pkg = JSON.parse((0, fs_1.readFileSync)(pkgPath, 'utf-8'));
64
+ const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
65
+ if (allDeps['@playwright/test'] || allDeps.playwright) {
66
+ return 'playwright';
67
+ }
68
+ if (allDeps.cypress) {
69
+ return 'cypress';
70
+ }
71
+ if (allDeps.supertest) {
72
+ return 'supertest';
73
+ }
74
+ if (allDeps['selenium-webdriver'] || allDeps.webdriverio) {
75
+ return 'selenium';
76
+ }
77
+ }
78
+ catch {
79
+ // ignore malformed package.json
80
+ }
81
+ const pytestFramework = detectPytestFramework(resolvedPath);
82
+ if (pytestFramework) {
83
+ return pytestFramework;
84
+ }
85
+ return 'auto';
86
+ }
87
+ /**
88
+ * Detect the tests root directory by scanning common conventions.
89
+ */
90
+ function detectTestsRoot(appPath) {
91
+ const resolvedPath = (0, path_1.resolve)(appPath);
92
+ const candidates = [
93
+ 'e2e-tests/playwright',
94
+ 'e2e-tests',
95
+ 'e2e',
96
+ 'tests/e2e',
97
+ 'test/e2e',
98
+ 'tests',
99
+ 'test',
100
+ 'specs',
101
+ 'playwright',
102
+ 'cypress',
103
+ ];
104
+ for (const candidate of candidates) {
105
+ if ((0, fs_1.existsSync)((0, path_1.join)(resolvedPath, candidate))) {
106
+ return candidate;
107
+ }
108
+ }
109
+ return undefined;
110
+ }
111
+ /**
112
+ * Detect the git default branch for diffing.
113
+ * Returns origin/<branch> format.
114
+ */
115
+ function detectGitDefaultBranch(appPath) {
116
+ try {
117
+ // Try to find the remote HEAD branch first
118
+ const remoteInfo = (0, child_process_1.execFileSync)('git', ['remote', 'show', 'origin'], {
119
+ cwd: (0, path_1.resolve)(appPath),
120
+ encoding: 'utf-8',
121
+ stdio: ['pipe', 'pipe', 'pipe'],
122
+ timeout: 5000,
123
+ });
124
+ const headMatch = remoteInfo.match(/HEAD branch:\s*(.+)/);
125
+ if (headMatch) {
126
+ return `origin/${headMatch[1].trim()}`;
127
+ }
128
+ }
129
+ catch {
130
+ // fallback to current branch
131
+ }
132
+ try {
133
+ const result = (0, child_process_1.execFileSync)('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
134
+ cwd: (0, path_1.resolve)(appPath),
135
+ encoding: 'utf-8',
136
+ stdio: ['pipe', 'pipe', 'pipe'],
137
+ timeout: 5000,
138
+ }).trim();
139
+ return `origin/${result}`;
140
+ }
141
+ catch {
142
+ return 'origin/main';
143
+ }
144
+ }
145
+ /**
146
+ * Detect the project root by walking up to find package.json or .git.
147
+ */
148
+ function detectProjectRoot(startDir) {
149
+ let current = (0, path_1.resolve)(startDir);
150
+ while (true) {
151
+ if ((0, fs_1.existsSync)((0, path_1.join)(current, 'package.json')) || (0, fs_1.existsSync)((0, path_1.join)(current, '.git'))) {
152
+ return current;
153
+ }
154
+ const parent = (0, path_1.resolve)(current, '..');
155
+ if (parent === current) {
156
+ break;
157
+ }
158
+ current = parent;
159
+ }
160
+ return startDir;
161
+ }
162
+ /**
163
+ * Resolve defaults for CLI commands that need path/testsRoot/framework/since.
164
+ * Explicit values from CLI flags take precedence over detected values.
165
+ */
166
+ function resolveDefaults(explicit) {
167
+ const path = explicit.path || detectProjectRoot(process.cwd());
168
+ const testsRoot = explicit.testsRoot || detectTestsRoot(path) || '.';
169
+ const framework = explicit.framework || detectFramework(path);
170
+ const since = explicit.gitSince || detectGitDefaultBranch(path);
171
+ return { path, testsRoot, framework, since };
172
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * CLI Error types with structured exit codes.
3
+ *
4
+ * Exit codes:
5
+ * 0 = success
6
+ * 1 = general/user error (bad args, missing config, invalid input)
7
+ * 2 = budget exceeded
8
+ * 3 = LLM provider unavailable (API down, auth failure)
9
+ * 4 = invalid manifest or config file
10
+ */
11
+ export declare const EXIT_CODES: {
12
+ readonly SUCCESS: 0;
13
+ readonly GENERAL_ERROR: 1;
14
+ readonly BUDGET_EXCEEDED: 2;
15
+ readonly PROVIDER_UNAVAILABLE: 3;
16
+ readonly INVALID_CONFIG: 4;
17
+ };
18
+ export type ExitCode = typeof EXIT_CODES[keyof typeof EXIT_CODES];
19
+ export declare class CliError extends Error {
20
+ readonly exitCode: ExitCode;
21
+ constructor(message: string, exitCode?: ExitCode);
22
+ }
23
+ /**
24
+ * Classify an unknown error into the appropriate exit code.
25
+ */
26
+ export declare function classifyError(error: unknown): ExitCode;
27
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AAEH,eAAO,MAAM,UAAU;;;;;;CAMb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAElE,qBAAa,QAAS,SAAQ,KAAK;aAGX,QAAQ,EAAE,QAAQ;gBADlC,OAAO,EAAE,MAAM,EACC,QAAQ,GAAE,QAAmC;CAKpE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CA0BtD"}