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

444 lines 18.3 kB
/** * QA Orchestrator - Quality Assurance workflows * * Handles code review, security scanning, compliance checking, and documentation validation */ export class QAOrchestrator { subAgents = { codeReview: 'code_review_agent', security: 'security_scan_agent', compliance: 'compliance_check_agent', documentation: 'documentation_validation_agent', accessibility: 'accessibility_audit_agent', bestPractices: 'best_practices_agent' }; async orchestrate(task) { console.error('✅ QA Orchestrator: Starting quality assurance workflow...'); 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 = { scope: task.scope || 'full', severity: task.severity || 'balanced', hasTarget: !!task.target, standards: task.standards || ['default'], suggestedAgents: [] }; // Determine agents based on scope if (analysis.scope === 'full') { // Comprehensive QA analysis.suggestedAgents.push(this.subAgents.codeReview, this.subAgents.security, this.subAgents.bestPractices, this.subAgents.documentation); // Add compliance if standards specified if (task.standards && task.standards.length > 0) { analysis.suggestedAgents.push(this.subAgents.compliance); } } else { // Focused QA based on scope switch (analysis.scope) { case 'code-review': analysis.suggestedAgents.push(this.subAgents.codeReview, this.subAgents.bestPractices); break; case 'security': analysis.suggestedAgents.push(this.subAgents.security, this.subAgents.compliance); break; case 'compliance': analysis.suggestedAgents.push(this.subAgents.compliance, this.subAgents.documentation); break; case 'documentation': analysis.suggestedAgents.push(this.subAgents.documentation, this.subAgents.bestPractices); break; } } // Add agents based on keywords if (keywords.includes('accessibility') || keywords.includes('a11y')) { if (!analysis.suggestedAgents.includes(this.subAgents.accessibility)) { analysis.suggestedAgents.push(this.subAgents.accessibility); } } if (keywords.includes('security') || keywords.includes('vulnerability')) { if (!analysis.suggestedAgents.includes(this.subAgents.security)) { analysis.suggestedAgents.push(this.subAgents.security); } } return analysis; } createExecutionPlan(analysis) { const plan = { steps: [], parallel: true, // QA checks can run in parallel estimatedDuration: 0 }; analysis.suggestedAgents.forEach(agent => { switch (agent) { case this.subAgents.codeReview: plan.steps.push({ agent, action: 'review_code_quality', params: { checkStyle: true, checkComplexity: true, checkDuplication: true, severity: analysis.severity } }); break; case this.subAgents.security: plan.steps.push({ agent, action: 'scan_security_vulnerabilities', params: { deepScan: analysis.severity === 'strict', checkDependencies: true, checkSecrets: true, owasp: true } }); break; case this.subAgents.compliance: plan.steps.push({ agent, action: 'check_compliance', params: { standards: analysis.standards, includeLicenses: true, checkPrivacy: true } }); break; case this.subAgents.documentation: plan.steps.push({ agent, action: 'validate_documentation', params: { checkCompleteness: true, checkAccuracy: true, checkExamples: true, apiDocs: true } }); break; case this.subAgents.accessibility: plan.steps.push({ agent, action: 'audit_accessibility', params: { wcagLevel: 'AA', includeAria: true, checkKeyboard: true, checkContrast: true } }); break; case this.subAgents.bestPractices: plan.steps.push({ agent, action: 'evaluate_best_practices', params: { framework: 'auto-detect', modern: true, performance: true } }); break; } }); plan.estimatedDuration = plan.steps.length * 5; // 5 seconds per check return plan; } async executePlan(plan) { const results = []; // Execute in parallel since QA checks are independent const promises = plan.steps.map(async (step) => { console.log(` → Delegating to ${step.agent} for ${step.action}...`); // Mock implementation return { agent: step.agent, action: step.action, success: true, summary: `Completed ${step.action}`, data: this.getMockDataForAction(step.action), duration: Math.random() * 3000 + 2000 }; }); const parallelResults = await Promise.all(promises); results.push(...parallelResults); return results; } getMockDataForAction(action) { switch (action) { case 'review_code_quality': return { score: 82, issues: [ { type: 'complexity', severity: 'medium', count: 3 }, { type: 'duplication', severity: 'low', count: 5 }, { type: 'naming', severity: 'low', count: 8 } ], suggestions: ['Reduce cyclomatic complexity', 'Extract common code'] }; case 'scan_security_vulnerabilities': return { vulnerabilities: [ { severity: 'high', type: 'SQL Injection', location: 'api/users.js:45', cwe: 'CWE-89' }, { severity: 'medium', type: 'Insecure Dependency', package: 'old-package@1.0.0', fix: 'Update to 2.0.0' } ], securityScore: 65 }; case 'check_compliance': return { compliant: false, violations: [ { standard: 'GDPR', issue: 'Missing privacy policy link', severity: 'high' } ], licenses: { compatible: 15, incompatible: 1, unknown: 2 } }; case 'validate_documentation': return { coverage: 75, issues: [ { type: 'missing', count: 5, examples: ['UserService.create()'] }, { type: 'outdated', count: 3, examples: ['API v1 docs'] }, { type: 'broken_links', count: 2 } ], apiDocsCoverage: 68 }; case 'audit_accessibility': return { score: 88, wcagLevel: 'AA', violations: [ { rule: 'color-contrast', impact: 'serious', count: 3 }, { rule: 'label', impact: 'critical', count: 1 } ] }; case 'evaluate_best_practices': return { adherence: 90, recommendations: [ 'Use modern ES6+ features', 'Implement error boundaries', 'Add performance monitoring' ], outdatedPatterns: ['callbacks instead of promises', 'var instead of const/let'] }; default: return {}; } } synthesizeResults(results) { const findings = { critical: [], warnings: [], info: [] }; // Process security vulnerabilities const securityResult = results.find(r => r.action === 'scan_security_vulnerabilities'); if (securityResult?.data?.vulnerabilities) { securityResult.data.vulnerabilities.forEach((vuln) => { findings[vuln.severity === 'high' ? 'critical' : 'warnings'].push({ type: 'security_vulnerability', severity: vuln.severity === 'high' ? 'critical' : 'warning', title: `${vuln.type} vulnerability`, description: `Found at ${vuln.location || vuln.package}`, fix: vuln.fix }); }); } // Process compliance violations const complianceResult = results.find(r => r.action === 'check_compliance'); if (complianceResult?.data?.violations) { complianceResult.data.violations.forEach((violation) => { findings.critical.push({ type: 'compliance_violation', severity: 'critical', title: `${violation.standard} violation`, description: violation.issue }); }); } // Process accessibility issues const a11yResult = results.find(r => r.action === 'audit_accessibility'); if (a11yResult?.data?.violations) { a11yResult.data.violations.forEach((violation) => { const severity = violation.impact === 'critical' ? 'critical' : 'warning'; findings[severity === 'critical' ? 'critical' : 'warnings'].push({ type: 'accessibility_issue', severity, title: `Accessibility: ${violation.rule}`, description: `${violation.count} instances with ${violation.impact} impact` }); }); } // Process code quality issues const codeReviewResult = results.find(r => r.action === 'review_code_quality'); if (codeReviewResult?.data?.issues) { codeReviewResult.data.issues.forEach((issue) => { if (issue.severity === 'medium' || issue.severity === 'high') { findings.warnings.push({ type: 'code_quality', severity: 'warning', title: `Code quality: ${issue.type}`, description: `Found ${issue.count} instances` }); } }); } const suggestions = this.generateSuggestions(results); const summary = this.createSummary(results, findings); // Calculate overall QA score const qaScore = this.calculateQAScore(results); return { success: findings.critical.length === 0, summary, findings, suggestions: suggestions.slice(0, 5), // More suggestions for QA nextSteps: this.determineNextSteps(findings, qaScore), metadata: { duration: Math.max(...results.map(r => r.duration)), agentsUsed: [...new Set(results.map(r => r.agent))], confidence: 0.92, qaScore } }; } createSummary(results, findings) { const parts = []; // Add QA scores const codeReview = results.find(r => r.action === 'review_code_quality'); if (codeReview?.data?.score) { parts.push(`Code Quality: ${codeReview.data.score}/100`); } const security = results.find(r => r.action === 'scan_security_vulnerabilities'); if (security?.data?.securityScore) { parts.push(`Security: ${security.data.securityScore}/100`); } const a11y = results.find(r => r.action === 'audit_accessibility'); if (a11y?.data?.score) { parts.push(`Accessibility: ${a11y.data.score}/100`); } // Add issue counts if (findings.critical.length > 0) { parts.push(`⚠️ ${findings.critical.length} critical issues`); } if (findings.warnings.length > 0) { parts.push(`⚡ ${findings.warnings.length} warnings`); } return parts.join(' | ') || 'QA analysis complete'; } generateSuggestions(results) { const suggestions = []; // Security suggestions const security = results.find(r => r.action === 'scan_security_vulnerabilities'); if (security?.data?.vulnerabilities?.length > 0) { suggestions.push({ title: 'Fix security vulnerabilities immediately', description: 'Security issues should be addressed before deployment', priority: 'critical', effort: 'medium' }); } // Documentation suggestions const docs = results.find(r => r.action === 'validate_documentation'); if (docs?.data?.coverage !== undefined && docs.data.coverage < 80) { suggestions.push({ title: 'Improve documentation coverage', description: `Current coverage: ${docs.data.coverage}%. Target: 80%+`, priority: 'medium', effort: 'medium' }); } // Code quality suggestions const codeReview = results.find(r => r.action === 'review_code_quality'); codeReview?.data?.suggestions?.forEach((suggestion) => { suggestions.push({ title: suggestion, description: 'Improves code maintainability', priority: 'medium', effort: 'small' }); }); // Accessibility suggestions const a11y = results.find(r => r.action === 'audit_accessibility'); if (a11y?.data?.violations?.some((v) => v.impact === 'critical')) { suggestions.push({ title: 'Fix critical accessibility issues', description: 'Required for WCAG compliance', priority: 'high', effort: 'small' }); } return suggestions; } calculateQAScore(results) { const scores = []; results.forEach(result => { if (result.data.score !== undefined) { scores.push(result.data.score); } else if (result.data.securityScore !== undefined) { scores.push(result.data.securityScore); } else if (result.data.coverage !== undefined) { scores.push(result.data.coverage); } else if (result.data.adherence !== undefined) { scores.push(result.data.adherence); } }); if (scores.length === 0) return 0; return Math.round(scores.reduce((a, b) => a + b, 0) / scores.length); } determineNextSteps(findings, qaScore) { const steps = []; if (findings.critical.length > 0) { steps.push('Address all critical issues before deployment'); steps.push('Re-run QA checks after fixes'); } else if (qaScore < 70) { steps.push('Focus on improving overall quality score'); steps.push('Implement suggested best practices'); } else if (qaScore >= 90) { steps.push('Set up automated QA gates in CI/CD'); steps.push('Monitor quality metrics over time'); } else { steps.push('Address high-priority warnings'); steps.push('Schedule regular QA reviews'); } return steps; } } //# sourceMappingURL=qa-orchestrator.js.map