#!/usr/bin/env python3 """ CleverClaude Migration Validation Script This script validates that the Python implementation preserves all functionality from the original TypeScript claude-flow project. """ import sys from pathlib import Path class MigrationValidator: """Validates the completeness of the TypeScript to Python migration.""" def __init__(self): self.src_path = Path(__file__).parent / "src" / "cleverclaude" self.validation_results = { "core_modules": {"passed": 0, "failed": 0, "details": []}, "mcp_tools": {"passed": 0, "failed": 0, "details": []}, "cli_commands": {"passed": 0, "failed": 0, "details": []}, "agent_types": {"passed": 0, "failed": 0, "details": []}, "swarm_topologies": {"passed": 0, "failed": 0, "details": []}, "configuration": {"passed": 0, "failed": 0, "details": []}, "testing": {"passed": 0, "failed": 0, "details": []}, "architecture": {"passed": 0, "failed": 0, "details": []}, } def validate_core_modules(self) -> bool: """Validate that all core modules are implemented.""" print("šŸ” Validating core modules...") required_modules = [ "core/app.py", "agents/__init__.py", "agents/manager.py", "agents/types.py", "coordination/swarm.py", "coordination/types.py", "mcp/client.py", "mcp/protocol.py", "mcp/types.py", "cli/main.py", "cli/commands/init.py", "cli/commands/start.py", "cli/commands/status.py", "config/settings.py", "database/models.py", "neural/network.py", "memory/manager.py", ] all_passed = True for module_path in required_modules: full_path = self.src_path / module_path if full_path.exists(): self.validation_results["core_modules"]["passed"] += 1 self.validation_results["core_modules"]["details"].append(f"āœ… {module_path}") else: self.validation_results["core_modules"]["failed"] += 1 self.validation_results["core_modules"]["details"].append(f"āŒ {module_path} - Missing") all_passed = False return all_passed def validate_mcp_tools(self) -> bool: """Validate MCP tools implementation.""" print("šŸ” Validating MCP tools (87+ tools requirement)...") # Check if MCP protocol file exists and has tool definitions mcp_protocol_path = self.src_path / "mcp" / "protocol.py" if not mcp_protocol_path.exists(): self.validation_results["mcp_tools"]["failed"] += 1 self.validation_results["mcp_tools"]["details"].append("āŒ MCP protocol file missing") return False # Read protocol file and count tool constants protocol_content = mcp_protocol_path.read_text() # Expected tool categories based on original claude-flow expected_tools = [ # Core swarm management "swarm_init", "agent_spawn", "task_orchestrate", "swarm_status", "swarm_destroy", "agent_list", "agent_metrics", "swarm_monitor", "topology_optimize", "load_balance", # Neural operations "neural_train", "neural_predict", "neural_status", "neural_patterns", "model_load", "model_save", "inference_run", "pattern_recognize", "cognitive_analyze", # Memory management "memory_usage", "memory_search", "memory_persist", "memory_namespace", "memory_backup", "cache_manage", "state_snapshot", "context_restore", # Performance monitoring "performance_report", "bottleneck_analyze", "token_usage", "benchmark_run", "metrics_collect", "trend_analysis", "cost_analysis", "quality_assess", # Workflow automation "workflow_create", "workflow_execute", "workflow_export", "automation_setup", "pipeline_create", "scheduler_manage", "trigger_setup", # GitHub integration "github_repo_analyze", "github_pr_manage", "github_issue_track", "github_release_coord", "github_workflow_auto", "github_code_review", "github_sync_coord", "github_metrics", # DAA (Decentralized Autonomous Agents) "daa_agent_create", "daa_capability_match", "daa_resource_alloc", "daa_lifecycle_manage", "daa_communication", "daa_consensus", "daa_fault_tolerance", "daa_optimization", # System tools "terminal_execute", "config_manage", "features_detect", "security_scan", "backup_create", "restore_system", "log_analysis", "diagnostic_run", # Additional specialized tools "wasm_optimize", "coordination_sync", "swarm_scale", "learning_adapt", "ensemble_create", "transfer_learn", "neural_explain", "memory_compress", "memory_sync", "memory_analytics", "parallel_execute", "batch_process", "health_check", "usage_stats", "error_analysis", ] found_tools = 0 missing_tools = [] for tool in expected_tools: if tool.upper() in protocol_content or f'"{tool}"' in protocol_content: found_tools += 1 else: missing_tools.append(tool) self.validation_results["mcp_tools"]["passed"] = found_tools self.validation_results["mcp_tools"]["failed"] = len(missing_tools) if found_tools >= 87: # Meets the 87+ requirement self.validation_results["mcp_tools"]["details"].append( f"āœ… {found_tools} MCP tools implemented (exceeds 87+ requirement)" ) return True else: self.validation_results["mcp_tools"]["details"].append( f"āŒ Only {found_tools} tools found, missing {len(missing_tools)}" ) self.validation_results["mcp_tools"]["details"].extend( [f" Missing: {tool}" for tool in missing_tools[:10]] ) return False def validate_cli_commands(self) -> bool: """Validate CLI command compatibility.""" print("šŸ” Validating CLI commands...") cli_main_path = self.src_path / "cli" / "main.py" if not cli_main_path.exists(): self.validation_results["cli_commands"]["failed"] += 1 self.validation_results["cli_commands"]["details"].append("āŒ CLI main module missing") return False cli_content = cli_main_path.read_text() # Check for required commands required_commands = ["init", "start", "status", "config", "monitor"] all_passed = True for command in required_commands: if f'"{command}"' in cli_content or f"'{command}'" in cli_content: self.validation_results["cli_commands"]["passed"] += 1 self.validation_results["cli_commands"]["details"].append(f"āœ… Command '{command}' implemented") else: self.validation_results["cli_commands"]["failed"] += 1 self.validation_results["cli_commands"]["details"].append(f"āŒ Command '{command}' missing") all_passed = False return all_passed def validate_agent_types(self) -> bool: """Validate agent types implementation.""" print("šŸ” Validating agent types...") agent_types_path = self.src_path / "agents" / "types.py" if not agent_types_path.exists(): self.validation_results["agent_types"]["failed"] += 1 self.validation_results["agent_types"]["details"].append("āŒ Agent types module missing") return False types_content = agent_types_path.read_text() # Check for required agent types required_types = ["RESEARCHER", "CODER", "ANALYST", "COORDINATOR", "REVIEWER", "TESTER"] all_passed = True for agent_type in required_types: if agent_type in types_content: self.validation_results["agent_types"]["passed"] += 1 self.validation_results["agent_types"]["details"].append(f"āœ… AgentType.{agent_type} implemented") else: self.validation_results["agent_types"]["failed"] += 1 self.validation_results["agent_types"]["details"].append(f"āŒ AgentType.{agent_type} missing") all_passed = False return all_passed def validate_swarm_topologies(self) -> bool: """Validate swarm topology implementations.""" print("šŸ” Validating swarm topologies...") coord_types_path = self.src_path / "coordination" / "types.py" if not coord_types_path.exists(): self.validation_results["swarm_topologies"]["failed"] += 1 self.validation_results["swarm_topologies"]["details"].append("āŒ Coordination types module missing") return False types_content = coord_types_path.read_text() # Check for required topologies required_topologies = ["MESH", "HIERARCHICAL", "STAR", "RING"] all_passed = True for topology in required_topologies: if topology in types_content: self.validation_results["swarm_topologies"]["passed"] += 1 self.validation_results["swarm_topologies"]["details"].append( f"āœ… SwarmTopology.{topology} implemented" ) else: self.validation_results["swarm_topologies"]["failed"] += 1 self.validation_results["swarm_topologies"]["details"].append(f"āŒ SwarmTopology.{topology} missing") all_passed = False return all_passed def validate_configuration(self) -> bool: """Validate configuration system.""" print("šŸ” Validating configuration system...") settings_path = self.src_path / "config" / "settings.py" if not settings_path.exists(): self.validation_results["configuration"]["failed"] += 1 self.validation_results["configuration"]["details"].append("āŒ Settings module missing") return False settings_content = settings_path.read_text() # Check for required configuration sections required_configs = [ "AppConfig", "DatabaseConfig", "AgentsConfig", "SwarmConfig", "APIConfig", "MonitoringConfig", ] all_passed = True for config in required_configs: if config in settings_content: self.validation_results["configuration"]["passed"] += 1 self.validation_results["configuration"]["details"].append(f"āœ… {config} implemented") else: self.validation_results["configuration"]["failed"] += 1 self.validation_results["configuration"]["details"].append(f"āŒ {config} missing") all_passed = False return all_passed def validate_testing_framework(self) -> bool: """Validate testing framework completeness.""" print("šŸ” Validating testing framework...") # Check for BDD feature files features_dir = Path("features") if not features_dir.exists(): self.validation_results["testing"]["failed"] += 1 self.validation_results["testing"]["details"].append("āŒ BDD features directory missing") return False required_features = ["cli.feature", "agents.feature", "swarm.feature", "mcp.feature"] bdd_passed = True for feature in required_features: feature_path = features_dir / feature if feature_path.exists(): self.validation_results["testing"]["passed"] += 1 self.validation_results["testing"]["details"].append(f"āœ… BDD feature {feature} implemented") else: self.validation_results["testing"]["failed"] += 1 self.validation_results["testing"]["details"].append(f"āŒ BDD feature {feature} missing") bdd_passed = False # Check for unit tests tests_dir = Path("tests") if tests_dir.exists(): unit_tests_dir = tests_dir / "unit" if unit_tests_dir.exists(): unit_test_files = list(unit_tests_dir.glob("test_*.py")) if len(unit_test_files) >= 3: # Should have multiple unit test files self.validation_results["testing"]["passed"] += 1 self.validation_results["testing"]["details"].append( f"āœ… Unit tests implemented ({len(unit_test_files)} files)" ) else: self.validation_results["testing"]["failed"] += 1 self.validation_results["testing"]["details"].append("āŒ Insufficient unit test coverage") bdd_passed = False # Check for integration tests integration_tests_dir = tests_dir / "integration" if integration_tests_dir.exists(): integration_files = list(integration_tests_dir.glob("test_*.py")) if len(integration_files) >= 1: self.validation_results["testing"]["passed"] += 1 self.validation_results["testing"]["details"].append( f"āœ… Integration tests implemented ({len(integration_files)} files)" ) else: self.validation_results["testing"]["failed"] += 1 self.validation_results["testing"]["details"].append("āŒ Integration tests missing") bdd_passed = False return bdd_passed def validate_architecture(self) -> bool: """Validate architectural patterns and structure.""" print("šŸ” Validating architecture patterns...") architectural_checks = [ # Check for async/await patterns ("Async/Await Pattern", "async def", self.src_path), # Check for dependency injection ("Dependency Injection", "def __init__(self", self.src_path), # Check for type hints ("Type Hints", "from typing import", self.src_path), # Check for structured logging ("Structured Logging", "structlog", self.src_path), # Check for configuration management ("Configuration", "Settings", self.src_path / "config"), # Check for error handling ("Error Handling", "try:", self.src_path), ] all_passed = True for pattern_name, pattern, search_path in architectural_checks: if self._search_pattern_in_directory(pattern, search_path): self.validation_results["architecture"]["passed"] += 1 self.validation_results["architecture"]["details"].append(f"āœ… {pattern_name} implemented") else: self.validation_results["architecture"]["failed"] += 1 self.validation_results["architecture"]["details"].append(f"āŒ {pattern_name} missing") all_passed = False return all_passed def _search_pattern_in_directory(self, pattern: str, directory: Path) -> bool: """Search for a pattern in all Python files in a directory.""" if not directory.exists(): return False for py_file in directory.rglob("*.py"): try: content = py_file.read_text() if pattern in content: return True except (UnicodeDecodeError, PermissionError): continue return False def run_validation(self) -> bool: """Run all validation checks.""" print("šŸš€ Starting CleverClaude Migration Validation") print("=" * 60) validations = [ ("Core Modules", self.validate_core_modules), ("MCP Tools (87+ requirement)", self.validate_mcp_tools), ("CLI Commands", self.validate_cli_commands), ("Agent Types", self.validate_agent_types), ("Swarm Topologies", self.validate_swarm_topologies), ("Configuration", self.validate_configuration), ("Testing Framework", self.validate_testing_framework), ("Architecture Patterns", self.validate_architecture), ] all_passed = True for validation_name, validation_func in validations: try: result = validation_func() if not result: all_passed = False print() # Add spacing between validations except Exception as e: print(f"āŒ Error during {validation_name} validation: {e}") all_passed = False return all_passed def print_summary(self) -> None: """Print validation summary.""" print("=" * 60) print("šŸ“Š MIGRATION VALIDATION SUMMARY") print("=" * 60) total_passed = 0 total_failed = 0 for category, results in self.validation_results.items(): passed = results["passed"] failed = results["failed"] total_passed += passed total_failed += failed status_icon = "āœ…" if failed == 0 else "āš ļø" if passed > failed else "āŒ" print(f"{status_icon} {category.replace('_', ' ').title()}: {passed} passed, {failed} failed") # Print details for failed items if failed > 0: for detail in results["details"]: if "āŒ" in detail: print(f" {detail}") print("-" * 60) print(f"TOTAL: {total_passed} passed, {total_failed} failed") if total_failed == 0: print("šŸŽ‰ MIGRATION VALIDATION PASSED - All functionality preserved!") else: print("āš ļø MIGRATION VALIDATION INCOMPLETE - Some issues need attention") print("=" * 60) def main(): """Main validation function.""" validator = MigrationValidator() try: success = validator.run_validation() validator.print_summary() sys.exit(0 if success else 1) except KeyboardInterrupt: print("\nā¹ļø Validation interrupted by user") sys.exit(130) except Exception as e: print(f"šŸ’„ Validation failed with error: {e}") sys.exit(1) if __name__ == "__main__": main()