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
483 lines • 23.3 kB
JavaScript
/**
* Flutter Session Stability Handler
* Addresses Flutter-specific feedback: accessibility timeouts, quantum debugging prerequisites
* Integrates SessionStabilityManager, EnhancedErrorHandler, and ToolDependencyManager
*/
import { BaseToolHandler } from './base-handler.js';
import { SessionStabilityManager } from '../utils/session-stability-manager.js';
import { EnhancedErrorHandler } from '../utils/enhanced-error-handler.js';
import { ToolDependencyManager } from '../utils/tool-dependency-manager.js';
export class FlutterSessionStabilityHandler extends BaseToolHandler {
sessionManager;
errorHandler;
dependencyManager;
constructor() {
super();
this.sessionManager = new SessionStabilityManager();
this.errorHandler = new EnhancedErrorHandler();
this.dependencyManager = new ToolDependencyManager();
this.setupSessionEventHandlers();
}
tools = [
{
name: 'get_session_diagnostics',
description: 'Get comprehensive session health diagnostics with Flutter-specific status information. Shows browser connection, accessibility status, quantum debug state, and recommendations.',
inputSchema: {
type: 'object',
properties: {
sessionId: { type: 'string', description: 'Debug session ID to diagnose' }
},
required: ['sessionId']
}
},
{
name: 'validate_tool_prerequisites',
description: 'Validate if a tool can be used given current session state and provide specific setup instructions. Prevents "tool interdependency" issues.',
inputSchema: {
type: 'object',
properties: {
toolName: { type: 'string', description: 'Name of the tool to validate (e.g., flutter_enable_accessibility, flutter_quantum_analyze)' },
sessionId: { type: 'string', description: 'Current debug session ID' }
},
required: ['toolName', 'sessionId']
}
},
{
name: 'get_flutter_workflow_guidance',
description: 'Get step-by-step Flutter debugging workflow with estimated times and prerequisites. Addresses "suggest logical tool sequences" feedback.',
inputSchema: {
type: 'object',
properties: {
debuggingGoal: {
type: 'string',
description: 'What you want to debug',
enum: ['ui_analysis', 'accessibility_issues', 'performance_problems', 'interaction_testing', 'general_debugging']
},
currentStep: { type: 'number', description: 'Current step in workflow (optional)', minimum: 1 }
},
required: ['debuggingGoal']
}
},
{
name: 'recover_flutter_session',
description: 'Automatically recover from Flutter session failures with preserved context. Addresses "Target page, context or browser has been closed" errors for Flutter apps.',
inputSchema: {
type: 'object',
properties: {
failedSessionId: { type: 'string', description: 'Session ID that failed' },
lastError: { type: 'string', description: 'Last error message received' },
preserveContext: { type: 'boolean', description: 'Whether to preserve debugging context', default: true }
},
required: ['failedSessionId', 'lastError']
}
},
{
name: 'analyze_flutter_error',
description: 'Get detailed analysis of Flutter-specific errors with actionable solutions. Replaces generic error messages with specific diagnostics.',
inputSchema: {
type: 'object',
properties: {
errorMessage: { type: 'string', description: 'Flutter error message to analyze' },
toolName: { type: 'string', description: 'Tool that generated the error (optional)' },
sessionId: { type: 'string', description: 'Session ID where error occurred (optional)' }
},
required: ['errorMessage']
}
},
{
name: 'create_stable_flutter_session',
description: 'Create a new Flutter debugging session with built-in stability monitoring and recovery. Addresses session instability issues.',
inputSchema: {
type: 'object',
properties: {
url: { type: 'string', description: 'Flutter application URL' },
debuggingGoal: { type: 'string', description: 'What you plan to debug (for workflow optimization)' },
enableMonitoring: { type: 'boolean', description: 'Enable real-time session monitoring', default: true }
},
required: ['url']
}
}
];
async handle(toolName, args, sessions) {
try {
switch (toolName) {
case 'get_session_diagnostics':
return this.getSessionDiagnostics(args, sessions);
case 'validate_tool_prerequisites':
return this.validateToolPrerequisites(args, sessions);
case 'get_flutter_workflow_guidance':
return this.getFlutterWorkflowGuidance(args);
case 'recover_flutter_session':
return this.recoverFailedSession(args, sessions);
case 'analyze_flutter_error':
return this.analyzeFlutterError(args);
case 'create_stable_flutter_session':
return this.createStableFlutterSession(args, sessions);
default:
throw new Error(`Unknown Flutter session stability tool: ${toolName}`);
}
}
catch (error) {
// Use enhanced error handling for all errors
const detailedError = this.errorHandler.analyzeError(error, {
tool: toolName,
sessionId: args.sessionId,
framework: 'flutter'
});
return this.createTextResponse(this.errorHandler.formatError(detailedError, { sessionId: args.sessionId }));
}
}
async getSessionDiagnostics(args, sessions) {
const diagnostics = this.sessionManager.getSessionDiagnostics(args.sessionId);
if (!diagnostics) {
return this.createTextResponse(`❌ **Session Not Found**\n\n**Session ID**: ${args.sessionId}\n\n**Solution**: Create a new session with \`create_stable_flutter_session\``);
}
const sections = [
'🔍 **Session Diagnostics**',
'',
`**Session ID**: ${args.sessionId}`,
`**Overall Status**: ${this.getStatusEmoji(diagnostics.status)} ${diagnostics.status.toUpperCase()}`,
'',
'## 📊 **Detailed Status**',
'',
`**Browser**: ${diagnostics.details.browser.status}`,
`**Framework**: ${diagnostics.details.framework.detected ? '✅' : '❌'} ${diagnostics.details.framework.type || 'Not detected'}`,
`**Accessibility**: ${diagnostics.details.accessibility.enabled ? '✅ Enabled' : '❌ Disabled'}`,
`**Quantum Debug**: ${diagnostics.details.quantumDebug.initialized ? '✅ Initialized' : '❌ Not initialized'}`,
''
];
// Working tools
if (diagnostics.details.tools.working.length > 0) {
sections.push('**✅ Working Tools**:');
diagnostics.details.tools.working.forEach(tool => {
sections.push(`- ${tool}`);
});
sections.push('');
}
// Failed tools
if (diagnostics.details.tools.failed.length > 0) {
sections.push('**❌ Failed Tools**:');
diagnostics.details.tools.failed.forEach(tool => {
sections.push(`- ${tool}`);
});
sections.push('');
}
// Specific Flutter diagnostics
if (diagnostics.details.accessibility.error) {
sections.push('**🚨 Accessibility Issue**:');
sections.push(`${diagnostics.details.accessibility.error}`);
sections.push('');
}
if (diagnostics.details.quantumDebug.error) {
sections.push('**🚨 Quantum Debug Issue**:');
sections.push(`${diagnostics.details.quantumDebug.error}`);
sections.push('');
}
// Activity info
sections.push('## ⏱️ **Activity**');
sections.push(`**Last Activity**: ${diagnostics.details.activity.ageMinutes} minutes ago`);
sections.push('');
// Recommendations
if (diagnostics.recommendations.length > 0) {
sections.push('## 💡 **Recommendations**');
diagnostics.recommendations.forEach(rec => {
sections.push(`- ${rec}`);
});
sections.push('');
}
// Next suggested workflow
const workflow = this.sessionManager.getRecommendedWorkflow(args.sessionId);
if (workflow.nextSteps.length > 0) {
sections.push('## 🎯 **Suggested Next Steps**');
sections.push(`**Current Phase**: ${workflow.currentPhase}`);
sections.push('');
workflow.nextSteps.forEach((step, index) => {
sections.push(`${index + 1}. **${step.tool}** - ${step.reason}`);
if (step.prerequisites.length > 0) {
sections.push(` Prerequisites: ${step.prerequisites.join(', ')}`);
}
sections.push(` Estimated time: ${Math.round(step.estimatedTime / 1000)}s`);
sections.push('');
});
}
if (workflow.blockers.length > 0) {
sections.push('## 🚫 **Current Blockers**');
workflow.blockers.forEach(blocker => {
sections.push(`- ${blocker}`);
});
}
return this.createTextResponse(sections.join('\n'));
}
async validateToolPrerequisites(args, sessions) {
// Get current session state
const sessionState = sessions?.get(args.sessionId) || {};
// Get completed tools (would be tracked in real implementation)
const completedTools = ['inject_debugging']; // Example
const validation = this.dependencyManager.validateToolUsage(args.toolName, sessionState, completedTools);
const sections = [
`🔧 **Tool Prerequisites Validation: ${args.toolName}**`,
'',
`**Can Use Tool**: ${validation.isValid ? '✅ Yes' : '❌ No'}`,
''
];
if (!validation.isValid) {
sections.push('## 🚫 **Missing Requirements**');
sections.push('');
if (validation.missingDependencies.length > 0) {
sections.push('**Missing Tool Dependencies**:');
validation.missingDependencies.forEach(dep => {
sections.push(`- ${dep} (must be completed first)`);
});
sections.push('');
}
if (validation.missingPrerequisites.length > 0) {
sections.push('**Missing Prerequisites**:');
validation.missingPrerequisites.forEach(prereq => {
sections.push(`- **${prereq.requirement}**`);
sections.push(` Current: ${prereq.current}`);
sections.push(` Expected: ${prereq.expected}`);
sections.push(` Fix: ${prereq.howToFix}`);
sections.push('');
});
}
}
if (validation.warnings.length > 0) {
sections.push('## ⚠️ **Warnings**');
validation.warnings.forEach(warning => {
sections.push(`- ${warning}`);
});
sections.push('');
}
if (validation.recommendations.length > 0) {
sections.push('## 💡 **Recommendations**');
validation.recommendations.forEach(rec => {
sections.push(`- ${rec}`);
});
sections.push('');
}
if (validation.estimatedSetupTime > 0) {
sections.push(`**Estimated Setup Time**: ${Math.round(validation.estimatedSetupTime / 1000)} seconds`);
}
// Add tool-specific documentation
const toolDoc = this.dependencyManager.generateToolDocumentation(args.toolName);
if (toolDoc) {
sections.push('## 📚 **Tool Documentation**');
sections.push(`**Purpose**: ${toolDoc.overview}`);
sections.push(`**Phase**: ${toolDoc.workflow.phase}`);
sections.push(`**Estimated Runtime**: ${Math.round(toolDoc.workflow.timeToRun / 1000)}s`);
sections.push('');
if (toolDoc.dependencies.required.length > 0) {
sections.push('**Required Dependencies**:');
toolDoc.dependencies.required.forEach(dep => {
sections.push(`- ${dep.tool}: ${dep.reason}`);
});
sections.push('');
}
if (toolDoc.troubleshooting.length > 0) {
sections.push('**Common Issues**:');
toolDoc.troubleshooting.forEach(issue => {
sections.push(`- **${issue.problem}**: ${issue.solution}`);
});
}
}
return this.createTextResponse(sections.join('\n'));
}
async getFlutterWorkflowGuidance(args) {
const workflow = this.dependencyManager.getWorkflowForGoal('flutter_ui_debugging', 'flutter');
const sections = [
`🎯 **${workflow.title}**`,
'',
workflow.description,
'',
`**Total Estimated Time**: ${Math.round(workflow.totalEstimatedTime / 1000)} seconds`,
'',
'## 📋 **Step-by-Step Workflow**',
''
];
workflow.steps.forEach((step) => {
const isCurrent = args.currentStep && step.step === args.currentStep;
const stepIcon = isCurrent ? '👉' : step.step <= (args.currentStep || 0) ? '✅' : '📝';
sections.push(`### ${stepIcon} Step ${step.step}: ${step.tool}`);
sections.push(`**Purpose**: ${step.purpose}`);
sections.push(`**Time**: ~${Math.round(step.estimatedTime / 1000)}s`);
if (step.prerequisites.length > 0) {
sections.push(`**Prerequisites**: ${step.prerequisites.join(', ')}`);
}
if (step.validations.length > 0) {
sections.push(`**Success Criteria**: ${step.validations.join(', ')}`);
}
sections.push('');
});
if (workflow.alternatives.length > 0) {
sections.push('## 🔄 **Alternative Approaches**');
workflow.alternatives.forEach((alt) => {
sections.push(`**${alt.condition}**:`);
alt.alternativeSteps.forEach((altStep) => {
sections.push(`- ${altStep}`);
});
sections.push('');
});
}
sections.push('## 💡 **Pro Tips**');
sections.push('- Always run `flutter_health_check` first to identify configuration issues');
sections.push('- Keep browser tab active during tool execution to prevent connection losses');
sections.push('- If accessibility fails, check `flutter.engine.semanticsEnabled = true`');
sections.push('- Use `get_session_diagnostics` if any step fails to understand the issue');
return this.createTextResponse(sections.join('\n'));
}
async recoverFailedSession(args, sessions) {
// Create recovery plan based on error
const error = new Error(args.lastError);
const recoveryPlan = await this.sessionManager.detectSessionFailure(args.failedSessionId, error);
const sections = [
'🔄 **Session Recovery Analysis**',
'',
`**Failed Session**: ${args.failedSessionId}`,
`**Error**: ${args.lastError}`,
`**Recoverable**: ${recoveryPlan.canRecover ? '✅ Yes' : '❌ No'}`,
''
];
if (!recoveryPlan.canRecover) {
sections.push('## ❌ **Recovery Not Possible**');
sections.push('**Recommendation**: Create a new session with `create_stable_flutter_session`');
return this.createTextResponse(sections.join('\n'));
}
sections.push('## 🔧 **Recovery Plan**');
sections.push('');
recoveryPlan.steps.forEach((step, index) => {
sections.push(`${index + 1}. **${step.action}**`);
sections.push(` Tool: \`${step.tool}\``);
sections.push(` Reason: ${step.reason}`);
sections.push(` Estimated Time: ${Math.round(step.estimatedTime / 1000)}s`);
sections.push('');
});
if (recoveryPlan.riskFactors.length > 0) {
sections.push('## ⚠️ **Risk Factors**');
recoveryPlan.riskFactors.forEach(risk => {
sections.push(`- ${risk}`);
});
sections.push('');
}
sections.push('## 🔄 **Preserved State**');
sections.push(`- URL: ${recoveryPlan.preservedState.url}`);
sections.push(`- Framework: ${recoveryPlan.preservedState.framework}`);
if (recoveryPlan.preservedState.context?.debuggingGoal) {
sections.push(`- Debugging Goal: ${recoveryPlan.preservedState.context.debuggingGoal}`);
}
// Auto-execute recovery if requested
if (args.preserveContext) {
try {
const result = await this.sessionManager.executeSessionRecovery(args.failedSessionId, recoveryPlan);
sections.push('');
sections.push('## ✅ **Recovery Executed**');
sections.push(`**Success**: ${result.success ? 'Yes' : 'No'}`);
if (result.newSessionId) {
sections.push(`**New Session ID**: ${result.newSessionId}`);
}
if (result.restoredFeatures.length > 0) {
sections.push('**Restored Features**:');
result.restoredFeatures.forEach(feature => {
sections.push(`- ✅ ${feature}`);
});
}
if (result.failedFeatures.length > 0) {
sections.push('**Failed to Restore**:');
result.failedFeatures.forEach(feature => {
sections.push(`- ❌ ${feature}`);
});
}
}
catch (recoveryError) {
sections.push('');
sections.push('## ❌ **Recovery Failed**');
sections.push(`**Error**: ${recoveryError}`);
sections.push('**Recommendation**: Create a new session manually');
}
}
return this.createTextResponse(sections.join('\n'));
}
async analyzeFlutterError(args) {
const error = new Error(args.errorMessage);
const detailedError = this.errorHandler.analyzeError(error, {
tool: args.toolName,
sessionId: args.sessionId,
framework: 'flutter'
});
return this.createTextResponse(this.errorHandler.formatError(detailedError, { sessionId: args.sessionId }));
}
async createStableFlutterSession(args, sessions) {
try {
const { sessionId, state } = await this.sessionManager.createStableSession(args.url, {
framework: 'flutter',
debuggingGoal: args.debuggingGoal,
workflowPhase: 'Session Creation'
});
// Add to sessions map
if (sessions) {
sessions.set(sessionId, {
...state,
page: {}, // Mock page object for compatibility
framework: 'flutter'
});
}
const sections = [
'🚀 **Stable Flutter Session Created**',
'',
`**Session ID**: ${sessionId}`,
`**URL**: ${args.url}`,
`**Framework**: Flutter`,
`**Debugging Goal**: ${args.debuggingGoal || 'General debugging'}`,
`**Monitoring**: ${args.enableMonitoring ? 'Enabled' : 'Disabled'}`,
'',
'## 🎯 **Next Steps**'
];
// Get recommended workflow for their debugging goal
if (args.debuggingGoal) {
const workflow = this.dependencyManager.getWorkflowForGoal('flutter_ui_debugging', 'flutter');
sections.push(`**Recommended Workflow**: ${workflow.title}`);
sections.push(`**First Step**: ${workflow.steps[0]?.tool || 'flutter_health_check'}`);
sections.push('');
sections.push('**Quick Start Commands**:');
sections.push(`1. \`flutter_health_check({"sessionId": "${sessionId}"})\``);
sections.push(`2. \`flutter_enable_accessibility({"sessionId": "${sessionId}"})\``);
sections.push(`3. \`take_screenshot({"sessionId": "${sessionId}"})\``);
}
sections.push('');
sections.push('## 💡 **Pro Tips**');
sections.push('- Use `get_session_diagnostics` anytime to check session health');
sections.push('- Use `validate_tool_prerequisites` before running tools to avoid errors');
sections.push('- Keep this browser tab active to maintain session stability');
return this.createTextResponse(sections.join('\n'));
}
catch (error) {
const detailedError = this.errorHandler.analyzeError(error, {
tool: 'create_stable_flutter_session',
framework: 'flutter'
});
return this.createTextResponse(this.errorHandler.formatError(detailedError));
}
}
setupSessionEventHandlers() {
this.sessionManager.on('sessionFailureDetected', (event) => {
console.log(`Session failure detected: ${event.sessionId}`, event.recoveryPlan);
});
this.sessionManager.on('sessionRecovered', (event) => {
console.log(`Session recovered: ${event.oldSessionId} → ${event.newSessionId}`);
});
this.sessionManager.on('sessionExpired', (event) => {
console.log(`Session expired: ${event.sessionId}`);
});
}
getStatusEmoji(status) {
switch (status) {
case 'healthy': return '✅';
case 'degraded': return '⚠️';
case 'failed': return '❌';
default: return '❓';
}
}
destroy() {
this.sessionManager.destroy();
}
}
//# sourceMappingURL=flutter-session-stability-handler.js.map