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.

222 lines (221 loc) 9.41 kB
import * as path from 'path'; export class UniversalClassOptimizer { config; constructor(config) { this.config = config; } optimizeClassInfo(cls, _config) { const importance = this.calculateClassImportance(cls); const publicInterface = this.extractPublicInterface(cls); if (importance >= 8.0) { return this.formatCriticalClass(cls, publicInterface); } else if (importance >= 5.0) { return this.formatStandardClass(cls, publicInterface); } else { return this.formatMinimalClass(cls); } } extractPublicInterface(cls) { const publicMethods = (cls.methods || []) .filter(method => this.isPublicMember(method)) .filter(method => !this.isGetterSetter(method)) .sort((a, b) => this.calculateMethodImportance(b) - this.calculateMethodImportance(a)); const publicProperties = (cls.properties || []) .filter(prop => this.isPublicMember(prop)) .filter(prop => !this.isGetterSetterProperty(prop, cls.methods || [])) .sort((a, b) => this.calculatePropertyImportance(b) - this.calculatePropertyImportance(a)); const getterSetterPairs = this.identifyGetterSetterPairs(cls.methods || []); return { keyMethods: publicMethods.slice(0, 5), keyProperties: publicProperties.slice(0, 5), getterSetterPairs: getterSetterPairs.slice(0, 3), inheritance: this.extractInheritanceInfo(cls) }; } isPublicMember(member) { if (member.accessModifier) { return member.accessModifier === 'public' || member.accessModifier === 'export'; } if (member.access) { return member.access === 'public' || member.access === 'export'; } return !member.name.startsWith('_') && !member.name.startsWith('#'); } isGetterSetter(method) { const name = method.name.toLowerCase(); return name.startsWith('get') || name.startsWith('set') || name.startsWith('is') || name.startsWith('has'); } isGetterSetterProperty(property, methods) { const propName = property.name; const hasGetter = methods.some(m => m.name.toLowerCase() === `get${propName.toLowerCase()}` || m.name.toLowerCase() === `is${propName.toLowerCase()}`); const hasSetter = methods.some(m => m.name.toLowerCase() === `set${propName.toLowerCase()}`); return hasGetter || hasSetter; } identifyGetterSetterPairs(methods) { const pairs = []; const getters = methods.filter(m => m.name.startsWith('get') || m.name.startsWith('is') || m.name.startsWith('has')); getters.forEach(getter => { let propertyName = ''; if (getter.name.startsWith('get')) { propertyName = getter.name.substring(3); } else if (getter.name.startsWith('is')) { propertyName = getter.name.substring(2); } else if (getter.name.startsWith('has')) { propertyName = getter.name.substring(3); } const setter = methods.find(m => m.name === `set${propertyName}`); pairs.push({ name: propertyName, hasGetter: true, hasSetter: !!setter, type: getter.returnType || 'unknown' }); }); return pairs; } formatCriticalClass(cls, publicInterface) { let result = `### ${cls.name}`; if (publicInterface.inheritance) { result += ` ${publicInterface.inheritance}`; } result += '\n'; if (cls.comment) { const maxLength = this.config?.contentDensity?.maxContentLength ?? 25; const compressed = this.compressDescription(cls.comment, maxLength); if (compressed) { result += `- **Purpose**: ${compressed}\n`; } } if (publicInterface.keyMethods.length > 0) { const methodNames = publicInterface.keyMethods.map(m => m.name); result += `- **Key Methods**: ${methodNames.join(', ')}\n`; } if (publicInterface.getterSetterPairs.length > 0) { const propNames = publicInterface.getterSetterPairs.map(p => `${p.name}${p.hasSetter ? '' : ' (ro)'}`); result += `- **Properties**: ${propNames.join(', ')}\n`; } if (publicInterface.keyProperties.length > 0) { const propNames = publicInterface.keyProperties.map(p => p.name); result += `- **Fields**: ${propNames.join(', ')}\n`; } return result + '\n'; } formatStandardClass(cls, publicInterface) { let result = `### ${cls.name}`; if (publicInterface.inheritance) { result += ` ${publicInterface.inheritance}`; } result += '\n'; const methodCount = publicInterface.keyMethods.length; const propertyCount = publicInterface.keyProperties.length + publicInterface.getterSetterPairs.length; if (methodCount > 0) { result += `- **Methods**: ${methodCount} public\n`; } if (propertyCount > 0) { result += `- **Properties**: ${propertyCount} public\n`; } return result + '\n'; } formatMinimalClass(cls) { const inheritance = this.extractInheritanceInfo(cls); const suffix = inheritance ? ` ${inheritance}` : ''; return `- **${cls.name}**${suffix}\n`; } extractInheritanceInfo(cls) { const parts = []; if (cls.extends || cls.parentClass) { const parent = cls.extends || cls.parentClass; parts.push(`ext:${parent}`); } if (cls.implements && cls.implements.length > 0) { const impls = cls.implements.slice(0, 2).join(','); const hasMore = cls.implements.length > 2; parts.push(`impl:${impls}${hasMore ? '...' : ''}`); } else if (cls.implementedInterfaces && cls.implementedInterfaces.length > 0) { const impls = cls.implementedInterfaces.slice(0, 2).join(','); const hasMore = cls.implementedInterfaces.length > 2; parts.push(`impl:${impls}${hasMore ? '...' : ''}`); } return parts.length > 0 ? `(${parts.join(' ')})` : ''; } compressDescription(description, maxLength) { if (description.length <= maxLength) return description; const compressed = description .replace(/\bthis (function|method|class)\b/gi, '') .replace(/\bprovides? (a|an|the)?\b/gi, '') .replace(/\bis used (to|for)\b/gi, '') .replace(/\s+/g, ' ') .trim(); if (compressed.length > maxLength) { const truncated = compressed.substring(0, maxLength); const lastSpace = truncated.lastIndexOf(' '); return lastSpace > maxLength * 0.8 ? truncated.substring(0, lastSpace) + '...' : truncated + '...'; } return compressed; } calculateFileImportance(fileInfo) { let score = 5.0; const exportCount = (fileInfo.classes?.filter(c => c.isExported).length || 0) + (fileInfo.functions?.filter(f => f.isExported).length || 0); score += Math.min(exportCount * 0.5, 2.0); const totalSymbols = (fileInfo.classes?.length || 0) + (fileInfo.functions?.length || 0); score += Math.min(totalSymbols * 0.1, 1.5); const fileName = path.basename(fileInfo.relativePath, path.extname(fileInfo.relativePath)); if (['index', 'main', 'app', 'server', 'config'].includes(fileName.toLowerCase())) { score += 2.0; } if (fileInfo.relativePath.includes('test') || fileInfo.relativePath.includes('spec')) { score -= 3.0; } return Math.max(0, Math.min(score, 10.0)); } calculateClassImportance(cls) { let score = 5.0; if (cls.isExported) score += 2.0; const publicMethodCount = (cls.methods || []).filter(m => this.isPublicMember(m)).length; score += Math.min(publicMethodCount * 0.3, 2.0); if (cls.extends || cls.parentClass || (cls.implements && cls.implements.length > 0)) { score += 1.0; } if (cls.isAbstract) score += 1.5; return Math.min(score, 10.0); } calculateMethodImportance(method) { let score = 5.0; if (method.name === 'constructor' || method.name === '__init__' || method.isConstructor) { score += 3.0; } if (['main', 'run', 'execute', 'start', 'init'].includes(method.name.toLowerCase())) { score += 2.0; } if (this.isPublicMember(method)) score += 1.0; if (method.isExported) score += 1.0; if (method.parameters && method.parameters.length > 0) score += 0.5; return Math.min(score, 10.0); } calculatePropertyImportance(property) { let score = 5.0; if (this.isPublicMember(property)) score += 1.0; if (property.isStatic) score += 0.5; if (property.type) score += 0.5; return Math.min(score, 10.0); } }