UNPKG

ai-debug-local-mcp

Version:

🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

302 lines 11.8 kB
/** * Test Orchestrator - Testing and validation workflows * * Coordinates test generation, execution, coverage analysis, and regression detection */ export class TestOrchestrator { subAgents = { generation: 'test_generation_agent', execution: 'test_execution_agent', coverage: 'coverage_analysis_agent', regression: 'regression_detection_agent', validation: 'test_validation_agent' }; async orchestrate(task) { console.error('🧪 Test Orchestrator: Analyzing testing task...'); const analysis = this.analyzeTask(task); const plan = this.createExecutionPlan(analysis); const results = await this.executePlan(plan); return this.synthesizeResults(results); } analyzeTask(task) { const keywords = (task.task || task.description || '').toLowerCase(); const analysis = { action: 'general', scope: task.scope || 'all', hasTarget: !!task.target, suggestedAgents: [] }; // Determine primary action if (keywords.includes('generate') || keywords.includes('create') || keywords.includes('write')) { analysis.action = 'generate'; analysis.suggestedAgents.push(this.subAgents.generation); } else if (keywords.includes('run') || keywords.includes('execute')) { analysis.action = 'execute'; analysis.suggestedAgents.push(this.subAgents.execution); } else if (keywords.includes('coverage') || keywords.includes('uncovered')) { analysis.action = 'coverage'; analysis.suggestedAgents.push(this.subAgents.coverage); } else if (keywords.includes('regression') || keywords.includes('broken')) { analysis.action = 'regression'; analysis.suggestedAgents.push(this.subAgents.regression); } else { // Default: full testing workflow analysis.action = 'full'; analysis.suggestedAgents.push(this.subAgents.execution, this.subAgents.coverage, this.subAgents.validation); } return analysis; } createExecutionPlan(analysis) { const plan = { steps: [], parallel: false, estimatedDuration: 0 }; switch (analysis.action) { case 'generate': // Generate tests workflow plan.steps.push({ agent: this.subAgents.generation, action: 'generate_tests', params: { scope: analysis.scope, target: analysis.hasTarget ? 'specific' : 'general', style: 'behavior-driven' } }); plan.steps.push({ agent: this.subAgents.validation, action: 'validate_generated_tests', params: { runSample: true } }); break; case 'execute': // Run tests workflow plan.steps.push({ agent: this.subAgents.execution, action: 'run_tests', params: { scope: analysis.scope, parallel: true, bail: false } }); plan.steps.push({ agent: this.subAgents.coverage, action: 'analyze_results', params: { generateReport: true } }); break; case 'coverage': // Coverage analysis workflow plan.steps.push({ agent: this.subAgents.coverage, action: 'collect_coverage', params: { includeUntested: true, showGaps: true } }); plan.steps.push({ agent: this.subAgents.generation, action: 'suggest_missing_tests', params: { prioritizeByRisk: true } }); break; case 'regression': // Regression detection workflow plan.steps.push({ agent: this.subAgents.regression, action: 'detect_regressions', params: { compareToBaseline: true, includePerformance: true } }); break; default: // Full testing workflow plan.steps.push({ agent: this.subAgents.execution, action: 'run_all_tests', params: { scope: 'all' } }, { agent: this.subAgents.coverage, action: 'generate_coverage_report', params: { detailed: true } }, { agent: this.subAgents.validation, action: 'validate_test_quality', params: { checkFlaky: true } }); } plan.estimatedDuration = plan.steps.length * 10; // 10 seconds per step return plan; } async executePlan(plan) { const results = []; for (const step of plan.steps) { console.log(` → Delegating to ${step.agent} for ${step.action}...`); // Mock implementation const result = { agent: step.agent, action: step.action, success: true, summary: `Completed ${step.action}`, data: this.getMockDataForAction(step.action), duration: Math.random() * 8000 + 2000 }; results.push(result); } return results; } getMockDataForAction(action) { switch (action) { case 'generate_tests': return { generated: 15, types: { unit: 10, integration: 5 }, files: ['user.test.js', 'api.test.js'] }; case 'run_tests': case 'run_all_tests': return { total: 45, passed: 42, failed: 2, skipped: 1, duration: 12.5 }; case 'collect_coverage': case 'generate_coverage_report': return { lines: 85.5, branches: 78.2, functions: 92.1, statements: 86.3, uncoveredFiles: ['utils/helper.js', 'services/cache.js'] }; case 'detect_regressions': return { regressions: [ { test: 'user login flow', type: 'functional', confidence: 0.95 } ] }; default: return { status: 'completed' }; } } synthesizeResults(results) { const testResults = results.find(r => r.action === 'run_tests' || r.action === 'run_all_tests'); const coverageResults = results.find(r => r.action.includes('coverage')); const findings = { critical: [], warnings: [], info: [] }; // Process test failures if (testResults?.data?.failed && testResults.data.failed > 0) { findings.critical.push({ type: 'test_failure', severity: 'critical', title: `${testResults.data.failed} tests failing`, description: 'Tests are failing and need immediate attention' }); } // Process coverage if (coverageResults?.data?.lines !== undefined && coverageResults.data.lines < 80) { findings.warnings.push({ type: 'low_coverage', severity: 'warning', title: `Test coverage at ${coverageResults.data.lines}%`, description: 'Coverage is below recommended 80% threshold' }); } // Process regressions const regressionResult = results.find(r => r.action === 'detect_regressions'); if (regressionResult?.data?.regressions && regressionResult.data.regressions.length > 0) { regressionResult.data.regressions.forEach((reg) => { findings.critical.push({ type: 'regression', severity: 'critical', title: `Regression in ${reg.test}`, description: `${reg.type} regression detected with ${reg.confidence * 100}% confidence` }); }); } const summary = this.createSummary(testResults?.data, coverageResults?.data, findings); return { success: !findings.critical.length, summary, findings, suggestions: this.generateSuggestions(results), nextSteps: this.determineNextSteps(findings), metadata: { duration: results.reduce((sum, r) => sum + r.duration, 0), agentsUsed: [...new Set(results.map(r => r.agent))], confidence: 0.9 } }; } createSummary(testData, coverageData, findings) { const parts = []; if (testData) { const passRate = ((testData.passed / testData.total) * 100).toFixed(1); parts.push(`Tests: ${testData.passed}/${testData.total} (${passRate}%)`); } if (coverageData) { parts.push(`Coverage: ${coverageData.lines}%`); } if (findings.critical.length > 0) { parts.push(`⚠️ ${findings.critical.length} critical issues`); } return parts.join(' | ') || 'Test analysis complete'; } generateSuggestions(results) { const suggestions = []; const coverageResult = results.find(r => r.action.includes('coverage')); if (coverageResult?.data?.uncoveredFiles) { suggestions.push({ title: 'Add tests for uncovered files', description: `Files need coverage: ${coverageResult.data.uncoveredFiles.join(', ')}`, priority: 'high', effort: 'medium' }); } const testResult = results.find(r => r.action.includes('run_tests')); if (testResult?.data?.skipped && testResult.data.skipped > 0) { suggestions.push({ title: 'Enable skipped tests', description: `${testResult.data.skipped} tests are currently skipped`, priority: 'medium', effort: 'low' }); } return suggestions; } determineNextSteps(findings) { const steps = []; if (findings.critical.length > 0) { steps.push('Fix failing tests immediately'); steps.push('Run regression tests after fixes'); } else if (findings.warnings.length > 0) { steps.push('Improve test coverage to 80%+'); steps.push('Add integration tests for critical paths'); } else { steps.push('Set up continuous test monitoring'); steps.push('Consider property-based testing for edge cases'); } return steps; } } //# sourceMappingURL=test-orchestrator.js.map