Skip to main content
Glama
cbunting99

MCP Code Analysis & Quality Server

by cbunting99
IntelligentPrioritizationEngine.ts39.2 kB
// Copyright 2025 Chris Bunting // Brief: Intelligent prioritization engine for MCP Code Analysis & Quality Server // Scope: AI-powered system to prioritize analysis results based on impact and context import { EventEmitter } from 'events'; import { UnifiedAnalysisResult, UnifiedIssue, PriorityLevel, SeverityLevel, RiskLevel, AnalysisContext, ImpactAssessment, CorrelationData, SuggestionData, UserPreferences, HistoricalData, PatternData, QualityTrend, PerformanceData, IssueCategory, CrossReferenceType, ProjectType, DevelopmentStage, ExperienceLevel, TrendDirection, PatternType } from '@mcp-code-analysis/shared-types'; import { CacheInterface } from '@mcp-code-analysis/shared-types'; export interface PrioritizationConfig { weights: { severity: number; impact: number; frequency: number; context: number; trends: number; patterns: number; }; thresholds: { critical: number; high: number; medium: number; low: number; }; learning: { enabled: boolean; adaptationRate: number; feedbackWeight: number; }; rules: PrioritizationRule[]; } export interface PrioritizationRule { id: string; name: string; description: string; condition: (issue: UnifiedIssue, context: AnalysisContext) => boolean; priority: PriorityLevel; weight: number; enabled: boolean; tags: string[]; } export interface PriorityScore { score: number; confidence: number; factors: PriorityFactor[]; reasoning: string[]; priority: PriorityLevel; estimatedEffort: number; businessValue: number; technicalDebt: number; } export interface PriorityFactor { name: string; value: number; weight: number; contribution: number; description: string; } export interface LearningData { userActions: UserActionData[]; patterns: PatternData[]; effectiveness: EffectivenessData[]; adaptations: AdaptationData[]; } export interface UserActionData { userId: string; action: 'accepted' | 'rejected' | 'modified'; issueId: string; timestamp: Date; context: AnalysisContext; reasoning: string; } export interface EffectivenessData { ruleId: string; effectiveness: number; sampleSize: number; timestamp: Date; context: string; } export interface AdaptationData { parameter: string; oldValue: number; newValue: number; reason: string; timestamp: Date; effectiveness: number; } export class IntelligentPrioritizationEngine extends EventEmitter { private config: PrioritizationConfig; private cache: CacheInterface; private learningData: LearningData; private customRules: Map<string, PrioritizationRule> = new Map(); private logger: any; // Will be properly typed with LoggerInterface constructor(config: PrioritizationConfig, cache: CacheInterface, logger: any) { super(); this.config = config; this.cache = cache; this.logger = logger; this.learningData = { userActions: [], patterns: [], effectiveness: [], adaptations: [] }; this.setupEventHandlers(); } private setupEventHandlers(): void { this.on('prioritized', this.handlePrioritized.bind(this)); this.on('user-feedback', this.handleUserFeedback.bind(this)); this.on('pattern-detected', this.handlePatternDetected.bind(this)); } async initialize(): Promise<void> { this.logger.info('Initializing Intelligent Prioritization Engine'); // Load learning data from cache await this.loadLearningData(); // Initialize default rules this.initializeDefaultRules(); // Start learning process if enabled if (this.config.learning.enabled) { this.startLearningProcess(); } this.logger.info('Intelligent Prioritization Engine initialized successfully'); } async prioritizeResults( results: UnifiedAnalysisResult[], context: AnalysisContext ): Promise<UnifiedAnalysisResult[]> { try { this.logger.info(`Prioritizing ${results.length} analysis results`); // Process each result const prioritizedResults = await Promise.all( results.map(result => this.prioritizeSingleResult(result, context)) ); // Sort by priority score prioritizedResults.sort((a, b) => { const scoreA = this.calculateOverallPriorityScore(a); const scoreB = this.calculateOverallPriorityScore(b); return scoreB - scoreA; }); // Emit prioritization event this.emit('prioritized', { results: prioritizedResults, context, timestamp: new Date() }); this.logger.info('Results prioritized successfully'); return prioritizedResults; } catch (error) { this.logger.error('Failed to prioritize results:', error); throw error; } } private async prioritizeSingleResult( result: UnifiedAnalysisResult, context: AnalysisContext ): Promise<UnifiedAnalysisResult> { // Prioritize issues within the result const prioritizedIssues = await Promise.all( result.issues.map(issue => this.prioritizeIssue(issue, context)) ); // Sort issues by priority prioritizedIssues.sort((a, b) => { const scoreA = this.calculateIssuePriorityScore(a); const scoreB = this.calculateIssuePriorityScore(b); return scoreB - scoreA; }); // Update correlations and suggestions based on prioritization const enhancedCorrelations = await this.enhanceCorrelations( result.correlations, prioritizedIssues, context ); const enhancedSuggestions = await this.enhanceSuggestions( result.suggestions, prioritizedIssues, context ); return { ...result, issues: prioritizedIssues, correlations: enhancedCorrelations, suggestions: enhancedSuggestions, priority: this.calculateResultPriority(prioritizedIssues) }; } private async prioritizeIssue( issue: UnifiedIssue, context: AnalysisContext ): Promise<UnifiedIssue> { // Calculate priority score const priorityScore = await this.calculatePriorityScore(issue, context); // Apply custom rules const ruleAdjustments = await this.applyCustomRules(issue, context); // Apply learning-based adjustments const learningAdjustments = this.config.learning.enabled ? await this.applyLearningAdjustments(issue, context) : 0; // Calculate final priority const finalScore = priorityScore.score + ruleAdjustments + learningAdjustments; const finalPriority = this.scoreToPriority(finalScore); // Enhance cross-references based on priority const enhancedCrossReferences = await this.enhanceCrossReferences( (issue.crossReferences || []).map(ref => ref.type), issue, context ); return { ...issue, priority: finalPriority, crossReferences: enhancedCrossReferences as any, impact: this.enhanceImpactAssessment(issue.impact, finalScore, context) }; } private async calculatePriorityScore( issue: UnifiedIssue, context: AnalysisContext ): Promise<PriorityScore> { const factors: PriorityFactor[] = []; // Severity factor const severityScore = this.calculateSeverityScore(issue.severity); factors.push({ name: 'severity', value: severityScore, weight: this.config.weights.severity, contribution: severityScore * this.config.weights.severity, description: `Severity level: ${issue.severity}` }); // Impact factor const impactScore = this.calculateImpactScore(issue.impact); factors.push({ name: 'impact', value: impactScore, weight: this.config.weights.impact, contribution: impactScore * this.config.weights.impact, description: `Business and technical impact assessment` }); // Context factor const contextScore = await this.calculateContextScore(issue, context); factors.push({ name: 'context', value: contextScore, weight: this.config.weights.context, contribution: contextScore * this.config.weights.context, description: `Project and team context relevance` }); // Frequency factor const frequencyScore = await this.calculateFrequencyScore(issue, context); factors.push({ name: 'frequency', value: frequencyScore, weight: this.config.weights.frequency, contribution: frequencyScore * this.config.weights.frequency, description: `Historical frequency and recurrence patterns` }); // Trends factor const trendsScore = await this.calculateTrendsScore(issue, context); factors.push({ name: 'trends', value: trendsScore, weight: this.config.weights.trends, contribution: trendsScore * this.config.weights.trends, description: `Quality and performance trends` }); // Patterns factor const patternsScore = await this.calculatePatternsScore(issue, context); factors.push({ name: 'patterns', value: patternsScore, weight: this.config.weights.patterns, contribution: patternsScore * this.config.weights.patterns, description: `Pattern recognition and anti-patterns` }); // Calculate total score const totalScore = factors.reduce((sum, factor) => sum + factor.contribution, 0); // Calculate confidence const confidence = this.calculateConfidence(factors); // Generate reasoning const reasoning = this.generateReasoning(factors, issue, context); return { score: totalScore, confidence, factors, reasoning, priority: this.scoreToPriority(totalScore), estimatedEffort: this.estimateEffort(issue, context), businessValue: this.calculateBusinessValue(issue, context), technicalDebt: this.calculateTechnicalDebt(issue, context) }; } private calculateSeverityScore(severity: SeverityLevel): number { const severityMap = { [SeverityLevel.ERROR]: 1.0, [SeverityLevel.WARNING]: 0.7, [SeverityLevel.INFO]: 0.4, [SeverityLevel.HINT]: 0.1 }; return severityMap[severity] || 0.5; } private calculateImpactScore(impact: ImpactAssessment): number { const weights = { business: 0.4, technical: 0.3, user: 0.2, risk: 0.1 }; const normalizedImpact = { business: impact.businessImpact / 10, technical: impact.technicalImpact / 10, user: impact.userImpact / 10, risk: this.riskLevelToScore(impact.riskLevel) }; return ( normalizedImpact.business * weights.business + normalizedImpact.technical * weights.technical + normalizedImpact.user * weights.user + normalizedImpact.risk * weights.risk ); } private async calculateContextScore( issue: UnifiedIssue, context: AnalysisContext ): Promise<number> { let score = 0.5; // Base score // Project type relevance const projectTypeScore = this.getProjectTypeRelevance(issue, context.projectType); score += projectTypeScore * 0.3; // Development stage relevance const stageScore = this.getDevelopmentStageRelevance(issue, context.developmentStage); score += stageScore * 0.2; // Team experience relevance const experienceScore = this.getExperienceRelevance(issue, context.teamContext.experienceLevel); score += experienceScore * 0.2; // User preferences relevance const preferenceScore = this.getPreferenceRelevance(issue, context.userPreferences); score += preferenceScore * 0.3; return Math.min(Math.max(score, 0), 1); } private async calculateFrequencyScore( issue: UnifiedIssue, context: AnalysisContext ): Promise<number> { const cacheKey = `frequency:${issue.ruleId}:${context.technologyStack.join('-')}`; const cached = await this.cache.get<number>(cacheKey); if (cached !== undefined) { return cached; } // Calculate frequency based on historical data const frequency = this.calculateIssueFrequency(issue, context.historicalData); const normalizedFrequency = Math.min(frequency / 10, 1); // Normalize to 0-1 // Cache the result await this.cache.set(cacheKey, normalizedFrequency, 300000); // 5 minutes return normalizedFrequency; } private async calculateTrendsScore( issue: UnifiedIssue, context: AnalysisContext ): Promise<number> { const qualityTrends = context.historicalData.qualityTrends; const performanceHistory = context.historicalData.performanceHistory; let trendScore = 0.5; // Base score // Analyze quality trends const qualityTrendScore = this.analyzeQualityTrends(issue, qualityTrends); trendScore += qualityTrendScore * 0.6; // Analyze performance trends const performanceTrendScore = this.analyzePerformanceTrends(issue, performanceHistory); trendScore += performanceTrendScore * 0.4; return Math.min(Math.max(trendScore, 0), 1); } private async calculatePatternsScore( issue: UnifiedIssue, context: AnalysisContext ): Promise<number> { const patterns = context.historicalData.recurringPatterns; let patternScore = 0.5; // Base score // Check for matching patterns const matchingPatterns = patterns.filter(pattern => this.isPatternMatch(issue, pattern) ); if (matchingPatterns.length > 0) { // Higher score for more frequent and severe patterns const avgFrequency = matchingPatterns.reduce((sum, p) => sum + p.frequency, 0) / matchingPatterns.length; const avgSeverity = matchingPatterns.reduce((sum, p) => sum + this.severityToScore(p.severity), 0) / matchingPatterns.length; patternScore += (avgFrequency / 10) * 0.5 + avgSeverity * 0.5; } return Math.min(Math.max(patternScore, 0), 1); } private async applyCustomRules( issue: UnifiedIssue, context: AnalysisContext ): Promise<number> { let adjustment = 0; for (const rule of this.config.rules) { if (rule.enabled && rule.condition(issue, context)) { const ruleScore = this.priorityToScore(rule.priority); adjustment += ruleScore * rule.weight; } } // Apply custom rules for (const customRule of this.customRules.values()) { if (customRule.enabled && customRule.condition(issue, context)) { const ruleScore = this.priorityToScore(customRule.priority); adjustment += ruleScore * customRule.weight; } } return adjustment; } private applyLearningAdjustments( issue: UnifiedIssue, context: AnalysisContext ): number { if (!this.config.learning.enabled) { return 0; } let adjustment = 0; // Analyze user action patterns const userActionScore = this.analyzeUserActions(issue, context); adjustment += userActionScore * this.config.learning.feedbackWeight; // Analyze rule effectiveness const effectivenessScore = this.analyzeRuleEffectiveness(issue); adjustment += effectivenessScore * this.config.learning.adaptationRate; return adjustment; } private calculateConfidence(factors: PriorityFactor[]): number { if (factors.length === 0) { return 0; } // Calculate confidence based on factor variance and completeness const values = factors.map(f => f.value); const mean = values.reduce((sum, val) => sum + val, 0) / values.length; const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length; // Higher variance means lower confidence const variancePenalty = Math.min(variance * 0.5, 0.3); // Base confidence on number of factors const factorBonus = Math.min(factors.length * 0.1, 0.3); return Math.max(0, Math.min(1, 1 - variancePenalty + factorBonus)); } private generateReasoning( factors: PriorityFactor[], issue: UnifiedIssue, context: AnalysisContext ): string[] { const reasoning: string[] = []; // Add top contributing factors const topFactors = factors .sort((a, b) => b.contribution - a.contribution) .slice(0, 3); topFactors.forEach(factor => { reasoning.push(`${factor.name}: ${factor.description} (score: ${factor.value.toFixed(2)}, weight: ${factor.weight})`); }); // Add context-specific reasoning if (context.projectType === ProjectType.WEB_APP && issue.category === IssueCategory.SECURITY) { reasoning.push('Security issues are critical for web applications'); } if (context.developmentStage === DevelopmentStage.PRODUCTION && issue.severity === SeverityLevel.ERROR) { reasoning.push('Errors in production require immediate attention'); } return reasoning; } private scoreToPriority(score: number): PriorityLevel { if (score >= this.config.thresholds.critical) { return PriorityLevel.CRITICAL; } else if (score >= this.config.thresholds.high) { return PriorityLevel.HIGH; } else if (score >= this.config.thresholds.medium) { return PriorityLevel.MEDIUM; } else { return PriorityLevel.LOW; } } private priorityToScore(priority: PriorityLevel): number { const priorityMap = { [PriorityLevel.CRITICAL]: 1.0, [PriorityLevel.HIGH]: 0.8, [PriorityLevel.MEDIUM]: 0.6, [PriorityLevel.LOW]: 0.4, [PriorityLevel.INFO]: 0.2 }; return priorityMap[priority] || 0.5; } private riskLevelToScore(riskLevel: RiskLevel): number { const riskMap = { [RiskLevel.CRITICAL]: 1.0, [RiskLevel.HIGH]: 0.8, [RiskLevel.MEDIUM]: 0.6, [RiskLevel.LOW]: 0.4 }; return riskMap[riskLevel] || 0.5; } private severityToScore(severity: SeverityLevel): number { return this.calculateSeverityScore(severity); } private initializeDefaultRules(): void { const defaultRules: PrioritizationRule[] = [ { id: 'security-critical', name: 'Security Critical Issues', description: 'Elevate priority for security-related issues', condition: (issue, _context) => issue.category === IssueCategory.SECURITY && issue.severity === SeverityLevel.ERROR, priority: PriorityLevel.CRITICAL, weight: 0.9, enabled: true, tags: ['security', 'critical'] }, { id: 'production-blocking', name: 'Production Blocking Issues', description: 'Elevate priority for issues blocking production', condition: (issue, context) => context.developmentStage === DevelopmentStage.PRODUCTION && issue.severity === SeverityLevel.ERROR, priority: PriorityLevel.CRITICAL, weight: 0.8, enabled: true, tags: ['production', 'blocking'] }, { id: 'performance-critical', name: 'Performance Critical Issues', description: 'Elevate priority for performance bottlenecks', condition: (issue, _context) => issue.category === IssueCategory.PERFORMANCE && issue.impact.businessImpact > 7, priority: PriorityLevel.HIGH, weight: 0.7, enabled: true, tags: ['performance', 'critical'] } ]; defaultRules.forEach(rule => { this.customRules.set(rule.id, rule); }); } private async loadLearningData(): Promise<void> { try { const cached = await this.cache.get<LearningData>('learning-data'); if (cached) { this.learningData = cached; this.logger.info('Learning data loaded from cache'); } } catch (error) { this.logger.warn('Failed to load learning data:', error); } } private async saveLearningData(): Promise<void> { try { await this.cache.set('learning-data', this.learningData, 3600000); // 1 hour } catch (error) { this.logger.warn('Failed to save learning data:', error); } } private startLearningProcess(): void { // Start periodic learning updates setInterval(() => { this.updateLearningModels(); }, 300000); // Every 5 minutes this.logger.info('Learning process started'); } private async updateLearningModels(): Promise<void> { try { // Analyze user actions await this.analyzeUserActionPatterns(); // Update rule effectiveness await this.updateRuleEffectiveness(); // Adapt parameters based on learning await this.adaptParameters(); // Save updated learning data await this.saveLearningData(); this.logger.debug('Learning models updated'); } catch (error) { this.logger.error('Failed to update learning models:', error); } } private handlePrioritized(_data: any): void { this.logger.debug('Results prioritized event handled'); } private handleUserFeedback(data: any): void { // Process user feedback for learning const { action, issueId, context } = data; this.learningData.userActions.push({ userId: context.userPreferences?.toString() || 'anonymous', action: action.outcome, issueId, timestamp: new Date(), context: context.projectContext, reasoning: action.reasoning || '' }); } private handlePatternDetected(data: any): void { // Process detected patterns this.learningData.patterns.push(data.pattern); } // Helper methods for score calculations private getProjectTypeRelevance(issue: UnifiedIssue, projectType: ProjectType): number { const relevanceMap: Record<ProjectType, Record<IssueCategory, number>> = { [ProjectType.WEB_APP]: { [IssueCategory.SECURITY]: 0.9, [IssueCategory.PERFORMANCE]: 0.8, [IssueCategory.ACCESSIBILITY]: 0.7, [IssueCategory.SYNTAX]: 0.3, [IssueCategory.STYLE]: 0.3, [IssueCategory.MAINTAINABILITY]: 0.5, [IssueCategory.TECHNICAL_DEBT]: 0.4, [IssueCategory.COMPLEXITY]: 0.4, [IssueCategory.DOCUMENTATION]: 0.6 }, [ProjectType.API]: { [IssueCategory.SECURITY]: 0.9, [IssueCategory.PERFORMANCE]: 0.8, [IssueCategory.MAINTAINABILITY]: 0.7, [IssueCategory.SYNTAX]: 0.3, [IssueCategory.STYLE]: 0.3, [IssueCategory.ACCESSIBILITY]: 0.2, [IssueCategory.TECHNICAL_DEBT]: 0.4, [IssueCategory.COMPLEXITY]: 0.4, [IssueCategory.DOCUMENTATION]: 0.8 }, [ProjectType.LIBRARY]: { [IssueCategory.MAINTAINABILITY]: 0.9, [IssueCategory.PERFORMANCE]: 0.8, [IssueCategory.DOCUMENTATION]: 0.7, [IssueCategory.SYNTAX]: 0.3, [IssueCategory.STYLE]: 0.3, [IssueCategory.SECURITY]: 0.4, [IssueCategory.ACCESSIBILITY]: 0.2, [IssueCategory.TECHNICAL_DEBT]: 0.4, [IssueCategory.COMPLEXITY]: 0.4 }, [ProjectType.MICROSERVICE]: { [IssueCategory.SECURITY]: 0.8, [IssueCategory.PERFORMANCE]: 0.9, [IssueCategory.MAINTAINABILITY]: 0.6, [IssueCategory.SYNTAX]: 0.3, [IssueCategory.STYLE]: 0.3, [IssueCategory.ACCESSIBILITY]: 0.2, [IssueCategory.TECHNICAL_DEBT]: 0.4, [IssueCategory.COMPLEXITY]: 0.4, [IssueCategory.DOCUMENTATION]: 0.7 }, [ProjectType.MOBILE_APP]: { [IssueCategory.SECURITY]: 0.8, [IssueCategory.PERFORMANCE]: 0.9, [IssueCategory.ACCESSIBILITY]: 0.8, [IssueCategory.SYNTAX]: 0.3, [IssueCategory.STYLE]: 0.3, [IssueCategory.MAINTAINABILITY]: 0.5, [IssueCategory.TECHNICAL_DEBT]: 0.4, [IssueCategory.COMPLEXITY]: 0.4, [IssueCategory.DOCUMENTATION]: 0.5 }, [ProjectType.DESKTOP_APP]: { [IssueCategory.SECURITY]: 0.7, [IssueCategory.PERFORMANCE]: 0.8, [IssueCategory.ACCESSIBILITY]: 0.6, [IssueCategory.SYNTAX]: 0.3, [IssueCategory.STYLE]: 0.3, [IssueCategory.MAINTAINABILITY]: 0.5, [IssueCategory.TECHNICAL_DEBT]: 0.4, [IssueCategory.COMPLEXITY]: 0.4, [IssueCategory.DOCUMENTATION]: 0.4 }, [ProjectType.MONOLITH]: { [IssueCategory.SECURITY]: 0.7, [IssueCategory.PERFORMANCE]: 0.7, [IssueCategory.MAINTAINABILITY]: 0.8, [IssueCategory.SYNTAX]: 0.3, [IssueCategory.STYLE]: 0.3, [IssueCategory.ACCESSIBILITY]: 0.2, [IssueCategory.TECHNICAL_DEBT]: 0.5, [IssueCategory.COMPLEXITY]: 0.5, [IssueCategory.DOCUMENTATION]: 0.6 } }; return relevanceMap[projectType]?.[issue.category] || 0.5; } private getDevelopmentStageRelevance(issue: UnifiedIssue, stage: DevelopmentStage): number { const stageMap: Record<DevelopmentStage, Record<SeverityLevel, number>> = { [DevelopmentStage.PLANNING]: { [SeverityLevel.ERROR]: 0.6, [SeverityLevel.WARNING]: 0.7, [SeverityLevel.INFO]: 0.8, [SeverityLevel.HINT]: 0.5 }, [DevelopmentStage.DEVELOPMENT]: { [SeverityLevel.ERROR]: 0.8, [SeverityLevel.WARNING]: 0.7, [SeverityLevel.INFO]: 0.6, [SeverityLevel.HINT]: 0.4 }, [DevelopmentStage.TESTING]: { [SeverityLevel.ERROR]: 0.9, [SeverityLevel.WARNING]: 0.8, [SeverityLevel.INFO]: 0.6, [SeverityLevel.HINT]: 0.4 }, [DevelopmentStage.PRODUCTION]: { [SeverityLevel.ERROR]: 1.0, [SeverityLevel.WARNING]: 0.9, [SeverityLevel.INFO]: 0.6, [SeverityLevel.HINT]: 0.3 }, [DevelopmentStage.MAINTENANCE]: { [SeverityLevel.ERROR]: 0.9, [SeverityLevel.WARNING]: 0.8, [SeverityLevel.INFO]: 0.7, [SeverityLevel.HINT]: 0.5 }, [DevelopmentStage.DEPLOYMENT]: { [SeverityLevel.ERROR]: 0.95, [SeverityLevel.WARNING]: 0.85, [SeverityLevel.INFO]: 0.6, [SeverityLevel.HINT]: 0.4 } }; return stageMap[stage]?.[issue.severity] || 0.5; } private getExperienceRelevance(_issue: UnifiedIssue, experienceLevel: ExperienceLevel): number { const experienceMap: Record<ExperienceLevel, number> = { [ExperienceLevel.JUNIOR]: 0.8, [ExperienceLevel.MID]: 0.6, [ExperienceLevel.SENIOR]: 0.4, [ExperienceLevel.EXPERT]: 0.3 }; return experienceMap[experienceLevel] || 0.5; } private getPreferenceRelevance(issue: UnifiedIssue, preferences: UserPreferences): number { let score = 0.5; // Check if issue category is preferred if (preferences.preferredCategories.includes(issue.category)) { score += 0.3; } // Check severity threshold if (this.severityToScore(issue.severity) >= this.severityToScore(preferences.severityThreshold)) { score += 0.2; } return Math.min(score, 1.0); } private calculateIssueFrequency(issue: UnifiedIssue, historicalData: HistoricalData): number { // Count occurrences of similar issues in historical data const similarIssues = historicalData.previousIssues.filter(prevId => prevId.includes(issue.ruleId) || prevId.includes(issue.category) ); return similarIssues.length; } private analyzeQualityTrends(_issue: UnifiedIssue, trends: QualityTrend[]): number { const relevantTrends = trends.filter(trend => trend.metric.includes('quality') || trend.metric.includes('defects') ); if (relevantTrends.length === 0) { return 0.5; } // Calculate trend direction and magnitude const avgTrend = relevantTrends.reduce((sum, trend) => { const trendValue = trend.trend === TrendDirection.IMPROVING ? -1 : trend.trend === TrendDirection.DECLINING ? 1 : 0; return sum + trendValue; }, 0) / relevantTrends.length; // Higher score for declining trends return 0.5 + (avgTrend * 0.5); } private analyzePerformanceTrends(issue: UnifiedIssue, history: PerformanceData[]): number { if (issue.category !== IssueCategory.PERFORMANCE) { return 0.5; } const relevantHistory = history.filter(h => h.metric.includes('performance') || h.metric.includes('response') ); if (relevantHistory.length === 0) { return 0.5; } // Calculate performance degradation const avgDeviation = relevantHistory.reduce((sum, h) => sum + h.deviation, 0) / relevantHistory.length; // Higher score for higher deviations return Math.min(0.5 + (avgDeviation * 0.5), 1.0); } private isPatternMatch(issue: UnifiedIssue, pattern: PatternData): boolean { return pattern.type === PatternType.ANTI_PATTERN && pattern.locations.some(loc => loc.filePath === issue.location.filePath || pattern.description.toLowerCase().includes(issue.ruleId.toLowerCase()) ); } private analyzeUserActions(issue: UnifiedIssue, context: AnalysisContext): number { const relevantActions = this.learningData.userActions.filter(action => action.issueId === issue.id || action.context.technologyStack.join('-') === context.technologyStack.join('-') ); if (relevantActions.length === 0) { return 0; } // Calculate acceptance rate const acceptanceRate = relevantActions.filter(action => action.action === 'accepted' ).length / relevantActions.length; return (acceptanceRate - 0.5) * 2; // Convert to -1 to 1 range } private analyzeRuleEffectiveness(issue: UnifiedIssue): number { const ruleEffectiveness = this.learningData.effectiveness.filter(eff => eff.ruleId === issue.ruleId ); if (ruleEffectiveness.length === 0) { return 0; } const avgEffectiveness = ruleEffectiveness.reduce((sum, eff) => sum + eff.effectiveness, 0 ) / ruleEffectiveness.length; return (avgEffectiveness - 0.5) * 2; // Convert to -1 to 1 range } private estimateEffort(issue: UnifiedIssue, context: AnalysisContext): number { // Base effort estimation let effort = 1; // Adjust by severity effort *= this.severityToScore(issue.severity) * 2; // Adjust by impact effort *= (issue.impact.effortEstimate / 5); // Adjust by team experience const experienceMultiplier = { [ExperienceLevel.JUNIOR]: 1.5, [ExperienceLevel.MID]: 1.2, [ExperienceLevel.SENIOR]: 1.0, [ExperienceLevel.EXPERT]: 0.8 }; effort *= experienceMultiplier[context.teamContext.experienceLevel]; return Math.round(effort); } private calculateBusinessValue(issue: UnifiedIssue, context: AnalysisContext): number { let value = issue.impact.businessImpact; // Adjust by project type const projectTypeMultiplier: Record<ProjectType, number> = { [ProjectType.WEB_APP]: 1.2, [ProjectType.API]: 1.1, [ProjectType.LIBRARY]: 0.9, [ProjectType.MICROSERVICE]: 1.0, [ProjectType.MOBILE_APP]: 1.1, [ProjectType.DESKTOP_APP]: 1.0, [ProjectType.MONOLITH]: 0.9 }; value *= projectTypeMultiplier[context.projectType] || 1.0; // Adjust by development stage const stageMultiplier: Record<DevelopmentStage, number> = { [DevelopmentStage.PLANNING]: 0.8, [DevelopmentStage.DEVELOPMENT]: 1.0, [DevelopmentStage.TESTING]: 1.1, [DevelopmentStage.PRODUCTION]: 1.3, [DevelopmentStage.MAINTENANCE]: 1.2, [DevelopmentStage.DEPLOYMENT]: 1.25 }; value *= stageMultiplier[context.developmentStage] || 1.0; return Math.min(Math.round(value), 10); } private calculateTechnicalDebt(issue: UnifiedIssue, _context: AnalysisContext): number { let debt = 5; // Base technical debt // Adjust by complexity debt *= (1 + issue.impact.technicalImpact / 10); // Adjust by category - use only existing categories const categoryMultiplier: Record<IssueCategory, number> = { [IssueCategory.SECURITY]: 1.4, [IssueCategory.PERFORMANCE]: 1.3, [IssueCategory.ACCESSIBILITY]: 1.1, [IssueCategory.SYNTAX]: 0.8, [IssueCategory.STYLE]: 0.6, [IssueCategory.MAINTAINABILITY]: 1.5, [IssueCategory.TECHNICAL_DEBT]: 1.6, [IssueCategory.COMPLEXITY]: 1.2, [IssueCategory.DOCUMENTATION]: 0.9 }; debt *= categoryMultiplier[issue.category] || 1.0; return Math.min(Math.round(debt), 10); } private calculateOverallPriorityScore(result: UnifiedAnalysisResult): number { if (result.issues.length === 0) { return 0; } const issueScores = result.issues.map(issue => this.calculateIssuePriorityScore(issue)); return issueScores.reduce((sum, score) => sum + score, 0) / issueScores.length; } private calculateIssuePriorityScore(issue: UnifiedIssue): number { return this.priorityToScore(issue.priority || PriorityLevel.LOW); } private calculateResultPriority(issues: UnifiedIssue[]): PriorityLevel { if (issues.length === 0) { return PriorityLevel.INFO; } const scores = issues.map(issue => this.calculateIssuePriorityScore(issue)); const avgScore = scores.reduce((sum, score) => sum + score, 0) / scores.length; return this.scoreToPriority(avgScore); } private async enhanceCorrelations( correlations: CorrelationData[], issues: UnifiedIssue[], _context: AnalysisContext ): Promise<CorrelationData[]> { // Enhance correlations based on prioritized issues return correlations.map(correlation => ({ ...correlation, confidence: Math.min(correlation.confidence * 1.1, 1.0), // Slight confidence boost relatedIssues: correlation.relatedIssues.filter(issueId => issues.some(issue => issue.id === issueId) ) })); } private async enhanceSuggestions( suggestions: SuggestionData[], issues: UnifiedIssue[], context: AnalysisContext ): Promise<SuggestionData[]> { // Enhance suggestions based on prioritized issues return suggestions.map(suggestion => ({ ...suggestion, priority: this.enhanceSuggestionPriority(suggestion, issues), impact: this.enhanceSuggestionImpact(suggestion, issues, context) })); } private enhanceSuggestionPriority(suggestion: SuggestionData, issues: UnifiedIssue[]): PriorityLevel { const relatedIssues = issues.filter(issue => suggestion.id.includes(issue.id) || suggestion.description.toLowerCase().includes(issue.ruleId.toLowerCase()) ); if (relatedIssues.length === 0) { return suggestion.priority; } const maxIssuePriority = relatedIssues.reduce((max, issue) => { const issueScore = this.calculateIssuePriorityScore(issue); const maxScore = this.priorityToScore(max); return issueScore > maxScore ? issue.priority : max; }, PriorityLevel.LOW); return maxIssuePriority; } private enhanceSuggestionImpact( suggestion: SuggestionData, issues: UnifiedIssue[], _context: AnalysisContext ): ImpactAssessment { const relatedIssues = issues.filter(issue => suggestion.id.includes(issue.id) || suggestion.description.toLowerCase().includes(issue.ruleId.toLowerCase()) ); if (relatedIssues.length === 0) { return suggestion.impact; } // Aggregate impact from related issues const businessImpact = Math.max(...relatedIssues.map(issue => issue.impact.businessImpact)); const technicalImpact = Math.max(...relatedIssues.map(issue => issue.impact.technicalImpact)); const userImpact = Math.max(...relatedIssues.map(issue => issue.impact.userImpact)); const effortEstimate = Math.min(...relatedIssues.map(issue => issue.impact.effortEstimate)); const riskLevelScores = relatedIssues.map(issue => this.riskLevelToScore(issue.impact.riskLevel)); const maxRiskScore = Math.max(...riskLevelScores); const riskLevel = this.scoreToRiskLevel(maxRiskScore); return { businessImpact, technicalImpact, userImpact, priorityScore: (businessImpact + technicalImpact + userImpact) / 3, effortEstimate, riskLevel }; } private scoreToRiskLevel(score: number): RiskLevel { if (score >= 0.8) return RiskLevel.CRITICAL; if (score >= 0.6) return RiskLevel.HIGH; if (score >= 0.4) return RiskLevel.MEDIUM; return RiskLevel.LOW; } private async enhanceCrossReferences( crossReferences: CrossReferenceType[], _issue: UnifiedIssue, _context: AnalysisContext ): Promise<CrossReferenceType[]> { // Enhance cross-references based on priority return crossReferences.map(ref => ref); // No enhancement needed for enum type } private enhanceImpactAssessment( impact: ImpactAssessment, score: number, _context: AnalysisContext ): ImpactAssessment { // Enhance impact assessment based on priority score const multiplier = 1 + (score - 0.5) * 0.2; // Adjust by ±10% return { ...impact, businessImpact: Math.min(impact.businessImpact * multiplier, 10), technicalImpact: Math.min(impact.technicalImpact * multiplier, 10), userImpact: Math.min(impact.userImpact * multiplier, 10), priorityScore: Math.min(impact.priorityScore * multiplier, 10) }; } private async analyzeUserActionPatterns(): Promise<void> { // Analyze patterns in user actions for learning // Implementation would include pattern recognition algorithms } private async updateRuleEffectiveness(): Promise<void> { // Update rule effectiveness based on user feedback // Implementation would include statistical analysis } private async adaptParameters(): Promise<void> { // Adapt configuration parameters based on learning // Implementation would include optimization algorithms } // Public API methods async addCustomRule(rule: PrioritizationRule): Promise<void> { this.customRules.set(rule.id, rule); this.logger.info(`Custom rule added: ${rule.name}`); } async removeCustomRule(ruleId: string): Promise<void> { this.customRules.delete(ruleId); this.logger.info(`Custom rule removed: ${ruleId}`); } async updateConfig(config: Partial<PrioritizationConfig>): Promise<void> { this.config = { ...this.config, ...config }; this.logger.info('Prioritization configuration updated'); } async getLearningStats(): Promise<any> { return { totalUserActions: this.learningData.userActions.length, totalPatterns: this.learningData.patterns.length, totalEffectiveness: this.learningData.effectiveness.length, totalAdaptations: this.learningData.adaptations.length, learningEnabled: this.config.learning.enabled }; } async shutdown(): Promise<void> { this.logger.info('Shutting down Intelligent Prioritization Engine'); // Save learning data await this.saveLearningData(); // Clear event listeners this.removeAllListeners(); this.logger.info('Intelligent Prioritization Engine shutdown complete'); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cbunting99/mcp-code-analysis-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server