@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,148 @@
|
|
|
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.generateReport = generateReport;
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
function generateReport(config, phase1, phase2, verdict, generatedSpecs) {
|
|
9
|
+
const outputDir = config.outputDir || '.e2e-ai-agents';
|
|
10
|
+
(0, fs_1.mkdirSync)(outputDir, { recursive: true });
|
|
11
|
+
const reportPath = (0, path_1.join)(outputDir, 'qa-report.json');
|
|
12
|
+
const summaryPath = (0, path_1.join)(outputDir, 'qa-summary.md');
|
|
13
|
+
const report = {
|
|
14
|
+
schemaVersion: '1.0.0',
|
|
15
|
+
generatedAt: new Date().toISOString(),
|
|
16
|
+
mode: config.mode,
|
|
17
|
+
config: {
|
|
18
|
+
baseUrl: config.baseUrl,
|
|
19
|
+
timeLimitMinutes: config.timeLimitMinutes,
|
|
20
|
+
budgetUSD: config.budgetUSD,
|
|
21
|
+
},
|
|
22
|
+
phase1,
|
|
23
|
+
phase2,
|
|
24
|
+
phase3: {
|
|
25
|
+
reportPath,
|
|
26
|
+
summaryPath,
|
|
27
|
+
verdict,
|
|
28
|
+
generatedSpecs,
|
|
29
|
+
},
|
|
30
|
+
verdict,
|
|
31
|
+
};
|
|
32
|
+
try {
|
|
33
|
+
(0, fs_1.writeFileSync)(reportPath, JSON.stringify(report, null, 2), 'utf-8');
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
throw new Error(`Failed to write report to ${reportPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
37
|
+
}
|
|
38
|
+
const markdown = renderMarkdown(report);
|
|
39
|
+
try {
|
|
40
|
+
(0, fs_1.writeFileSync)(summaryPath, markdown, 'utf-8');
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
throw new Error(`Failed to write summary to ${summaryPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
reportPath,
|
|
47
|
+
summaryPath,
|
|
48
|
+
verdict,
|
|
49
|
+
generatedSpecs,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function renderMarkdown(report) {
|
|
53
|
+
const v = report.verdict;
|
|
54
|
+
const badge = v.decision === 'go' ? '✅ GO' : v.decision === 'no-go' ? '❌ NO-GO' : '⚠️ CONDITIONAL';
|
|
55
|
+
const lines = [
|
|
56
|
+
`# QA Agent Report — ${badge}`,
|
|
57
|
+
'',
|
|
58
|
+
`**Mode:** ${report.mode}`,
|
|
59
|
+
`**Base URL:** ${report.config.baseUrl}`,
|
|
60
|
+
`**Generated:** ${report.generatedAt}`,
|
|
61
|
+
'',
|
|
62
|
+
`## Verdict`,
|
|
63
|
+
'',
|
|
64
|
+
`**Decision:** ${badge}`,
|
|
65
|
+
`**Reason:** ${v.reason}`,
|
|
66
|
+
'',
|
|
67
|
+
`| Severity | Count |`,
|
|
68
|
+
`|----------|-------|`,
|
|
69
|
+
`| Critical | ${v.criticalFindings} |`,
|
|
70
|
+
`| High | ${v.highFindings} |`,
|
|
71
|
+
`| Medium | ${v.mediumFindings} |`,
|
|
72
|
+
`| Low | ${v.lowFindings} |`,
|
|
73
|
+
'',
|
|
74
|
+
];
|
|
75
|
+
// Phase 1 summary
|
|
76
|
+
const specTotal = report.phase1.specResults.length;
|
|
77
|
+
const specPassed = report.phase1.specResults.reduce((s, r) => s + r.passed, 0);
|
|
78
|
+
const specFailed = report.phase1.specResults.reduce((s, r) => s + r.failed, 0);
|
|
79
|
+
lines.push(`## Phase 1: Scripted Tests`, '', `- Flows identified: ${report.phase1.flows.length}`, `- Specs run: ${specTotal} (${specPassed} passed, ${specFailed} failed)`, '');
|
|
80
|
+
// Phase 2 summary
|
|
81
|
+
lines.push(`## Phase 2: Autonomous Exploration`, '', `- Flows explored: ${report.phase2.flowsExplored.length}`, `- Actions taken: ${report.phase2.actionsCount}`, `- Duration: ${Math.round(report.phase2.durationMs / 1000)}s`, `- Cost: $${report.phase2.costUSD.toFixed(4)}`, `- Tokens: ${report.phase2.tokensUsed}`, '');
|
|
82
|
+
// Findings
|
|
83
|
+
if (report.phase2.findings.length > 0) {
|
|
84
|
+
lines.push(`## Findings`, '');
|
|
85
|
+
for (const f of report.phase2.findings) {
|
|
86
|
+
const dupNote = f.duplicateCount && f.duplicateCount > 1
|
|
87
|
+
? ` (seen ${f.duplicateCount} times)`
|
|
88
|
+
: '';
|
|
89
|
+
lines.push(`### [${f.severity.toUpperCase()}] ${f.summary}${dupNote}`);
|
|
90
|
+
lines.push('');
|
|
91
|
+
lines.push(`- **Type:** ${f.type}`);
|
|
92
|
+
lines.push(`- **Flow:** ${f.flow}`);
|
|
93
|
+
lines.push(`- **URL:** ${f.evidence.url}`);
|
|
94
|
+
// Expected vs actual behavior
|
|
95
|
+
if (f.evidence.expectedBehavior || f.evidence.actualBehavior) {
|
|
96
|
+
const escapePipe = (s) => s.replace(/\|/g, '\\|');
|
|
97
|
+
lines.push('');
|
|
98
|
+
lines.push(`| Expected | Actual |`);
|
|
99
|
+
lines.push(`|----------|--------|`);
|
|
100
|
+
lines.push(`| ${escapePipe(f.evidence.expectedBehavior || '—')} | ${escapePipe(f.evidence.actualBehavior || '—')} |`);
|
|
101
|
+
lines.push('');
|
|
102
|
+
}
|
|
103
|
+
// Screenshot evidence (inline images)
|
|
104
|
+
if (f.evidence.screenshotRefs && f.evidence.screenshotRefs.length > 0) {
|
|
105
|
+
for (const ref of f.evidence.screenshotRefs) {
|
|
106
|
+
lines.push(``);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (f.evidence.screenshotPath) {
|
|
110
|
+
lines.push(``);
|
|
111
|
+
}
|
|
112
|
+
// Console errors
|
|
113
|
+
if (f.evidence.consoleErrors && f.evidence.consoleErrors.length > 0) {
|
|
114
|
+
lines.push('');
|
|
115
|
+
lines.push('**Console errors:**');
|
|
116
|
+
for (const err of f.evidence.consoleErrors.slice(0, 5)) {
|
|
117
|
+
lines.push(`- \`${err.replace(/`/g, '\\`')}\``);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (f.evidence.reproSteps.length > 0) {
|
|
121
|
+
lines.push('');
|
|
122
|
+
lines.push('**Repro steps:**');
|
|
123
|
+
for (const step of f.evidence.reproSteps) {
|
|
124
|
+
lines.push(` 1. ${step}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
lines.push('');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Flow sign-offs
|
|
131
|
+
lines.push(`## Flow Sign-offs`, '');
|
|
132
|
+
lines.push(`| Flow | Status | Findings |`);
|
|
133
|
+
lines.push(`|------|--------|----------|`);
|
|
134
|
+
for (const s of v.flowSignoffs) {
|
|
135
|
+
const statusIcon = s.status === 'passed' ? '✅' : s.status === 'failed' ? '❌' : '⏭️';
|
|
136
|
+
lines.push(`| ${s.flowName} | ${statusIcon} ${s.status} | ${s.findings.length} |`);
|
|
137
|
+
}
|
|
138
|
+
lines.push('');
|
|
139
|
+
// Generated specs
|
|
140
|
+
if (report.phase3.generatedSpecs.length > 0) {
|
|
141
|
+
lines.push(`## Generated Specs`, '');
|
|
142
|
+
for (const spec of report.phase3.generatedSpecs) {
|
|
143
|
+
lines.push(`- ${spec}`);
|
|
144
|
+
}
|
|
145
|
+
lines.push('');
|
|
146
|
+
}
|
|
147
|
+
return lines.join('\n');
|
|
148
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec_generator.d.ts","sourceRoot":"","sources":["../../../src/qa-agent/phase3/spec_generator.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,OAAO,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AAUnD,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,EAAE,QAAQ,GACjB,MAAM,EAAE,CAiEV"}
|
|
@@ -0,0 +1,65 @@
|
|
|
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.generateSpecsForFindings = generateSpecsForFindings;
|
|
6
|
+
const child_process_1 = require("child_process");
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const logger_js_1 = require("../../logger.js");
|
|
10
|
+
const safe_env_js_1 = require("../safe_env.js");
|
|
11
|
+
function generateSpecsForFindings(findings, config) {
|
|
12
|
+
// Only generate specs for bugs and gaps (not visual/UX issues)
|
|
13
|
+
const actionable = findings.filter((f) => f.type === 'bug' || f.type === 'gap');
|
|
14
|
+
if (actionable.length === 0) {
|
|
15
|
+
logger_js_1.logger.info('No actionable findings for spec generation');
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
const scenarios = actionable.map((f) => ({
|
|
19
|
+
title: `Verify: ${f.summary}`,
|
|
20
|
+
flow: f.flow,
|
|
21
|
+
steps: f.evidence.reproSteps,
|
|
22
|
+
expected: `The issue "${f.summary}" should not occur`,
|
|
23
|
+
priority: f.severity === 'critical' || f.severity === 'high' ? 'P0' : 'P1',
|
|
24
|
+
}));
|
|
25
|
+
// Write scenarios to a temp file
|
|
26
|
+
const outputDir = config.outputDir || '.e2e-ai-agents';
|
|
27
|
+
(0, fs_1.mkdirSync)(outputDir, { recursive: true });
|
|
28
|
+
const scenariosPath = (0, path_1.join)(outputDir, 'qa-findings-scenarios.json');
|
|
29
|
+
(0, fs_1.writeFileSync)(scenariosPath, JSON.stringify(scenarios, null, 2), 'utf-8');
|
|
30
|
+
// Call impact-gate generate with the scenarios
|
|
31
|
+
const args = [
|
|
32
|
+
'impact-gate', 'generate',
|
|
33
|
+
'--scenarios', scenariosPath,
|
|
34
|
+
];
|
|
35
|
+
if (config.testsRoot) {
|
|
36
|
+
args.push('--tests-root', config.testsRoot);
|
|
37
|
+
}
|
|
38
|
+
if (config.baseUrl) {
|
|
39
|
+
args.push('--pipeline-base-url', config.baseUrl);
|
|
40
|
+
}
|
|
41
|
+
logger_js_1.logger.info('Generating specs for findings', { count: scenarios.length });
|
|
42
|
+
const result = (0, child_process_1.spawnSync)('npx', args, {
|
|
43
|
+
cwd: config.testsRoot || process.cwd(),
|
|
44
|
+
encoding: 'utf-8',
|
|
45
|
+
timeout: 300000,
|
|
46
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
47
|
+
env: (0, safe_env_js_1.safeEnv)(),
|
|
48
|
+
});
|
|
49
|
+
if (result.status !== 0) {
|
|
50
|
+
logger_js_1.logger.warn('Spec generation exited with non-zero', {
|
|
51
|
+
status: result.status,
|
|
52
|
+
stderr: (result.stderr || '').slice(0, 500),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Parse generated spec paths from output
|
|
56
|
+
const generatedPaths = [];
|
|
57
|
+
const lines = (result.stdout || '').split('\n');
|
|
58
|
+
for (const line of lines) {
|
|
59
|
+
const match = line.match(/generated.*?:\s*(.+\.spec\.ts)/i);
|
|
60
|
+
if (match) {
|
|
61
|
+
generatedPaths.push(match[1].trim());
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return generatedPaths;
|
|
65
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict.d.ts","sourceRoot":"","sources":["../../../src/qa-agent/phase3/verdict.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAU,YAAY,EAAE,YAAY,EAAE,cAAc,EAA0B,MAAM,aAAa,CAAC;AAE9G,wBAAgB,cAAc,CAC1B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,YAAY,GACrB,cAAc,CAwDhB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
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.computeVerdict = computeVerdict;
|
|
6
|
+
function computeVerdict(phase1, phase2) {
|
|
7
|
+
const findings = phase2.findings;
|
|
8
|
+
const critical = findings.filter((f) => f.severity === 'critical').length;
|
|
9
|
+
const high = findings.filter((f) => f.severity === 'high').length;
|
|
10
|
+
const medium = findings.filter((f) => f.severity === 'medium').length;
|
|
11
|
+
const low = findings.filter((f) => f.severity === 'low' || f.severity === 'info').length;
|
|
12
|
+
// Flow sign-offs
|
|
13
|
+
const flowSignoffs = buildFlowSignoffs(phase1.flows, phase2);
|
|
14
|
+
// Decision logic
|
|
15
|
+
let decision;
|
|
16
|
+
let reason;
|
|
17
|
+
if (critical > 0) {
|
|
18
|
+
decision = 'no-go';
|
|
19
|
+
reason = `${critical} critical finding(s) — must fix before release.`;
|
|
20
|
+
}
|
|
21
|
+
else if (high > 0) {
|
|
22
|
+
decision = 'no-go';
|
|
23
|
+
reason = `${high} high-severity finding(s) — requires triage before release.`;
|
|
24
|
+
}
|
|
25
|
+
else if (medium > 0) {
|
|
26
|
+
decision = 'conditional';
|
|
27
|
+
reason = `${medium} medium-severity finding(s) — review and decide if acceptable.`;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
decision = 'go';
|
|
31
|
+
reason = findings.length === 0
|
|
32
|
+
? 'No issues found across all tested flows.'
|
|
33
|
+
: `Only low/info findings (${low}). Safe to proceed.`;
|
|
34
|
+
}
|
|
35
|
+
// Check for untested flows (P0/P1 not tested → downgrade to conditional)
|
|
36
|
+
const untestedP0P1 = flowSignoffs.filter((s) => s.status === 'not-tested' && phase1.flows.find((f) => f.id === s.flowId && (f.priority === 'P0' || f.priority === 'P1')));
|
|
37
|
+
if (untestedP0P1.length > 0 && decision === 'go') {
|
|
38
|
+
decision = 'conditional';
|
|
39
|
+
reason += ` ${untestedP0P1.length} P0/P1 flow(s) were not tested.`;
|
|
40
|
+
}
|
|
41
|
+
// Check Phase 1 spec failures
|
|
42
|
+
const specFailures = phase1.specResults.reduce((sum, r) => sum + r.failed, 0);
|
|
43
|
+
if (specFailures > 0 && decision === 'go') {
|
|
44
|
+
decision = 'conditional';
|
|
45
|
+
reason += ` ${specFailures} existing spec(s) failed in Phase 1.`;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
decision,
|
|
49
|
+
reason,
|
|
50
|
+
flowSignoffs,
|
|
51
|
+
criticalFindings: critical,
|
|
52
|
+
highFindings: high,
|
|
53
|
+
mediumFindings: medium,
|
|
54
|
+
lowFindings: low,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function buildFlowSignoffs(flows, phase2) {
|
|
58
|
+
return flows.map((flow) => {
|
|
59
|
+
const explored = phase2.flowsExplored.includes(flow.id);
|
|
60
|
+
const flowFindings = phase2.findings.filter((f) => f.flow === flow.id);
|
|
61
|
+
const hasIssues = flowFindings.some((f) => f.type === 'bug' || f.severity === 'critical' || f.severity === 'high');
|
|
62
|
+
return {
|
|
63
|
+
flowId: flow.id,
|
|
64
|
+
flowName: flow.name,
|
|
65
|
+
status: explored ? (hasIssues ? 'failed' : 'passed') : 'not-tested',
|
|
66
|
+
findings: flowFindings.map((f) => f.id),
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe_env.d.ts","sourceRoot":"","sources":["../../src/qa-agent/safe_env.ts"],"names":[],"mappings":"AAGA,4EAA4E;AAC5E,wBAAgB,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAkBzE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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.safeEnv = safeEnv;
|
|
6
|
+
/** Build a minimal env for child processes — only forward what's needed. */
|
|
7
|
+
function safeEnv(extra) {
|
|
8
|
+
const env = {
|
|
9
|
+
PATH: process.env.PATH,
|
|
10
|
+
HOME: process.env.HOME,
|
|
11
|
+
NODE_PATH: process.env.NODE_PATH,
|
|
12
|
+
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
|
|
13
|
+
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
|
|
14
|
+
LLM_PROVIDER: process.env.LLM_PROVIDER,
|
|
15
|
+
LOG_LEVEL: process.env.LOG_LEVEL,
|
|
16
|
+
// Node needs LANG/LC_ALL for proper string handling
|
|
17
|
+
LANG: process.env.LANG,
|
|
18
|
+
// npm/npx need these
|
|
19
|
+
npm_config_prefix: process.env.npm_config_prefix,
|
|
20
|
+
NVM_DIR: process.env.NVM_DIR,
|
|
21
|
+
NVM_BIN: process.env.NVM_BIN,
|
|
22
|
+
};
|
|
23
|
+
if (extra)
|
|
24
|
+
Object.assign(env, extra);
|
|
25
|
+
return env;
|
|
26
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { FlowPriority } from '../agent/types.js';
|
|
2
|
+
export type RunMode = 'pr' | 'hunt' | 'fix' | 'release';
|
|
3
|
+
export interface QAConfig {
|
|
4
|
+
mode: RunMode;
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
since?: string;
|
|
7
|
+
huntTarget?: string;
|
|
8
|
+
phase?: 1 | 2 | 3;
|
|
9
|
+
timeLimitMinutes: number;
|
|
10
|
+
budgetUSD: number;
|
|
11
|
+
headed?: boolean;
|
|
12
|
+
testsRoot?: string;
|
|
13
|
+
project?: string;
|
|
14
|
+
users?: UserCredentials[];
|
|
15
|
+
screenshotDir?: string;
|
|
16
|
+
outputDir?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface UserCredentials {
|
|
19
|
+
role: string;
|
|
20
|
+
username: string;
|
|
21
|
+
password: string;
|
|
22
|
+
}
|
|
23
|
+
export type BrowserActionType = 'navigate' | 'click' | 'fill' | 'type' | 'press' | 'press_key' | 'scroll' | 'back' | 'go_back' | 'screenshot' | 'take_screenshot' | 'snapshot' | 'get_url' | 'get_title' | 'get_text' | 'eval' | 'report_finding' | 'mark_flow_done' | 'switch_user' | 'wait_for' | 'compressed';
|
|
24
|
+
export interface BrowserAction {
|
|
25
|
+
type: BrowserActionType;
|
|
26
|
+
target?: string;
|
|
27
|
+
value?: string;
|
|
28
|
+
timestamp: number;
|
|
29
|
+
}
|
|
30
|
+
export type FindingType = 'bug' | 'visual-regression' | 'ux-issue' | 'gap' | 'verified-ok';
|
|
31
|
+
export type FindingSeverity = 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
32
|
+
export interface Finding {
|
|
33
|
+
id: string;
|
|
34
|
+
type: FindingType;
|
|
35
|
+
severity: FindingSeverity;
|
|
36
|
+
summary: string;
|
|
37
|
+
flow: string;
|
|
38
|
+
evidence: FindingEvidence;
|
|
39
|
+
timestamp: number;
|
|
40
|
+
/** Number of duplicate findings collapsed into this one */
|
|
41
|
+
duplicateCount?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface FindingEvidence {
|
|
44
|
+
screenshotPath?: string;
|
|
45
|
+
/** Multiple screenshot references (e.g. before/after) */
|
|
46
|
+
screenshotRefs?: string[];
|
|
47
|
+
url: string;
|
|
48
|
+
reproSteps: string[];
|
|
49
|
+
consoleErrors?: string[];
|
|
50
|
+
expectedBehavior?: string;
|
|
51
|
+
actualBehavior?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface TargetFlow {
|
|
54
|
+
id: string;
|
|
55
|
+
name: string;
|
|
56
|
+
url?: string;
|
|
57
|
+
priority: FlowPriority;
|
|
58
|
+
}
|
|
59
|
+
export interface ExplorationState {
|
|
60
|
+
flowsToExplore: TargetFlow[];
|
|
61
|
+
flowsExplored: string[];
|
|
62
|
+
currentFlow: string | null;
|
|
63
|
+
findings: Finding[];
|
|
64
|
+
/** Dedup index: maps finding hash key → index in findings array. Runtime-only — not serializable to JSON. */
|
|
65
|
+
findingDedupIndex: Record<string, number>;
|
|
66
|
+
actionsLog: BrowserAction[];
|
|
67
|
+
recentActions: BrowserAction[];
|
|
68
|
+
tokensUsed: number;
|
|
69
|
+
costUSD: number;
|
|
70
|
+
startTime: number;
|
|
71
|
+
timeLimitMs: number;
|
|
72
|
+
budgetUSD: number;
|
|
73
|
+
}
|
|
74
|
+
export interface SpecResult {
|
|
75
|
+
specPath: string;
|
|
76
|
+
passed: number;
|
|
77
|
+
failed: number;
|
|
78
|
+
flaky: number;
|
|
79
|
+
skipped: number;
|
|
80
|
+
}
|
|
81
|
+
export interface Phase1Result {
|
|
82
|
+
flows: TargetFlow[];
|
|
83
|
+
specResults: SpecResult[];
|
|
84
|
+
planPath?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface Phase2Result {
|
|
87
|
+
findings: Finding[];
|
|
88
|
+
flowsExplored: string[];
|
|
89
|
+
actionsCount: number;
|
|
90
|
+
tokensUsed: number;
|
|
91
|
+
costUSD: number;
|
|
92
|
+
durationMs: number;
|
|
93
|
+
}
|
|
94
|
+
export interface Phase3Result {
|
|
95
|
+
reportPath: string;
|
|
96
|
+
summaryPath: string;
|
|
97
|
+
verdict: ReleaseVerdict;
|
|
98
|
+
generatedSpecs: string[];
|
|
99
|
+
}
|
|
100
|
+
export type VerdictDecision = 'go' | 'no-go' | 'conditional';
|
|
101
|
+
export interface FlowSignoff {
|
|
102
|
+
flowId: string;
|
|
103
|
+
flowName: string;
|
|
104
|
+
status: 'passed' | 'failed' | 'not-tested';
|
|
105
|
+
findings: string[];
|
|
106
|
+
}
|
|
107
|
+
export interface ReleaseVerdict {
|
|
108
|
+
decision: VerdictDecision;
|
|
109
|
+
reason: string;
|
|
110
|
+
flowSignoffs: FlowSignoff[];
|
|
111
|
+
criticalFindings: number;
|
|
112
|
+
highFindings: number;
|
|
113
|
+
mediumFindings: number;
|
|
114
|
+
lowFindings: number;
|
|
115
|
+
}
|
|
116
|
+
export interface QAReport {
|
|
117
|
+
schemaVersion: '1.0.0';
|
|
118
|
+
generatedAt: string;
|
|
119
|
+
mode: RunMode;
|
|
120
|
+
config: {
|
|
121
|
+
baseUrl: string;
|
|
122
|
+
timeLimitMinutes: number;
|
|
123
|
+
budgetUSD: number;
|
|
124
|
+
};
|
|
125
|
+
phase1: Phase1Result;
|
|
126
|
+
phase2: Phase2Result;
|
|
127
|
+
phase3: Phase3Result;
|
|
128
|
+
verdict: ReleaseVerdict;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/qa-agent/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"junit.d.ts","sourceRoot":"","sources":["../../src/reporters/junit.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,OAAO,KAAK,EAAc,QAAQ,EAAC,MAAM,eAAe,CAAC;AA6BzD,eAAO,MAAM,aAAa,EAAE,QAyE3B,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
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.junitReporter = void 0;
|
|
6
|
+
function escapeXml(str) {
|
|
7
|
+
return str
|
|
8
|
+
.replace(/&/g, '&')
|
|
9
|
+
.replace(/</g, '<')
|
|
10
|
+
.replace(/>/g, '>')
|
|
11
|
+
.replace(/"/g, '"')
|
|
12
|
+
.replace(/'/g, ''');
|
|
13
|
+
}
|
|
14
|
+
function buildTestCase(tc, flowName) {
|
|
15
|
+
const className = escapeXml(flowName.replace(/\s+/g, '.'));
|
|
16
|
+
const testName = escapeXml(tc.name);
|
|
17
|
+
return ` <testcase classname="${className}" name="${testName}" status="${escapeXml(tc.priority)}">\n` +
|
|
18
|
+
` <properties>\n` +
|
|
19
|
+
` <property name="type" value="${escapeXml(tc.type)}" />\n` +
|
|
20
|
+
` <property name="priority" value="${escapeXml(tc.priority)}" />\n` +
|
|
21
|
+
` </properties>\n` +
|
|
22
|
+
` </testcase>`;
|
|
23
|
+
}
|
|
24
|
+
function buildFailureCase(finding) {
|
|
25
|
+
const name = escapeXml(finding.title);
|
|
26
|
+
return ` <testcase classname="findings" name="${name}">\n` +
|
|
27
|
+
` <failure message="${escapeXml(finding.title)}" type="${escapeXml(finding.severity)}">${escapeXml(finding.description)}</failure>\n` +
|
|
28
|
+
` </testcase>`;
|
|
29
|
+
}
|
|
30
|
+
exports.junitReporter = {
|
|
31
|
+
name: 'junit',
|
|
32
|
+
extension: '.xml',
|
|
33
|
+
format(results) {
|
|
34
|
+
const suites = [];
|
|
35
|
+
// Build a lookup from flowName -> test cases
|
|
36
|
+
const designsByFlow = new Map();
|
|
37
|
+
for (const design of results.testDesigns) {
|
|
38
|
+
designsByFlow.set(design.flowName, design.testCases);
|
|
39
|
+
}
|
|
40
|
+
// High-severity findings as failure cases
|
|
41
|
+
const highFindings = results.findings.filter((f) => f.severity === 'high');
|
|
42
|
+
// Each strategy entry becomes a test suite
|
|
43
|
+
for (const entry of results.strategyEntries) {
|
|
44
|
+
const testCases = designsByFlow.get(entry.flowName) ?? [];
|
|
45
|
+
const failures = highFindings.filter((f) => f.title.includes(entry.flowName));
|
|
46
|
+
const totalTests = testCases.length + failures.length;
|
|
47
|
+
const casesXml = testCases.map((tc) => buildTestCase(tc, entry.flowName)).join('\n');
|
|
48
|
+
const failuresXml = failures.map((f) => buildFailureCase(f)).join('\n');
|
|
49
|
+
const allCases = [casesXml, failuresXml].filter(Boolean).join('\n');
|
|
50
|
+
// Warnings as system-out
|
|
51
|
+
const warningsText = results.warnings.length > 0
|
|
52
|
+
? ` <system-out>${escapeXml(results.warnings.join('\n'))}</system-out>`
|
|
53
|
+
: '';
|
|
54
|
+
suites.push(` <testsuite name="${escapeXml(entry.flowName)}" tests="${totalTests}" failures="${failures.length}" ` +
|
|
55
|
+
`id="${escapeXml(entry.flowId)}">\n` +
|
|
56
|
+
` <properties>\n` +
|
|
57
|
+
` <property name="priority" value="${escapeXml(entry.priority)}" />\n` +
|
|
58
|
+
` <property name="approach" value="${escapeXml(entry.approach)}" />\n` +
|
|
59
|
+
` <property name="rationale" value="${escapeXml(entry.rationale)}" />\n` +
|
|
60
|
+
` </properties>\n` +
|
|
61
|
+
(allCases ? allCases + '\n' : '') +
|
|
62
|
+
(warningsText ? warningsText + '\n' : '') +
|
|
63
|
+
` </testsuite>`);
|
|
64
|
+
}
|
|
65
|
+
// Remaining high findings not tied to a strategy entry
|
|
66
|
+
const coveredFlowNames = new Set(results.strategyEntries.map((e) => e.flowName));
|
|
67
|
+
const uncoveredFindings = highFindings.filter((f) => !Array.from(coveredFlowNames).some((name) => f.title.includes(name)));
|
|
68
|
+
if (uncoveredFindings.length > 0) {
|
|
69
|
+
const failureCases = uncoveredFindings.map((f) => buildFailureCase(f)).join('\n');
|
|
70
|
+
suites.push(` <testsuite name="findings" tests="${uncoveredFindings.length}" failures="${uncoveredFindings.length}">\n` +
|
|
71
|
+
failureCases + '\n' +
|
|
72
|
+
` </testsuite>`);
|
|
73
|
+
}
|
|
74
|
+
const totalTests = results.testDesigns.reduce((sum, d) => sum + d.testCases.length, 0) + highFindings.length;
|
|
75
|
+
const totalFailures = highFindings.length;
|
|
76
|
+
return `<?xml version="1.0" encoding="UTF-8"?>\n` +
|
|
77
|
+
`<testsuites name="impact-gate: ${escapeXml(results.workflow)}" ` +
|
|
78
|
+
`tests="${totalTests}" failures="${totalFailures}" ` +
|
|
79
|
+
`time="0">\n` +
|
|
80
|
+
` <properties>\n` +
|
|
81
|
+
` <property name="changedFiles" value="${results.changedFiles}" />\n` +
|
|
82
|
+
` <property name="impactedFlows" value="${results.impactedFlows}" />\n` +
|
|
83
|
+
` <property name="cost" value="${results.cost}" />\n` +
|
|
84
|
+
` <property name="tokens" value="${results.tokens}" />\n` +
|
|
85
|
+
` </properties>\n` +
|
|
86
|
+
suites.join('\n') + '\n' +
|
|
87
|
+
`</testsuites>\n`;
|
|
88
|
+
},
|
|
89
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reporter interface and shared types for output format plugins.
|
|
3
|
+
*/
|
|
4
|
+
export interface CrewResults {
|
|
5
|
+
workflow: string;
|
|
6
|
+
changedFiles: number;
|
|
7
|
+
impactedFlows: number;
|
|
8
|
+
strategyEntries: Array<{
|
|
9
|
+
flowId: string;
|
|
10
|
+
flowName: string;
|
|
11
|
+
priority: string;
|
|
12
|
+
approach: string;
|
|
13
|
+
rationale: string;
|
|
14
|
+
}>;
|
|
15
|
+
testDesigns: Array<{
|
|
16
|
+
flowName: string;
|
|
17
|
+
testCases: Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
type: string;
|
|
20
|
+
priority: string;
|
|
21
|
+
}>;
|
|
22
|
+
}>;
|
|
23
|
+
crossImpacts: Array<{
|
|
24
|
+
sourceFamily: string;
|
|
25
|
+
affectedFamily: string;
|
|
26
|
+
riskLevel: string;
|
|
27
|
+
}>;
|
|
28
|
+
findings: Array<{
|
|
29
|
+
title: string;
|
|
30
|
+
severity: string;
|
|
31
|
+
description: string;
|
|
32
|
+
}>;
|
|
33
|
+
warnings: string[];
|
|
34
|
+
cost: number;
|
|
35
|
+
tokens: number;
|
|
36
|
+
}
|
|
37
|
+
export interface Reporter {
|
|
38
|
+
name: string;
|
|
39
|
+
extension: string;
|
|
40
|
+
format(results: CrewResults): string;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../src/reporters/reporter.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,KAAK,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,WAAW,EAAE,KAAK,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,KAAK,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,QAAQ,EAAE,MAAM,CAAC;SACpB,CAAC,CAAC;KACN,CAAC,CAAC;IACH,YAAY,EAAE,KAAK,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,QAAQ,EAAE,KAAK,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAAC;CACxC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF v2.1.0 reporter — maps crew results to Static Analysis Results
|
|
3
|
+
* Interchange Format for GitHub Advanced Security / Azure DevOps.
|
|
4
|
+
*/
|
|
5
|
+
import type { Reporter } from './reporter.js';
|
|
6
|
+
export declare const sarifReporter: Reporter;
|
|
7
|
+
//# sourceMappingURL=sarif.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../../src/reporters/sarif.ts"],"names":[],"mappings":"AAGA;;;GAGG;AAEH,OAAO,KAAK,EAAc,QAAQ,EAAC,MAAM,eAAe,CAAC;AA0DzD,eAAO,MAAM,aAAa,EAAE,QAoH3B,CAAC"}
|