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
JavaScript
/**
* 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