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.

190 lines (189 loc) 6.75 kB
import { BaseLanguageHandler } from './base.js'; import { getNodeText } from '../astAnalyzer.js'; import logger from '../../../logger.js'; export class BashHandler extends BaseLanguageHandler { options; getFunctionQueryPatterns() { return [ 'function_definition', 'declaration_command' ]; } getClassQueryPatterns() { return [ 'program' ]; } getImportQueryPatterns() { return [ 'source_command', 'command' ]; } extractFunctionName(node, sourceCode, _options) { try { if (node.type === 'function_definition') { const nameNode = node.childForFieldName('name'); if (nameNode) { const name = getNodeText(nameNode, sourceCode); if (name.startsWith('test_')) { return name; } if (this.isHookFunction(name)) { return `hook_${name}`; } return name; } } if (node.type === 'declaration_command') { const commandNode = node.childForFieldName('command'); if (commandNode?.text === 'function') { const nameNode = node.childForFieldName('name'); if (nameNode) { const name = getNodeText(nameNode, sourceCode); if (name.startsWith('test_')) { return name; } if (this.isHookFunction(name)) { return `hook_${name}`; } return name; } } } return 'anonymous'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Bash/Shell function name'); return 'anonymous'; } } isHookFunction(name) { const hookFunctions = [ 'pre_install', 'post_install', 'pre_upgrade', 'post_upgrade', 'pre_remove', 'post_remove', 'setup', 'teardown', 'before_script', 'after_script' ]; return hookFunctions.includes(name); } extractClassName(node, _sourceCode) { try { if (node.type === 'program' && this.options?.filePath) { const filename = this.options.filePath.split('/').pop() || 'script'; return filename.replace(/\.[^.]+$/, ''); } return 'Script'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Bash/Shell class name'); return 'Script'; } } extractImportPath(node, sourceCode) { try { if (node.type === 'source_command') { const pathNode = node.childForFieldName('path'); if (pathNode) { return getNodeText(pathNode, sourceCode); } } else if (node.type === 'command') { const nameNode = node.childForFieldName('name'); if (nameNode && (nameNode.text === 'source' || nameNode.text === '.')) { const argumentNode = node.childForFieldName('argument'); if (argumentNode) { return getNodeText(argumentNode, sourceCode); } } } return 'unknown'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Bash/Shell import path'); return 'unknown'; } } extractFunctionComment(node, sourceCode) { try { const current = node; let prev = current.previousNamedSibling; while (prev && prev.type !== 'comment') { prev = prev.previousNamedSibling; } if (prev && prev.type === 'comment') { const commentText = getNodeText(prev, sourceCode); return commentText .replace(/^#\s*/mg, '') .trim(); } return undefined; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Bash/Shell function comment'); return undefined; } } extractClassComment(node, sourceCode) { try { if (node.type === 'program') { const firstChild = node.firstChild; if (firstChild?.type === 'shebang') { return `Shell: ${getNodeText(firstChild, sourceCode)}`; } let commentBlock = ''; let current = node.firstChild; if (current?.type === 'shebang') { current = current.nextNamedSibling; } while (current && current.type === 'comment') { commentBlock += getNodeText(current, sourceCode).replace(/^#\s*/mg, '') + '\n'; current = current.nextNamedSibling; } if (commentBlock) { return commentBlock.trim(); } } return undefined; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Bash/Shell class comment'); return undefined; } } detectFramework(sourceCode) { try { if (sourceCode.includes('docker ') || sourceCode.includes('Dockerfile') || sourceCode.includes('docker-compose')) { return 'docker'; } if (sourceCode.includes('ansible-playbook') || sourceCode.includes('ansible-galaxy') || sourceCode.includes('ansible ')) { return 'ansible'; } if (sourceCode.includes('kubectl ') || sourceCode.includes('kubelet') || sourceCode.includes('kubernetes')) { return 'kubernetes'; } if (sourceCode.includes('aws ') || sourceCode.includes('AWS_') || sourceCode.includes('aws-cli')) { return 'aws'; } return null; } catch (error) { logger.warn({ err: error }, 'Error detecting Bash/Shell framework'); return null; } } }