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
JavaScript
/**
* 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