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.

166 lines (165 loc) 5.55 kB
import resolve from 'resolve'; import * as path from 'path'; import logger from '../../../logger.js'; class LRUCache { cache; maxSize; constructor(maxSize) { this.cache = new Map(); this.maxSize = maxSize; } get(key) { const value = this.cache.get(key); if (value !== undefined) { this.cache.delete(key); this.cache.set(key, value); } return value; } set(key, value) { if (this.cache.has(key)) { this.cache.delete(key); } if (this.cache.size >= this.maxSize) { const firstKey = this.cache.keys().next().value; if (firstKey !== undefined) { this.cache.delete(firstKey); } } this.cache.set(key, value); } has(key) { return this.cache.has(key); } clear() { this.cache.clear(); } get size() { return this.cache.size; } keys() { return this.cache.keys(); } delete(key) { return this.cache.delete(key); } } const importCache = new LRUCache(1000); export function resolveImport(importPath, options) { if (isBuiltinModule(importPath)) { return importPath; } const cacheKey = `${options.fromFile}:${importPath}:${options.language}`; if (options.useCache !== false && importCache.has(cacheKey)) { return importCache.get(cacheKey); } try { if (isExternalPackage(importPath)) { const packageName = getPackageName(importPath); try { const basedir = path.dirname(options.fromFile); const resolvedPackage = resolve.sync(packageName, { basedir, preserveSymlinks: false }); logger.debug({ packageName, resolvedPackage }, 'Package exists but specific import cannot be resolved'); return importPath; } catch (packageError) { logger.debug({ err: packageError, packageName }, 'Package not found'); return importPath; } } const basedir = path.dirname(options.fromFile); const extensions = options.extensions || getDefaultExtensions(options.language); const resolvedPath = resolve.sync(importPath, { basedir, extensions, preserveSymlinks: false }); let finalPath = resolvedPath; if (options.projectRoot) { if (resolvedPath.startsWith(options.projectRoot)) { finalPath = path.relative(options.projectRoot, resolvedPath); finalPath = finalPath.replace(/\\/g, '/'); if (!finalPath.startsWith('./') && !finalPath.startsWith('../')) { finalPath = `./${finalPath}`; } logger.debug({ originalPath: importPath, resolvedPath, finalPath, projectRoot: options.projectRoot }, 'Resolved import path relative to project root'); } else { logger.debug({ originalPath: importPath, resolvedPath, projectRoot: options.projectRoot }, 'Resolved import path is outside project root'); } } if (options.useCache !== false) { importCache.set(cacheKey, finalPath); } return finalPath; } catch (error) { logger.debug({ err: error, importPath, fromFile: options.fromFile }, 'Error resolving import'); return importPath; } } export function clearImportCache() { importCache.clear(); } export function getImportCacheSize() { return importCache.size; } function isBuiltinModule(moduleName) { const builtinModules = [ 'assert', 'buffer', 'child_process', 'cluster', 'console', 'constants', 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'module', 'net', 'os', 'path', 'perf_hooks', 'process', 'punycode', 'querystring', 'readline', 'repl', 'stream', 'string_decoder', 'timers', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib' ]; return builtinModules.includes(moduleName); } function isExternalPackage(moduleName) { return !moduleName.startsWith('.') && !moduleName.startsWith('/') && !isBuiltinModule(moduleName); } function getPackageName(moduleName) { if (moduleName.startsWith('@')) { const parts = moduleName.split('/'); if (parts.length >= 2) { return `${parts[0]}/${parts[1]}`; } } const parts = moduleName.split('/'); return parts[0]; } function getDefaultExtensions(language) { switch (language) { case 'javascript': return ['.js', '.json', '.node', '.mjs', '.cjs']; case 'typescript': return ['.ts', '.tsx', '.js', '.jsx', '.json', '.node']; case 'python': return ['.py', '.pyw', '.pyc', '.pyo', '.pyd']; case 'java': return ['.java', '.class', '.jar']; case 'csharp': return ['.cs', '.dll']; case 'go': return ['.go']; case 'ruby': return ['.rb', '.rake', '.gemspec']; case 'rust': return ['.rs']; case 'php': return ['.php']; default: return ['.js', '.json', '.node']; } }