Skip to content
16 changes: 12 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,15 @@ VisionTest is an MCP (Model Context Protocol) server enabling AI agents to inter

Kotlin/JVM server using stdio transport. Key files:
- `Main.kt` - Entry point, initializes managers and connects via stdio
- `ToolFactory.kt` - Registers all MCP tools (Android, iOS, and Automation)
- `ToolFactory.kt` - Thin coordinator that wires registrars and delegates tool registration
- `tools/ToolDsl.kt` - `ToolScope` DSL wrapping timeout/error handling + `CallToolRequest` extension helpers
- `tools/ToolRegistrar.kt` - Interface for modular tool registration
- `tools/ToolHelpers.kt` - Pure utility functions (`extractProperty`, `formatAppInfo`, etc.)
- `tools/AndroidDeviceToolRegistrar.kt` - 4 Android device tools
- `tools/AndroidAutomationToolRegistrar.kt` - 14 Android automation tools
- `tools/IOSDeviceToolRegistrar.kt` - 4 iOS device tools
- `tools/IOSAutomationToolRegistrar.kt` - 12 iOS automation tools + xcodebuild process management
- `discovery/ToolDiscovery.kt` - APK, Xcode project, xctestrun, and project root discovery
- `android/Android.kt` - ADB communication via Adam library
- `android/AutomationClient.kt` - HTTP client for Android Automation Server JSON-RPC
- `ios/IOSManager.kt` - iOS simulator operations via `xcrun simctl`
Expand Down Expand Up @@ -364,8 +372,8 @@ All Gradle tests are pure JVM (no device/emulator needed). iOS tests run on the
| `android/AndroidValidationTest.kt` | `isValidPackageName`, `validateForwardArgs`, `validateShellArgs`, `validateInstallArgs` |
| `android/AutomationClientTest.kt` | `sendRequest` POST/params/errors, `isServerRunning` health check (MockWebServer) |
| `config/AppConfigTest.kt` | Default config values and log level |
| `ToolFactoryHelpersTest.kt` | `extractProperty`, `extractPattern`, `formatAppInfo` |
| `ToolFactoryPathTest.kt` | `findProjectRoot` (settings.gradle discovery, depth limit, edge cases), `findAutomationServerApk` (env var, search roots, ordering) |
| `ToolFactoryHelpersTest.kt` | `ToolHelpers.extractProperty`, `extractPattern`, `formatAppInfo` |
| `ToolFactoryPathTest.kt` | `ToolDiscovery.findProjectRoot`, `findAutomationServerApk`, `resolveMainApkPath`, `findXctestrun`; `IOSAutomationToolRegistrar.buildXcodebuildCommand` |

### Automation Server (`automation-server/src/test/java/com/example/automationserver/`)

Expand All @@ -392,7 +400,7 @@ See `.claude/unit-testing-strategy.md` for the full testing roadmap (Plans 1-7).
- Device list caching reduces ADB overhead (validity: 1000ms default)
- Retry logic with exponential backoff in `ErrorHandler.retryOperation()`
- Custom exception hierarchy in `Exceptions.kt` with platform-specific error codes
- Tool timeout wrapper: `runWithTimeout()` in ToolFactory (default: 10s, 30s for UI hierarchy)
- Tool timeout wrapper: `ToolScope` DSL with `withTimeout` (default: 10s, 30s for UI hierarchy, 200s for iOS server startup)
- Automation Server uses Ktor/Netty for HTTP server with Gson serialization
- Template Method Pattern: `BaseUiAutomatorBridge` defines operations, subclasses provide `UiDevice`, `UiAutomation`, and display bounds
- Reflection-based hierarchy dumping via `UiDevice.getWindowRoots()` for Flutter app support
Expand Down
22 changes: 16 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,17 @@ visiontest/
├── app/ # MCP Server (Kotlin/JVM)
│ └── src/main/kotlin/com/example/visiontest/
│ ├── Main.kt # Entry point
│ ├── ToolFactory.kt # MCP tool registration
│ ├── ToolFactory.kt # Thin coordinator wiring registrars
│ ├── tools/
│ │ ├── ToolDsl.kt # ToolScope DSL + CallToolRequest helpers
│ │ ├── ToolRegistrar.kt # Interface for modular registration
│ │ ├── ToolHelpers.kt # Pure utility functions
│ │ ├── AndroidDeviceToolRegistrar.kt
│ │ ├── AndroidAutomationToolRegistrar.kt
│ │ ├── IOSDeviceToolRegistrar.kt
│ │ └── IOSAutomationToolRegistrar.kt
│ ├── discovery/
│ │ └── ToolDiscovery.kt # APK, Xcode project, xctestrun discovery
│ ├── android/
│ │ ├── Android.kt # ADB communication (Adam library)
│ │ └── AutomationClient.kt # JSON-RPC client (Android)
Expand Down Expand Up @@ -247,8 +257,8 @@ All Gradle tests are pure JVM unit tests (no device or emulator required). iOS t
| `app/` | `AndroidValidationTest.kt` | Package name validation, ADB argument validation |
| `app/` | `AutomationClientTest.kt` | `sendRequest` POST/params/errors, `isServerRunning` health check |
| `app/` | `AppConfigTest.kt` | Default configuration values |
| `app/` | `ToolFactoryHelpersTest.kt` | Property extraction, pattern matching, app info formatting |
| `app/` | `ToolFactoryPathTest.kt` | `findProjectRoot`, `findAutomationServerApk`, `findXctestrun` |
| `app/` | `ToolFactoryHelpersTest.kt` | `ToolHelpers.extractProperty`, `extractPattern`, `formatAppInfo` |
| `app/` | `ToolFactoryPathTest.kt` | `ToolDiscovery.findProjectRoot`, `findAutomationServerApk`, `resolveMainApkPath`, `findXctestrun`; `IOSAutomationToolRegistrar.buildXcodebuildCommand` |
| `automation-server/` | `JsonRpcModelsTest.kt` | JSON-RPC error factory methods, request/response defaults |
| `automation-server/` | `UiAutomatorModelsTest.kt` | Data classes, default values, enum entries |
| `automation-server/` | `ServerConfigPortTest.kt` | Port validation boundaries |
Expand Down Expand Up @@ -300,12 +310,12 @@ curl -X POST http://localhost:9009/jsonrpc -H 'Content-Type: application/json' \
1. Add method to `BaseUiAutomatorBridge.kt` (uses `getUiDevice()`, `getUiAutomation()`, `getDisplayRect()`)
2. Register in `JsonRpcServerInstrumented.kt` `executeMethod()`
3. Add client method to `AutomationClient.kt`
4. Create MCP tool in `ToolFactory.kt`
4. Add the MCP tool to the appropriate registrar in `tools/` (e.g., `AndroidAutomationToolRegistrar.kt`)

### Adding New MCP Tools

1. Create method in `ToolFactory.kt`
2. Register in `registerAllTools()`
1. Add the tool to the appropriate registrar in `tools/` using the `ToolScope` DSL
2. The tool is automatically registered via `ToolFactory.registerAllTools()`

## Error Codes

Expand Down
Loading
Loading