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.

186 lines (185 loc) 9.9 kB
import path from 'path'; import { generateHeuristicComment } from './astAnalyzer.js'; export function formatCodeMapToMarkdown(codeMap, projectRoot) { let markdownOutput = `# Code Map for ${path.basename(projectRoot)}\n\n`; markdownOutput += `Processed ${codeMap.files.length} files.\n`; const errorFiles = codeMap.files.filter(f => f.comment?.startsWith("Error processing file")); if (errorFiles.length > 0) { markdownOutput += `${errorFiles.length} file(s) encountered errors during processing.\n`; } markdownOutput += `\n`; for (const fileInfo of codeMap.files) { markdownOutput += `## File: ${fileInfo.relativePath}\n`; if (fileInfo.comment) { markdownOutput += `*${fileInfo.comment.split('\n')[0]}*\n\n`; } else { markdownOutput += `*${generateHeuristicComment(path.basename(fileInfo.relativePath), 'file')}*\n\n`; } if (fileInfo.imports.length > 0) { markdownOutput += `### Imports\n`; fileInfo.imports.forEach(imp => { let displayPath = imp.path; if (imp.path === 'unknown' && imp.nodeText) { const es6ImportMatch = imp.nodeText.match(/from\s+['"]([^'"]+)['"]/); if (es6ImportMatch && es6ImportMatch[1]) { displayPath = es6ImportMatch[1]; } else { const requireMatch = imp.nodeText.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/); if (requireMatch && requireMatch[1]) { displayPath = requireMatch[1]; } else { const dynamicImportMatch = imp.nodeText.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/); if (dynamicImportMatch && dynamicImportMatch[1]) { displayPath = dynamicImportMatch[1]; } else { displayPath = imp.importedItems && imp.importedItems.length > 0 ? `${imp.importedItems[0]} (imported)` : 'module import'; } } } } let impDetails = imp.importedItems && imp.path !== 'unknown' ? `(${imp.importedItems.join(', ')})` : ''; if (imp.isDefault && imp.importedItems && imp.importedItems.length > 0 && imp.path !== 'unknown') { impDetails = `${imp.importedItems[0]} (default)`; if (imp.importedItems.length > 1) { impDetails += `, { ${imp.importedItems.slice(1).join(', ')} }`; } } else if (imp.isDefault && imp.path !== 'unknown') { impDetails = `(default)`; } const isResolved = imp.path !== 'unknown' && (imp.path.startsWith('/') || imp.path.includes(':\\') || imp.path.match(/^[a-zA-Z]:\//)); const isExternalPackage = imp.isExternalPackage || (!imp.path.startsWith('.') && !imp.path.startsWith('/') && imp.path !== 'unknown'); const isProjectFile = imp.isProjectFile || (imp.path.startsWith('./') || imp.path.startsWith('../')); if (isResolved) { const originalPath = imp.originalPath || imp.path; const resolvedPath = imp.path; const fileName = path.basename(resolvedPath); markdownOutput += `- \`${originalPath}\` → \`${fileName}\` ${impDetails}\n`; markdownOutput += ` *Resolved to: ${resolvedPath}*\n`; } else if (isProjectFile) { const originalPath = imp.originalPath || imp.path; markdownOutput += `- \`${originalPath}\` ${impDetails}\n`; if (imp.path !== originalPath) { markdownOutput += ` *Project file: ${imp.path}*\n`; } } else if (isExternalPackage) { const packageName = imp.packageName || (imp.path.startsWith('@') ? imp.path.split('/').slice(0, 2).join('/') : imp.path.split('/')[0]); markdownOutput += `- \`${displayPath}\` ${impDetails}\n`; if (packageName && packageName !== imp.path) { markdownOutput += ` *Package: ${packageName}*\n`; } } else if (imp.path === 'unknown') { markdownOutput += `- \`${displayPath}\` ${impDetails}\n`; if (imp.nodeText) { const cleanNodeText = imp.nodeText.replace(/\s+/g, ' ').trim(); const snippet = cleanNodeText.length > 50 ? cleanNodeText.substring(0, 47) + '...' : cleanNodeText; markdownOutput += ` *Import snippet: \`${snippet}\`*\n`; } else { markdownOutput += ` *Note: This is an unresolved import. It might be a built-in module, an external package, or a local file.*\n`; } } else { markdownOutput += `- \`${displayPath}\` ${impDetails}\n`; } }); markdownOutput += `\n`; } if (fileInfo.classes.length > 0) { markdownOutput += `### Classes\n`; for (const classInfo of fileInfo.classes) { markdownOutput += `- **${classInfo.name}**`; if (classInfo.parentClass) markdownOutput += ` (extends ${classInfo.parentClass})`; if (classInfo.comment) markdownOutput += ` — *${classInfo.comment.split('\n')[0]}*\n`; else markdownOutput += `\n`; if (classInfo.properties && classInfo.properties.length > 0) { classInfo.properties.forEach(prop => { markdownOutput += ` - \`${prop.name}${prop.type ? `: ${prop.type}` : ''}\``; if (prop.comment) markdownOutput += ` — *${prop.comment.split('\n')[0]}*\n`; else markdownOutput += `\n`; }); } for (const method of classInfo.methods) { markdownOutput += ` - \`${method.signature}\``; if (method.comment) markdownOutput += ` — *${method.comment.split('\n')[0]}*\n`; else markdownOutput += `\n`; } } markdownOutput += `\n`; } if (fileInfo.functions.length > 0) { markdownOutput += `### Functions\n`; for (const funcInfo of fileInfo.functions) { markdownOutput += `- \`${funcInfo.signature}\``; if (funcInfo.comment) markdownOutput += ` — *${funcInfo.comment.split('\n')[0]}*\n`; else markdownOutput += `\n`; } markdownOutput += `\n`; } markdownOutput += `\n---\n\n`; } return markdownOutput; } export function optimizeMarkdownOutput(markdown, maxLength = 80000) { if (markdown.length <= maxLength) { return markdown; } const diagramsMarker = "\n## File Dependency Diagram"; const diagramsStart = markdown.indexOf(diagramsMarker); const detailedStructureMarker = "\n## File: "; let detailedStructureStart = markdown.indexOf(detailedStructureMarker); if (detailedStructureStart === -1) { detailedStructureStart = markdown.length / 2; } const truncationMessage = "\n\n... (Output truncated due to length constraints. Some file details might be omitted)"; const availableLengthForDetails = maxLength - (diagramsStart > -1 ? diagramsStart : detailedStructureStart) - truncationMessage.length; if (diagramsStart > -1 && diagramsStart < maxLength * 0.75) { const introAndDiagrams = markdown.substring(0, diagramsStart); let detailsToKeep = ""; if (detailedStructureStart > diagramsStart && availableLengthForDetails > 0) { const detailsSection = markdown.substring(diagramsStart); const lastNewline = detailsSection.substring(0, availableLengthForDetails).lastIndexOf('\n## File: '); detailsToKeep = lastNewline > 0 ? detailsSection.substring(0, lastNewline) : detailsSection.substring(0, availableLengthForDetails); } else if (availableLengthForDetails > 0) { const detailsSection = markdown.substring(detailedStructureStart); const lastNewline = detailsSection.substring(0, availableLengthForDetails).lastIndexOf('\n## File: '); detailsToKeep = lastNewline > 0 ? detailsSection.substring(0, lastNewline) : detailsSection.substring(0, availableLengthForDetails); return markdown.substring(0, detailedStructureStart) + detailsToKeep + truncationMessage; } return introAndDiagrams + detailsToKeep + truncationMessage; } else { let truncatedMarkdown = markdown.substring(0, maxLength - truncationMessage.length); const lastNewline = truncatedMarkdown.lastIndexOf('\n'); if (lastNewline > 0) { truncatedMarkdown = truncatedMarkdown.substring(0, lastNewline); } return truncatedMarkdown + truncationMessage; } }