UNPKG

@toponextech/smartembed-mcp-server

Version:

MCP server for intelligent embedded development with PlatformIO - AI-powered project creation, error diagnosis, and device detection

267 lines 9.34 kB
"use strict"; /** * Error Parser for SmartEmbed * Parses compilation errors and extracts structured information */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ErrorParser = exports.ErrorSeverity = exports.ErrorCategory = exports.ErrorType = void 0; var ErrorType; (function (ErrorType) { ErrorType["COMPILATION"] = "compilation"; ErrorType["LINKING"] = "linking"; ErrorType["SYNTAX"] = "syntax"; ErrorType["DECLARATION"] = "declaration"; ErrorType["LIBRARY"] = "library"; ErrorType["BOARD"] = "board"; ErrorType["MEMORY"] = "memory"; ErrorType["PERMISSION"] = "permission"; ErrorType["UNKNOWN"] = "unknown"; })(ErrorType || (exports.ErrorType = ErrorType = {})); var ErrorCategory; (function (ErrorCategory) { ErrorCategory["BUILD"] = "build"; ErrorCategory["UPLOAD"] = "upload"; ErrorCategory["LIBRARY"] = "library"; ErrorCategory["CONFIGURATION"] = "configuration"; ErrorCategory["HARDWARE"] = "hardware"; })(ErrorCategory || (exports.ErrorCategory = ErrorCategory = {})); var ErrorSeverity; (function (ErrorSeverity) { ErrorSeverity["ERROR"] = "error"; ErrorSeverity["WARNING"] = "warning"; ErrorSeverity["FATAL"] = "fatal"; })(ErrorSeverity || (exports.ErrorSeverity = ErrorSeverity = {})); // Common error patterns const ERROR_PATTERNS = [ // Compilation errors { pattern: /error:\s*'([^']+)'\s+was not declared in this scope/i, type: ErrorType.DECLARATION, extract: (match) => ({ message: `'${match[1]}' was not declared in this scope`, details: { undeclared: match[1] }, }), }, { pattern: /error:\s*'([^']+)'\s+does not name a type/i, type: ErrorType.DECLARATION, extract: (match) => ({ message: `'${match[1]}' does not name a type`, details: { unknownType: match[1] }, }), }, { pattern: /fatal error:\s*([^:]+):\s*No such file or directory/i, type: ErrorType.LIBRARY, extract: (match) => ({ message: `Missing header file: ${match[1]}`, details: { missingFile: match[1] }, }), }, // Library errors { pattern: /Library Manager:\s*([^@]+)@([^\s]+)\s+is already installed/i, type: ErrorType.LIBRARY, extract: (match) => ({ message: `Library ${match[1]} version ${match[2]} is already installed`, details: { library: match[1], version: match[2] }, }), }, { pattern: /Error:\s*Could not find the package with '([^']+)' requirements/i, type: ErrorType.LIBRARY, extract: (match) => ({ message: `Could not find package with requirements: ${match[1]}`, details: { requirements: match[1] }, }), }, // Board/Platform errors { pattern: /Error:\s*Unknown board ID '([^']+)'/i, type: ErrorType.BOARD, extract: (match) => ({ message: `Unknown board ID: ${match[1]}`, details: { boardId: match[1] }, }), }, { pattern: /Platform Manager:\s*platform '([^']+)' is not installed/i, type: ErrorType.BOARD, extract: (match) => ({ message: `Platform '${match[1]}' is not installed`, details: { platform: match[1] }, }), }, // Memory errors { pattern: /region\s+`([^']+)'\s+overflowed by\s+(\d+)\s+bytes/i, type: ErrorType.MEMORY, extract: (match) => ({ message: `Memory region '${match[1]}' overflowed by ${match[2]} bytes`, details: { region: match[1], overflow: parseInt(match[2]) }, }), }, // Upload/Permission errors { pattern: /error opening ([^:]+):\s*([^:]+)/i, type: ErrorType.PERMISSION, extract: (match) => ({ message: `Error opening ${match[1]}: ${match[2]}`, details: { port: match[1], reason: match[2] }, }), }, { pattern: /Access is denied|Permission denied/i, type: ErrorType.PERMISSION, extract: () => ({ message: 'Permission denied when accessing device', details: {}, }), }, // Syntax errors { pattern: /error:\s*expected\s*'([^']+)'\s*before\s*'([^']+)'/i, type: ErrorType.SYNTAX, extract: (match) => ({ message: `Expected '${match[1]}' before '${match[2]}'`, details: { expected: match[1], found: match[2] }, }), }, { pattern: /error:\s*stray\s*'\\(\d+)'\s*in program/i, type: ErrorType.SYNTAX, extract: (match) => ({ message: `Stray character '\\${match[1]}' in program`, details: { character: `\\${match[1]}` }, }), }, // Linking errors { pattern: /undefined reference to\s*`([^']+)'/i, type: ErrorType.LINKING, extract: (match) => ({ message: `Undefined reference to '${match[1]}'`, details: { symbol: match[1] }, }), }, { pattern: /multiple definition of\s*`([^']+)'/i, type: ErrorType.LINKING, extract: (match) => ({ message: `Multiple definition of '${match[1]}'`, details: { symbol: match[1] }, }), }, ]; // File location patterns const FILE_LOCATION_PATTERNS = [ // GCC/G++ style: file.cpp:123:45: error: /^([^:]+):(\d+):(\d+):\s*(error|warning|fatal error):/, // Alternative style: In file included from file.cpp:123: /In file included from ([^:]+):(\d+):/, // Simple style: file.cpp:123: error: /^([^:]+):(\d+):\s*(error|warning):/, ]; class ErrorParser { /** * Parse error output into structured format */ parse(errorOutput) { const errors = []; const lines = errorOutput.split('\n'); for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (!line) continue; // Try to extract file location let fileInfo = {}; for (const pattern of FILE_LOCATION_PATTERNS) { const match = line.match(pattern); if (match) { fileInfo = { file: match[1], line: match[2] ? parseInt(match[2]) : undefined, column: match[3] && !isNaN(parseInt(match[3])) ? parseInt(match[3]) : undefined, }; break; } } // Try to match error patterns let errorInfo = null; let errorType = ErrorType.UNKNOWN; for (const { pattern, type, extract } of ERROR_PATTERNS) { const match = line.match(pattern); if (match) { errorInfo = extract(match); errorType = type; break; } } // If we found an error pattern or this line contains error/warning if (errorInfo || /error:|warning:|fatal error:/i.test(line)) { const severity = /fatal error:/i.test(line) ? ErrorSeverity.FATAL : /warning:/i.test(line) ? ErrorSeverity.WARNING : ErrorSeverity.ERROR; const category = this.categorizeError(errorType); errors.push({ type: errorType, file: fileInfo.file, line: fileInfo.line, column: fileInfo.column, message: errorInfo?.message || this.cleanErrorMessage(line), rawError: line, category, severity, ...errorInfo?.details, }); } } return errors; } /** * Categorize error type into broader categories */ categorizeError(type) { switch (type) { case ErrorType.COMPILATION: case ErrorType.SYNTAX: case ErrorType.DECLARATION: case ErrorType.LINKING: case ErrorType.MEMORY: return ErrorCategory.BUILD; case ErrorType.LIBRARY: return ErrorCategory.LIBRARY; case ErrorType.BOARD: return ErrorCategory.CONFIGURATION; case ErrorType.PERMISSION: return ErrorCategory.UPLOAD; default: return ErrorCategory.BUILD; } } /** * Clean error message by removing file location and prefixes */ cleanErrorMessage(line) { return line .replace(/^[^:]+:\d+(:\d+)?:\s*(error|warning|fatal error):\s*/i, '') .replace(/^\s*\^+\s*$/, '') // Remove caret indicators .trim(); } /** * Aggregate similar errors */ aggregateErrors(errors) { const groups = new Map(); for (const error of errors) { const key = `${error.type}:${error.message}`; if (!groups.has(key)) { groups.set(key, []); } groups.get(key).push(error); } return groups; } } exports.ErrorParser = ErrorParser; //# sourceMappingURL=error-parser.js.map