@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.
- package/LICENSE +168 -0
- package/README.md +520 -0
- package/dist/adapters/cypress.d.ts +10 -0
- package/dist/adapters/cypress.d.ts.map +1 -0
- package/dist/adapters/cypress.js +86 -0
- package/dist/adapters/framework_adapter.d.ts +41 -0
- package/dist/adapters/framework_adapter.d.ts.map +1 -0
- package/dist/adapters/framework_adapter.js +152 -0
- package/dist/adapters/playwright.d.ts +10 -0
- package/dist/adapters/playwright.d.ts.map +1 -0
- package/dist/adapters/playwright.js +86 -0
- package/dist/adapters/pytest.d.ts +10 -0
- package/dist/adapters/pytest.d.ts.map +1 -0
- package/dist/adapters/pytest.js +96 -0
- package/dist/adapters/supertest.d.ts +12 -0
- package/dist/adapters/supertest.d.ts.map +1 -0
- package/dist/adapters/supertest.js +85 -0
- package/dist/agent/api_catalog.d.ts +11 -0
- package/dist/agent/api_catalog.d.ts.map +1 -0
- package/dist/agent/api_catalog.js +210 -0
- package/dist/agent/config.d.ts +193 -0
- package/dist/agent/config.d.ts.map +1 -0
- package/dist/agent/config.js +875 -0
- package/dist/agent/feedback.d.ts +91 -0
- package/dist/agent/feedback.d.ts.map +1 -0
- package/dist/agent/feedback.js +323 -0
- package/dist/agent/git.d.ts +19 -0
- package/dist/agent/git.d.ts.map +1 -0
- package/dist/agent/git.js +257 -0
- package/dist/agent/handoff.d.ts +22 -0
- package/dist/agent/handoff.d.ts.map +1 -0
- package/dist/agent/handoff.js +180 -0
- package/dist/agent/llm_agents_flow.d.ts +15 -0
- package/dist/agent/llm_agents_flow.d.ts.map +1 -0
- package/dist/agent/llm_agents_flow.js +434 -0
- package/dist/agent/native_flow.d.ts +6 -0
- package/dist/agent/native_flow.d.ts.map +1 -0
- package/dist/agent/native_flow.js +179 -0
- package/dist/agent/pipeline.d.ts +7 -0
- package/dist/agent/pipeline.d.ts.map +1 -0
- package/dist/agent/pipeline.js +260 -0
- package/dist/agent/pipeline_types.d.ts +54 -0
- package/dist/agent/pipeline_types.d.ts.map +1 -0
- package/dist/agent/pipeline_types.js +4 -0
- package/dist/agent/pipeline_utils.d.ts +12 -0
- package/dist/agent/pipeline_utils.d.ts.map +1 -0
- package/dist/agent/pipeline_utils.js +156 -0
- package/dist/agent/plan.d.ts +170 -0
- package/dist/agent/plan.d.ts.map +1 -0
- package/dist/agent/plan.js +86 -0
- package/dist/agent/playwright_report.d.ts +8 -0
- package/dist/agent/playwright_report.d.ts.map +1 -0
- package/dist/agent/playwright_report.js +126 -0
- package/dist/agent/process_runner.d.ts +10 -0
- package/dist/agent/process_runner.d.ts.map +1 -0
- package/dist/agent/process_runner.js +92 -0
- package/dist/agent/spec_generator.d.ts +5 -0
- package/dist/agent/spec_generator.d.ts.map +1 -0
- package/dist/agent/spec_generator.js +253 -0
- package/dist/agent/test_path.d.ts +2 -0
- package/dist/agent/test_path.d.ts.map +1 -0
- package/dist/agent/test_path.js +23 -0
- package/dist/agent/traceability_capture.d.ts +18 -0
- package/dist/agent/traceability_capture.d.ts.map +1 -0
- package/dist/agent/traceability_capture.js +313 -0
- package/dist/agent/traceability_ingest.d.ts +21 -0
- package/dist/agent/traceability_ingest.d.ts.map +1 -0
- package/dist/agent/traceability_ingest.js +237 -0
- package/dist/agent/types.d.ts +42 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +4 -0
- package/dist/agent/utils.d.ts +13 -0
- package/dist/agent/utils.d.ts.map +1 -0
- package/dist/agent/utils.js +152 -0
- package/dist/agent/validation_runner.d.ts +5 -0
- package/dist/agent/validation_runner.d.ts.map +1 -0
- package/dist/agent/validation_runner.js +77 -0
- package/dist/agentic/fix_loop.d.ts +26 -0
- package/dist/agentic/fix_loop.d.ts.map +1 -0
- package/dist/agentic/fix_loop.js +96 -0
- package/dist/agentic/playwright_runner.d.ts +43 -0
- package/dist/agentic/playwright_runner.d.ts.map +1 -0
- package/dist/agentic/playwright_runner.js +165 -0
- package/dist/agentic/runner.d.ts +27 -0
- package/dist/agentic/runner.d.ts.map +1 -0
- package/dist/agentic/runner.js +210 -0
- package/dist/agentic/types.d.ts +62 -0
- package/dist/agentic/types.d.ts.map +1 -0
- package/dist/agentic/types.js +4 -0
- package/dist/agents/coverage-evaluator.d.ts +8 -0
- package/dist/agents/coverage-evaluator.d.ts.map +1 -0
- package/dist/agents/coverage-evaluator.js +41 -0
- package/dist/agents/cross-impact.d.ts +13 -0
- package/dist/agents/cross-impact.d.ts.map +1 -0
- package/dist/agents/cross-impact.js +140 -0
- package/dist/agents/executor.d.ts +8 -0
- package/dist/agents/executor.d.ts.map +1 -0
- package/dist/agents/executor.js +75 -0
- package/dist/agents/explorer.d.ts +12 -0
- package/dist/agents/explorer.d.ts.map +1 -0
- package/dist/agents/explorer.js +43 -0
- package/dist/agents/generator.d.ts +8 -0
- package/dist/agents/generator.d.ts.map +1 -0
- package/dist/agents/generator.js +77 -0
- package/dist/agents/healer.d.ts +8 -0
- package/dist/agents/healer.d.ts.map +1 -0
- package/dist/agents/healer.js +31 -0
- package/dist/agents/impact-analyst.d.ts +8 -0
- package/dist/agents/impact-analyst.d.ts.map +1 -0
- package/dist/agents/impact-analyst.js +38 -0
- package/dist/agents/regression-advisor.d.ts +8 -0
- package/dist/agents/regression-advisor.d.ts.map +1 -0
- package/dist/agents/regression-advisor.js +116 -0
- package/dist/agents/strategist.d.ts +9 -0
- package/dist/agents/strategist.d.ts.map +1 -0
- package/dist/agents/strategist.js +92 -0
- package/dist/agents/test-designer.d.ts +8 -0
- package/dist/agents/test-designer.d.ts.map +1 -0
- package/dist/agents/test-designer.js +111 -0
- package/dist/anthropic_provider.d.ts +65 -0
- package/dist/anthropic_provider.d.ts.map +1 -0
- package/dist/anthropic_provider.js +334 -0
- package/dist/api.d.ts +48 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +151 -0
- package/dist/base_provider.d.ts +109 -0
- package/dist/base_provider.d.ts.map +1 -0
- package/dist/base_provider.js +203 -0
- package/dist/budget_ledger.d.ts +28 -0
- package/dist/budget_ledger.d.ts.map +1 -0
- package/dist/budget_ledger.js +62 -0
- package/dist/cache/cached_provider.d.ts +49 -0
- package/dist/cache/cached_provider.d.ts.map +1 -0
- package/dist/cache/cached_provider.js +91 -0
- package/dist/cache/response_cache.d.ts +79 -0
- package/dist/cache/response_cache.d.ts.map +1 -0
- package/dist/cache/response_cache.js +177 -0
- package/dist/cli/commands/analyze.d.ts +3 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +77 -0
- package/dist/cli/commands/bootstrap.d.ts +3 -0
- package/dist/cli/commands/bootstrap.d.ts.map +1 -0
- package/dist/cli/commands/bootstrap.js +109 -0
- package/dist/cli/commands/cost_report.d.ts +3 -0
- package/dist/cli/commands/cost_report.d.ts.map +1 -0
- package/dist/cli/commands/cost_report.js +115 -0
- package/dist/cli/commands/crew.d.ts +3 -0
- package/dist/cli/commands/crew.d.ts.map +1 -0
- package/dist/cli/commands/crew.js +255 -0
- package/dist/cli/commands/feedback.d.ts +3 -0
- package/dist/cli/commands/feedback.d.ts.map +1 -0
- package/dist/cli/commands/feedback.js +39 -0
- package/dist/cli/commands/finalize.d.ts +3 -0
- package/dist/cli/commands/finalize.d.ts.map +1 -0
- package/dist/cli/commands/finalize.js +41 -0
- package/dist/cli/commands/gate.d.ts +3 -0
- package/dist/cli/commands/gate.d.ts.map +1 -0
- package/dist/cli/commands/gate.js +89 -0
- package/dist/cli/commands/generate.d.ts +4 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +108 -0
- package/dist/cli/commands/heal.d.ts +3 -0
- package/dist/cli/commands/heal.d.ts.map +1 -0
- package/dist/cli/commands/heal.js +60 -0
- package/dist/cli/commands/impact.d.ts +4 -0
- package/dist/cli/commands/impact.d.ts.map +1 -0
- package/dist/cli/commands/impact.js +33 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +169 -0
- package/dist/cli/commands/llm_health.d.ts +2 -0
- package/dist/cli/commands/llm_health.d.ts.map +1 -0
- package/dist/cli/commands/llm_health.js +22 -0
- package/dist/cli/commands/plan.d.ts +4 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +120 -0
- package/dist/cli/commands/plan_crew.d.ts +17 -0
- package/dist/cli/commands/plan_crew.d.ts.map +1 -0
- package/dist/cli/commands/plan_crew.js +316 -0
- package/dist/cli/commands/traceability.d.ts +4 -0
- package/dist/cli/commands/traceability.d.ts.map +1 -0
- package/dist/cli/commands/traceability.js +77 -0
- package/dist/cli/commands/train.d.ts +3 -0
- package/dist/cli/commands/train.d.ts.map +1 -0
- package/dist/cli/commands/train.js +391 -0
- package/dist/cli/defaults.d.ts +35 -0
- package/dist/cli/defaults.d.ts.map +1 -0
- package/dist/cli/defaults.js +172 -0
- package/dist/cli/errors.d.ts +27 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +57 -0
- package/dist/cli/parse_args.d.ts +6 -0
- package/dist/cli/parse_args.d.ts.map +1 -0
- package/dist/cli/parse_args.js +257 -0
- package/dist/cli/types.d.ts +87 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +4 -0
- package/dist/cli/usage.d.ts +2 -0
- package/dist/cli/usage.d.ts.map +1 -0
- package/dist/cli/usage.js +109 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +194 -0
- package/dist/crew/context.d.ts +55 -0
- package/dist/crew/context.d.ts.map +1 -0
- package/dist/crew/context.js +36 -0
- package/dist/crew/orchestrator.d.ts +50 -0
- package/dist/crew/orchestrator.d.ts.map +1 -0
- package/dist/crew/orchestrator.js +329 -0
- package/dist/crew/protocol.d.ts +46 -0
- package/dist/crew/protocol.d.ts.map +1 -0
- package/dist/crew/protocol.js +4 -0
- package/dist/crew/provider.d.ts +17 -0
- package/dist/crew/provider.d.ts.map +1 -0
- package/dist/crew/provider.js +36 -0
- package/dist/crew/sanitize.d.ts +3 -0
- package/dist/crew/sanitize.d.ts.map +1 -0
- package/dist/crew/sanitize.js +31 -0
- package/dist/crew/types.d.ts +52 -0
- package/dist/crew/types.d.ts.map +1 -0
- package/dist/crew/types.js +4 -0
- package/dist/crew/workflows.d.ts +52 -0
- package/dist/crew/workflows.d.ts.map +1 -0
- package/dist/crew/workflows.js +36 -0
- package/dist/custom_provider.d.ts +20 -0
- package/dist/custom_provider.d.ts.map +1 -0
- package/dist/custom_provider.js +277 -0
- package/dist/engine/ai_enrichment.d.ts +44 -0
- package/dist/engine/ai_enrichment.d.ts.map +1 -0
- package/dist/engine/ai_enrichment.js +267 -0
- package/dist/engine/diff_loader.d.ts +11 -0
- package/dist/engine/diff_loader.d.ts.map +1 -0
- package/dist/engine/diff_loader.js +63 -0
- package/dist/engine/impact_engine.d.ts +72 -0
- package/dist/engine/impact_engine.d.ts.map +1 -0
- package/dist/engine/impact_engine.js +298 -0
- package/dist/engine/plan_builder.d.ts +11 -0
- package/dist/engine/plan_builder.d.ts.map +1 -0
- package/dist/engine/plan_builder.js +599 -0
- package/dist/esm/adapters/cypress.js +49 -0
- package/dist/esm/adapters/framework_adapter.js +114 -0
- package/dist/esm/adapters/playwright.js +49 -0
- package/dist/esm/adapters/pytest.js +59 -0
- package/dist/esm/adapters/supertest.js +48 -0
- package/dist/esm/agent/api_catalog.js +199 -0
- package/dist/esm/agent/config.js +872 -0
- package/dist/esm/agent/feedback.js +317 -0
- package/dist/esm/agent/git.js +252 -0
- package/dist/esm/agent/handoff.js +177 -0
- package/dist/esm/agent/llm_agents_flow.js +421 -0
- package/dist/esm/agent/native_flow.js +175 -0
- package/dist/esm/agent/pipeline.js +256 -0
- package/dist/esm/agent/pipeline_types.js +3 -0
- package/dist/esm/agent/pipeline_utils.js +146 -0
- package/dist/esm/agent/plan.js +83 -0
- package/dist/esm/agent/playwright_report.js +123 -0
- package/dist/esm/agent/process_runner.js +83 -0
- package/dist/esm/agent/spec_generator.js +249 -0
- package/dist/esm/agent/test_path.js +20 -0
- package/dist/esm/agent/traceability_capture.js +310 -0
- package/dist/esm/agent/traceability_ingest.js +234 -0
- package/dist/esm/agent/types.js +3 -0
- package/dist/esm/agent/utils.js +138 -0
- package/dist/esm/agent/validation_runner.js +73 -0
- package/dist/esm/agentic/fix_loop.js +91 -0
- package/dist/esm/agentic/playwright_runner.js +161 -0
- package/dist/esm/agentic/runner.js +207 -0
- package/dist/esm/agentic/types.js +3 -0
- package/dist/esm/agents/coverage-evaluator.js +37 -0
- package/dist/esm/agents/cross-impact.js +136 -0
- package/dist/esm/agents/executor.js +71 -0
- package/dist/esm/agents/explorer.js +39 -0
- package/dist/esm/agents/generator.js +73 -0
- package/dist/esm/agents/healer.js +27 -0
- package/dist/esm/agents/impact-analyst.js +34 -0
- package/dist/esm/agents/regression-advisor.js +112 -0
- package/dist/esm/agents/strategist.js +88 -0
- package/dist/esm/agents/test-designer.js +107 -0
- package/dist/esm/anthropic_provider.js +326 -0
- package/dist/esm/api.js +143 -0
- package/dist/esm/base_provider.js +198 -0
- package/dist/esm/budget_ledger.js +58 -0
- package/dist/esm/cache/cached_provider.js +85 -0
- package/dist/esm/cache/response_cache.js +140 -0
- package/dist/esm/cli/commands/analyze.js +74 -0
- package/dist/esm/cli/commands/bootstrap.js +106 -0
- package/dist/esm/cli/commands/cost_report.js +112 -0
- package/dist/esm/cli/commands/crew.js +252 -0
- package/dist/esm/cli/commands/feedback.js +36 -0
- package/dist/esm/cli/commands/finalize.js +38 -0
- package/dist/esm/cli/commands/gate.js +86 -0
- package/dist/esm/cli/commands/generate.js +105 -0
- package/dist/esm/cli/commands/heal.js +57 -0
- package/dist/esm/cli/commands/impact.js +30 -0
- package/dist/esm/cli/commands/init.js +133 -0
- package/dist/esm/cli/commands/llm_health.js +19 -0
- package/dist/esm/cli/commands/plan.js +117 -0
- package/dist/esm/cli/commands/plan_crew.js +309 -0
- package/dist/esm/cli/commands/traceability.js +73 -0
- package/dist/esm/cli/commands/train.js +355 -0
- package/dist/esm/cli/defaults.js +165 -0
- package/dist/esm/cli/errors.js +52 -0
- package/dist/esm/cli/parse_args.js +251 -0
- package/dist/esm/cli/types.js +3 -0
- package/dist/esm/cli/usage.js +106 -0
- package/dist/esm/cli.js +192 -0
- package/dist/esm/crew/context.js +32 -0
- package/dist/esm/crew/orchestrator.js +325 -0
- package/dist/esm/crew/protocol.js +3 -0
- package/dist/esm/crew/provider.js +33 -0
- package/dist/esm/crew/sanitize.js +27 -0
- package/dist/esm/crew/types.js +3 -0
- package/dist/esm/crew/workflows.js +33 -0
- package/dist/esm/custom_provider.js +273 -0
- package/dist/esm/engine/ai_enrichment.js +264 -0
- package/dist/esm/engine/diff_loader.js +59 -0
- package/dist/esm/engine/impact_engine.js +291 -0
- package/dist/esm/engine/plan_builder.js +593 -0
- package/dist/esm/index.js +72 -0
- package/dist/esm/knowledge/api_surface.js +408 -0
- package/dist/esm/knowledge/cluster_utils.js +60 -0
- package/dist/esm/knowledge/context_loader.js +85 -0
- package/dist/esm/knowledge/failure_history.js +121 -0
- package/dist/esm/knowledge/kg_bridge.js +381 -0
- package/dist/esm/knowledge/kg_types.js +3 -0
- package/dist/esm/knowledge/route_families.js +393 -0
- package/dist/esm/knowledge/spec_index.js +122 -0
- package/dist/esm/logger.js +115 -0
- package/dist/esm/mcp-server.js +621 -0
- package/dist/esm/metrics/prometheus.js +149 -0
- package/dist/esm/model_router.js +59 -0
- package/dist/esm/ollama_provider.js +301 -0
- package/dist/esm/openai_provider.js +243 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/pipeline/orchestrator.js +228 -0
- package/dist/esm/pipeline/spec_verifier.js +75 -0
- package/dist/esm/pipeline/stage0_preprocess.js +102 -0
- package/dist/esm/pipeline/stage1_impact.js +140 -0
- package/dist/esm/pipeline/stage2_coverage.js +153 -0
- package/dist/esm/pipeline/stage3_generation.js +284 -0
- package/dist/esm/pipeline/stage4_heal.js +288 -0
- package/dist/esm/progress.js +112 -0
- package/dist/esm/prompts/coverage.js +57 -0
- package/dist/esm/prompts/cross-impact.js +53 -0
- package/dist/esm/prompts/generation.js +297 -0
- package/dist/esm/prompts/generation_profile.js +147 -0
- package/dist/esm/prompts/heal.js +91 -0
- package/dist/esm/prompts/impact.js +63 -0
- package/dist/esm/prompts/json_extract.js +36 -0
- package/dist/esm/prompts/strategist.js +61 -0
- package/dist/esm/prompts/test-designer.js +92 -0
- package/dist/esm/provider_factory.js +366 -0
- package/dist/esm/provider_interface.js +23 -0
- package/dist/esm/provider_utils.js +96 -0
- package/dist/esm/qa-agent/cli.js +205 -0
- package/dist/esm/qa-agent/orchestrator.js +120 -0
- package/dist/esm/qa-agent/phase1/runner.js +139 -0
- package/dist/esm/qa-agent/phase1/scope.js +126 -0
- package/dist/esm/qa-agent/phase2/agent_browser.js +95 -0
- package/dist/esm/qa-agent/phase2/agent_loop.js +351 -0
- package/dist/esm/qa-agent/phase2/exploration_state.js +97 -0
- package/dist/esm/qa-agent/phase2/tools.js +386 -0
- package/dist/esm/qa-agent/phase2/vision.js +75 -0
- package/dist/esm/qa-agent/phase3/feedback.js +34 -0
- package/dist/esm/qa-agent/phase3/reporter.js +145 -0
- package/dist/esm/qa-agent/phase3/spec_generator.js +62 -0
- package/dist/esm/qa-agent/phase3/verdict.js +66 -0
- package/dist/esm/qa-agent/safe_env.js +23 -0
- package/dist/esm/qa-agent/types.js +3 -0
- package/dist/esm/reporters/junit.js +86 -0
- package/dist/esm/reporters/reporter.js +3 -0
- package/dist/esm/reporters/sarif.js +132 -0
- package/dist/esm/resilience/circuit_breaker.js +78 -0
- package/dist/esm/resilience/retry.js +56 -0
- package/dist/esm/sanitize.js +66 -0
- package/dist/esm/training/enricher.js +345 -0
- package/dist/esm/training/kg_scanner.js +115 -0
- package/dist/esm/training/merger.js +204 -0
- package/dist/esm/training/scanner.js +923 -0
- package/dist/esm/training/types.js +6 -0
- package/dist/esm/training/validator.js +254 -0
- package/dist/esm/validation/guardrails.js +101 -0
- package/dist/esm/validation/output_schema.js +80 -0
- package/dist/esm/version.js +33 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +169 -0
- package/dist/knowledge/api_surface.d.ts +37 -0
- package/dist/knowledge/api_surface.d.ts.map +1 -0
- package/dist/knowledge/api_surface.js +418 -0
- package/dist/knowledge/cluster_utils.d.ts +28 -0
- package/dist/knowledge/cluster_utils.d.ts.map +1 -0
- package/dist/knowledge/cluster_utils.js +67 -0
- package/dist/knowledge/context_loader.d.ts +13 -0
- package/dist/knowledge/context_loader.d.ts.map +1 -0
- package/dist/knowledge/context_loader.js +90 -0
- package/dist/knowledge/failure_history.d.ts +39 -0
- package/dist/knowledge/failure_history.d.ts.map +1 -0
- package/dist/knowledge/failure_history.js +128 -0
- package/dist/knowledge/kg_bridge.d.ts +31 -0
- package/dist/knowledge/kg_bridge.d.ts.map +1 -0
- package/dist/knowledge/kg_bridge.js +388 -0
- package/dist/knowledge/kg_types.d.ts +75 -0
- package/dist/knowledge/kg_types.d.ts.map +1 -0
- package/dist/knowledge/kg_types.js +4 -0
- package/dist/knowledge/route_families.d.ts +98 -0
- package/dist/knowledge/route_families.d.ts.map +1 -0
- package/dist/knowledge/route_families.js +410 -0
- package/dist/knowledge/spec_index.d.ts +18 -0
- package/dist/knowledge/spec_index.d.ts.map +1 -0
- package/dist/knowledge/spec_index.js +128 -0
- package/dist/logger.d.ts +31 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +119 -0
- package/dist/mcp-server.d.ts +68 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +629 -0
- package/dist/metrics/prometheus.d.ts +37 -0
- package/dist/metrics/prometheus.d.ts.map +1 -0
- package/dist/metrics/prometheus.js +153 -0
- package/dist/model_router.d.ts +28 -0
- package/dist/model_router.d.ts.map +1 -0
- package/dist/model_router.js +63 -0
- package/dist/ollama_provider.d.ts +65 -0
- package/dist/ollama_provider.d.ts.map +1 -0
- package/dist/ollama_provider.js +309 -0
- package/dist/openai_provider.d.ts +23 -0
- package/dist/openai_provider.d.ts.map +1 -0
- package/dist/openai_provider.js +251 -0
- package/dist/pipeline/orchestrator.d.ts +33 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -0
- package/dist/pipeline/orchestrator.js +231 -0
- package/dist/pipeline/spec_verifier.d.ts +20 -0
- package/dist/pipeline/spec_verifier.d.ts.map +1 -0
- package/dist/pipeline/spec_verifier.js +79 -0
- package/dist/pipeline/stage0_preprocess.d.ts +31 -0
- package/dist/pipeline/stage0_preprocess.d.ts.map +1 -0
- package/dist/pipeline/stage0_preprocess.js +105 -0
- package/dist/pipeline/stage1_impact.d.ts +19 -0
- package/dist/pipeline/stage1_impact.d.ts.map +1 -0
- package/dist/pipeline/stage1_impact.js +143 -0
- package/dist/pipeline/stage2_coverage.d.ts +19 -0
- package/dist/pipeline/stage2_coverage.d.ts.map +1 -0
- package/dist/pipeline/stage2_coverage.js +156 -0
- package/dist/pipeline/stage3_generation.d.ts +43 -0
- package/dist/pipeline/stage3_generation.d.ts.map +1 -0
- package/dist/pipeline/stage3_generation.js +287 -0
- package/dist/pipeline/stage4_heal.d.ts +62 -0
- package/dist/pipeline/stage4_heal.d.ts.map +1 -0
- package/dist/pipeline/stage4_heal.js +294 -0
- package/dist/progress.d.ts +22 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +116 -0
- package/dist/prompts/coverage.d.ts +39 -0
- package/dist/prompts/coverage.d.ts.map +1 -0
- package/dist/prompts/coverage.js +61 -0
- package/dist/prompts/cross-impact.d.ts +23 -0
- package/dist/prompts/cross-impact.d.ts.map +1 -0
- package/dist/prompts/cross-impact.js +57 -0
- package/dist/prompts/generation.d.ts +25 -0
- package/dist/prompts/generation.d.ts.map +1 -0
- package/dist/prompts/generation.js +302 -0
- package/dist/prompts/generation_profile.d.ts +29 -0
- package/dist/prompts/generation_profile.d.ts.map +1 -0
- package/dist/prompts/generation_profile.js +151 -0
- package/dist/prompts/heal.d.ts +23 -0
- package/dist/prompts/heal.d.ts.map +1 -0
- package/dist/prompts/heal.js +95 -0
- package/dist/prompts/impact.d.ts +31 -0
- package/dist/prompts/impact.d.ts.map +1 -0
- package/dist/prompts/impact.js +67 -0
- package/dist/prompts/json_extract.d.ts +14 -0
- package/dist/prompts/json_extract.d.ts.map +1 -0
- package/dist/prompts/json_extract.js +39 -0
- package/dist/prompts/strategist.d.ts +25 -0
- package/dist/prompts/strategist.d.ts.map +1 -0
- package/dist/prompts/strategist.js +65 -0
- package/dist/prompts/test-designer.d.ts +35 -0
- package/dist/prompts/test-designer.d.ts.map +1 -0
- package/dist/prompts/test-designer.js +96 -0
- package/dist/provider_factory.d.ts +104 -0
- package/dist/provider_factory.d.ts.map +1 -0
- package/dist/provider_factory.js +371 -0
- package/dist/provider_interface.d.ts +365 -0
- package/dist/provider_interface.d.ts.map +1 -0
- package/dist/provider_interface.js +28 -0
- package/dist/provider_utils.d.ts +39 -0
- package/dist/provider_utils.d.ts.map +1 -0
- package/dist/provider_utils.js +103 -0
- package/dist/qa-agent/cli.d.ts +3 -0
- package/dist/qa-agent/cli.d.ts.map +1 -0
- package/dist/qa-agent/cli.js +207 -0
- package/dist/qa-agent/orchestrator.d.ts +3 -0
- package/dist/qa-agent/orchestrator.d.ts.map +1 -0
- package/dist/qa-agent/orchestrator.js +123 -0
- package/dist/qa-agent/phase1/runner.d.ts +3 -0
- package/dist/qa-agent/phase1/runner.d.ts.map +1 -0
- package/dist/qa-agent/phase1/runner.js +142 -0
- package/dist/qa-agent/phase1/scope.d.ts +6 -0
- package/dist/qa-agent/phase1/scope.d.ts.map +1 -0
- package/dist/qa-agent/phase1/scope.js +129 -0
- package/dist/qa-agent/phase2/agent_browser.d.ts +35 -0
- package/dist/qa-agent/phase2/agent_browser.d.ts.map +1 -0
- package/dist/qa-agent/phase2/agent_browser.js +99 -0
- package/dist/qa-agent/phase2/agent_loop.d.ts +3 -0
- package/dist/qa-agent/phase2/agent_loop.d.ts.map +1 -0
- package/dist/qa-agent/phase2/agent_loop.js +357 -0
- package/dist/qa-agent/phase2/exploration_state.d.ts +12 -0
- package/dist/qa-agent/phase2/exploration_state.d.ts.map +1 -0
- package/dist/qa-agent/phase2/exploration_state.js +109 -0
- package/dist/qa-agent/phase2/tools.d.ts +28 -0
- package/dist/qa-agent/phase2/tools.d.ts.map +1 -0
- package/dist/qa-agent/phase2/tools.js +390 -0
- package/dist/qa-agent/phase2/vision.d.ts +3 -0
- package/dist/qa-agent/phase2/vision.d.ts.map +1 -0
- package/dist/qa-agent/phase2/vision.js +78 -0
- package/dist/qa-agent/phase3/feedback.d.ts +3 -0
- package/dist/qa-agent/phase3/feedback.d.ts.map +1 -0
- package/dist/qa-agent/phase3/feedback.js +37 -0
- package/dist/qa-agent/phase3/reporter.d.ts +3 -0
- package/dist/qa-agent/phase3/reporter.d.ts.map +1 -0
- package/dist/qa-agent/phase3/reporter.js +148 -0
- package/dist/qa-agent/phase3/spec_generator.d.ts +3 -0
- package/dist/qa-agent/phase3/spec_generator.d.ts.map +1 -0
- package/dist/qa-agent/phase3/spec_generator.js +65 -0
- package/dist/qa-agent/phase3/verdict.d.ts +3 -0
- package/dist/qa-agent/phase3/verdict.d.ts.map +1 -0
- package/dist/qa-agent/phase3/verdict.js +69 -0
- package/dist/qa-agent/safe_env.d.ts +3 -0
- package/dist/qa-agent/safe_env.d.ts.map +1 -0
- package/dist/qa-agent/safe_env.js +26 -0
- package/dist/qa-agent/types.d.ts +130 -0
- package/dist/qa-agent/types.d.ts.map +1 -0
- package/dist/qa-agent/types.js +4 -0
- package/dist/reporters/junit.d.ts +6 -0
- package/dist/reporters/junit.d.ts.map +1 -0
- package/dist/reporters/junit.js +89 -0
- package/dist/reporters/reporter.d.ts +42 -0
- package/dist/reporters/reporter.d.ts.map +1 -0
- package/dist/reporters/reporter.js +4 -0
- package/dist/reporters/sarif.d.ts +7 -0
- package/dist/reporters/sarif.d.ts.map +1 -0
- package/dist/reporters/sarif.js +135 -0
- package/dist/resilience/circuit_breaker.d.ts +36 -0
- package/dist/resilience/circuit_breaker.d.ts.map +1 -0
- package/dist/resilience/circuit_breaker.js +82 -0
- package/dist/resilience/retry.d.ts +11 -0
- package/dist/resilience/retry.d.ts.map +1 -0
- package/dist/resilience/retry.js +59 -0
- package/dist/sanitize.d.ts +15 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +71 -0
- package/dist/training/enricher.d.ts +17 -0
- package/dist/training/enricher.d.ts.map +1 -0
- package/dist/training/enricher.js +350 -0
- package/dist/training/kg_scanner.d.ts +13 -0
- package/dist/training/kg_scanner.d.ts.map +1 -0
- package/dist/training/kg_scanner.js +118 -0
- package/dist/training/merger.d.ts +15 -0
- package/dist/training/merger.d.ts.map +1 -0
- package/dist/training/merger.js +208 -0
- package/dist/training/scanner.d.ts +36 -0
- package/dist/training/scanner.d.ts.map +1 -0
- package/dist/training/scanner.js +932 -0
- package/dist/training/types.d.ts +117 -0
- package/dist/training/types.d.ts.map +1 -0
- package/dist/training/types.js +9 -0
- package/dist/training/validator.d.ts +21 -0
- package/dist/training/validator.d.ts.map +1 -0
- package/dist/training/validator.js +262 -0
- package/dist/validation/guardrails.d.ts +31 -0
- package/dist/validation/guardrails.d.ts.map +1 -0
- package/dist/validation/guardrails.js +112 -0
- package/dist/validation/output_schema.d.ts +67 -0
- package/dist/validation/output_schema.d.ts.map +1 -0
- package/dist/validation/output_schema.js +84 -0
- package/dist/version.d.ts +6 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +36 -0
- package/package.json +126 -0
- package/schemas/flow-decision.schema.json +83 -0
- package/schemas/gap.schema.json +18 -0
- package/schemas/impact.schema.json +455 -0
- package/schemas/plan.schema.json +491 -0
- package/schemas/route-families.schema.json +137 -0
- package/schemas/subsystem-risk-map.schema.json +62 -0
- package/schemas/traceability-input.schema.json +122 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
3
|
+
// See LICENSE.txt for license information.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.OpenAIProvider = void 0;
|
|
9
|
+
exports.checkOpenAISetup = checkOpenAISetup;
|
|
10
|
+
const openai_1 = __importDefault(require("openai"));
|
|
11
|
+
const provider_interface_js_1 = require("./provider_interface.js");
|
|
12
|
+
const provider_utils_js_1 = require("./provider_utils.js");
|
|
13
|
+
const base_provider_js_1 = require("./base_provider.js");
|
|
14
|
+
const logger_js_1 = require("./logger.js");
|
|
15
|
+
function inferVisionSupport(model) {
|
|
16
|
+
const lower = model.toLowerCase();
|
|
17
|
+
return lower.includes('vision') || lower.includes('4o') || lower.includes('omni');
|
|
18
|
+
}
|
|
19
|
+
class OpenAIProvider extends base_provider_js_1.BaseProvider {
|
|
20
|
+
constructor(config) {
|
|
21
|
+
super();
|
|
22
|
+
this.name = 'openai';
|
|
23
|
+
if (!provider_utils_js_1.API_KEY_PATTERNS.openai.test(config.apiKey)) {
|
|
24
|
+
throw new Error('Invalid API key format. Expected sk-* format.');
|
|
25
|
+
}
|
|
26
|
+
if (config.baseUrl) {
|
|
27
|
+
const validation = (0, provider_utils_js_1.validateAndSanitizeUrl)(config.baseUrl);
|
|
28
|
+
if (!validation.valid) {
|
|
29
|
+
throw new Error(`Invalid base URL: ${validation.warning}`);
|
|
30
|
+
}
|
|
31
|
+
if (validation.warning) {
|
|
32
|
+
logger_js_1.logger.warn(`HTTPS required for remote URLs: ${validation.warning}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
this.client = new openai_1.default({
|
|
36
|
+
apiKey: config.apiKey,
|
|
37
|
+
baseURL: config.baseUrl,
|
|
38
|
+
organization: config.organizationId,
|
|
39
|
+
});
|
|
40
|
+
this.model = config.model || 'gpt-4';
|
|
41
|
+
const maxTokens = config.maxTokens || 128000;
|
|
42
|
+
const costPer1MInputTokens = config.costPer1MInputTokens ?? 0;
|
|
43
|
+
const costPer1MOutputTokens = config.costPer1MOutputTokens ?? 0;
|
|
44
|
+
this.capabilities = {
|
|
45
|
+
vision: inferVisionSupport(this.model),
|
|
46
|
+
streaming: true,
|
|
47
|
+
maxTokens,
|
|
48
|
+
costPer1MInputTokens,
|
|
49
|
+
costPer1MOutputTokens,
|
|
50
|
+
supportsTools: true,
|
|
51
|
+
supportsPromptCaching: false,
|
|
52
|
+
typicalResponseTimeMs: 1200,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
async generateText(prompt, options) {
|
|
56
|
+
this.checkBudget();
|
|
57
|
+
const startTime = Date.now();
|
|
58
|
+
try {
|
|
59
|
+
if (prompt.length > 10 * 1024 * 1024) {
|
|
60
|
+
throw new Error('Prompt exceeds maximum size (10MB)');
|
|
61
|
+
}
|
|
62
|
+
const messages = [];
|
|
63
|
+
if (options?.systemPrompt) {
|
|
64
|
+
messages.push({ role: 'system', content: options.systemPrompt });
|
|
65
|
+
}
|
|
66
|
+
messages.push({ role: 'user', content: prompt });
|
|
67
|
+
const response = await (0, provider_utils_js_1.withTimeout)(this.client.chat.completions.create({
|
|
68
|
+
model: this.model,
|
|
69
|
+
messages,
|
|
70
|
+
max_tokens: options?.maxTokens,
|
|
71
|
+
temperature: options?.temperature,
|
|
72
|
+
top_p: options?.topP,
|
|
73
|
+
stop: options?.stopSequences,
|
|
74
|
+
}), options?.timeout, 'generateText');
|
|
75
|
+
const responseTime = Date.now() - startTime;
|
|
76
|
+
const text = response.choices[0]?.message?.content || '';
|
|
77
|
+
const usage = this.extractUsage(response.usage);
|
|
78
|
+
const cost = this.calculateCost(usage, this.capabilities.costPer1MInputTokens, this.capabilities.costPer1MOutputTokens);
|
|
79
|
+
this.updateStats(usage, responseTime, cost);
|
|
80
|
+
return {
|
|
81
|
+
text,
|
|
82
|
+
usage,
|
|
83
|
+
cost,
|
|
84
|
+
metadata: {
|
|
85
|
+
model: this.model,
|
|
86
|
+
responseTimeMs: responseTime,
|
|
87
|
+
finishReason: response.choices[0]?.finish_reason,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
this.stats.failedRequests++;
|
|
93
|
+
throw new provider_interface_js_1.LLMProviderError((0, provider_utils_js_1.sanitizeErrorMessage)(error, 'generateText'), this.name, this.extractStatusCode(error), error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async analyzeImage(images, prompt, options) {
|
|
97
|
+
if (!this.capabilities.vision) {
|
|
98
|
+
throw new provider_interface_js_1.UnsupportedCapabilityError(this.name, 'vision');
|
|
99
|
+
}
|
|
100
|
+
const startTime = Date.now();
|
|
101
|
+
try {
|
|
102
|
+
if (images.length === 0 || images.length > 20) {
|
|
103
|
+
throw new Error('Image count must be between 1 and 20');
|
|
104
|
+
}
|
|
105
|
+
if (prompt.length > 10 * 1024 * 1024) {
|
|
106
|
+
throw new Error('Prompt exceeds maximum size (10MB)');
|
|
107
|
+
}
|
|
108
|
+
const content = [{ type: 'text', text: prompt }];
|
|
109
|
+
for (const image of images) {
|
|
110
|
+
const mediaType = (image.mimeType || image.mediaType || 'image/png');
|
|
111
|
+
if (!['image/png', 'image/jpeg', 'image/webp'].includes(mediaType)) {
|
|
112
|
+
throw new Error(`Unsupported image type: ${mediaType}`);
|
|
113
|
+
}
|
|
114
|
+
const data = image.data || image.base64 || '';
|
|
115
|
+
if (data.length > 20 * 1024 * 1024) {
|
|
116
|
+
throw new Error('Image data exceeds maximum size (20MB)');
|
|
117
|
+
}
|
|
118
|
+
const url = `data:${mediaType};base64,${data}`;
|
|
119
|
+
content.push({ type: 'image_url', image_url: { url } });
|
|
120
|
+
if (image.description) {
|
|
121
|
+
content.push({ type: 'text', text: `[Image: ${image.description}]` });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const messages = [];
|
|
125
|
+
if (options?.systemPrompt) {
|
|
126
|
+
messages.push({ role: 'system', content: options.systemPrompt });
|
|
127
|
+
}
|
|
128
|
+
messages.push({ role: 'user', content });
|
|
129
|
+
const response = await (0, provider_utils_js_1.withTimeout)(this.client.chat.completions.create({
|
|
130
|
+
model: this.model,
|
|
131
|
+
messages,
|
|
132
|
+
max_tokens: options?.maxTokens,
|
|
133
|
+
temperature: options?.temperature,
|
|
134
|
+
top_p: options?.topP,
|
|
135
|
+
stop: options?.stopSequences,
|
|
136
|
+
}), options?.timeout, 'analyzeImage');
|
|
137
|
+
const responseTime = Date.now() - startTime;
|
|
138
|
+
const text = response.choices[0]?.message?.content || '';
|
|
139
|
+
const usage = this.extractUsage(response.usage);
|
|
140
|
+
const cost = this.calculateCost(usage, this.capabilities.costPer1MInputTokens, this.capabilities.costPer1MOutputTokens);
|
|
141
|
+
this.updateStats(usage, responseTime, cost);
|
|
142
|
+
return {
|
|
143
|
+
text,
|
|
144
|
+
usage,
|
|
145
|
+
cost,
|
|
146
|
+
metadata: {
|
|
147
|
+
model: this.model,
|
|
148
|
+
responseTimeMs: responseTime,
|
|
149
|
+
finishReason: response.choices[0]?.finish_reason,
|
|
150
|
+
imageCount: images.length,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
this.stats.failedRequests++;
|
|
156
|
+
throw new provider_interface_js_1.LLMProviderError((0, provider_utils_js_1.sanitizeErrorMessage)(error, 'analyzeImage'), this.name, this.extractStatusCode(error), error);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async *streamText(prompt, options) {
|
|
160
|
+
try {
|
|
161
|
+
if (prompt.length > 10 * 1024 * 1024) {
|
|
162
|
+
throw new Error('Prompt exceeds maximum size (10MB)');
|
|
163
|
+
}
|
|
164
|
+
const messages = [];
|
|
165
|
+
if (options?.systemPrompt) {
|
|
166
|
+
messages.push({ role: 'system', content: options.systemPrompt });
|
|
167
|
+
}
|
|
168
|
+
messages.push({ role: 'user', content: prompt });
|
|
169
|
+
const stream = await (0, provider_utils_js_1.withTimeout)(this.client.chat.completions.create({
|
|
170
|
+
model: this.model,
|
|
171
|
+
messages,
|
|
172
|
+
max_tokens: options?.maxTokens,
|
|
173
|
+
temperature: options?.temperature,
|
|
174
|
+
top_p: options?.topP,
|
|
175
|
+
stop: options?.stopSequences,
|
|
176
|
+
stream: true,
|
|
177
|
+
}), options?.timeout, 'streamText');
|
|
178
|
+
for await (const chunk of stream) {
|
|
179
|
+
const content = chunk.choices[0]?.delta?.content;
|
|
180
|
+
if (content) {
|
|
181
|
+
yield content;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
this.stats.requestCount++;
|
|
185
|
+
this.stats.lastUpdated = new Date();
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
this.stats.failedRequests++;
|
|
189
|
+
throw new provider_interface_js_1.LLMProviderError((0, provider_utils_js_1.sanitizeErrorMessage)(error, 'streamText'), this.name, this.extractStatusCode(error), error);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
extractUsage(usage) {
|
|
193
|
+
return {
|
|
194
|
+
inputTokens: usage?.prompt_tokens || 0,
|
|
195
|
+
outputTokens: usage?.completion_tokens || 0,
|
|
196
|
+
totalTokens: usage?.total_tokens || 0,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
extractStatusCode(error) {
|
|
200
|
+
if (error && typeof error === 'object') {
|
|
201
|
+
const err = error;
|
|
202
|
+
const status = err.status;
|
|
203
|
+
if (typeof status === 'number') {
|
|
204
|
+
return status;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
async checkHealth() {
|
|
210
|
+
try {
|
|
211
|
+
await (0, provider_utils_js_1.withTimeout)(this.client.chat.completions.create({
|
|
212
|
+
model: this.model,
|
|
213
|
+
max_tokens: 5,
|
|
214
|
+
messages: [{ role: 'user', content: 'Hi' }],
|
|
215
|
+
}), 5000, 'health check');
|
|
216
|
+
return {
|
|
217
|
+
healthy: true,
|
|
218
|
+
message: 'OpenAI API is accessible',
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
return {
|
|
223
|
+
healthy: false,
|
|
224
|
+
message: `OpenAI API error: ${(0, provider_utils_js_1.sanitizeErrorMessage)(error, 'health check')}`,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
exports.OpenAIProvider = OpenAIProvider;
|
|
230
|
+
async function checkOpenAISetup(apiKey) {
|
|
231
|
+
if (!apiKey) {
|
|
232
|
+
return {
|
|
233
|
+
valid: false,
|
|
234
|
+
message: 'No API key provided',
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
const provider = new OpenAIProvider({ apiKey });
|
|
239
|
+
const health = await provider.checkHealth();
|
|
240
|
+
return {
|
|
241
|
+
valid: health.healthy,
|
|
242
|
+
message: health.message,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
return {
|
|
247
|
+
valid: false,
|
|
248
|
+
message: `Setup check failed: ${(0, provider_utils_js_1.sanitizeErrorMessage)(error, 'setup check')}`,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ImpactConfig } from './stage1_impact.js';
|
|
2
|
+
import { type CoverageConfig } from './stage2_coverage.js';
|
|
3
|
+
import { type GenerationConfig, type GeneratedSpec } from './stage3_generation.js';
|
|
4
|
+
import { type HealConfig, type HealResult } from './stage4_heal.js';
|
|
5
|
+
import { type FlowDecisionReport } from '../validation/output_schema.js';
|
|
6
|
+
import type { RouteFamilyConfig } from '../knowledge/route_families.js';
|
|
7
|
+
import type { ApiSurfaceConfig } from '../knowledge/api_surface.js';
|
|
8
|
+
import type { GenerationProfile } from '../prompts/generation_profile.js';
|
|
9
|
+
export interface PipelineConfig {
|
|
10
|
+
appPath: string;
|
|
11
|
+
testsRoot: string;
|
|
12
|
+
gitSince: string;
|
|
13
|
+
gitIncludeUncommitted?: boolean;
|
|
14
|
+
routeFamilies?: RouteFamilyConfig;
|
|
15
|
+
apiSurface?: ApiSurfaceConfig;
|
|
16
|
+
profile?: GenerationProfile;
|
|
17
|
+
impact?: ImpactConfig;
|
|
18
|
+
coverage?: CoverageConfig;
|
|
19
|
+
generation?: GenerationConfig;
|
|
20
|
+
heal?: HealConfig;
|
|
21
|
+
/** Path to a Playwright JSON report for heal-from-report mode */
|
|
22
|
+
playwrightReportPath?: string;
|
|
23
|
+
stages?: Array<'preprocess' | 'impact' | 'coverage' | 'generation' | 'heal'>;
|
|
24
|
+
}
|
|
25
|
+
export interface PipelineResult {
|
|
26
|
+
report: FlowDecisionReport;
|
|
27
|
+
reportPath: string;
|
|
28
|
+
warnings: string[];
|
|
29
|
+
generated?: GeneratedSpec[];
|
|
30
|
+
healResult?: HealResult;
|
|
31
|
+
}
|
|
32
|
+
export declare function runPipeline(config: PipelineConfig): Promise<PipelineResult>;
|
|
33
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/pipeline/orchestrator.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,KAAK,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAmB,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAqB,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAC,MAAM,wBAAwB,CAAC;AACrG,OAAO,EAAuD,KAAK,UAAU,EAAE,KAAK,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACxH,OAAO,EAAe,KAAK,kBAAkB,EAAoB,MAAM,gCAAgC,CAAC;AAExG,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,kCAAkC,CAAC;AAGxE,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iEAAiE;IACjE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC,CAAC;CAChF;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;CAC3B;AAYD,wBAAsB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CA8IjF"}
|
|
@@ -0,0 +1,231 @@
|
|
|
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.runPipeline = runPipeline;
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const git_js_1 = require("../agent/git.js");
|
|
9
|
+
const logger_js_1 = require("../logger.js");
|
|
10
|
+
const stage0_preprocess_js_1 = require("./stage0_preprocess.js");
|
|
11
|
+
const stage1_impact_js_1 = require("./stage1_impact.js");
|
|
12
|
+
const stage2_coverage_js_1 = require("./stage2_coverage.js");
|
|
13
|
+
const stage3_generation_js_1 = require("./stage3_generation.js");
|
|
14
|
+
const stage4_heal_js_1 = require("./stage4_heal.js");
|
|
15
|
+
const output_schema_js_1 = require("../validation/output_schema.js");
|
|
16
|
+
const guardrails_js_1 = require("../validation/guardrails.js");
|
|
17
|
+
const generation_profile_js_1 = require("../prompts/generation_profile.js");
|
|
18
|
+
function createRunId() {
|
|
19
|
+
const ciRunId = process.env.GITHUB_RUN_ID;
|
|
20
|
+
const entropy = Math.random().toString(36).slice(2, 8);
|
|
21
|
+
const ts = Date.now().toString(36);
|
|
22
|
+
if (ciRunId) {
|
|
23
|
+
return `pipeline-gh-${ciRunId}-${ts}-${entropy}`;
|
|
24
|
+
}
|
|
25
|
+
return `pipeline-local-${ts}-${entropy}`;
|
|
26
|
+
}
|
|
27
|
+
async function runPipeline(config) {
|
|
28
|
+
const runId = createRunId();
|
|
29
|
+
const startedAt = new Date().toISOString();
|
|
30
|
+
const allWarnings = [];
|
|
31
|
+
const stages = config.stages || ['preprocess', 'impact', 'coverage'];
|
|
32
|
+
const profile = config.profile || (0, generation_profile_js_1.resolveGenerationProfile)();
|
|
33
|
+
let generatedSpecs;
|
|
34
|
+
let healResult;
|
|
35
|
+
// Step 1: Get changed files
|
|
36
|
+
const gitResult = (0, git_js_1.getChangedFiles)(config.appPath, config.gitSince, {
|
|
37
|
+
includeUncommitted: config.gitIncludeUncommitted,
|
|
38
|
+
});
|
|
39
|
+
if (gitResult.error) {
|
|
40
|
+
allWarnings.push(`Git diff warning: ${gitResult.error}`);
|
|
41
|
+
}
|
|
42
|
+
const changedFiles = gitResult.files
|
|
43
|
+
.map((f) => f.replace(/\\/g, '/'))
|
|
44
|
+
.filter((f) => !(0, git_js_1.isTestFile)(f));
|
|
45
|
+
if (changedFiles.length === 0) {
|
|
46
|
+
allWarnings.push('No changed application files detected.');
|
|
47
|
+
const emptyReport = {
|
|
48
|
+
runId,
|
|
49
|
+
timestamp: startedAt,
|
|
50
|
+
gitRef: config.gitSince,
|
|
51
|
+
summary: (0, output_schema_js_1.buildSummary)([]),
|
|
52
|
+
decisions: [],
|
|
53
|
+
warnings: allWarnings,
|
|
54
|
+
model: {},
|
|
55
|
+
};
|
|
56
|
+
const reportPath = writeReport(config.testsRoot, emptyReport);
|
|
57
|
+
return { report: emptyReport, reportPath, warnings: allWarnings };
|
|
58
|
+
}
|
|
59
|
+
const timings = {};
|
|
60
|
+
// Step 2: Preprocess — deterministic file classification + route family binding
|
|
61
|
+
const preprocessTimer = logger_js_1.logger.timer('preprocess');
|
|
62
|
+
const preprocessResult = (0, stage0_preprocess_js_1.preprocess)(changedFiles, {
|
|
63
|
+
appPath: config.appPath,
|
|
64
|
+
testsRoot: config.testsRoot,
|
|
65
|
+
routeFamilies: config.routeFamilies,
|
|
66
|
+
apiSurface: config.apiSurface,
|
|
67
|
+
});
|
|
68
|
+
timings.preprocess = preprocessTimer.end();
|
|
69
|
+
allWarnings.push(...preprocessResult.warnings);
|
|
70
|
+
let decisions = [];
|
|
71
|
+
// Step 3: Impact stage — AI-powered flow identification per family
|
|
72
|
+
if (stages.includes('impact')) {
|
|
73
|
+
const impactTimer = logger_js_1.logger.timer('impact');
|
|
74
|
+
const impactResult = await (0, stage1_impact_js_1.runImpactStage)(preprocessResult.familyGroups, preprocessResult.manifest, preprocessResult.specIndex, preprocessResult.apiSurface, preprocessResult.context, config.impact || {});
|
|
75
|
+
decisions = impactResult.decisions;
|
|
76
|
+
allWarnings.push(...impactResult.warnings);
|
|
77
|
+
timings.impact = impactTimer.end();
|
|
78
|
+
// Check cannot_determine ratio
|
|
79
|
+
const cannotDetermineRatio = (0, guardrails_js_1.computeCannotDetermineRatio)(decisions);
|
|
80
|
+
if (cannotDetermineRatio > 0.3) {
|
|
81
|
+
allWarnings.push(`High cannot_determine ratio (${(cannotDetermineRatio * 100).toFixed(0)}%). Consider updating route-families.json or running with MCP exploration.`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Step 4: Coverage stage — AI-powered spec coverage evaluation
|
|
85
|
+
if (stages.includes('coverage') && decisions.length > 0) {
|
|
86
|
+
const coverageTimer = logger_js_1.logger.timer('coverage');
|
|
87
|
+
const coverageResult = await (0, stage2_coverage_js_1.runCoverageStage)(decisions, preprocessResult.specIndex, preprocessResult.context, config.testsRoot, { ...(config.coverage || {}), profile });
|
|
88
|
+
decisions = coverageResult.decisions;
|
|
89
|
+
timings.coverage = coverageTimer.end();
|
|
90
|
+
allWarnings.push(...coverageResult.warnings);
|
|
91
|
+
}
|
|
92
|
+
// Step 5: Generation stage — AI-powered spec generation for create_spec / add_scenarios
|
|
93
|
+
if (stages.includes('generation') && decisions.length > 0) {
|
|
94
|
+
const generationTimer = logger_js_1.logger.timer('generation');
|
|
95
|
+
const generationResult = await (0, stage3_generation_js_1.runGenerationStage)(decisions, preprocessResult.apiSurface, config.testsRoot, { ...(config.generation || {}), profile });
|
|
96
|
+
generatedSpecs = generationResult.generated;
|
|
97
|
+
timings.generation = generationTimer.end();
|
|
98
|
+
allWarnings.push(...generationResult.warnings);
|
|
99
|
+
}
|
|
100
|
+
// Step 6: Heal stage — MCP-backed playwright-test-healer for failing/flaky specs
|
|
101
|
+
if (stages.includes('heal')) {
|
|
102
|
+
const healTimer = logger_js_1.logger.timer('heal');
|
|
103
|
+
const healTargets = (0, stage4_heal_js_1.resolveHealTargets)(config.testsRoot, {
|
|
104
|
+
playwrightReportPath: config.playwrightReportPath,
|
|
105
|
+
generatedSpecs,
|
|
106
|
+
}, decisions);
|
|
107
|
+
if (healTargets.length > 0) {
|
|
108
|
+
healResult = await (0, stage4_heal_js_1.runHealStage)(config.testsRoot, healTargets, { ...(config.heal || { mcp: true }), profile });
|
|
109
|
+
allWarnings.push(...healResult.warnings);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
allWarnings.push('Heal stage: no targets found (no failing specs in report, no generated specs).');
|
|
113
|
+
}
|
|
114
|
+
timings.heal = healTimer.end();
|
|
115
|
+
}
|
|
116
|
+
// Build report
|
|
117
|
+
const report = {
|
|
118
|
+
runId,
|
|
119
|
+
timestamp: startedAt,
|
|
120
|
+
gitRef: config.gitSince,
|
|
121
|
+
summary: (0, output_schema_js_1.buildSummary)(decisions),
|
|
122
|
+
decisions,
|
|
123
|
+
warnings: allWarnings,
|
|
124
|
+
model: {
|
|
125
|
+
impactAgent: config.impact?.provider || 'auto',
|
|
126
|
+
coverageAgent: config.coverage?.provider || 'auto',
|
|
127
|
+
generationAgent: stages.includes('generation') ? (config.generation?.provider || 'auto') : undefined,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
const reportPath = writeReport(config.testsRoot, report, healResult, timings);
|
|
131
|
+
return { report, reportPath, warnings: allWarnings, generated: generatedSpecs, healResult };
|
|
132
|
+
}
|
|
133
|
+
function writeReport(testsRoot, report, healResult, timings) {
|
|
134
|
+
const outputDir = (0, path_1.join)(testsRoot, '.e2e-ai-agents');
|
|
135
|
+
if (!(0, fs_1.existsSync)(outputDir)) {
|
|
136
|
+
(0, fs_1.mkdirSync)(outputDir, { recursive: true });
|
|
137
|
+
}
|
|
138
|
+
// Include timings in the JSON report if available
|
|
139
|
+
const reportWithTimings = timings ? { ...report, timings } : report;
|
|
140
|
+
const jsonPath = (0, path_1.join)(outputDir, 'pipeline-report.json');
|
|
141
|
+
(0, fs_1.writeFileSync)(jsonPath, JSON.stringify(reportWithTimings, null, 2), 'utf-8');
|
|
142
|
+
const mdPath = (0, path_1.join)(outputDir, 'pipeline-report.md');
|
|
143
|
+
(0, fs_1.writeFileSync)(mdPath, renderMarkdown(report, healResult), 'utf-8');
|
|
144
|
+
return jsonPath;
|
|
145
|
+
}
|
|
146
|
+
function renderMarkdown(report, healResult) {
|
|
147
|
+
const lines = [
|
|
148
|
+
`# Impact Analysis Pipeline Report`,
|
|
149
|
+
'',
|
|
150
|
+
`**Run ID:** ${report.runId}`,
|
|
151
|
+
`**Timestamp:** ${report.timestamp}`,
|
|
152
|
+
`**Git Ref:** ${report.gitRef}`,
|
|
153
|
+
'',
|
|
154
|
+
`## Summary`,
|
|
155
|
+
'',
|
|
156
|
+
`| Metric | Value |`,
|
|
157
|
+
`|--------|-------|`,
|
|
158
|
+
`| Changed Files | ${report.summary.changedFiles} |`,
|
|
159
|
+
`| Route Families Impacted | ${report.summary.routeFamiliesImpacted.join(', ') || 'none'} |`,
|
|
160
|
+
`| Flows Identified | ${report.summary.flowsIdentified} |`,
|
|
161
|
+
`| Covered | ${report.summary.flowsCovered} |`,
|
|
162
|
+
`| Partial | ${report.summary.flowsPartial} |`,
|
|
163
|
+
`| Uncovered | ${report.summary.flowsUncovered} |`,
|
|
164
|
+
`| Cannot Determine | ${report.summary.actionsRequired.cannot_determine} |`,
|
|
165
|
+
`| Overall Confidence | ${report.summary.overallConfidence} |`,
|
|
166
|
+
'',
|
|
167
|
+
];
|
|
168
|
+
if (report.decisions.length > 0) {
|
|
169
|
+
lines.push('## Decisions', '');
|
|
170
|
+
for (const d of report.decisions) {
|
|
171
|
+
lines.push(`### ${d.flowName} (${d.priority})`);
|
|
172
|
+
lines.push('');
|
|
173
|
+
lines.push(`- **Action:** ${d.action}`);
|
|
174
|
+
lines.push(`- **Route Family:** ${d.routeFamily}${d.featureId ? ` / ${d.featureId}` : ''}`);
|
|
175
|
+
if (d.specificRoute) {
|
|
176
|
+
lines.push(`- **Route:** ${d.specificRoute}`);
|
|
177
|
+
}
|
|
178
|
+
lines.push(`- **Confidence:** ${d.confidence}%`);
|
|
179
|
+
lines.push(`- **Evidence:** ${d.evidence}`);
|
|
180
|
+
lines.push(`- **Changed Files:** ${d.changedFiles.join(', ')}`);
|
|
181
|
+
if (d.userActions.length > 0) {
|
|
182
|
+
lines.push(`- **User Actions:** ${d.userActions.join('; ')}`);
|
|
183
|
+
}
|
|
184
|
+
if (d.existingSpecs.length > 0) {
|
|
185
|
+
lines.push('- **Existing Coverage:**');
|
|
186
|
+
for (const spec of d.existingSpecs) {
|
|
187
|
+
lines.push(` - ${spec.path} (${spec.coverageLevel})`);
|
|
188
|
+
if (spec.testTitles.length > 0) {
|
|
189
|
+
for (const title of spec.testTitles) {
|
|
190
|
+
lines.push(` - \`${title}\``);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (spec.missingScenarios && spec.missingScenarios.length > 0) {
|
|
194
|
+
lines.push(' - Missing:');
|
|
195
|
+
for (const scenario of spec.missingScenarios) {
|
|
196
|
+
lines.push(` - ${scenario}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (d.scenariosToAdd && d.scenariosToAdd.length > 0) {
|
|
202
|
+
lines.push('- **Scenarios to Add:**');
|
|
203
|
+
for (const s of d.scenariosToAdd) {
|
|
204
|
+
lines.push(` - ${s}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (d.targetSpec) {
|
|
208
|
+
lines.push(`- **Target Spec:** ${d.targetSpec}`);
|
|
209
|
+
}
|
|
210
|
+
if (d.newSpecPath) {
|
|
211
|
+
lines.push(`- **New Spec Path:** ${d.newSpecPath}`);
|
|
212
|
+
}
|
|
213
|
+
if (d.blockingReason) {
|
|
214
|
+
lines.push(`- **Blocking Reason:** ${d.blockingReason}`);
|
|
215
|
+
}
|
|
216
|
+
lines.push('');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (healResult) {
|
|
220
|
+
lines.push('');
|
|
221
|
+
lines.push((0, stage4_heal_js_1.renderHealMarkdown)(healResult));
|
|
222
|
+
}
|
|
223
|
+
if (report.warnings.length > 0) {
|
|
224
|
+
lines.push('## Warnings', '');
|
|
225
|
+
for (const w of report.warnings) {
|
|
226
|
+
lines.push(`- ${w}`);
|
|
227
|
+
}
|
|
228
|
+
lines.push('');
|
|
229
|
+
}
|
|
230
|
+
return lines.join('\n');
|
|
231
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface CompileCheckResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
errors: string[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Compile-check a generated spec file using tsc --noEmit.
|
|
7
|
+
* Returns success: true if compilation succeeds, or errors array on failure.
|
|
8
|
+
*/
|
|
9
|
+
export declare function compileCheckSpec(specPath: string, testsRoot: string): CompileCheckResult;
|
|
10
|
+
export interface SmokeRunResult {
|
|
11
|
+
success: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Smoke-run a generated spec against a running app.
|
|
16
|
+
* Runs in a restricted environment with sensitive env vars stripped.
|
|
17
|
+
* Returns success: true if the test passes with retries.
|
|
18
|
+
*/
|
|
19
|
+
export declare function smokeRunSpec(specPath: string, testsRoot: string, playwrightBinary: string): SmokeRunResult;
|
|
20
|
+
//# sourceMappingURL=spec_verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec_verifier.d.ts","sourceRoot":"","sources":["../../src/pipeline/spec_verifier.ts"],"names":[],"mappings":"AAyCA,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAuBxF;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CACxB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACzB,cAAc,CAuBhB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
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.compileCheckSpec = compileCheckSpec;
|
|
6
|
+
exports.smokeRunSpec = smokeRunSpec;
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const process_runner_js_1 = require("../agent/process_runner.js");
|
|
9
|
+
/** Env var prefixes/names stripped when running LLM-generated specs */
|
|
10
|
+
const SENSITIVE_ENV_PREFIXES = [
|
|
11
|
+
'AWS_', 'AZURE_', 'GCP_', 'GOOGLE_', 'ANTHROPIC_', 'OPENAI_',
|
|
12
|
+
'GITHUB_TOKEN', 'NPM_TOKEN', 'SSH_', 'SECRET_', 'PRIVATE_',
|
|
13
|
+
'DATABASE_URL', 'DB_', 'REDIS_', 'POSTGRES_', 'MYSQL_', 'MONGO_',
|
|
14
|
+
'API_KEY', 'API_SECRET', 'AUTH_', 'JWT_', 'STRIPE_', 'TWILIO_',
|
|
15
|
+
'SENDGRID_', 'SLACK_TOKEN', 'SLACK_BOT', 'MATTERMOST_',
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Build a restricted environment for running LLM-generated spec files.
|
|
19
|
+
* Strips credentials and secrets to limit damage from malicious generated code.
|
|
20
|
+
*/
|
|
21
|
+
function buildRestrictedEnv() {
|
|
22
|
+
const env = {};
|
|
23
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
24
|
+
const isSensitive = SENSITIVE_ENV_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
25
|
+
if (!isSensitive) {
|
|
26
|
+
env[key] = value;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return env;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Validate and normalize a spec path to prevent argument injection.
|
|
33
|
+
* Rejects raw input that starts with '-' (could be interpreted as flags by tsc/playwright).
|
|
34
|
+
*/
|
|
35
|
+
function sanitizeSpecPath(specPath) {
|
|
36
|
+
if (specPath.startsWith('-')) {
|
|
37
|
+
throw new Error(`Invalid spec path: "${specPath}" — path must not start with a dash`);
|
|
38
|
+
}
|
|
39
|
+
return (0, path_1.resolve)(specPath);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Compile-check a generated spec file using tsc --noEmit.
|
|
43
|
+
* Returns success: true if compilation succeeds, or errors array on failure.
|
|
44
|
+
*/
|
|
45
|
+
function compileCheckSpec(specPath, testsRoot) {
|
|
46
|
+
const safeSpecPath = sanitizeSpecPath(specPath);
|
|
47
|
+
const result = (0, process_runner_js_1.runCommand)('npx', ['tsc', '--noEmit', '--esModuleInterop', '--resolveJsonModule', '--moduleResolution', 'node', '--target', 'ES2020', safeSpecPath], testsRoot, 30000, buildRestrictedEnv());
|
|
48
|
+
if (result.status === 0) {
|
|
49
|
+
return { success: true, errors: [] };
|
|
50
|
+
}
|
|
51
|
+
const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
|
|
52
|
+
const errorLines = output.split('\n')
|
|
53
|
+
.filter((l) => l.includes('error TS') || l.includes('Error:'))
|
|
54
|
+
.slice(0, 10);
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
errors: errorLines.length > 0 ? errorLines : [output.slice(0, 500) || 'Compilation failed'],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Smoke-run a generated spec against a running app.
|
|
62
|
+
* Runs in a restricted environment with sensitive env vars stripped.
|
|
63
|
+
* Returns success: true if the test passes with retries.
|
|
64
|
+
*/
|
|
65
|
+
function smokeRunSpec(specPath, testsRoot, playwrightBinary) {
|
|
66
|
+
const safeSpecPath = sanitizeSpecPath(specPath);
|
|
67
|
+
const result = (0, process_runner_js_1.runCommand)(playwrightBinary, ['test', safeSpecPath, '--retries', '2', '--reporter', 'list'], testsRoot, 120000, buildRestrictedEnv());
|
|
68
|
+
if (result.status === 0) {
|
|
69
|
+
return { success: true };
|
|
70
|
+
}
|
|
71
|
+
const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
|
|
72
|
+
const errorLines = output.split('\n')
|
|
73
|
+
.filter((l) => l.includes('Error') || l.includes('FAILED') || l.includes('Timeout'))
|
|
74
|
+
.slice(0, 5);
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
error: errorLines.join('\n') || result.error || 'Smoke run failed',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type FileBinding, type RouteFamilyConfig, type RouteFamilyManifest } from '../knowledge/route_families.js';
|
|
2
|
+
import { type ApiSurfaceCatalog, type ApiSurfaceConfig } from '../knowledge/api_surface.js';
|
|
3
|
+
import { type SpecIndex } from '../knowledge/spec_index.js';
|
|
4
|
+
import { type LoadedContext } from '../knowledge/context_loader.js';
|
|
5
|
+
export interface PreprocessConfig {
|
|
6
|
+
appPath: string;
|
|
7
|
+
testsRoot: string;
|
|
8
|
+
routeFamilies?: RouteFamilyConfig;
|
|
9
|
+
apiSurface?: ApiSurfaceConfig;
|
|
10
|
+
}
|
|
11
|
+
export interface FamilyGroup {
|
|
12
|
+
familyId: string;
|
|
13
|
+
featureId?: string;
|
|
14
|
+
files: Array<{
|
|
15
|
+
path: string;
|
|
16
|
+
snippet?: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
export interface PreprocessResult {
|
|
20
|
+
changedFiles: string[];
|
|
21
|
+
fileBindings: FileBinding[];
|
|
22
|
+
unboundFiles: string[];
|
|
23
|
+
familyGroups: FamilyGroup[];
|
|
24
|
+
manifest: RouteFamilyManifest | null;
|
|
25
|
+
apiSurface: ApiSurfaceCatalog;
|
|
26
|
+
specIndex: SpecIndex;
|
|
27
|
+
context: LoadedContext;
|
|
28
|
+
warnings: string[];
|
|
29
|
+
}
|
|
30
|
+
export declare function preprocess(changedFiles: string[], config: PreprocessConfig): PreprocessResult;
|
|
31
|
+
//# sourceMappingURL=stage0_preprocess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stage0_preprocess.d.ts","sourceRoot":"","sources":["../../src/pipeline/stage0_preprocess.ts"],"names":[],"mappings":"AAKA,OAAO,EAIH,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAC3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAwB,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AACjH,OAAO,EAAiB,KAAK,SAAS,EAAC,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAuB,KAAK,aAAa,EAAC,MAAM,gCAAgC,CAAC;AAExF,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,gBAAgB;IAC7B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AA0BD,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAmF7F"}
|