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