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

357 lines (351 loc) 16.4 kB
/** * Serena Integration Handler * * Implements AI-Debug ↔ Serena workflow integration * Enables seamless debug → analyze → fix → validate cycles */ import { SerenaIntegrationManager } from '../integrations/serena-integration-protocol.js'; import { writeFile, mkdir } from 'fs/promises'; export class SerenaIntegrationHandler { tools = [ { name: 'export_findings_for_serena', description: 'Export current debugging session findings in Serena-compatible format for code analysis and fixes. Creates JSON export with debugging context, performance issues, accessibility violations, and recommended Serena commands.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID to export findings from' }, exportPath: { type: 'string', description: 'Optional path to save export file (defaults to project root)', default: './ai-debug-findings.json' }, includeScreenshots: { type: 'boolean', description: 'Include screenshot evidence in export', default: true }, generateSerenaCommands: { type: 'boolean', description: 'Generate suggested Serena commands for common fixes', default: true } }, required: ['sessionId'] } }, { name: 'create_cross_tool_session', description: 'Create shared session context that both AI-Debug and Serena can reference. Enables seamless workflow transitions between runtime debugging and static code analysis.', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to project being debugged', default: '.' }, task: { type: 'string', description: 'Current development task description', default: 'debugging_session' }, framework: { type: 'string', description: 'Detected framework (auto-detected if not provided)' } } } }, { name: 'generate_serena_workflow', description: 'Generate recommended Serena commands based on AI-Debug findings. Provides optimized command sequences for code analysis, refactoring, and fixes.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID to analyze' }, focusArea: { type: 'string', enum: ['performance', 'accessibility', 'errors', 'security', 'all'], description: 'Focus analysis on specific issue type', default: 'all' } }, required: ['sessionId'] } }, { name: 'claude_code_sub_agent_handoff', description: 'Coordinate handoff between AI-Debug and Serena for Claude Code sub-agents. Provides intelligent workflow orchestration with automatic tool selection and context preservation.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Current AI-Debug session ID' }, workflowType: { type: 'string', enum: ['debug-analyze', 'tdd-refactor', 'performance-optimize', 'accessibility-fix'], description: 'Type of sub-agent workflow to initiate' }, contextSummary: { type: 'string', description: 'Summary of current debugging context and goals' }, nextPhase: { type: 'string', enum: ['static-analysis', 'code-fixing', 'validation', 'completion'], description: 'Next phase in the workflow', default: 'static-analysis' } }, required: ['sessionId', 'workflowType', 'contextSummary'] } } ]; async handle(toolName, args, sessions) { switch (toolName) { case 'export_findings_for_serena': return this.exportFindings(args, sessions); case 'create_cross_tool_session': return this.createCrossToolSession(args); case 'generate_serena_workflow': return this.generateSerenaWorkflow(args, sessions); case 'claude_code_sub_agent_handoff': return this.handleSubAgentHandoff(args, sessions); default: throw new Error(`Unknown tool: ${toolName}`); } } async exportFindings(args, sessions) { const { sessionId, exportPath = './ai-debug-findings.json', includeScreenshots = true, generateSerenaCommands = true } = args; // Get session data const session = sessions.get(sessionId); if (!session) { return { content: [{ type: 'text', text: `❌ **Session not found**: ${sessionId}\n\nPlease start a debugging session first with \`inject_debugging\`.` }] }; } try { // Gather findings from current session const findings = await this.gatherSessionFindings(session, includeScreenshots); // Create export data const exportData = { meta: { exported_at: new Date().toISOString(), ai_debug_version: '2.19.1', session_id: sessionId, project_path: process.cwd(), total_findings: findings.length }, session_context: await SerenaIntegrationManager.exportSessionContext(sessionId), findings, serena_commands: generateSerenaCommands ? SerenaIntegrationManager.generateSerenaWorkflow(findings) : [] }; // Ensure export directory exists const exportDir = exportPath.substring(0, exportPath.lastIndexOf('/')); if (exportDir && exportDir !== '.') { await mkdir(exportDir, { recursive: true }); } // Write export file await writeFile(exportPath, JSON.stringify(exportData, null, 2)); return { content: [{ type: 'text', text: `🔄 **Findings Exported for Serena**\n\n**Export File**: \`${exportPath}\`\n**Findings**: ${findings.length} issues found\n**Serena Commands**: ${exportData.serena_commands.length} suggested\n\n**Next Steps**:\n1. Open project in Serena: \`serena activate "${process.cwd()}"\`\n2. Import findings context (planned feature)\n3. Run suggested commands to analyze and fix issues\n4. Return to AI-Debug to validate fixes\n\n**🎯 Complementary Workflow Active**` }] }; } catch (error) { return { content: [{ type: 'text', text: `❌ **Export Failed**: ${error?.message || 'Unknown error'}\n\nPlease check session status and try again.` }] }; } } async createCrossToolSession(args) { const { projectPath = '.', task = 'debugging_session', framework } = args; const sharedSessionId = SerenaIntegrationManager.generateSharedSessionId(projectPath); const crossToolSession = { id: sharedSessionId, project_path: projectPath, created_at: Date.now(), updated_at: Date.now(), serena_active: false, framework: framework || 'auto-detect', primary_language: 'typescript', // TODO: Auto-detect active_files: [], current_task: task }; return { content: [{ type: 'text', text: `🔗 **Cross-Tool Session Created**\n\n**Session ID**: \`${sharedSessionId}\`\n**Project**: ${projectPath}\n**Task**: ${task}\n\n**Integration Ready**: Both AI-Debug and Serena can now reference this session for seamless workflow transitions.\n\n**Usage**:\n- Continue debugging with AI-Debug tools\n- Export findings when ready for code analysis\n- Switch to Serena for static analysis and fixes\n- Return to AI-Debug for validation` }], sessionId: sharedSessionId, crossToolSession }; } async generateSerenaWorkflow(args, sessions) { const { sessionId, focusArea = 'all' } = args; const session = sessions.get(sessionId); if (!session) { return { content: [{ type: 'text', text: `❌ **Session not found**: ${sessionId}` }] }; } // Gather findings and filter by focus area const allFindings = await this.gatherSessionFindings(session, false); const findings = focusArea === 'all' ? allFindings : allFindings.filter(f => f.type === focusArea); const commands = SerenaIntegrationManager.generateSerenaWorkflow(findings); return { content: [{ type: 'text', text: `🎯 **Serena Workflow Generated**\n\n**Focus**: ${focusArea}\n**Findings**: ${findings.length} issues\n**Commands**: ${commands.length} suggested\n\n**Recommended Serena Commands**:\n\`\`\`bash\n${commands.join('\n')}\n\`\`\`\n\n**Workflow**:\n1. Run commands in Serena to analyze code patterns\n2. Apply suggested fixes and refactoring\n3. Return to AI-Debug to validate changes with \`inject_debugging\`\n4. Run performance/accessibility audits to confirm improvements` }] }; } async gatherSessionFindings(session, includeScreenshots) { const findings = []; // Mock implementation - in real version, gather from actual session data // This would integrate with existing audit results, console logs, performance metrics, etc. // Example performance finding if (session.auditResults?.performance) { findings.push({ id: `perf_${Date.now()}`, sessionId: session.id, timestamp: Date.now(), type: 'performance', severity: 'medium', title: 'Large Component Re-renders', description: 'Component re-rendering too frequently, impacting performance', location: { component: 'UserComponent', file: 'src/components/UserComponent.tsx', line: 45 }, evidence: { metrics: { render_count: 23, avg_render_time: 12.5 } }, recommendations: { action: 'refactor', context: 'Add memoization to prevent unnecessary re-renders', files_to_examine: ['src/components/UserComponent.tsx'], search_patterns: ['useMemo', 'useCallback', 'React.memo'] } }); } // Example accessibility finding if (session.auditResults?.accessibility) { findings.push({ id: `a11y_${Date.now()}`, sessionId: session.id, timestamp: Date.now(), type: 'accessibility', severity: 'high', title: 'Missing ARIA Labels', description: 'Interactive elements lack proper accessibility labels', location: { selector: 'button.submit-btn', component: 'FormComponent' }, evidence: {}, recommendations: { action: 'analyze_code', context: 'Add aria-label or aria-labelledby attributes', search_patterns: ['aria-', 'role=', 'alt='] } }); } return findings; } async handleSubAgentHandoff(args, sessions) { const { sessionId, workflowType, contextSummary, nextPhase } = args; // Get session data const session = sessions.get(sessionId); if (!session) { return { content: [{ type: 'text', text: `❌ **Session not found**: ${sessionId}\n\nPlease start a debugging session first with \`inject_debugging\`.` }] }; } try { // Generate handoff package based on workflow type const handoffData = await this.generateHandoffPackage(session, workflowType, nextPhase); // Create cross-tool session for coordination const sharedSessionId = SerenaIntegrationManager.generateSharedSessionId(process.cwd()); const crossToolSession = { id: sharedSessionId }; return { content: [{ type: 'text', text: `🔄 **Sub-Agent Handoff Initiated** **Workflow Type**: ${workflowType} **Current Phase**: Debugging Complete → ${nextPhase} **Session ID**: ${sessionId} **Cross-Tool Session**: ${crossToolSession.id} **Context Summary**: ${contextSummary} **Handoff Package Prepared**: - 📊 Session findings: ${handoffData.findingsCount} items - 🖼️ Visual evidence: ${handoffData.screenshotsCount} screenshots - 🔧 Recommended actions: ${handoffData.actionsCount} suggestions - 📁 Export path: ./ai-debug-handoff-${sessionId}.json **Ready for**: ${nextPhase === 'static-analysis' ? 'Serena code analysis' : nextPhase} **Next Steps**: 1. AI-Debug findings exported for cross-tool usage 2. Shared session context established 3. Ready for seamless tool transition Use the exported data with other MCP tools or continue with AI-Debug validation.` }] }; } catch (error) { return { content: [{ type: 'text', text: `❌ **Sub-Agent Handoff Failed**: ${error?.message || 'Unknown error'}\n\nPlease try again or check the session status.` }] }; } } async generateHandoffPackage(session, workflowType, nextPhase) { // Gather findings specific to workflow type const allFindings = await this.gatherSessionFindings(session, true); // Filter findings based on workflow type let relevantFindings = allFindings; if (workflowType === 'performance-optimize') { relevantFindings = allFindings.filter(f => f.type === 'performance'); } else if (workflowType === 'accessibility-fix') { relevantFindings = allFindings.filter(f => f.type === 'accessibility'); } return { findingsCount: relevantFindings.length, screenshotsCount: relevantFindings.filter(f => f.evidence?.screenshot).length, actionsCount: relevantFindings.filter(f => f.recommendations?.action).length, workflowType, nextPhase, findings: relevantFindings }; } } //# sourceMappingURL=serena-integration-handler.js.map