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,158 lines โข 59.4 kB
JavaScript
import { BaseToolHandler } from './base-handler.js';
import { TDDImplementationPlanner } from '../utils/tdd-implementation-planner.js';
/**
* Debug Workflow Advisor - Guides AI models on HOW and WHEN to use ai-debug tools effectively
* Addresses the feedback that AI models use tools for verification rather than active debugging
* Enhanced with TDD-specific guidance tools based on Cycle 22 user feedback
*/
export class DebugWorkflowAdvisor extends BaseToolHandler {
tddPlanner;
constructor() {
super();
this.tddPlanner = TDDImplementationPlanner.getInstance();
}
tools = [
{
name: 'suggest_debugging_workflow',
description: 'Get a step-by-step debugging workflow for specific errors or issues. Helps AI models transition from verification to active debugging.',
inputSchema: {
type: 'object',
properties: {
errorDescription: {
type: 'string',
description: 'Description of the error or issue to debug (e.g., "GenServer not alive error", "Pydantic validation failure", "test failures")'
},
applicationContext: {
type: 'string',
description: 'Type of application/framework',
enum: ['phoenix_liveview', 'nextjs', 'python_backend', 'react', 'flutter', 'general']
},
currentStep: {
type: 'string',
description: 'Current step in development cycle if applicable (e.g., "Step 7: Execute task")',
default: 'unknown'
},
availableTime: {
type: 'string',
description: 'Time available for debugging',
enum: ['quick', 'thorough', 'comprehensive'],
default: 'thorough'
}
},
required: ['errorDescription', 'applicationContext']
}
},
{
name: 'create_debugging_session_plan',
description: 'Create a detailed debugging session plan with specific ai-debug tool sequences. Promotes active debugging over passive verification.',
inputSchema: {
type: 'object',
properties: {
issueType: {
type: 'string',
description: 'Type of issue to debug',
enum: ['process_lifecycle', 'test_failures', 'ui_issues', 'api_integration', 'database_problems', 'performance_issues']
},
reproduction: {
type: 'string',
description: 'How to reproduce the issue (user actions, test commands, etc.)'
},
expectedOutcome: {
type: 'string',
description: 'What should happen vs what actually happens'
},
frameworkSpecific: {
type: 'boolean',
description: 'Include framework-specific debugging steps',
default: true
}
},
required: ['issueType', 'reproduction']
}
},
{
name: 'get_tdd_debugging_guidance',
description: 'Get guidance for Test-Driven Debugging (TDD) using ai-debug tools. Helps AI models integrate debugging into development workflows.',
inputSchema: {
type: 'object',
properties: {
developmentPhase: {
type: 'string',
description: 'Current development phase',
enum: ['implementing_fix', 'validating_solution', 'refactoring', 'testing_changes']
},
testType: {
type: 'string',
description: 'Type of test or validation needed',
enum: ['unit_tests', 'integration_tests', 'ui_behavior', 'api_endpoints', 'performance']
},
iterationGoal: {
type: 'string',
description: 'Goal for this TDD iteration'
}
},
required: ['developmentPhase', 'testType']
}
},
{
name: 'analyze_debugging_gap',
description: 'Analyze why previous debugging attempts may have failed and suggest more effective approaches using ai-debug tools.',
inputSchema: {
type: 'object',
properties: {
previousApproach: {
type: 'string',
description: 'Description of previous debugging attempts'
},
toolsUsed: {
type: 'array',
items: { type: 'string' },
description: 'ai-debug tools used previously'
},
resultAchieved: {
type: 'string',
description: 'What was accomplished with previous approach'
},
issueStillPresent: {
type: 'boolean',
description: 'Whether the original issue is still present',
default: true
}
},
required: ['previousApproach', 'resultAchieved']
}
},
{
name: 'suggest_tdd_implementation_steps',
description: 'Generate implementation steps from failing tests using TDD methodology. Based on Cycle 22 success - transforms test failures into clear implementation roadmap.',
inputSchema: {
type: 'object',
properties: {
failingTests: {
type: 'array',
items: { type: 'string' },
description: 'List of failing test descriptions or test file paths'
},
testContext: {
type: 'object',
properties: {
testFramework: {
type: 'string',
enum: ['flutter_test', 'integration_test', 'widget_test'],
default: 'flutter_test'
},
authenticationRequired: { type: 'boolean', default: true },
uiComponentsNeeded: {
type: 'array',
items: { type: 'string' },
description: 'UI components that tests expect (e.g., family_overview_section)'
},
complexityLevel: {
type: 'string',
enum: ['simple', 'moderate', 'complex'],
default: 'moderate'
}
}
},
timeConstraint: {
type: 'string',
enum: ['none', 'tight', 'very_tight'],
default: 'none',
description: 'Time pressure for implementation'
},
generateCodeTemplates: {
type: 'boolean',
default: true,
description: 'Include ready-to-use code templates'
}
},
required: ['failingTests']
}
},
{
name: 'validate_test_driven_architecture',
description: 'Analyze if current implementation follows good TDD architecture patterns. Validates that tests drive better component design.',
inputSchema: {
type: 'object',
properties: {
implementationContext: {
type: 'object',
properties: {
componentType: {
type: 'string',
enum: ['widget', 'provider', 'service', 'model', 'screen'],
description: 'Type of component being validated'
},
testCoverage: {
type: 'object',
properties: {
hasUnitTests: { type: 'boolean', default: false },
hasWidgetTests: { type: 'boolean', default: false },
hasIntegrationTests: { type: 'boolean', default: false },
testToCodeRatio: {
type: 'number',
description: 'Estimated ratio of test code to implementation code',
minimum: 0
}
}
},
dependencyStructure: {
type: 'object',
properties: {
providerDependencies: {
type: 'array',
items: { type: 'string' },
description: 'List of provider dependencies'
},
externalDependencies: {
type: 'array',
items: { type: 'string' },
description: 'External service/API dependencies'
}
}
}
},
required: ['componentType']
},
architectureGoals: {
type: 'array',
items: {
type: 'string',
enum: ['testability', 'maintainability', 'separation_of_concerns', 'dependency_injection', 'modularity']
},
default: ['testability', 'maintainability'],
description: 'Architecture quality goals to validate against'
}
},
required: ['implementationContext']
}
},
{
name: 'analyze_test_failure_patterns',
description: 'Identify common TDD anti-patterns and failure modes. Helps prevent recurring issues and improves test quality.',
inputSchema: {
type: 'object',
properties: {
testFailureHistory: {
type: 'array',
items: {
type: 'object',
properties: {
testName: { type: 'string' },
failureReason: { type: 'string' },
failureCategory: {
type: 'string',
enum: ['authentication', 'missing_widget', 'provider_error', 'timing', 'infrastructure', 'logic_error'],
description: 'Category of test failure'
},
resolutionApproach: { type: 'string', description: 'How the failure was resolved' },
timeToResolve: {
type: 'number',
description: 'Minutes taken to resolve the issue'
}
},
required: ['testName', 'failureReason', 'failureCategory']
},
description: 'History of test failures to analyze for patterns'
},
currentTestSuite: {
type: 'object',
properties: {
testFramework: { type: 'string', default: 'flutter_test' },
totalTests: { type: 'number', description: 'Total number of tests' },
passingTests: { type: 'number', description: 'Number of passing tests' },
flakyTests: {
type: 'array',
items: { type: 'string' },
description: 'List of tests that intermittently fail'
}
}
},
analysisDepth: {
type: 'string',
enum: ['surface', 'detailed', 'comprehensive'],
default: 'detailed',
description: 'Depth of pattern analysis to perform'
}
},
required: ['testFailureHistory']
}
}
];
async handle(toolName, args) {
switch (toolName) {
case 'suggest_debugging_workflow':
return this.suggestDebuggingWorkflow(args);
case 'create_debugging_session_plan':
return this.createDebuggingSessionPlan(args);
case 'get_tdd_debugging_guidance':
return this.getTddDebuggingGuidance(args);
case 'analyze_debugging_gap':
return this.analyzeDebuggingGap(args);
case 'suggest_tdd_implementation_steps':
return this.suggestTddImplementationSteps(args);
case 'validate_test_driven_architecture':
return this.validateTestDrivenArchitecture(args);
case 'analyze_test_failure_patterns':
return this.analyzeTestFailurePatterns(args);
default:
throw new Error(`Unknown debug workflow tool: ${toolName}`);
}
}
async suggestDebuggingWorkflow(args) {
const { errorDescription, applicationContext, currentStep, availableTime } = args;
const workflow = this.generateWorkflowForError(errorDescription, applicationContext);
const timeAdjustedWorkflow = this.adjustWorkflowForTime(workflow, availableTime);
const sections = [
'๐ **Active Debugging Workflow Recommendation**',
'',
`**Error**: ${errorDescription}`,
`**Context**: ${applicationContext}`,
`**Current Step**: ${currentStep}`,
`**Time Allocation**: ${availableTime}`,
'',
'## ๐ฏ **Active Debugging Strategy**',
'',
'**Key Principle**: Move from verification to investigation - reproduce the issue first, then fix it.',
'',
'## ๐ **Step-by-Step Workflow**',
''
];
timeAdjustedWorkflow.forEach((step, index) => {
sections.push(`### ${index + 1}. ${step.action}`);
sections.push(`**Tool**: \`${step.tool}\``);
sections.push(`**Purpose**: ${step.purpose}`);
sections.push(`**Command**: ${step.command}`);
if (step.expectedResult) {
sections.push(`**Expected Result**: ${step.expectedResult}`);
}
sections.push('');
});
sections.push('## ๐ก **TDD Integration Tips**');
sections.push('');
sections.push('- Use `take_screenshot` before and after implementing fixes');
sections.push('- Use `monitor_realtime` to validate that your fix resolves the process issues');
sections.push('- Use `simulate_user_action` to test the exact user journey that caused the problem');
sections.push('');
sections.push('## โ ๏ธ **Common AI Model Debugging Mistakes to Avoid**');
sections.push('');
sections.push('- โ Using ai-debug only for verification after implementing fixes');
sections.push('- โ Not reproducing the actual error before attempting solutions');
sections.push('- โ Skipping real-time monitoring during problem reproduction');
sections.push('- โ
**Instead**: Reproduce first, monitor during reproduction, then implement and validate');
return this.createTextResponse(sections.join('\n'));
}
generateWorkflowForError(error, context) {
const workflows = {
'genserver_not_alive': [
{
action: 'Start Active Debugging Session',
tool: 'inject_debugging',
purpose: 'Create debugging session for live investigation',
command: 'inject_debugging({ url: "http://localhost:4000" })',
expectedResult: 'Active debugging session with session ID'
},
{
action: 'Navigate to Problem Area',
tool: 'simulate_user_action',
purpose: 'Reproduce the exact user journey that triggers the GenServer error',
command: 'simulate_user_action({ sessionId: "session-id", action: "navigate", selector: "/admin/users" })',
expectedResult: 'Navigation to admin panel where GenServer issues occur'
},
{
action: 'Monitor Process Lifecycle',
tool: 'monitor_realtime',
purpose: 'Watch GenServer processes in real-time during issue reproduction',
command: 'monitor_realtime({ sessionId: "session-id", events: ["process_lifecycle", "genserver_events"] })',
expectedResult: 'Real-time process monitoring active'
},
{
action: 'Trigger the GenServer Issue',
tool: 'simulate_user_action',
purpose: 'Perform the specific action that causes GenServer termination',
command: 'simulate_user_action({ sessionId: "session-id", action: "click", selector: "button[data-action=admin-action]" })',
expectedResult: 'GenServer error reproduction with real-time monitoring data'
},
{
action: 'Capture Error State',
tool: 'take_screenshot',
purpose: 'Document the exact state when GenServer fails',
command: 'take_screenshot({ sessionId: "session-id", annotations: ["Error state captured"] })',
expectedResult: 'Screenshot showing UI state during GenServer failure'
},
{
action: 'Analyze Console Logs',
tool: 'get_console_logs',
purpose: 'Capture any JavaScript errors related to admin panel interactions',
command: 'get_console_logs({ sessionId: "session-id", level: "error" })',
expectedResult: 'Console error logs showing frontend/backend interaction issues'
}
],
'python_test_failures': [
{
action: 'Analyze Test Structure and Failures',
tool: 'analyze_python_tests',
purpose: 'Get comprehensive analysis of test failures and structure',
command: 'analyze_python_tests({ testFilePath: "tests/", includeStackTrace: true })',
expectedResult: 'Detailed test failure analysis with stack traces'
},
{
action: 'Validate Pydantic Models',
tool: 'validate_pydantic_models',
purpose: 'Check for model validation issues causing test failures',
command: 'validate_pydantic_models({ modelFilePath: "models.py", validationError: "error message" })',
expectedResult: 'Pydantic model validation analysis'
},
{
action: 'Debug Database Schema Issues',
tool: 'debug_database_schema',
purpose: 'Identify database-related test failures',
command: 'debug_database_schema({ schemaFilePath: "schema.py", databaseType: "postgresql" })',
expectedResult: 'Database schema analysis and migration suggestions'
}
],
'api_integration_issues': [
{
action: 'Start Frontend Debugging Session',
tool: 'inject_debugging',
purpose: 'Debug frontend-backend API integration',
command: 'inject_debugging({ url: "http://localhost:3000" })',
expectedResult: 'Active debugging session for API testing'
},
{
action: 'Monitor Network Requests',
tool: 'monitor_realtime',
purpose: 'Watch API calls in real-time',
command: 'monitor_realtime({ sessionId: "session-id", events: ["network_requests", "api_responses"] })',
expectedResult: 'Real-time API request/response monitoring'
},
{
action: 'Simulate API Interaction',
tool: 'simulate_user_action',
purpose: 'Trigger the API call that is failing',
command: 'simulate_user_action({ sessionId: "session-id", action: "api_request", data: "request-data" })',
expectedResult: 'API request reproduction with monitoring data'
},
{
action: 'Analyze Backend API Code',
tool: 'analyze_api_integration',
purpose: 'Debug backend API endpoint issues',
command: 'analyze_api_integration({ apiEndpointPath: "api/endpoints.py", frameworkType: "fastapi" })',
expectedResult: 'Backend API analysis with integration recommendations'
}
]
};
// Match error description to workflow
const errorLower = error.toLowerCase();
if (errorLower.includes('genserver') || errorLower.includes('process') || errorLower.includes('not alive')) {
return workflows['genserver_not_alive'];
}
else if (errorLower.includes('test') || errorLower.includes('pytest') || errorLower.includes('unittest')) {
return workflows['python_test_failures'];
}
else if (errorLower.includes('api') || errorLower.includes('integration') || errorLower.includes('request')) {
return workflows['api_integration_issues'];
}
// Default general debugging workflow
return [
{
action: 'Start Investigation Session',
tool: 'inject_debugging',
purpose: 'Begin active debugging session',
command: 'inject_debugging({ url: "application-url" })',
expectedResult: 'Active debugging session established'
},
{
action: 'Reproduce the Issue',
tool: 'simulate_user_action',
purpose: 'Recreate the conditions that cause the error',
command: 'simulate_user_action({ sessionId: "session-id", action: "reproduce_issue" })',
expectedResult: 'Issue successfully reproduced for analysis'
}
];
}
adjustWorkflowForTime(workflow, timeAllocation) {
switch (timeAllocation) {
case 'quick':
return workflow.slice(0, 2); // First 2 steps only
case 'comprehensive':
return workflow; // All steps
default: // thorough
return workflow.slice(0, 4); // First 4 steps
}
}
async createDebuggingSessionPlan(args) {
const { issueType, reproduction, expectedOutcome, frameworkSpecific } = args;
const sections = [
'๐ **Debugging Session Plan**',
'',
`**Issue Type**: ${issueType}`,
`**Reproduction Steps**: ${reproduction}`,
`**Expected vs Actual**: ${expectedOutcome}`,
'',
'## ๐ฏ **Session Objectives**',
'',
'1. **Reproduce**: Actively recreate the issue using ai-debug tools',
'2. **Monitor**: Observe system behavior during issue reproduction',
'3. **Analyze**: Capture detailed state information',
'4. **Validate**: Test fixes using the same reproduction steps',
'',
'## ๐ **TDD Debugging Loop**',
'',
'1. **Red Phase**: Reproduce the failing condition',
'2. **Green Phase**: Implement minimal fix',
'3. **Refactor Phase**: Validate fix with ai-debug monitoring',
'4. **Repeat**: Continue until issue is fully resolved',
'',
'## ๐ ๏ธ **Tool Sequence for Active Debugging**',
''
];
const toolSequence = this.generateToolSequenceForIssueType(issueType);
toolSequence.forEach((step, index) => {
sections.push(`### ${index + 1}. ${step.action}`);
sections.push(`\`${step.tool}\` - ${step.description}`);
sections.push('');
});
return this.createTextResponse(sections.join('\n'));
}
generateToolSequenceForIssueType(issueType) {
const sequences = {
'process_lifecycle': [
{ action: 'Start debugging session', tool: 'inject_debugging', description: 'Establish active debugging connection' },
{ action: 'Monitor process events', tool: 'monitor_realtime', description: 'Watch process lifecycle in real-time' },
{ action: 'Reproduce process issue', tool: 'simulate_user_action', description: 'Trigger the process termination' },
{ action: 'Capture failure state', tool: 'take_screenshot', description: 'Document UI state during failure' },
{ action: 'Analyze logs', tool: 'get_console_logs', description: 'Collect error logs and stack traces' }
],
'test_failures': [
{ action: 'Analyze test structure', tool: 'analyze_python_tests', description: 'Comprehensive test failure analysis' },
{ action: 'Validate models', tool: 'validate_pydantic_models', description: 'Check Pydantic model issues' },
{ action: 'Debug schema', tool: 'debug_database_schema', description: 'Identify database-related failures' },
{ action: 'Analyze backend logic', tool: 'analyze_backend_logic', description: 'Debug complex business logic' }
],
'ui_issues': [
{ action: 'Start UI debugging', tool: 'inject_debugging', description: 'Launch browser debugging session' },
{ action: 'Navigate to problem area', tool: 'simulate_user_action', description: 'Go to affected UI component' },
{ action: 'Capture initial state', tool: 'take_screenshot', description: 'Document current UI state' },
{ action: 'Monitor interactions', tool: 'monitor_realtime', description: 'Watch UI interactions in real-time' },
{ action: 'Test user flows', tool: 'simulate_user_action', description: 'Execute user interactions' }
]
};
return sequences[issueType] || sequences['ui_issues'];
}
async getTddDebuggingGuidance(args) {
const { developmentPhase, testType, iterationGoal } = args;
const sections = [
'๐ **Test-Driven Debugging (TDD) Guidance**',
'',
`**Phase**: ${developmentPhase}`,
`**Test Type**: ${testType}`,
`**Goal**: ${iterationGoal}`,
'',
'## ๐ฏ **TDD Debugging Principles**',
'',
'1. **Debug First**: Understand the problem before implementing solutions',
'2. **Validate Continuously**: Use ai-debug tools to verify each change',
'3. **Reproduce Reliably**: Ensure you can consistently recreate issues',
'4. **Monitor Changes**: Watch system behavior as you implement fixes',
'',
'## ๐ **Phase-Specific Guidance**',
''
];
const phaseGuidance = this.getPhaseSpecificGuidance(developmentPhase, testType);
sections.push(...phaseGuidance);
return this.createTextResponse(sections.join('\n'));
}
getPhaseSpecificGuidance(phase, testType) {
const guidance = {
'implementing_fix': [
'### ๐ง Implementing Fix Phase',
'',
'**Before implementing**:',
'- Use `inject_debugging` to establish active monitoring',
'- Use `monitor_realtime` to watch system behavior',
'- Use `take_screenshot` to capture "before" state',
'',
'**During implementation**:',
'- Use `simulate_user_action` to test changes incrementally',
'- Use `monitor_realtime` to validate that changes work as expected',
'',
'**After implementation**:',
'- Use `take_screenshot` to capture "after" state',
'- Use the same reproduction steps to verify the fix',
''
],
'validating_solution': [
'### โ
Validating Solution Phase',
'',
'**Validation Steps**:',
'- Reproduce original issue to confirm it\'s fixed',
'- Use `monitor_realtime` to ensure no new issues introduced',
'- Use `simulate_user_action` to test edge cases',
'- Use `take_screenshot` for before/after comparison',
'',
'**Success Criteria**:',
'- Original reproduction steps no longer cause the issue',
'- No new errors or warnings in monitoring',
'- UI behaves as expected in all test scenarios',
''
]
};
return guidance[phase] || ['### General TDD guidance for current phase'];
}
async analyzeDebuggingGap(args) {
const { previousApproach, toolsUsed, resultAchieved, issueStillPresent } = args;
const sections = [
'๐ **Debugging Gap Analysis**',
'',
`**Previous Approach**: ${previousApproach}`,
`**Tools Used**: ${toolsUsed?.join(', ') || 'None specified'}`,
`**Result**: ${resultAchieved}`,
`**Issue Still Present**: ${issueStillPresent ? 'Yes' : 'No'}`,
'',
'## ๐ **Analysis**',
''
];
// Analyze the gap
const analysis = this.analyzeApproachGaps(previousApproach, toolsUsed, resultAchieved);
sections.push(...analysis);
sections.push('## ๐ก **Recommended Next Steps**');
sections.push('');
const recommendations = this.generateImprovedApproach(previousApproach, toolsUsed);
sections.push(...recommendations);
return this.createTextResponse(sections.join('\n'));
}
analyzeApproachGaps(approach, tools, result) {
const analysis = [];
if (!tools || tools.length === 0) {
analysis.push('**Gap Identified**: No ai-debug tools were used for active debugging');
analysis.push('**Impact**: Likely using passive analysis instead of active reproduction');
}
if (!tools?.includes('inject_debugging')) {
analysis.push('**Gap Identified**: No active debugging session established');
analysis.push('**Impact**: Cannot perform real-time investigation or reproduction');
}
if (!tools?.includes('monitor_realtime')) {
analysis.push('**Gap Identified**: No real-time monitoring during debugging');
analysis.push('**Impact**: Missing crucial system behavior observations');
}
if (!tools?.includes('simulate_user_action')) {
analysis.push('**Gap Identified**: No active reproduction of user interactions');
analysis.push('**Impact**: Cannot reliably recreate the problem conditions');
}
if (approach.toLowerCase().includes('verification') || approach.toLowerCase().includes('checking')) {
analysis.push('**Gap Identified**: Verification-focused instead of investigation-focused approach');
analysis.push('**Impact**: Not reproducing and understanding the root cause');
}
return analysis;
}
generateImprovedApproach(previousApproach, toolsUsed) {
return [
'1. **Start with Active Debugging**: Use `inject_debugging` to establish a live session',
'2. **Reproduce the Issue**: Use `simulate_user_action` to recreate the exact problem',
'3. **Monitor in Real-time**: Use `monitor_realtime` to observe system behavior during reproduction',
'4. **Capture Evidence**: Use `take_screenshot` and `get_console_logs` to document the issue',
'5. **Implement and Validate**: Make changes while monitoring continues to validate fixes',
'',
'**Key Shift**: Move from "checking if things work" to "actively investigating why things fail"'
];
}
/**
* Generate TDD implementation steps from failing tests (NEW TDD TOOL)
*/
async suggestTddImplementationSteps(args) {
const { failingTests, testContext, timeConstraint, generateCodeTemplates } = args;
// Create implementation context for TDD planner
const implementationContext = {
failing_tests: failingTests,
test_framework: testContext?.testFramework || 'flutter_test',
authentication_required: testContext?.authenticationRequired !== false,
ui_components_needed: testContext?.uiComponentsNeeded || [],
provider_dependencies: [], // Could be enhanced to extract from test analysis
complexity_level: testContext?.complexityLevel || 'moderate',
time_constraint: timeConstraint || 'none'
};
// Generate TDD implementation plan
const tddPlan = await this.tddPlanner.generateImplementationPlan(implementationContext);
const sections = [
'๐ฏ **TDD Implementation Steps from Failing Tests**',
'',
`**Failing Tests**: ${failingTests.length} test(s)`,
`**Test Framework**: ${implementationContext.test_framework}`,
`**Time Constraint**: ${timeConstraint}`,
`**Complexity**: ${implementationContext.complexity_level}`,
'',
'## ๐ **Generated Implementation Plan**',
'',
`**Plan Title**: ${tddPlan.title}`,
`**Methodology**: ${tddPlan.methodology}`,
`**Estimated Time**: ${tddPlan.estimatedTimeMinutes} minutes`,
`**Success Criteria**: ${tddPlan.success_criteria.length} criteria defined`,
'',
'## ๐ **TDD Phases**',
''
];
// Add each phase with steps
tddPlan.phases.forEach((phase, phaseIndex) => {
const phaseIcon = phase.phase_type === 'red' ? '๐ด' :
phase.phase_type === 'green' ? '๐ข' :
phase.phase_type === 'refactor' ? '๐ต' : 'โ
';
sections.push(`### ${phaseIcon} Phase ${phaseIndex + 1}: ${phase.name}`);
sections.push(`**Description**: ${phase.description}`);
sections.push(`**Duration**: ~${phase.duration_estimate_minutes} minutes`);
if (phase.prerequisites.length > 0) {
sections.push(`**Prerequisites**: ${phase.prerequisites.join(', ')}`);
}
sections.push('');
sections.push('**Steps**:');
phase.steps.forEach((step, stepIndex) => {
const stepIcon = step.step_type === 'test' ? '๐งช' :
step.step_type === 'implement' ? '๐จ' :
step.step_type === 'refactor' ? 'โป๏ธ' :
step.step_type === 'validate' ? 'โ
' : '๐ง';
sections.push(`${stepIndex + 1}. ${stepIcon} **${step.action}**`);
sections.push(` - ${step.description}`);
sections.push(` - Tools: ${step.tools_needed.join(', ')}`);
if (step.validation_criteria.length > 0) {
sections.push(` - Success: ${step.validation_criteria.join(', ')}`);
}
if (generateCodeTemplates && step.code_template) {
sections.push(' - Code Template:');
sections.push(' ```dart');
sections.push(` ${step.code_template.trim()}`);
sections.push(' ```');
}
if (step.common_pitfalls.length > 0) {
sections.push(` - โ ๏ธ Avoid: ${step.common_pitfalls.join(', ')}`);
}
sections.push('');
});
sections.push(`**Success Indicators**: ${phase.success_indicators.join(', ')}`);
sections.push('');
});
// Quality gates
if (tddPlan.quality_gates.length > 0) {
sections.push('## ๐ง **Quality Gates**');
sections.push('');
tddPlan.quality_gates.forEach(gate => {
const blockingIcon = gate.blocking ? '๐ซ' : 'โน๏ธ';
sections.push(`${blockingIcon} **${gate.name}** ${gate.blocking ? '(Blocking)' : '(Advisory)'}`);
sections.push(`**Criteria**: ${gate.criteria.join(', ')}`);
sections.push(`**Automated Checks**: ${gate.automated_checks.join(', ')}`);
sections.push('');
});
}
sections.push('## ๐ก **TDD Success Tips (Based on Cycle 22)**');
sections.push('- **Start with provider mocks** - Fix authentication issues first');
sections.push('- **Use visual debugging** - Screenshot before and after each step');
sections.push('- **Keep implementations minimal** - Only do what makes tests pass');
sections.push('- **Validate continuously** - Use ai-debug tools to verify each change');
sections.push('');
sections.push('## ๐ฏ **Next Actions**');
sections.push('1. **Start with Phase 1** - Focus on the current failing tests');
sections.push('2. **Use `detect_flutter_test_mode`** to configure test environment');
sections.push('3. **Use `analyze_provider_gaps`** to fix authentication issues');
sections.push('4. **Use `track_implementation_progress`** to monitor each step');
return this.createTextResponse(sections.join('\n'));
}
/**
* Validate test-driven architecture patterns (NEW TDD TOOL)
*/
async validateTestDrivenArchitecture(args) {
const { implementationContext, architectureGoals } = args;
const sections = [
'๐๏ธ **Test-Driven Architecture Validation**',
'',
`**Component Type**: ${implementationContext.componentType}`,
`**Architecture Goals**: ${architectureGoals.join(', ')}`,
'',
'## ๐ **Test Coverage Analysis**',
''
];
const testCoverage = implementationContext.testCoverage || {};
const coverageScore = this.calculateCoverageScore(testCoverage);
sections.push(`**Overall Test Coverage Score**: ${coverageScore}/100`);
sections.push(`**Unit Tests**: ${testCoverage.hasUnitTests ? 'โ
' : 'โ'}`);
sections.push(`**Widget Tests**: ${testCoverage.hasWidgetTests ? 'โ
' : 'โ'}`);
sections.push(`**Integration Tests**: ${testCoverage.hasIntegrationTests ? 'โ
' : 'โ'}`);
if (testCoverage.testToCodeRatio) {
sections.push(`**Test-to-Code Ratio**: ${testCoverage.testToCodeRatio}:1 ${this.evaluateTestRatio(testCoverage.testToCodeRatio)}`);
}
sections.push('');
// Architecture goal validation
sections.push('## ๐ฏ **Architecture Goal Validation**');
sections.push('');
architectureGoals.forEach((goal) => {
const validation = this.validateArchitectureGoal(goal, implementationContext);
const statusIcon = validation.score >= 80 ? 'โ
' : validation.score >= 60 ? 'โ ๏ธ' : 'โ';
sections.push(`### ${statusIcon} ${goal.replace('_', ' ').toUpperCase()}`);
sections.push(`**Score**: ${validation.score}/100`);
sections.push(`**Assessment**: ${validation.assessment}`);
if (validation.recommendations.length > 0) {
sections.push('**Recommendations**:');
validation.recommendations.forEach(rec => {
sections.push(`- ${rec}`);
});
}
sections.push('');
});
// Dependency analysis
const depStructure = implementationContext.dependencyStructure || {};
if (depStructure.providerDependencies?.length > 0 || depStructure.externalDependencies?.length > 0) {
sections.push('## ๐ **Dependency Structure Analysis**');
sections.push('');
if (depStructure.providerDependencies?.length > 0) {
sections.push('**Provider Dependencies**:');
depStructure.providerDependencies.forEach((dep) => {
const testability = this.assessProviderTestability(dep);
sections.push(`- ${dep} ${testability.icon} ${testability.assessment}`);
});
sections.push('');
}
if (depStructure.externalDependencies?.length > 0) {
sections.push('**External Dependencies**:');
depStructure.externalDependencies.forEach((dep) => {
const mockability = this.assessExternalDependencyMockability(dep);
sections.push(`- ${dep} ${mockability.icon} ${mockability.assessment}`);
});
sections.push('');
}
}
// TDD quality indicators
sections.push('## ๐ **TDD Quality Indicators**');
sections.push('');
const tddQuality = this.assessTddQuality(implementationContext);
sections.push(`**Red-Green-Refactor Adherence**: ${tddQuality.redGreenRefactor}%`);
sections.push(`**Test-First Development**: ${tddQuality.testFirst ? 'โ
' : 'โ'}`);
sections.push(`**Minimal Implementation**: ${tddQuality.minimalImplementation ? 'โ
' : 'โ'}`);
sections.push(`**Continuous Refactoring**: ${tddQuality.continuousRefactoring ? 'โ
' : 'โ'}`);
sections.push('');
// Recommendations
sections.push('## ๐ก **Architecture Improvement Recommendations**');
sections.push('');
const recommendations = this.generateArchitectureRecommendations(implementationContext, architectureGoals);
recommendations.forEach(rec => {
sections.push(`- **${rec.priority}**: ${rec.recommendation}`);
if (rec.reasoning) {
sections.push(` Reasoning: ${rec.reasoning}`);
}
sections.push('');
});
sections.push('## ๐ฏ **Next Steps for Architecture Improvement**');
sections.push('1. **Address high-priority recommendations** first');
sections.push('2. **Increase test coverage** for areas scoring below 80%');
sections.push('3. **Use `suggest_tdd_implementation_steps`** for systematic improvement');
sections.push('4. **Re-run this validation** after implementing changes');
return this.createTextResponse(sections.join('\n'));
}
/**
* Analyze test failure patterns to identify anti-patterns (NEW TDD TOOL)
*/
async analyzeTestFailurePatterns(args) {
const { testFailureHistory, currentTestSuite, analysisDepth } = args;
const sections = [
'๐ **Test Failure Pattern Analysis**',
'',
`**Test History**: ${testFailureHistory.length} failure records`,
`**Analysis Depth**: ${analysisDepth}`,
`**Current Test Suite**: ${currentTestSuite?.totalTests || 'Not specified'} tests`,
'',
'## ๐ **Failure Pattern Analysis**',
''
];
// Categorize failures
const failureCategories = this.categorizeFailures(testFailureHistory);
const patterns = this.identifyFailurePatterns(testFailureHistory);
sections.push('### ๐ **Failure Categories**');
sections.push('');
Object.entries(failureCategories).forEach(([category, failures]) => {
const percentage = Math.round((failures.length / testFailureHistory.length) * 100);
const trend = this.analyzeCategoryTrend(category, failures);
sections.push(`**${category.toUpperCase()}**: ${failures.length} failures (${percentage}%) ${trend.icon}`);
sections.push(`- Average resolution time: ${this.calculateAverageResolutionTime(failures)} minutes`);
sections.push(`- Trend: ${trend.description}`);
sections.push('');
});
// Common anti-patterns
sections.push('### โ ๏ธ **Identified Anti-Patterns**');
sections.push('');
const antiPatterns = this.identifyTestAntiPatterns(testFailureHistory);
antiPatterns.forEach(pattern => {
const severityIcon = pattern.severity === 'high' ? '๐จ' :
pattern.severity === 'medium' ? 'โ ๏ธ' : 'โน๏ธ';
sections.push(`${severityIcon} **${pattern.name}**`);
sections.push(`**Frequency**: ${pattern.frequency} occurrences`);
sections.push(`**Impact**: ${pattern.impact}`);
sections.push(`**Resolution**: ${pattern.resolution}`);
sections.push('');
});
// Temporal patterns
if (analysisDepth === 'detailed' || analysisDepth === 'comprehensive') {
sections.push('### โฐ **Temporal Patterns**');
sections.push('');
const temporalPatterns = this.analyzeTemporalPatterns(testFailureHistory);
temporalPatterns.forEach(pattern => {
sections.push(`- **${pattern.type}**: ${pattern.description}`);
});
sections.push('');
}
// Flaky test analysis
if (currentTestSuite?.flakyTests?.length > 0) {
sections.push('### ๐ฒ **Flaky Test Analysis**');
sections.push('');
sections.push(`**Flaky Tests Identified**: ${currentTestSuite.flakyTests.length}`);
const flakiness = (currentTestSuite.flakyTests.length / (currentTestSuite.totalTests || 1)) * 100;
sections.push(`**Flakiness Rate**: ${Math.round(flakiness)}% ${this.evaluateFlakiness(flakiness)}`);
sections.push('**Flaky Tests**:');
currentTestSuite.flakyTests.forEach((test) => {
sections.push(`- ${test}`);
});
sections.push('');
}
// Success rate analysis
if (currentTestSuite?.totalTests && currentTestSuite?.passingTests) {
const successRate = Math.round((currentTestSuite.passingTests / currentTestSuite.totalTests) * 100);
sections.push(`### ๐ **Current Test Suite Health**`);
sections.push('');
sections.push(`**Success Rate**: ${successRate}% ${this.evaluateSuccessRate(successRate)}`);
sections.push(`**Passing Tests**: ${currentTestSuite.passingTests}/${currentTestSuite.totalTests}`);
sections.push('');
}
// Recommendations based on patterns
sections.push('## ๐ก **Pattern-Based Recommendations**');
sections.push('');
const recommendations = this.generatePatternRecommendations(failureCategories, antiPatterns);
recommendations.forEach(rec => {
sections.push(`**${rec.priority}**: ${rec.recommendation}`);
sections.push(`Action: ${rec.action}`);
sections.push('');
});
// Prevention strategies
sections.push('## ๐ก๏ธ **Failure Prevention Strategies**');
sections.push('');
const preventionStrategies = this.generatePreventionStrategies(antiPatterns);
preventionStrategies.forEach(strategy => {
sections.push(`- **${strategy.category}**: ${strategy.strategy}`);
});
sections.push('');
sections.push('## ๐ฏ **Next Steps**');
sections.push('1. **Address highest frequency anti-patterns** first');
sections.push('2. **Implement prevention strategies** for recurring issues');
sections.push('3. **Use `suggest_tdd_implementation_steps`** for systematic improvements');
sections.push('4. **Re-analyze patterns** after implementing improvements');
return this.createTextResponse(sections.join('\n'));
}
// Helper methods for the new TDD tools
calculateCoverageScore(testCoverage) {
let score = 0;
if (testCoverage.hasUnitTests)
score += 30;
if (testCoverage.hasWidgetTests)
score += 40;
if (testCoverage.hasIntegrationTests)
score += 30;
// Adjust based on test-to-code ratio
if (testCoverage.testToCodeRatio) {
if (testCoverage.testToCodeRatio >= 0.8)
score += 10;
else if (testCoverage.testToCodeRatio >= 0.5)
score += 5;
}
return Math.min(score, 100);
}
evaluateTestRatio(ratio) {
if (ratio >= 1.0)
return 'โ
Excellent';
if (ratio >= 0.8)
return '๐ Good';
if (ratio >= 0.5)
return 'โ ๏ธ Adequate';
return 'โ Insufficient';
}
validateArchitectureGoal(goal, context) {
const validations = {
'testability': {
score: context.testCoverage?.hasWidgetTests ? 80 : 40,
assessment: context.testCoverage?.hasWidgetTests ? 'Good testability with widget tests' : 'Limited testability - missing widget tests',
recommendations: context.testCoverage?.hasWidgetTests ? [] : ['Add widget tests for UI components', 'Create test utilities for common scenarios']
},
'maintainability': {
score: 75,
assessment: 'Component structure supports maintainability',
recommendations: ['Consider extracting reusable components', 'Add comprehensive documentation']
},
'separation_of_concerns': {
score: context.dependencyStructure?.providerDependencies ? 85 : 60,
assessment: context.dependencyStructure?.providerDependencies ? 'Good separation with provider pattern' : 'Could improve separation of concerns',
recommendations: context.dependencyStructure?.providerDependencies ? [] : ['Use provider pattern for state management', 'Separate business logic from UI']
}
};
return validations[goal] || { score: 50, assessment: 'Unable to assess', recommendations: [] };
}
assessProviderTestability(provider) {
const knownTestableProviders = ['unifiedAuthNotifierProvider', 'currentUserProvider', 'unifiedFamilyMembersProvider'];
if (knownTestableProviders.includes(provider)) {
return { icon: 'โ
', assessment: 'Easily mockable for tests' };
}
return { icon: 'โ ๏ธ', assessment: 'May need custom mocking strategy' };
}
assessExternalDependencyMockability(dep) {
const easyToMock = ['http', 'api', 'storage'];
const hardToMock = ['camera', 'location', 'platform'];
if (easyToMock.some(easy => dep.toLowerCase().includes(easy))) {
return { icon: 'โ
', assessment: 'Standard mocking available' };
}
if (hardToMock.some(hard => dep.toLowerCase().includes(hard))) {
return { icon: 'โ', assessment: 'Requires platform-specific mocking' };
}
return { icon: 'โ ๏ธ', assessment: 'Mockability depends on implementation' };
}
assessTddQuality(context) {
// Simple heuristic-based assessment
return {
redGreenRefactor: context.testCoverage?.hasUnitTests ? 80 : 40,
testFirst: context.testCoverage?.testToCodeRatio >= 0.8,
minimalImplementation: true, // Would need code analysis to determine
continuousRefactoring: false // Would need git history analysis
};
}
generateArchitectureRecommendations(context, goals) {
const recommendations = [];
if (!context.testCoverage?.hasWidgetTests) {
recommendations.push({
priority: 'HIGH',
recommendation: 'Add widget tests for UI components',
reasoning: 'Widget tests are essential for TDD in Flutter applications'
});
}
if (!context.dependencyStructure?.providerDependencies) {
recommendations.push({
priority: 'MEDIUM',
recommendation: 'Implement provider pattern for state management',
reasoning: 'Providers improve testability and separation of concerns'
});
}
return recommendations;
}
categorizeFailures(failures) {
const categories = {};
failures.forEach(failure => {
const category = failure.failureCategory || 'unknown';
if (!categories[category])
categories[category] = [];
categories[category].push(failure);
});
return categories;
}
identifyFailurePatterns(failures) {
// Simple pattern identification - could be enhanced with ML
const patterns = [];
const authFailures = failures.filter(f => f.failureCategory === 'authentication');
if (authFailures.length > failures.length * 0.3) {
patterns.push({
type: 'authentication_heavy',
description: 'High proportion of authentication-related failures',
recommendation: 'Review authentication mocking strategy'
});
}
return patterns;
}
analyzeCategoryTrend(category, failures) {
// Simple trend analysis - could be enhanced with time series analysis
const recent = failures.filter(f => f.timeToResolve && f.timeToResolve < 30);
const trend = recent.length / failures.length;
if (trend > 0.7) {
return { icon: '๐', description: 'Improving resolution times' };
}
else if (trend < 0.3) {
return { icon: '๐', description: 'Degrading resolution times' };
}
return { icon: 'โก๏ธ', description: 'Stable resolution times' };
}
calculateAverageResolutionTime(failures) {
const timesWithData = failures.filter(f => f.timeToResolve).map(f => f.timeToResolve);
if (timesWithData.length === 0)
return 0;
return Math.round(timesWithData.reduce((sum, time) => sum + time, 0) / timesWithData.length);
}
identifyTestAntiPatterns(failures) {
const antiPatterns = [];
// Identify specific anti-patterns from failure history
const authFailures = failures.filter(f => f.failureCategory === 'authentication');
if (authFailures.length >= 3) {
antiPatterns.push({
name: 'Inconsistent Authentication Mocking',
frequency: authFailures.length,
severity: 'high',
impact: 'Causes repeated test failures and development delays',
resolution: 'Create standardized authentication test utilities (like DashboardTestUtils)'
});
}
const widgetFailures = failures.filter(f => f.failureCategory === 'missing_widget');
if (widgetFailures.length >= 2) {
antiPatterns.push({
name: 'Implementation Before Tests Pattern',
frequency: widgetFailures.length,
severity: 'medium',
impact: 'Tests fail because implementation does not match expectations',
resolution: 'Follow TDD red-green-refactor cycle strictly'
});
}
return antiPatterns;
}
analyzeTemporalPatterns(failures) {
// Simplified temporal analysis
return [
{
type: 'Authentication failures cluster',
description: 'Multiple authentication failures suggest systematic mocking issues'
}
];
}
evaluateFlakiness(rate) {
if (rate > 20)
return '๐จ Critical';
if (rate > 10)
return 'โ ๏ธ High';
if (rate > 5)
return 'โ ๏ธ Moderate';
return 'โ
Low';
}
evaluateSuccessRate(rate) {
if (rate >= 95)
return 'โ
Excellent';
if (rate >= 85)
return '๐ Good';
if (rate >= 70)
return 'โ ๏ธ Needs improvement';
return 'โ Poor';
}
generatePatternRecommendations(categories, antiPatterns) {
const recommendations = [];
if (antiPatterns.find(p => p.name.includes('Authentication'))) {
recommendations.push({
priority: 'HIGH',
recommendation: 'Standardize authentication mocking',
action: 'Use `suggest_authentication_mocks` tool to create reusable test utilities'
});
}
return recommendations;
}
generatePreventionStrategies(antiPatterns) {
return [
{
category: 'Authentication',
strategy: 'Create comprehensive test utilities with all required provider mocks'
},
{
category: 'Widget Testing',
strategy: 'Use TDD approach - write tests first, then implement to make them pass'
},
{
category: 'Provider Management',
strategy: 'Maintain consistent provider mocking patterns across all tests'
}
];
}
}
//# sourceMappingURL=debug-workflow-advisor.js.map