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

192 lines 8.2 kB
import { BaseToolHandler } from '../base-handler.js'; /** * Handler for Next.js analysis tools (image audit, issue detection) */ export class NextJSAnalysisHandler extends BaseToolHandler { nextjsEngine; constructor(nextjsEngine) { super(); this.nextjsEngine = nextjsEngine; } tools = [ { name: 'nextjs_image_audit', description: 'Audit Next.js image optimization. Detects unoptimized images, suggests next/image usage, and identifies oversized images.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'nextjs_detect_issues', description: 'Detect Next.js specific problems: hydration errors, large RSC payloads, slow transitions, unnecessary SSR.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } } ]; async handle(toolName, args, sessions) { const session = sessions.get(args.sessionId); if (!session) { throw new Error(`Debug session ${args.sessionId} not found`); } // Validate this is a Next.js app if (session.framework !== 'nextjs' && session.framework !== 'next' && !(session.framework === 'react' && session.isNextJS)) { throw new Error('This tool only works with Next.js applications'); } switch (toolName) { case 'nextjs_image_audit': return this.auditImages(args, session); case 'nextjs_detect_issues': return this.detectIssues(args, session); default: throw new Error(`Unknown Next.js analysis tool: ${toolName}`); } } async auditImages(args, session) { try { const audit = await this.nextjsEngine.auditImages(session); let content = '🖼️ **Next.js Image Optimization Audit**\n\n'; // Summary stats content += `**Total Images:** ${audit.totalImages}\n`; const usingNextImage = Math.round(audit.totalImages * (audit.nextImageUsage / 100)); content += `**Using next/image:** ${usingNextImage} (${audit.nextImageUsage.toFixed(1)}%)\n\n`; // Unoptimized images if (audit.unoptimizedImages.length > 0) { content += '**⚠️ Unoptimized Images:**\n'; audit.unoptimizedImages.forEach((img) => { content += `- **${img.src}**\n`; content += ` - Format: ${img.format}\n`; content += ` - Displayed: ${img.displayed.width}x${img.displayed.height}\n`; content += ` - Actual: ${img.actual.width}x${img.actual.height}\n`; content += ` - ${img.improvement}\n`; }); content += '\n'; } else if (audit.totalImages > 0) { content += '✅ All images are properly optimized!\n\n'; } // Lazy load failures if (audit.lazyLoadFailures && audit.lazyLoadFailures.length > 0) { content += '**⚠️ Images with Lazy Load Issues:**\n'; audit.lazyLoadFailures.forEach((img) => { content += `- ${img}\n`; }); content += '\n'; } // Recommendations if (audit.recommendations && audit.recommendations.length > 0) { content += '**💡 Recommendations:**\n'; audit.recommendations.forEach((rec) => { content += `- ${rec}\n`; }); } return { content: [{ type: 'text', text: content.trim() }] }; } catch (error) { throw new Error(`Failed to audit Next.js images: ${error instanceof Error ? error.message : String(error)}`); } } async detectIssues(args, session) { try { const issues = await this.nextjsEngine.detectIssues(session); let content = '🔍 **Next.js Issues Detected**\n\n'; let hasIssues = false; // Hydration errors if (issues.hydrationErrors && issues.hydrationErrors.length > 0) { hasIssues = true; content += '**❌ Hydration Errors:**\n'; issues.hydrationErrors.forEach((error) => { content += `- **Component:** ${error.component}\n`; content += ` - Type: ${error.type}\n`; if (error.serverText && error.clientText) { content += ` - Server: "${error.serverText}"\n`; content += ` - Client: "${error.clientText}"\n`; } if (error.stackTrace) { content += ` - Stack: ${error.stackTrace}\n`; } }); content += '\n'; } // Large RSC payloads if (issues.largeRSCPayloads && issues.largeRSCPayloads.length > 0) { hasIssues = true; content += '**⚠️ Large RSC Payloads:**\n'; issues.largeRSCPayloads.forEach((payload) => { content += `- **${payload.component}**: ${payload.size}\n`; if (payload.recommendation) { content += ` - ${payload.recommendation}\n`; } }); content += '\n'; } // Slow transitions if (issues.slowTransitions && issues.slowTransitions.length > 0) { hasIssues = true; content += '**🐌 Slow Route Transitions:**\n'; issues.slowTransitions.forEach((transition) => { content += `- **${transition.from}** → **${transition.to}**: ${transition.duration}\n`; if (transition.bottleneck) { content += ` - Bottleneck: ${transition.bottleneck}\n`; } }); content += '\n'; } // Unnecessary SSR if (issues.unnecessarySSR && issues.unnecessarySSR.length > 0) { hasIssues = true; content += '**💡 Unnecessary SSR:**\n'; issues.unnecessarySSR.forEach((page) => { content += `- **${page.path}**\n`; content += ` - ${page.reason}\n`; if (page.suggestion) { content += ` - Suggestion: ${page.suggestion}\n`; } }); content += '\n'; } if (!hasIssues) { content += '✅ No issues detected!\n\n'; content += 'Your Next.js app appears to be running smoothly.\n'; } else { // Overall recommendations if (issues.recommendations && issues.recommendations.length > 0) { content += '**📋 Recommendations:**\n'; issues.recommendations.forEach((rec) => { content += `- ${rec}\n`; }); } } return { content: [{ type: 'text', text: content.trim() }] }; } catch (error) { throw new Error(`Failed to detect Next.js issues: ${error instanceof Error ? error.message : String(error)}`); } } } //# sourceMappingURL=nextjs-analysis-handler.js.map