- Enhanced CLAUDE.md with comprehensive architecture documentation - Added KiCad IPC API integration patterns and usage examples - Documented FreeRouting integration workflow and setup - Explained dual-mode operation (IPC + CLI) with detection logic - Added tool implementation patterns and security architecture - Included debugging tips and common issue resolutions - Reorganized test files into proper structure - Moved integration tests to tests/integration/ - Moved demonstration scripts to tests/examples/ - Added .gitignore patterns for temporary exploration scripts - Updated .gitignore to exclude development/exploration scripts - Prevents accidental commits of ad-hoc testing files - Maintains clean repository structure
166 lines
5.5 KiB
Python
166 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script for enhanced KiCad MCP server functionality.
|
|
|
|
This script tests the new routing capabilities, AI integration, and IPC API features
|
|
using the thermal camera project as a test case.
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Add the kicad_mcp module to path
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
from kicad_mcp.utils.freerouting_engine import check_routing_prerequisites
|
|
from kicad_mcp.utils.ipc_client import check_kicad_availability
|
|
from kicad_mcp.tools.analysis_tools import register_analysis_tools
|
|
from kicad_mcp.tools.routing_tools import register_routing_tools
|
|
from kicad_mcp.tools.ai_tools import register_ai_tools
|
|
|
|
# Set up logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Test project path
|
|
PROJECT_PATH = "/home/rpm/claude/MLX90640-Thermal-Camera/PCB/Thermal_Camera.kicad_pro"
|
|
|
|
|
|
def test_routing_prerequisites():
|
|
"""Test routing prerequisites check."""
|
|
logger.info("Testing routing prerequisites...")
|
|
|
|
try:
|
|
status = check_routing_prerequisites()
|
|
logger.info(f"Routing prerequisites status: {json.dumps(status, indent=2)}")
|
|
|
|
# Check individual components
|
|
components = status.get("components", {})
|
|
|
|
# KiCad IPC API
|
|
kicad_ipc = components.get("kicad_ipc", {})
|
|
logger.info(f"KiCad IPC API available: {kicad_ipc.get('available', False)}")
|
|
|
|
# FreeRouting
|
|
freerouting = components.get("freerouting", {})
|
|
logger.info(f"FreeRouting available: {freerouting.get('available', False)}")
|
|
|
|
# KiCad CLI
|
|
kicad_cli = components.get("kicad_cli", {})
|
|
logger.info(f"KiCad CLI available: {kicad_cli.get('available', False)}")
|
|
|
|
overall_ready = status.get("overall_ready", False)
|
|
logger.info(f"Overall routing readiness: {overall_ready}")
|
|
|
|
return status
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error checking routing prerequisites: {e}")
|
|
return None
|
|
|
|
|
|
def test_kicad_ipc():
|
|
"""Test KiCad IPC API availability."""
|
|
logger.info("Testing KiCad IPC API...")
|
|
|
|
try:
|
|
status = check_kicad_availability()
|
|
logger.info(f"KiCad IPC status: {json.dumps(status, indent=2)}")
|
|
|
|
if status.get("available", False):
|
|
logger.info("✓ KiCad IPC API is available")
|
|
return True
|
|
else:
|
|
logger.warning("✗ KiCad IPC API is not available")
|
|
logger.warning(f"Reason: {status.get('message', 'Unknown')}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error testing KiCad IPC: {e}")
|
|
return False
|
|
|
|
|
|
def test_project_validation():
|
|
"""Test project validation with the thermal camera project."""
|
|
logger.info("Testing project validation...")
|
|
|
|
try:
|
|
from kicad_mcp.utils.file_utils import get_project_files
|
|
|
|
if not Path(PROJECT_PATH).exists():
|
|
logger.error(f"Test project not found: {PROJECT_PATH}")
|
|
return False
|
|
|
|
files = get_project_files(PROJECT_PATH)
|
|
logger.info(f"Project files found: {list(files.keys())}")
|
|
|
|
required_files = ["project", "pcb", "schematic"]
|
|
missing_files = [f for f in required_files if f not in files]
|
|
|
|
if missing_files:
|
|
logger.error(f"Missing required files: {missing_files}")
|
|
return False
|
|
else:
|
|
logger.info("✓ All required project files found")
|
|
return True
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error validating project: {e}")
|
|
return False
|
|
|
|
|
|
def test_enhanced_features():
|
|
"""Test enhanced MCP server features."""
|
|
logger.info("Testing enhanced features...")
|
|
|
|
results = {
|
|
"routing_prerequisites": test_routing_prerequisites(),
|
|
"kicad_ipc": test_kicad_ipc(),
|
|
"project_validation": test_project_validation()
|
|
}
|
|
|
|
return results
|
|
|
|
|
|
def main():
|
|
"""Main test function."""
|
|
logger.info("=== KiCad MCP Server Integration Test ===")
|
|
logger.info(f"Testing with project: {PROJECT_PATH}")
|
|
|
|
# Run tests
|
|
results = test_enhanced_features()
|
|
|
|
# Summary
|
|
logger.info("\n=== Test Summary ===")
|
|
for test_name, result in results.items():
|
|
status = "✓ PASS" if result else "✗ FAIL"
|
|
logger.info(f"{test_name}: {status}")
|
|
|
|
# Overall assessment
|
|
routing_ready = results["routing_prerequisites"] and results["routing_prerequisites"].get("overall_ready", False)
|
|
ipc_ready = results["kicad_ipc"]
|
|
project_valid = results["project_validation"]
|
|
|
|
logger.info(f"\nOverall Assessment:")
|
|
logger.info(f"- Project validation: {'✓' if project_valid else '✗'}")
|
|
logger.info(f"- KiCad IPC API: {'✓' if ipc_ready else '✗'}")
|
|
logger.info(f"- Routing capabilities: {'✓' if routing_ready else '✗'}")
|
|
|
|
if project_valid and ipc_ready:
|
|
logger.info("🎉 KiCad MCP server is ready for enhanced features!")
|
|
if not routing_ready:
|
|
logger.info("💡 To enable full routing automation, install FreeRouting:")
|
|
logger.info(" Download from: https://github.com/freerouting/freerouting/releases")
|
|
logger.info(" Place freerouting.jar in PATH or ~/freerouting.jar")
|
|
else:
|
|
logger.warning("⚠️ Some components need attention before full functionality")
|
|
|
|
return all([project_valid, ipc_ready])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = main()
|
|
sys.exit(0 if success else 1) |