UNPKG

@ai-capabilities-suite/mcp-debugger-core

Version:

Core debugging engine for Node.js and TypeScript applications. Provides Inspector Protocol integration, breakpoint management, variable inspection, execution control, profiling, hang detection, and source map support.

338 lines 12.4 kB
"use strict"; /** * Smart breakpoint suggestions based on code analysis * Recommends breakpoint locations for common debugging scenarios */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.BreakpointSuggester = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); /** * Suggests breakpoint locations based on code analysis */ class BreakpointSuggester { /** * Suggest breakpoints for a file */ suggestBreakpoints(filePath, context) { if (!fs.existsSync(filePath)) { return []; } const content = fs.readFileSync(filePath, "utf-8"); const lines = content.split("\n"); const suggestions = []; // Analyze based on context if (context?.scenario === "error" && context.errorMessage) { suggestions.push(...this.suggestForError(filePath, lines, context)); } else if (context?.scenario === "test-failure") { suggestions.push(...this.suggestForTestFailure(filePath, lines, context)); } else if (context?.scenario === "performance") { suggestions.push(...this.suggestForPerformance(filePath, lines)); } else { suggestions.push(...this.suggestGeneral(filePath, lines)); } // Sort by priority return suggestions.sort((a, b) => { const priorityOrder = { high: 0, medium: 1, low: 2 }; return priorityOrder[a.priority] - priorityOrder[b.priority]; }); } /** * Suggest breakpoints for error scenarios */ suggestForError(filePath, lines, context) { const suggestions = []; // Suggest breakpoints at throw statements lines.forEach((line, index) => { if (line.match(/\bthrow\s+/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Error is thrown here", priority: "high", }); } }); // Suggest breakpoints at error handling lines.forEach((line, index) => { if (line.match(/\bcatch\s*\(/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Error is caught here", priority: "high", }); } }); // Suggest breakpoints at null/undefined checks lines.forEach((line, index) => { if (line.match(/===?\s*(null|undefined)|null|undefined\s*===?/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Null/undefined check - potential source of error", priority: "medium", }); } }); return suggestions; } /** * Suggest breakpoints for test failure scenarios */ suggestForTestFailure(filePath, lines, context) { const suggestions = []; // Suggest breakpoints at assertions lines.forEach((line, index) => { if (line.match(/\b(expect|assert|should)\s*\(/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Assertion - check test expectations", priority: "high", }); } }); // Suggest breakpoints at test setup lines.forEach((line, index) => { if (line.match(/\b(beforeEach|beforeAll|setUp)\s*\(/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Test setup - verify initial state", priority: "medium", }); } }); return suggestions; } /** * Suggest breakpoints for performance scenarios */ suggestForPerformance(filePath, lines) { const suggestions = []; // Suggest breakpoints at loops lines.forEach((line, index) => { if (line.match(/\b(for|while|do)\s*[\(\{]/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Loop - potential performance bottleneck", priority: "high", }); } }); // Suggest breakpoints at recursive calls lines.forEach((line, index) => { if (line.match(/\bfunction\s+(\w+)/) || line.match(/const\s+(\w+)\s*=\s*\(/)) { const functionName = line.match(/\bfunction\s+(\w+)/)?.[1] || line.match(/const\s+(\w+)\s*=\s*\(/)?.[1]; if (functionName) { // Check if function calls itself const functionBody = lines.slice(index).join("\n"); if (functionBody.match(new RegExp(`\\b${functionName}\\s*\\(`))) { suggestions.push({ file: filePath, line: index + 1, reason: "Recursive function - check for infinite recursion", priority: "high", }); } } } }); // Suggest breakpoints at database/network calls lines.forEach((line, index) => { if (line.match(/\b(fetch|axios|http|query|execute)\s*\(/)) { suggestions.push({ file: filePath, line: index + 1, reason: "External call - potential performance issue", priority: "medium", }); } }); return suggestions; } /** * Suggest general breakpoints */ suggestGeneral(filePath, lines) { const suggestions = []; // Suggest breakpoints at function entries lines.forEach((line, index) => { if (line.match(/\bfunction\s+\w+\s*\(/) || line.match(/\b\w+\s*:\s*function\s*\(/) || line.match(/\b\w+\s*=\s*\([^)]*\)\s*=>/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Function entry point", priority: "medium", }); } }); // Suggest breakpoints at class methods lines.forEach((line, index) => { if (line.match(/^\s*(public|private|protected)?\s*\w+\s*\([^)]*\)\s*[:{]/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Method entry point", priority: "medium", }); } }); // Suggest breakpoints at conditional branches lines.forEach((line, index) => { if (line.match(/\bif\s*\(/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Conditional branch - check logic flow", priority: "low", }); } }); // Suggest breakpoints at return statements lines.forEach((line, index) => { if (line.match(/\breturn\s+/)) { suggestions.push({ file: filePath, line: index + 1, reason: "Return statement - check return value", priority: "low", }); } }); return suggestions; } /** * Suggest conditional breakpoints based on context */ suggestConditionalBreakpoints(filePath, context) { if (!fs.existsSync(filePath)) { return []; } const content = fs.readFileSync(filePath, "utf-8"); const lines = content.split("\n"); const suggestions = []; // Suggest conditional breakpoints for loops lines.forEach((line, index) => { const loopMatch = line.match(/for\s*\(\s*let\s+(\w+)\s*=/); if (loopMatch) { const variable = loopMatch[1]; suggestions.push({ file: filePath, line: index + 1, reason: "Loop iteration - break on specific iteration", condition: `${variable} === 10`, priority: "medium", }); } }); // Suggest conditional breakpoints for error conditions if (context.errorMessage) { lines.forEach((line, index) => { const variableMatch = line.match(/\b(const|let|var)\s+(\w+)\s*=/); if (variableMatch) { const variable = variableMatch[2]; suggestions.push({ file: filePath, line: index + 1, reason: "Variable assignment - break on specific value", condition: `${variable} === null || ${variable} === undefined`, priority: "medium", }); } }); } return suggestions; } /** * Suggest breakpoints based on stack trace */ suggestFromStackTrace(stackTrace) { const suggestions = []; for (const frame of stackTrace) { // Parse stack frame: "at functionName (file:line:column)" const match = frame.match(/at\s+.*?\s*\(([^:]+):(\d+):\d+\)/); if (match) { const [, file, lineStr] = match; const line = parseInt(lineStr, 10); suggestions.push({ file: path.resolve(file), line, reason: "Stack trace location", priority: "high", }); } } return suggestions; } /** * Suggest breakpoints for common debugging scenarios */ suggestForScenario(scenario, filePath) { const scenarios = { "null-pointer": { scenario: "error", errorMessage: "Cannot read property of null", }, "infinite-loop": { scenario: "performance", }, "test-failure": { scenario: "test-failure", }, "async-issue": { scenario: "error", errorMessage: "Promise rejection", }, }; const context = scenarios[scenario]; if (!context) { return []; } return this.suggestBreakpoints(filePath, context); } } exports.BreakpointSuggester = BreakpointSuggester; //# sourceMappingURL=breakpoint-suggester.js.map