UNPKG

vibe-coder-mcp

Version:

Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.

310 lines (304 loc) 13.4 kB
export class UniversalDiagramOptimizer { optimizeImports(imports) { if (!imports || imports.length === 0) { return imports; } const optimizedImports = []; const resolved = imports.filter(imp => !this.isUnresolvedImport(imp)); const unresolved = imports.filter(imp => this.isUnresolvedImport(imp)); const consolidatedSummary = this.consolidateImports(resolved, unresolved); if (consolidatedSummary) { optimizedImports.push({ path: consolidatedSummary, type: 'summary', comment: 'Consolidated import summary', isExternalPackage: false }); } const importantResolved = resolved .filter(imp => this.isImportantImport(imp)) .slice(0, 3); optimizedImports.push(...importantResolved); return optimizedImports; } consolidateImports(resolved, unresolved) { const parts = []; if (resolved.length > 0) { parts.push(`${resolved.length} internal modules`); } if (unresolved.length > 0) { const patterns = this.analyzeUnresolvedPatterns(unresolved); if (patterns.standardLibs > 0) { parts.push(`${patterns.standardLibs} standard libraries`); } if (patterns.frameworks > 0) { parts.push(`${patterns.frameworks} framework dependencies`); } if (patterns.utilities > 0) { parts.push(`${patterns.utilities} utility packages`); } const otherUnresolved = unresolved.length - patterns.standardLibs - patterns.frameworks - patterns.utilities; if (otherUnresolved > 0) { parts.push(`${otherUnresolved} external dependencies`); } } return parts.length > 0 ? parts.join(', ') : ''; } analyzeUnresolvedPatterns(unresolved) { const standardLibPatterns = ['fs', 'path', 'crypto', 'util', 'os', 'http', 'https', 'url', 'events', 'stream']; const frameworkPatterns = ['react', 'vue', 'angular', 'express', 'fastify', 'next', 'nuxt', 'django', 'flask', 'spring']; const utilityPatterns = ['lodash', 'moment', 'axios', 'fetch', 'uuid', 'chalk', 'debug', 'winston']; let standardLibs = 0; let frameworks = 0; let utilities = 0; unresolved.forEach(imp => { const path = imp.path.toLowerCase(); if (standardLibPatterns.some(pattern => path.includes(pattern))) { standardLibs++; } else if (frameworkPatterns.some(pattern => path.includes(pattern))) { frameworks++; } else if (utilityPatterns.some(pattern => path.includes(pattern))) { utilities++; } }); return { standardLibs, frameworks, utilities }; } isImportantImport(imp) { const path = imp.path.toLowerCase(); const importantPatterns = [ 'config', 'service', 'manager', 'controller', 'handler', 'model', 'schema', 'types', 'interface', 'api' ]; return importantPatterns.some(pattern => path.includes(pattern)) || Boolean(imp.importedItems && imp.importedItems.length > 3); } isUnresolvedImport(imp) { return imp.path === 'unknown' || imp.path === 'module import' || imp.path.startsWith('module import') || (imp.path === 'unknown' && (!imp.importedItems || imp.importedItems.length === 0)); } countUnresolvedImports(imports) { return imports.filter(imp => this.isUnresolvedImport(imp)).length; } createUnresolvedImportSummary(count) { return { path: `${count} unresolved imports`, type: 'summary', comment: 'These imports could not be resolved to specific module names', isExternalPackage: false }; } optimizeFileInfo(fileInfo) { return { ...fileInfo, imports: this.optimizeImports(fileInfo.imports) }; } optimizeFileInfos(fileInfos) { return fileInfos.map(fileInfo => this.optimizeFileInfo(fileInfo)); } optimizeDependencyDiagram(nodes, edges, config) { const analysis = this.analyzeDependencyComplexity(nodes, edges); if (config.eliminateVerboseDiagrams || analysis.totalNodes > 20) { return this.generateArchitectureSummary(analysis); } else if (analysis.totalNodes > 10) { return this.generateSimplifiedDiagram(nodes, edges); } else { return this.generateCompactDiagram(nodes, edges); } } analyzeDependencyComplexity(nodes, edges) { const coreComponents = this.identifyCoreComponents(nodes, edges); const externalDeps = this.identifyExternalDependencies(nodes); const internalModules = this.identifyInternalModules(nodes); return { totalNodes: nodes.length, coreComponents, externalDependencies: externalDeps, internalModules, complexityScore: this.calculateComplexityScore(nodes, edges), architecturalPattern: this.detectArchitecturePattern(nodes, edges) }; } generateArchitectureSummary(analysis) { const coreComponents = analysis.coreComponents.slice(0, 6); const externalDeps = analysis.externalDependencies.slice(0, 8); return `## Architecture Overview **Core Components** (${coreComponents.length}/${analysis.coreComponents.length}): ${coreComponents.map(comp => `- **${comp.name}**: ${comp.role}`).join('\n')} **External Dependencies** (${externalDeps.length}/${analysis.externalDependencies.length}): ${externalDeps.join(', ')} **Architecture Pattern**: ${analysis.architecturalPattern} **Module Organization**: ${analysis.internalModules.length} internal modules `; } identifyCoreComponents(nodes, edges) { return nodes .map(node => ({ name: this.extractComponentName(node.id), importance: this.calculateComponentImportance(node, edges), role: this.inferComponentRole(node), connections: this.countConnections(node.id, edges) })) .filter(comp => comp.importance >= 6.0) .sort((a, b) => b.importance - a.importance); } extractComponentName(filePath) { const segments = filePath.split('/').filter(Boolean); const fileName = segments[segments.length - 1]; return fileName.replace(/\.(ts|js|py|java|go|rs|php|rb|cpp|cs|kt|swift|dart|scala)$/, ''); } inferComponentRole(node) { const path = node.id.toLowerCase(); if (path.includes('service') || path.includes('api')) return 'Service'; if (path.includes('model') || path.includes('entity')) return 'Data'; if (path.includes('controller') || path.includes('handler')) return 'Handler'; if (path.includes('util') || path.includes('helper')) return 'Utility'; if (path.includes('config') || path.includes('setting')) return 'Config'; if (path.includes('test') || path.includes('spec')) return 'Test'; if (path.includes('component') || path.includes('widget')) return 'UI'; if (path.includes('middleware') || path.includes('interceptor')) return 'Middleware'; const fileName = this.extractComponentName(node.id).toLowerCase(); if (fileName.includes('manager') || fileName.includes('coordinator')) return 'Manager'; if (fileName.includes('factory') || fileName.includes('builder')) return 'Factory'; if (fileName.includes('adapter') || fileName.includes('wrapper')) return 'Adapter'; return 'Component'; } calculateComponentImportance(node, edges) { let score = 5.0; const incomingCount = edges.filter(e => e.to === node.id).length; const outgoingCount = edges.filter(e => e.from === node.id).length; score += Math.min(incomingCount * 0.5, 3.0); score += Math.min(outgoingCount * 0.3, 2.0); const role = this.inferComponentRole(node); if (['Service', 'Manager', 'Handler'].includes(role)) score += 2.0; if (['Data', 'Config'].includes(role)) score += 1.0; const fileName = this.extractComponentName(node.id).toLowerCase(); if (['index', 'main', 'app', 'server'].includes(fileName)) score += 2.0; return Math.min(score, 10.0); } countConnections(nodeId, edges) { return edges.filter(e => e.from === nodeId || e.to === nodeId).length; } identifyExternalDependencies(nodes) { return nodes .filter(node => this.isExternalDependency(node.id)) .map(node => this.extractDependencyName(node.id)) .filter((dep, index, arr) => arr.indexOf(dep) === index) .sort(); } isExternalDependency(nodeId) { return nodeId.includes('node_modules') || nodeId.includes('site-packages') || nodeId.includes('vendor') || nodeId.includes('lib') || nodeId.startsWith('@') || !nodeId.includes('/') && !nodeId.includes('\\'); } extractDependencyName(nodeId) { if (nodeId.includes('node_modules')) { const parts = nodeId.split('node_modules/')[1]?.split('/'); return parts?.[0]?.startsWith('@') ? `${parts[0]}/${parts[1]}` : parts?.[0] || nodeId; } if (nodeId.includes('site-packages')) { const parts = nodeId.split('site-packages/')[1]?.split('/'); return parts?.[0] || nodeId; } return nodeId; } identifyInternalModules(nodes) { return nodes .filter(node => !this.isExternalDependency(node.id)) .map(node => this.extractModulePath(node.id)) .filter((module, index, arr) => arr.indexOf(module) === index) .sort(); } extractModulePath(filePath) { const segments = filePath.split('/').filter(Boolean); return segments.length > 1 ? segments[0] : filePath; } calculateComplexityScore(nodes, edges) { const nodeCount = nodes.length; const edgeCount = edges.length; const density = nodeCount > 0 ? edgeCount / nodeCount : 0; return Math.min(nodeCount * 0.1 + density * 2, 10.0); } detectArchitecturePattern(nodes, edges) { const analysis = this.analyzeArchitecturalPatterns(nodes, edges); if (analysis.hasLayeredStructure) return 'Layered Architecture'; if (analysis.hasMicroservicePattern) return 'Microservices'; if (analysis.hasMVCPattern) return 'MVC Pattern'; if (analysis.hasModularStructure) return 'Modular Architecture'; if (analysis.hasComponentStructure) return 'Component-Based'; return 'Custom Architecture'; } analyzeArchitecturalPatterns(nodes, _edges) { const paths = nodes.map(n => n.id.toLowerCase()); return { hasLayeredStructure: this.detectLayeredStructure(paths), hasMicroservicePattern: this.detectMicroservicePattern(paths), hasMVCPattern: this.detectMVCPattern(paths), hasModularStructure: this.detectModularStructure(paths), hasComponentStructure: this.detectComponentStructure(paths) }; } detectLayeredStructure(paths) { const layers = ['controller', 'service', 'repository', 'model', 'dao']; const foundLayers = layers.filter(layer => paths.some(path => path.includes(layer))); return foundLayers.length >= 3; } detectMicroservicePattern(paths) { const serviceIndicators = ['service', 'api', 'gateway', 'proxy']; return serviceIndicators.filter(indicator => paths.some(path => path.includes(indicator))).length >= 2; } detectMVCPattern(paths) { const mvcComponents = ['controller', 'model', 'view']; return mvcComponents.every(component => paths.some(path => path.includes(component))); } detectModularStructure(paths) { const modules = new Set(paths.map(path => path.split('/')[0])); return modules.size >= 3; } detectComponentStructure(paths) { const componentIndicators = ['component', 'widget', 'element']; return componentIndicators.some(indicator => paths.some(path => path.includes(indicator))); } generateSimplifiedDiagram(nodes, edges) { const coreNodes = nodes.slice(0, 15); const coreEdges = edges.filter(e => coreNodes.some(n => n.id === e.from) && coreNodes.some(n => n.id === e.to)); return `## Simplified Architecture **Components**: ${coreNodes.map(n => this.extractComponentName(n.id)).join(', ')} **Connections**: ${coreEdges.length} dependencies `; } generateCompactDiagram(nodes, edges) { return `## Architecture Diagram **Components** (${nodes.length}): ${nodes.map(n => this.extractComponentName(n.id)).join(', ')} **Dependencies**: ${edges.length} connections `; } }