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.

218 lines (217 loc) 9.7 kB
import { getNodeText } from '../astAnalyzer.js'; import logger from '../../../logger.js'; export function isLikelyImport(node) { try { const text = node.text.toLowerCase(); return text.includes('import') || text.includes('require') || text.includes('from'); } catch (error) { logger.debug({ err: error, nodeType: node.type }, 'Error checking if node is likely an import'); return false; } } export function tryExtractImportPath(node) { try { const text = node.text; const importFromMatch = text.match(/from\s+['"]([^'"]+)['"]/); if (importFromMatch && importFromMatch[1]) { return importFromMatch[1]; } const dynamicImportMatch = text.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/); if (dynamicImportMatch && dynamicImportMatch[1]) { return dynamicImportMatch[1]; } const requireMatch = text.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/); if (requireMatch && requireMatch[1]) { return requireMatch[1]; } return null; } catch (error) { logger.debug({ err: error, nodeType: node.type }, 'Error extracting import path with regex'); return null; } } export function extractJSImports(node, sourceCode) { const imports = []; try { switch (node.type) { case 'import_statement': case 'import_declaration': { const source = node.childForFieldName('source'); if (source && source.text) { const path = source.text.replace(/['"`]/g, ''); imports.push({ path, type: 'static', isExternalPackage: !path.startsWith('.') && !path.startsWith('/'), importedItems: extractImportedItemsFromES6Import(node, sourceCode), startLine: node.startPosition.row + 1, endLine: node.endPosition.row + 1 }); } break; } case 'call_expression': { const funcName = node.childForFieldName('function')?.text; if (funcName === 'import') { const args = node.childForFieldName('arguments'); const firstArg = args?.firstChild; if (firstArg && firstArg.text) { const path = firstArg.text.replace(/['"`]/g, ''); imports.push({ path, type: 'dynamic', isExternalPackage: !path.startsWith('.') && !path.startsWith('/'), startLine: node.startPosition.row + 1, endLine: node.endPosition.row + 1 }); } } else if (funcName === 'require') { const args = node.childForFieldName('arguments'); const firstArg = args?.firstChild; if (firstArg && firstArg.text) { const path = firstArg.text.replace(/['"`]/g, ''); imports.push({ path, type: 'commonjs', isExternalPackage: !path.startsWith('.') && !path.startsWith('/'), startLine: node.startPosition.row + 1, endLine: node.endPosition.row + 1 }); } } break; } case 'variable_declaration': { const declarator = node.childForFieldName('declarator'); const value = declarator?.childForFieldName('value'); if (value?.type === 'call_expression' && value.childForFieldName('function')?.text === 'require') { const args = value.childForFieldName('arguments'); const firstArg = args?.firstChild; if (firstArg && firstArg.text) { const path = firstArg.text.replace(/['"`]/g, ''); imports.push({ path, type: 'commonjs', isExternalPackage: !path.startsWith('.') && !path.startsWith('/'), startLine: node.startPosition.row + 1, endLine: node.endPosition.row + 1 }); } } break; } } if (imports.length === 0 && isLikelyImport(node)) { const extractedPath = tryExtractImportPath(node); if (extractedPath) { imports.push({ path: extractedPath, type: node.text.includes('import(') ? 'dynamic' : node.text.includes('require(') ? 'commonjs' : 'extracted', isExternalPackage: !extractedPath.startsWith('.') && !extractedPath.startsWith('/'), startLine: node.startPosition.row + 1, endLine: node.endPosition.row + 1 }); } } } catch (error) { logger.debug({ err: error, nodeType: node.type }, 'Error extracting JS/TS imports'); } return imports; } export function extractImportedItemsFromES6Import(node, sourceCode) { try { const items = []; if (node.type === 'import_statement' || node.type === 'import_declaration') { const defaultSpecifier = node.childForFieldName('default'); if (defaultSpecifier) { items.push({ name: getNodeText(defaultSpecifier, sourceCode), isDefault: true, isNamespace: false }); } const namedImports = node.childForFieldName('named_imports'); if (namedImports) { for (let i = 0; i < namedImports.namedChildCount; i++) { const specifier = namedImports.namedChild(i); if (specifier) { const importedName = specifier.childForFieldName('name'); const aliasName = specifier.childForFieldName('alias'); if (importedName) { items.push({ name: getNodeText(importedName, sourceCode), alias: aliasName ? getNodeText(aliasName, sourceCode) : undefined, isDefault: false, isNamespace: false }); } } } } const namespaceImport = node.childForFieldName('namespace_import'); if (namespaceImport) { const name = namespaceImport.childForFieldName('name'); if (name) { items.push({ name: getNodeText(name, sourceCode), isDefault: false, isNamespace: true }); } } const importClause = node.childForFieldName('import_clause'); if (importClause) { const defaultImport = importClause.childForFieldName('default'); if (defaultImport) { items.push({ name: getNodeText(defaultImport, sourceCode), isDefault: true, isNamespace: false }); } const namedImportsInClause = importClause.childForFieldName('named_imports'); if (namedImportsInClause && namedImportsInClause.namedChildCount > 0) { for (let i = 0; i < namedImportsInClause.namedChildCount; i++) { const specifier = namedImportsInClause.namedChild(i); if (specifier) { const importedName = specifier.childForFieldName('name'); const aliasName = specifier.childForFieldName('alias'); if (importedName) { items.push({ name: getNodeText(importedName, sourceCode), alias: aliasName ? getNodeText(aliasName, sourceCode) : undefined, isDefault: false, isNamespace: false }); } } } } const namespaceImportInClause = importClause.childForFieldName('namespace_import'); if (namespaceImportInClause) { const name = namespaceImportInClause.childForFieldName('name'); if (name) { items.push({ name: getNodeText(name, sourceCode), isDefault: false, isNamespace: true }); } } } } return items.length > 0 ? items : undefined; } catch (error) { logger.debug({ err: error, nodeType: node.type }, 'Error extracting imported items from ES6 import'); return undefined; } }