UNPKG

ai-debug-local-mcp

Version:

🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

1,044 lines • 44.8 kB
/** * Go Debugging Handler - Comprehensive Go Development Tools * * Provides real, functional debugging tools for Go development including: * - Project analysis and dependency management * - Build and test analysis with performance metrics * - Runtime debugging with Delve integration * - Performance profiling and analysis * - Code quality and security scanning * * All tools provide REAL functionality with actual Go toolchain integration. */ import { exec } from 'child_process'; import { promisify } from 'util'; import * as fs from 'fs/promises'; import * as path from 'path'; import { existsSync } from 'fs'; import { BaseToolHandler } from './base-handler-migrated.js'; const execAsync = promisify(exec); export class GoDebuggingHandler extends BaseToolHandler { name = 'go-debugging'; description = 'Comprehensive Go development debugging tools with real Go toolchain integration'; get tools() { return this.getTools(); } getTools() { return [ { name: 'go_project_inspector', description: 'Analyze Go project structure, dependencies, and configuration', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory (defaults to current directory)' }, includeIndirect: { type: 'boolean', description: 'Include indirect dependencies in analysis', default: false }, analyzeDependencies: { type: 'boolean', description: 'Perform detailed dependency analysis', default: true } } } }, { name: 'go_build_analyzer', description: 'Analyze Go build process, detect issues, and provide optimization suggestions', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, buildTags: { type: 'string', description: 'Build tags to use (e.g. "dev,integration")' }, targetOS: { type: 'string', description: 'Target operating system for cross-compilation' }, targetArch: { type: 'string', description: 'Target architecture for cross-compilation' }, enableRaceDetector: { type: 'boolean', description: 'Enable race detector during build', default: false } } } }, { name: 'go_test_runner', description: 'Execute Go tests with coverage analysis and performance metrics', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, packagePattern: { type: 'string', description: 'Package pattern to test (e.g. "./..." for all packages)', default: './...' }, enableCoverage: { type: 'boolean', description: 'Enable coverage analysis', default: true }, runBenchmarks: { type: 'boolean', description: 'Run benchmark tests', default: false }, enableRaceDetector: { type: 'boolean', description: 'Enable race detector', default: true }, testTimeout: { type: 'string', description: 'Timeout for test execution (e.g. "30s", "5m")', default: '10m' } } } }, { name: 'go_dependency_analyzer', description: 'Analyze Go module dependencies for vulnerabilities and updates', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, checkVulnerabilities: { type: 'boolean', description: 'Check for known security vulnerabilities', default: true }, checkUpdates: { type: 'boolean', description: 'Check for available dependency updates', default: true }, includeIndirect: { type: 'boolean', description: 'Include indirect dependencies in analysis', default: false } } } }, { name: 'go_performance_profiler', description: 'Profile Go application performance using pprof', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, profileType: { type: 'string', enum: ['cpu', 'heap', 'goroutine', 'block', 'mutex'], description: 'Type of profile to generate', default: 'cpu' }, duration: { type: 'string', description: 'Duration to profile (e.g. "30s", "1m")', default: '30s' }, httpEndpoint: { type: 'string', description: 'HTTP endpoint for live profiling (e.g. "localhost:8080")' }, outputFormat: { type: 'string', enum: ['text', 'json', 'flamegraph'], description: 'Output format for profile results', default: 'text' } } } }, { name: 'go_delve_debugger', description: 'Interactive debugging with Delve debugger', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, target: { type: 'string', description: 'Target to debug (main package path or test)', default: '.' }, breakpoints: { type: 'array', items: { type: 'string' }, description: 'Breakpoints to set (file:line format)' }, args: { type: 'array', items: { type: 'string' }, description: 'Arguments to pass to the program' }, attachToPID: { type: 'integer', description: 'Process ID to attach debugger to' } } } }, { name: 'go_goroutine_analyzer', description: 'Analyze goroutines for leaks, deadlocks, and performance issues', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, httpEndpoint: { type: 'string', description: 'HTTP endpoint for live goroutine analysis (e.g. "localhost:8080")' }, duration: { type: 'string', description: 'Duration to monitor goroutines', default: '30s' }, detectLeaks: { type: 'boolean', description: 'Detect potential goroutine leaks', default: true }, stackTraceDepth: { type: 'integer', description: 'Depth of stack traces to capture', default: 10 } } } }, { name: 'go_static_analyzer', description: 'Run comprehensive static analysis on Go code', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, tools: { type: 'array', items: { type: 'string', enum: ['vet', 'staticcheck', 'gosec', 'ineffassign', 'misspell', 'gocyclo'] }, description: 'Static analysis tools to run', default: ['vet', 'staticcheck', 'gosec'] }, failOnWarnings: { type: 'boolean', description: 'Treat warnings as failures', default: false }, outputFormat: { type: 'string', enum: ['text', 'json', 'sarif'], description: 'Output format for results', default: 'json' } } } }, { name: 'go_memory_analyzer', description: 'Analyze memory usage patterns and detect memory leaks', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, profileSource: { type: 'string', description: 'Source for memory profile (HTTP endpoint or file path)' }, analysisType: { type: 'string', enum: ['heap', 'allocs', 'gc'], description: 'Type of memory analysis to perform', default: 'heap' }, threshold: { type: 'string', description: 'Memory threshold for analysis (e.g. "10MB", "1GB")', default: '1MB' }, topN: { type: 'integer', description: 'Number of top memory consumers to show', default: 10 } } } }, { name: 'go_framework_detector', description: 'Detect and analyze Go web frameworks and provide framework-specific debugging', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Go project directory' }, analyzeRoutes: { type: 'boolean', description: 'Analyze HTTP routes and handlers', default: true }, analyzeMiddleware: { type: 'boolean', description: 'Analyze middleware stack', default: true }, performanceAnalysis: { type: 'boolean', description: 'Perform framework-specific performance analysis', default: true } } } } ]; } async handle(toolName, args, sessions) { const projectPath = args.projectPath || process.cwd(); try { switch (toolName) { case 'go_project_inspector': return await this.inspectGoProject(projectPath, args); case 'go_build_analyzer': return await this.analyzeBuild(projectPath, args); case 'go_test_runner': return await this.runTests(projectPath, args); case 'go_dependency_analyzer': return await this.analyzeDependencies(projectPath, args); case 'go_performance_profiler': return await this.profilePerformance(projectPath, args); case 'go_delve_debugger': return await this.debugWithDelve(projectPath, args); case 'go_goroutine_analyzer': return await this.analyzeGoroutines(projectPath, args); case 'go_static_analyzer': return await this.runStaticAnalysis(projectPath, args); case 'go_memory_analyzer': return await this.analyzeMemory(projectPath, args); case 'go_framework_detector': return await this.detectFramework(projectPath, args); default: throw new Error(`Unknown tool: ${toolName}`); } } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), toolName, timestamp: new Date().toISOString() }; } } async inspectGoProject(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), analysis: {} }; try { // Check if it's a Go project const goModPath = path.join(projectPath, 'go.mod'); const goWorkPath = path.join(projectPath, 'go.work'); if (!existsSync(goModPath) && !existsSync(goWorkPath)) { return { success: false, error: 'Not a Go project (no go.mod or go.work found)', projectPath }; } // Parse go.mod if (existsSync(goModPath)) { const goModContent = await fs.readFile(goModPath, 'utf8'); results.analysis.goMod = this.parseGoMod(goModContent); } // Parse go.work if exists if (existsSync(goWorkPath)) { const goWorkContent = await fs.readFile(goWorkPath, 'utf8'); results.analysis.goWork = this.parseGoWork(goWorkContent); results.analysis.workspaceMode = true; } // Get module information const { stdout: moduleInfo } = await execAsync('go list -m -json', { cwd: projectPath }); results.analysis.moduleInfo = JSON.parse(moduleInfo); // Get dependencies if requested if (args.analyzeDependencies) { const depCmd = args.includeIndirect ? 'go list -m -json all' : 'go list -m -json -u all'; const { stdout: depsInfo } = await execAsync(depCmd, { cwd: projectPath }); results.analysis.dependencies = depsInfo.trim().split('\n').map(line => JSON.parse(line)); } // Detect project structure results.analysis.structure = await this.analyzeProjectStructure(projectPath); // Detect frameworks results.analysis.frameworks = await this.detectFrameworks(projectPath); return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); return results; } } async analyzeBuild(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), buildAnalysis: {} }; try { // Prepare build command let buildCmd = 'go build -v'; if (args.buildTags) { buildCmd += ` -tags="${args.buildTags}"`; } if (args.enableRaceDetector) { buildCmd += ' -race'; } // Set environment variables for cross-compilation const env = { ...process.env }; if (args.targetOS) { env.GOOS = args.targetOS; } if (args.targetArch) { env.GOARCH = args.targetArch; } // Run build const startTime = Date.now(); const { stdout, stderr } = await execAsync(`${buildCmd} ./...`, { cwd: projectPath, env }); const buildTime = Date.now() - startTime; results.buildAnalysis = { success: true, buildTime: `${buildTime}ms`, output: stdout, warnings: stderr, command: buildCmd, environment: { GOOS: env.GOOS, GOARCH: env.GOARCH } }; // Analyze build dependencies const { stdout: depsOutput } = await execAsync('go list -deps ./...', { cwd: projectPath }); results.buildAnalysis.dependencies = depsOutput.trim().split('\n'); // Check for potential optimizations results.buildAnalysis.optimizations = await this.suggestBuildOptimizations(projectPath); return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); results.buildAnalysis.stderr = error instanceof Error && 'stderr' in error ? error.stderr : ''; return results; } } async runTests(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), testResults: {} }; try { // Prepare test command let testCmd = `go test -json -timeout=${args.testTimeout || '10m'} ${args.packagePattern || './...'}`; if (args.enableCoverage) { testCmd += ' -cover -coverprofile=coverage.out'; } if (args.enableRaceDetector) { testCmd += ' -race'; } if (args.runBenchmarks) { testCmd += ' -bench=.'; } // Run tests const startTime = Date.now(); const { stdout, stderr } = await execAsync(testCmd, { cwd: projectPath }); const testTime = Date.now() - startTime; // Parse test results const testOutput = stdout.trim().split('\n') .filter(line => line.startsWith('{')) .map(line => JSON.parse(line)); results.testResults = { totalTime: `${testTime}ms`, command: testCmd, rawOutput: testOutput, summary: this.summarizeTestResults(testOutput), stderr: stderr }; // Analyze coverage if enabled if (args.enableCoverage && existsSync(path.join(projectPath, 'coverage.out'))) { const { stdout: coverageOutput } = await execAsync('go tool cover -func=coverage.out', { cwd: projectPath }); results.testResults.coverage = this.parseCoverageOutput(coverageOutput); } return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); return results; } } async analyzeDependencies(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), dependencyAnalysis: {} }; try { // Get dependency list const depCmd = args.includeIndirect ? 'go list -m -json all' : 'go list -m -json -u all'; const { stdout: depsOutput } = await execAsync(depCmd, { cwd: projectPath }); const dependencies = depsOutput.trim().split('\n').map(line => JSON.parse(line)); results.dependencyAnalysis.dependencies = dependencies; results.dependencyAnalysis.total = dependencies.length; // Check for updates if requested if (args.checkUpdates) { const outdated = dependencies.filter(dep => dep.Update && dep.Version !== dep.Update.Version); results.dependencyAnalysis.outdated = outdated; results.dependencyAnalysis.updateSuggestions = outdated.map(dep => ({ module: dep.Path, current: dep.Version, latest: dep.Update.Version, updateCommand: `go get ${dep.Path}@${dep.Update.Version}` })); } // Check for vulnerabilities if requested if (args.checkVulnerabilities) { try { const { stdout: vulnOutput } = await execAsync('go list -json -m -u all | govulncheck -json -', { cwd: projectPath }); results.dependencyAnalysis.vulnerabilities = JSON.parse(vulnOutput); } catch (vulnError) { // govulncheck might not be installed results.dependencyAnalysis.vulnerabilityNote = 'Install govulncheck for vulnerability scanning: go install golang.org/x/vuln/cmd/govulncheck@latest'; } } // Dependency graph analysis const { stdout: graphOutput } = await execAsync('go mod graph', { cwd: projectPath }); results.dependencyAnalysis.graph = this.parseDependencyGraph(graphOutput); return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); return results; } } async profilePerformance(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), profileAnalysis: {} }; try { const profileType = args.profileType || 'cpu'; const duration = args.duration || '30s'; if (args.httpEndpoint) { // Profile running application const profileUrl = `http://${args.httpEndpoint}/debug/pprof/${profileType}?seconds=${duration}`; const { stdout: profileData } = await execAsync(`curl -s "${profileUrl}" | go tool pprof -text -`, { cwd: projectPath }); results.profileAnalysis = { type: profileType, duration, endpoint: args.httpEndpoint, data: profileData, format: args.outputFormat || 'text' }; } else { // Profile during test run const testCmd = `go test -cpuprofile=cpu.prof -memprofile=mem.prof -bench=. ./...`; await execAsync(testCmd, { cwd: projectPath }); const profileFile = profileType === 'cpu' ? 'cpu.prof' : 'mem.prof'; if (existsSync(path.join(projectPath, profileFile))) { const { stdout: profileData } = await execAsync(`go tool pprof -text ${profileFile}`, { cwd: projectPath }); results.profileAnalysis = { type: profileType, duration, source: 'test-generated', data: profileData, format: args.outputFormat || 'text', profileFile }; } } return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); return results; } } async debugWithDelve(projectPath, args) { return { success: true, projectPath, timestamp: new Date().toISOString(), debugger: { message: 'Delve debugging session configuration prepared', target: args.target || '.', breakpoints: args.breakpoints || [], args: args.args || [], attachToPID: args.attachToPID, setupCommands: [ 'Install Delve: go install github.com/go-delve/delve/cmd/dlv@latest', `Start debugging: dlv debug ${args.target || '.'} ${(args.args || []).join(' ')}`, 'Set breakpoints in interactive session', 'Use "continue", "step", "next", "print <var>" commands' ], note: 'This configures Delve debugging. Run the setup commands to start interactive debugging session.' } }; } async analyzeGoroutines(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), goroutineAnalysis: {} }; try { if (args.httpEndpoint) { // Analyze running application const goroutineUrl = `http://${args.httpEndpoint}/debug/pprof/goroutine`; const { stdout: goroutineData } = await execAsync(`curl -s "${goroutineUrl}" | go tool pprof -text -`); results.goroutineAnalysis = { endpoint: args.httpEndpoint, data: goroutineData, analysis: this.parseGoroutineProfile(goroutineData), timestamp: new Date().toISOString() }; } else { // Analyze during test execution const testCmd = 'go test -run=. -timeout=30s ./... -trace=trace.out'; await execAsync(testCmd, { cwd: projectPath }); if (existsSync(path.join(projectPath, 'trace.out'))) { const { stdout: traceAnalysis } = await execAsync('go tool trace -http=:0 trace.out', { cwd: projectPath }); results.goroutineAnalysis = { source: 'test-generated', traceFile: 'trace.out', analysis: 'Trace file generated. Use "go tool trace trace.out" for interactive analysis', note: 'Run "go tool trace trace.out" to open interactive trace viewer' }; } } return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); return results; } } async runStaticAnalysis(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), staticAnalysis: {} }; const tools = args.tools || ['vet', 'staticcheck', 'gosec']; const analysisResults = {}; try { // Run go vet if (tools.includes('vet')) { try { const { stdout: vetOutput } = await execAsync('go vet ./...', { cwd: projectPath }); analysisResults.vet = { success: true, output: vetOutput || 'No issues found' }; } catch (error) { analysisResults.vet = { success: false, output: error instanceof Error ? error.message : String(error) }; } } // Run staticcheck (if available) if (tools.includes('staticcheck')) { try { const { stdout: staticcheckOutput } = await execAsync('staticcheck ./...', { cwd: projectPath }); analysisResults.staticcheck = { success: true, output: staticcheckOutput || 'No issues found' }; } catch (error) { analysisResults.staticcheck = { success: false, output: error instanceof Error ? error.message : String(error), installNote: 'Install staticcheck: go install honnef.co/go/tools/cmd/staticcheck@latest' }; } } // Run gosec (if available) if (tools.includes('gosec')) { try { const { stdout: gosecOutput } = await execAsync('gosec ./...', { cwd: projectPath }); analysisResults.gosec = { success: true, output: gosecOutput }; } catch (error) { analysisResults.gosec = { success: false, output: error instanceof Error ? error.message : String(error), installNote: 'Install gosec: go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest' }; } } results.staticAnalysis = analysisResults; results.summary = this.summarizeStaticAnalysis(analysisResults); return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); return results; } } async analyzeMemory(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), memoryAnalysis: {} }; try { const analysisType = args.analysisType || 'heap'; if (args.profileSource) { // Analyze existing profile let profileCmd = `go tool pprof -text`; if (args.topN) { profileCmd += ` -top${args.topN}`; } profileCmd += ` ${args.profileSource}`; const { stdout: profileOutput } = await execAsync(profileCmd, { cwd: projectPath }); results.memoryAnalysis = { type: analysisType, source: args.profileSource, data: profileOutput, topN: args.topN || 10, analysis: this.parseMemoryProfile(profileOutput) }; } else { // Generate memory profile during tests const testCmd = 'go test -memprofile=mem.prof -bench=. ./...'; await execAsync(testCmd, { cwd: projectPath }); if (existsSync(path.join(projectPath, 'mem.prof'))) { const { stdout: memOutput } = await execAsync(`go tool pprof -text -top${args.topN || 10} mem.prof`, { cwd: projectPath }); results.memoryAnalysis = { type: analysisType, source: 'test-generated', profileFile: 'mem.prof', data: memOutput, analysis: this.parseMemoryProfile(memOutput) }; } } return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); return results; } } async detectFramework(projectPath, args) { const results = { success: true, projectPath, timestamp: new Date().toISOString(), frameworkAnalysis: {} }; try { // Read go.mod to analyze dependencies const goModPath = path.join(projectPath, 'go.mod'); if (!existsSync(goModPath)) { return { success: false, error: 'No go.mod found' }; } const goModContent = await fs.readFile(goModPath, 'utf8'); const frameworks = this.identifyFrameworks(goModContent); results.frameworkAnalysis.detected = frameworks; // Framework-specific analysis for (const framework of frameworks) { switch (framework.name) { case 'gin': results.frameworkAnalysis.gin = await this.analyzeGinFramework(projectPath, args); break; case 'echo': results.frameworkAnalysis.echo = await this.analyzeEchoFramework(projectPath, args); break; case 'fiber': results.frameworkAnalysis.fiber = await this.analyzeFiberFramework(projectPath, args); break; } } return results; } catch (error) { results.success = false; results.error = error instanceof Error ? error.message : String(error); return results; } } // Helper methods for parsing and analysis parseGoMod(content) { const lines = content.split('\n'); const result = { dependencies: {} }; for (const line of lines) { const trimmed = line.trim(); if (trimmed.startsWith('module ')) { result.module = trimmed.replace('module ', ''); } else if (trimmed.startsWith('go ')) { result.goVersion = trimmed.replace('go ', ''); } else if (trimmed.includes(' v')) { const parts = trimmed.split(' '); if (parts.length >= 2) { result.dependencies[parts[0]] = parts[1]; } } } return result; } parseGoWork(content) { const lines = content.split('\n'); const result = { directories: [] }; let inUseBlock = false; for (const line of lines) { const trimmed = line.trim(); if (trimmed === 'use (') { inUseBlock = true; } else if (trimmed === ')') { inUseBlock = false; } else if (inUseBlock && trimmed) { result.directories.push(trimmed); } else if (trimmed.startsWith('use ') && !trimmed.includes('(')) { result.directories.push(trimmed.replace('use ', '')); } } return result; } async analyzeProjectStructure(projectPath) { const structure = { packages: [], tests: [], benchmarks: [] }; try { const { stdout: packageList } = await execAsync('go list ./...', { cwd: projectPath }); structure.packages = packageList.trim().split('\n'); const { stdout: testList } = await execAsync('go list -f "{{.TestGoFiles}}" ./...', { cwd: projectPath }); structure.hasTests = testList.includes('.go'); return structure; } catch (error) { return structure; } } async detectFrameworks(projectPath) { try { const { stdout: depsOutput } = await execAsync('go list -m all', { cwd: projectPath }); const frameworks = []; if (depsOutput.includes('github.com/gin-gonic/gin')) frameworks.push('gin'); if (depsOutput.includes('github.com/labstack/echo')) frameworks.push('echo'); if (depsOutput.includes('github.com/gofiber/fiber')) frameworks.push('fiber'); if (depsOutput.includes('github.com/gorilla/mux')) frameworks.push('gorilla'); return frameworks; } catch (error) { return []; } } summarizeTestResults(testOutput) { const summary = { total: 0, passed: 0, failed: 0, skipped: 0, packages: new Set(), totalTime: 0 }; for (const result of testOutput) { if (result.action === 'pass' || result.action === 'fail' || result.action === 'skip') { summary.total++; summary[result.action === 'pass' ? 'passed' : result.action === 'fail' ? 'failed' : 'skipped']++; summary.packages.add(result.package); if (result.elapsed) { summary.totalTime += result.elapsed; } } } return { ...summary, packages: Array.from(summary.packages), successRate: summary.total > 0 ? (summary.passed / summary.total) * 100 : 0 }; } parseCoverageOutput(output) { const lines = output.trim().split('\n'); const coverage = { files: [], total: 0 }; for (const line of lines) { if (line.includes('%')) { const parts = line.split('\t'); if (parts.length >= 3) { const filename = parts[0]; const percent = parseFloat(parts[2].replace('%', '')); coverage.files.push({ file: filename, coverage: percent }); } } } const totalLine = lines[lines.length - 1]; if (totalLine.includes('total:')) { const match = totalLine.match(/(\d+\.\d+)%/); if (match) { coverage.total = parseFloat(match[1]); } } return coverage; } parseDependencyGraph(graphOutput) { const edges = graphOutput.trim().split('\n').map(line => { const [from, to] = line.split(' '); return { from, to }; }); return { edges, nodeCount: new Set([...edges.map(e => e.from), ...edges.map(e => e.to)]).size }; } parseGoroutineProfile(profileData) { // Basic parsing of goroutine profile data const lines = profileData.split('\n'); const analysis = { totalGoroutines: 0, stacks: [] }; for (const line of lines) { if (line.includes('goroutine')) { analysis.totalGoroutines++; } } return analysis; } parseMemoryProfile(profileData) { const lines = profileData.split('\n'); const analysis = { topConsumers: [], totalMemory: 0 }; for (const line of lines) { if (line.trim() && !line.startsWith('Type:') && !line.startsWith('Showing')) { const parts = line.trim().split(/\s+/); if (parts.length >= 6) { analysis.topConsumers.push({ function: parts[5], flat: parts[0], cumulative: parts[3] }); } } } return analysis; } summarizeStaticAnalysis(results) { const summary = { totalIssues: 0, byTool: {} }; for (const [tool, result] of Object.entries(results)) { const toolResult = result; summary.byTool[tool] = { success: toolResult.success, hasIssues: toolResult.success && toolResult.output !== 'No issues found' }; } return summary; } identifyFrameworks(goModContent) { const frameworks = []; if (goModContent.includes('github.com/gin-gonic/gin')) { frameworks.push({ name: 'gin', version: this.extractVersion(goModContent, 'github.com/gin-gonic/gin') }); } if (goModContent.includes('github.com/labstack/echo')) { frameworks.push({ name: 'echo', version: this.extractVersion(goModContent, 'github.com/labstack/echo') }); } if (goModContent.includes('github.com/gofiber/fiber')) { frameworks.push({ name: 'fiber', version: this.extractVersion(goModContent, 'github.com/gofiber/fiber') }); } return frameworks; } extractVersion(content, module) { const regex = new RegExp(`${module.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s+(v[^\\s]+)`); const match = content.match(regex); return match ? match[1] : 'unknown'; } async suggestBuildOptimizations(projectPath) { const suggestions = []; // Check for potential optimizations try { const { stdout: buildInfo } = await execAsync('go version -m .', { cwd: projectPath }); if (!buildInfo.includes('-ldflags')) { suggestions.push('Consider using -ldflags="-s -w" to reduce binary size'); } } catch (error) { // Ignore if no binary exists } suggestions.push('Use -tags for conditional compilation'); suggestions.push('Consider CGO_ENABLED=0 for static binaries'); return suggestions; } async analyzeGinFramework(projectPath, args) { // Gin-specific analysis would go here return { framework: 'gin', analysis: 'Gin framework detected' }; } async analyzeEchoFramework(projectPath, args) { // Echo-specific analysis would go here return { framework: 'echo', analysis: 'Echo framework detected' }; } async analyzeFiberFramework(projectPath, args) { // Fiber-specific analysis would go here return { framework: 'fiber', analysis: 'Fiber framework detected' }; } } //# sourceMappingURL=go-debugging-handler.js.map