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
JavaScript
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
`;
}
}