From 78a20380f04f7ae1454ad48cf560fbb4f6b32eb8 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 3 Feb 2026 18:13:43 +0000 Subject: [PATCH 01/34] Add spec for mauidevtools --- docs/design/maui-devtools-spec.md | 1918 +++++++++++++++++++++++++++++ 1 file changed, 1918 insertions(+) create mode 100644 docs/design/maui-devtools-spec.md diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md new file mode 100644 index 000000000000..a17a231b87f8 --- /dev/null +++ b/docs/design/maui-devtools-spec.md @@ -0,0 +1,1918 @@ +# MAUI Dev Tools Client — Product Specification + +**Version**: 1.0-draft +**Status**: Proposal +**Last Updated**: 2026-02-03 + +--- + +## Table of Contents + +1. [Executive Summary](#1-executive-summary) +2. [Problem Statement](#2-problem-statement) +3. [Goals / Non-Goals](#3-goals--non-goals) +4. [Personas & User Journeys](#4-personas--user-journeys) +5. [Functional Requirements](#5-functional-requirements) +6. [Non-Functional Requirements](#6-non-functional-requirements) +7. [Architecture](#7-architecture) +8. [Public API Surface](#8-public-api-surface) +9. [User Experience](#9-user-experience) +10. [Telemetry & Diagnostics](#10-telemetry--diagnostics) +11. [Security Model](#11-security-model) +12. [Extensibility](#12-extensibility) +13. [Testing Strategy](#13-testing-strategy) +14. [Rollout Plan](#14-rollout-plan) +15. [Open Questions & Risks](#15-open-questions--risks) +16. [Appendix](#16-appendix) + +--- + +## 1. Executive Summary + +### What It Is + +**MAUI Dev Tools Client** is a unified local tool and service API that detects, installs, repairs, and automates all native dependencies required for .NET MAUI development. It exposes device and simulator helpers that human users, IDEs, and AI agents can invoke safely and consistently. + +### Why It Exists + +Setting up a .NET MAUI development environment is one of the most significant friction points for new and experienced developers alike. The current experience requires: + +- Manual installation of Android SDK, build-tools, emulators, and system images +- Manual installation and configuration of Xcode, simulators, and runtimes on macOS +- Troubleshooting cryptic errors when components are missing or misconfigured +- No unified way for IDEs or AI agents to query environment status or automate fixes + +This tool eliminates that friction by providing a single, authoritative source for environment health and automated remediation. + +### Who It's For + +| Persona | Primary Value | +|---------|---------------| +| MAUI Developer (Windows) | One-command setup for Android development | +| MAUI Developer (macOS) | Unified setup for Android + iOS/Mac Catalyst | +| CI Engineer | Headless, scriptable environment provisioning | +| AI Agent | Structured APIs for querying and fixing environment issues | +| IDE (VS/VS Code) | Fast, reliable environment checks with actionable fixes | + +--- + +## 2. Problem Statement + +### Current Pain Points + +1. **Fragmented Tooling**: Developers must use `sdkmanager`, `avdmanager`, `xcrun`, `simctl`, and `xcode-select` separately—each with different UX patterns, output formats, and error handling. + +2. **Silent Failures**: Missing or misconfigured dependencies often surface as cryptic build errors deep in MSBuild logs, not as clear diagnostic messages. + +3. **No Unified "Doctor"**: Unlike Flutter's `flutter doctor`, there's no single command that checks all MAUI prerequisites and offers fixes. + +4. **IDE Integration Gap**: Visual Studio and VS Code must independently implement detection and installation logic, leading to inconsistent experiences. + +5. **AI Agent Blindspot**: AI coding assistants cannot reliably query environment state or propose fixes because there's no structured API. + +6. **CI Complexity**: Setting up MAUI builds in CI requires extensive scripting and platform-specific knowledge. + +### Impact + +- High abandonment rate for new MAUI developers during setup +- Increased support burden for environment-related issues +- Duplicated effort across IDE teams +- AI agents cannot effectively assist with environment problems + +--- + +## 3. Goals / Non-Goals + +### Goals + +| ID | Goal | Success Metric | +|----|------|----------------| +| G1 | Reduce MAUI setup time to under 10 minutes | Time-to-first-build < 10 min for 90% of users | +| G2 | Provide a single "doctor" command that identifies all issues | 100% coverage of common setup issues | +| G3 | Enable one-click/one-command fixes for detected issues | >80% of issues auto-fixable | +| G4 | Expose structured APIs for IDE and AI agent consumption | JSON-RPC API with stable schema | +| G5 | Support headless operation for CI environments | All commands runnable non-interactively | +| G6 | Unify Android and Apple device/simulator management | Single CLI surface for both platforms | + +### Non-Goals + +| ID | Non-Goal | Rationale | +|----|----------|-----------| +| NG1 | Replace `dotnet` CLI | This tool complements, not replaces, the .NET CLI | +| NG2 | Full Apple signing/provisioning management | Complex domain; integrate with existing tools instead | +| NG3 | Linux host support (MVP) | MAUI mobile development requires Windows or macOS | +| NG4 | Physical iOS device provisioning | Requires Apple Developer account; out of scope for MVP | +| NG5 | Manage Visual Studio installation | VS has its own installer; we detect, not manage | + +--- + +## 4. Personas & User Journeys + +### 4.1 MAUI Developer on Windows + +**Profile**: Sarah, a .NET developer building a cross-platform app. She has Visual Studio installed but has never done Android development. + +**Journey**: +1. Sarah installs the .NET MAUI workload via `dotnet workload install maui` +2. She opens her project in VS Code and sees a notification: "MAUI environment issues detected" +3. She clicks "View Details" and sees a structured list: + - ❌ Android SDK not found + - ❌ Android emulator not installed + - ❌ No Android system images available +4. She clicks "Fix All" and watches a progress panel: + - Installing Android SDK... ✓ + - Installing build-tools 34.0.0... ✓ + - Installing emulator... ✓ + - Installing system-images;android-34;google_apis;x86_64... ✓ + - Creating default AVD "Pixel_5_API_34"... ✓ +5. She presses F5 and her app launches in the emulator + +**Key Requirements**: +- Clear, actionable error messages +- One-click installation of all dependencies +- Progress indication for long-running operations +- No prior Android knowledge required + +### 4.2 MAUI Developer on macOS + +**Profile**: Marcus, building an iOS app. He has Xcode installed but outdated simulators. + +**Journey**: +1. Marcus runs `maui doctor` in terminal +2. Output shows: + ``` + ✓ .NET SDK 9.0.100 + ✓ MAUI workload 9.0.0 + ✓ Xcode 16.0 (/Applications/Xcode.app) + ✓ Android SDK (/Users/marcus/Library/Android/sdk) + ⚠ iOS 18.0 runtime not installed (iOS 17.4 available) + ⚠ No iPhone 16 simulator available + ``` +3. He runs `maui doctor --fix` +4. Tool prompts: "Install iOS 18.0 runtime? (requires 8GB download) [Y/n]" +5. After confirmation, runtime installs and simulator is created + +**Key Requirements**: +- Detection of Xcode and simulator state +- Clear prompts for large downloads +- Respect for user's existing configuration + +### 4.3 CI Engineer + +**Profile**: DevOps engineer configuring GitHub Actions for a MAUI project. + +**Journey**: +1. Engineer adds step to workflow: + ```yaml + - name: Setup MAUI Environment + run: | + dotnet tool install -g Microsoft.Maui.DevTools + maui doctor --fix --non-interactive --json > setup-report.json + ``` +2. Tool runs silently, installs missing components, outputs JSON report +3. If any unfixable issues exist, tool exits with non-zero code +4. Subsequent build step succeeds + +**Key Requirements**: +- `--non-interactive` flag for unattended operation +- Deterministic exit codes +- JSON output for pipeline integration +- Idempotent execution (safe to run multiple times) + +### 4.4 AI Agent Invoked from IDE + +**Profile**: Copilot agent assisting a developer with a build error. + +**Journey**: +1. User asks: "My Android build is failing with 'SDK not found'" +2. Agent invokes: `maui doctor --json --target android` +3. Agent receives structured response: + ```json + { + "status": "unhealthy", + "issues": [ + { + "id": "ANDROID_SDK_MISSING", + "severity": "error", + "message": "Android SDK not found", + "fixable": true, + "fix_command": "maui android sdk install --recommended" + } + ] + } + ``` +4. Agent explains the issue and asks: "Would you like me to install the Android SDK?" +5. User confirms; agent invokes fix command with permission gate +6. Agent verifies fix by re-running doctor + +**Key Requirements**: +- Structured JSON output with stable schema +- Fix commands included in diagnostic output +- Permission gates for destructive operations +- Correlation IDs for tracing + +--- + +## 5. Functional Requirements + +### 5.1 Doctor Capability + +| ID | Requirement | Priority | +|----|-------------|----------| +| FR-D1 | Detect .NET SDK version and MAUI workload installation status | P0 | +| FR-D2 | Detect Android SDK location and installed components | P0 | +| FR-D3 | Detect Android build-tools, platform-tools, and emulator presence | P0 | +| FR-D4 | Detect Xcode installation, version, and selected developer directory | P0 | +| FR-D5 | Detect installed iOS/macOS runtimes and simulators | P0 | +| FR-D6 | Detect Windows SDK installation (on Windows) | P1 | +| FR-D7 | Produce human-readable output with color-coded status | P0 | +| FR-D8 | Produce machine-readable JSON output with stable schema | P0 | +| FR-D9 | Provide `--fix` flag to automatically remediate fixable issues | P0 | +| FR-D10 | Prompt for confirmation before downloads >100MB | P0 | +| FR-D11 | Support `--target` filter (android, ios, windows, maccatalyst) | P1 | + +### 5.2 Android Management + +| ID | Requirement | Priority | +|----|-------------|----------| +| FR-A1 | List connected devices and running emulators | P0 | +| FR-A2 | List installed SDK packages with version info | P0 | +| FR-A3 | Install SDK packages by name or alias (e.g., `--recommended`) | P0 | +| FR-A4 | List available AVDs | P0 | +| FR-A5 | Create AVD with specified device profile and system image | P0 | +| FR-A6 | Start AVD and wait for boot completion | P0 | +| FR-A7 | Stop running emulator | P1 | +| FR-A8 | Cold boot emulator (wipe runtime state) | P1 | +| FR-A9 | Wipe AVD data | P2 | +| FR-A10 | Stream logcat output with filtering | P1 | +| FR-A11 | Install APK to device/emulator | P1 | +| FR-A12 | Uninstall package from device/emulator | P2 | +| FR-A13 | Capture screenshot from device/emulator | P0 | + +### 5.3 Apple (Xcode) Management + +| ID | Requirement | Priority | +|----|-------------|----------| +| FR-X1 | List available simulators with runtime/device type info | P0 | +| FR-X2 | Filter simulators by runtime, device type, or state | P0 | +| FR-X3 | Boot simulator by UDID or name | P0 | +| FR-X4 | Shutdown simulator | P0 | +| FR-X5 | Create simulator with specified runtime and device type | P0 | +| FR-X6 | Delete simulator | P2 | +| FR-X7 | List available runtimes | P0 | +| FR-X8 | Install runtime (guide user if manual steps needed) | P1 | +| FR-X9 | Capture screenshot from simulator | P0 | +| FR-X10 | Stream simulator/device logs | P1 | +| FR-X11 | Validate basic signing prerequisites (team ID, certificate presence) | P2 | +| FR-X12 | Open Simulator.app with specific device | P1 | + +### 5.4 Cross-Platform Screenshot + +| ID | Requirement | Priority | +|----|-------------|----------| +| FR-S1 | Unified `screenshot` command across all platforms | P0 | +| FR-S2 | Auto-detect target device if only one is available | P0 | +| FR-S3 | Support `--device` flag for explicit device selection | P0 | +| FR-S4 | Support `--output` flag for file path (default: timestamped file) | P0 | +| FR-S5 | Support `--wait` flag to delay capture | P1 | +| FR-S6 | Support `--format` flag (png, jpg) | P2 | +| FR-S7 | Return file path in JSON output | P0 | + +### 5.5 Device Listing (Unified) + +| ID | Requirement | Priority | +|----|-------------|----------| +| FR-DL1 | `device list` shows all available devices across platforms | P0 | +| FR-DL2 | Include device type (physical/emulator/simulator), platform, state | P0 | +| FR-DL3 | Include unique identifier (serial/UDID) for targeting | P0 | +| FR-DL4 | Support `--platform` filter | P1 | +| FR-DL5 | Support `--json` output | P0 | + +--- + +## 6. Non-Functional Requirements + +### 6.1 Reliability + +| ID | Requirement | +|----|-------------| +| NFR-R1 | All operations must be idempotent (safe to retry) | +| NFR-R2 | Network failures must produce clear error messages with retry guidance | +| NFR-R3 | Partial failures during multi-step operations must leave system in consistent state | +| NFR-R4 | Tool must gracefully handle missing permissions | + +### 6.2 Observability + +| ID | Requirement | +|----|-------------| +| NFR-O1 | All operations must support `--verbose` flag for detailed logging | +| NFR-O2 | JSON output must include `correlation_id` for tracing | +| NFR-O3 | Long-running operations must emit progress events | +| NFR-O4 | `diagnostic-bundle` command must collect all relevant logs and state | + +### 6.3 Performance + +| ID | Requirement | +|----|-------------| +| NFR-P1 | `doctor` command must complete in <5s when no network calls needed | +| NFR-P2 | Device list must complete in <2s | +| NFR-P3 | Daemon mode must respond to health checks in <100ms | +| NFR-P4 | Downloaded artifacts must be cached locally | + +### 6.4 Security + +| ID | Requirement | +|----|-------------| +| NFR-S1 | Downloads must verify checksums before installation | +| NFR-S2 | Tool must never store or transmit credentials | +| NFR-S3 | Elevation must be requested explicitly with clear justification | +| NFR-S4 | AI agent calls must respect permission gates (see Security Model) | + +### 6.5 Privacy + +| ID | Requirement | +|----|-------------| +| NFR-PR1 | No PII in logs or telemetry | +| NFR-PR2 | File paths must be redacted in telemetry (keep structure only) | +| NFR-PR3 | Telemetry must be opt-in with clear disclosure | + +### 6.6 Accessibility + +| ID | Requirement | +|----|-------------| +| NFR-A1 | CLI output must work with screen readers (avoid relying solely on color) | +| NFR-A2 | All status indicators must have text equivalents | +| NFR-A3 | IDE integration must follow platform accessibility guidelines | + +--- + +## 7. Architecture + +### 7.1 High-Level Components + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ Consumers │ +├─────────────┬─────────────┬─────────────┬─────────────┬─────────────────┤ +│ Terminal │ VS Code │ Visual │ AI Agent │ CI/CD │ +│ (Human) │ Extension │ Studio │ (Copilot) │ Pipeline │ +└──────┬──────┴──────┬──────┴──────┬──────┴──────┬──────┴────────┬────────┘ + │ │ │ │ │ + │ CLI │ JSON-RPC │ JSON-RPC │ JSON-RPC │ CLI + │ │ (stdio) │ (named pipe)│ (stdio) │ + ▼ ▼ ▼ ▼ ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ MAUI Dev Tools Client │ +├─────────────────────────────────────────────────────────────────────────┤ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ CLI Layer │ │ JSON-RPC │ │ Daemon │ │ +│ │ (Parsing) │ │ Server │ │ (Optional) │ │ +│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ Core Services │ │ +│ ├──────────────┬──────────────┬──────────────┬─────────────────┤ │ +│ │ Doctor │ Device │ Artifact │ Logging │ │ +│ │ Service │ Manager │ Manager │ Service │ │ +│ └──────┬───────┴──────┬───────┴──────┬───────┴────────┬────────┘ │ +│ │ │ │ │ │ +│ ▼ ▼ ▼ ▼ │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ Platform Providers │ │ +│ ├────────────────┬────────────────┬────────────────────────────┤ │ +│ │ Android │ Apple │ Windows │ │ +│ │ Provider │ Provider │ Provider │ │ +│ └────────────────┴────────────────┴────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ Native Toolchains │ +├───────────────────┬───────────────────┬─────────────────────────────────┤ +│ Android SDK │ Xcode/xcrun │ Windows SDK │ +│ (sdkmanager, │ (simctl, │ (vsdevcmd) │ +│ adb, avdmanager)│ xcode-select) │ │ +└───────────────────┴───────────────────┴─────────────────────────────────┘ +``` + +### 7.2 Component Descriptions + +#### CLI Layer +- Parses command-line arguments using `System.CommandLine` +- Maps commands to core service calls +- Formats output for human consumption (colors, tables, progress bars) +- Entry point: `maui` command + +#### JSON-RPC Server +- Implements JSON-RPC 2.0 over multiple transports: + - **stdio**: For AI agents and simple integrations + - **Named pipes**: For high-performance IDE integration (Windows) + - **Unix domain sockets**: For high-performance IDE integration (macOS) +- Stateless request/response model +- Streaming support for logs and progress + +#### Daemon (Optional) +- Long-running background process for faster IDE interactions +- Maintains cached state (device list, SDK components) +- Auto-starts on first IDE request; auto-terminates after idle timeout +- Not required for CLI usage + +#### Core Services + +| Service | Responsibility | +|---------|----------------| +| Doctor Service | Aggregates health checks from all providers; produces unified report | +| Device Manager | Unified device/emulator/simulator listing; dispatches to providers | +| Artifact Manager | Manages downloads, caching, and verification | +| Logging Service | Structured logging with correlation IDs; diagnostic bundle export | + +#### Platform Providers + +| Provider | Responsibility | +|----------|----------------| +| Android Provider | Wraps `sdkmanager`, `avdmanager`, `adb`, `emulator` | +| Apple Provider | Wraps `xcrun simctl`, `xcode-select`, `xcodebuild` | +| Windows Provider | Wraps Windows SDK detection and VS build tools | + +### 7.3 Data Flow: Doctor Command + +``` +User: maui doctor --json + │ + ▼ + ┌─────────┐ + │ CLI │ + └────┬────┘ + │ Parse args, determine output format + ▼ + ┌─────────────┐ + │ Doctor │ + │ Service │ + └──────┬──────┘ + │ Invoke each provider's health check + ├────────────────────────┬────────────────────────┐ + ▼ ▼ ▼ + ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ + │ Android │ │ Apple │ │ Windows │ + │ Provider │ │ Provider │ │ Provider │ + └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ + │ │ │ + ▼ ▼ ▼ + ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ + │ sdkmanager │ │ simctl │ │ VS Where │ + │ adb │ │xcode-select │ │ │ + └─────────────┘ └─────────────┘ └─────────────┘ + │ │ │ + └────────────────────────┴────────────────────────┘ + │ + ▼ Aggregate results + ┌─────────────┐ + │ Doctor │ + │ Service │ + └──────┬──────┘ + │ Format as JSON + ▼ + ┌─────────────┐ + │ stdout │ + └─────────────┘ +``` + +### 7.4 IDE Extension Integration + +#### VS Code Extension + +``` +┌─────────────────────────────────────────────────────────────┐ +│ VS Code │ +├─────────────────────────────────────────────────────────────┤ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ MAUI Extension │ │ +│ ├──────────────────────────────────────────────────────┤ │ +│ │ • Environment Status Bar Item │ │ +│ │ • "MAUI: Setup Environment" command │ │ +│ │ • Problems panel integration │ │ +│ │ • Quick Fix code actions │ │ +│ └─────────────────────┬────────────────────────────────┘ │ +│ │ │ +│ │ JSON-RPC (stdio) │ +│ ▼ │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ MAUI Dev Tools Client │ │ +│ │ (spawned as child process) │ │ +│ └──────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +**Extension Responsibilities**: +1. Spawn `maui` process with `--rpc` flag on activation +2. Send `doctor.status` request on workspace open +3. Display issues in Problems panel +4. Register "MAUI: Setup Environment" command +5. Show progress notifications during fixes + +#### Visual Studio Extension + +- Uses named pipes for faster communication +- Integrates with Visual Studio's environment detection UI +- Surfaces issues in Error List window +- Provides menu items in Tools > MAUI submenu + +### 7.5 Daemon Mode vs On-Demand + +| Aspect | On-Demand (CLI) | Daemon Mode | +|--------|-----------------|-------------| +| Startup | New process per command | Single long-running process | +| Latency | ~200ms cold start | <50ms response | +| Use Case | CI, terminal, simple scripts | IDE integration | +| State | Stateless | Cached device list, SDK state | +| Resource Usage | None when idle | ~20MB memory when idle | + +**Daemon Lifecycle**: +1. IDE sends request to well-known socket/pipe +2. If no daemon running, extension spawns `maui daemon --background` +3. Daemon responds to requests +4. After 5 minutes idle, daemon self-terminates +5. Next request restarts daemon + +--- + +## 8. Public API Surface + +### 8.1 CLI Commands + +#### Command Hierarchy + +``` +maui +├── doctor # Check environment health +│ ├── --fix # Auto-fix detected issues +│ ├── --target # Filter: android, ios, windows, maccatalyst +│ ├── --json # Output as JSON +│ └── --non-interactive # No prompts (for CI) +│ +├── device +│ ├── list # List all devices +│ │ ├── --platform # Filter by platform +│ │ └── --json # Output as JSON +│ └── screenshot # Capture screenshot +│ ├── --device # Target device +│ ├── --output # Output file +│ ├── --wait # Delay before capture +│ └── --format # png, jpg +│ +├── android +│ ├── sdk +│ │ ├── list # List installed packages +│ │ ├── list-available # List available packages +│ │ └── install # Install package +│ ├── avd +│ │ ├── list # List AVDs +│ │ ├── create # Create AVD +│ │ │ ├── --name # AVD name +│ │ │ ├── --device # Device profile +│ │ │ ├── --image # System image +│ │ │ └── --force # Overwrite existing +│ │ ├── start # Start AVD +│ │ │ ├── --name # AVD name (or --avd) +│ │ │ ├── --cold-boot # Fresh boot +│ │ │ └── --wait # Wait for boot +│ │ └── stop # Stop emulator +│ │ └── --device # Emulator serial +│ ├── logcat # Stream logs +│ │ ├── --device # Target device +│ │ └── --filter # Tag filter +│ └── install # Install APK +│ ├── --device # Target device +│ └── # APK file +│ +├── apple +│ ├── simulator +│ │ ├── list # List simulators +│ │ │ ├── --runtime # Filter by runtime +│ │ │ ├── --device-type # Filter by device type +│ │ │ └── --state # Filter: booted, shutdown +│ │ ├── create # Create simulator +│ │ │ ├── --name # Simulator name +│ │ │ ├── --runtime # Runtime identifier +│ │ │ └── --device-type # Device type identifier +│ │ ├── boot # Boot simulator +│ │ │ └── --udid # Simulator UDID (or name) +│ │ ├── shutdown # Shutdown simulator +│ │ │ └── --udid # Simulator UDID +│ │ └── delete # Delete simulator +│ │ └── --udid # Simulator UDID +│ ├── runtime +│ │ ├── list # List runtimes +│ │ └── install # Install runtime (guidance) +│ │ └── --version # Runtime version +│ └── logs # Stream device logs +│ └── --udid # Simulator UDID +│ +├── logs +│ └── stream # Stream logs from device +│ ├── --device # Device identifier +│ └── --filter # Filter expression +│ +├── diagnostic-bundle # Export diagnostic info +│ └── --output # Output zip file +│ +├── daemon # Daemon management +│ ├── start # Start daemon +│ ├── stop # Stop daemon +│ └── status # Check daemon status +│ +└── --version # Show version +``` + +#### Command Table + +| Command | Description | Inputs | Output | Exit Codes | +|---------|-------------|--------|--------|------------| +| `doctor` | Check environment health | `--fix`, `--target`, `--json` | Status report | 0=healthy, 1=issues, 2=error | +| `device list` | List available devices | `--platform`, `--json` | Device list | 0=success, 2=error | +| `device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 1=no device, 2=error | +| `android sdk list` | List SDK packages | `--json` | Package list | 0=success, 2=error | +| `android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 1=not found, 2=error | +| `android avd create` | Create emulator | `--name`, `--device`, `--image` | AVD name | 0=success, 1=exists, 2=error | +| `android avd start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 1=not found, 2=error | +| `apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | +| `apple simulator boot` | Boot simulator | `--udid` or name | UDID | 0=success, 1=not found, 2=error | +| `apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | + +### 8.2 JSON-RPC API + +**Transport**: JSON-RPC 2.0 over stdio (primary) or named pipes/Unix sockets (daemon mode) + +**Why JSON-RPC**: +- Language-agnostic (works with any IDE/agent) +- Simple request/response model +- Well-defined error handling +- Supports notifications for streaming (logs, progress) + +#### Method Reference + +##### doctor.status + +Check environment health. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "doctor.status", + "params": { + "targets": ["android", "ios"] + } +} +``` + +**Response**: +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "correlation_id": "abc-123", + "status": "unhealthy", + "checks": [ + { + "category": "dotnet", + "name": ".NET SDK", + "status": "ok", + "details": { "version": "9.0.100", "path": "/usr/local/share/dotnet" } + }, + { + "category": "dotnet", + "name": "MAUI Workload", + "status": "ok", + "details": { "version": "9.0.0" } + }, + { + "category": "android", + "name": "Android SDK", + "status": "error", + "message": "Android SDK not found", + "issue": { + "id": "ANDROID_SDK_MISSING", + "severity": "error", + "fixable": true, + "fix": { + "method": "doctor.fix", + "params": { "issue_id": "ANDROID_SDK_MISSING" } + } + } + } + ], + "summary": { + "total": 8, + "ok": 5, + "warning": 1, + "error": 2 + } + } +} +``` + +##### doctor.fix + +Fix a specific issue or all fixable issues. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 2, + "method": "doctor.fix", + "params": { + "issue_id": "ANDROID_SDK_MISSING", + "confirm": true + } +} +``` + +**Response** (streaming progress via notifications): +```json +{ + "jsonrpc": "2.0", + "method": "progress", + "params": { + "correlation_id": "abc-123", + "operation": "android.sdk.install", + "status": "running", + "message": "Downloading Android SDK...", + "percent": 45 + } +} +``` + +**Final Response**: +```json +{ + "jsonrpc": "2.0", + "id": 2, + "result": { + "correlation_id": "abc-123", + "status": "success", + "fixed": ["ANDROID_SDK_MISSING"] + } +} +``` + +##### device.list + +List all available devices. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 3, + "method": "device.list", + "params": { + "platform": "android" + } +} +``` + +**Response**: +```json +{ + "jsonrpc": "2.0", + "id": 3, + "result": { + "devices": [ + { + "id": "emulator-5554", + "name": "Pixel_5_API_34", + "platform": "android", + "type": "emulator", + "state": "online", + "os_version": "14", + "details": { + "avd_name": "Pixel_5_API_34", + "api_level": 34 + } + }, + { + "id": "R58M32XXXXX", + "name": "Galaxy S21", + "platform": "android", + "type": "physical", + "state": "online", + "os_version": "13" + } + ] + } +} +``` + +##### device.screenshot + +Capture screenshot from device. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 4, + "method": "device.screenshot", + "params": { + "device_id": "emulator-5554", + "output_path": "/tmp/screenshot.png", + "wait_ms": 500 + } +} +``` + +**Response**: +```json +{ + "jsonrpc": "2.0", + "id": 4, + "result": { + "path": "/tmp/screenshot.png", + "width": 1080, + "height": 2400, + "format": "png" + } +} +``` + +##### android.sdk.list + +List installed Android SDK packages. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 5, + "method": "android.sdk.list", + "params": {} +} +``` + +**Response**: +```json +{ + "jsonrpc": "2.0", + "id": 5, + "result": { + "sdk_path": "/Users/dev/Library/Android/sdk", + "packages": [ + { + "path": "build-tools;34.0.0", + "version": "34.0.0", + "description": "Android SDK Build-Tools 34", + "location": "build-tools/34.0.0" + }, + { + "path": "platforms;android-34", + "version": "2", + "description": "Android SDK Platform 34", + "location": "platforms/android-34" + } + ] + } +} +``` + +##### android.sdk.install + +Install Android SDK package. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 6, + "method": "android.sdk.install", + "params": { + "packages": ["platforms;android-34", "build-tools;34.0.0"], + "accept_licenses": true + } +} +``` + +##### android.avd.create + +Create Android Virtual Device. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 7, + "method": "android.avd.create", + "params": { + "name": "Pixel_5_API_34", + "device": "pixel_5", + "system_image": "system-images;android-34;google_apis;x86_64", + "force": false + } +} +``` + +##### android.avd.start + +Start Android emulator. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 8, + "method": "android.avd.start", + "params": { + "name": "Pixel_5_API_34", + "wait_for_boot": true, + "cold_boot": false, + "timeout_seconds": 120 + } +} +``` + +**Response**: +```json +{ + "jsonrpc": "2.0", + "id": 8, + "result": { + "device_id": "emulator-5554", + "state": "online", + "boot_time_ms": 45000 + } +} +``` + +##### apple.simulator.list + +List iOS simulators. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 9, + "method": "apple.simulator.list", + "params": { + "runtime": "iOS 18.0", + "device_type": "iPhone", + "state": "booted" + } +} +``` + +**Response**: +```json +{ + "jsonrpc": "2.0", + "id": 9, + "result": { + "simulators": [ + { + "udid": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890", + "name": "iPhone 16 Pro", + "state": "booted", + "runtime": { + "identifier": "com.apple.CoreSimulator.SimRuntime.iOS-18-0", + "name": "iOS 18.0", + "version": "18.0" + }, + "device_type": { + "identifier": "com.apple.CoreSimulator.SimDeviceType.iPhone-16-Pro", + "name": "iPhone 16 Pro" + } + } + ] + } +} +``` + +##### apple.simulator.boot + +Boot iOS simulator. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 10, + "method": "apple.simulator.boot", + "params": { + "udid": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890" + } +} +``` + +##### apple.simulator.create + +Create iOS simulator. + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 11, + "method": "apple.simulator.create", + "params": { + "name": "Test iPhone 16", + "device_type": "com.apple.CoreSimulator.SimDeviceType.iPhone-16-Pro", + "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-18-0" + } +} +``` + +##### logs.stream + +Stream logs from device (uses JSON-RPC notifications). + +**Request**: +```json +{ + "jsonrpc": "2.0", + "id": 12, + "method": "logs.stream", + "params": { + "device_id": "emulator-5554", + "filter": "Microsoft.Maui" + } +} +``` + +**Notifications** (streamed): +```json +{ + "jsonrpc": "2.0", + "method": "logs.entry", + "params": { + "stream_id": "log-123", + "timestamp": "2026-02-03T17:45:00.123Z", + "level": "info", + "tag": "Microsoft.Maui.Controls", + "message": "Application started" + } +} +``` + +#### State Machine for Long-Running Operations + +``` + ┌─────────┐ + │ Queued │ + └────┬────┘ + │ start + ▼ + ┌────────────────────────────────────────┐ + │ Running │ + │ • Emits progress notifications │ + │ • Can be canceled │ + └───────┬─────────────┬─────────────┬────┘ + │ │ │ + success failure cancel + │ │ │ + ▼ ▼ ▼ + ┌───────────┐ ┌───────────┐ ┌───────────┐ + │ Succeeded │ │ Failed │ │ Canceled │ + └───────────┘ └───────────┘ └───────────┘ +``` + +**Progress Notification Schema**: +```json +{ + "jsonrpc": "2.0", + "method": "progress", + "params": { + "correlation_id": "string", + "operation_id": "string", + "status": "queued | running | succeeded | failed | canceled", + "message": "string", + "percent": 0-100, + "bytes_downloaded": 123456, + "bytes_total": 1000000, + "eta_seconds": 30 + } +} +``` + +### 8.3 Capabilities Model + +| Command | Windows | macOS | Requires Elevation | +|---------|---------|-------|-------------------| +| `doctor` | ✓ | ✓ | No | +| `doctor --fix` | ✓ | ✓ | Sometimes* | +| `device list` | ✓ | ✓ | No | +| `device screenshot` | ✓ | ✓ | No | +| `android sdk list` | ✓ | ✓ | No | +| `android sdk install` | ✓ | ✓ | No | +| `android avd create` | ✓ | ✓ | No | +| `android avd start` | ✓ | ✓ | No | +| `android logcat` | ✓ | ✓ | No | +| `apple simulator list` | — | ✓ | No | +| `apple simulator boot` | — | ✓ | No | +| `apple simulator create` | — | ✓ | No | +| `apple runtime list` | — | ✓ | No | +| `apple runtime install` | — | ✓ | Yes (admin) | +| `logs stream` | ✓ | ✓ | No | + +*Elevation required for: installing Android SDK to system locations, installing Xcode runtimes + +--- + +## 9. User Experience + +### 9.1 IDE UI Flows + +#### VS Code: Environment Status + +**Status Bar Item** (always visible): +``` +$(check-circle) MAUI Ready ← Green when healthy +$(warning) MAUI: 2 issues ← Yellow with issue count +$(error) MAUI: Setup Required ← Red when critical +``` + +**Click Action**: Opens "MAUI Environment" panel + +#### VS Code: Environment Panel + +``` +┌────────────────────────────────────────────────────────────┐ +│ MAUI ENVIRONMENT [Refresh] │ +├────────────────────────────────────────────────────────────┤ +│ │ +│ .NET SDK │ +│ ├── ✓ .NET SDK 9.0.100 │ +│ └── ✓ MAUI Workload 9.0.0 │ +│ │ +│ Android │ +│ ├── ✓ Android SDK (/Users/dev/Android/sdk) │ +│ ├── ✓ Build Tools 34.0.0 │ +│ ├── ⚠ Emulator not running [Start] │ +│ └── ✓ AVD: Pixel_5_API_34 │ +│ │ +│ iOS / macOS (Xcode 16.0) │ +│ ├── ✓ iOS 18.0 Runtime │ +│ ├── ✓ iPhone 16 Pro Simulator │ +│ └── ⚠ macOS 15.0 Runtime missing [Install] │ +│ │ +│ ─────────────────────────────────────────────────────────│ +│ [Fix All Issues] │ +└────────────────────────────────────────────────────────────┘ +``` + +**States**: +- ✓ Green checkmark: Component healthy +- ⚠ Yellow warning: Non-critical issue, fixable +- ✖ Red X: Critical issue, blocks development +- [Action]: Inline fix button + +#### VS Code: Fix Progress + +``` +┌────────────────────────────────────────────────────────────┐ +│ Setting up MAUI Environment │ +├────────────────────────────────────────────────────────────┤ +│ │ +│ ✓ Installing Android SDK │ +│ ✓ Installing build-tools;34.0.0 │ +│ ● Installing system-images;android-34;google_apis;x86_64 │ +│ ████████████░░░░░░░░░░░░░░░░░░░░░░ 45% (1.2 GB/2.6 GB)│ +│ ○ Creating AVD Pixel_5_API_34 │ +│ ○ Verifying setup │ +│ │ +│ ─────────────────────────────────────────────────────────│ +│ [Cancel] ETA: 3 min │ +└────────────────────────────────────────────────────────────┘ +``` + +#### Visual Studio: Tools Menu Integration + +``` +Tools +├── MAUI +│ ├── Check Environment... Ctrl+Shift+M, E +│ ├── Fix Environment Issues... Ctrl+Shift+M, F +│ ├── ───────────────────────── +│ ├── Android +│ │ ├── SDK Manager... +│ │ ├── AVD Manager... +│ │ └── Device Log... +│ ├── iOS Simulators... +│ └── ───────────────────────── +│ └── Diagnostic Bundle... +``` + +### 9.2 Interactive Prompting + +When running in interactive mode (terminal), the tool prompts for missing information: + +**Example: AVD Creation with Missing Parameters**: +``` +$ maui android avd create + +? AVD name: My_Pixel_5 + +? Select device profile: + ❯ Pixel 5 (1080x2340, 440dpi) + Pixel 6 (1080x2400, 411dpi) + Pixel 7 Pro (1440x3120, 512dpi) + (more...) + +? Select system image: + ❯ android-34 | Google APIs | x86_64 (recommended) + android-34 | Google Play | x86_64 + android-33 | Google APIs | x86_64 + (more...) + +Creating AVD 'My_Pixel_5'... done +``` + +**Non-Interactive Mode**: +``` +$ maui android avd create --non-interactive +Error: --name is required in non-interactive mode +``` + +**Example: Large Download Confirmation**: +``` +$ maui doctor --fix + +The following will be installed: + • system-images;android-34;google_apis;x86_64 (2.6 GB) + • iOS 18.0 Runtime (8.1 GB) + +Total download size: 10.7 GB + +? Proceed? [Y/n] +``` + +--- + +## 10. Telemetry & Diagnostics + +### 10.1 Telemetry Events + +| Event | Data Collected | Purpose | +|-------|----------------|---------| +| `command.invoked` | Command name, flags used, duration | Understand usage patterns | +| `doctor.result` | Issue counts by category (no specifics) | Track environment health | +| `fix.attempted` | Issue type, success/failure | Measure fix effectiveness | +| `error.occurred` | Error code, category (no stack traces) | Identify common failures | + +### 10.2 Opt-In / Opt-Out + +``` +# Check telemetry status +$ maui telemetry status +Telemetry is currently: DISABLED + +# Enable telemetry +$ maui telemetry enable + +# Disable telemetry +$ maui telemetry disable +``` + +**Default**: Telemetry is **OFF** by default. First run prompts: +``` +? Help improve MAUI Dev Tools by sending anonymous usage data? [y/N] +``` + +### 10.3 Redaction Rules + +All telemetry and logs follow these redaction rules: + +| Data Type | Rule | Example | +|-----------|------|---------| +| File paths | Replace with `` or keep structure | `/Users/name/code` → `/code` | +| Device names | Replace with type | `John's iPhone` → `` | +| Serial numbers | Redact | `R58M32XXXXX` → `` | +| UDIDs | Redact | `A1B2C3...` → `` | +| Error messages | Keep, unless contains path | Preserved | + +### 10.4 Diagnostic Bundle + +``` +$ maui diagnostic-bundle --output ~/Desktop/maui-diag.zip + +Collecting diagnostics... + • Environment info + • Tool configuration + • Recent command history (redacted) + • Android SDK state + • Xcode/simulator state + • .NET SDK info + +Saved to: /Users/dev/Desktop/maui-diag.zip (2.3 MB) +``` + +**Bundle Contents**: +``` +maui-diag/ +├── environment.json # OS, tool version, paths +├── doctor-report.json # Full doctor output +├── android/ +│ ├── sdk-packages.json +│ └── avd-list.json +├── apple/ +│ ├── simulators.json +│ └── runtimes.json +├── dotnet/ +│ ├── sdk-info.json +│ └── workloads.json +└── logs/ + └── recent-commands.log # Last 50 commands (redacted) +``` + +--- + +## 11. Security Model + +### 11.1 Principle of Least Privilege + +| Action | Privilege Level | Justification | +|--------|-----------------|---------------| +| Query status | User | Read-only operations | +| Install SDK to user directory | User | Default SDK location | +| Install SDK to system directory | Admin | System-wide installation | +| Create/start emulator | User | User-space operation | +| Install Xcode runtime | Admin | System component | +| Capture screenshot | User | Device already authorized | + +### 11.2 Download Verification + +All downloads are verified before installation: + +1. **HTTPS only**: All downloads use HTTPS +2. **Checksum verification**: SHA-256 checksums verified against known-good values +3. **Signature verification**: Where available (Android SDK, Xcode components) +4. **Source allowlist**: Only download from: + - `dl.google.com` (Android SDK) + - `developer.apple.com` (Xcode components) + - `aka.ms` / `dotnetcli.azureedge.net` (.NET components) + +### 11.3 AI Agent Permission Gates + +When invoked by an AI agent, certain operations require explicit user confirmation: + +| Operation | Permission Required | Confirmation UI | +|-----------|---------------------|-----------------| +| `doctor.status` | None | — | +| `device.list` | None | — | +| `device.screenshot` | `device.capture` | IDE prompt | +| `doctor.fix` | `environment.modify` | IDE prompt with details | +| `android.sdk.install` | `environment.modify` | IDE prompt with package list | +| `android.avd.create` | `device.create` | IDE prompt | +| `logs.stream` | `device.logs` | IDE prompt | + +**Permission Flow**: +``` +┌─────────────────────────────────────────────────────────────┐ +│ AI Agent Request │ +│ "Install Android SDK build-tools" │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ The AI assistant wants to install: │ +│ • build-tools;34.0.0 (52 MB) │ +│ │ +│ This will modify your Android SDK installation. │ +│ │ +│ [Allow] [Allow Once] [Deny] │ +│ │ +│ □ Remember this choice for this session │ +└─────────────────────────────────────────────────────────────┘ +``` + +### 11.4 Sandbox Boundaries + +AI agent calls are sandboxed: +- Cannot access arbitrary file system paths +- Cannot execute arbitrary commands +- Limited to defined API surface +- All actions logged with agent identifier + +--- + +## 12. Extensibility + +### 12.1 Plugin Model for Platform Providers + +New platform providers can be added by implementing `IPlatformProvider`: + +```csharp +public interface IPlatformProvider +{ + string PlatformId { get; } // e.g., "android", "ios", "windows" + + Task CheckHealthAsync(CancellationToken ct); + Task> GetIssuesAsync(CancellationToken ct); + Task FixIssueAsync(string issueId, CancellationToken ct); + Task> GetDevicesAsync(CancellationToken ct); +} +``` + +Providers are discovered via assembly scanning or explicit registration. + +### 12.2 Adding New Subcommands + +New commands are added by: +1. Creating a new `Command` class with `System.CommandLine` +2. Implementing the handler using core services +3. Registering the command in the root command builder +4. Adding corresponding JSON-RPC method if needed + +### 12.3 Versioning Strategy + +**CLI Versioning**: +- Follows SemVer: `MAJOR.MINOR.PATCH` +- MAJOR: Breaking changes to CLI arguments or behavior +- MINOR: New commands or options +- PATCH: Bug fixes + +**API Versioning**: +- JSON-RPC methods include version in response +- Schema version included in all JSON output +- Breaking changes require new method names (e.g., `doctor.status` → `doctor.status.v2`) + +**Capability Negotiation**: +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "initialize", + "params": { + "client_version": "1.0.0", + "capabilities": ["streaming", "progress"] + } +} +``` + +Response includes server capabilities: +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "server_version": "1.2.0", + "schema_version": "1.1", + "capabilities": ["streaming", "progress", "daemon"], + "platforms": ["android", "ios", "windows", "maccatalyst"] + } +} +``` + +--- + +## 13. Testing Strategy + +### 13.1 Unit Tests + +| Component | Coverage Target | Approach | +|-----------|-----------------|----------| +| CLI argument parsing | 100% | Test all commands, options, combinations | +| JSON-RPC serialization | 100% | Schema validation tests | +| Issue detection logic | 90% | Mock file system and tool outputs | +| Fix execution logic | 80% | Mock tool invocations | + +### 13.2 Integration Tests + +| Scenario | Environment | Frequency | +|----------|-------------|-----------| +| Doctor on clean Windows | Windows VM | Every PR | +| Doctor on clean macOS | macOS VM | Every PR | +| SDK installation | Isolated environment | Nightly | +| AVD creation/start | Android emulator | Nightly | +| Simulator management | macOS with Xcode | Nightly | + +### 13.3 Device Farm / Emulator Tests + +| Test | Infrastructure | Frequency | +|------|----------------|-----------| +| Screenshot capture | Helix (Android emulator) | Weekly | +| Screenshot capture | Helix (iOS simulator) | Weekly | +| Logcat streaming | Helix (Android emulator) | Weekly | +| Full doctor + fix flow | Dedicated VMs | Release | + +### 13.4 Test Environments + +```yaml +# CI Matrix +test-matrix: + - os: windows-latest + tests: [unit, integration-windows] + - os: macos-14 + tests: [unit, integration-macos, integration-xcode] + - os: ubuntu-latest + tests: [unit] # Limited to non-platform-specific +``` + +--- + +## 14. Rollout Plan + +### 14.1 Release Channels + +| Channel | Stability | Update Frequency | Audience | +|---------|-----------|------------------|----------| +| Preview | Experimental | Weekly | Early adopters, feedback | +| Release Candidate | Stable | Bi-weekly | Broader testing | +| Stable | Production | Monthly | General availability | + +### 14.2 Packaging + +**dotnet tool**: +``` +Package ID: Microsoft.Maui.DevTools +Install: dotnet tool install -g Microsoft.Maui.DevTools [--prerelease] +Update: dotnet tool update -g Microsoft.Maui.DevTools +``` + +**IDE Bundling**: +- VS Code extension bundles specific version +- Visual Studio includes in MAUI workload +- Can override with global tool if newer version needed + +### 14.3 Backwards Compatibility + +| Aspect | Guarantee | +|--------|-----------| +| CLI arguments | No breaking changes within major version | +| JSON output schema | Additive changes only; new fields don't break clients | +| JSON-RPC methods | Methods never removed; deprecated methods return warnings | +| Exit codes | Stable within major version | + +### 14.4 Update Strategy + +**Auto-update notification**: +``` +$ maui doctor +A new version of MAUI Dev Tools is available (1.2.0 → 1.3.0) +Run 'dotnet tool update -g Microsoft.Maui.DevTools' to update. + +[Current output continues...] +``` + +**IDE handling**: +- Check for updates on extension activation +- Prompt to update if major version behind +- Auto-update patch versions silently + +--- + +## 15. Open Questions & Risks + +### 15.1 Open Questions + +| ID | Question | Options | Recommendation | +|----|----------|---------|----------------| +| OQ1 | Should we support Linux for Android-only development? | Yes/No | Defer to vNext; validate demand first | +| OQ2 | How to handle multiple Xcode versions? | Detect all / Use xcode-select | Use xcode-select default; allow override | +| OQ3 | Should daemon auto-start on login? | Yes/No/Optional | No; start on first IDE request | +| OQ4 | How to handle Apple Silicon vs Intel for simulators? | Auto-detect / Require flag | Auto-detect from `uname -m` | +| OQ5 | Should we cache SDK installers? | Yes/No/Configurable | Yes, with configurable cache location | + +### 15.2 Risks + +| ID | Risk | Likelihood | Impact | Mitigation | +|----|------|------------|--------|------------| +| R1 | Android SDK license changes break auto-install | Low | High | Monitor Google announcements; have manual fallback | +| R2 | Xcode CLI tools break with updates | Medium | Medium | Version-specific handling; quick patch releases | +| R3 | IDE teams don't adopt | Medium | High | Early engagement; joint design reviews | +| R4 | Performance issues with large SDK installations | Low | Medium | Progress UI; resumable downloads | +| R5 | Security vulnerabilities in downloaded components | Low | Critical | Checksum verification; CVE monitoring | + +--- + +## 16. Appendix + +### 16.1 Command Examples + +#### Doctor Commands +```bash +# Basic health check +maui doctor + +# Health check with JSON output +maui doctor --json + +# Check and fix automatically +maui doctor --fix + +# Check only Android components +maui doctor --target android + +# Non-interactive mode for CI +maui doctor --fix --non-interactive +``` + +#### Android Commands +```bash +# List connected devices +maui android device list + +# Install recommended SDK packages +maui android sdk install --recommended + +# Install specific packages +maui android sdk install "platforms;android-34" "build-tools;34.0.0" + +# Create AVD +maui android avd create --name "Test_Pixel_5" --device pixel_5 --image "system-images;android-34;google_apis;x86_64" + +# Start emulator and wait for boot +maui android avd start --name "Test_Pixel_5" --wait + +# Stream logcat +maui android logcat --device emulator-5554 --filter "Microsoft.Maui:V *:S" + +# Take screenshot +maui device screenshot --device emulator-5554 --output ./screenshot.png +``` + +#### Apple Commands +```bash +# List all simulators +maui apple simulator list + +# List only booted iPhone simulators +maui apple simulator list --device-type iPhone --state booted + +# Boot specific simulator +maui apple simulator boot --udid A1B2C3D4-E5F6-7890-ABCD-EF1234567890 + +# Create new simulator +maui apple simulator create --name "Test iPhone 16" --device-type "iPhone 16 Pro" --runtime "iOS 18.0" + +# List available runtimes +maui apple runtime list + +# Take screenshot from simulator +maui device screenshot --device A1B2C3D4-E5F6-7890-ABCD-EF1234567890 --output ./sim-screenshot.png +``` + +### 16.2 JSON Output Examples + +#### Doctor Output (Healthy) +```json +{ + "schema_version": "1.0", + "correlation_id": "diag-2026-02-03-174500-abc123", + "timestamp": "2026-02-03T17:45:00.000Z", + "status": "healthy", + "checks": [ + { + "category": "dotnet", + "name": ".NET SDK", + "status": "ok", + "details": { + "version": "9.0.100", + "path": "/usr/local/share/dotnet", + "architecture": "arm64" + } + }, + { + "category": "dotnet", + "name": "MAUI Workload", + "status": "ok", + "details": { + "version": "9.0.0", + "installed_packs": [ + "Microsoft.Maui.Sdk", + "Microsoft.Maui.Controls", + "Microsoft.Maui.Core" + ] + } + }, + { + "category": "android", + "name": "Android SDK", + "status": "ok", + "details": { + "path": "/Users/dev/Library/Android/sdk", + "build_tools": ["34.0.0", "33.0.2"], + "platforms": ["android-34", "android-33"], + "emulator_version": "34.1.9" + } + }, + { + "category": "apple", + "name": "Xcode", + "status": "ok", + "details": { + "version": "16.0", + "path": "/Applications/Xcode.app", + "developer_dir": "/Applications/Xcode.app/Contents/Developer" + } + } + ], + "summary": { + "total": 8, + "ok": 8, + "warning": 0, + "error": 0 + } +} +``` + +#### Doctor Output (Issues Found) +```json +{ + "schema_version": "1.0", + "correlation_id": "diag-2026-02-03-174600-def456", + "timestamp": "2026-02-03T17:46:00.000Z", + "status": "unhealthy", + "checks": [ + { + "category": "android", + "name": "Android SDK", + "status": "error", + "message": "Android SDK not found at expected locations", + "issue": { + "id": "ANDROID_SDK_MISSING", + "severity": "error", + "description": "Android SDK is required for Android development", + "fixable": true, + "fix": { + "description": "Install Android SDK to default location", + "command": "maui android sdk install --recommended", + "rpc_method": "android.sdk.install", + "rpc_params": { "packages": ["recommended"] }, + "estimated_size_bytes": 2800000000, + "requires_confirmation": true + } + } + } + ], + "summary": { + "total": 8, + "ok": 5, + "warning": 1, + "error": 2 + } +} +``` + +#### Device List Output +```json +{ + "schema_version": "1.0", + "devices": [ + { + "id": "emulator-5554", + "name": "Pixel_5_API_34", + "platform": "android", + "type": "emulator", + "state": "online", + "os_version": "14", + "architecture": "x86_64", + "details": { + "avd_name": "Pixel_5_API_34", + "api_level": 34, + "skin": "pixel_5", + "snapshot": true + } + }, + { + "id": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890", + "name": "iPhone 16 Pro", + "platform": "ios", + "type": "simulator", + "state": "booted", + "os_version": "18.0", + "architecture": "arm64", + "details": { + "udid": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890", + "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-18-0", + "device_type": "com.apple.CoreSimulator.SimDeviceType.iPhone-16-Pro" + } + } + ] +} +``` + +### 16.3 Error Code Catalog + +| Code | Category | Message | Resolution | +|------|----------|---------|------------| +| `E1001` | General | Unknown command | Check command spelling; run `maui --help` | +| `E1002` | General | Missing required argument | Provide required argument or use interactive mode | +| `E1003` | General | Invalid argument value | Check allowed values in help | +| `E2001` | Android | Android SDK not found | Run `maui android sdk install --recommended` | +| `E2002` | Android | ADB not found | Install platform-tools via SDK manager | +| `E2003` | Android | Emulator not found | Install emulator package | +| `E2004` | Android | AVD not found | Create AVD with `maui android avd create` | +| `E2005` | Android | System image not found | Install required system image | +| `E2006` | Android | Device offline | Reconnect device or restart emulator | +| `E2007` | Android | APK installation failed | Check device storage; verify APK is valid | +| `E3001` | Apple | Xcode not found | Install Xcode from App Store | +| `E3002` | Apple | Xcode CLI tools not found | Run `xcode-select --install` | +| `E3003` | Apple | Runtime not found | Install via Xcode > Settings > Platforms | +| `E3004` | Apple | Simulator not found | Create simulator with `maui apple simulator create` | +| `E3005` | Apple | Simulator failed to boot | Check runtime compatibility; try different device | +| `E3006` | Apple | Developer directory not set | Run `sudo xcode-select -s /Applications/Xcode.app` | +| `E4001` | Network | Download failed | Check internet connection; retry | +| `E4002` | Network | Checksum verification failed | Re-download; report if persistent | +| `E4003` | Network | Connection timeout | Retry; check firewall/proxy settings | +| `E5001` | Permission | Elevation required | Run with administrator/sudo | +| `E5002` | Permission | Access denied | Check file/directory permissions | +| `E5003` | Permission | Agent permission denied | Approve action in IDE prompt | + +--- + +## 17. MVP vs vNext Features + +### MVP (v1.0) + +| Priority | Feature | +|----------|---------| +| P0 | `doctor` command with status reporting | +| P0 | `doctor --fix` for automated remediation | +| P0 | Android SDK detection and installation | +| P0 | Android AVD creation and management | +| P0 | iOS simulator listing and boot/shutdown | +| P0 | Unified `device list` command | +| P0 | `device screenshot` command | +| P0 | JSON output for all commands | +| P0 | JSON-RPC API for IDE integration | +| P0 | VS Code extension integration | +| P1 | Logcat streaming | +| P1 | iOS runtime listing | +| P1 | Interactive prompting | + +### vNext (v1.x / v2.0) + +| Priority | Feature | +|----------|---------| +| P1 | Visual Studio extension integration | +| P1 | Daemon mode for faster IDE interactions | +| P1 | iOS runtime installation guidance | +| P1 | APK install/uninstall | +| P2 | AVD snapshot management | +| P2 | Simulator log streaming | +| P2 | Windows SDK management | +| P2 | Linux host support (Android only) | +| P2 | Physical iOS device support (requires signing) | +| P2 | `tree` command for dependency visualization | +| P2 | `archive` command for app packaging | +| Future | MCP server integration for AI agents | +| Future | Cloud-hosted device support | + +--- + +## 18. Acceptance Criteria + +The following criteria must be met for v1.0 release: + +1. **AC1**: `maui doctor` completes in <5 seconds on a healthy system and correctly identifies all missing MAUI prerequisites. + +2. **AC2**: `maui doctor --fix` can install Android SDK, build-tools, emulator, and system images without manual intervention (license acceptance via `--accept-licenses`). + +3. **AC3**: `maui android avd create` creates a functional emulator that can boot and run a MAUI app. + +4. **AC4**: `maui apple simulator list` returns all available simulators with runtime and state information matching `xcrun simctl list`. + +5. **AC5**: `maui device list` returns a unified list of all Android devices/emulators and iOS simulators with consistent schema. + +6. **AC6**: `maui device screenshot` captures screenshots from both Android emulator and iOS simulator, saving to specified path. + +7. **AC7**: All commands support `--json` output with stable schema documented in spec. + +8. **AC8**: JSON-RPC server responds to all documented methods over stdio transport. + +9. **AC9**: VS Code extension can invoke `doctor.status`, display results, and trigger fixes via `doctor.fix`. + +10. **AC10**: Running `maui doctor --fix --non-interactive` in CI completes without prompts and returns appropriate exit codes. + +11. **AC11**: All downloads verify SHA-256 checksums before installation. + +12. **AC12**: AI agent permission gates prevent unauthorized modifications; all fix operations require explicit IDE confirmation. + +13. **AC13**: `diagnostic-bundle` produces a zip file containing all relevant diagnostic information with PII redacted. + +14. **AC14**: Tool runs correctly on Windows 10+ (x64/arm64) and macOS 13+ (arm64). + +15. **AC15**: Full test suite passes with >80% code coverage on unit tests. + +--- + +## 19. Future Subcommands (Roadmap) + +Inspired by MAUI CLI TODOs and community requests: + +| Command | Description | Inspiration | +|---------|-------------|-------------| +| `maui logs` | Stream unified logs from device/simulator | MAUI CLI TODO | +| `maui tree` | Display dependency tree for MAUI project | MAUI CLI TODO | +| `maui archive` | Build and package app for distribution | MAUI CLI TODO | +| `maui deploy` | Deploy to connected device | MAUI CLI TODO | +| `maui clean` | Clean MAUI build artifacts and caches | Common request | +| `maui template` | Scaffold new MAUI projects (delegate to dotnet new) | Convenience | +| `maui perf` | Performance profiling helpers | Future | +| `maui test` | Run device tests (delegate to dotnet test with device targeting) | Future | + +--- + +*End of Specification* From 942a4824599ccd6a8d682127d87a9b82d5970a7b Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 3 Feb 2026 18:32:14 +0000 Subject: [PATCH 02/34] Update spec --- docs/design/maui-devtools-spec.md | 267 +++++++++++++++++++++++++----- 1 file changed, 228 insertions(+), 39 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index a17a231b87f8..7207f0967451 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 1.0-draft +**Version**: 1.1-draft **Status**: Proposal **Last Updated**: 2026-02-03 @@ -27,6 +27,15 @@ --- +## Revision History + +| Version | Date | Changes | +|---------|------|---------| +| 1.1-draft | 2026-02-03 | Added: Exit code standardization, Windows management, offline/proxy support, container environments, migration strategy, concurrency model, permission storage, ARM64 considerations | +| 1.0-draft | 2026-02-03 | Initial draft | + +--- + ## 1. Executive Summary ### What It Is @@ -222,14 +231,17 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-D1 | Detect .NET SDK version and MAUI workload installation status | P0 | | FR-D2 | Detect Android SDK location and installed components | P0 | | FR-D3 | Detect Android build-tools, platform-tools, and emulator presence | P0 | -| FR-D4 | Detect Xcode installation, version, and selected developer directory | P0 | +| FR-D4 | Detect Xcode installation (full Xcode.app, not just CLI Tools), version, and selected developer directory | P0 | | FR-D5 | Detect installed iOS/macOS runtimes and simulators | P0 | -| FR-D6 | Detect Windows SDK installation (on Windows) | P1 | -| FR-D7 | Produce human-readable output with color-coded status | P0 | +| FR-D6 | Detect Windows SDK installation and Developer Mode status (on Windows) | P1 | +| FR-D7 | Produce human-readable output with color-coded status (with text fallback for accessibility) | P0 | | FR-D8 | Produce machine-readable JSON output with stable schema | P0 | | FR-D9 | Provide `--fix` flag to automatically remediate fixable issues | P0 | | FR-D10 | Prompt for confirmation before downloads >100MB | P0 | -| FR-D11 | Support `--target` filter (android, ios, windows, maccatalyst) | P1 | +| FR-D11 | Support `--platform` filter (android, ios, windows, maccatalyst) — multiple allowed | P1 | +| FR-D12 | Verify available disk space before attempting large downloads | P0 | +| FR-D13 | Support `--fix ` for targeted fixes | P1 | +| FR-D14 | Detect multiple SDK installations and report conflicts | P1 | ### 5.2 Android Management @@ -265,8 +277,21 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-X10 | Stream simulator/device logs | P1 | | FR-X11 | Validate basic signing prerequisites (team ID, certificate presence) | P2 | | FR-X12 | Open Simulator.app with specific device | P1 | +| FR-X13 | Handle multiple Xcode versions (detect all, use `xcode-select` default) | P1 | +| FR-X14 | Detect Xcode beta installations at `/Applications/Xcode-beta.app` | P2 | -### 5.4 Cross-Platform Screenshot +### 5.4 Windows Management + +| ID | Requirement | Priority | +|----|-------------|----------| +| FR-W1 | Detect Windows SDK installation and version | P1 | +| FR-W2 | Detect Developer Mode enabled status | P0 | +| FR-W3 | Guide user to enable Developer Mode if disabled | P0 | +| FR-W4 | Detect Visual Studio installation and MAUI workload | P1 | +| FR-W5 | Detect Hyper-V availability for Android emulation | P1 | +| FR-W6 | Detect Windows App SDK dependencies | P2 | + +### 5.5 Cross-Platform Screenshot | ID | Requirement | Priority | |----|-------------|----------| @@ -318,6 +343,12 @@ This tool eliminates that friction by providing a single, authoritative source f | NFR-P2 | Device list must complete in <2s | | NFR-P3 | Daemon mode must respond to health checks in <100ms | | NFR-P4 | Downloaded artifacts must be cached locally | +| NFR-P5 | Read operations must use direct file parsing (not CLI wrappers) for performance | + +**Performance Implementation Notes**: +- Android SDK detection: Parse `package.xml` and `source.properties` directly instead of invoking `sdkmanager --list` (which has 3-10s JVM startup time) +- iOS simulator list: Use `xcrun simctl list -j` (fast native tool) +- Fall back to CLI tools only for write operations (install, create, etc.) ### 6.4 Security @@ -344,6 +375,34 @@ This tool eliminates that friction by providing a single, authoritative source f | NFR-A2 | All status indicators must have text equivalents | | NFR-A3 | IDE integration must follow platform accessibility guidelines | +### 6.7 Network & Offline Support + +| ID | Requirement | +|----|-------------| +| NFR-N1 | Respect system proxy settings (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) | +| NFR-N2 | Support custom CA certificates for corporate SSL inspection | +| NFR-N3 | Provide `--offline` mode for doctor to skip network checks | +| NFR-N4 | Support `--local-source ` for installing from pre-downloaded artifacts | +| NFR-N5 | Large downloads must support HTTP Range requests for resumability | +| NFR-N6 | Cache downloaded installers with configurable location and size limits | + +### 6.8 Container & Headless Environments + +| Environment | Android Emulator | iOS Simulator | Doctor | SDK Install | +|-------------|------------------|---------------|--------|-------------| +| macOS native | ✓ | ✓ | ✓ | ✓ | +| Windows native | ✓ | — | ✓ | ✓ | +| Docker (Linux) | ✓ (with KVM) | — | ✓ | ✓ | +| Docker (macOS) | ❌ No nested virt | ❌ No CoreSimulator | Partial | Partial | +| GitHub Actions macOS | ✓ | ✓ | ✓ | ✓ | +| GitHub Actions Windows | ✓ (with HAXM) | — | ✓ | ✓ | +| Azure DevOps Hosted | ✓ | ✓ (macOS only) | ✓ | ✓ | +| WSL2 | ✓ (experimental) | — | Partial | ✓ | + +When emulator/simulator unavailable: +- `maui doctor` reports capability with reason (e.g., "emulator: unavailable (virtualization disabled)") +- `maui android avd start` fails fast with `E2010` "Hardware acceleration unavailable" + --- ## 7. Architecture @@ -532,9 +591,58 @@ User: maui doctor --json 1. IDE sends request to well-known socket/pipe 2. If no daemon running, extension spawns `maui daemon --background` 3. Daemon responds to requests -4. After 5 minutes idle, daemon self-terminates +4. After 5 minutes idle (configurable via `--idle-timeout`), daemon self-terminates 5. Next request restarts daemon +**Well-Known Paths**: +- macOS: `/tmp/maui-devtools.sock` (Unix domain socket) +- Windows: `\\.\pipe\MauiDevTools` (named pipe) + +### 7.6 Concurrency Model + +| Aspect | Behavior | +|--------|----------| +| Read Operations | Parallelized (multiple simultaneous queries allowed) | +| Write Operations | Serialized (single writer at a time) | +| Lock File | `$TMPDIR/maui-devtools.lock` prevents duplicate daemon instances | +| Request Timeout | Requests waiting >30s for lock rejected with `E5010` | +| Progress Notifications | Buffered with backpressure; slow consumers receive "progress.dropped" notification | + +**Race Condition Prevention**: +- Multiple IDE instances requesting daemon start simultaneously are handled via lock file +- First acquirer starts daemon; others connect to existing instance +- Socket/pipe creation is atomic + +### 7.7 SDK Conflict Resolution + +When multiple SDK installations are detected: + +**Android SDK Precedence** (first match wins): +1. `ANDROID_HOME` environment variable +2. `ANDROID_SDK_ROOT` environment variable +3. Visual Studio configured path (Windows) +4. Android Studio configured path (`~/.android/sdk` or registry) +5. Default location (`~/Library/Android/sdk` on macOS, `%LOCALAPPDATA%\Android\Sdk` on Windows) + +**Conflict Handling**: +- `maui doctor` reports all detected SDKs with recommendation +- `maui config set android-sdk-path ` to override +- `--sdk-path` flag available on all android commands for one-off override + +**Android Studio Coexistence**: +- Detect Android Studio installation +- Warn if both AS and tool would manage same SDK +- Offer to adopt AS's SDK rather than installing duplicate + +### 7.8 Migration from Existing Setups + +When an existing SDK is detected: + +1. **Validate** existing SDK health before offering modifications +2. **Adopt or Fresh**: Offer "adopt existing" vs "install fresh" options +3. **Non-Destructive**: Never delete or modify user's existing SDK without explicit consent +4. **Override Support**: `--sdk-path` for non-standard locations + --- ## 8. Public API Surface @@ -546,42 +654,46 @@ User: maui doctor --json ``` maui ├── doctor # Check environment health -│ ├── --fix # Auto-fix detected issues -│ ├── --target # Filter: android, ios, windows, maccatalyst +│ ├── --fix [issue-id] # Auto-fix all or specific issue +│ ├── --platform

# Filter: android, ios, windows, maccatalyst (repeatable) │ ├── --json # Output as JSON -│ └── --non-interactive # No prompts (for CI) +│ ├── --non-interactive # No prompts (for CI) +│ └── --offline # Skip network checks │ ├── device │ ├── list # List all devices │ │ ├── --platform # Filter by platform │ │ └── --json # Output as JSON -│ └── screenshot # Capture screenshot -│ ├── --device # Target device -│ ├── --output # Output file -│ ├── --wait # Delay before capture -│ └── --format # png, jpg +│ ├── screenshot # Capture screenshot +│ │ ├── --device # Target device +│ │ ├── --output # Output file +│ │ ├── --wait # Delay before capture +│ │ └── --format # png, jpg +│ └── logs # Stream logs from device +│ ├── --device # Device identifier +│ └── --filter # Filter expression │ ├── android │ ├── sdk │ │ ├── list # List installed packages │ │ ├── list-available # List available packages -│ │ └── install # Install package +│ │ ├── install # Install package +│ │ └── uninstall # Uninstall package │ ├── avd │ │ ├── list # List AVDs │ │ ├── create # Create AVD │ │ │ ├── --name # AVD name │ │ │ ├── --device # Device profile -│ │ │ ├── --image # System image +│ │ │ ├── --image # System image (prefers arm64 on Apple Silicon) │ │ │ └── --force # Overwrite existing │ │ ├── start # Start AVD │ │ │ ├── --name # AVD name (or --avd) │ │ │ ├── --cold-boot # Fresh boot │ │ │ └── --wait # Wait for boot -│ │ └── stop # Stop emulator -│ │ └── --device # Emulator serial -│ ├── logcat # Stream logs -│ │ ├── --device # Target device -│ │ └── --filter # Tag filter +│ │ ├── stop # Stop emulator +│ │ │ └── --device # Emulator serial +│ │ └── delete # Delete AVD +│ │ └── --name # AVD name │ └── install # Install APK │ ├── --device # Target device │ └── # APK file @@ -597,22 +709,20 @@ maui │ │ │ ├── --runtime # Runtime identifier │ │ │ └── --device-type # Device type identifier │ │ ├── boot # Boot simulator -│ │ │ └── --udid # Simulator UDID (or name) +│ │ │ └── --udid # Simulator UDID (or --name) │ │ ├── shutdown # Shutdown simulator │ │ │ └── --udid # Simulator UDID │ │ └── delete # Delete simulator │ │ └── --udid # Simulator UDID -│ ├── runtime -│ │ ├── list # List runtimes -│ │ └── install # Install runtime (guidance) -│ │ └── --version # Runtime version -│ └── logs # Stream device logs -│ └── --udid # Simulator UDID +│ └── runtime +│ ├── list # List runtimes +│ └── install # Install runtime (guidance) +│ └── --version # Runtime version │ -├── logs -│ └── stream # Stream logs from device -│ ├── --device # Device identifier -│ └── --filter # Filter expression +├── config # Configuration management +│ ├── list # List all config values +│ ├── get # Get config value +│ └── set # Set config value │ ├── diagnostic-bundle # Export diagnostic info │ └── --output # Output zip file @@ -625,30 +735,54 @@ maui └── --version # Show version ``` +#### Exit Code Standard + +All commands follow a consistent exit code scheme: + +| Code | Meaning | When Used | +|------|---------|-----------| +| 0 | Success / Healthy | Operation completed successfully | +| 1 | Partial success / Issues found | `doctor` found issues; operation completed with warnings | +| 2 | Operation failed | Command failed (network error, invalid input, etc.) | +| 3 | Permission denied | Elevation required but not granted | +| 4 | User canceled | User declined confirmation prompt | +| 5 | Resource not found | Requested device/AVD/simulator not found | +| 126 | Command not executable | Binary not found or not executable | +| 127 | Command not found | Unknown subcommand | + #### Command Table | Command | Description | Inputs | Output | Exit Codes | |---------|-------------|--------|--------|------------| -| `doctor` | Check environment health | `--fix`, `--target`, `--json` | Status report | 0=healthy, 1=issues, 2=error | +| `doctor` | Check environment health | `--fix`, `--platform`, `--json` | Status report | 0=healthy, 1=issues, 2=error | | `device list` | List available devices | `--platform`, `--json` | Device list | 0=success, 2=error | -| `device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 1=no device, 2=error | +| `device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 5=no device, 2=error | | `android sdk list` | List SDK packages | `--json` | Package list | 0=success, 2=error | -| `android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 1=not found, 2=error | +| `android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 5=not found, 2=error | | `android avd create` | Create emulator | `--name`, `--device`, `--image` | AVD name | 0=success, 1=exists, 2=error | -| `android avd start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 1=not found, 2=error | +| `android avd start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | | `apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | -| `apple simulator boot` | Boot simulator | `--udid` or name | UDID | 0=success, 1=not found, 2=error | +| `apple simulator boot` | Boot simulator | `--udid` or `--name` | UDID | 0=success, 5=not found, 2=error | | `apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | +| `config set` | Set configuration | ``, `` | Confirmation | 0=success, 2=error | ### 8.2 JSON-RPC API **Transport**: JSON-RPC 2.0 over stdio (primary) or named pipes/Unix sockets (daemon mode) +**Transport Details**: +- **stdio mode**: Newline-delimited JSON (NDJSON) — one JSON object per line, requests on stdin, responses on stdout +- **Named pipes** (Windows): `\\.\pipe\MauiDevTools` +- **Unix sockets** (macOS): `/tmp/maui-devtools.sock` +- **Line protocol**: Each message is a complete JSON object followed by `\n` +- **Encoding**: UTF-8 + **Why JSON-RPC**: - Language-agnostic (works with any IDE/agent) - Simple request/response model - Well-defined error handling - Supports notifications for streaming (logs, progress) +- Familiar to IDE developers (same as LSP) #### Method Reference @@ -663,7 +797,7 @@ Check environment health. "id": 1, "method": "doctor.status", "params": { - "targets": ["android", "ios"] + "platforms": ["android", "ios"] } } ``` @@ -1394,6 +1528,61 @@ AI agent calls are sandboxed: - Limited to defined API surface - All actions logged with agent identifier +**Safe Paths** (agents may read/write only within): +- Project root directory +- Temp directory (`$TMPDIR` / `%TEMP%`) +- SDK directories (Android SDK, Xcode Developer directory) +- Tool cache directory (`~/.maui-devtools/`) + +**Path Validation**: +- Reject paths containing `..` +- Reject absolute paths outside safe paths +- Validate in CLI Layer before dispatching to services + +### 11.5 Permission Storage + +| Context | Storage Location | Lifetime | +|---------|------------------|----------| +| IDE Session | In-memory | Until IDE closes | +| Terminal | Per-command | Single invocation | +| CI | Environment variable `MAUI_DEVTOOLS_ALLOW_MODIFY=1` | Pipeline run | +| Persistent | `~/.config/maui-devtools/permissions.json` | Until revoked | + +**Persistent Permission Schema**: +```json +{ + "schema_version": 1, + "agents": { + "github-copilot": { + "environment.modify": "allow", + "device.create": "prompt", + "device.capture": "allow" + }, + "default": { + "environment.modify": "prompt", + "device.create": "prompt", + "device.capture": "prompt" + } + } +} +``` + +**Permission Values**: +- `allow`: Permitted without prompt +- `prompt`: Requires user confirmation each time +- `deny`: Blocked (agent receives permission error) + +### 11.6 Elevation Handling + +When an operation requires elevation: + +| Platform | Mechanism | User Experience | +|----------|-----------|-----------------| +| macOS | `sudo` prompt in terminal; Authorization Services in GUI | System password dialog | +| Windows | UAC prompt | Standard elevation dialog | + +**For AI Agents**: Elevated operations cannot be auto-approved. Agent receives error `E5001` with message explaining elevation requirement. User must run command manually or through IDE's privileged execution path. + --- ## 12. Extensibility From cf60c2918b31cb4b8a712f3828dc0e4cc0538799 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 3 Feb 2026 18:39:27 +0000 Subject: [PATCH 03/34] Try to integrate with dotnet tool --- docs/design/maui-devtools-spec.md | 182 +++++++++++++++++++++++++++++- 1 file changed, 178 insertions(+), 4 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 7207f0967451..e005fbc4dbab 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 1.1-draft +**Version**: 1.2-draft **Status**: Proposal **Last Updated**: 2026-02-03 @@ -31,6 +31,7 @@ | Version | Date | Changes | |---------|------|---------| +| 1.2-draft | 2026-02-03 | Added: MSBuild integration alignment with dotnet/sdk spec, `dotnet run` pipeline integration, `--list-devices` convention, deploy step, AI agent considerations | | 1.1-draft | 2026-02-03 | Added: Exit code standardization, Windows management, offline/proxy support, container environments, migration strategy, concurrency model, permission storage, ARM64 considerations | | 1.0-draft | 2026-02-03 | Initial draft | @@ -719,6 +720,12 @@ maui │ └── install # Install runtime (guidance) │ └── --version # Runtime version │ +├── deploy # Deploy app to device (without running) +│ ├── --device # Target device +│ ├── --project # Project file (default: current dir) +│ ├── --configuration # Build configuration +│ └── --framework # Target framework +│ ├── config # Configuration management │ ├── list # List all config values │ ├── get # Get config value @@ -735,6 +742,15 @@ maui └── --version # Show version ``` +#### Global Options (Available on All Commands) + +| Option | Description | +|--------|-------------| +| `--json` | Output as JSON (machine-readable) | +| `--verbose` | Enable verbose logging | +| `--non-interactive` | Disable prompts; fail if input needed | +| `--correlation-id` | Set correlation ID for tracing | + #### Exit Code Standard All commands follow a consistent exit code scheme: @@ -1587,7 +1603,161 @@ When an operation requires elevation: ## 12. Extensibility -### 12.1 Plugin Model for Platform Providers +### 12.1 Alignment with `dotnet run` Pipeline + +This tool is designed to complement and integrate with the `dotnet run` extensibility spec ([dotnet/sdk#51337](https://github.com/dotnet/sdk/pull/51337)). The SDK spec introduces MSBuild targets that workloads can implement for device discovery and deployment. + +**Key MSBuild Integration Points**: + +| MSBuild Target | SDK Responsibility | MAUI DevTools Role | +|----------------|-------------------|-------------------| +| `ComputeAvailableDevices` | Called by `dotnet run` to get device list | DevTools can invoke same target OR provide faster cached results | +| `DeployToDevice` | Called by `dotnet run` after build | DevTools wraps this for standalone deploy scenarios | +| `ComputeRunArguments` | Sets `$(RunCommand)` and `$(RunArguments)` | DevTools uses these for consistent launch behavior | + +**Device Item Schema** (aligned with SDK spec): + +```xml + + + + + + + + +``` + +**Metadata Specification**: + +| Metadata | Required | Values | Description | +|----------|----------|--------|-------------| +| `Description` | Yes | Free text | Human-readable device name | +| `Type` | Yes | `Device`, `Emulator`, `Simulator` | Device category | +| `Status` | Yes | `Online`, `Offline`, `Booted`, `Shutdown`, `Paired`, `Unavailable` | Current state | +| `Platform` | No | `android`, `ios`, `maccatalyst`, `windows` | Inferred from TFM if not specified | +| `OSVersion` | No | Version string | e.g., "14", "18.0" | + +### 12.2 Interactive Prompting Alignment + +Following the SDK spec pattern, MAUI DevTools supports interactive prompting with graceful non-interactive fallback: + +**Interactive Mode** (terminal with TTY): +``` +$ maui device list +? Select target framework: + ❯ net10.0-android + net10.0-ios + net10.0-maccatalyst + net10.0-windows10.0.19041.0 + +? Select device: + ❯ emulator-5554 (Pixel 7 - API 35) [Online] + 0A041FDD400327 (Pixel 7 Pro) [Online] +``` + +**Non-Interactive Mode** (CI, piped, `--non-interactive`): +``` +$ maui device list --non-interactive +Error: Multiple target frameworks available. Use --platform to specify: + --platform android + --platform ios + --platform maccatalyst + --platform windows + +$ maui device screenshot --non-interactive +Error: Multiple devices available. Use --device to specify: + --device emulator-5554 # Pixel 7 - API 35 [Online] + --device 0A041FDD400327 # Pixel 7 Pro [Online] +``` + +### 12.3 `--list-devices` Convention + +Aligned with `dotnet run --list-devices`, this tool provides: + +```bash +# List devices for current project context +maui device list + +# List devices for specific platform +maui device list --platform android + +# Equivalent to dotnet run --list-devices (when in project directory) +dotnet run --list-devices +``` + +**Output Format** (aligned with SDK expectations): + +``` +Available devices for net10.0-android: + + ID DESCRIPTION TYPE STATUS + emulator-5554 Pixel 7 - API 35 Emulator Online + 0A041FDD400327 Pixel 7 Pro Device Online + +Run with: dotnet run --device + or: maui device screenshot --device +``` + +### 12.4 Deploy Step Support + +The SDK spec introduces a `deploy` step in the `dotnet run` pipeline. MAUI DevTools provides standalone access: + +```bash +# Deploy without running (useful for testing) +maui deploy --device emulator-5554 + +# This invokes the DeployToDevice MSBuild target +``` + +**JSON-RPC Method**: +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "deploy", + "params": { + "project_path": "/path/to/MyApp.csproj", + "device_id": "emulator-5554", + "configuration": "Debug", + "framework": "net10.0-android" + } +} +``` + +### 12.5 AI Agent Considerations + +The SDK spec explicitly mentions AI agents: + +> "This has become more relevant in the AI era, as someone is going to expect AIs in 'agent mode' to build and run their app." + +MAUI DevTools is designed with AI agents as first-class consumers: + +| Requirement | How DevTools Addresses It | +|-------------|---------------------------| +| Structured output | All commands support `--json` with stable schema | +| Discoverability | `--list-devices` provides machine-parseable device list | +| Non-interactive | `--non-interactive` mode with helpful error messages | +| Deterministic | Same inputs produce same outputs; idempotent operations | +| Permission gates | Explicit confirmation for modifications (see §11.3) | + +**AI Agent Workflow Example**: + +```python +# 1. Discover available devices +devices = run("maui device list --platform android --json") + +# 2. Select appropriate device (first online emulator) +device = next(d for d in devices if d["status"] == "Online" and d["type"] == "Emulator") + +# 3. Build and deploy (with user confirmation via IDE) +run(f"maui deploy --device {device['id']} --project ./MyApp.csproj") + +# 4. Capture screenshot for verification +run(f"maui device screenshot --device {device['id']} --output ./screenshot.png") +``` + +### 12.6 Plugin Model for Platform Providers New platform providers can be added by implementing `IPlatformProvider`: @@ -1600,12 +1770,16 @@ public interface IPlatformProvider Task> GetIssuesAsync(CancellationToken ct); Task FixIssueAsync(string issueId, CancellationToken ct); Task> GetDevicesAsync(CancellationToken ct); + + // New: MSBuild target integration + bool HasMSBuildTarget(string targetName); + Task InvokeMSBuildTargetAsync(string targetName, IDictionary properties, CancellationToken ct); } ``` Providers are discovered via assembly scanning or explicit registration. -### 12.2 Adding New Subcommands +### 12.7 Adding New Subcommands New commands are added by: 1. Creating a new `Command` class with `System.CommandLine` @@ -1613,7 +1787,7 @@ New commands are added by: 3. Registering the command in the root command builder 4. Adding corresponding JSON-RPC method if needed -### 12.3 Versioning Strategy +### 12.8 Versioning Strategy **CLI Versioning**: - Follows SemVer: `MAJOR.MINOR.PATCH` From a4811a2f7cc9b066d4cb44d752be7ad61df7ee14 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 3 Feb 2026 19:38:29 +0000 Subject: [PATCH 04/34] Add copilot helper --- docs/design/maui-devtools-spec.md | 213 +++++++++++++++++++++++++++++- 1 file changed, 210 insertions(+), 3 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index e005fbc4dbab..2fbea24cdb4f 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 1.2-draft +**Version**: 1.3-draft **Status**: Proposal **Last Updated**: 2026-02-03 @@ -31,6 +31,7 @@ | Version | Date | Changes | |---------|------|---------| +| 1.3-draft | 2026-02-03 | Added: Copilot-assisted troubleshooting (§9.3), MCP tool integration, escalation hierarchy, context handoff schema | | 1.2-draft | 2026-02-03 | Added: MSBuild integration alignment with dotnet/sdk spec, `dotnet run` pipeline integration, `--list-devices` convention, deploy step, AI agent considerations | | 1.1-draft | 2026-02-03 | Added: Exit code standardization, Windows management, offline/proxy support, container environments, migration strategy, concurrency model, permission storage, ARM64 considerations | | 1.0-draft | 2026-02-03 | Initial draft | @@ -1399,9 +1400,215 @@ Total download size: 10.7 GB ? Proceed? [Y/n] ``` ---- +### 9.3 Copilot-Assisted Troubleshooting + +When automated fixes fail or issues are too complex for deterministic resolution, the tool can escalate to GitHub Copilot for AI-assisted troubleshooting. This provides a graceful fallback that combines structured diagnostics with conversational problem-solving. + +#### Escalation Triggers + +The tool escalates to Copilot when: + +| Trigger | Example | Escalation Action | +|---------|---------|-------------------| +| Fix failed | SDK install fails with network error | Offer "Ask Copilot for help" | +| Unknown issue | Unrecognized error code from `adb` | Auto-suggest Copilot assistance | +| Complex diagnosis | Multiple interrelated issues | Recommend Copilot review | +| User request | User clicks "Get AI Help" | Open Copilot with context | + +#### Context Handoff + +When escalating to Copilot, the tool provides structured context: + +```json +{ + "escalation_type": "fix_failed", + "tool_version": "1.2.0", + "doctor_report": { /* full doctor.status output */ }, + "failed_operation": { + "command": "android.sdk.install", + "params": { "packages": ["platforms;android-34"] }, + "error": { + "code": "E4001", + "message": "Download failed: Connection reset", + "details": "Failed after 3 retries to dl.google.com" + } + }, + "environment": { + "os": "macOS 15.0", + "proxy_configured": true, + "network_type": "corporate" + }, + "attempted_fixes": [ + { "action": "retry_download", "result": "failed" }, + { "action": "clear_cache", "result": "failed" } + ] +} +``` + +#### IDE Integration (VS Code) + +``` +┌────────────────────────────────────────────────────────────┐ +│ ✖ Fix Failed │ +├────────────────────────────────────────────────────────────┤ +│ │ +│ Unable to install Android SDK automatically. │ +│ │ +│ Error: Connection reset while downloading from │ +│ dl.google.com (E4001) │ +│ │ +│ Attempted: │ +│ • Retry download (3 times) │ +│ • Clear download cache │ +│ │ +│ This may be caused by: │ +│ • Corporate proxy/firewall blocking Google domains │ +│ • Network connectivity issues │ +│ • SSL inspection interfering with downloads │ +│ │ +│ ─────────────────────────────────────────────────────────│ +│ [Ask Copilot for Help] [View Logs] [Retry] [Cancel] │ +└────────────────────────────────────────────────────────────┘ +``` + +**"Ask Copilot for Help" Flow**: + +1. User clicks button or types `/maui-help` in Copilot Chat +2. Extension sends diagnostic context to Copilot +3. Copilot receives structured data + conversation prompt: + +``` +The MAUI Dev Tools detected an issue it couldn't fix automatically. + +**Issue**: Android SDK installation failed (E4001 - Connection reset) +**Environment**: macOS 15.0, corporate network with proxy +**Attempted**: 3 download retries, cache clear + +The diagnostic bundle is attached. Please help the user resolve this issue. +Common causes for this error include proxy configuration, firewall rules, +or SSL inspection. Ask clarifying questions if needed. +``` + +4. Copilot engages in conversational troubleshooting +5. Copilot can suggest manual steps or request tool actions with user approval + +#### CLI Integration + +```bash +$ maui doctor --fix +... +✖ Failed to install Android SDK + +Error: Connection reset while downloading (E4001) + +Attempted fixes: + • Retry download (3 times) - failed + • Clear download cache - failed + +Would you like to get help from Copilot? [Y/n] y + +Opening Copilot with diagnostic context... +Run: gh copilot explain "MAUI SDK install failure E4001" + +Or copy this diagnostic summary: + maui diagnostic-bundle --output /tmp/maui-diag.zip + gh copilot explain --file /tmp/maui-diag.zip +``` + +#### Copilot Tool Actions (MCP Integration) + +When running as an MCP server, the tool exposes actions that Copilot can invoke (with user approval): + +```json +{ + "tools": [ + { + "name": "maui_doctor_status", + "description": "Check MAUI development environment health", + "requires_approval": false + }, + { + "name": "maui_doctor_fix", + "description": "Attempt to fix detected environment issues", + "requires_approval": true + }, + { + "name": "maui_diagnostic_bundle", + "description": "Generate diagnostic bundle for troubleshooting", + "requires_approval": false + }, + { + "name": "maui_config_set", + "description": "Update tool configuration (e.g., proxy settings)", + "requires_approval": true + } + ] +} +``` + +**Example Copilot Conversation**: + +``` +User: My MAUI Android build keeps failing with SDK errors + +Copilot: Let me check your MAUI environment. + [Calling maui_doctor_status...] + + I found several issues: + 1. ❌ Android SDK not found at expected location + 2. ⚠️ ANDROID_HOME environment variable not set -## 10. Telemetry & Diagnostics + It looks like the Android SDK may not be installed, or it's + installed in a non-standard location. + + Would you like me to: + a) Install the Android SDK to the default location + b) Help you configure ANDROID_HOME to point to an existing SDK + +User: Install it please + +Copilot: I'll install the Android SDK with recommended components. + [Requesting approval for maui_doctor_fix...] + + ✓ User approved + + [Calling maui_doctor_fix with issue_id="ANDROID_SDK_MISSING"...] + + ✓ Android SDK installed successfully + ✓ ANDROID_HOME configured + + Your environment is now ready. Try building again! +``` + +#### Fallback Hierarchy + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 1. Automated Fix (maui doctor --fix) │ +│ Tool attempts deterministic fix based on known patterns │ +├─────────────────────────────────────────────────────────────┤ +│ 2. Guided Manual Fix │ +│ Tool provides step-by-step instructions for user │ +├─────────────────────────────────────────────────────────────┤ +│ 3. Copilot-Assisted Troubleshooting │ +│ AI helps diagnose complex/unknown issues conversationally│ +├─────────────────────────────────────────────────────────────┤ +│ 4. Community/Support Escalation │ +│ Link to GitHub issues, docs, or support channels │ +└─────────────────────────────────────────────────────────────┘ +``` + +#### Privacy Considerations + +When escalating to Copilot: + +- **Opt-in**: User must explicitly request Copilot assistance +- **Data minimization**: Only relevant diagnostic data shared +- **Redaction**: PII (paths, device names) redacted per §10.3 rules +- **Transparency**: User can view exact data being shared before sending +- **Local option**: `--offline-diagnosis` generates report without sending to Copilot + +--- ### 10.1 Telemetry Events From eb8b351967d52bdc3df17f75f3da45ce19598512 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 3 Feb 2026 19:51:51 +0000 Subject: [PATCH 05/34] Fix some commands info --- docs/design/maui-devtools-spec.md | 175 +++++++++++++++++++----------- 1 file changed, 110 insertions(+), 65 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 2fbea24cdb4f..e13e38838996 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 1.3-draft +**Version**: 1.4-draft **Status**: Proposal **Last Updated**: 2026-02-03 @@ -31,6 +31,7 @@ | Version | Date | Changes | |---------|------|---------| +| 1.4-draft | 2026-02-03 | Changed CLI to `dotnet maui` pattern; kept `apple` for Apple platform commands; added `windows` subcommand | | 1.3-draft | 2026-02-03 | Added: Copilot-assisted troubleshooting (§9.3), MCP tool integration, escalation hierarchy, context handoff schema | | 1.2-draft | 2026-02-03 | Added: MSBuild integration alignment with dotnet/sdk spec, `dotnet run` pipeline integration, `--list-devices` convention, deploy step, AI agent considerations | | 1.1-draft | 2026-02-03 | Added: Exit code standardization, Windows management, offline/proxy support, container environments, migration strategy, concurrency model, permission storage, ARM64 considerations | @@ -149,7 +150,7 @@ This tool eliminates that friction by providing a single, authoritative source f **Profile**: Marcus, building an iOS app. He has Xcode installed but outdated simulators. **Journey**: -1. Marcus runs `maui doctor` in terminal +1. Marcus runs `dotnet maui doctor` in terminal 2. Output shows: ``` ✓ .NET SDK 9.0.100 @@ -159,7 +160,7 @@ This tool eliminates that friction by providing a single, authoritative source f ⚠ iOS 18.0 runtime not installed (iOS 17.4 available) ⚠ No iPhone 16 simulator available ``` -3. He runs `maui doctor --fix` +3. He runs `dotnet maui doctor --fix` 4. Tool prompts: "Install iOS 18.0 runtime? (requires 8GB download) [Y/n]" 5. After confirmation, runtime installs and simulator is created @@ -178,7 +179,7 @@ This tool eliminates that friction by providing a single, authoritative source f - name: Setup MAUI Environment run: | dotnet tool install -g Microsoft.Maui.DevTools - maui doctor --fix --non-interactive --json > setup-report.json + dotnet maui doctor --fix --non-interactive --json > setup-report.json ``` 2. Tool runs silently, installs missing components, outputs JSON report 3. If any unfixable issues exist, tool exits with non-zero code @@ -196,7 +197,7 @@ This tool eliminates that friction by providing a single, authoritative source f **Journey**: 1. User asks: "My Android build is failing with 'SDK not found'" -2. Agent invokes: `maui doctor --json --target android` +2. Agent invokes: `dotnet maui doctor --json --platform android` 3. Agent receives structured response: ```json { @@ -207,7 +208,7 @@ This tool eliminates that friction by providing a single, authoritative source f "severity": "error", "message": "Android SDK not found", "fixable": true, - "fix_command": "maui android sdk install --recommended" + "fix_command": "dotnet maui android sdk install --recommended" } ] } @@ -402,8 +403,8 @@ This tool eliminates that friction by providing a single, authoritative source f | WSL2 | ✓ (experimental) | — | Partial | ✓ | When emulator/simulator unavailable: -- `maui doctor` reports capability with reason (e.g., "emulator: unavailable (virtualization disabled)") -- `maui android avd start` fails fast with `E2010` "Hardware acceleration unavailable" +- `dotnet maui doctor` reports capability with reason (e.g., "emulator: unavailable (virtualization disabled)") +- `dotnet maui android avd start` fails fast with `E2010` "Hardware acceleration unavailable" --- @@ -627,8 +628,8 @@ When multiple SDK installations are detected: 5. Default location (`~/Library/Android/sdk` on macOS, `%LOCALAPPDATA%\Android\Sdk` on Windows) **Conflict Handling**: -- `maui doctor` reports all detected SDKs with recommendation -- `maui config set android-sdk-path ` to override +- `dotnet maui doctor` reports all detected SDKs with recommendation +- `dotnet maui config set android-sdk-path ` to override - `--sdk-path` flag available on all android commands for one-off override **Android Studio Coexistence**: @@ -651,10 +652,12 @@ When an existing SDK is detected: ### 8.1 CLI Commands +The tool is invoked as `dotnet maui `, integrating naturally with the .NET CLI. Platform-specific commands use the target framework moniker pattern (`ios`, `android`, `maccatalyst`, `windows`). + #### Command Hierarchy ``` -maui +dotnet maui ├── doctor # Check environment health │ ├── --fix [issue-id] # Auto-fix all or specific issue │ ├── --platform

# Filter: android, ios, windows, maccatalyst (repeatable) @@ -663,7 +666,7 @@ maui │ └── --offline # Skip network checks │ ├── device -│ ├── list # List all devices +│ ├── list # List all devices across platforms │ │ ├── --platform # Filter by platform │ │ └── --json # Output as JSON │ ├── screenshot # Capture screenshot @@ -675,7 +678,7 @@ maui │ ├── --device # Device identifier │ └── --filter # Filter expression │ -├── android +├── android # Android-specific commands │ ├── sdk │ │ ├── list # List installed packages │ │ ├── list-available # List available packages @@ -696,11 +699,14 @@ maui │ │ │ └── --device # Emulator serial │ │ └── delete # Delete AVD │ │ └── --name # AVD name -│ └── install # Install APK +│ ├── install # Install APK +│ │ ├── --device # Target device +│ │ └── # APK file +│ └── logcat # Stream Android logs │ ├── --device # Target device -│ └── # APK file +│ └── --filter # Tag filter (e.g., "MainActivity:V *:S") │ -├── apple +├── apple # Apple platform commands (macOS only) │ ├── simulator │ │ ├── list # List simulators │ │ │ ├── --runtime # Filter by runtime @@ -717,10 +723,17 @@ maui │ │ └── delete # Delete simulator │ │ └── --udid # Simulator UDID │ └── runtime -│ ├── list # List runtimes +│ ├── list # List installed iOS/macOS runtimes │ └── install # Install runtime (guidance) │ └── --version # Runtime version │ +├── windows # Windows-specific commands (Windows only) +│ ├── sdk +│ │ └── list # List Windows SDK installations +│ └── developer-mode +│ ├── status # Check Developer Mode status +│ └── enable # Guide to enable Developer Mode +│ ├── deploy # Deploy app to device (without running) │ ├── --device # Target device │ ├── --project # Project file (default: current dir) @@ -743,6 +756,29 @@ maui └── --version # Show version ``` +**Command Examples**: +```bash +# Cross-platform commands +dotnet maui doctor +dotnet maui doctor --fix +dotnet maui device list +dotnet maui device screenshot --device emulator-5554 + +# Android-specific +dotnet maui android sdk install platforms;android-34 +dotnet maui android avd create --name Pixel_8 --device pixel_8 +dotnet maui android avd start --name Pixel_8 --wait +dotnet maui android logcat --device emulator-5554 + +# Apple-specific (macOS only) +dotnet maui apple simulator list +dotnet maui apple simulator boot --name "iPhone 16 Pro" +dotnet maui apple runtime list + +# Windows-specific +dotnet maui windows developer-mode status +``` + #### Global Options (Available on All Commands) | Option | Description | @@ -771,17 +807,17 @@ All commands follow a consistent exit code scheme: | Command | Description | Inputs | Output | Exit Codes | |---------|-------------|--------|--------|------------| -| `doctor` | Check environment health | `--fix`, `--platform`, `--json` | Status report | 0=healthy, 1=issues, 2=error | -| `device list` | List available devices | `--platform`, `--json` | Device list | 0=success, 2=error | -| `device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 5=no device, 2=error | -| `android sdk list` | List SDK packages | `--json` | Package list | 0=success, 2=error | -| `android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 5=not found, 2=error | -| `android avd create` | Create emulator | `--name`, `--device`, `--image` | AVD name | 0=success, 1=exists, 2=error | -| `android avd start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | -| `apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | -| `apple simulator boot` | Boot simulator | `--udid` or `--name` | UDID | 0=success, 5=not found, 2=error | -| `apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | -| `config set` | Set configuration | ``, `` | Confirmation | 0=success, 2=error | +| `dotnet maui doctor` | Check environment health | `--fix`, `--platform`, `--json` | Status report | 0=healthy, 1=issues, 2=error | +| `dotnet maui device list` | List available devices | `--platform`, `--json` | Device list | 0=success, 2=error | +| `dotnet maui device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 5=no device, 2=error | +| `dotnet maui android sdk list` | List SDK packages | `--json` | Package list | 0=success, 2=error | +| `dotnet maui android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 5=not found, 2=error | +| `dotnet maui android avd create` | Create emulator | `--name`, `--device`, `--image` | AVD name | 0=success, 1=exists, 2=error | +| `dotnet maui android avd start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | +| `dotnet maui apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | +| `dotnet maui apple simulator boot` | Boot simulator | `--udid` or `--name` | UDID | 0=success, 5=not found, 2=error | +| `dotnet maui apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | +| `dotnet maui config set` | Set configuration | ``, `` | Confirmation | 0=success, 2=error | ### 8.2 JSON-RPC API @@ -1254,19 +1290,19 @@ Stream logs from device (uses JSON-RPC notifications). |---------|---------|-------|-------------------| | `doctor` | ✓ | ✓ | No | | `doctor --fix` | ✓ | ✓ | Sometimes* | -| `device list` | ✓ | ✓ | No | -| `device screenshot` | ✓ | ✓ | No | -| `android sdk list` | ✓ | ✓ | No | -| `android sdk install` | ✓ | ✓ | No | -| `android avd create` | ✓ | ✓ | No | -| `android avd start` | ✓ | ✓ | No | -| `android logcat` | ✓ | ✓ | No | -| `apple simulator list` | — | ✓ | No | -| `apple simulator boot` | — | ✓ | No | -| `apple simulator create` | — | ✓ | No | -| `apple runtime list` | — | ✓ | No | -| `apple runtime install` | — | ✓ | Yes (admin) | -| `logs stream` | ✓ | ✓ | No | +| `dotnet maui device list` | ✓ | ✓ | No | +| `dotnet maui device screenshot` | ✓ | ✓ | No | +| `dotnet maui android sdk list` | ✓ | ✓ | No | +| `dotnet maui android sdk install` | ✓ | ✓ | No | +| `dotnet maui android avd create` | ✓ | ✓ | No | +| `dotnet maui android avd start` | ✓ | ✓ | No | +| `dotnet maui android logcat` | ✓ | ✓ | No | +| `dotnet maui apple simulator list` | — | ✓ | No | +| `dotnet maui apple simulator boot` | — | ✓ | No | +| `dotnet maui apple simulator create` | — | ✓ | No | +| `dotnet maui apple runtime list` | — | ✓ | No | +| `dotnet maui apple runtime install` | — | ✓ | Yes (admin) | +| `dotnet maui device logs` | ✓ | ✓ | No | *Elevation required for: installing Android SDK to system locations, installing Xcode runtimes @@ -2163,64 +2199,73 @@ Run 'dotnet tool update -g Microsoft.Maui.DevTools' to update. #### Doctor Commands ```bash # Basic health check -maui doctor +dotnet maui doctor # Health check with JSON output -maui doctor --json +dotnet maui doctor --json # Check and fix automatically -maui doctor --fix +dotnet maui doctor --fix # Check only Android components -maui doctor --target android +dotnet maui doctor --platform android # Non-interactive mode for CI -maui doctor --fix --non-interactive +dotnet maui doctor --fix --non-interactive ``` #### Android Commands ```bash -# List connected devices -maui android device list +# List connected devices and emulators +dotnet maui device list --platform android # Install recommended SDK packages -maui android sdk install --recommended +dotnet maui android sdk install --recommended # Install specific packages -maui android sdk install "platforms;android-34" "build-tools;34.0.0" +dotnet maui android sdk install "platforms;android-34" "build-tools;34.0.0" # Create AVD -maui android avd create --name "Test_Pixel_5" --device pixel_5 --image "system-images;android-34;google_apis;x86_64" +dotnet maui android avd create --name "Test_Pixel_5" --device pixel_5 --image "system-images;android-34;google_apis;x86_64" # Start emulator and wait for boot -maui android avd start --name "Test_Pixel_5" --wait +dotnet maui android avd start --name "Test_Pixel_5" --wait # Stream logcat -maui android logcat --device emulator-5554 --filter "Microsoft.Maui:V *:S" +dotnet maui android logcat --device emulator-5554 --filter "Microsoft.Maui:V *:S" # Take screenshot -maui device screenshot --device emulator-5554 --output ./screenshot.png +dotnet maui device screenshot --device emulator-5554 --output ./screenshot.png ``` -#### Apple Commands +#### iOS Commands ```bash # List all simulators -maui apple simulator list +dotnet maui apple simulator list # List only booted iPhone simulators -maui apple simulator list --device-type iPhone --state booted +dotnet maui apple simulator list --device-type iPhone --state booted # Boot specific simulator -maui apple simulator boot --udid A1B2C3D4-E5F6-7890-ABCD-EF1234567890 +dotnet maui apple simulator boot --udid A1B2C3D4-E5F6-7890-ABCD-EF1234567890 # Create new simulator -maui apple simulator create --name "Test iPhone 16" --device-type "iPhone 16 Pro" --runtime "iOS 18.0" +dotnet maui apple simulator create --name "Test iPhone 16" --device-type "iPhone 16 Pro" --runtime "iOS 18.0" # List available runtimes -maui apple runtime list +dotnet maui apple runtime list # Take screenshot from simulator -maui device screenshot --device A1B2C3D4-E5F6-7890-ABCD-EF1234567890 --output ./sim-screenshot.png +dotnet maui device screenshot --device A1B2C3D4-E5F6-7890-ABCD-EF1234567890 --output ./sim-screenshot.png +``` + +#### Windows Commands +```bash +# Check Developer Mode status +dotnet maui windows developer-mode status + +# List Windows SDK installations +dotnet maui windows sdk list ``` ### 16.2 JSON Output Examples @@ -2367,20 +2412,20 @@ maui device screenshot --device A1B2C3D4-E5F6-7890-ABCD-EF1234567890 --output ./ | Code | Category | Message | Resolution | |------|----------|---------|------------| -| `E1001` | General | Unknown command | Check command spelling; run `maui --help` | +| `E1001` | General | Unknown command | Check command spelling; run `dotnet maui --help` | | `E1002` | General | Missing required argument | Provide required argument or use interactive mode | | `E1003` | General | Invalid argument value | Check allowed values in help | -| `E2001` | Android | Android SDK not found | Run `maui android sdk install --recommended` | +| `E2001` | Android | Android SDK not found | Run `dotnet maui android sdk install --recommended` | | `E2002` | Android | ADB not found | Install platform-tools via SDK manager | | `E2003` | Android | Emulator not found | Install emulator package | -| `E2004` | Android | AVD not found | Create AVD with `maui android avd create` | +| `E2004` | Android | AVD not found | Create AVD with `dotnet maui android avd create` | | `E2005` | Android | System image not found | Install required system image | | `E2006` | Android | Device offline | Reconnect device or restart emulator | | `E2007` | Android | APK installation failed | Check device storage; verify APK is valid | | `E3001` | Apple | Xcode not found | Install Xcode from App Store | | `E3002` | Apple | Xcode CLI tools not found | Run `xcode-select --install` | | `E3003` | Apple | Runtime not found | Install via Xcode > Settings > Platforms | -| `E3004` | Apple | Simulator not found | Create simulator with `maui apple simulator create` | +| `E3004` | Apple | Simulator not found | Create simulator with `dotnet maui apple simulator create` | | `E3005` | Apple | Simulator failed to boot | Check runtime compatibility; try different device | | `E3006` | Apple | Developer directory not set | Run `sudo xcode-select -s /Applications/Xcode.app` | | `E4001` | Network | Download failed | Check internet connection; retry | From c1fe8973b3fe396d4db1ee36aba58a9877495a50 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 4 Feb 2026 15:58:43 +0000 Subject: [PATCH 06/34] Add info of VS tools we can deprecate --- docs/design/maui-devtools-spec.md | 55 +++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index e13e38838996..d90494bc831f 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,8 +1,8 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 1.4-draft +**Version**: 1.5-draft **Status**: Proposal -**Last Updated**: 2026-02-03 +**Last Updated**: 2026-02-04 --- @@ -31,6 +31,7 @@ | Version | Date | Changes | |---------|------|---------| +| 1.5-draft | 2026-02-04 | Added: Design Principles (DP1: delegate to native tools, DP2: consolidate VS repositories); added NG6 for no custom download logic | | 1.4-draft | 2026-02-03 | Changed CLI to `dotnet maui` pattern; kept `apple` for Apple platform commands; added `windows` subcommand | | 1.3-draft | 2026-02-03 | Added: Copilot-assisted troubleshooting (§9.3), MCP tool integration, escalation hierarchy, context handoff schema | | 1.2-draft | 2026-02-03 | Added: MSBuild integration alignment with dotnet/sdk spec, `dotnet run` pipeline integration, `--list-devices` convention, deploy step, AI agent considerations | @@ -115,6 +116,56 @@ This tool eliminates that friction by providing a single, authoritative source f | NG3 | Linux host support (MVP) | MAUI mobile development requires Windows or macOS | | NG4 | Physical iOS device provisioning | Requires Apple Developer account; out of scope for MVP | | NG5 | Manage Visual Studio installation | VS has its own installer; we detect, not manage | +| NG6 | Implement custom download/installation logic | Delegate to native platform tools; avoid reinventing package management | + +### Design Principles + +#### DP1: Delegate to Native Toolchains — Do Not Reimplement + +**This tool MUST NOT implement custom logic to download, install, or configure platform components.** Instead, it delegates all such operations to the native platform tools: + +| Platform | Native Tools Used | What They Handle | +|----------|-------------------|------------------| +| Android | `sdkmanager`, `avdmanager`, `adb`, `emulator` | SDK packages, AVDs, device communication, emulator lifecycle | +| Apple | `xcrun simctl`, `xcode-select`, `xcodebuild` | Simulators, runtimes, Xcode selection, build tools | +| Windows | Windows SDK installer, VS Build Tools | Windows SDK components | + +**Rationale**: +- Native tools are **authoritative** and always up-to-date with platform changes +- Avoids **maintenance burden** of tracking repository URLs, package formats, and installation procedures +- Reduces **security risk** from implementing custom download/verification logic +- Ensures **consistency** between manual and automated installations +- Leverages **existing testing** of platform tools by their maintainers + +**Example**: +``` +❌ WRONG: Download android-sdk-*.zip from Google, extract, configure PATH +✅ RIGHT: Invoke `sdkmanager "platform-tools" "platforms;android-34"` and parse output +``` + +This tool's value is in **orchestration, detection, and unified UX**—not in reimplementing what the platform tools already do well. + +#### DP2: Consolidate Existing Visual Studio Acquisition Repositories + +This tool enables **consolidation of existing Visual Studio repositories** that currently implement Android acquisition separately: + +| Repository | Current Function | Future State | +|------------|------------------|--------------| +| [ClientTools.android-acquisition](https://devdiv.visualstudio.com/DevDiv/_git/ClientTools.android-acquisition) | Android SDK acquisition for VS | **Deprecate**: Use `dotnet maui android sdk install` | +| [android-platform-support](https://devdiv.visualstudio.com/DevDiv/_git/android-platform-support) | Android platform support for VS | **Deprecate**: Use `dotnet maui android` commands | + +**Benefits of Consolidation**: +- **Single codebase** for Android tooling across VS, VS Code, CLI, and CI +- **Reduced duplication** of detection and installation logic +- **Consistent behavior** across all Microsoft developer tools +- **Shared bug fixes** and improvements +- **Simplified maintenance** with one team owning the tooling + +**Migration Path**: +1. Visual Studio installer integrates `dotnet maui` tool +2. VS Android features call `dotnet maui android` commands instead of internal libraries +3. Internal repositories enter maintenance mode +4. After VS release cycle, internal repositories are archived --- From 7c73fc72b66356552c007e092e6cf3edfc2d7769 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 4 Feb 2026 16:21:17 +0000 Subject: [PATCH 07/34] Add state, json and jdk information --- docs/design/maui-devtools-spec.md | 480 ++++++++++++++++++++++++++++-- 1 file changed, 456 insertions(+), 24 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index d90494bc831f..bd94862fc8b4 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 1.5-draft +**Version**: 2.0-draft **Status**: Proposal **Last Updated**: 2026-02-04 @@ -31,6 +31,7 @@ | Version | Date | Changes | |---------|------|---------| +| 2.0-draft | 2026-02-04 | **Major revision from multi-model review**: Added DP3 (stateless-first), DP4 (machine-first output); Added Error Contract Specification (§7.9); Added Bootstrap State Machine (§5.6) with JDK installation; Clarified deploy vs run semantics; Added `--json`, `--dry-run`, `--ci` flags; Added JDK management commands; Defined default installation paths per platform | | 1.5-draft | 2026-02-04 | Added: Design Principles (DP1: delegate to native tools, DP2: consolidate VS repositories); added NG6 for no custom download logic | | 1.4-draft | 2026-02-03 | Changed CLI to `dotnet maui` pattern; kept `apple` for Apple platform commands; added `windows` subcommand | | 1.3-draft | 2026-02-03 | Added: Copilot-assisted troubleshooting (§9.3), MCP tool integration, escalation hierarchy, context handoff schema | @@ -167,6 +168,62 @@ This tool enables **consolidation of existing Visual Studio repositories** that 3. Internal repositories enter maintenance mode 4. After VS release cycle, internal repositories are archived +#### DP3: Stateless-First Architecture + +**The CLI MUST operate statelessly by default.** No background daemon is required for core functionality. + +| Mode | When to Use | Characteristics | +|------|-------------|-----------------| +| **Stateless (default)** | CLI invocations, CI/CD, AI agents | Each command reads state, acts, exits; no process coordination | +| **Daemon (optional, v2+)** | IDE performance optimization only | Explicit opt-in via `dotnet maui daemon start` | + +**Rationale**: +- Daemon lifecycle (orphaned processes, stale state, port conflicts) is a major source of tooling bugs +- Stateless commands are easier to debug, test, and reason about +- AI agents prefer deterministic request/response over managing socket connections +- Performance bottleneck is native tool execution, not process spin-up + +**State Caching**: +Stateless does not mean slow. The tool uses file-system caching: +``` +~/.maui/cache/ +├── devices.json # TTL: 30 seconds +├── android-sdk-state.json # TTL: 5 minutes +├── apple-runtimes.json # TTL: 5 minutes +└── doctor-report.json # TTL: 1 minute +``` + +Commands read from cache if fresh, otherwise invoke native tools and update cache. + +#### DP4: Machine-First Output — The User is the AI + +**Every command MUST support `--json` output with a stable, versioned schema.** + +This tool is designed for three consumers in priority order: +1. **AI Agents** (GitHub Copilot, IDE assistants) — need structured data to reason about +2. **CI/CD Pipelines** — need deterministic exit codes and parseable output +3. **Human Developers** — need readable summaries with color and formatting + +**Implication**: If an error message is ambiguous plain text, AI agents will fail to use the tool reliably. Every failure must be expressed as structured data. + +```bash +# Human-friendly (default) +dotnet maui doctor +# ✓ .NET SDK 9.0.100 +# ✗ Android SDK not found + +# Machine-friendly (for AI/CI) +dotnet maui doctor --json +# { "status": "unhealthy", "checks": [...], "errors": [...] } +``` + +**Required flags for all commands**: +| Flag | Purpose | +|------|---------| +| `--json` | Output structured JSON instead of human-readable text | +| `--dry-run` | Show what would be done without executing (enables "what will this do?" UX) | +| `--ci` | Strict mode: no interactive prompts, non-zero exit on warnings, machine-readable only | + --- ## 4. Personas & User Journeys @@ -314,6 +371,10 @@ This tool enables **consolidation of existing Visual Studio repositories** that | FR-A11 | Install APK to device/emulator | P1 | | FR-A12 | Uninstall package from device/emulator | P2 | | FR-A13 | Capture screenshot from device/emulator | P0 | +| FR-A14 | Bootstrap full Android environment (JDK + SDK) from scratch | P0 | +| FR-A15 | Detect JDK installation and version | P0 | +| FR-A16 | Install OpenJDK if missing (version 17 default, 21 supported) | P0 | +| FR-A17 | Use platform-appropriate default paths when env vars not set | P0 | ### 5.3 Apple (Xcode) Management @@ -367,6 +428,157 @@ This tool enables **consolidation of existing Visual Studio repositories** that | FR-DL4 | Support `--platform` filter | P1 | | FR-DL5 | Support `--json` output | P0 | +### 5.6 Bootstrap State Machine + +**Critical**: The tool must handle the "bootstrap gap" — the chicken-and-egg problem where native tools (sdkmanager, xcrun) don't exist yet. + +#### Platform Bootstrap States + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ MISSING │────▶│ DOWNLOADING │────▶│ INSTALLING │────▶│ READY │ +└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ + │ │ │ │ + │ │ │ │ + ▼ ▼ ▼ ▼ + User action Progress Progress Operational + required reporting reporting (delegate to + (or auto-fix) native tools) +``` + +#### Android Bootstrap + +The tool can fully bootstrap an Android development environment from scratch, including JDK and SDK installation. + +**Dependency Order**: JDK must be installed before SDK (sdkmanager requires Java). + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ JDK Check │────▶│ JDK Install │────▶│ SDK Install │────▶│ READY │ +└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ + │ │ │ │ + Missing? Download Download Operational + OpenJDK 17 cmdline-tools (delegate) +``` + +**Default Installation Paths** (when env vars not set): + +| Platform | JDK Path | SDK Path | +|----------|----------|----------| +| macOS | `~/Library/Developer/Android/jdk` | `~/Library/Developer/Android/sdk` | +| Windows | `%LOCALAPPDATA%\Android\jdk` | `%LOCALAPPDATA%\Android\sdk` | + +**Bootstrap States**: + +| State | Detection | Behavior | +|-------|-----------|----------| +| `JDK_MISSING` | No `java` in PATH, no JDK at default paths | Install OpenJDK 17 to default path | +| `SDK_MISSING` | `ANDROID_HOME` not set, no SDK at standard paths | Install command-line tools to default path | +| `PARTIAL` | SDK exists but `sdkmanager` missing/broken | Repair SDK or reinstall cmdline-tools | +| `READY` | `java -version` succeeds AND `sdkmanager --list` succeeds | Delegate all operations to native tools | + +**Bootstrap Command**: +```bash +# Full bootstrap: JDK + SDK + recommended packages +dotnet maui android bootstrap --accept-licenses + +# With custom paths +dotnet maui android bootstrap --jdk-path ~/my-jdk --sdk-path ~/my-sdk --accept-licenses +``` + +This command: +1. Checks for JDK; if missing, downloads and installs OpenJDK 17 +2. Sets `JAVA_HOME` for the session (prints guidance for permanent setup) +3. Downloads Android command-line tools (if missing) +4. Accepts SDK licenses non-interactively (if `--accept-licenses`) +5. Installs recommended packages (platform-tools, build-tools, emulator, system image) +6. Prints environment variable guidance (doesn't modify shell config) + +**JDK Management Commands**: +```bash +# Check JDK status +dotnet maui android jdk status + +# Install OpenJDK (default: version 17) +dotnet maui android jdk install +dotnet maui android jdk install --version 21 + +# List available JDK versions +dotnet maui android jdk list-available +``` + +**Environment Variable Guidance Output**: +``` +✓ JDK installed to ~/Library/Developer/Android/jdk +✓ SDK installed to ~/Library/Developer/Android/sdk + +Add to your shell profile (~/.zshrc or ~/.bashrc): + + export JAVA_HOME="$HOME/Library/Developer/Android/jdk" + export ANDROID_HOME="$HOME/Library/Developer/Android/sdk" + export PATH="$JAVA_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH" +``` + +#### Apple Bootstrap + +| State | Detection | Behavior | +|-------|-----------|----------| +| `MISSING` | No Xcode.app at `/Applications/Xcode*.app` | Error: "Install Xcode from App Store" (cannot auto-install) | +| `CLI_ONLY` | Only Command Line Tools installed | Error: "Full Xcode required for simulators" | +| `READY` | `xcrun simctl list` succeeds | Delegate all operations to native tools | + +**Important**: Apple bootstrap is limited because: +- Xcode cannot be installed programmatically (App Store only) +- Runtime downloads require Xcode to be open at least once (license acceptance) + +```bash +dotnet maui apple bootstrap +``` + +This command: +1. Verifies Xcode installation +2. Runs `xcode-select --install` if CLI tools missing +3. Prompts user to accept Xcode license if needed +4. Reports status and next steps + +#### Windows Bootstrap + +| State | Detection | Behavior | +|-------|-----------|----------| +| `MISSING` | No Windows SDK detected | Provide download link | +| `NO_DEV_MODE` | Developer Mode disabled | Guide user to enable (requires Settings app) | +| `READY` | SDK present, Developer Mode enabled | Operational | + +### 5.7 Deploy vs Run Semantics + +**Critical clarification**: The spec distinguishes between deployment operations: + +| Operation | Command | Behavior | Returns | +|-----------|---------|----------|---------| +| **Install Only** | `dotnet maui deploy --install-only` | Copy app to device, do not launch | Exit 0 on success | +| **Launch** | `dotnet maui deploy` | Install and launch app | Exit 0 when app starts | +| **Run to Completion** | `dotnet maui deploy --wait` | Install, launch, wait for exit | App exit code | +| **Debug Attach** | `dotnet maui deploy --debug` | Install, launch with debugger attached | Blocks until detach | + +**Lifecycle Detection**: +The tool MUST detect "app successfully started" per platform: +- **Android**: `adb shell am start` returns 0 + activity launched +- **iOS Simulator**: `xcrun simctl launch` returns 0 + process appears +- **Windows**: Process starts and main window appears + +**App Lifecycle Events** (JSON output): +```json +{ + "operation": "deploy", + "events": [ + { "type": "installing", "timestamp": "..." }, + { "type": "installed", "timestamp": "..." }, + { "type": "launching", "timestamp": "..." }, + { "type": "launched", "pid": 12345, "timestamp": "..." }, + { "type": "exited", "exit_code": 0, "timestamp": "..." } + ] +} + --- ## 6. Non-Functional Requirements @@ -631,22 +843,65 @@ User: maui doctor --json - Surfaces issues in Error List window - Provides menu items in Tools > MAUI submenu -### 7.5 Daemon Mode vs On-Demand +### 7.5 Stateless-First Architecture with Optional Daemon + +> **Design Decision (from multi-model review)**: The tool operates statelessly by default. Daemon mode is an optional optimization for IDE performance, NOT a requirement. -| Aspect | On-Demand (CLI) | Daemon Mode | -|--------|-----------------|-------------| -| Startup | New process per command | Single long-running process | -| Latency | ~200ms cold start | <50ms response | -| Use Case | CI, terminal, simple scripts | IDE integration | -| State | Stateless | Cached device list, SDK state | -| Resource Usage | None when idle | ~20MB memory when idle | +#### Why Stateless-First? + +| Concern | Daemon Problem | Stateless Solution | +|---------|----------------|-------------------| +| Orphaned processes | Daemon crashes, leaves socket locked | No persistent process to orphan | +| Stale state | Daemon caches outdated SDK state | Read fresh state each invocation | +| Multiple IDEs | Port conflicts, duplicate daemons | No coordination needed | +| Debugging | Hidden process state hard to inspect | CLI behavior is fully observable | +| CI/CD | Daemon unnecessary overhead | Clean process per command | + +#### On-Demand Mode (Default) + +| Aspect | Behavior | +|--------|----------| +| Startup | New process per command | +| Latency | ~200ms cold start (acceptable for most use cases) | +| State | Reads from file cache (`~/.maui/cache/`), always current | +| Best for | CI, terminal, scripts, AI agents | + +**File Cache Structure**: +``` +~/.maui/cache/ +├── devices.json # TTL: 30 seconds +├── android-sdk.json # TTL: 5 minutes +├── apple-runtimes.json # TTL: 5 minutes +└── doctor-report.json # TTL: 1 minute +``` + +#### Daemon Mode (Optional, v2+) + +Daemon is an **explicit opt-in** for IDE performance optimization only: + +```bash +# Explicit daemon control +dotnet maui daemon start # Start daemon +dotnet maui daemon stop # Stop daemon +dotnet maui daemon status # Check if running + +# Daemon-aware commands (use daemon if running, fallback to direct) +dotnet maui device list # Uses daemon if available, else direct +``` + +| Aspect | Behavior | +|--------|----------| +| Startup | Single long-running process | +| Latency | <50ms response | +| State | In-memory cache with file persistence | +| Best for | IDE integration requiring sub-100ms response | **Daemon Lifecycle**: -1. IDE sends request to well-known socket/pipe -2. If no daemon running, extension spawns `maui daemon --background` -3. Daemon responds to requests +1. User or IDE explicitly starts daemon with `dotnet maui daemon start` +2. Daemon listens on well-known socket/pipe +3. CLI commands check for daemon; use if running, else execute directly 4. After 5 minutes idle (configurable via `--idle-timeout`), daemon self-terminates -5. Next request restarts daemon +5. IDE can restart daemon when needed **Well-Known Paths**: - macOS: `/tmp/maui-devtools.sock` (Unix domain socket) @@ -697,6 +952,139 @@ When an existing SDK is detected: 3. **Non-Destructive**: Never delete or modify user's existing SDK without explicit consent 4. **Override Support**: `--sdk-path` for non-standard locations +### 7.9 Error Contract Specification + +**This is the highest-priority architectural element.** Every consumer (AI agents, CI pipelines, IDEs, humans) depends on predictable error handling. + +#### Error Taxonomy + +Errors are classified into three categories: + +| Category | Prefix | Responsibility | Example | +|----------|--------|----------------|---------| +| **Tool** | `E1xxx` | Bug in this tool | E1001: Internal state corruption | +| **Platform** | `E2xxx` | Native tool or SDK issue | E2001: sdkmanager license not accepted | +| **User** | `E3xxx` | User action required | E3001: Xcode not installed | + +#### Error Object Schema + +**Every error MUST be expressible as this JSON structure:** + +```json +{ + "code": "E2001", + "category": "platform", + "severity": "error", + "message": "Android SDK licenses not accepted", + "native_error": "Warning: License for package Android SDK Platform 34 not accepted.", + "context": { + "sdk_path": "/Users/dev/Library/Android/sdk", + "package": "platforms;android-34" + }, + "remediation": { + "type": "auto_fixable", + "command": "dotnet maui android sdk accept-licenses", + "manual_steps": null + }, + "docs_url": "https://learn.microsoft.com/dotnet/maui/troubleshoot/E2001", + "correlation_id": "7f3d2a1b-..." +} +``` + +#### Remediation Types + +| Type | Meaning | AI Agent Behavior | +|------|---------|-------------------| +| `auto_fixable` | Tool can fix this automatically | Execute `remediation.command` with user permission | +| `user_action` | User must take manual steps | Display `remediation.manual_steps`, cannot auto-fix | +| `terminal` | Cannot be fixed (e.g., unsupported OS) | Report error, suggest alternatives | +| `unknown` | Tool doesn't recognize this error | Escalate to Copilot Handoff | + +#### Error Code Registry (Partial) + +| Code | Category | Message | Remediation Type | +|------|----------|---------|------------------| +| `E1001` | tool | Internal error | terminal | +| `E2001` | platform | SDK licenses not accepted | auto_fixable | +| `E2002` | platform | sdkmanager not found | auto_fixable (bootstrap) | +| `E2003` | platform | xcrun failed | user_action | +| `E2004` | platform | Emulator acceleration unavailable | user_action | +| `E3001` | user | Xcode not installed | user_action | +| `E3002` | user | Developer Mode not enabled | user_action | +| `E3003` | user | Insufficient disk space | user_action | +| `E3004` | user | Network unavailable | user_action | + +#### Unknown Error Handling + +When the tool encounters an error it doesn't recognize: + +```json +{ + "code": "E0000", + "category": "unknown", + "severity": "error", + "message": "Unexpected error from native tool", + "native_error": "", + "remediation": { + "type": "unknown", + "command": null, + "manual_steps": null + }, + "copilot_handoff": { + "eligible": true, + "context": { + "doctor_report": { ... }, + "failed_command": "dotnet maui android avd create ...", + "environment": { ... }, + "native_tool_output": "..." + } + } +} +``` + +This is the **Copilot escalation trigger** — structured data that AI agents can consume to diagnose novel issues. + +#### Exit Code Mapping + +| Exit Code | Meaning | Contains | +|-----------|---------|----------| +| 0 | Success | Result data | +| 1 | Partial success | Result + warnings | +| 2 | Operation failed | Error objects | +| 3 | Permission denied | Error + elevation guidance | +| 4 | User cancelled | Cancellation reason | +| 5 | Resource not found | Error + suggestions | +| 126 | Command not executable | Error | +| 127 | Command not found | Error | + +#### Structured Output Contract + +**All commands MUST support these output modes:** + +```bash +# Default: Human-readable (stderr for errors, stdout for results) +dotnet maui doctor + +# Machine-readable: JSON to stdout (errors included in JSON, not stderr) +dotnet maui doctor --json + +# CI mode: JSON output, no prompts, warnings become errors +dotnet maui doctor --ci +``` + +**JSON output envelope:** + +```json +{ + "success": false, + "correlation_id": "...", + "duration_ms": 1234, + "result": null, + "errors": [ { ... } ], + "warnings": [ { ... } ] +} +``` + --- ## 8. Public API Surface @@ -725,15 +1113,29 @@ dotnet maui │ │ ├── --output # Output file │ │ ├── --wait # Delay before capture │ │ └── --format # png, jpg -│ └── logs # Stream logs from device -│ ├── --device # Device identifier -│ └── --filter # Filter expression +│ └── logs # Stream logs from device (unified across platforms) +│ ├── --device # Device identifier (required) +│ ├── --filter # Filter expression (platform-specific) +│ ├── --maui-only # Filter to MAUI-related logs only +│ └── --since

# JDK installation directory +│ │ └── --sdk-path # SDK installation directory +│ ├── jdk # JDK management +│ │ ├── status # Check JDK installation status +│ │ ├── install # Install OpenJDK +│ │ │ ├── --version # JDK version (default: 17) +│ │ │ └── --path # Installation directory +│ │ └── list-available # List available JDK versions │ ├── sdk │ │ ├── list # List installed packages │ │ ├── list-available # List available packages │ │ ├── install # Install package +│ │ ├── accept-licenses # Accept all SDK licenses │ │ └── uninstall # Uninstall package │ ├── avd │ │ ├── list # List AVDs @@ -785,11 +1187,15 @@ dotnet maui │ ├── status # Check Developer Mode status │ └── enable # Guide to enable Developer Mode │ -├── deploy # Deploy app to device (without running) +├── deploy # Deploy app to device │ ├── --device # Target device │ ├── --project # Project file (default: current dir) │ ├── --configuration # Build configuration -│ └── --framework # Target framework +│ ├── --framework # Target framework +│ ├── --install-only # Install without launching +│ ├── --wait # Wait for app to exit (returns app exit code) +│ ├── --debug # Launch with debugger attached +│ └── --timeout # Timeout for launch detection (default: 30) │ ├── config # Configuration management │ ├── list # List all config values @@ -832,12 +1238,38 @@ dotnet maui windows developer-mode status #### Global Options (Available on All Commands) -| Option | Description | -|--------|-------------| -| `--json` | Output as JSON (machine-readable) | -| `--verbose` | Enable verbose logging | -| `--non-interactive` | Disable prompts; fail if input needed | -| `--correlation-id` | Set correlation ID for tracing | +> **Design Principle DP4**: Every command MUST support `--json` output with a stable, versioned schema. The primary consumer is AI agents, not humans. + +| Option | Description | Required | +|--------|-------------|----------| +| `--json` | Output as JSON (machine-readable) | **Mandatory on all commands** | +| `--dry-run` | Show what would be done without executing | **Mandatory on write commands** | +| `--ci` | Strict mode: no prompts, warnings become errors, JSON output forced | Recommended | +| `--verbose` | Enable verbose logging | Optional | +| `--non-interactive` | Disable prompts; fail if input needed | Optional | +| `--correlation-id` | Set correlation ID for tracing | Optional | +| `--offline` | Skip network operations; use cached data only | Optional | + +**`--ci` Mode Behavior**: +- Forces `--json` output (human-readable disabled) +- Forces `--non-interactive` (no stdin prompts) +- Elevates warnings to errors (exit code 1 → 2) +- Includes full diagnostic context in error output +- Ideal for CI/CD pipelines and AI agent consumption + +**`--dry-run` Mode Output**: +```json +{ + "dry_run": true, + "planned_operations": [ + { "action": "install", "target": "platforms;android-34", "size_mb": 150 }, + { "action": "install", "target": "build-tools;34.0.0", "size_mb": 55 } + ], + "estimated_duration_seconds": 120, + "requires_approval": true, + "approval_reason": "Downloads exceed 100MB" +} +``` #### Exit Code Standard From 6d39c06b0b0082ca8952395b44cbd4a47119bc25 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 4 Feb 2026 16:47:42 +0000 Subject: [PATCH 08/34] Add info from other repositories --- docs/design/maui-devtools-spec.md | 106 +++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index bd94862fc8b4..94608678e3bd 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -24,6 +24,10 @@ 14. [Rollout Plan](#14-rollout-plan) 15. [Open Questions & Risks](#15-open-questions--risks) 16. [Appendix](#16-appendix) +17. [MVP vs vNext Features](#17-mvp-vs-vnext-features) +18. [Acceptance Criteria](#18-acceptance-criteria) +19. [Implementation References & Prior Art](#19-implementation-references--prior-art) +20. [Future Subcommands (Roadmap)](#20-future-subcommands-roadmap) --- @@ -31,7 +35,7 @@ | Version | Date | Changes | |---------|------|---------| -| 2.0-draft | 2026-02-04 | **Major revision from multi-model review**: Added DP3 (stateless-first), DP4 (machine-first output); Added Error Contract Specification (§7.9); Added Bootstrap State Machine (§5.6) with JDK installation; Clarified deploy vs run semantics; Added `--json`, `--dry-run`, `--ci` flags; Added JDK management commands; Defined default installation paths per platform | +| 2.0-draft | 2026-02-04 | **Major revision from multi-model review**: Added DP3 (stateless-first), DP4 (machine-first output); Added Error Contract Specification (§7.9); Added Bootstrap State Machine (§5.6) with JDK installation; Clarified deploy vs run semantics; Added `--json`, `--dry-run`, `--ci` flags; Added JDK management commands; Defined default installation paths per platform; Added Implementation References (§19) with AndroidSdk.Tools, AppleDev.Tools, MAUI.Sherpa, and official SDK targets | | 1.5-draft | 2026-02-04 | Added: Design Principles (DP1: delegate to native tools, DP2: consolidate VS repositories); added NG6 for no custom download logic | | 1.4-draft | 2026-02-03 | Changed CLI to `dotnet maui` pattern; kept `apple` for Apple platform commands; added `windows` subcommand | | 1.3-draft | 2026-02-03 | Added: Copilot-assisted troubleshooting (§9.3), MCP tool integration, escalation hierarchy, context handoff schema | @@ -2996,7 +3000,105 @@ The following criteria must be met for v1.0 release: --- -## 19. Future Subcommands (Roadmap) +## 19. Implementation References & Prior Art + +The following existing repositories and code contain reusable logic, patterns, and prior art that should be leveraged for implementation: + +### 19.1 Community Tools (Redth) + +| Repository | Description | Reusable Components | +|------------|-------------|---------------------| +| [AndroidSdk.Tools](https://github.com/Redth/AndroidSdk.Tools/) | C# library for Android SDK management | SDK detection, package installation, AVD management, emulator control, `adb` wrapper | +| [AppleDev.Tools](https://github.com/Redth/AppleDev.Tools) | C# library for Apple development tools | Xcode detection, simulator management, `xcrun` wrapper, provisioning profile handling | +| [MAUI.Sherpa](https://github.com/Redth/MAUI.Sherpa) | MAUI development environment helper | Doctor-style diagnostics, environment validation, fix suggestions | + +**Recommendation**: These libraries are production-tested and can be directly referenced or their patterns adopted. Consider contributing improvements back upstream. + +### 19.2 Official .NET SDK Targets + +| File | Description | Relevant Code | +|------|-------------|---------------| +| [Microsoft.Android.Sdk.Application.targets](https://github.com/dotnet/android/blob/main/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Application.targets#L42) | Android SDK build targets | Device detection via `_ResolveAndroidDevice`, deployment logic, `adb` integration | +| [Microsoft.Sdk.Mobile.targets](https://github.com/dotnet/macios/blob/e79838c4de379be59f4038117c713d4dd3963a62/dotnet/targets/Microsoft.Sdk.Mobile.targets#L146) | iOS/macOS SDK mobile targets | Simulator detection, `xcrun` integration, deployment to devices | + +**Key MSBuild Patterns to Adopt**: + +```xml + + + + + + + + + +``` + +### 19.3 Integration Strategy + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ MAUI Dev Tools Client │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ Core Services │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌──────────────────┼──────────────────┐ │ +│ ▼ ▼ ▼ │ +│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ +│ │ Android Provider│ │ Apple Provider │ │ Windows Provider│ │ +│ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ │ +│ │ REUSE: │ │ REUSE: │ │ │ │ +│ │ AndroidSdk.Tools│ │ AppleDev.Tools │ │ (New impl) │ │ +│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 19.4 Code Patterns to Extract + +**From AndroidSdk.Tools**: +- `SdkManager` class for package management +- `AvdManager` class for AVD lifecycle +- `Adb` class for device communication +- `Emulator` class for emulator control +- SDK path detection logic (environment variables, standard paths) + +**From AppleDev.Tools**: +- `Simctl` class for simulator management +- `XcodeSelect` class for Xcode detection +- Runtime/device type enumeration +- Provisioning profile parsing + +**From MAUI.Sherpa**: +- Doctor check architecture +- Issue categorization and severity +- Fix recommendation engine +- Progress reporting patterns + +**From Official SDK Targets**: +- MSBuild target integration patterns +- `ComputeAvailableDevices` output schema +- Device selection logic +- Deployment pipeline hooks + +### 19.5 Consolidation Roadmap + +| Phase | Action | Repositories Affected | +|-------|--------|----------------------| +| 1 | Reference AndroidSdk.Tools and AppleDev.Tools as dependencies | New tool | +| 2 | Contribute improvements (JSON output, new commands) upstream | Redth repos | +| 3 | Integrate with MSBuild targets via `ComputeAvailableDevices` | dotnet/android, dotnet/macios | +| 4 | Deprecate internal VS repos | ClientTools.android-acquisition, android-platform-support | +| 5 | Consider merging community tools into dotnet org (with maintainer agreement) | Long-term | + +--- + +## 20. Future Subcommands (Roadmap) Inspired by MAUI CLI TODOs and community requests: From dccae2e2d0afda209f1551eff2194a33f8eb83b2 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 4 Feb 2026 19:17:19 +0000 Subject: [PATCH 09/34] Split idea and AI integration , remove extra info --- docs/design/maui-devtools-ai-integration.md | 396 ++++++++ docs/design/maui-devtools-ide-integration.md | 301 ++++++ docs/design/maui-devtools-spec.md | 962 +------------------ 3 files changed, 724 insertions(+), 935 deletions(-) create mode 100644 docs/design/maui-devtools-ai-integration.md create mode 100644 docs/design/maui-devtools-ide-integration.md diff --git a/docs/design/maui-devtools-ai-integration.md b/docs/design/maui-devtools-ai-integration.md new file mode 100644 index 000000000000..9a03fdcc8944 --- /dev/null +++ b/docs/design/maui-devtools-ai-integration.md @@ -0,0 +1,396 @@ +# MAUI Dev Tools — AI Agent Integration + +**Parent Document**: [MAUI Dev Tools Specification](./maui-devtools-spec.md) + +This document details how AI agents (GitHub Copilot, IDE assistants) interact with MAUI Dev Tools. + +--- + +## Table of Contents + +1. [Design Principle: Machine-First Output](#1-design-principle-machine-first-output) +2. [AI Agent Persona & Journey](#2-ai-agent-persona--journey) +3. [Copilot-Assisted Troubleshooting](#3-copilot-assisted-troubleshooting) +4. [Permission Model](#4-permission-model) +5. [AI Agent Considerations](#5-ai-agent-considerations) + +--- + +## 1. Design Principle: Machine-First Output + +**Every command MUST support `--json` output with a stable, versioned schema.** + +This tool is designed for three consumers in priority order: +1. **AI Agents** (GitHub Copilot, IDE assistants) — need structured data to reason about +2. **CI/CD Pipelines** — need deterministic exit codes and parseable output +3. **Human Developers** — need readable summaries with color and formatting + +**Implication**: If an error message is ambiguous plain text, AI agents will fail to use the tool reliably. Every failure must be expressed as structured data. + +```bash +# Human-friendly (default) +dotnet maui doctor +# ✓ .NET SDK 9.0.100 +# ✗ Android SDK not found + +# Machine-friendly (for AI/CI) +dotnet maui doctor --json +# { "status": "unhealthy", "checks": [...], "errors": [...] } +``` + +**Required flags for all commands**: +| Flag | Purpose | +|------|---------| +| `--json` | Output structured JSON instead of human-readable text | +| `--dry-run` | Show what would be done without executing (enables "what will this do?" UX) | +| `--ci` | Strict mode: no interactive prompts, non-zero exit on warnings, machine-readable only | + +--- + +## 2. AI Agent Persona & Journey + +**Profile**: Copilot agent assisting a developer with a build error. + +**Journey**: +1. User asks: "My Android build is failing with 'SDK not found'" +2. Agent invokes: `dotnet maui doctor --json --platform android` +3. Agent receives structured response: + ```json + { + "status": "unhealthy", + "issues": [ + { + "id": "ANDROID_SDK_MISSING", + "severity": "error", + "message": "Android SDK not found", + "fixable": true, + "fix_command": "dotnet maui android sdk install --recommended" + } + ] + } + ``` +4. Agent explains the issue and asks: "Would you like me to install the Android SDK?" +5. User confirms; agent invokes fix command with permission gate +6. Agent verifies fix by re-running doctor + +**Key Requirements**: +- Structured JSON output with stable schema +- Fix commands included in diagnostic output +- Permission gates for destructive operations +- Correlation IDs for tracing + +--- + +## 3. Copilot-Assisted Troubleshooting + +When automated fixes fail or issues are too complex for deterministic resolution, the tool can escalate to GitHub Copilot for AI-assisted troubleshooting. This provides a graceful fallback that combines structured diagnostics with conversational problem-solving. + +### Escalation Triggers + +The tool escalates to Copilot when: + +| Trigger | Example | Escalation Action | +|---------|---------|-------------------| +| Fix failed | SDK install fails with network error | Offer "Ask Copilot for help" | +| Unknown issue | Unrecognized error code from `adb` | Auto-suggest Copilot assistance | +| Complex diagnosis | Multiple interrelated issues | Recommend Copilot review | +| User request | User clicks "Get AI Help" | Open Copilot with context | + +### Context Handoff + +When escalating to Copilot, the tool provides structured context: + +```json +{ + "escalation_type": "fix_failed", + "tool_version": "1.2.0", + "doctor_report": { /* full doctor.status output */ }, + "failed_operation": { + "command": "android.sdk.install", + "params": { "packages": ["platforms;android-34"] }, + "error": { + "code": "E4001", + "message": "Download failed: Connection reset", + "details": "Failed after 3 retries to dl.google.com" + } + }, + "environment": { + "os": "macOS 15.0", + "proxy_configured": true, + "network_type": "corporate" + }, + "attempted_fixes": [ + { "action": "retry_download", "result": "failed" }, + { "action": "clear_cache", "result": "failed" } + ] +} +``` + +### CLI Integration + +```bash +$ maui doctor --fix +... +✖ Failed to install Android SDK + +Error: Connection reset while downloading (E4001) + +Attempted fixes: + • Retry download (3 times) - failed + • Clear download cache - failed + +Would you like to get help from Copilot? [Y/n] y + +Opening Copilot with diagnostic context... +Run: gh copilot explain "MAUI SDK install failure E4001" + +Or copy this diagnostic summary: + maui diagnostic-bundle --output /tmp/maui-diag.zip + gh copilot explain --file /tmp/maui-diag.zip +``` + +### MCP Tool Integration + +When running as an MCP server, the tool exposes actions that Copilot can invoke (with user approval): + +```json +{ + "tools": [ + { + "name": "maui_doctor_status", + "description": "Check MAUI development environment health", + "requires_approval": false + }, + { + "name": "maui_doctor_fix", + "description": "Attempt to fix detected environment issues", + "requires_approval": true + }, + { + "name": "maui_diagnostic_bundle", + "description": "Generate diagnostic bundle for troubleshooting", + "requires_approval": false + }, + { + "name": "maui_config_set", + "description": "Update tool configuration (e.g., proxy settings)", + "requires_approval": true + } + ] +} +``` + +### Example Copilot Conversation + +``` +User: My MAUI Android build keeps failing with SDK errors + +Copilot: Let me check your MAUI environment. + [Calling maui_doctor_status...] + + I found several issues: + 1. ❌ Android SDK not found at expected location + 2. ⚠️ ANDROID_HOME environment variable not set + + It looks like the Android SDK may not be installed, or it's + installed in a non-standard location. + + Would you like me to: + a) Install the Android SDK to the default location + b) Help you configure ANDROID_HOME to point to an existing SDK + +User: Install it please + +Copilot: I'll install the Android SDK with recommended components. + [Requesting approval for maui_doctor_fix...] + + ✓ User approved + + [Calling maui_doctor_fix with issue_id="ANDROID_SDK_MISSING"...] + + ✓ Android SDK installed successfully + ✓ ANDROID_HOME configured + + Your environment is now ready. Try building again! +``` + +### Fallback Hierarchy + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 1. Automated Fix (maui doctor --fix) │ +│ Tool attempts deterministic fix based on known patterns │ +├─────────────────────────────────────────────────────────────┤ +│ 2. Guided Manual Fix │ +│ Tool provides step-by-step instructions for user │ +├─────────────────────────────────────────────────────────────┤ +│ 3. Copilot-Assisted Troubleshooting │ +│ AI helps diagnose complex/unknown issues conversationally│ +├─────────────────────────────────────────────────────────────┤ +│ 4. Community/Support Escalation │ +│ Link to GitHub issues, docs, or support channels │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Privacy Considerations + +When escalating to Copilot: + +- **Opt-in**: User must explicitly request Copilot assistance +- **Data minimization**: Only relevant diagnostic data shared +- **Redaction**: PII (paths, device names) redacted per privacy rules +- **Transparency**: User can view exact data being shared before sending +- **Local option**: `--offline-diagnosis` generates report without sending to Copilot + +--- + +## 4. Permission Model + +### Permission Gates + +When invoked by an AI agent, certain operations require explicit user confirmation: + +| Operation | Permission Required | Confirmation UI | +|-----------|---------------------|-----------------| +| `doctor.status` | None | — | +| `device.list` | None | — | +| `device.screenshot` | `device.capture` | IDE prompt | +| `doctor.fix` | `environment.modify` | IDE prompt with details | +| `android.sdk.install` | `environment.modify` | IDE prompt with package list | +| `android.avd.create` | `device.create` | IDE prompt | +| `logs.stream` | `device.logs` | IDE prompt | + +**Permission Flow**: +``` +┌─────────────────────────────────────────────────────────────┐ +│ AI Agent Request │ +│ "Install Android SDK build-tools" │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ The AI assistant wants to install: │ +│ • build-tools;34.0.0 (52 MB) │ +│ │ +│ This will modify your Android SDK installation. │ +│ │ +│ [Allow] [Allow Once] [Deny] │ +│ │ +│ □ Remember this choice for this session │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Sandbox Boundaries + +AI agent calls are sandboxed: +- Cannot access arbitrary file system paths +- Cannot execute arbitrary commands +- Limited to defined API surface +- All actions logged with agent identifier + +**Safe Paths** (agents may read/write only within): +- Project root directory +- Temp directory (`$TMPDIR` / `%TEMP%`) +- SDK directories (Android SDK, Xcode Developer directory) +- Tool cache directory (`~/.maui-devtools/`) + +**Path Validation**: +- Reject paths containing `..` +- Reject absolute paths outside safe paths +- Validate in CLI Layer before dispatching to services + +### Permission Storage + +| Context | Storage Location | Lifetime | +|---------|------------------|----------| +| IDE Session | In-memory | Until IDE closes | +| Terminal | Per-command | Single invocation | +| CI | Environment variable `MAUI_DEVTOOLS_ALLOW_MODIFY=1` | Pipeline run | +| Persistent | `~/.config/maui-devtools/permissions.json` | Until revoked | + +**Persistent Permission Schema**: +```json +{ + "schema_version": 1, + "agents": { + "github-copilot": { + "environment.modify": "allow", + "device.create": "prompt", + "device.capture": "allow" + }, + "default": { + "environment.modify": "prompt", + "device.create": "prompt", + "device.capture": "prompt" + } + } +} +``` + +**Permission Values**: +- `allow`: Permitted without prompt +- `prompt`: Requires user confirmation each time +- `deny`: Blocked (agent receives permission error) + +### Elevation Handling + +When an operation requires elevation: + +| Platform | Mechanism | User Experience | +|----------|-----------|-----------------| +| macOS | `sudo` prompt in terminal; Authorization Services in GUI | System password dialog | +| Windows | UAC prompt | Standard elevation dialog | + +**For AI Agents**: Elevated operations cannot be auto-approved. Agent receives error `E5001` with message explaining elevation requirement. User must run command manually or through IDE's privileged execution path. + +--- + +## 5. AI Agent Considerations + +The dotnet/sdk spec explicitly mentions AI agents: + +> "This has become more relevant in the AI era, as someone is going to expect AIs in 'agent mode' to build and run their app." + +MAUI DevTools is designed with AI agents as first-class consumers: + +| Requirement | How DevTools Addresses It | +|-------------|---------------------------| +| Structured output | All commands support `--json` with stable schema | +| Discoverability | `--list-devices` provides machine-parseable device list | +| Non-interactive | `--non-interactive` mode with helpful error messages | +| Deterministic | Same inputs produce same outputs; idempotent operations | +| Permission gates | Explicit confirmation for modifications (see §4) | + +**AI Agent Workflow Example**: + +```python +# 1. Discover available devices +devices = run("dotnet maui device list --platform android --json") + +# 2. Select appropriate device (first online emulator) +device = next(d for d in devices if d["status"] == "Online" and d["type"] == "Emulator") + +# 3. Build and deploy (with user confirmation via IDE) +run(f"dotnet maui deploy --device {device['id']} --project ./MyApp.csproj") + +# 4. Capture screenshot for verification +run(f"dotnet maui device screenshot --device {device['id']} --output ./screenshot.png") +``` + +### Error Contract for AI Agents + +AI agents depend on predictable error handling. Every error includes: + +| Field | Purpose | +|-------|---------| +| `code` | Unique error code (e.g., `E1001`) | +| `category` | Error category for routing | +| `message` | Human-readable description | +| `remediation` | Suggested fix actions | + +**Remediation Types**: + +| Type | Meaning | AI Agent Behavior | +|------|---------|-------------------| +| `automatic` | Tool can fix this automatically | Call `doctor.fix` with issue ID | +| `manual` | Requires user action | Present instructions to user | +| `escalate` | Tool doesn't know how to fix | Trigger Copilot Handoff | +| `unknown` | Tool doesn't recognize this error | Escalate to Copilot Handoff | diff --git a/docs/design/maui-devtools-ide-integration.md b/docs/design/maui-devtools-ide-integration.md new file mode 100644 index 000000000000..7cddb3f73641 --- /dev/null +++ b/docs/design/maui-devtools-ide-integration.md @@ -0,0 +1,301 @@ +# MAUI Dev Tools — IDE Integration + +**Parent Document**: [MAUI Dev Tools Specification](./maui-devtools-spec.md) + +This document details how IDEs (Visual Studio, VS Code) integrate with MAUI Dev Tools. + +--- + +## Table of Contents + +1. [Extension Architecture](#1-extension-architecture) +2. [VS Code Integration](#2-vs-code-integration) +3. [Visual Studio Integration](#3-visual-studio-integration) +4. [Common UI Patterns](#4-common-ui-patterns) + +--- + +## 1. Extension Architecture + +### VS Code Extension + +``` +┌─────────────────────────────────────────────────────────────┐ +│ VS Code │ +├─────────────────────────────────────────────────────────────┤ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ MAUI Extension │ │ +│ ├──────────────────────────────────────────────────────┤ │ +│ │ • Environment Status Bar Item │ │ +│ │ • "MAUI: Setup Environment" command │ │ +│ │ • Problems panel integration │ │ +│ │ • Quick Fix code actions │ │ +│ └─────────────────────┬────────────────────────────────┘ │ +│ │ │ +│ │ CLI invocation (stdio) │ +│ ▼ │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ MAUI Dev Tools Client │ │ +│ │ (spawned as child process) │ │ +│ └──────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +**Extension Responsibilities**: +1. Spawn `dotnet maui` process on activation +2. Send `dotnet maui doctor --json` request on workspace open +3. Display issues in Problems panel +4. Register "MAUI: Setup Environment" command +5. Show progress notifications during fixes + +### Visual Studio Extension + +- Uses CLI invocation for communication +- Integrates with Visual Studio's environment detection UI +- Surfaces issues in Error List window +- Provides menu items in Tools > MAUI submenu + +--- + +## 2. VS Code Integration + +### Status Bar Item + +Always visible indicator of MAUI environment health: + +``` +$(check-circle) MAUI Ready ← Green when healthy +$(warning) MAUI: 2 issues ← Yellow with issue count +$(error) MAUI: Setup Required ← Red when critical +``` + +**Click Action**: Opens "MAUI Environment" panel + +### Environment Panel + +``` +┌────────────────────────────────────────────────────────────┐ +│ MAUI ENVIRONMENT [Refresh] │ +├────────────────────────────────────────────────────────────┤ +│ │ +│ .NET SDK │ +│ ├── ✓ .NET SDK 9.0.100 │ +│ └── ✓ MAUI Workload 9.0.0 │ +│ │ +│ Android │ +│ ├── ✓ Android SDK (/Users/dev/Android/sdk) │ +│ ├── ✓ Build Tools 34.0.0 │ +│ ├── ⚠ Emulator not running [Start] │ +│ └── ✓ AVD: Pixel_5_API_34 │ +│ │ +│ iOS / macOS (Xcode 16.0) │ +│ ├── ✓ iOS 18.0 Runtime │ +│ ├── ✓ iPhone 16 Pro Simulator │ +│ └── ⚠ macOS 15.0 Runtime missing [Install] │ +│ │ +│ ─────────────────────────────────────────────────────────│ +│ [Fix All Issues] │ +└────────────────────────────────────────────────────────────┘ +``` + +**States**: +- ✓ Green checkmark: Component healthy +- ⚠ Yellow warning: Non-critical issue, fixable +- ✖ Red X: Critical issue, blocks development +- [Action]: Inline fix button + +### Fix Progress Dialog + +``` +┌────────────────────────────────────────────────────────────┐ +│ Setting up MAUI Environment │ +├────────────────────────────────────────────────────────────┤ +│ │ +│ ✓ Installing Android SDK │ +│ ✓ Installing build-tools;34.0.0 │ +│ ● Installing system-images;android-34;google_apis;x86_64 │ +│ ████████████░░░░░░░░░░░░░░░░░░░░░░ 45% (1.2 GB/2.6 GB)│ +│ ○ Creating AVD Pixel_5_API_34 │ +│ ○ Verifying setup │ +│ │ +│ ─────────────────────────────────────────────────────────│ +│ [Cancel] ETA: 3 min │ +└────────────────────────────────────────────────────────────┘ +``` + +### Fix Failed Dialog + +When a fix operation fails: + +``` +┌────────────────────────────────────────────────────────────┐ +│ ✖ Fix Failed │ +├────────────────────────────────────────────────────────────┤ +│ │ +│ Unable to install Android SDK automatically. │ +│ │ +│ Error: Connection reset while downloading from │ +│ dl.google.com (E4001) │ +│ │ +│ Attempted: │ +│ • Retry download (3 times) │ +│ • Clear download cache │ +│ │ +│ This may be caused by: │ +│ • Corporate proxy/firewall blocking Google domains │ +│ • Network connectivity issues │ +│ • SSL inspection interfering with downloads │ +│ │ +│ ─────────────────────────────────────────────────────────│ +│ [Ask Copilot for Help] [View Logs] [Retry] [Cancel] │ +└────────────────────────────────────────────────────────────┘ +``` + +**"Ask Copilot for Help" Flow**: + +1. User clicks button or types `/maui-help` in Copilot Chat +2. Extension sends diagnostic context to Copilot +3. Copilot receives structured data + conversation prompt: + +``` +The MAUI Dev Tools detected an issue it couldn't fix automatically. + +**Issue**: Android SDK installation failed (E4001 - Connection reset) +**Environment**: macOS 15.0, corporate network with proxy +**Attempted**: 3 download retries, cache clear + +The diagnostic bundle is attached. Please help the user resolve this issue. +Common causes for this error include proxy configuration, firewall rules, +or SSL inspection. Ask clarifying questions if needed. +``` + +4. Copilot engages in conversational troubleshooting +5. Copilot can suggest manual steps or request tool actions with user approval + +--- + +## 3. Visual Studio Integration + +### Tools Menu + +``` +Tools +├── MAUI +│ ├── Check Environment... Ctrl+Shift+M, E +│ ├── Fix Environment Issues... Ctrl+Shift+M, F +│ ├── ───────────────────────── +│ ├── Android +│ │ ├── SDK Manager... +│ │ ├── AVD Manager... +│ │ └── Device Log... +│ ├── iOS Simulators... +│ └── ───────────────────────── +│ └── Diagnostic Bundle... +``` + +### Error List Integration + +Issues detected by `dotnet maui doctor` appear in Visual Studio's Error List window: + +| Severity | Code | Description | Project | +|----------|------|-------------|---------| +| ⚠️ Warning | MAUI001 | Android SDK build-tools outdated | Solution | +| ❌ Error | MAUI002 | iOS runtime 18.0 not installed | Solution | + +Double-clicking an item opens the fix dialog. + +### Output Window + +Detailed logs available in Output window under "MAUI Dev Tools" pane: + +``` +[15:32:01] Running environment check... +[15:32:02] ✓ .NET SDK 9.0.100 found +[15:32:02] ✓ MAUI workload installed +[15:32:03] ✗ Android SDK not found at expected locations +[15:32:03] Checked: ANDROID_HOME, ANDROID_SDK_ROOT, ~/Library/Android/sdk +[15:32:03] Environment check complete: 1 error, 0 warnings +``` + +--- + +## 4. Common UI Patterns + +### Interactive Prompting + +When running in interactive mode (terminal), the tool prompts for missing information: + +**Example: AVD Creation with Missing Parameters**: +``` +$ dotnet maui android avd create + +? AVD name: My_Pixel_5 + +? Select device profile: + ❯ Pixel 5 (1080x2340, 440dpi) + Pixel 6 (1080x2400, 411dpi) + Pixel 7 Pro (1440x3120, 512dpi) + (more...) + +? Select system image: + ❯ android-34 | Google APIs | x86_64 (recommended) + android-34 | Google Play | x86_64 + android-33 | Google APIs | x86_64 + (more...) + +Creating AVD 'My_Pixel_5'... done +``` + +**Non-Interactive Mode**: +``` +$ dotnet maui android avd create --non-interactive +Error: --name is required in non-interactive mode +``` + +**Example: Large Download Confirmation**: +``` +$ dotnet maui doctor --fix + +The following will be installed: + • system-images;android-34;google_apis;x86_64 (2.6 GB) + • iOS 18.0 Runtime (8.1 GB) + +Total download size: 10.7 GB + +? Proceed? [Y/n] +``` + +### Permission Prompt (AI Agent) + +When an AI agent requests a modification: + +``` +┌─────────────────────────────────────────────────────────────┐ +│ AI Agent Request │ +│ "Install Android SDK build-tools" │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ The AI assistant wants to install: │ +│ • build-tools;34.0.0 (52 MB) │ +│ │ +│ This will modify your Android SDK installation. │ +│ │ +│ [Allow] [Allow Once] [Deny] │ +│ │ +│ □ Remember this choice for this session │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Progress Notification + +For long-running operations, IDEs show progress: + +**VS Code**: Notification toast with progress bar +**Visual Studio**: Status bar progress indicator + Output window details + +Progress updates include: +- Current operation name +- Percentage complete (when determinable) +- Bytes downloaded / total (for downloads) +- ETA (estimated time remaining) +- Cancel button diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 94608678e3bd..7c5e3addb7c6 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.0-draft +**Version**: 2.1-draft **Status**: Proposal **Last Updated**: 2026-02-04 @@ -31,10 +31,20 @@ --- +## Related Documents + +| Document | Description | +|----------|-------------| +| [AI Agent Integration](./maui-devtools-ai-integration.md) | Copilot integration, permission model, MCP tools | +| [IDE Integration](./maui-devtools-ide-integration.md) | VS Code and Visual Studio UI flows | + +--- + ## Revision History | Version | Date | Changes | |---------|------|---------| +| 2.1-draft | 2026-02-04 | **Document restructuring**: Extracted AI integration and IDE integration to separate documents; Removed JSON-RPC API section (use CLI with `--json` instead) | | 2.0-draft | 2026-02-04 | **Major revision from multi-model review**: Added DP3 (stateless-first), DP4 (machine-first output); Added Error Contract Specification (§7.9); Added Bootstrap State Machine (§5.6) with JDK installation; Clarified deploy vs run semantics; Added `--json`, `--dry-run`, `--ci` flags; Added JDK management commands; Defined default installation paths per platform; Added Implementation References (§19) with AndroidSdk.Tools, AppleDev.Tools, MAUI.Sherpa, and official SDK targets | | 1.5-draft | 2026-02-04 | Added: Design Principles (DP1: delegate to native tools, DP2: consolidate VS repositories); added NG6 for no custom download logic | | 1.4-draft | 2026-02-03 | Changed CLI to `dotnet maui` pattern; kept `apple` for Apple platform commands; added `windows` subcommand | @@ -305,35 +315,9 @@ dotnet maui doctor --json ### 4.4 AI Agent Invoked from IDE -**Profile**: Copilot agent assisting a developer with a build error. +> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed AI agent personas, Copilot-assisted troubleshooting, and permission model. -**Journey**: -1. User asks: "My Android build is failing with 'SDK not found'" -2. Agent invokes: `dotnet maui doctor --json --platform android` -3. Agent receives structured response: - ```json - { - "status": "unhealthy", - "issues": [ - { - "id": "ANDROID_SDK_MISSING", - "severity": "error", - "message": "Android SDK not found", - "fixable": true, - "fix_command": "dotnet maui android sdk install --recommended" - } - ] - } - ``` -4. Agent explains the issue and asks: "Would you like me to install the Android SDK?" -5. User confirms; agent invokes fix command with permission gate -6. Agent verifies fix by re-running doctor - -**Key Requirements**: -- Structured JSON output with stable schema -- Fix commands included in diagnostic output -- Permission gates for destructive operations -- Correlation IDs for tracing +**Summary**: AI agents (GitHub Copilot, IDE assistants) can invoke `dotnet maui doctor --json` to diagnose environment issues, receive structured responses with fix commands, and execute fixes with user permission gates. --- @@ -809,43 +793,9 @@ User: maui doctor --json ### 7.4 IDE Extension Integration -#### VS Code Extension - -``` -┌─────────────────────────────────────────────────────────────┐ -│ VS Code │ -├─────────────────────────────────────────────────────────────┤ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ MAUI Extension │ │ -│ ├──────────────────────────────────────────────────────┤ │ -│ │ • Environment Status Bar Item │ │ -│ │ • "MAUI: Setup Environment" command │ │ -│ │ • Problems panel integration │ │ -│ │ • Quick Fix code actions │ │ -│ └─────────────────────┬────────────────────────────────┘ │ -│ │ │ -│ │ JSON-RPC (stdio) │ -│ ▼ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ MAUI Dev Tools Client │ │ -│ │ (spawned as child process) │ │ -│ └──────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ -``` - -**Extension Responsibilities**: -1. Spawn `maui` process with `--rpc` flag on activation -2. Send `doctor.status` request on workspace open -3. Display issues in Problems panel -4. Register "MAUI: Setup Environment" command -5. Show progress notifications during fixes - -#### Visual Studio Extension - -- Uses named pipes for faster communication -- Integrates with Visual Studio's environment detection UI -- Surfaces issues in Error List window -- Provides menu items in Tools > MAUI submenu +> **See [IDE Integration](./maui-devtools-ide-integration.md)** for detailed VS Code and Visual Studio UI flows, status panels, and menu integrations. + +**Summary**: IDEs spawn `dotnet maui` as a child process, invoke `dotnet maui doctor --json` on workspace open, display issues in their problems/error list panels, and provide commands for environment setup with progress notifications. ### 7.5 Stateless-First Architecture with Optional Daemon @@ -1306,472 +1256,7 @@ All commands follow a consistent exit code scheme: | `dotnet maui apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | | `dotnet maui config set` | Set configuration | ``, `` | Confirmation | 0=success, 2=error | -### 8.2 JSON-RPC API - -**Transport**: JSON-RPC 2.0 over stdio (primary) or named pipes/Unix sockets (daemon mode) - -**Transport Details**: -- **stdio mode**: Newline-delimited JSON (NDJSON) — one JSON object per line, requests on stdin, responses on stdout -- **Named pipes** (Windows): `\\.\pipe\MauiDevTools` -- **Unix sockets** (macOS): `/tmp/maui-devtools.sock` -- **Line protocol**: Each message is a complete JSON object followed by `\n` -- **Encoding**: UTF-8 - -**Why JSON-RPC**: -- Language-agnostic (works with any IDE/agent) -- Simple request/response model -- Well-defined error handling -- Supports notifications for streaming (logs, progress) -- Familiar to IDE developers (same as LSP) - -#### Method Reference - -##### doctor.status - -Check environment health. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 1, - "method": "doctor.status", - "params": { - "platforms": ["android", "ios"] - } -} -``` - -**Response**: -```json -{ - "jsonrpc": "2.0", - "id": 1, - "result": { - "correlation_id": "abc-123", - "status": "unhealthy", - "checks": [ - { - "category": "dotnet", - "name": ".NET SDK", - "status": "ok", - "details": { "version": "9.0.100", "path": "/usr/local/share/dotnet" } - }, - { - "category": "dotnet", - "name": "MAUI Workload", - "status": "ok", - "details": { "version": "9.0.0" } - }, - { - "category": "android", - "name": "Android SDK", - "status": "error", - "message": "Android SDK not found", - "issue": { - "id": "ANDROID_SDK_MISSING", - "severity": "error", - "fixable": true, - "fix": { - "method": "doctor.fix", - "params": { "issue_id": "ANDROID_SDK_MISSING" } - } - } - } - ], - "summary": { - "total": 8, - "ok": 5, - "warning": 1, - "error": 2 - } - } -} -``` - -##### doctor.fix - -Fix a specific issue or all fixable issues. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 2, - "method": "doctor.fix", - "params": { - "issue_id": "ANDROID_SDK_MISSING", - "confirm": true - } -} -``` - -**Response** (streaming progress via notifications): -```json -{ - "jsonrpc": "2.0", - "method": "progress", - "params": { - "correlation_id": "abc-123", - "operation": "android.sdk.install", - "status": "running", - "message": "Downloading Android SDK...", - "percent": 45 - } -} -``` - -**Final Response**: -```json -{ - "jsonrpc": "2.0", - "id": 2, - "result": { - "correlation_id": "abc-123", - "status": "success", - "fixed": ["ANDROID_SDK_MISSING"] - } -} -``` - -##### device.list - -List all available devices. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 3, - "method": "device.list", - "params": { - "platform": "android" - } -} -``` - -**Response**: -```json -{ - "jsonrpc": "2.0", - "id": 3, - "result": { - "devices": [ - { - "id": "emulator-5554", - "name": "Pixel_5_API_34", - "platform": "android", - "type": "emulator", - "state": "online", - "os_version": "14", - "details": { - "avd_name": "Pixel_5_API_34", - "api_level": 34 - } - }, - { - "id": "R58M32XXXXX", - "name": "Galaxy S21", - "platform": "android", - "type": "physical", - "state": "online", - "os_version": "13" - } - ] - } -} -``` - -##### device.screenshot - -Capture screenshot from device. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 4, - "method": "device.screenshot", - "params": { - "device_id": "emulator-5554", - "output_path": "/tmp/screenshot.png", - "wait_ms": 500 - } -} -``` - -**Response**: -```json -{ - "jsonrpc": "2.0", - "id": 4, - "result": { - "path": "/tmp/screenshot.png", - "width": 1080, - "height": 2400, - "format": "png" - } -} -``` - -##### android.sdk.list - -List installed Android SDK packages. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 5, - "method": "android.sdk.list", - "params": {} -} -``` - -**Response**: -```json -{ - "jsonrpc": "2.0", - "id": 5, - "result": { - "sdk_path": "/Users/dev/Library/Android/sdk", - "packages": [ - { - "path": "build-tools;34.0.0", - "version": "34.0.0", - "description": "Android SDK Build-Tools 34", - "location": "build-tools/34.0.0" - }, - { - "path": "platforms;android-34", - "version": "2", - "description": "Android SDK Platform 34", - "location": "platforms/android-34" - } - ] - } -} -``` - -##### android.sdk.install - -Install Android SDK package. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 6, - "method": "android.sdk.install", - "params": { - "packages": ["platforms;android-34", "build-tools;34.0.0"], - "accept_licenses": true - } -} -``` - -##### android.avd.create - -Create Android Virtual Device. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 7, - "method": "android.avd.create", - "params": { - "name": "Pixel_5_API_34", - "device": "pixel_5", - "system_image": "system-images;android-34;google_apis;x86_64", - "force": false - } -} -``` - -##### android.avd.start - -Start Android emulator. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 8, - "method": "android.avd.start", - "params": { - "name": "Pixel_5_API_34", - "wait_for_boot": true, - "cold_boot": false, - "timeout_seconds": 120 - } -} -``` - -**Response**: -```json -{ - "jsonrpc": "2.0", - "id": 8, - "result": { - "device_id": "emulator-5554", - "state": "online", - "boot_time_ms": 45000 - } -} -``` - -##### apple.simulator.list - -List iOS simulators. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 9, - "method": "apple.simulator.list", - "params": { - "runtime": "iOS 18.0", - "device_type": "iPhone", - "state": "booted" - } -} -``` - -**Response**: -```json -{ - "jsonrpc": "2.0", - "id": 9, - "result": { - "simulators": [ - { - "udid": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890", - "name": "iPhone 16 Pro", - "state": "booted", - "runtime": { - "identifier": "com.apple.CoreSimulator.SimRuntime.iOS-18-0", - "name": "iOS 18.0", - "version": "18.0" - }, - "device_type": { - "identifier": "com.apple.CoreSimulator.SimDeviceType.iPhone-16-Pro", - "name": "iPhone 16 Pro" - } - } - ] - } -} -``` - -##### apple.simulator.boot - -Boot iOS simulator. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 10, - "method": "apple.simulator.boot", - "params": { - "udid": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890" - } -} -``` - -##### apple.simulator.create - -Create iOS simulator. - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 11, - "method": "apple.simulator.create", - "params": { - "name": "Test iPhone 16", - "device_type": "com.apple.CoreSimulator.SimDeviceType.iPhone-16-Pro", - "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-18-0" - } -} -``` - -##### logs.stream - -Stream logs from device (uses JSON-RPC notifications). - -**Request**: -```json -{ - "jsonrpc": "2.0", - "id": 12, - "method": "logs.stream", - "params": { - "device_id": "emulator-5554", - "filter": "Microsoft.Maui" - } -} -``` - -**Notifications** (streamed): -```json -{ - "jsonrpc": "2.0", - "method": "logs.entry", - "params": { - "stream_id": "log-123", - "timestamp": "2026-02-03T17:45:00.123Z", - "level": "info", - "tag": "Microsoft.Maui.Controls", - "message": "Application started" - } -} -``` - -#### State Machine for Long-Running Operations - -``` - ┌─────────┐ - │ Queued │ - └────┬────┘ - │ start - ▼ - ┌────────────────────────────────────────┐ - │ Running │ - │ • Emits progress notifications │ - │ • Can be canceled │ - └───────┬─────────────┬─────────────┬────┘ - │ │ │ - success failure cancel - │ │ │ - ▼ ▼ ▼ - ┌───────────┐ ┌───────────┐ ┌───────────┐ - │ Succeeded │ │ Failed │ │ Canceled │ - └───────────┘ └───────────┘ └───────────┘ -``` - -**Progress Notification Schema**: -```json -{ - "jsonrpc": "2.0", - "method": "progress", - "params": { - "correlation_id": "string", - "operation_id": "string", - "status": "queued | running | succeeded | failed | canceled", - "message": "string", - "percent": 0-100, - "bytes_downloaded": 123456, - "bytes_total": 1000000, - "eta_seconds": 30 - } -} -``` - -### 8.3 Capabilities Model +### 8.2 Capabilities Model | Command | Windows | macOS | Requires Elevation | |---------|---------|-------|-------------------| @@ -1799,85 +1284,7 @@ Stream logs from device (uses JSON-RPC notifications). ### 9.1 IDE UI Flows -#### VS Code: Environment Status - -**Status Bar Item** (always visible): -``` -$(check-circle) MAUI Ready ← Green when healthy -$(warning) MAUI: 2 issues ← Yellow with issue count -$(error) MAUI: Setup Required ← Red when critical -``` - -**Click Action**: Opens "MAUI Environment" panel - -#### VS Code: Environment Panel - -``` -┌────────────────────────────────────────────────────────────┐ -│ MAUI ENVIRONMENT [Refresh] │ -├────────────────────────────────────────────────────────────┤ -│ │ -│ .NET SDK │ -│ ├── ✓ .NET SDK 9.0.100 │ -│ └── ✓ MAUI Workload 9.0.0 │ -│ │ -│ Android │ -│ ├── ✓ Android SDK (/Users/dev/Android/sdk) │ -│ ├── ✓ Build Tools 34.0.0 │ -│ ├── ⚠ Emulator not running [Start] │ -│ └── ✓ AVD: Pixel_5_API_34 │ -│ │ -│ iOS / macOS (Xcode 16.0) │ -│ ├── ✓ iOS 18.0 Runtime │ -│ ├── ✓ iPhone 16 Pro Simulator │ -│ └── ⚠ macOS 15.0 Runtime missing [Install] │ -│ │ -│ ─────────────────────────────────────────────────────────│ -│ [Fix All Issues] │ -└────────────────────────────────────────────────────────────┘ -``` - -**States**: -- ✓ Green checkmark: Component healthy -- ⚠ Yellow warning: Non-critical issue, fixable -- ✖ Red X: Critical issue, blocks development -- [Action]: Inline fix button - -#### VS Code: Fix Progress - -``` -┌────────────────────────────────────────────────────────────┐ -│ Setting up MAUI Environment │ -├────────────────────────────────────────────────────────────┤ -│ │ -│ ✓ Installing Android SDK │ -│ ✓ Installing build-tools;34.0.0 │ -│ ● Installing system-images;android-34;google_apis;x86_64 │ -│ ████████████░░░░░░░░░░░░░░░░░░░░░░ 45% (1.2 GB/2.6 GB)│ -│ ○ Creating AVD Pixel_5_API_34 │ -│ ○ Verifying setup │ -│ │ -│ ─────────────────────────────────────────────────────────│ -│ [Cancel] ETA: 3 min │ -└────────────────────────────────────────────────────────────┘ -``` - -#### Visual Studio: Tools Menu Integration - -``` -Tools -├── MAUI -│ ├── Check Environment... Ctrl+Shift+M, E -│ ├── Fix Environment Issues... Ctrl+Shift+M, F -│ ├── ───────────────────────── -│ ├── Android -│ │ ├── SDK Manager... -│ │ ├── AVD Manager... -│ │ └── Device Log... -│ ├── iOS Simulators... -│ └── ───────────────────────── -│ └── Diagnostic Bundle... -``` +> **See [IDE Integration](./maui-devtools-ide-integration.md)** for detailed VS Code status bars, environment panels, fix progress dialogs, and Visual Studio menu integration. ### 9.2 Interactive Prompting @@ -1925,214 +1332,14 @@ Total download size: 10.7 GB ### 9.3 Copilot-Assisted Troubleshooting -When automated fixes fail or issues are too complex for deterministic resolution, the tool can escalate to GitHub Copilot for AI-assisted troubleshooting. This provides a graceful fallback that combines structured diagnostics with conversational problem-solving. - -#### Escalation Triggers +> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed Copilot escalation triggers, context handoff schema, MCP tool integration, and example conversations. -The tool escalates to Copilot when: - -| Trigger | Example | Escalation Action | -|---------|---------|-------------------| -| Fix failed | SDK install fails with network error | Offer "Ask Copilot for help" | -| Unknown issue | Unrecognized error code from `adb` | Auto-suggest Copilot assistance | -| Complex diagnosis | Multiple interrelated issues | Recommend Copilot review | -| User request | User clicks "Get AI Help" | Open Copilot with context | - -#### Context Handoff - -When escalating to Copilot, the tool provides structured context: - -```json -{ - "escalation_type": "fix_failed", - "tool_version": "1.2.0", - "doctor_report": { /* full doctor.status output */ }, - "failed_operation": { - "command": "android.sdk.install", - "params": { "packages": ["platforms;android-34"] }, - "error": { - "code": "E4001", - "message": "Download failed: Connection reset", - "details": "Failed after 3 retries to dl.google.com" - } - }, - "environment": { - "os": "macOS 15.0", - "proxy_configured": true, - "network_type": "corporate" - }, - "attempted_fixes": [ - { "action": "retry_download", "result": "failed" }, - { "action": "clear_cache", "result": "failed" } - ] -} -``` - -#### IDE Integration (VS Code) - -``` -┌────────────────────────────────────────────────────────────┐ -│ ✖ Fix Failed │ -├────────────────────────────────────────────────────────────┤ -│ │ -│ Unable to install Android SDK automatically. │ -│ │ -│ Error: Connection reset while downloading from │ -│ dl.google.com (E4001) │ -│ │ -│ Attempted: │ -│ • Retry download (3 times) │ -│ • Clear download cache │ -│ │ -│ This may be caused by: │ -│ • Corporate proxy/firewall blocking Google domains │ -│ • Network connectivity issues │ -│ • SSL inspection interfering with downloads │ -│ │ -│ ─────────────────────────────────────────────────────────│ -│ [Ask Copilot for Help] [View Logs] [Retry] [Cancel] │ -└────────────────────────────────────────────────────────────┘ -``` - -**"Ask Copilot for Help" Flow**: - -1. User clicks button or types `/maui-help` in Copilot Chat -2. Extension sends diagnostic context to Copilot -3. Copilot receives structured data + conversation prompt: - -``` -The MAUI Dev Tools detected an issue it couldn't fix automatically. - -**Issue**: Android SDK installation failed (E4001 - Connection reset) -**Environment**: macOS 15.0, corporate network with proxy -**Attempted**: 3 download retries, cache clear - -The diagnostic bundle is attached. Please help the user resolve this issue. -Common causes for this error include proxy configuration, firewall rules, -or SSL inspection. Ask clarifying questions if needed. -``` - -4. Copilot engages in conversational troubleshooting -5. Copilot can suggest manual steps or request tool actions with user approval - -#### CLI Integration - -```bash -$ maui doctor --fix -... -✖ Failed to install Android SDK - -Error: Connection reset while downloading (E4001) - -Attempted fixes: - • Retry download (3 times) - failed - • Clear download cache - failed - -Would you like to get help from Copilot? [Y/n] y - -Opening Copilot with diagnostic context... -Run: gh copilot explain "MAUI SDK install failure E4001" - -Or copy this diagnostic summary: - maui diagnostic-bundle --output /tmp/maui-diag.zip - gh copilot explain --file /tmp/maui-diag.zip -``` - -#### Copilot Tool Actions (MCP Integration) - -When running as an MCP server, the tool exposes actions that Copilot can invoke (with user approval): - -```json -{ - "tools": [ - { - "name": "maui_doctor_status", - "description": "Check MAUI development environment health", - "requires_approval": false - }, - { - "name": "maui_doctor_fix", - "description": "Attempt to fix detected environment issues", - "requires_approval": true - }, - { - "name": "maui_diagnostic_bundle", - "description": "Generate diagnostic bundle for troubleshooting", - "requires_approval": false - }, - { - "name": "maui_config_set", - "description": "Update tool configuration (e.g., proxy settings)", - "requires_approval": true - } - ] -} -``` - -**Example Copilot Conversation**: - -``` -User: My MAUI Android build keeps failing with SDK errors - -Copilot: Let me check your MAUI environment. - [Calling maui_doctor_status...] - - I found several issues: - 1. ❌ Android SDK not found at expected location - 2. ⚠️ ANDROID_HOME environment variable not set - - It looks like the Android SDK may not be installed, or it's - installed in a non-standard location. - - Would you like me to: - a) Install the Android SDK to the default location - b) Help you configure ANDROID_HOME to point to an existing SDK - -User: Install it please - -Copilot: I'll install the Android SDK with recommended components. - [Requesting approval for maui_doctor_fix...] - - ✓ User approved - - [Calling maui_doctor_fix with issue_id="ANDROID_SDK_MISSING"...] - - ✓ Android SDK installed successfully - ✓ ANDROID_HOME configured - - Your environment is now ready. Try building again! -``` - -#### Fallback Hierarchy - -``` -┌─────────────────────────────────────────────────────────────┐ -│ 1. Automated Fix (maui doctor --fix) │ -│ Tool attempts deterministic fix based on known patterns │ -├─────────────────────────────────────────────────────────────┤ -│ 2. Guided Manual Fix │ -│ Tool provides step-by-step instructions for user │ -├─────────────────────────────────────────────────────────────┤ -│ 3. Copilot-Assisted Troubleshooting │ -│ AI helps diagnose complex/unknown issues conversationally│ -├─────────────────────────────────────────────────────────────┤ -│ 4. Community/Support Escalation │ -│ Link to GitHub issues, docs, or support channels │ -└─────────────────────────────────────────────────────────────┘ -``` - -#### Privacy Considerations - -When escalating to Copilot: - -- **Opt-in**: User must explicitly request Copilot assistance -- **Data minimization**: Only relevant diagnostic data shared -- **Redaction**: PII (paths, device names) redacted per §10.3 rules -- **Transparency**: User can view exact data being shared before sending -- **Local option**: `--offline-diagnosis` generates report without sending to Copilot +**Summary**: When automated fixes fail, the tool can escalate to GitHub Copilot with structured diagnostic context. The fallback hierarchy is: Automated Fix → Guided Manual Fix → Copilot-Assisted Troubleshooting → Community/Support Escalation. --- +## 10. Telemetry & Diagnostics + ### 10.1 Telemetry Events | Event | Data Collected | Purpose | @@ -2234,100 +1441,11 @@ All downloads are verified before installation: - `developer.apple.com` (Xcode components) - `aka.ms` / `dotnetcli.azureedge.net` (.NET components) -### 11.3 AI Agent Permission Gates - -When invoked by an AI agent, certain operations require explicit user confirmation: - -| Operation | Permission Required | Confirmation UI | -|-----------|---------------------|-----------------| -| `doctor.status` | None | — | -| `device.list` | None | — | -| `device.screenshot` | `device.capture` | IDE prompt | -| `doctor.fix` | `environment.modify` | IDE prompt with details | -| `android.sdk.install` | `environment.modify` | IDE prompt with package list | -| `android.avd.create` | `device.create` | IDE prompt | -| `logs.stream` | `device.logs` | IDE prompt | - -**Permission Flow**: -``` -┌─────────────────────────────────────────────────────────────┐ -│ AI Agent Request │ -│ "Install Android SDK build-tools" │ -├─────────────────────────────────────────────────────────────┤ -│ │ -│ The AI assistant wants to install: │ -│ • build-tools;34.0.0 (52 MB) │ -│ │ -│ This will modify your Android SDK installation. │ -│ │ -│ [Allow] [Allow Once] [Deny] │ -│ │ -│ □ Remember this choice for this session │ -└─────────────────────────────────────────────────────────────┘ -``` - -### 11.4 Sandbox Boundaries - -AI agent calls are sandboxed: -- Cannot access arbitrary file system paths -- Cannot execute arbitrary commands -- Limited to defined API surface -- All actions logged with agent identifier - -**Safe Paths** (agents may read/write only within): -- Project root directory -- Temp directory (`$TMPDIR` / `%TEMP%`) -- SDK directories (Android SDK, Xcode Developer directory) -- Tool cache directory (`~/.maui-devtools/`) - -**Path Validation**: -- Reject paths containing `..` -- Reject absolute paths outside safe paths -- Validate in CLI Layer before dispatching to services - -### 11.5 Permission Storage - -| Context | Storage Location | Lifetime | -|---------|------------------|----------| -| IDE Session | In-memory | Until IDE closes | -| Terminal | Per-command | Single invocation | -| CI | Environment variable `MAUI_DEVTOOLS_ALLOW_MODIFY=1` | Pipeline run | -| Persistent | `~/.config/maui-devtools/permissions.json` | Until revoked | - -**Persistent Permission Schema**: -```json -{ - "schema_version": 1, - "agents": { - "github-copilot": { - "environment.modify": "allow", - "device.create": "prompt", - "device.capture": "allow" - }, - "default": { - "environment.modify": "prompt", - "device.create": "prompt", - "device.capture": "prompt" - } - } -} -``` - -**Permission Values**: -- `allow`: Permitted without prompt -- `prompt`: Requires user confirmation each time -- `deny`: Blocked (agent receives permission error) +### 11.3 AI Agent Security -### 11.6 Elevation Handling +> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed permission gates, sandbox boundaries, permission storage schema, and elevation handling for AI agents. -When an operation requires elevation: - -| Platform | Mechanism | User Experience | -|----------|-----------|-----------------| -| macOS | `sudo` prompt in terminal; Authorization Services in GUI | System password dialog | -| Windows | UAC prompt | Standard elevation dialog | - -**For AI Agents**: Elevated operations cannot be auto-approved. Agent receives error `E5001` with message explaining elevation requirement. User must run command manually or through IDE's privileged execution path. +**Summary**: AI agent calls are sandboxed with permission gates requiring user confirmation for modifications. Safe paths are restricted to project root, temp, SDK directories, and tool cache. Elevated operations cannot be auto-approved by agents. --- @@ -2457,35 +1575,9 @@ maui deploy --device emulator-5554 ### 12.5 AI Agent Considerations -The SDK spec explicitly mentions AI agents: - -> "This has become more relevant in the AI era, as someone is going to expect AIs in 'agent mode' to build and run their app." - -MAUI DevTools is designed with AI agents as first-class consumers: - -| Requirement | How DevTools Addresses It | -|-------------|---------------------------| -| Structured output | All commands support `--json` with stable schema | -| Discoverability | `--list-devices` provides machine-parseable device list | -| Non-interactive | `--non-interactive` mode with helpful error messages | -| Deterministic | Same inputs produce same outputs; idempotent operations | -| Permission gates | Explicit confirmation for modifications (see §11.3) | +> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed AI agent design principles, workflow examples, and error contract specifications. -**AI Agent Workflow Example**: - -```python -# 1. Discover available devices -devices = run("maui device list --platform android --json") - -# 2. Select appropriate device (first online emulator) -device = next(d for d in devices if d["status"] == "Online" and d["type"] == "Emulator") - -# 3. Build and deploy (with user confirmation via IDE) -run(f"maui deploy --device {device['id']} --project ./MyApp.csproj") - -# 4. Capture screenshot for verification -run(f"maui device screenshot --device {device['id']} --output ./screenshot.png") -``` +**Summary**: MAUI DevTools is designed with AI agents as first-class consumers. All commands support `--json` for structured output, `--non-interactive` mode, and `--dry-run` for predictable behavior. Permission gates ensure user confirmation for modifications. ### 12.6 Plugin Model for Platform Providers From 4360a1bf43558b066ae8fe9ba80395d5c2519b51 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 4 Feb 2026 19:49:03 +0000 Subject: [PATCH 10/34] Remove some information --- docs/design/maui-devtools-spec.md | 974 ++---------------------------- 1 file changed, 42 insertions(+), 932 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 7c5e3addb7c6..be0a8f9734e7 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.1-draft +**Version**: 2.5-draft **Status**: Proposal **Last Updated**: 2026-02-04 @@ -18,40 +18,7 @@ 8. [Public API Surface](#8-public-api-surface) 9. [User Experience](#9-user-experience) 10. [Telemetry & Diagnostics](#10-telemetry--diagnostics) -11. [Security Model](#11-security-model) -12. [Extensibility](#12-extensibility) -13. [Testing Strategy](#13-testing-strategy) -14. [Rollout Plan](#14-rollout-plan) -15. [Open Questions & Risks](#15-open-questions--risks) -16. [Appendix](#16-appendix) -17. [MVP vs vNext Features](#17-mvp-vs-vnext-features) -18. [Acceptance Criteria](#18-acceptance-criteria) -19. [Implementation References & Prior Art](#19-implementation-references--prior-art) -20. [Future Subcommands (Roadmap)](#20-future-subcommands-roadmap) - ---- - -## Related Documents - -| Document | Description | -|----------|-------------| -| [AI Agent Integration](./maui-devtools-ai-integration.md) | Copilot integration, permission model, MCP tools | -| [IDE Integration](./maui-devtools-ide-integration.md) | VS Code and Visual Studio UI flows | - ---- - -## Revision History - -| Version | Date | Changes | -|---------|------|---------| -| 2.1-draft | 2026-02-04 | **Document restructuring**: Extracted AI integration and IDE integration to separate documents; Removed JSON-RPC API section (use CLI with `--json` instead) | -| 2.0-draft | 2026-02-04 | **Major revision from multi-model review**: Added DP3 (stateless-first), DP4 (machine-first output); Added Error Contract Specification (§7.9); Added Bootstrap State Machine (§5.6) with JDK installation; Clarified deploy vs run semantics; Added `--json`, `--dry-run`, `--ci` flags; Added JDK management commands; Defined default installation paths per platform; Added Implementation References (§19) with AndroidSdk.Tools, AppleDev.Tools, MAUI.Sherpa, and official SDK targets | -| 1.5-draft | 2026-02-04 | Added: Design Principles (DP1: delegate to native tools, DP2: consolidate VS repositories); added NG6 for no custom download logic | -| 1.4-draft | 2026-02-03 | Changed CLI to `dotnet maui` pattern; kept `apple` for Apple platform commands; added `windows` subcommand | -| 1.3-draft | 2026-02-03 | Added: Copilot-assisted troubleshooting (§9.3), MCP tool integration, escalation hierarchy, context handoff schema | -| 1.2-draft | 2026-02-03 | Added: MSBuild integration alignment with dotnet/sdk spec, `dotnet run` pipeline integration, `--list-devices` convention, deploy step, AI agent considerations | -| 1.1-draft | 2026-02-03 | Added: Exit code standardization, Windows management, offline/proxy support, container environments, migration strategy, concurrency model, permission storage, ARM64 considerations | -| 1.0-draft | 2026-02-03 | Initial draft | +11. [MVP vs vNext Features](#11-mvp-vs-vnext-features) --- @@ -118,9 +85,8 @@ This tool eliminates that friction by providing a single, authoritative source f | G1 | Reduce MAUI setup time to under 10 minutes | Time-to-first-build < 10 min for 90% of users | | G2 | Provide a single "doctor" command that identifies all issues | 100% coverage of common setup issues | | G3 | Enable one-click/one-command fixes for detected issues | >80% of issues auto-fixable | -| G4 | Expose structured APIs for IDE and AI agent consumption | JSON-RPC API with stable schema | +| G4 | Expose structured APIs for IDE and AI agent consumption | JSON output with stable schema | | G5 | Support headless operation for CI environments | All commands runnable non-interactively | -| G6 | Unify Android and Apple device/simulator management | Single CLI surface for both platforms | ### Non-Goals @@ -131,7 +97,6 @@ This tool eliminates that friction by providing a single, authoritative source f | NG3 | Linux host support (MVP) | MAUI mobile development requires Windows or macOS | | NG4 | Physical iOS device provisioning | Requires Apple Developer account; out of scope for MVP | | NG5 | Manage Visual Studio installation | VS has its own installer; we detect, not manage | -| NG6 | Implement custom download/installation logic | Delegate to native platform tools; avoid reinventing package management | ### Design Principles @@ -182,19 +147,13 @@ This tool enables **consolidation of existing Visual Studio repositories** that 3. Internal repositories enter maintenance mode 4. After VS release cycle, internal repositories are archived -#### DP3: Stateless-First Architecture - -**The CLI MUST operate statelessly by default.** No background daemon is required for core functionality. +#### DP3: Stateless Architecture -| Mode | When to Use | Characteristics | -|------|-------------|-----------------| -| **Stateless (default)** | CLI invocations, CI/CD, AI agents | Each command reads state, acts, exits; no process coordination | -| **Daemon (optional, v2+)** | IDE performance optimization only | Explicit opt-in via `dotnet maui daemon start` | +**The CLI operates statelessly.** Each command reads state, acts, and exits. **Rationale**: -- Daemon lifecycle (orphaned processes, stale state, port conflicts) is a major source of tooling bugs - Stateless commands are easier to debug, test, and reason about -- AI agents prefer deterministic request/response over managing socket connections +- AI agents prefer deterministic request/response - Performance bottleneck is native tool execution, not process spin-up **State Caching**: @@ -537,36 +496,6 @@ This command: | `NO_DEV_MODE` | Developer Mode disabled | Guide user to enable (requires Settings app) | | `READY` | SDK present, Developer Mode enabled | Operational | -### 5.7 Deploy vs Run Semantics - -**Critical clarification**: The spec distinguishes between deployment operations: - -| Operation | Command | Behavior | Returns | -|-----------|---------|----------|---------| -| **Install Only** | `dotnet maui deploy --install-only` | Copy app to device, do not launch | Exit 0 on success | -| **Launch** | `dotnet maui deploy` | Install and launch app | Exit 0 when app starts | -| **Run to Completion** | `dotnet maui deploy --wait` | Install, launch, wait for exit | App exit code | -| **Debug Attach** | `dotnet maui deploy --debug` | Install, launch with debugger attached | Blocks until detach | - -**Lifecycle Detection**: -The tool MUST detect "app successfully started" per platform: -- **Android**: `adb shell am start` returns 0 + activity launched -- **iOS Simulator**: `xcrun simctl launch` returns 0 + process appears -- **Windows**: Process starts and main window appears - -**App Lifecycle Events** (JSON output): -```json -{ - "operation": "deploy", - "events": [ - { "type": "installing", "timestamp": "..." }, - { "type": "installed", "timestamp": "..." }, - { "type": "launching", "timestamp": "..." }, - { "type": "launched", "pid": 12345, "timestamp": "..." }, - { "type": "exited", "exit_code": 0, "timestamp": "..." } - ] -} - --- ## 6. Non-Functional Requirements @@ -595,9 +524,8 @@ The tool MUST detect "app successfully started" per platform: |----|-------------| | NFR-P1 | `doctor` command must complete in <5s when no network calls needed | | NFR-P2 | Device list must complete in <2s | -| NFR-P3 | Daemon mode must respond to health checks in <100ms | -| NFR-P4 | Downloaded artifacts must be cached locally | -| NFR-P5 | Read operations must use direct file parsing (not CLI wrappers) for performance | +| NFR-P3 | Downloaded artifacts must be cached locally | +| NFR-P4 | Read operations must use direct file parsing (not CLI wrappers) for performance | **Performance Implementation Notes**: - Android SDK detection: Parse `package.xml` and `source.properties` directly instead of invoking `sdkmanager --list` (which has 3-10s JVM startup time) @@ -671,18 +599,18 @@ When emulator/simulator unavailable: │ (Human) │ Extension │ Studio │ (Copilot) │ Pipeline │ └──────┬──────┴──────┬──────┴──────┬──────┴──────┬──────┴────────┬────────┘ │ │ │ │ │ - │ CLI │ JSON-RPC │ JSON-RPC │ JSON-RPC │ CLI - │ │ (stdio) │ (named pipe)│ (stdio) │ + │ CLI │ CLI │ CLI │ CLI │ CLI + │ │ (--json) │ (--json) │ (--json) │ ▼ ▼ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ MAUI Dev Tools Client │ ├─────────────────────────────────────────────────────────────────────────┤ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ CLI Layer │ │ JSON-RPC │ │ Daemon │ │ -│ │ (Parsing) │ │ Server │ │ (Optional) │ │ -│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ CLI Layer │ │ +│ │ (Argument parsing, output formatting, --json support) │ │ +│ └──────────────────────────────┬──────────────────────────────┘ │ +│ │ │ +│ ▼ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ Core Services │ │ │ ├──────────────┬──────────────┬──────────────┬─────────────────┤ │ @@ -715,21 +643,8 @@ When emulator/simulator unavailable: - Parses command-line arguments using `System.CommandLine` - Maps commands to core service calls - Formats output for human consumption (colors, tables, progress bars) -- Entry point: `maui` command - -#### JSON-RPC Server -- Implements JSON-RPC 2.0 over multiple transports: - - **stdio**: For AI agents and simple integrations - - **Named pipes**: For high-performance IDE integration (Windows) - - **Unix domain sockets**: For high-performance IDE integration (macOS) -- Stateless request/response model -- Streaming support for logs and progress - -#### Daemon (Optional) -- Long-running background process for faster IDE interactions -- Maintains cached state (device list, SDK components) -- Auto-starts on first IDE request; auto-terminates after idle timeout -- Not required for CLI usage +- Supports `--json` for machine-readable output +- Entry point: `dotnet maui` command #### Core Services @@ -797,86 +712,16 @@ User: maui doctor --json **Summary**: IDEs spawn `dotnet maui` as a child process, invoke `dotnet maui doctor --json` on workspace open, display issues in their problems/error list panels, and provide commands for environment setup with progress notifications. -### 7.5 Stateless-First Architecture with Optional Daemon - -> **Design Decision (from multi-model review)**: The tool operates statelessly by default. Daemon mode is an optional optimization for IDE performance, NOT a requirement. - -#### Why Stateless-First? - -| Concern | Daemon Problem | Stateless Solution | -|---------|----------------|-------------------| -| Orphaned processes | Daemon crashes, leaves socket locked | No persistent process to orphan | -| Stale state | Daemon caches outdated SDK state | Read fresh state each invocation | -| Multiple IDEs | Port conflicts, duplicate daemons | No coordination needed | -| Debugging | Hidden process state hard to inspect | CLI behavior is fully observable | -| CI/CD | Daemon unnecessary overhead | Clean process per command | - -#### On-Demand Mode (Default) - -| Aspect | Behavior | -|--------|----------| -| Startup | New process per command | -| Latency | ~200ms cold start (acceptable for most use cases) | -| State | Reads from file cache (`~/.maui/cache/`), always current | -| Best for | CI, terminal, scripts, AI agents | - -**File Cache Structure**: -``` -~/.maui/cache/ -├── devices.json # TTL: 30 seconds -├── android-sdk.json # TTL: 5 minutes -├── apple-runtimes.json # TTL: 5 minutes -└── doctor-report.json # TTL: 1 minute -``` - -#### Daemon Mode (Optional, v2+) - -Daemon is an **explicit opt-in** for IDE performance optimization only: - -```bash -# Explicit daemon control -dotnet maui daemon start # Start daemon -dotnet maui daemon stop # Stop daemon -dotnet maui daemon status # Check if running - -# Daemon-aware commands (use daemon if running, fallback to direct) -dotnet maui device list # Uses daemon if available, else direct -``` - -| Aspect | Behavior | -|--------|----------| -| Startup | Single long-running process | -| Latency | <50ms response | -| State | In-memory cache with file persistence | -| Best for | IDE integration requiring sub-100ms response | - -**Daemon Lifecycle**: -1. User or IDE explicitly starts daemon with `dotnet maui daemon start` -2. Daemon listens on well-known socket/pipe -3. CLI commands check for daemon; use if running, else execute directly -4. After 5 minutes idle (configurable via `--idle-timeout`), daemon self-terminates -5. IDE can restart daemon when needed - -**Well-Known Paths**: -- macOS: `/tmp/maui-devtools.sock` (Unix domain socket) -- Windows: `\\.\pipe\MauiDevTools` (named pipe) - -### 7.6 Concurrency Model +### 7.5 Concurrency Model | Aspect | Behavior | |--------|----------| | Read Operations | Parallelized (multiple simultaneous queries allowed) | | Write Operations | Serialized (single writer at a time) | -| Lock File | `$TMPDIR/maui-devtools.lock` prevents duplicate daemon instances | +| Lock File | `$TMPDIR/maui-devtools.lock` prevents concurrent writes | | Request Timeout | Requests waiting >30s for lock rejected with `E5010` | -| Progress Notifications | Buffered with backpressure; slow consumers receive "progress.dropped" notification | -**Race Condition Prevention**: -- Multiple IDE instances requesting daemon start simultaneously are handled via lock file -- First acquirer starts daemon; others connect to existing instance -- Socket/pipe creation is atomic - -### 7.7 SDK Conflict Resolution +### 7.6 SDK Conflict Resolution When multiple SDK installations are detected: @@ -897,7 +742,7 @@ When multiple SDK installations are detected: - Warn if both AS and tool would manage same SDK - Offer to adopt AS's SDK rather than installing duplicate -### 7.8 Migration from Existing Setups +### 7.7 Migration from Existing Setups When an existing SDK is detected: @@ -906,7 +751,7 @@ When an existing SDK is detected: 3. **Non-Destructive**: Never delete or modify user's existing SDK without explicit consent 4. **Override Support**: `--sdk-path` for non-standard locations -### 7.9 Error Contract Specification +### 7.8 Error Contract Specification **This is the highest-priority architectural element.** Every consumer (AI agents, CI pipelines, IDEs, humans) depends on predictable error handling. @@ -1159,11 +1004,6 @@ dotnet maui ├── diagnostic-bundle # Export diagnostic info │ └── --output # Output zip file │ -├── daemon # Daemon management -│ ├── start # Start daemon -│ ├── stop # Stop daemon -│ └── status # Check daemon status -│ └── --version # Show version ``` @@ -1172,7 +1012,9 @@ dotnet maui # Cross-platform commands dotnet maui doctor dotnet maui doctor --fix -dotnet maui device list +dotnet maui device list # List all devices (physical + emulators + simulators) +dotnet maui device list --platform android # Android devices and emulators +dotnet maui device list --platform ios # iOS simulators and physical devices dotnet maui device screenshot --device emulator-5554 # Android-specific @@ -1416,607 +1258,8 @@ maui-diag/ --- -## 11. Security Model - -### 11.1 Principle of Least Privilege - -| Action | Privilege Level | Justification | -|--------|-----------------|---------------| -| Query status | User | Read-only operations | -| Install SDK to user directory | User | Default SDK location | -| Install SDK to system directory | Admin | System-wide installation | -| Create/start emulator | User | User-space operation | -| Install Xcode runtime | Admin | System component | -| Capture screenshot | User | Device already authorized | - -### 11.2 Download Verification - -All downloads are verified before installation: - -1. **HTTPS only**: All downloads use HTTPS -2. **Checksum verification**: SHA-256 checksums verified against known-good values -3. **Signature verification**: Where available (Android SDK, Xcode components) -4. **Source allowlist**: Only download from: - - `dl.google.com` (Android SDK) - - `developer.apple.com` (Xcode components) - - `aka.ms` / `dotnetcli.azureedge.net` (.NET components) - -### 11.3 AI Agent Security - -> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed permission gates, sandbox boundaries, permission storage schema, and elevation handling for AI agents. - -**Summary**: AI agent calls are sandboxed with permission gates requiring user confirmation for modifications. Safe paths are restricted to project root, temp, SDK directories, and tool cache. Elevated operations cannot be auto-approved by agents. - ---- - -## 12. Extensibility - -### 12.1 Alignment with `dotnet run` Pipeline - -This tool is designed to complement and integrate with the `dotnet run` extensibility spec ([dotnet/sdk#51337](https://github.com/dotnet/sdk/pull/51337)). The SDK spec introduces MSBuild targets that workloads can implement for device discovery and deployment. - -**Key MSBuild Integration Points**: - -| MSBuild Target | SDK Responsibility | MAUI DevTools Role | -|----------------|-------------------|-------------------| -| `ComputeAvailableDevices` | Called by `dotnet run` to get device list | DevTools can invoke same target OR provide faster cached results | -| `DeployToDevice` | Called by `dotnet run` after build | DevTools wraps this for standalone deploy scenarios | -| `ComputeRunArguments` | Sets `$(RunCommand)` and `$(RunArguments)` | DevTools uses these for consistent launch behavior | -**Device Item Schema** (aligned with SDK spec): - -```xml - - - - - - - - -``` - -**Metadata Specification**: - -| Metadata | Required | Values | Description | -|----------|----------|--------|-------------| -| `Description` | Yes | Free text | Human-readable device name | -| `Type` | Yes | `Device`, `Emulator`, `Simulator` | Device category | -| `Status` | Yes | `Online`, `Offline`, `Booted`, `Shutdown`, `Paired`, `Unavailable` | Current state | -| `Platform` | No | `android`, `ios`, `maccatalyst`, `windows` | Inferred from TFM if not specified | -| `OSVersion` | No | Version string | e.g., "14", "18.0" | - -### 12.2 Interactive Prompting Alignment - -Following the SDK spec pattern, MAUI DevTools supports interactive prompting with graceful non-interactive fallback: - -**Interactive Mode** (terminal with TTY): -``` -$ maui device list -? Select target framework: - ❯ net10.0-android - net10.0-ios - net10.0-maccatalyst - net10.0-windows10.0.19041.0 - -? Select device: - ❯ emulator-5554 (Pixel 7 - API 35) [Online] - 0A041FDD400327 (Pixel 7 Pro) [Online] -``` - -**Non-Interactive Mode** (CI, piped, `--non-interactive`): -``` -$ maui device list --non-interactive -Error: Multiple target frameworks available. Use --platform to specify: - --platform android - --platform ios - --platform maccatalyst - --platform windows - -$ maui device screenshot --non-interactive -Error: Multiple devices available. Use --device to specify: - --device emulator-5554 # Pixel 7 - API 35 [Online] - --device 0A041FDD400327 # Pixel 7 Pro [Online] -``` - -### 12.3 `--list-devices` Convention - -Aligned with `dotnet run --list-devices`, this tool provides: - -```bash -# List devices for current project context -maui device list - -# List devices for specific platform -maui device list --platform android - -# Equivalent to dotnet run --list-devices (when in project directory) -dotnet run --list-devices -``` - -**Output Format** (aligned with SDK expectations): - -``` -Available devices for net10.0-android: - - ID DESCRIPTION TYPE STATUS - emulator-5554 Pixel 7 - API 35 Emulator Online - 0A041FDD400327 Pixel 7 Pro Device Online - -Run with: dotnet run --device - or: maui device screenshot --device -``` - -### 12.4 Deploy Step Support - -The SDK spec introduces a `deploy` step in the `dotnet run` pipeline. MAUI DevTools provides standalone access: - -```bash -# Deploy without running (useful for testing) -maui deploy --device emulator-5554 - -# This invokes the DeployToDevice MSBuild target -``` - -**JSON-RPC Method**: -```json -{ - "jsonrpc": "2.0", - "id": 1, - "method": "deploy", - "params": { - "project_path": "/path/to/MyApp.csproj", - "device_id": "emulator-5554", - "configuration": "Debug", - "framework": "net10.0-android" - } -} -``` - -### 12.5 AI Agent Considerations - -> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed AI agent design principles, workflow examples, and error contract specifications. - -**Summary**: MAUI DevTools is designed with AI agents as first-class consumers. All commands support `--json` for structured output, `--non-interactive` mode, and `--dry-run` for predictable behavior. Permission gates ensure user confirmation for modifications. - -### 12.6 Plugin Model for Platform Providers - -New platform providers can be added by implementing `IPlatformProvider`: - -```csharp -public interface IPlatformProvider -{ - string PlatformId { get; } // e.g., "android", "ios", "windows" - - Task CheckHealthAsync(CancellationToken ct); - Task> GetIssuesAsync(CancellationToken ct); - Task FixIssueAsync(string issueId, CancellationToken ct); - Task> GetDevicesAsync(CancellationToken ct); - - // New: MSBuild target integration - bool HasMSBuildTarget(string targetName); - Task InvokeMSBuildTargetAsync(string targetName, IDictionary properties, CancellationToken ct); -} -``` - -Providers are discovered via assembly scanning or explicit registration. - -### 12.7 Adding New Subcommands - -New commands are added by: -1. Creating a new `Command` class with `System.CommandLine` -2. Implementing the handler using core services -3. Registering the command in the root command builder -4. Adding corresponding JSON-RPC method if needed - -### 12.8 Versioning Strategy - -**CLI Versioning**: -- Follows SemVer: `MAJOR.MINOR.PATCH` -- MAJOR: Breaking changes to CLI arguments or behavior -- MINOR: New commands or options -- PATCH: Bug fixes - -**API Versioning**: -- JSON-RPC methods include version in response -- Schema version included in all JSON output -- Breaking changes require new method names (e.g., `doctor.status` → `doctor.status.v2`) - -**Capability Negotiation**: -```json -{ - "jsonrpc": "2.0", - "id": 1, - "method": "initialize", - "params": { - "client_version": "1.0.0", - "capabilities": ["streaming", "progress"] - } -} -``` - -Response includes server capabilities: -```json -{ - "jsonrpc": "2.0", - "id": 1, - "result": { - "server_version": "1.2.0", - "schema_version": "1.1", - "capabilities": ["streaming", "progress", "daemon"], - "platforms": ["android", "ios", "windows", "maccatalyst"] - } -} -``` - ---- - -## 13. Testing Strategy - -### 13.1 Unit Tests - -| Component | Coverage Target | Approach | -|-----------|-----------------|----------| -| CLI argument parsing | 100% | Test all commands, options, combinations | -| JSON-RPC serialization | 100% | Schema validation tests | -| Issue detection logic | 90% | Mock file system and tool outputs | -| Fix execution logic | 80% | Mock tool invocations | - -### 13.2 Integration Tests - -| Scenario | Environment | Frequency | -|----------|-------------|-----------| -| Doctor on clean Windows | Windows VM | Every PR | -| Doctor on clean macOS | macOS VM | Every PR | -| SDK installation | Isolated environment | Nightly | -| AVD creation/start | Android emulator | Nightly | -| Simulator management | macOS with Xcode | Nightly | - -### 13.3 Device Farm / Emulator Tests - -| Test | Infrastructure | Frequency | -|------|----------------|-----------| -| Screenshot capture | Helix (Android emulator) | Weekly | -| Screenshot capture | Helix (iOS simulator) | Weekly | -| Logcat streaming | Helix (Android emulator) | Weekly | -| Full doctor + fix flow | Dedicated VMs | Release | - -### 13.4 Test Environments - -```yaml -# CI Matrix -test-matrix: - - os: windows-latest - tests: [unit, integration-windows] - - os: macos-14 - tests: [unit, integration-macos, integration-xcode] - - os: ubuntu-latest - tests: [unit] # Limited to non-platform-specific -``` - ---- - -## 14. Rollout Plan - -### 14.1 Release Channels - -| Channel | Stability | Update Frequency | Audience | -|---------|-----------|------------------|----------| -| Preview | Experimental | Weekly | Early adopters, feedback | -| Release Candidate | Stable | Bi-weekly | Broader testing | -| Stable | Production | Monthly | General availability | - -### 14.2 Packaging - -**dotnet tool**: -``` -Package ID: Microsoft.Maui.DevTools -Install: dotnet tool install -g Microsoft.Maui.DevTools [--prerelease] -Update: dotnet tool update -g Microsoft.Maui.DevTools -``` - -**IDE Bundling**: -- VS Code extension bundles specific version -- Visual Studio includes in MAUI workload -- Can override with global tool if newer version needed - -### 14.3 Backwards Compatibility - -| Aspect | Guarantee | -|--------|-----------| -| CLI arguments | No breaking changes within major version | -| JSON output schema | Additive changes only; new fields don't break clients | -| JSON-RPC methods | Methods never removed; deprecated methods return warnings | -| Exit codes | Stable within major version | - -### 14.4 Update Strategy - -**Auto-update notification**: -``` -$ maui doctor -A new version of MAUI Dev Tools is available (1.2.0 → 1.3.0) -Run 'dotnet tool update -g Microsoft.Maui.DevTools' to update. - -[Current output continues...] -``` - -**IDE handling**: -- Check for updates on extension activation -- Prompt to update if major version behind -- Auto-update patch versions silently - ---- - -## 15. Open Questions & Risks - -### 15.1 Open Questions - -| ID | Question | Options | Recommendation | -|----|----------|---------|----------------| -| OQ1 | Should we support Linux for Android-only development? | Yes/No | Defer to vNext; validate demand first | -| OQ2 | How to handle multiple Xcode versions? | Detect all / Use xcode-select | Use xcode-select default; allow override | -| OQ3 | Should daemon auto-start on login? | Yes/No/Optional | No; start on first IDE request | -| OQ4 | How to handle Apple Silicon vs Intel for simulators? | Auto-detect / Require flag | Auto-detect from `uname -m` | -| OQ5 | Should we cache SDK installers? | Yes/No/Configurable | Yes, with configurable cache location | - -### 15.2 Risks - -| ID | Risk | Likelihood | Impact | Mitigation | -|----|------|------------|--------|------------| -| R1 | Android SDK license changes break auto-install | Low | High | Monitor Google announcements; have manual fallback | -| R2 | Xcode CLI tools break with updates | Medium | Medium | Version-specific handling; quick patch releases | -| R3 | IDE teams don't adopt | Medium | High | Early engagement; joint design reviews | -| R4 | Performance issues with large SDK installations | Low | Medium | Progress UI; resumable downloads | -| R5 | Security vulnerabilities in downloaded components | Low | Critical | Checksum verification; CVE monitoring | - ---- - -## 16. Appendix - -### 16.1 Command Examples - -#### Doctor Commands -```bash -# Basic health check -dotnet maui doctor - -# Health check with JSON output -dotnet maui doctor --json - -# Check and fix automatically -dotnet maui doctor --fix - -# Check only Android components -dotnet maui doctor --platform android - -# Non-interactive mode for CI -dotnet maui doctor --fix --non-interactive -``` - -#### Android Commands -```bash -# List connected devices and emulators -dotnet maui device list --platform android - -# Install recommended SDK packages -dotnet maui android sdk install --recommended - -# Install specific packages -dotnet maui android sdk install "platforms;android-34" "build-tools;34.0.0" - -# Create AVD -dotnet maui android avd create --name "Test_Pixel_5" --device pixel_5 --image "system-images;android-34;google_apis;x86_64" - -# Start emulator and wait for boot -dotnet maui android avd start --name "Test_Pixel_5" --wait - -# Stream logcat -dotnet maui android logcat --device emulator-5554 --filter "Microsoft.Maui:V *:S" - -# Take screenshot -dotnet maui device screenshot --device emulator-5554 --output ./screenshot.png -``` - -#### iOS Commands -```bash -# List all simulators -dotnet maui apple simulator list - -# List only booted iPhone simulators -dotnet maui apple simulator list --device-type iPhone --state booted - -# Boot specific simulator -dotnet maui apple simulator boot --udid A1B2C3D4-E5F6-7890-ABCD-EF1234567890 - -# Create new simulator -dotnet maui apple simulator create --name "Test iPhone 16" --device-type "iPhone 16 Pro" --runtime "iOS 18.0" - -# List available runtimes -dotnet maui apple runtime list - -# Take screenshot from simulator -dotnet maui device screenshot --device A1B2C3D4-E5F6-7890-ABCD-EF1234567890 --output ./sim-screenshot.png -``` - -#### Windows Commands -```bash -# Check Developer Mode status -dotnet maui windows developer-mode status - -# List Windows SDK installations -dotnet maui windows sdk list -``` - -### 16.2 JSON Output Examples - -#### Doctor Output (Healthy) -```json -{ - "schema_version": "1.0", - "correlation_id": "diag-2026-02-03-174500-abc123", - "timestamp": "2026-02-03T17:45:00.000Z", - "status": "healthy", - "checks": [ - { - "category": "dotnet", - "name": ".NET SDK", - "status": "ok", - "details": { - "version": "9.0.100", - "path": "/usr/local/share/dotnet", - "architecture": "arm64" - } - }, - { - "category": "dotnet", - "name": "MAUI Workload", - "status": "ok", - "details": { - "version": "9.0.0", - "installed_packs": [ - "Microsoft.Maui.Sdk", - "Microsoft.Maui.Controls", - "Microsoft.Maui.Core" - ] - } - }, - { - "category": "android", - "name": "Android SDK", - "status": "ok", - "details": { - "path": "/Users/dev/Library/Android/sdk", - "build_tools": ["34.0.0", "33.0.2"], - "platforms": ["android-34", "android-33"], - "emulator_version": "34.1.9" - } - }, - { - "category": "apple", - "name": "Xcode", - "status": "ok", - "details": { - "version": "16.0", - "path": "/Applications/Xcode.app", - "developer_dir": "/Applications/Xcode.app/Contents/Developer" - } - } - ], - "summary": { - "total": 8, - "ok": 8, - "warning": 0, - "error": 0 - } -} -``` - -#### Doctor Output (Issues Found) -```json -{ - "schema_version": "1.0", - "correlation_id": "diag-2026-02-03-174600-def456", - "timestamp": "2026-02-03T17:46:00.000Z", - "status": "unhealthy", - "checks": [ - { - "category": "android", - "name": "Android SDK", - "status": "error", - "message": "Android SDK not found at expected locations", - "issue": { - "id": "ANDROID_SDK_MISSING", - "severity": "error", - "description": "Android SDK is required for Android development", - "fixable": true, - "fix": { - "description": "Install Android SDK to default location", - "command": "maui android sdk install --recommended", - "rpc_method": "android.sdk.install", - "rpc_params": { "packages": ["recommended"] }, - "estimated_size_bytes": 2800000000, - "requires_confirmation": true - } - } - } - ], - "summary": { - "total": 8, - "ok": 5, - "warning": 1, - "error": 2 - } -} -``` - -#### Device List Output -```json -{ - "schema_version": "1.0", - "devices": [ - { - "id": "emulator-5554", - "name": "Pixel_5_API_34", - "platform": "android", - "type": "emulator", - "state": "online", - "os_version": "14", - "architecture": "x86_64", - "details": { - "avd_name": "Pixel_5_API_34", - "api_level": 34, - "skin": "pixel_5", - "snapshot": true - } - }, - { - "id": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890", - "name": "iPhone 16 Pro", - "platform": "ios", - "type": "simulator", - "state": "booted", - "os_version": "18.0", - "architecture": "arm64", - "details": { - "udid": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890", - "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-18-0", - "device_type": "com.apple.CoreSimulator.SimDeviceType.iPhone-16-Pro" - } - } - ] -} -``` - -### 16.3 Error Code Catalog - -| Code | Category | Message | Resolution | -|------|----------|---------|------------| -| `E1001` | General | Unknown command | Check command spelling; run `dotnet maui --help` | -| `E1002` | General | Missing required argument | Provide required argument or use interactive mode | -| `E1003` | General | Invalid argument value | Check allowed values in help | -| `E2001` | Android | Android SDK not found | Run `dotnet maui android sdk install --recommended` | -| `E2002` | Android | ADB not found | Install platform-tools via SDK manager | -| `E2003` | Android | Emulator not found | Install emulator package | -| `E2004` | Android | AVD not found | Create AVD with `dotnet maui android avd create` | -| `E2005` | Android | System image not found | Install required system image | -| `E2006` | Android | Device offline | Reconnect device or restart emulator | -| `E2007` | Android | APK installation failed | Check device storage; verify APK is valid | -| `E3001` | Apple | Xcode not found | Install Xcode from App Store | -| `E3002` | Apple | Xcode CLI tools not found | Run `xcode-select --install` | -| `E3003` | Apple | Runtime not found | Install via Xcode > Settings > Platforms | -| `E3004` | Apple | Simulator not found | Create simulator with `dotnet maui apple simulator create` | -| `E3005` | Apple | Simulator failed to boot | Check runtime compatibility; try different device | -| `E3006` | Apple | Developer directory not set | Run `sudo xcode-select -s /Applications/Xcode.app` | -| `E4001` | Network | Download failed | Check internet connection; retry | -| `E4002` | Network | Checksum verification failed | Re-download; report if persistent | -| `E4003` | Network | Connection timeout | Retry; check firewall/proxy settings | -| `E5001` | Permission | Elevation required | Run with administrator/sudo | -| `E5002` | Permission | Access denied | Check file/directory permissions | -| `E5003` | Permission | Agent permission denied | Approve action in IDE prompt | - ---- - -## 17. MVP vs vNext Features +## 11. MVP vs vNext Features ### MVP (v1.0) @@ -2027,10 +1270,9 @@ dotnet maui windows sdk list | P0 | Android SDK detection and installation | | P0 | Android AVD creation and management | | P0 | iOS simulator listing and boot/shutdown | -| P0 | Unified `device list` command | +| P0 | Unified `device list` command (emulators, simulators, physical devices) | | P0 | `device screenshot` command | | P0 | JSON output for all commands | -| P0 | JSON-RPC API for IDE integration | | P0 | VS Code extension integration | | P1 | Logcat streaming | | P1 | iOS runtime listing | @@ -2041,7 +1283,6 @@ dotnet maui windows sdk list | Priority | Feature | |----------|---------| | P1 | Visual Studio extension integration | -| P1 | Daemon mode for faster IDE interactions | | P1 | iOS runtime installation guidance | | P1 | APK install/uninstall | | P2 | AVD snapshot management | @@ -2049,161 +1290,30 @@ dotnet maui windows sdk list | P2 | Windows SDK management | | P2 | Linux host support (Android only) | | P2 | Physical iOS device support (requires signing) | -| P2 | `tree` command for dependency visualization | -| P2 | `archive` command for app packaging | | Future | MCP server integration for AI agents | | Future | Cloud-hosted device support | --- -## 18. Acceptance Criteria - -The following criteria must be met for v1.0 release: - -1. **AC1**: `maui doctor` completes in <5 seconds on a healthy system and correctly identifies all missing MAUI prerequisites. - -2. **AC2**: `maui doctor --fix` can install Android SDK, build-tools, emulator, and system images without manual intervention (license acceptance via `--accept-licenses`). - -3. **AC3**: `maui android avd create` creates a functional emulator that can boot and run a MAUI app. - -4. **AC4**: `maui apple simulator list` returns all available simulators with runtime and state information matching `xcrun simctl list`. - -5. **AC5**: `maui device list` returns a unified list of all Android devices/emulators and iOS simulators with consistent schema. - -6. **AC6**: `maui device screenshot` captures screenshots from both Android emulator and iOS simulator, saving to specified path. - -7. **AC7**: All commands support `--json` output with stable schema documented in spec. - -8. **AC8**: JSON-RPC server responds to all documented methods over stdio transport. - -9. **AC9**: VS Code extension can invoke `doctor.status`, display results, and trigger fixes via `doctor.fix`. - -10. **AC10**: Running `maui doctor --fix --non-interactive` in CI completes without prompts and returns appropriate exit codes. - -11. **AC11**: All downloads verify SHA-256 checksums before installation. - -12. **AC12**: AI agent permission gates prevent unauthorized modifications; all fix operations require explicit IDE confirmation. - -13. **AC13**: `diagnostic-bundle` produces a zip file containing all relevant diagnostic information with PII redacted. - -14. **AC14**: Tool runs correctly on Windows 10+ (x64/arm64) and macOS 13+ (arm64). - -15. **AC15**: Full test suite passes with >80% code coverage on unit tests. - ---- - -## 19. Implementation References & Prior Art - -The following existing repositories and code contain reusable logic, patterns, and prior art that should be leveraged for implementation: - -### 19.1 Community Tools (Redth) - -| Repository | Description | Reusable Components | -|------------|-------------|---------------------| -| [AndroidSdk.Tools](https://github.com/Redth/AndroidSdk.Tools/) | C# library for Android SDK management | SDK detection, package installation, AVD management, emulator control, `adb` wrapper | -| [AppleDev.Tools](https://github.com/Redth/AppleDev.Tools) | C# library for Apple development tools | Xcode detection, simulator management, `xcrun` wrapper, provisioning profile handling | -| [MAUI.Sherpa](https://github.com/Redth/MAUI.Sherpa) | MAUI development environment helper | Doctor-style diagnostics, environment validation, fix suggestions | - -**Recommendation**: These libraries are production-tested and can be directly referenced or their patterns adopted. Consider contributing improvements back upstream. - -### 19.2 Official .NET SDK Targets - -| File | Description | Relevant Code | -|------|-------------|---------------| -| [Microsoft.Android.Sdk.Application.targets](https://github.com/dotnet/android/blob/main/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Application.targets#L42) | Android SDK build targets | Device detection via `_ResolveAndroidDevice`, deployment logic, `adb` integration | -| [Microsoft.Sdk.Mobile.targets](https://github.com/dotnet/macios/blob/e79838c4de379be59f4038117c713d4dd3963a62/dotnet/targets/Microsoft.Sdk.Mobile.targets#L146) | iOS/macOS SDK mobile targets | Simulator detection, `xcrun` integration, deployment to devices | - -**Key MSBuild Patterns to Adopt**: - -```xml - - - - - - - - - -``` - -### 19.3 Integration Strategy - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ MAUI Dev Tools Client │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ Core Services │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ┌──────────────────┼──────────────────┐ │ -│ ▼ ▼ ▼ │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ -│ │ Android Provider│ │ Apple Provider │ │ Windows Provider│ │ -│ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ │ -│ │ REUSE: │ │ REUSE: │ │ │ │ -│ │ AndroidSdk.Tools│ │ AppleDev.Tools │ │ (New impl) │ │ -│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +## Related Documents -### 19.4 Code Patterns to Extract - -**From AndroidSdk.Tools**: -- `SdkManager` class for package management -- `AvdManager` class for AVD lifecycle -- `Adb` class for device communication -- `Emulator` class for emulator control -- SDK path detection logic (environment variables, standard paths) - -**From AppleDev.Tools**: -- `Simctl` class for simulator management -- `XcodeSelect` class for Xcode detection -- Runtime/device type enumeration -- Provisioning profile parsing - -**From MAUI.Sherpa**: -- Doctor check architecture -- Issue categorization and severity -- Fix recommendation engine -- Progress reporting patterns - -**From Official SDK Targets**: -- MSBuild target integration patterns -- `ComputeAvailableDevices` output schema -- Device selection logic -- Deployment pipeline hooks - -### 19.5 Consolidation Roadmap - -| Phase | Action | Repositories Affected | -|-------|--------|----------------------| -| 1 | Reference AndroidSdk.Tools and AppleDev.Tools as dependencies | New tool | -| 2 | Contribute improvements (JSON output, new commands) upstream | Redth repos | -| 3 | Integrate with MSBuild targets via `ComputeAvailableDevices` | dotnet/android, dotnet/macios | -| 4 | Deprecate internal VS repos | ClientTools.android-acquisition, android-platform-support | -| 5 | Consider merging community tools into dotnet org (with maintainer agreement) | Long-term | +| Document | Description | +|----------|-------------| +| [AI Agent Integration](./maui-devtools-ai-integration.md) | Copilot integration, permission model, MCP tools | +| [IDE Integration](./maui-devtools-ide-integration.md) | VS Code and Visual Studio UI flows | --- -## 20. Future Subcommands (Roadmap) - -Inspired by MAUI CLI TODOs and community requests: +## Revision History -| Command | Description | Inspiration | -|---------|-------------|-------------| -| `maui logs` | Stream unified logs from device/simulator | MAUI CLI TODO | -| `maui tree` | Display dependency tree for MAUI project | MAUI CLI TODO | -| `maui archive` | Build and package app for distribution | MAUI CLI TODO | -| `maui deploy` | Deploy to connected device | MAUI CLI TODO | -| `maui clean` | Clean MAUI build artifacts and caches | Common request | -| `maui template` | Scaffold new MAUI projects (delegate to dotnet new) | Convenience | -| `maui perf` | Performance profiling helpers | Future | -| `maui test` | Run device tests (delegate to dotnet test with device targeting) | Future | +| Version | Date | Changes | +|---------|------|---------| +| 2.5-draft | 2026-02-04 | Removed §11 Security, §12 Extensibility; Added physical device support to device list | +| 2.4-draft | 2026-02-04 | Removed §13 Testing Strategy, §14 Rollout Plan | +| 2.3-draft | 2026-02-04 | Removed §15-20 (Open Questions, Appendix, Acceptance Criteria, etc.) | +| 2.2-draft | 2026-02-04 | Removed daemon mode, §5.7 Deploy vs Run, G6, NG6 | +| 2.1-draft | 2026-02-04 | Extracted AI/IDE integration to separate documents; Removed JSON-RPC API | +| 1.0-draft | 2026-02-03 | Initial draft | --- From 1f689ce4cf3270ca1380f9a7303a02003db5da33 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 4 Feb 2026 19:56:26 +0000 Subject: [PATCH 11/34] Consolidate more --- docs/design/maui-devtools-spec.md | 283 +++++++----------------------- 1 file changed, 62 insertions(+), 221 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index be0a8f9734e7..7eeb0d601c9a 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.5-draft +**Version**: 2.6-draft **Status**: Proposal **Last Updated**: 2026-02-04 @@ -10,15 +10,14 @@ 1. [Executive Summary](#1-executive-summary) 2. [Problem Statement](#2-problem-statement) -3. [Goals / Non-Goals](#3-goals--non-goals) -4. [Personas & User Journeys](#4-personas--user-journeys) -5. [Functional Requirements](#5-functional-requirements) -6. [Non-Functional Requirements](#6-non-functional-requirements) -7. [Architecture](#7-architecture) -8. [Public API Surface](#8-public-api-surface) -9. [User Experience](#9-user-experience) -10. [Telemetry & Diagnostics](#10-telemetry--diagnostics) -11. [MVP vs vNext Features](#11-mvp-vs-vnext-features) +3. [Goals, Non-Goals & Personas](#3-goals-non-goals--personas) +4. [Functional Requirements](#4-functional-requirements) +5. [Non-Functional Requirements](#5-non-functional-requirements) +6. [Architecture](#6-architecture) +7. [Public API Surface](#7-public-api-surface) +8. [User Experience](#8-user-experience) +9. [Telemetry & Diagnostics](#9-telemetry--diagnostics) +10. [MVP vs vNext Features](#10-mvp-vs-vnext-features) --- @@ -76,7 +75,7 @@ This tool eliminates that friction by providing a single, authoritative source f --- -## 3. Goals / Non-Goals +## 3. Goals, Non-Goals & Personas ### Goals @@ -100,189 +99,30 @@ This tool eliminates that friction by providing a single, authoritative source f ### Design Principles -#### DP1: Delegate to Native Toolchains — Do Not Reimplement +**DP1: Delegate to Native Toolchains** — Do not reimplement. Use `sdkmanager`, `avdmanager`, `adb`, `emulator` for Android; `xcrun simctl`, `xcode-select` for Apple; Windows SDK installer for Windows. Native tools are authoritative, reduce maintenance burden, and ensure consistency. -**This tool MUST NOT implement custom logic to download, install, or configure platform components.** Instead, it delegates all such operations to the native platform tools: +**DP2: Consolidate Existing VS Repositories** — Replace `ClientTools.android-acquisition` and `android-platform-support` with unified `dotnet maui android` commands across VS, VS Code, CLI, and CI. -| Platform | Native Tools Used | What They Handle | -|----------|-------------------|------------------| -| Android | `sdkmanager`, `avdmanager`, `adb`, `emulator` | SDK packages, AVDs, device communication, emulator lifecycle | -| Apple | `xcrun simctl`, `xcode-select`, `xcodebuild` | Simulators, runtimes, Xcode selection, build tools | -| Windows | Windows SDK installer, VS Build Tools | Windows SDK components | +**DP3: Stateless Architecture** — Each command reads state, acts, and exits. Uses file-system caching (`~/.maui/cache/`) with TTLs for performance. -**Rationale**: -- Native tools are **authoritative** and always up-to-date with platform changes -- Avoids **maintenance burden** of tracking repository URLs, package formats, and installation procedures -- Reduces **security risk** from implementing custom download/verification logic -- Ensures **consistency** between manual and automated installations -- Leverages **existing testing** of platform tools by their maintainers +**DP4: Machine-First Output** — Every command supports `--json` with stable schema. Priority: AI agents > CI/CD > humans. Required flags: `--json`, `--dry-run`, `--ci`. -**Example**: -``` -❌ WRONG: Download android-sdk-*.zip from Google, extract, configure PATH -✅ RIGHT: Invoke `sdkmanager "platform-tools" "platforms;android-34"` and parse output -``` - -This tool's value is in **orchestration, detection, and unified UX**—not in reimplementing what the platform tools already do well. - -#### DP2: Consolidate Existing Visual Studio Acquisition Repositories - -This tool enables **consolidation of existing Visual Studio repositories** that currently implement Android acquisition separately: - -| Repository | Current Function | Future State | -|------------|------------------|--------------| -| [ClientTools.android-acquisition](https://devdiv.visualstudio.com/DevDiv/_git/ClientTools.android-acquisition) | Android SDK acquisition for VS | **Deprecate**: Use `dotnet maui android sdk install` | -| [android-platform-support](https://devdiv.visualstudio.com/DevDiv/_git/android-platform-support) | Android platform support for VS | **Deprecate**: Use `dotnet maui android` commands | - -**Benefits of Consolidation**: -- **Single codebase** for Android tooling across VS, VS Code, CLI, and CI -- **Reduced duplication** of detection and installation logic -- **Consistent behavior** across all Microsoft developer tools -- **Shared bug fixes** and improvements -- **Simplified maintenance** with one team owning the tooling - -**Migration Path**: -1. Visual Studio installer integrates `dotnet maui` tool -2. VS Android features call `dotnet maui android` commands instead of internal libraries -3. Internal repositories enter maintenance mode -4. After VS release cycle, internal repositories are archived - -#### DP3: Stateless Architecture - -**The CLI operates statelessly.** Each command reads state, acts, and exits. - -**Rationale**: -- Stateless commands are easier to debug, test, and reason about -- AI agents prefer deterministic request/response -- Performance bottleneck is native tool execution, not process spin-up - -**State Caching**: -Stateless does not mean slow. The tool uses file-system caching: -``` -~/.maui/cache/ -├── devices.json # TTL: 30 seconds -├── android-sdk-state.json # TTL: 5 minutes -├── apple-runtimes.json # TTL: 5 minutes -└── doctor-report.json # TTL: 1 minute -``` +### Target Personas -Commands read from cache if fresh, otherwise invoke native tools and update cache. - -#### DP4: Machine-First Output — The User is the AI - -**Every command MUST support `--json` output with a stable, versioned schema.** - -This tool is designed for three consumers in priority order: -1. **AI Agents** (GitHub Copilot, IDE assistants) — need structured data to reason about -2. **CI/CD Pipelines** — need deterministic exit codes and parseable output -3. **Human Developers** — need readable summaries with color and formatting - -**Implication**: If an error message is ambiguous plain text, AI agents will fail to use the tool reliably. Every failure must be expressed as structured data. - -```bash -# Human-friendly (default) -dotnet maui doctor -# ✓ .NET SDK 9.0.100 -# ✗ Android SDK not found - -# Machine-friendly (for AI/CI) -dotnet maui doctor --json -# { "status": "unhealthy", "checks": [...], "errors": [...] } -``` - -**Required flags for all commands**: -| Flag | Purpose | -|------|---------| -| `--json` | Output structured JSON instead of human-readable text | -| `--dry-run` | Show what would be done without executing (enables "what will this do?" UX) | -| `--ci` | Strict mode: no interactive prompts, non-zero exit on warnings, machine-readable only | - ---- +| Persona | Profile | Key Need | +|---------|---------|----------| +| **Windows Developer** | .NET dev, new to Android | One-click install of all Android dependencies | +| **macOS Developer** | Building iOS apps, has Xcode | Detection of runtime/simulator state, guided fixes | +| **CI Engineer** | DevOps configuring pipelines | `--non-interactive`, JSON output, deterministic exit codes | +| **AI Agent** | GitHub Copilot, IDE assistants | Structured JSON for diagnosis, permission-gated fixes | -## 4. Personas & User Journeys - -### 4.1 MAUI Developer on Windows - -**Profile**: Sarah, a .NET developer building a cross-platform app. She has Visual Studio installed but has never done Android development. - -**Journey**: -1. Sarah installs the .NET MAUI workload via `dotnet workload install maui` -2. She opens her project in VS Code and sees a notification: "MAUI environment issues detected" -3. She clicks "View Details" and sees a structured list: - - ❌ Android SDK not found - - ❌ Android emulator not installed - - ❌ No Android system images available -4. She clicks "Fix All" and watches a progress panel: - - Installing Android SDK... ✓ - - Installing build-tools 34.0.0... ✓ - - Installing emulator... ✓ - - Installing system-images;android-34;google_apis;x86_64... ✓ - - Creating default AVD "Pixel_5_API_34"... ✓ -5. She presses F5 and her app launches in the emulator - -**Key Requirements**: -- Clear, actionable error messages -- One-click installation of all dependencies -- Progress indication for long-running operations -- No prior Android knowledge required - -### 4.2 MAUI Developer on macOS - -**Profile**: Marcus, building an iOS app. He has Xcode installed but outdated simulators. - -**Journey**: -1. Marcus runs `dotnet maui doctor` in terminal -2. Output shows: - ``` - ✓ .NET SDK 9.0.100 - ✓ MAUI workload 9.0.0 - ✓ Xcode 16.0 (/Applications/Xcode.app) - ✓ Android SDK (/Users/marcus/Library/Android/sdk) - ⚠ iOS 18.0 runtime not installed (iOS 17.4 available) - ⚠ No iPhone 16 simulator available - ``` -3. He runs `dotnet maui doctor --fix` -4. Tool prompts: "Install iOS 18.0 runtime? (requires 8GB download) [Y/n]" -5. After confirmation, runtime installs and simulator is created - -**Key Requirements**: -- Detection of Xcode and simulator state -- Clear prompts for large downloads -- Respect for user's existing configuration - -### 4.3 CI Engineer - -**Profile**: DevOps engineer configuring GitHub Actions for a MAUI project. - -**Journey**: -1. Engineer adds step to workflow: - ```yaml - - name: Setup MAUI Environment - run: | - dotnet tool install -g Microsoft.Maui.DevTools - dotnet maui doctor --fix --non-interactive --json > setup-report.json - ``` -2. Tool runs silently, installs missing components, outputs JSON report -3. If any unfixable issues exist, tool exits with non-zero code -4. Subsequent build step succeeds - -**Key Requirements**: -- `--non-interactive` flag for unattended operation -- Deterministic exit codes -- JSON output for pipeline integration -- Idempotent execution (safe to run multiple times) - -### 4.4 AI Agent Invoked from IDE - -> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed AI agent personas, Copilot-assisted troubleshooting, and permission model. - -**Summary**: AI agents (GitHub Copilot, IDE assistants) can invoke `dotnet maui doctor --json` to diagnose environment issues, receive structured responses with fix commands, and execute fixes with user permission gates. +> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed AI agent personas and permission model. --- -## 5. Functional Requirements +## 4. Functional Requirements -### 5.1 Doctor Capability +### 4.1 Doctor Capability | ID | Requirement | Priority | |----|-------------|----------| @@ -301,7 +141,7 @@ dotnet maui doctor --json | FR-D13 | Support `--fix ` for targeted fixes | P1 | | FR-D14 | Detect multiple SDK installations and report conflicts | P1 | -### 5.2 Android Management +### 4.2 Android Management | ID | Requirement | Priority | |----|-------------|----------| @@ -323,7 +163,7 @@ dotnet maui doctor --json | FR-A16 | Install OpenJDK if missing (version 17 default, 21 supported) | P0 | | FR-A17 | Use platform-appropriate default paths when env vars not set | P0 | -### 5.3 Apple (Xcode) Management +### 4.3 Apple (Xcode) Management | ID | Requirement | Priority | |----|-------------|----------| @@ -342,7 +182,7 @@ dotnet maui doctor --json | FR-X13 | Handle multiple Xcode versions (detect all, use `xcode-select` default) | P1 | | FR-X14 | Detect Xcode beta installations at `/Applications/Xcode-beta.app` | P2 | -### 5.4 Windows Management +### 4.4 Windows Management | ID | Requirement | Priority | |----|-------------|----------| @@ -353,7 +193,7 @@ dotnet maui doctor --json | FR-W5 | Detect Hyper-V availability for Android emulation | P1 | | FR-W6 | Detect Windows App SDK dependencies | P2 | -### 5.5 Cross-Platform Screenshot +### 4.5 Cross-Platform Screenshot | ID | Requirement | Priority | |----|-------------|----------| @@ -365,7 +205,7 @@ dotnet maui doctor --json | FR-S6 | Support `--format` flag (png, jpg) | P2 | | FR-S7 | Return file path in JSON output | P0 | -### 5.5 Device Listing (Unified) +### 4.5 Device Listing (Unified) | ID | Requirement | Priority | |----|-------------|----------| @@ -375,7 +215,7 @@ dotnet maui doctor --json | FR-DL4 | Support `--platform` filter | P1 | | FR-DL5 | Support `--json` output | P0 | -### 5.6 Bootstrap State Machine +### 4.6 Bootstrap State Machine **Critical**: The tool must handle the "bootstrap gap" — the chicken-and-egg problem where native tools (sdkmanager, xcrun) don't exist yet. @@ -498,9 +338,9 @@ This command: --- -## 6. Non-Functional Requirements +## 5. Non-Functional Requirements -### 6.1 Reliability +### 5.1 Reliability | ID | Requirement | |----|-------------| @@ -509,7 +349,7 @@ This command: | NFR-R3 | Partial failures during multi-step operations must leave system in consistent state | | NFR-R4 | Tool must gracefully handle missing permissions | -### 6.2 Observability +### 5.2 Observability | ID | Requirement | |----|-------------| @@ -518,7 +358,7 @@ This command: | NFR-O3 | Long-running operations must emit progress events | | NFR-O4 | `diagnostic-bundle` command must collect all relevant logs and state | -### 6.3 Performance +### 5.3 Performance | ID | Requirement | |----|-------------| @@ -532,7 +372,7 @@ This command: - iOS simulator list: Use `xcrun simctl list -j` (fast native tool) - Fall back to CLI tools only for write operations (install, create, etc.) -### 6.4 Security +### 5.4 Security | ID | Requirement | |----|-------------| @@ -541,7 +381,7 @@ This command: | NFR-S3 | Elevation must be requested explicitly with clear justification | | NFR-S4 | AI agent calls must respect permission gates (see Security Model) | -### 6.5 Privacy +### 5.5 Privacy | ID | Requirement | |----|-------------| @@ -549,7 +389,7 @@ This command: | NFR-PR2 | File paths must be redacted in telemetry (keep structure only) | | NFR-PR3 | Telemetry must be opt-in with clear disclosure | -### 6.6 Accessibility +### 5.6 Accessibility | ID | Requirement | |----|-------------| @@ -557,7 +397,7 @@ This command: | NFR-A2 | All status indicators must have text equivalents | | NFR-A3 | IDE integration must follow platform accessibility guidelines | -### 6.7 Network & Offline Support +### 5.7 Network & Offline Support | ID | Requirement | |----|-------------| @@ -568,7 +408,7 @@ This command: | NFR-N5 | Large downloads must support HTTP Range requests for resumability | | NFR-N6 | Cache downloaded installers with configurable location and size limits | -### 6.8 Container & Headless Environments +### 5.8 Container & Headless Environments | Environment | Android Emulator | iOS Simulator | Doctor | SDK Install | |-------------|------------------|---------------|--------|-------------| @@ -587,9 +427,9 @@ When emulator/simulator unavailable: --- -## 7. Architecture +## 6. Architecture -### 7.1 High-Level Components +### 6.1 High-Level Components ``` ┌─────────────────────────────────────────────────────────────────────────┐ @@ -637,7 +477,7 @@ When emulator/simulator unavailable: └───────────────────┴───────────────────┴─────────────────────────────────┘ ``` -### 7.2 Component Descriptions +### 6.2 Component Descriptions #### CLI Layer - Parses command-line arguments using `System.CommandLine` @@ -663,7 +503,7 @@ When emulator/simulator unavailable: | Apple Provider | Wraps `xcrun simctl`, `xcode-select`, `xcodebuild` | | Windows Provider | Wraps Windows SDK detection and VS build tools | -### 7.3 Data Flow: Doctor Command +### 6.3 Data Flow: Doctor Command ``` User: maui doctor --json @@ -706,13 +546,13 @@ User: maui doctor --json └─────────────┘ ``` -### 7.4 IDE Extension Integration +### 6.4 IDE Extension Integration > **See [IDE Integration](./maui-devtools-ide-integration.md)** for detailed VS Code and Visual Studio UI flows, status panels, and menu integrations. **Summary**: IDEs spawn `dotnet maui` as a child process, invoke `dotnet maui doctor --json` on workspace open, display issues in their problems/error list panels, and provide commands for environment setup with progress notifications. -### 7.5 Concurrency Model +### 6.5 Concurrency Model | Aspect | Behavior | |--------|----------| @@ -721,7 +561,7 @@ User: maui doctor --json | Lock File | `$TMPDIR/maui-devtools.lock` prevents concurrent writes | | Request Timeout | Requests waiting >30s for lock rejected with `E5010` | -### 7.6 SDK Conflict Resolution +### 6.6 SDK Conflict Resolution When multiple SDK installations are detected: @@ -742,7 +582,7 @@ When multiple SDK installations are detected: - Warn if both AS and tool would manage same SDK - Offer to adopt AS's SDK rather than installing duplicate -### 7.7 Migration from Existing Setups +### 6.7 Migration from Existing Setups When an existing SDK is detected: @@ -751,7 +591,7 @@ When an existing SDK is detected: 3. **Non-Destructive**: Never delete or modify user's existing SDK without explicit consent 4. **Override Support**: `--sdk-path` for non-standard locations -### 7.8 Error Contract Specification +### 6.8 Error Contract Specification **This is the highest-priority architectural element.** Every consumer (AI agents, CI pipelines, IDEs, humans) depends on predictable error handling. @@ -886,9 +726,9 @@ dotnet maui doctor --ci --- -## 8. Public API Surface +## 7. Public API Surface -### 8.1 CLI Commands +### 7.1 CLI Commands The tool is invoked as `dotnet maui `, integrating naturally with the .NET CLI. Platform-specific commands use the target framework moniker pattern (`ios`, `android`, `maccatalyst`, `windows`). @@ -1098,7 +938,7 @@ All commands follow a consistent exit code scheme: | `dotnet maui apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | | `dotnet maui config set` | Set configuration | ``, `` | Confirmation | 0=success, 2=error | -### 8.2 Capabilities Model +### 7.2 Capabilities Model | Command | Windows | macOS | Requires Elevation | |---------|---------|-------|-------------------| @@ -1122,13 +962,13 @@ All commands follow a consistent exit code scheme: --- -## 9. User Experience +## 8. User Experience -### 9.1 IDE UI Flows +### 8.1 IDE UI Flows > **See [IDE Integration](./maui-devtools-ide-integration.md)** for detailed VS Code status bars, environment panels, fix progress dialogs, and Visual Studio menu integration. -### 9.2 Interactive Prompting +### 8.2 Interactive Prompting When running in interactive mode (terminal), the tool prompts for missing information: @@ -1172,7 +1012,7 @@ Total download size: 10.7 GB ? Proceed? [Y/n] ``` -### 9.3 Copilot-Assisted Troubleshooting +### 8.3 Copilot-Assisted Troubleshooting > **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed Copilot escalation triggers, context handoff schema, MCP tool integration, and example conversations. @@ -1180,9 +1020,9 @@ Total download size: 10.7 GB --- -## 10. Telemetry & Diagnostics +## 9. Telemetry & Diagnostics -### 10.1 Telemetry Events +### 9.1 Telemetry Events | Event | Data Collected | Purpose | |-------|----------------|---------| @@ -1191,7 +1031,7 @@ Total download size: 10.7 GB | `fix.attempted` | Issue type, success/failure | Measure fix effectiveness | | `error.occurred` | Error code, category (no stack traces) | Identify common failures | -### 10.2 Opt-In / Opt-Out +### 9.2 Opt-In / Opt-Out ``` # Check telemetry status @@ -1210,7 +1050,7 @@ $ maui telemetry disable ? Help improve MAUI Dev Tools by sending anonymous usage data? [y/N] ``` -### 10.3 Redaction Rules +### 9.3 Redaction Rules All telemetry and logs follow these redaction rules: @@ -1222,7 +1062,7 @@ All telemetry and logs follow these redaction rules: | UDIDs | Redact | `A1B2C3...` → `` | | Error messages | Keep, unless contains path | Preserved | -### 10.4 Diagnostic Bundle +### 9.4 Diagnostic Bundle ``` $ maui diagnostic-bundle --output ~/Desktop/maui-diag.zip @@ -1259,7 +1099,7 @@ maui-diag/ --- -## 11. MVP vs vNext Features +## 10. MVP vs vNext Features ### MVP (v1.0) @@ -1308,6 +1148,7 @@ maui-diag/ | Version | Date | Changes | |---------|------|---------| +| 2.6-draft | 2026-02-04 | Condensed §3 Goals and §4 Personas into single section; Now 10 sections | | 2.5-draft | 2026-02-04 | Removed §11 Security, §12 Extensibility; Added physical device support to device list | | 2.4-draft | 2026-02-04 | Removed §13 Testing Strategy, §14 Rollout Plan | | 2.3-draft | 2026-02-04 | Removed §15-20 (Open Questions, Appendix, Acceptance Criteria, etc.) | From 03fd31d7b399a82cd25584970f2afaea8d73b4ff Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 5 Feb 2026 19:17:51 +0000 Subject: [PATCH 12/34] Update spec with implemented features and learnings - Add MauiDevice JSON schema with all fields (platforms[], idiom, runtime_identifiers, etc.) - Add SdkPackage JSON schema with is_installed flag - Update sdk list command: --available and --all flags (replaces list-available) - Update avd commands: stop, delete; --package optional with auto-detection - Update bootstrap: --packages flag for comma-separated package list - Add progress reporting documentation with JSON format - Add shell quoting implementation notes for semicolon handling - Update jdk commands: check, list (consistent naming) - Bump version to 2.7-draft --- docs/design/maui-devtools-spec.md | 153 ++++++++++++++++++++++++++---- 1 file changed, 136 insertions(+), 17 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 7eeb0d601c9a..0e949beb4880 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,8 +1,8 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.6-draft +**Version**: 2.7-draft **Status**: Proposal -**Last Updated**: 2026-02-04 +**Last Updated**: 2026-02-05 --- @@ -271,6 +271,9 @@ dotnet maui android bootstrap --accept-licenses # With custom paths dotnet maui android bootstrap --jdk-path ~/my-jdk --sdk-path ~/my-sdk --accept-licenses + +# With specific packages (comma-separated) +dotnet maui android bootstrap --packages "platform-tools,build-tools;35.0.0,platforms;android-35" ``` This command: @@ -278,20 +281,20 @@ This command: 2. Sets `JAVA_HOME` for the session (prints guidance for permanent setup) 3. Downloads Android command-line tools (if missing) 4. Accepts SDK licenses non-interactively (if `--accept-licenses`) -5. Installs recommended packages (platform-tools, build-tools, emulator, system image) +5. Installs specified packages (or default recommended set if `--packages` not provided) 6. Prints environment variable guidance (doesn't modify shell config) **JDK Management Commands**: ```bash # Check JDK status -dotnet maui android jdk status +dotnet maui android jdk check # Install OpenJDK (default: version 17) dotnet maui android jdk install dotnet maui android jdk install --version 21 -# List available JDK versions -dotnet maui android jdk list-available +# List installed JDK versions +dotnet maui android jdk list ``` **Environment Variable Guidance Output**: @@ -306,6 +309,18 @@ Add to your shell profile (~/.zshrc or ~/.bashrc): export PATH="$JAVA_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH" ``` +**AVD Creation with Auto-Detection**: + +When `--package` is not specified, the tool automatically detects the most recent installed system image: + +```bash +# Auto-detect system image (uses highest API level installed) +dotnet maui android avd create MyEmulator + +# Explicitly specify system image +dotnet maui android avd create MyEmulator --package "system-images;android-35;google_apis;arm64-v8a" +``` + #### Apple Bootstrap | State | Detection | Behavior | @@ -358,6 +373,32 @@ This command: | NFR-O3 | Long-running operations must emit progress events | | NFR-O4 | `diagnostic-bundle` command must collect all relevant logs and state | +**Progress Reporting**: + +Long-running operations (bootstrap, SDK install, JDK install) emit step-by-step progress: + +Console output: +``` +[1/4] Checking JDK installation... +[2/4] Installing JDK 17... +[3/4] Checking SDK installation... +[4/4] Installing SDK packages: platform-tools, build-tools;35.0.0 +✓ Bootstrap completed successfully +``` + +JSON output (`--json`): +```json +{ + "type": "progress", + "step": 2, + "total_steps": 4, + "message": "Installing JDK 17...", + "percentage": 50 +} +``` + +IDE consumers can use the `type: "progress"` messages to update progress bars and status indicators. + ### 5.3 Performance | ID | Requirement | @@ -372,6 +413,12 @@ This command: - iOS simulator list: Use `xcrun simctl list -j` (fast native tool) - Fall back to CLI tools only for write operations (install, create, etc.) +**Shell Quoting Implementation Notes**: +- Package identifiers contain semicolons (e.g., `system-images;android-35;google_apis;arm64-v8a`) +- When calling `avdmanager` or `sdkmanager`, arguments with semicolons must be properly quoted +- Use single quotes with escaped inner quotes: `--package '{escapedImage}'` +- This prevents shell interpretation of semicolons as command separators + ### 5.4 Security | ID | Requirement | @@ -761,19 +808,21 @@ dotnet maui ├── android # Android-specific commands │ ├── bootstrap # Bootstrap Android SDK from scratch │ │ ├── --accept-licenses # Non-interactively accept licenses -│ │ ├── --recommended # Install recommended components +│ │ ├── --packages # Comma-separated packages to install │ │ ├── --jdk-path # JDK installation directory +│ │ ├── --jdk-version # JDK version (default: 17) │ │ └── --sdk-path # SDK installation directory │ ├── jdk # JDK management -│ │ ├── status # Check JDK installation status +│ │ ├── check # Check JDK installation status │ │ ├── install # Install OpenJDK │ │ │ ├── --version # JDK version (default: 17) │ │ │ └── --path # Installation directory -│ │ └── list-available # List available JDK versions +│ │ └── list # List installed JDK versions │ ├── sdk -│ │ ├── list # List installed packages -│ │ ├── list-available # List available packages -│ │ ├── install # Install package +│ │ ├── list # List SDK packages +│ │ │ ├── --available # Show packages available for install +│ │ │ └── --all # Show both installed and available +│ │ ├── install # Install package(s) - comma-separated │ │ ├── accept-licenses # Accept all SDK licenses │ │ └── uninstall # Uninstall package │ ├── avd @@ -781,14 +830,14 @@ dotnet maui │ │ ├── create # Create AVD │ │ │ ├── --name # AVD name │ │ │ ├── --device # Device profile -│ │ │ ├── --image # System image (prefers arm64 on Apple Silicon) +│ │ │ ├── --package # System image (optional, auto-detects latest) │ │ │ └── --force # Overwrite existing │ │ ├── start # Start AVD │ │ │ ├── --name # AVD name (or --avd) │ │ │ ├── --cold-boot # Fresh boot │ │ │ └── --wait # Wait for boot │ │ ├── stop # Stop emulator -│ │ │ └── --device # Emulator serial +│ │ │ └── --serial # Emulator serial (e.g., emulator-5554) │ │ └── delete # Delete AVD │ │ └── --name # AVD name │ ├── install # Install APK @@ -929,16 +978,86 @@ All commands follow a consistent exit code scheme: | `dotnet maui doctor` | Check environment health | `--fix`, `--platform`, `--json` | Status report | 0=healthy, 1=issues, 2=error | | `dotnet maui device list` | List available devices | `--platform`, `--json` | Device list | 0=success, 2=error | | `dotnet maui device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 5=no device, 2=error | -| `dotnet maui android sdk list` | List SDK packages | `--json` | Package list | 0=success, 2=error | +| `dotnet maui android sdk list` | List SDK packages | `--available`, `--all`, `--json` | Package list | 0=success, 2=error | | `dotnet maui android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 5=not found, 2=error | -| `dotnet maui android avd create` | Create emulator | `--name`, `--device`, `--image` | AVD name | 0=success, 1=exists, 2=error | +| `dotnet maui android avd create` | Create emulator | `--name`, `--device`, `--package` | AVD name | 0=success, 1=exists, 2=error | | `dotnet maui android avd start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | +| `dotnet maui android avd stop` | Stop emulator | `--serial` | Status | 0=success, 5=not found, 2=error | +| `dotnet maui android avd delete` | Delete AVD | `--name` | Status | 0=success, 5=not found, 2=error | | `dotnet maui apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | | `dotnet maui apple simulator boot` | Boot simulator | `--udid` or `--name` | UDID | 0=success, 5=not found, 2=error | | `dotnet maui apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | | `dotnet maui config set` | Set configuration | ``, `` | Confirmation | 0=success, 2=error | -### 7.2 Capabilities Model +### 7.2 JSON Output Schemas + +#### MauiDevice Schema + +The unified device model for all platforms (physical devices, emulators, simulators): + +```json +{ + "name": "iPhone 15 Pro", + "identifier": "12345678-1234-1234-1234-123456789ABC", + "emulator_id": null, + "platforms": ["ios", "maccatalyst"], + "version": "18.5", + "version_name": "iOS 18.5", + "manufacturer": "Apple", + "model": "iPhone 15 Pro", + "sub_model": "Pro", + "idiom": "phone", + "platform_architecture": "arm64", + "runtime_identifiers": ["ios-arm64", "maccatalyst-arm64"], + "architecture": "arm64", + "is_emulator": true, + "is_running": true, + "connection_type": "local", + "type": "Simulator", + "state": "Booted" +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `name` | string | Display name (required) | +| `identifier` | string | Unique ID - UDID (iOS) or serial (Android) (required) | +| `emulator_id` | string? | AVD name for Android emulators | +| `platforms` | string[] | Supported platforms (required) | +| `version` | string? | OS version number | +| `version_name` | string? | Human-readable OS version | +| `manufacturer` | string? | Device manufacturer | +| `model` | string? | Device model | +| `sub_model` | string? | Device variant | +| `idiom` | string? | Form factor: `phone`, `tablet`, `watch`, `tv`, `desktop` | +| `platform_architecture` | string? | Platform architecture (e.g., `arm64-v8a`) | +| `runtime_identifiers` | string[]? | .NET runtime identifiers | +| `architecture` | string? | CPU architecture | +| `is_emulator` | bool | True for emulator/simulator | +| `is_running` | bool | True if device is booted | +| `connection_type` | string? | `usb`, `wifi`, or `local` | + +#### SdkPackage Schema + +```json +{ + "path": "platforms;android-35", + "version": "3", + "description": "Android SDK Platform 35", + "location": "/Users/dev/Library/Android/sdk/platforms/android-35", + "is_installed": true +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `path` | string | Package identifier (required) | +| `version` | string? | Installed/available version | +| `description` | string? | Human-readable description | +| `location` | string? | Install path (for installed packages) | +| `is_installed` | bool | True if currently installed | + +### 7.3 Capabilities Model | Command | Windows | macOS | Requires Elevation | |---------|---------|-------|-------------------| From 9cad814f32e7959efd4809383003747e6e649830 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Mon, 9 Feb 2026 16:48:55 +0000 Subject: [PATCH 13/34] Sync spec with CLI implementation (v2.8-draft) (#33973) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Syncs the DevTools spec with the current CLI implementation on `maui-client-tool` branch. ### What changed **New commands documented:** - `apple xcode list` — List installed Xcode versions with version, build number, selected status - `apple xcode select ` — Switch active Xcode installation - `android sdk accept-licenses` — Accept SDK licenses - `android avd stop/delete` — Stop and delete AVDs - `android bootstrap/jdk` commands in capabilities model **Schema updates:** - `MauiDevice`: Added `type`, `state`, `details` fields - `MauiDevice`: Documented Android-specific field semantics (identifier = AVD name for emulators, version = API level, version_name = OS version without prefix, platform_architecture = raw ABI) - New `XcodeInstallation` schema (path, developer_dir, version, build, is_selected) **Spec corrections to match implementation:** - `doctor --platform` → `doctor --category` (matching actual CLI flag) - Simulator boot/shutdown/delete use positional `` not `--udid` option - Global options: marked `--non-interactive`, `--correlation-id`, `--offline` as vNext (not yet implemented) - FR-X13/X14: Updated from vague 'handle multiple Xcode versions' to specific `xcode list`/`xcode select` commands (P0) **MVP tracking:** - Added status column to MVP table showing which features are implemented - Moved `deploy`, `config`, `diagnostic-bundle`, `telemetry` to vNext (not yet implemented) Version bumped to 2.8-draft. --- docs/design/maui-devtools-spec.md | 165 +++++++++++++++++++++--------- 1 file changed, 115 insertions(+), 50 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 0e949beb4880..ed42730744c1 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,8 +1,8 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.7-draft +**Version**: 2.8-draft **Status**: Proposal -**Last Updated**: 2026-02-05 +**Last Updated**: 2026-02-09 --- @@ -179,8 +179,9 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-X10 | Stream simulator/device logs | P1 | | FR-X11 | Validate basic signing prerequisites (team ID, certificate presence) | P2 | | FR-X12 | Open Simulator.app with specific device | P1 | -| FR-X13 | Handle multiple Xcode versions (detect all, use `xcode-select` default) | P1 | -| FR-X14 | Detect Xcode beta installations at `/Applications/Xcode-beta.app` | P2 | +| FR-X13 | List all Xcode installations with version, build number, and selected status (`xcode list`) | P0 | +| FR-X14 | Switch active Xcode installation (`xcode select `) | P0 | +| FR-X15 | Detect Xcode beta installations at `/Applications/Xcode-beta.app` | P2 | ### 4.4 Windows Management @@ -784,11 +785,10 @@ The tool is invoked as `dotnet maui `, integrating naturally with the . ``` dotnet maui ├── doctor # Check environment health -│ ├── --fix [issue-id] # Auto-fix all or specific issue -│ ├── --platform

# Filter: android, ios, windows, maccatalyst (repeatable) +│ ├── --fix # Auto-fix all detected issues +│ ├── --category # Filter: dotnet, android, apple, windows │ ├── --json # Output as JSON -│ ├── --non-interactive # No prompts (for CI) -│ └── --offline # Skip network checks +│ └── --ci # CI mode (no prompts, fail-fast) │ ├── device │ ├── list # List all devices across platforms @@ -858,15 +858,18 @@ dotnet maui │ │ │ ├── --runtime # Runtime identifier │ │ │ └── --device-type # Device type identifier │ │ ├── boot # Boot simulator -│ │ │ └── --udid # Simulator UDID (or --name) +│ │ │ └── # Simulator UDID │ │ ├── shutdown # Shutdown simulator -│ │ │ └── --udid # Simulator UDID +│ │ │ └── # Simulator UDID │ │ └── delete # Delete simulator -│ │ └── --udid # Simulator UDID -│ └── runtime -│ ├── list # List installed iOS/macOS runtimes -│ └── install # Install runtime (guidance) -│ └── --version # Runtime version +│ │ └── # Simulator UDID +│ ├── runtime +│ │ ├── list # List installed iOS/macOS runtimes +│ │ └── install # Install runtime (guidance) +│ │ └── --version # Runtime version +│ └── xcode # Xcode installation management +│ ├── list # List installed Xcode versions +│ └── select # Switch active Xcode installation │ ├── windows # Windows-specific commands (Windows only) │ ├── sdk @@ -914,8 +917,10 @@ dotnet maui android logcat --device emulator-5554 # Apple-specific (macOS only) dotnet maui apple simulator list -dotnet maui apple simulator boot --name "iPhone 16 Pro" +dotnet maui apple simulator boot dotnet maui apple runtime list +dotnet maui apple xcode list +dotnet maui apple xcode select /Applications/Xcode.app # Windows-specific dotnet maui windows developer-mode status @@ -927,13 +932,13 @@ dotnet maui windows developer-mode status | Option | Description | Required | |--------|-------------|----------| -| `--json` | Output as JSON (machine-readable) | **Mandatory on all commands** | -| `--dry-run` | Show what would be done without executing | **Mandatory on write commands** | -| `--ci` | Strict mode: no prompts, warnings become errors, JSON output forced | Recommended | -| `--verbose` | Enable verbose logging | Optional | -| `--non-interactive` | Disable prompts; fail if input needed | Optional | -| `--correlation-id` | Set correlation ID for tracing | Optional | -| `--offline` | Skip network operations; use cached data only | Optional | +| `--json` | Output as JSON (machine-readable) | **Mandatory on all commands** ✅ | +| `--dry-run` | Show what would be done without executing | **Mandatory on write commands** ✅ | +| `--ci` | Strict mode: no prompts, warnings become errors, JSON output forced | Recommended ✅ | +| `--verbose` / `-v` | Enable verbose logging | Optional ✅ | +| `--non-interactive` | Disable prompts; fail if input needed | Optional (vNext) | +| `--correlation-id` | Set correlation ID for tracing | Optional (vNext) | +| `--offline` | Skip network operations; use cached data only | Optional (vNext) | **`--ci` Mode Behavior**: - Forces `--json` output (human-readable disabled) @@ -985,8 +990,14 @@ All commands follow a consistent exit code scheme: | `dotnet maui android avd stop` | Stop emulator | `--serial` | Status | 0=success, 5=not found, 2=error | | `dotnet maui android avd delete` | Delete AVD | `--name` | Status | 0=success, 5=not found, 2=error | | `dotnet maui apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | -| `dotnet maui apple simulator boot` | Boot simulator | `--udid` or `--name` | UDID | 0=success, 5=not found, 2=error | +| `dotnet maui apple simulator boot` | Boot simulator | `` | UDID | 0=success, 5=not found, 2=error | +| `dotnet maui apple simulator shutdown` | Shutdown simulator | `` | Status | 0=success, 5=not found, 2=error | +| `dotnet maui apple simulator create` | Create simulator | ` ` | UDID | 0=success, 2=error | +| `dotnet maui apple simulator delete` | Delete simulator | `` | Status | 0=success, 5=not found, 2=error | | `dotnet maui apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | +| `dotnet maui apple xcode list` | List Xcode installations | `--json` | Installation list | 0=success, 2=error | +| `dotnet maui apple xcode select` | Switch active Xcode | `` | Confirmation | 0=success, 3=permission denied | +| `dotnet maui android sdk accept-licenses` | Accept SDK licenses | `--json` | Status | 0=success, 2=error | | `dotnet maui config set` | Set configuration | ``, `` | Confirmation | 0=success, 2=error | ### 7.2 JSON Output Schemas @@ -1002,7 +1013,7 @@ The unified device model for all platforms (physical devices, emulators, simulat "emulator_id": null, "platforms": ["ios", "maccatalyst"], "version": "18.5", - "version_name": "iOS 18.5", + "version_name": "18.5", "manufacturer": "Apple", "model": "iPhone 15 Pro", "sub_model": "Pro", @@ -1014,28 +1025,43 @@ The unified device model for all platforms (physical devices, emulators, simulat "is_running": true, "connection_type": "local", "type": "Simulator", - "state": "Booted" + "state": "Booted", + "details": {} } ``` | Field | Type | Description | |-------|------|-------------| | `name` | string | Display name (required) | -| `identifier` | string | Unique ID - UDID (iOS) or serial (Android) (required) | +| `identifier` | string | Unique ID — AVD name (Android emulator), serial (Android physical), UDID (iOS) (required) | | `emulator_id` | string? | AVD name for Android emulators | | `platforms` | string[] | Supported platforms (required) | -| `version` | string? | OS version number | -| `version_name` | string? | Human-readable OS version | -| `manufacturer` | string? | Device manufacturer | -| `model` | string? | Device model | -| `sub_model` | string? | Device variant | +| `version` | string? | API level for Android (e.g., `"35"`), OS version for iOS (e.g., `"18.5"`) | +| `version_name` | string? | OS version number without platform prefix (e.g., `"15.0"` not `"Android 15.0"`) | +| `manufacturer` | string? | Device manufacturer (`"Google"` for emulators, `ro.product.manufacturer` for physical) | +| `model` | string? | Device model (e.g., `"Pixel 8"`, `"iPhone 15 Pro"`) | +| `sub_model` | string? | System image variant for Android (e.g., `"Google API's"`, `"Google API's, Play Store"`) | | `idiom` | string? | Form factor: `phone`, `tablet`, `watch`, `tv`, `desktop` | -| `platform_architecture` | string? | Platform architecture (e.g., `arm64-v8a`) | +| `platform_architecture` | string? | Raw platform ABI (e.g., `arm64-v8a`, `x86_64`, `arm64`) | | `runtime_identifiers` | string[]? | .NET runtime identifiers | -| `architecture` | string? | CPU architecture | +| `architecture` | string? | Normalized CPU architecture (e.g., `arm64`, `x64`) | | `is_emulator` | bool | True for emulator/simulator | | `is_running` | bool | True if device is booted | | `connection_type` | string? | `usb`, `wifi`, or `local` | +| `type` | string? | `Physical`, `Emulator`, or `Simulator` | +| `state` | string? | `Connected`, `Booted`, `Offline`, `Shutdown`, `Unknown` | +| `details` | object? | Additional platform-specific metadata (e.g., `tag_id`, `avd` for Android) | + +**Android-Specific Field Semantics**: + +| Field | Running Emulator | Shutdown Emulator | Physical Device | +|-------|-----------------|-------------------|-----------------| +| `identifier` | AVD name (e.g., `Pixel_8_API_35`) | AVD name | Serial (e.g., `R58M32XXXXX`) | +| `version` | API level from `ro.build.version.sdk` | API level from AVD config | API level from `ro.build.version.sdk` | +| `version_name` | `ro.build.version.release` | Mapped from API level | `ro.build.version.release` | +| `manufacturer` | `ro.product.manufacturer` | `"Google"` | `ro.product.manufacturer` | +| `platform_architecture` | Raw ABI (e.g., `arm64-v8a`) | From AVD config | Raw ABI from `ro.product.cpu.abi` | +| `sub_model` | Merged from AVD tag + `PlayStore.enabled` | From AVD tag + `PlayStore.enabled` | N/A | #### SdkPackage Schema @@ -1057,6 +1083,26 @@ The unified device model for all platforms (physical devices, emulators, simulat | `location` | string? | Install path (for installed packages) | | `is_installed` | bool | True if currently installed | +#### XcodeInstallation Schema + +```json +{ + "path": "/Applications/Xcode.app", + "developer_dir": "/Applications/Xcode.app/Contents/Developer", + "version": "16.2", + "build": "16C5032a", + "is_selected": true +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `path` | string | Path to Xcode.app bundle (required) | +| `developer_dir` | string | Path to Developer directory inside the bundle | +| `version` | string | Xcode version string | +| `build` | string | Xcode build number | +| `is_selected` | bool | True if this is the currently active Xcode (via `xcode-select`) | + ### 7.3 Capabilities Model | Command | Windows | macOS | Requires Elevation | @@ -1067,14 +1113,24 @@ The unified device model for all platforms (physical devices, emulators, simulat | `dotnet maui device screenshot` | ✓ | ✓ | No | | `dotnet maui android sdk list` | ✓ | ✓ | No | | `dotnet maui android sdk install` | ✓ | ✓ | No | +| `dotnet maui android sdk accept-licenses` | ✓ | ✓ | No | | `dotnet maui android avd create` | ✓ | ✓ | No | | `dotnet maui android avd start` | ✓ | ✓ | No | -| `dotnet maui android logcat` | ✓ | ✓ | No | +| `dotnet maui android avd stop` | ✓ | ✓ | No | +| `dotnet maui android avd delete` | ✓ | ✓ | No | +| `dotnet maui android bootstrap` | ✓ | ✓ | No | +| `dotnet maui android jdk check` | ✓ | ✓ | No | +| `dotnet maui android jdk install` | ✓ | ✓ | No | +| `dotnet maui android jdk list` | ✓ | ✓ | No | | `dotnet maui apple simulator list` | — | ✓ | No | | `dotnet maui apple simulator boot` | — | ✓ | No | +| `dotnet maui apple simulator shutdown` | — | ✓ | No | | `dotnet maui apple simulator create` | — | ✓ | No | +| `dotnet maui apple simulator delete` | — | ✓ | No | | `dotnet maui apple runtime list` | — | ✓ | No | | `dotnet maui apple runtime install` | — | ✓ | Yes (admin) | +| `dotnet maui apple xcode list` | — | ✓ | No | +| `dotnet maui apple xcode select` | — | ✓ | Yes (sudo) | | `dotnet maui device logs` | ✓ | ✓ | No | *Elevation required for: installing Android SDK to system locations, installing Xcode runtimes @@ -1222,20 +1278,24 @@ maui-diag/ ### MVP (v1.0) -| Priority | Feature | -|----------|---------| -| P0 | `doctor` command with status reporting | -| P0 | `doctor --fix` for automated remediation | -| P0 | Android SDK detection and installation | -| P0 | Android AVD creation and management | -| P0 | iOS simulator listing and boot/shutdown | -| P0 | Unified `device list` command (emulators, simulators, physical devices) | -| P0 | `device screenshot` command | -| P0 | JSON output for all commands | -| P0 | VS Code extension integration | -| P1 | Logcat streaming | -| P1 | iOS runtime listing | -| P1 | Interactive prompting | +| Priority | Feature | Status | +|----------|---------|--------| +| P0 | `doctor` command with status reporting | ✅ Implemented | +| P0 | `doctor --fix` for automated remediation | ✅ Implemented | +| P0 | Android SDK detection and installation | ✅ Implemented | +| P0 | Android AVD creation and management | ✅ Implemented | +| P0 | Android bootstrap (JDK + SDK from scratch) | ✅ Implemented | +| P0 | Android JDK management (check, install, list) | ✅ Implemented | +| P0 | Android SDK license acceptance | ✅ Implemented | +| P0 | iOS simulator listing and boot/shutdown/create/delete | ✅ Implemented | +| P0 | iOS runtime listing | ✅ Implemented | +| P0 | Xcode installation listing and selection | ✅ Implemented | +| P0 | Unified `device list` command (emulators, simulators, physical devices) | ✅ Implemented | +| P0 | `device screenshot` command | ✅ Implemented | +| P0 | JSON output for all commands | ✅ Implemented | +| P0 | VS Code extension integration | ✅ In progress | +| P1 | Device log streaming | ✅ Implemented | +| P1 | Interactive prompting | Planned | ### vNext (v1.x / v2.0) @@ -1244,11 +1304,15 @@ maui-diag/ | P1 | Visual Studio extension integration | | P1 | iOS runtime installation guidance | | P1 | APK install/uninstall | +| P1 | `deploy` command (build + deploy to device) | +| P1 | `config` command (get/set/list configuration) | +| P1 | `--non-interactive`, `--correlation-id`, `--offline` global options | | P2 | AVD snapshot management | -| P2 | Simulator log streaming | | P2 | Windows SDK management | | P2 | Linux host support (Android only) | | P2 | Physical iOS device support (requires signing) | +| P2 | `diagnostic-bundle` command | +| P2 | Telemetry (opt-in) | | Future | MCP server integration for AI agents | | Future | Cloud-hosted device support | @@ -1267,6 +1331,7 @@ maui-diag/ | Version | Date | Changes | |---------|------|---------| +| 2.8-draft | 2026-02-09 | Synced spec with implementation: added Xcode list/select commands, XcodeInstallation schema, Android device field semantics, updated MauiDevice schema with `type`/`state`/`details` fields, marked MVP features as implemented, updated capabilities model and command table, clarified global option implementation status | | 2.6-draft | 2026-02-04 | Condensed §3 Goals and §4 Personas into single section; Now 10 sections | | 2.5-draft | 2026-02-04 | Removed §11 Security, §12 Extensibility; Added physical device support to device list | | 2.4-draft | 2026-02-04 | Removed §13 Testing Strategy, §14 Rollout Plan | From 6876ced8fb11e3f3bd4eed1d68d5e38e4410fc2d Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Mon, 9 Feb 2026 20:35:14 +0000 Subject: [PATCH 14/34] =?UTF-8?q?Rename=20bootstrap=E2=86=92install,=20dro?= =?UTF-8?q?p=20deploy/config/diagnostic-bundle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per PR #33865 feedback: - Rename 'android bootstrap' to 'android install' throughout spec - Remove deploy command (covered by 'dotnet run'/'dotnet build -t:Install') - Remove config command (not needed for MVP) - Remove diagnostic-bundle section (deferred to vNext) - Remove telemetry section (deferred to vNext) - Rename §9 from 'Telemetry & Diagnostics' to 'Diagnostics' - Remove APK install and logcat from command tree (covered by 'dotnet run') - Clean up vNext list --- docs/design/maui-devtools-spec.md | 172 +++++++----------------------- 1 file changed, 40 insertions(+), 132 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index ed42730744c1..b63aa80b5b9a 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -16,7 +16,7 @@ 6. [Architecture](#6-architecture) 7. [Public API Surface](#7-public-api-surface) 8. [User Experience](#8-user-experience) -9. [Telemetry & Diagnostics](#9-telemetry--diagnostics) +9. [Diagnostics](#9-diagnostics) 10. [MVP vs vNext Features](#10-mvp-vs-vnext-features) --- @@ -158,7 +158,7 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-A11 | Install APK to device/emulator | P1 | | FR-A12 | Uninstall package from device/emulator | P2 | | FR-A13 | Capture screenshot from device/emulator | P0 | -| FR-A14 | Bootstrap full Android environment (JDK + SDK) from scratch | P0 | +| FR-A14 | Install full Android environment (JDK + SDK) from scratch | P0 | | FR-A15 | Detect JDK installation and version | P0 | | FR-A16 | Install OpenJDK if missing (version 17 default, 21 supported) | P0 | | FR-A17 | Use platform-appropriate default paths when env vars not set | P0 | @@ -216,9 +216,9 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-DL4 | Support `--platform` filter | P1 | | FR-DL5 | Support `--json` output | P0 | -### 4.6 Bootstrap State Machine +### 4.6 Install State Machine -**Critical**: The tool must handle the "bootstrap gap" — the chicken-and-egg problem where native tools (sdkmanager, xcrun) don't exist yet. +**Critical**: The tool must handle the "install gap" — the chicken-and-egg problem where native tools (sdkmanager, xcrun) don't exist yet. #### Platform Bootstrap States @@ -234,9 +234,9 @@ This tool eliminates that friction by providing a single, authoritative source f (or auto-fix) native tools) ``` -#### Android Bootstrap +#### Android Install -The tool can fully bootstrap an Android development environment from scratch, including JDK and SDK installation. +The tool can fully install an Android development environment from scratch, including JDK and SDK installation. **Dependency Order**: JDK must be installed before SDK (sdkmanager requires Java). @@ -256,7 +256,7 @@ The tool can fully bootstrap an Android development environment from scratch, in | macOS | `~/Library/Developer/Android/jdk` | `~/Library/Developer/Android/sdk` | | Windows | `%LOCALAPPDATA%\Android\jdk` | `%LOCALAPPDATA%\Android\sdk` | -**Bootstrap States**: +**Install States**: | State | Detection | Behavior | |-------|-----------|----------| @@ -265,16 +265,16 @@ The tool can fully bootstrap an Android development environment from scratch, in | `PARTIAL` | SDK exists but `sdkmanager` missing/broken | Repair SDK or reinstall cmdline-tools | | `READY` | `java -version` succeeds AND `sdkmanager --list` succeeds | Delegate all operations to native tools | -**Bootstrap Command**: +**Install Command**: ```bash -# Full bootstrap: JDK + SDK + recommended packages -dotnet maui android bootstrap --accept-licenses +# Full install: JDK + SDK + recommended packages +dotnet maui android install --accept-licenses # With custom paths -dotnet maui android bootstrap --jdk-path ~/my-jdk --sdk-path ~/my-sdk --accept-licenses +dotnet maui android install --jdk-path ~/my-jdk --sdk-path ~/my-sdk --accept-licenses # With specific packages (comma-separated) -dotnet maui android bootstrap --packages "platform-tools,build-tools;35.0.0,platforms;android-35" +dotnet maui android install --packages "platform-tools,build-tools;35.0.0,platforms;android-35" ``` This command: @@ -322,7 +322,7 @@ dotnet maui android avd create MyEmulator dotnet maui android avd create MyEmulator --package "system-images;android-35;google_apis;arm64-v8a" ``` -#### Apple Bootstrap +#### Apple Install | State | Detection | Behavior | |-------|-----------|----------| @@ -330,12 +330,12 @@ dotnet maui android avd create MyEmulator --package "system-images;android-35;go | `CLI_ONLY` | Only Command Line Tools installed | Error: "Full Xcode required for simulators" | | `READY` | `xcrun simctl list` succeeds | Delegate all operations to native tools | -**Important**: Apple bootstrap is limited because: +**Important**: Apple install is limited because: - Xcode cannot be installed programmatically (App Store only) - Runtime downloads require Xcode to be open at least once (license acceptance) ```bash -dotnet maui apple bootstrap +dotnet maui apple install ``` This command: @@ -344,7 +344,7 @@ This command: 3. Prompts user to accept Xcode license if needed 4. Reports status and next steps -#### Windows Bootstrap +#### Windows Install | State | Detection | Behavior | |-------|-----------|----------| @@ -372,11 +372,11 @@ This command: | NFR-O1 | All operations must support `--verbose` flag for detailed logging | | NFR-O2 | JSON output must include `correlation_id` for tracing | | NFR-O3 | Long-running operations must emit progress events | -| NFR-O4 | `diagnostic-bundle` command must collect all relevant logs and state | +| NFR-O4 | (vNext) `diagnostic-bundle` command to collect all relevant logs and state | **Progress Reporting**: -Long-running operations (bootstrap, SDK install, JDK install) emit step-by-step progress: +Long-running operations (install, SDK install, JDK install) emit step-by-step progress: Console output: ``` @@ -622,7 +622,6 @@ When multiple SDK installations are detected: **Conflict Handling**: - `dotnet maui doctor` reports all detected SDKs with recommendation -- `dotnet maui config set android-sdk-path ` to override - `--sdk-path` flag available on all android commands for one-off override **Android Studio Coexistence**: @@ -693,7 +692,7 @@ Errors are classified into three categories: |------|----------|---------|------------------| | `E1001` | tool | Internal error | terminal | | `E2001` | platform | SDK licenses not accepted | auto_fixable | -| `E2002` | platform | sdkmanager not found | auto_fixable (bootstrap) | +| `E2002` | platform | sdkmanager not found | auto_fixable (install) | | `E2003` | platform | xcrun failed | user_action | | `E2004` | platform | Emulator acceleration unavailable | user_action | | `E3001` | user | Xcode not installed | user_action | @@ -806,7 +805,7 @@ dotnet maui │ └── --since

# JDK installation directory @@ -825,27 +824,21 @@ dotnet maui │ │ ├── install # Install package(s) - comma-separated │ │ ├── accept-licenses # Accept all SDK licenses │ │ └── uninstall # Uninstall package -│ ├── avd -│ │ ├── list # List AVDs -│ │ ├── create # Create AVD -│ │ │ ├── --name # AVD name -│ │ │ ├── --device # Device profile -│ │ │ ├── --package # System image (optional, auto-detects latest) -│ │ │ └── --force # Overwrite existing -│ │ ├── start # Start AVD -│ │ │ ├── --name # AVD name (or --avd) -│ │ │ ├── --cold-boot # Fresh boot -│ │ │ └── --wait # Wait for boot -│ │ ├── stop # Stop emulator -│ │ │ └── --serial # Emulator serial (e.g., emulator-5554) -│ │ └── delete # Delete AVD -│ │ └── --name # AVD name -│ ├── install # Install APK -│ │ ├── --device # Target device -│ │ └── # APK file -│ └── logcat # Stream Android logs -│ ├── --device # Target device -│ └── --filter # Tag filter (e.g., "MainActivity:V *:S") +│ └── avd +│ ├── list # List AVDs +│ ├── create # Create AVD +│ │ ├── --name # AVD name +│ │ ├── --device # Device profile +│ │ ├── --package # System image (optional, auto-detects latest) +│ │ └── --force # Overwrite existing +│ ├── start # Start AVD +│ │ ├── --name # AVD name (or --avd) +│ │ ├── --cold-boot # Fresh boot +│ │ └── --wait # Wait for boot +│ ├── stop # Stop emulator +│ │ └── --serial # Emulator serial (e.g., emulator-5554) +│ └── delete # Delete AVD +│ └── --name # AVD name │ ├── apple # Apple platform commands (macOS only) │ ├── simulator @@ -878,24 +871,6 @@ dotnet maui │ ├── status # Check Developer Mode status │ └── enable # Guide to enable Developer Mode │ -├── deploy # Deploy app to device -│ ├── --device # Target device -│ ├── --project # Project file (default: current dir) -│ ├── --configuration # Build configuration -│ ├── --framework # Target framework -│ ├── --install-only # Install without launching -│ ├── --wait # Wait for app to exit (returns app exit code) -│ ├── --debug # Launch with debugger attached -│ └── --timeout # Timeout for launch detection (default: 30) -│ -├── config # Configuration management -│ ├── list # List all config values -│ ├── get # Get config value -│ └── set # Set config value -│ -├── diagnostic-bundle # Export diagnostic info -│ └── --output # Output zip file -│ └── --version # Show version ``` @@ -998,7 +973,6 @@ All commands follow a consistent exit code scheme: | `dotnet maui apple xcode list` | List Xcode installations | `--json` | Installation list | 0=success, 2=error | | `dotnet maui apple xcode select` | Switch active Xcode | `` | Confirmation | 0=success, 3=permission denied | | `dotnet maui android sdk accept-licenses` | Accept SDK licenses | `--json` | Status | 0=success, 2=error | -| `dotnet maui config set` | Set configuration | ``, `` | Confirmation | 0=success, 2=error | ### 7.2 JSON Output Schemas @@ -1118,7 +1092,7 @@ The unified device model for all platforms (physical devices, emulators, simulat | `dotnet maui android avd start` | ✓ | ✓ | No | | `dotnet maui android avd stop` | ✓ | ✓ | No | | `dotnet maui android avd delete` | ✓ | ✓ | No | -| `dotnet maui android bootstrap` | ✓ | ✓ | No | +| `dotnet maui android install` | ✓ | ✓ | No | | `dotnet maui android jdk check` | ✓ | ✓ | No | | `dotnet maui android jdk install` | ✓ | ✓ | No | | `dotnet maui android jdk list` | ✓ | ✓ | No | @@ -1195,37 +1169,9 @@ Total download size: 10.7 GB --- -## 9. Telemetry & Diagnostics - -### 9.1 Telemetry Events - -| Event | Data Collected | Purpose | -|-------|----------------|---------| -| `command.invoked` | Command name, flags used, duration | Understand usage patterns | -| `doctor.result` | Issue counts by category (no specifics) | Track environment health | -| `fix.attempted` | Issue type, success/failure | Measure fix effectiveness | -| `error.occurred` | Error code, category (no stack traces) | Identify common failures | - -### 9.2 Opt-In / Opt-Out +## 9. Diagnostics -``` -# Check telemetry status -$ maui telemetry status -Telemetry is currently: DISABLED - -# Enable telemetry -$ maui telemetry enable - -# Disable telemetry -$ maui telemetry disable -``` - -**Default**: Telemetry is **OFF** by default. First run prompts: -``` -? Help improve MAUI Dev Tools by sending anonymous usage data? [y/N] -``` - -### 9.3 Redaction Rules +### 9.1 Redaction Rules All telemetry and logs follow these redaction rules: @@ -1237,40 +1183,6 @@ All telemetry and logs follow these redaction rules: | UDIDs | Redact | `A1B2C3...` → `` | | Error messages | Keep, unless contains path | Preserved | -### 9.4 Diagnostic Bundle - -``` -$ maui diagnostic-bundle --output ~/Desktop/maui-diag.zip - -Collecting diagnostics... - • Environment info - • Tool configuration - • Recent command history (redacted) - • Android SDK state - • Xcode/simulator state - • .NET SDK info - -Saved to: /Users/dev/Desktop/maui-diag.zip (2.3 MB) -``` - -**Bundle Contents**: -``` -maui-diag/ -├── environment.json # OS, tool version, paths -├── doctor-report.json # Full doctor output -├── android/ -│ ├── sdk-packages.json -│ └── avd-list.json -├── apple/ -│ ├── simulators.json -│ └── runtimes.json -├── dotnet/ -│ ├── sdk-info.json -│ └── workloads.json -└── logs/ - └── recent-commands.log # Last 50 commands (redacted) -``` - --- @@ -1284,7 +1196,7 @@ maui-diag/ | P0 | `doctor --fix` for automated remediation | ✅ Implemented | | P0 | Android SDK detection and installation | ✅ Implemented | | P0 | Android AVD creation and management | ✅ Implemented | -| P0 | Android bootstrap (JDK + SDK from scratch) | ✅ Implemented | +| P0 | Android install (JDK + SDK from scratch) | ✅ Implemented | | P0 | Android JDK management (check, install, list) | ✅ Implemented | | P0 | Android SDK license acceptance | ✅ Implemented | | P0 | iOS simulator listing and boot/shutdown/create/delete | ✅ Implemented | @@ -1303,15 +1215,11 @@ maui-diag/ |----------|---------| | P1 | Visual Studio extension integration | | P1 | iOS runtime installation guidance | -| P1 | APK install/uninstall | -| P1 | `deploy` command (build + deploy to device) | -| P1 | `config` command (get/set/list configuration) | | P1 | `--non-interactive`, `--correlation-id`, `--offline` global options | | P2 | AVD snapshot management | | P2 | Windows SDK management | | P2 | Linux host support (Android only) | | P2 | Physical iOS device support (requires signing) | -| P2 | `diagnostic-bundle` command | | P2 | Telemetry (opt-in) | | Future | MCP server integration for AI agents | | Future | Cloud-hosted device support | @@ -1331,7 +1239,7 @@ maui-diag/ | Version | Date | Changes | |---------|------|---------| -| 2.8-draft | 2026-02-09 | Synced spec with implementation: added Xcode list/select commands, XcodeInstallation schema, Android device field semantics, updated MauiDevice schema with `type`/`state`/`details` fields, marked MVP features as implemented, updated capabilities model and command table, clarified global option implementation status | +| 2.8-draft | 2026-02-09 | Synced with implementation: renamed `bootstrap` → `install` per PR feedback; removed `deploy`, `config`, `diagnostic-bundle` commands (covered by `dotnet run`/`dotnet build`); removed telemetry section (vNext); added Xcode list/select, XcodeInstallation schema, Android device field semantics, `type`/`state`/`details` to MauiDevice | | 2.6-draft | 2026-02-04 | Condensed §3 Goals and §4 Personas into single section; Now 10 sections | | 2.5-draft | 2026-02-04 | Removed §11 Security, §12 Extensibility; Added physical device support to device list | | 2.4-draft | 2026-02-04 | Removed §13 Testing Strategy, §14 Rollout Plan | From 8baf3968d18af5b110dfca65cb52f84882637f5f Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 10 Feb 2026 12:51:12 +0000 Subject: [PATCH 15/34] =?UTF-8?q?Rename=20avd=E2=86=92emulator,=20simulato?= =?UTF-8?q?r=20boot=E2=86=92start,=20shutdown=E2=86=92stop=20in=20spec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/design/maui-devtools-spec.md | 91 ++++++++++++++++--------------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index b63aa80b5b9a..9aa6237ecde5 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,8 +1,8 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.8-draft +**Version**: 2.9-draft **Status**: Proposal -**Last Updated**: 2026-02-09 +**Last Updated**: 2026-02-10 --- @@ -148,12 +148,12 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-A1 | List connected devices and running emulators | P0 | | FR-A2 | List installed SDK packages with version info | P0 | | FR-A3 | Install SDK packages by name or alias (e.g., `--recommended`) | P0 | -| FR-A4 | List available AVDs | P0 | -| FR-A5 | Create AVD with specified device profile and system image | P0 | -| FR-A6 | Start AVD and wait for boot completion | P0 | +| FR-A4 | List available emulators | P0 | +| FR-A5 | Create emulator with specified device profile and system image | P0 | +| FR-A6 | Start emulator and wait for boot completion | P0 | | FR-A7 | Stop running emulator | P1 | | FR-A8 | Cold boot emulator (wipe runtime state) | P1 | -| FR-A9 | Wipe AVD data | P2 | +| FR-A9 | Wipe emulator data | P2 | | FR-A10 | Stream logcat output with filtering | P1 | | FR-A11 | Install APK to device/emulator | P1 | | FR-A12 | Uninstall package from device/emulator | P2 | @@ -169,8 +169,8 @@ This tool eliminates that friction by providing a single, authoritative source f |----|-------------|----------| | FR-X1 | List available simulators with runtime/device type info | P0 | | FR-X2 | Filter simulators by runtime, device type, or state | P0 | -| FR-X3 | Boot simulator by UDID or name | P0 | -| FR-X4 | Shutdown simulator | P0 | +| FR-X3 | Start simulator by UDID or name | P0 | +| FR-X4 | Stop simulator | P0 | | FR-X5 | Create simulator with specified runtime and device type | P0 | | FR-X6 | Delete simulator | P2 | | FR-X7 | List available runtimes | P0 | @@ -316,10 +316,10 @@ When `--package` is not specified, the tool automatically detects the most recen ```bash # Auto-detect system image (uses highest API level installed) -dotnet maui android avd create MyEmulator +dotnet maui android emulator create MyEmulator # Explicitly specify system image -dotnet maui android avd create MyEmulator --package "system-images;android-35;google_apis;arm64-v8a" +dotnet maui android emulator create MyEmulator --package "system-images;android-35;google_apis;arm64-v8a" ``` #### Apple Install @@ -471,7 +471,7 @@ IDE consumers can use the `type: "progress"` messages to update progress bars an When emulator/simulator unavailable: - `dotnet maui doctor` reports capability with reason (e.g., "emulator: unavailable (virtualization disabled)") -- `dotnet maui android avd start` fails fast with `E2010` "Hardware acceleration unavailable" +- `dotnet maui android emulator start` fails fast with `E2010` "Hardware acceleration unavailable" --- @@ -720,7 +720,7 @@ When the tool encounters an error it doesn't recognize: "eligible": true, "context": { "doctor_report": { ... }, - "failed_command": "dotnet maui android avd create ...", + "failed_command": "dotnet maui android emulator create ...", "environment": { ... }, "native_tool_output": "..." } @@ -824,21 +824,21 @@ dotnet maui │ │ ├── install # Install package(s) - comma-separated │ │ ├── accept-licenses # Accept all SDK licenses │ │ └── uninstall # Uninstall package -│ └── avd -│ ├── list # List AVDs -│ ├── create # Create AVD -│ │ ├── --name # AVD name +│ └── emulator +│ ├── list # List emulators +│ ├── create # Create emulator +│ │ ├── --name # Emulator name │ │ ├── --device # Device profile │ │ ├── --package # System image (optional, auto-detects latest) │ │ └── --force # Overwrite existing -│ ├── start # Start AVD -│ │ ├── --name # AVD name (or --avd) -│ │ ├── --cold-boot # Fresh boot +│ ├── start # Start emulator +│ │ ├── --name # Emulator name +│ │ ├── --cold-boot # Cold boot │ │ └── --wait # Wait for boot │ ├── stop # Stop emulator │ │ └── --serial # Emulator serial (e.g., emulator-5554) -│ └── delete # Delete AVD -│ └── --name # AVD name +│ └── delete # Delete emulator +│ └── --name # Emulator name │ ├── apple # Apple platform commands (macOS only) │ ├── simulator @@ -850,9 +850,9 @@ dotnet maui │ │ │ ├── --name # Simulator name │ │ │ ├── --runtime # Runtime identifier │ │ │ └── --device-type # Device type identifier -│ │ ├── boot # Boot simulator +│ │ ├── start # Start simulator │ │ │ └── # Simulator UDID -│ │ ├── shutdown # Shutdown simulator +│ │ ├── stop # Stop simulator │ │ │ └── # Simulator UDID │ │ └── delete # Delete simulator │ │ └── # Simulator UDID @@ -886,13 +886,13 @@ dotnet maui device screenshot --device emulator-5554 # Android-specific dotnet maui android sdk install platforms;android-34 -dotnet maui android avd create --name Pixel_8 --device pixel_8 -dotnet maui android avd start --name Pixel_8 --wait +dotnet maui android emulator create --name Pixel_8 --device pixel_8 +dotnet maui android emulator start --name Pixel_8 --wait dotnet maui android logcat --device emulator-5554 # Apple-specific (macOS only) dotnet maui apple simulator list -dotnet maui apple simulator boot +dotnet maui apple simulator start dotnet maui apple runtime list dotnet maui apple xcode list dotnet maui apple xcode select /Applications/Xcode.app @@ -960,13 +960,13 @@ All commands follow a consistent exit code scheme: | `dotnet maui device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 5=no device, 2=error | | `dotnet maui android sdk list` | List SDK packages | `--available`, `--all`, `--json` | Package list | 0=success, 2=error | | `dotnet maui android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 5=not found, 2=error | -| `dotnet maui android avd create` | Create emulator | `--name`, `--device`, `--package` | AVD name | 0=success, 1=exists, 2=error | -| `dotnet maui android avd start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | -| `dotnet maui android avd stop` | Stop emulator | `--serial` | Status | 0=success, 5=not found, 2=error | -| `dotnet maui android avd delete` | Delete AVD | `--name` | Status | 0=success, 5=not found, 2=error | +| `dotnet maui android emulator create` | Create emulator | `--name`, `--device`, `--package` | Emulator name | 0=success, 1=exists, 2=error | +| `dotnet maui android emulator start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | +| `dotnet maui android emulator stop` | Stop emulator | `--serial` | Status | 0=success, 5=not found, 2=error | +| `dotnet maui android emulator delete` | Delete emulator | `--name` | Status | 0=success, 5=not found, 2=error | | `dotnet maui apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | -| `dotnet maui apple simulator boot` | Boot simulator | `` | UDID | 0=success, 5=not found, 2=error | -| `dotnet maui apple simulator shutdown` | Shutdown simulator | `` | Status | 0=success, 5=not found, 2=error | +| `dotnet maui apple simulator start` | Start simulator | `` | UDID | 0=success, 5=not found, 2=error | +| `dotnet maui apple simulator stop` | Stop simulator | `` | Status | 0=success, 5=not found, 2=error | | `dotnet maui apple simulator create` | Create simulator | ` ` | UDID | 0=success, 2=error | | `dotnet maui apple simulator delete` | Delete simulator | `` | Status | 0=success, 5=not found, 2=error | | `dotnet maui apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | @@ -1088,17 +1088,17 @@ The unified device model for all platforms (physical devices, emulators, simulat | `dotnet maui android sdk list` | ✓ | ✓ | No | | `dotnet maui android sdk install` | ✓ | ✓ | No | | `dotnet maui android sdk accept-licenses` | ✓ | ✓ | No | -| `dotnet maui android avd create` | ✓ | ✓ | No | -| `dotnet maui android avd start` | ✓ | ✓ | No | -| `dotnet maui android avd stop` | ✓ | ✓ | No | -| `dotnet maui android avd delete` | ✓ | ✓ | No | +| `dotnet maui android emulator create` | ✓ | ✓ | No | +| `dotnet maui android emulator start` | ✓ | ✓ | No | +| `dotnet maui android emulator stop` | ✓ | ✓ | No | +| `dotnet maui android emulator delete` | ✓ | ✓ | No | | `dotnet maui android install` | ✓ | ✓ | No | | `dotnet maui android jdk check` | ✓ | ✓ | No | | `dotnet maui android jdk install` | ✓ | ✓ | No | | `dotnet maui android jdk list` | ✓ | ✓ | No | | `dotnet maui apple simulator list` | — | ✓ | No | -| `dotnet maui apple simulator boot` | — | ✓ | No | -| `dotnet maui apple simulator shutdown` | — | ✓ | No | +| `dotnet maui apple simulator start` | — | ✓ | No | +| `dotnet maui apple simulator stop` | — | ✓ | No | | `dotnet maui apple simulator create` | — | ✓ | No | | `dotnet maui apple simulator delete` | — | ✓ | No | | `dotnet maui apple runtime list` | — | ✓ | No | @@ -1121,11 +1121,11 @@ The unified device model for all platforms (physical devices, emulators, simulat When running in interactive mode (terminal), the tool prompts for missing information: -**Example: AVD Creation with Missing Parameters**: +**Example: Emulator Creation with Missing Parameters**: ``` -$ maui android avd create +$ maui android emulator create -? AVD name: My_Pixel_5 +? Emulator name: My_Pixel_5 ? Select device profile: ❯ Pixel 5 (1080x2340, 440dpi) @@ -1139,12 +1139,12 @@ $ maui android avd create android-33 | Google APIs | x86_64 (more...) -Creating AVD 'My_Pixel_5'... done +Creating emulator 'My_Pixel_5'... done ``` **Non-Interactive Mode**: ``` -$ maui android avd create --non-interactive +$ maui android emulator create --non-interactive Error: --name is required in non-interactive mode ``` @@ -1195,11 +1195,11 @@ All telemetry and logs follow these redaction rules: | P0 | `doctor` command with status reporting | ✅ Implemented | | P0 | `doctor --fix` for automated remediation | ✅ Implemented | | P0 | Android SDK detection and installation | ✅ Implemented | -| P0 | Android AVD creation and management | ✅ Implemented | +| P0 | Android emulator creation and management | ✅ Implemented | | P0 | Android install (JDK + SDK from scratch) | ✅ Implemented | | P0 | Android JDK management (check, install, list) | ✅ Implemented | | P0 | Android SDK license acceptance | ✅ Implemented | -| P0 | iOS simulator listing and boot/shutdown/create/delete | ✅ Implemented | +| P0 | iOS simulator listing and start/stop/create/delete | ✅ Implemented | | P0 | iOS runtime listing | ✅ Implemented | | P0 | Xcode installation listing and selection | ✅ Implemented | | P0 | Unified `device list` command (emulators, simulators, physical devices) | ✅ Implemented | @@ -1239,6 +1239,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| +| 2.9-draft | 2026-02-10 | Unified command naming: renamed `avd` → `emulator` for Android, `simulator boot` → `simulator start`, `simulator shutdown` → `simulator stop` for Apple — consistent start/stop verbs across platforms | | 2.8-draft | 2026-02-09 | Synced with implementation: renamed `bootstrap` → `install` per PR feedback; removed `deploy`, `config`, `diagnostic-bundle` commands (covered by `dotnet run`/`dotnet build`); removed telemetry section (vNext); added Xcode list/select, XcodeInstallation schema, Android device field semantics, `type`/`state`/`details` to MauiDevice | | 2.6-draft | 2026-02-04 | Condensed §3 Goals and §4 Personas into single section; Now 10 sections | | 2.5-draft | 2026-02-04 | Removed §11 Security, §12 Extensibility; Added physical device support to device list | From 7eb58236e1873d7a00a4f41ea3fe34e436424d1c Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 10 Feb 2026 15:04:29 +0000 Subject: [PATCH 16/34] Add apple install, runtime check/install, xcode check/accept-licenses; doctor --platform; emulator stop by name --- docs/design/maui-devtools-spec.md | 56 +++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 9aa6237ecde5..a7b469630294 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -335,14 +335,22 @@ dotnet maui android emulator create MyEmulator --package "system-images;android- - Runtime downloads require Xcode to be open at least once (license acceptance) ```bash +# Basic setup check dotnet maui apple install + +# Accept licenses automatically +dotnet maui apple install --accept-licenses + +# Also install a specific iOS runtime +dotnet maui apple install --runtime 18.5 --accept-licenses ``` This command: 1. Verifies Xcode installation -2. Runs `xcode-select --install` if CLI tools missing -3. Prompts user to accept Xcode license if needed -4. Reports status and next steps +2. Checks and optionally accepts Xcode license (`--accept-licenses`) +3. Lists installed runtimes +4. Installs a specific iOS runtime if `--runtime ` is provided +5. Reports overall status and next steps #### Windows Install @@ -785,7 +793,7 @@ The tool is invoked as `dotnet maui `, integrating naturally with the . dotnet maui ├── doctor # Check environment health │ ├── --fix # Auto-fix all detected issues -│ ├── --category # Filter: dotnet, android, apple, windows +│ ├── --platform

# Filter: dotnet, android, apple, windows │ ├── --json # Output as JSON │ └── --ci # CI mode (no prompts, fail-fast) │ @@ -836,11 +844,14 @@ dotnet maui │ │ ├── --cold-boot # Cold boot │ │ └── --wait # Wait for boot │ ├── stop # Stop emulator -│ │ └── --serial # Emulator serial (e.g., emulator-5554) +│ │ └── # Emulator name │ └── delete # Delete emulator │ └── --name # Emulator name │ ├── apple # Apple platform commands (macOS only) +│ ├── install # Set up Apple development environment +│ │ ├── --runtime # iOS runtime version to install +│ │ └── --accept-licenses # Accept Xcode license automatically │ ├── simulator │ │ ├── list # List simulators │ │ │ ├── --runtime # Filter by runtime @@ -857,12 +868,17 @@ dotnet maui │ │ └── delete # Delete simulator │ │ └── # Simulator UDID │ ├── runtime -│ │ ├── list # List installed iOS/macOS runtimes -│ │ └── install # Install runtime (guidance) -│ │ └── --version # Runtime version +│ │ ├── check # Check runtime installation status +│ │ ├── list # List runtimes +│ │ │ ├── --available # Show runtimes available for download +│ │ │ └── --all # Show all (installed + available) +│ │ └── install # Install iOS runtime +│ │ └── # Runtime version │ └── xcode # Xcode installation management +│ ├── check # Check Xcode installation and license │ ├── list # List installed Xcode versions -│ └── select # Switch active Xcode installation +│ ├── select # Switch active Xcode installation +│ └── accept-licenses # Accept Xcode license agreement │ ├── windows # Windows-specific commands (Windows only) │ ├── sdk @@ -891,11 +907,19 @@ dotnet maui android emulator start --name Pixel_8 --wait dotnet maui android logcat --device emulator-5554 # Apple-specific (macOS only) +dotnet maui apple install # Check Xcode + runtimes +dotnet maui apple install --accept-licenses # Also accept Xcode license +dotnet maui apple install --runtime 18.5 --accept-licenses # Full bootstrap dotnet maui apple simulator list dotnet maui apple simulator start +dotnet maui apple runtime check dotnet maui apple runtime list +dotnet maui apple runtime list --available # Show downloadable runtimes +dotnet maui apple runtime install 18.5 # Install specific runtime +dotnet maui apple xcode check dotnet maui apple xcode list dotnet maui apple xcode select /Applications/Xcode.app +dotnet maui apple xcode accept-licenses # Windows-specific dotnet maui windows developer-mode status @@ -962,16 +986,21 @@ All commands follow a consistent exit code scheme: | `dotnet maui android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 5=not found, 2=error | | `dotnet maui android emulator create` | Create emulator | `--name`, `--device`, `--package` | Emulator name | 0=success, 1=exists, 2=error | | `dotnet maui android emulator start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | -| `dotnet maui android emulator stop` | Stop emulator | `--serial` | Status | 0=success, 5=not found, 2=error | +| `dotnet maui android emulator stop` | Stop emulator | `` | Status | 0=success, 5=not found, 2=error | | `dotnet maui android emulator delete` | Delete emulator | `--name` | Status | 0=success, 5=not found, 2=error | | `dotnet maui apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | | `dotnet maui apple simulator start` | Start simulator | `` | UDID | 0=success, 5=not found, 2=error | | `dotnet maui apple simulator stop` | Stop simulator | `` | Status | 0=success, 5=not found, 2=error | | `dotnet maui apple simulator create` | Create simulator | ` ` | UDID | 0=success, 2=error | | `dotnet maui apple simulator delete` | Delete simulator | `` | Status | 0=success, 5=not found, 2=error | -| `dotnet maui apple runtime list` | List iOS runtimes | `--json` | Runtime list | 0=success, 2=error | +| `dotnet maui apple runtime list` | List iOS runtimes | `--available`, `--all`, `--json` | Runtime list | 0=success, 2=error | +| `dotnet maui apple runtime check` | Check runtime status | `--json` | Status report | 0=success, 2=error | +| `dotnet maui apple runtime install` | Install iOS runtime | `` | Progress, result | 0=success, 2=error | +| `dotnet maui apple xcode check` | Check Xcode status | `--json` | Status report | 0=success, 2=error | | `dotnet maui apple xcode list` | List Xcode installations | `--json` | Installation list | 0=success, 2=error | | `dotnet maui apple xcode select` | Switch active Xcode | `` | Confirmation | 0=success, 3=permission denied | +| `dotnet maui apple xcode accept-licenses` | Accept Xcode license | `--json` | Status | 0=success, 3=permission denied | +| `dotnet maui apple install` | Set up Apple environment | `--runtime`, `--accept-licenses` | Progress, result | 0=success, 2=error | | `dotnet maui android sdk accept-licenses` | Accept SDK licenses | `--json` | Status | 0=success, 2=error | ### 7.2 JSON Output Schemas @@ -1101,10 +1130,14 @@ The unified device model for all platforms (physical devices, emulators, simulat | `dotnet maui apple simulator stop` | — | ✓ | No | | `dotnet maui apple simulator create` | — | ✓ | No | | `dotnet maui apple simulator delete` | — | ✓ | No | +| `dotnet maui apple install` | — | ✓ | Sometimes* | +| `dotnet maui apple runtime check` | — | ✓ | No | | `dotnet maui apple runtime list` | — | ✓ | No | | `dotnet maui apple runtime install` | — | ✓ | Yes (admin) | +| `dotnet maui apple xcode check` | — | ✓ | No | | `dotnet maui apple xcode list` | — | ✓ | No | | `dotnet maui apple xcode select` | — | ✓ | Yes (sudo) | +| `dotnet maui apple xcode accept-licenses` | — | ✓ | Yes (sudo) | | `dotnet maui device logs` | ✓ | ✓ | No | *Elevation required for: installing Android SDK to system locations, installing Xcode runtimes @@ -1239,6 +1272,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| +| 2.10-draft | 2026-02-10 | Added `apple install` bootstrap command (Xcode + license + runtime), `runtime check`, `runtime list --available/--all`, `runtime install `, `xcode check`, `xcode accept-licenses`; changed `doctor --category` → `doctor --platform`; changed `emulator stop ` → `emulator stop ` for consistency | | 2.9-draft | 2026-02-10 | Unified command naming: renamed `avd` → `emulator` for Android, `simulator boot` → `simulator start`, `simulator shutdown` → `simulator stop` for Apple — consistent start/stop verbs across platforms | | 2.8-draft | 2026-02-09 | Synced with implementation: renamed `bootstrap` → `install` per PR feedback; removed `deploy`, `config`, `diagnostic-bundle` commands (covered by `dotnet run`/`dotnet build`); removed telemetry section (vNext); added Xcode list/select, XcodeInstallation schema, Android device field semantics, `type`/`state`/`details` to MauiDevice | | 2.6-draft | 2026-02-04 | Condensed §3 Goals and §4 Personas into single section; Now 10 sections | From cff31d039238d69b2898bf8c831450992a3b2edb Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 10 Feb 2026 16:58:09 +0000 Subject: [PATCH 17/34] Update spec --- docs/design/maui-devtools-ai-integration.md | 16 +++------------- docs/design/maui-devtools-ide-integration.md | 18 +++++++++--------- docs/design/maui-devtools-spec.md | 18 +++++++++--------- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/docs/design/maui-devtools-ai-integration.md b/docs/design/maui-devtools-ai-integration.md index 9a03fdcc8944..b0aa81215ae2 100644 --- a/docs/design/maui-devtools-ai-integration.md +++ b/docs/design/maui-devtools-ai-integration.md @@ -145,8 +145,8 @@ Opening Copilot with diagnostic context... Run: gh copilot explain "MAUI SDK install failure E4001" Or copy this diagnostic summary: - maui diagnostic-bundle --output /tmp/maui-diag.zip - gh copilot explain --file /tmp/maui-diag.zip + dotnet maui doctor --json --verbose > /tmp/maui-diag.json + gh copilot explain --file /tmp/maui-diag.json ``` ### MCP Tool Integration @@ -165,16 +165,6 @@ When running as an MCP server, the tool exposes actions that Copilot can invoke "name": "maui_doctor_fix", "description": "Attempt to fix detected environment issues", "requires_approval": true - }, - { - "name": "maui_diagnostic_bundle", - "description": "Generate diagnostic bundle for troubleshooting", - "requires_approval": false - }, - { - "name": "maui_config_set", - "description": "Update tool configuration (e.g., proxy settings)", - "requires_approval": true } ] } @@ -257,7 +247,7 @@ When invoked by an AI agent, certain operations require explicit user confirmati | `device.screenshot` | `device.capture` | IDE prompt | | `doctor.fix` | `environment.modify` | IDE prompt with details | | `android.sdk.install` | `environment.modify` | IDE prompt with package list | -| `android.avd.create` | `device.create` | IDE prompt | +| `android.emulator.create` | `device.create` | IDE prompt | | `logs.stream` | `device.logs` | IDE prompt | **Permission Flow**: diff --git a/docs/design/maui-devtools-ide-integration.md b/docs/design/maui-devtools-ide-integration.md index 7cddb3f73641..4d3d573a9cda 100644 --- a/docs/design/maui-devtools-ide-integration.md +++ b/docs/design/maui-devtools-ide-integration.md @@ -86,7 +86,7 @@ $(error) MAUI: Setup Required ← Red when critical │ ├── ✓ Android SDK (/Users/dev/Android/sdk) │ │ ├── ✓ Build Tools 34.0.0 │ │ ├── ⚠ Emulator not running [Start] │ -│ └── ✓ AVD: Pixel_5_API_34 │ +│ └── ✓ Emulator: Pixel_5_API_34 │ │ │ │ iOS / macOS (Xcode 16.0) │ │ ├── ✓ iOS 18.0 Runtime │ @@ -115,7 +115,7 @@ $(error) MAUI: Setup Required ← Red when critical │ ✓ Installing build-tools;34.0.0 │ │ ● Installing system-images;android-34;google_apis;x86_64 │ │ ████████████░░░░░░░░░░░░░░░░░░░░░░ 45% (1.2 GB/2.6 GB)│ -│ ○ Creating AVD Pixel_5_API_34 │ +│ ○ Creating Emulator Pixel_5_API_34 │ │ ○ Verifying setup │ │ │ │ ─────────────────────────────────────────────────────────│ @@ -186,11 +186,11 @@ Tools │ ├── ───────────────────────── │ ├── Android │ │ ├── SDK Manager... -│ │ ├── AVD Manager... +│ │ ├── Emulator Manager... │ │ └── Device Log... │ ├── iOS Simulators... │ └── ───────────────────────── -│ └── Diagnostic Bundle... +│ └── Environment Report... ``` ### Error List Integration @@ -225,11 +225,11 @@ Detailed logs available in Output window under "MAUI Dev Tools" pane: When running in interactive mode (terminal), the tool prompts for missing information: -**Example: AVD Creation with Missing Parameters**: +**Example: Emulator Creation with Missing Parameters**: ``` -$ dotnet maui android avd create +$ dotnet maui android emulator create -? AVD name: My_Pixel_5 +? Emulator name: My_Pixel_5 ? Select device profile: ❯ Pixel 5 (1080x2340, 440dpi) @@ -243,12 +243,12 @@ $ dotnet maui android avd create android-33 | Google APIs | x86_64 (more...) -Creating AVD 'My_Pixel_5'... done +Creating emulator 'My_Pixel_5'... done ``` **Non-Interactive Mode**: ``` -$ dotnet maui android avd create --non-interactive +$ dotnet maui android emulator create --non-interactive Error: --name is required in non-interactive mode ``` diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index a7b469630294..f3b91575c4be 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.9-draft +**Version**: 2.10-draft **Status**: Proposal **Last Updated**: 2026-02-10 @@ -154,7 +154,7 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-A7 | Stop running emulator | P1 | | FR-A8 | Cold boot emulator (wipe runtime state) | P1 | | FR-A9 | Wipe emulator data | P2 | -| FR-A10 | Stream logcat output with filtering | P1 | +| FR-A10 | Stream device logs with filtering | P1 | | FR-A11 | Install APK to device/emulator | P1 | | FR-A12 | Uninstall package from device/emulator | P2 | | FR-A13 | Capture screenshot from device/emulator | P0 | @@ -206,7 +206,7 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-S6 | Support `--format` flag (png, jpg) | P2 | | FR-S7 | Return file path in JSON output | P0 | -### 4.5 Device Listing (Unified) +### 4.6 Device Listing (Unified) | ID | Requirement | Priority | |----|-------------|----------| @@ -310,7 +310,7 @@ Add to your shell profile (~/.zshrc or ~/.bashrc): export PATH="$JAVA_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH" ``` -**AVD Creation with Auto-Detection**: +**Emulator Creation with Auto-Detection**: When `--package` is not specified, the tool automatically detects the most recent installed system image: @@ -331,8 +331,8 @@ dotnet maui android emulator create MyEmulator --package "system-images;android- | `READY` | `xcrun simctl list` succeeds | Delegate all operations to native tools | **Important**: Apple install is limited because: -- Xcode cannot be installed programmatically (App Store only) -- Runtime downloads require Xcode to be open at least once (license acceptance) +- Xcode cannot be installed fully unattended (App Store or interactive install with Apple ID credentials) +- Xcode license can be accepted programmatically (`xcodebuild -license accept`) via `apple xcode accept-licenses` ```bash # Basic setup check @@ -904,7 +904,7 @@ dotnet maui device screenshot --device emulator-5554 dotnet maui android sdk install platforms;android-34 dotnet maui android emulator create --name Pixel_8 --device pixel_8 dotnet maui android emulator start --name Pixel_8 --wait -dotnet maui android logcat --device emulator-5554 +dotnet maui device logs --device emulator-5554 # Apple-specific (macOS only) dotnet maui apple install # Check Xcode + runtimes @@ -971,7 +971,7 @@ All commands follow a consistent exit code scheme: | 2 | Operation failed | Command failed (network error, invalid input, etc.) | | 3 | Permission denied | Elevation required but not granted | | 4 | User canceled | User declined confirmation prompt | -| 5 | Resource not found | Requested device/AVD/simulator not found | +| 5 | Resource not found | Requested device/emulator/simulator not found | | 126 | Command not executable | Binary not found or not executable | | 127 | Command not found | Unknown subcommand | @@ -1249,7 +1249,7 @@ All telemetry and logs follow these redaction rules: | P1 | Visual Studio extension integration | | P1 | iOS runtime installation guidance | | P1 | `--non-interactive`, `--correlation-id`, `--offline` global options | -| P2 | AVD snapshot management | +| P2 | Emulator snapshot management | | P2 | Windows SDK management | | P2 | Linux host support (Android only) | | P2 | Physical iOS device support (requires signing) | From 10b1261f9ea290c1cfc5c7fcafeeb5926d9bcc93 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 10 Feb 2026 20:26:33 +0000 Subject: [PATCH 18/34] Update maui-devtools-spec.md --- docs/design/maui-devtools-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index f3b91575c4be..4aac2ecd7334 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1115,7 +1115,7 @@ The unified device model for all platforms (physical devices, emulators, simulat | `dotnet maui device list` | ✓ | ✓ | No | | `dotnet maui device screenshot` | ✓ | ✓ | No | | `dotnet maui android sdk list` | ✓ | ✓ | No | -| `dotnet maui android sdk install` | ✓ | ✓ | No | +| `dotnet maui android sdk install` | ✓ | ✓ | Sometimes* | | `dotnet maui android sdk accept-licenses` | ✓ | ✓ | No | | `dotnet maui android emulator create` | ✓ | ✓ | No | | `dotnet maui android emulator start` | ✓ | ✓ | No | @@ -1123,7 +1123,7 @@ The unified device model for all platforms (physical devices, emulators, simulat | `dotnet maui android emulator delete` | ✓ | ✓ | No | | `dotnet maui android install` | ✓ | ✓ | No | | `dotnet maui android jdk check` | ✓ | ✓ | No | -| `dotnet maui android jdk install` | ✓ | ✓ | No | +| `dotnet maui android jdk install` | ✓ | ✓ | Sometimes* | | `dotnet maui android jdk list` | ✓ | ✓ | No | | `dotnet maui apple simulator list` | — | ✓ | No | | `dotnet maui apple simulator start` | — | ✓ | No | From 995705b535dafdfc2dd872438d1ea358194161bf Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Tue, 10 Feb 2026 20:30:32 +0000 Subject: [PATCH 19/34] Add info about elevation --- docs/design/maui-devtools-ai-integration.md | 38 +++-- docs/design/maui-devtools-spec.md | 170 ++++++++++++++++---- 2 files changed, 158 insertions(+), 50 deletions(-) diff --git a/docs/design/maui-devtools-ai-integration.md b/docs/design/maui-devtools-ai-integration.md index b0aa81215ae2..37e79fb82ce0 100644 --- a/docs/design/maui-devtools-ai-integration.md +++ b/docs/design/maui-devtools-ai-integration.md @@ -238,17 +238,17 @@ When escalating to Copilot: ### Permission Gates -When invoked by an AI agent, certain operations require explicit user confirmation: - -| Operation | Permission Required | Confirmation UI | -|-----------|---------------------|-----------------| -| `doctor.status` | None | — | -| `device.list` | None | — | -| `device.screenshot` | `device.capture` | IDE prompt | -| `doctor.fix` | `environment.modify` | IDE prompt with details | -| `android.sdk.install` | `environment.modify` | IDE prompt with package list | -| `android.emulator.create` | `device.create` | IDE prompt | -| `logs.stream` | `device.logs` | IDE prompt | +When invoked by an AI agent, certain operations require explicit user confirmation. The complete mapping of commands to permission gates is defined in the **[Capabilities Model (§7.3)](./maui-devtools-spec.md#73-capabilities-model)** in the main specification. + +**Permission summary by gate**: + +| Permission | Operations | Confirmation UI | +|------------|-----------|-----------------| +| None | `doctor.status`, `device.list`, `sdk.list`, `simulator.list`, `runtime.list`, `xcode.list` | — | +| `device.capture` | `device.screenshot` | IDE prompt | +| `device.logs` | `device.logs` (streaming) | IDE prompt | +| `device.create` | `android.emulator.create/delete`, `apple.simulator.create/delete` | IDE prompt | +| `environment.modify` | `doctor.fix`, `android.sdk.install`, `android.install`, `android.jdk.install`, `apple.install`, `apple.runtime.install`, `apple.xcode.select`, `apple.xcode.accept-licenses` | IDE prompt with details | **Permission Flow**: ``` @@ -322,14 +322,18 @@ AI agent calls are sandboxed: ### Elevation Handling -When an operation requires elevation: +> **See [Elevation Model (§5.4)](./maui-devtools-spec.md#54-security)** in the main spec for full platform-specific elevation flows. + +When an operation requires OS elevation, AI agents have additional constraints: -| Platform | Mechanism | User Experience | -|----------|-----------|-----------------| -| macOS | `sudo` prompt in terminal; Authorization Services in GUI | System password dialog | -| Windows | UAC prompt | Standard elevation dialog | +| Scenario | AI Agent Behavior | +|----------|-------------------| +| Elevation needed (Windows UAC) | Agent receives `E5001` error. Cannot auto-approve UAC. Must inform user and suggest running from elevated terminal or using default user-writable paths. | +| Elevation needed (macOS sudo) | Agent receives `E5001` error. Cannot provide sudo password. Must inform user and suggest running the command manually. | +| Default paths (no elevation) | Agent can proceed normally with `environment.modify` permission gate. | +| CI environment (`--ci` flag) | Assumes pre-authorized. No elevation prompts — fails with `E5001` if permissions insufficient. | -**For AI Agents**: Elevated operations cannot be auto-approved. Agent receives error `E5001` with message explaining elevation requirement. User must run command manually or through IDE's privileged execution path. +**Key rule**: Elevated operations are **never auto-approved** by AI agents. The agent must always inform the user and provide alternatives (e.g., installing to a user-writable default path instead). --- diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 4aac2ecd7334..c3771701fe1f 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -437,6 +437,98 @@ IDE consumers can use the `type: "progress"` messages to update progress bars an | NFR-S3 | Elevation must be requested explicitly with clear justification | | NFR-S4 | AI agent calls must respect permission gates (see Security Model) | +#### Elevation Model + +Some operations require OS-level elevation when targeting system-protected paths. The tool **never silently elevates** — it always detects the need first, then delegates to the platform's native elevation mechanism. + +**When Elevation is Required**: + +| Scenario | Platform | Example | +|----------|----------|---------| +| Android SDK/JDK install to system path | Windows | Installing to `C:\Program Files\Android\sdk` | +| Android SDK/JDK install to system path | macOS | Installing to `/opt/android-sdk` (rare — default is user home) | +| Xcode selection | macOS | `xcode-select -s` requires `sudo` | +| Xcode license acceptance | macOS | `xcodebuild -license accept` requires `sudo` | +| iOS runtime installation | macOS | `xcodebuild -downloadPlatform iOS` requires admin | +| Enable Developer Mode | Windows | Requires Settings app (no CLI elevation path) | + +**Windows Elevation Flow**: + +When the tool detects that the target install path requires elevation (e.g., `Program Files`): + +1. The tool detects the current process is **not elevated** +2. It launches a **new elevated process** via `ProcessStartInfo` with `Verb = "runas"`, which triggers the standard UAC prompt +3. The elevated child process performs the install operation +4. The parent process monitors the child and reports progress/result +5. If the user declines UAC, the tool returns error `E5001` + +``` +┌─────────────────────────────────────────────────────────────┐ +│ dotnet maui android install --sdk-path "C:\Program Files\ │ +│ Android\sdk" │ +├─────────────────────────────────────────────────────────────┤ +│ 1. Detect: target path requires elevation │ +│ 2. Prompt: "Installing to a system path requires admin │ +│ permissions. Continue? [Y/n]" │ +│ 3. Launch: elevated child process (UAC dialog appears) │ +│ 4. Child: performs SDK download + install │ +│ 5. Parent: streams progress from child, reports result │ +└─────────────────────────────────────────────────────────────┘ +``` + +**macOS Elevation Flow**: + +| Context | Mechanism | Details | +|---------|-----------|---------| +| Terminal | `sudo` | Tool re-invokes itself with `sudo` for the specific operation that needs it (e.g., `sudo xcode-select -s `) | +| IDE (VS Code / VS for Mac) | Authorization Services | IDE presents system password dialog via `AuthorizationExecuteWithPrivileges` or equivalent | +| CI | Pre-authorized | CI agents typically run with required permissions; use `--ci` flag to skip interactive prompts | + +``` +┌─────────────────────────────────────────────────────────────┐ +│ dotnet maui apple xcode select /Applications/Xcode.app │ +├─────────────────────────────────────────────────────────────┤ +│ 1. Detect: xcode-select requires sudo │ +│ 2. Invoke: sudo xcode-select -s /Applications/Xcode.app │ +│ 3. macOS shows system password prompt │ +│ 4. On success: report new active Xcode │ +│ 5. On failure: return E5001 with guidance │ +└─────────────────────────────────────────────────────────────┘ +``` + +**Default Paths Avoid Elevation**: + +By default, the tool installs to **user-writable paths** that do not require elevation: + +| Platform | Default JDK Path | Default SDK Path | Elevation Needed | +|----------|------------------|------------------|------------------| +| macOS | `~/Library/Developer/Android/jdk` | `~/Library/Developer/Android/sdk` | No | +| Windows | `%LOCALAPPDATA%\Android\jdk` | `%LOCALAPPDATA%\Android\sdk` | No | + +Elevation is only triggered when the user explicitly specifies a system path via `--sdk-path`, `--jdk-path`, or for macOS operations that inherently require `sudo` (Xcode selection, license acceptance, runtime installs). + +**Error on Elevation Denial**: + +```json +{ + "code": "E5001", + "category": "user", + "message": "Operation requires elevated permissions", + "context": { + "operation": "android.sdk.install", + "target_path": "C:\\Program Files\\Android\\sdk", + "platform": "windows" + }, + "remediation": { + "type": "user_action", + "manual_steps": [ + "Run the command from an elevated terminal (Run as Administrator)", + "Or install to a user-writable path: dotnet maui android install --sdk-path %LOCALAPPDATA%\\Android\\sdk" + ] + } +} +``` + ### 5.5 Privacy | ID | Requirement | @@ -1108,39 +1200,51 @@ The unified device model for all platforms (physical devices, emulators, simulat ### 7.3 Capabilities Model -| Command | Windows | macOS | Requires Elevation | -|---------|---------|-------|-------------------| -| `doctor` | ✓ | ✓ | No | -| `doctor --fix` | ✓ | ✓ | Sometimes* | -| `dotnet maui device list` | ✓ | ✓ | No | -| `dotnet maui device screenshot` | ✓ | ✓ | No | -| `dotnet maui android sdk list` | ✓ | ✓ | No | -| `dotnet maui android sdk install` | ✓ | ✓ | Sometimes* | -| `dotnet maui android sdk accept-licenses` | ✓ | ✓ | No | -| `dotnet maui android emulator create` | ✓ | ✓ | No | -| `dotnet maui android emulator start` | ✓ | ✓ | No | -| `dotnet maui android emulator stop` | ✓ | ✓ | No | -| `dotnet maui android emulator delete` | ✓ | ✓ | No | -| `dotnet maui android install` | ✓ | ✓ | No | -| `dotnet maui android jdk check` | ✓ | ✓ | No | -| `dotnet maui android jdk install` | ✓ | ✓ | Sometimes* | -| `dotnet maui android jdk list` | ✓ | ✓ | No | -| `dotnet maui apple simulator list` | — | ✓ | No | -| `dotnet maui apple simulator start` | — | ✓ | No | -| `dotnet maui apple simulator stop` | — | ✓ | No | -| `dotnet maui apple simulator create` | — | ✓ | No | -| `dotnet maui apple simulator delete` | — | ✓ | No | -| `dotnet maui apple install` | — | ✓ | Sometimes* | -| `dotnet maui apple runtime check` | — | ✓ | No | -| `dotnet maui apple runtime list` | — | ✓ | No | -| `dotnet maui apple runtime install` | — | ✓ | Yes (admin) | -| `dotnet maui apple xcode check` | — | ✓ | No | -| `dotnet maui apple xcode list` | — | ✓ | No | -| `dotnet maui apple xcode select` | — | ✓ | Yes (sudo) | -| `dotnet maui apple xcode accept-licenses` | — | ✓ | Yes (sudo) | -| `dotnet maui device logs` | ✓ | ✓ | No | - -*Elevation required for: installing Android SDK to system locations, installing Xcode runtimes +| Command | Windows | macOS | OS Elevation | AI Agent Permission | +|---------|---------|-------|-------------|---------------------| +| `doctor` | ✓ | ✓ | No | None | +| `doctor --fix` | ✓ | ✓ | Sometimes* | `environment.modify` | +| `dotnet maui device list` | ✓ | ✓ | No | None | +| `dotnet maui device screenshot` | ✓ | ✓ | No | `device.capture` | +| `dotnet maui device logs` | ✓ | ✓ | No | `device.logs` | +| `dotnet maui android sdk list` | ✓ | ✓ | No | None | +| `dotnet maui android sdk install` | ✓ | ✓ | Sometimes* | `environment.modify` | +| `dotnet maui android sdk accept-licenses` | ✓ | ✓ | No | `environment.modify` | +| `dotnet maui android emulator create` | ✓ | ✓ | No | `device.create` | +| `dotnet maui android emulator start` | ✓ | ✓ | No | None | +| `dotnet maui android emulator stop` | ✓ | ✓ | No | None | +| `dotnet maui android emulator delete` | ✓ | ✓ | No | `device.create` | +| `dotnet maui android install` | ✓ | ✓ | Sometimes* | `environment.modify` | +| `dotnet maui android jdk check` | ✓ | ✓ | No | None | +| `dotnet maui android jdk install` | ✓ | ✓ | Sometimes* | `environment.modify` | +| `dotnet maui android jdk list` | ✓ | ✓ | No | None | +| `dotnet maui apple simulator list` | — | ✓ | No | None | +| `dotnet maui apple simulator start` | — | ✓ | No | None | +| `dotnet maui apple simulator stop` | — | ✓ | No | None | +| `dotnet maui apple simulator create` | — | ✓ | No | `device.create` | +| `dotnet maui apple simulator delete` | — | ✓ | No | `device.create` | +| `dotnet maui apple install` | — | ✓ | Sometimes* | `environment.modify` | +| `dotnet maui apple runtime check` | — | ✓ | No | None | +| `dotnet maui apple runtime list` | — | ✓ | No | None | +| `dotnet maui apple runtime install` | — | ✓ | Yes (admin) | `environment.modify` | +| `dotnet maui apple xcode check` | — | ✓ | No | None | +| `dotnet maui apple xcode list` | — | ✓ | No | None | +| `dotnet maui apple xcode select` | — | ✓ | Yes (sudo) | `environment.modify` | +| `dotnet maui apple xcode accept-licenses` | — | ✓ | Yes (sudo) | `environment.modify` | + +*OS Elevation required for: installing Android SDK/JDK to system locations (e.g., `Program Files`), installing Xcode runtimes, switching Xcode, accepting Xcode licenses + +**AI Agent Permission Gates**: + +| Permission | Description | Default | +|------------|-------------|---------| +| None | Read-only operation — no approval required | Allow | +| `device.capture` | Capture screenshots or screen recordings | Prompt | +| `device.logs` | Stream device/simulator logs | Prompt | +| `device.create` | Create or delete emulators/simulators | Prompt | +| `environment.modify` | Install, update, or configure SDK/JDK/runtime components | Prompt | + +> **See [AI Agent Integration](./maui-devtools-ai-integration.md) §4** for permission storage, persistent permission schema, and sandbox boundaries. --- From a7eeb2b6a06325568eab0e1bf8fc420822aca1c8 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 11 Feb 2026 14:25:28 +0000 Subject: [PATCH 20/34] Fix cspell issues: scriptable, Blindspot, UDID, UDIDs --- docs/design/maui-devtools-spec.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index c3771701fe1f..d587f5a0b14a 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -44,7 +44,7 @@ This tool eliminates that friction by providing a single, authoritative source f |---------|---------------| | MAUI Developer (Windows) | One-command setup for Android development | | MAUI Developer (macOS) | Unified setup for Android + iOS/Mac Catalyst | -| CI Engineer | Headless, scriptable environment provisioning | +| CI Engineer | Headless, automatable environment provisioning | | AI Agent | Structured APIs for querying and fixing environment issues | | IDE (VS/VS Code) | Fast, reliable environment checks with actionable fixes | @@ -62,7 +62,7 @@ This tool eliminates that friction by providing a single, authoritative source f 4. **IDE Integration Gap**: Visual Studio and VS Code must independently implement detection and installation logic, leading to inconsistent experiences. -5. **AI Agent Blindspot**: AI coding assistants cannot reliably query environment state or propose fixes because there's no structured API. +5. **AI Agent Blind Spot**: AI coding assistants cannot reliably query environment state or propose fixes because there's no structured API. 6. **CI Complexity**: Setting up MAUI builds in CI requires extensive scripting and platform-specific knowledge. @@ -169,7 +169,7 @@ This tool eliminates that friction by providing a single, authoritative source f |----|-------------|----------| | FR-X1 | List available simulators with runtime/device type info | P0 | | FR-X2 | Filter simulators by runtime, device type, or state | P0 | -| FR-X3 | Start simulator by UDID or name | P0 | +| FR-X3 | Start simulator by UUID or name | P0 | | FR-X4 | Stop simulator | P0 | | FR-X5 | Create simulator with specified runtime and device type | P0 | | FR-X6 | Delete simulator | P2 | @@ -1317,7 +1317,7 @@ All telemetry and logs follow these redaction rules: | File paths | Replace with `` or keep structure | `/Users/name/code` → `/code` | | Device names | Replace with type | `John's iPhone` → `` | | Serial numbers | Redact | `R58M32XXXXX` → `` | -| UDIDs | Redact | `A1B2C3...` → `` | +| Simulator IDs | Redact | `A1B2C3...` → `` | | Error messages | Keep, unless contains path | Preserved | --- From 289879a87201c13645ae1d45e6ec59e7759b674c Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Mon, 16 Feb 2026 16:43:50 +0000 Subject: [PATCH 21/34] Rename CLI root command from 'dotnet maui' to 'maui' in spec Update all command references throughout the specification to use the standalone 'maui' command instead of 'dotnet maui'. The tool is now invoked as 'maui ' rather than 'dotnet maui '. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/maui-devtools-spec.md | 208 +++++++++++++++--------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index d587f5a0b14a..2ba50825fa4d 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,8 +1,8 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.10-draft +**Version**: 2.11-draft **Status**: Proposal -**Last Updated**: 2026-02-10 +**Last Updated**: 2026-02-16 --- @@ -101,7 +101,7 @@ This tool eliminates that friction by providing a single, authoritative source f **DP1: Delegate to Native Toolchains** — Do not reimplement. Use `sdkmanager`, `avdmanager`, `adb`, `emulator` for Android; `xcrun simctl`, `xcode-select` for Apple; Windows SDK installer for Windows. Native tools are authoritative, reduce maintenance burden, and ensure consistency. -**DP2: Consolidate Existing VS Repositories** — Replace `ClientTools.android-acquisition` and `android-platform-support` with unified `dotnet maui android` commands across VS, VS Code, CLI, and CI. +**DP2: Consolidate Existing VS Repositories** — Replace `ClientTools.android-acquisition` and `android-platform-support` with unified `maui android` commands across VS, VS Code, CLI, and CI. **DP3: Stateless Architecture** — Each command reads state, acts, and exits. Uses file-system caching (`~/.maui/cache/`) with TTLs for performance. @@ -268,13 +268,13 @@ The tool can fully install an Android development environment from scratch, incl **Install Command**: ```bash # Full install: JDK + SDK + recommended packages -dotnet maui android install --accept-licenses +maui android install --accept-licenses # With custom paths -dotnet maui android install --jdk-path ~/my-jdk --sdk-path ~/my-sdk --accept-licenses +maui android install --jdk-path ~/my-jdk --sdk-path ~/my-sdk --accept-licenses # With specific packages (comma-separated) -dotnet maui android install --packages "platform-tools,build-tools;35.0.0,platforms;android-35" +maui android install --packages "platform-tools,build-tools;35.0.0,platforms;android-35" ``` This command: @@ -288,14 +288,14 @@ This command: **JDK Management Commands**: ```bash # Check JDK status -dotnet maui android jdk check +maui android jdk check # Install OpenJDK (default: version 17) -dotnet maui android jdk install -dotnet maui android jdk install --version 21 +maui android jdk install +maui android jdk install --version 21 # List installed JDK versions -dotnet maui android jdk list +maui android jdk list ``` **Environment Variable Guidance Output**: @@ -316,10 +316,10 @@ When `--package` is not specified, the tool automatically detects the most recen ```bash # Auto-detect system image (uses highest API level installed) -dotnet maui android emulator create MyEmulator +maui android emulator create MyEmulator # Explicitly specify system image -dotnet maui android emulator create MyEmulator --package "system-images;android-35;google_apis;arm64-v8a" +maui android emulator create MyEmulator --package "system-images;android-35;google_apis;arm64-v8a" ``` #### Apple Install @@ -336,13 +336,13 @@ dotnet maui android emulator create MyEmulator --package "system-images;android- ```bash # Basic setup check -dotnet maui apple install +maui apple install # Accept licenses automatically -dotnet maui apple install --accept-licenses +maui apple install --accept-licenses # Also install a specific iOS runtime -dotnet maui apple install --runtime 18.5 --accept-licenses +maui apple install --runtime 18.5 --accept-licenses ``` This command: @@ -464,7 +464,7 @@ When the tool detects that the target install path requires elevation (e.g., `Pr ``` ┌─────────────────────────────────────────────────────────────┐ -│ dotnet maui android install --sdk-path "C:\Program Files\ │ +│ maui android install --sdk-path "C:\Program Files\ │ │ Android\sdk" │ ├─────────────────────────────────────────────────────────────┤ │ 1. Detect: target path requires elevation │ @@ -486,7 +486,7 @@ When the tool detects that the target install path requires elevation (e.g., `Pr ``` ┌─────────────────────────────────────────────────────────────┐ -│ dotnet maui apple xcode select /Applications/Xcode.app │ +│ maui apple xcode select /Applications/Xcode.app │ ├─────────────────────────────────────────────────────────────┤ │ 1. Detect: xcode-select requires sudo │ │ 2. Invoke: sudo xcode-select -s /Applications/Xcode.app │ @@ -523,7 +523,7 @@ Elevation is only triggered when the user explicitly specifies a system path via "type": "user_action", "manual_steps": [ "Run the command from an elevated terminal (Run as Administrator)", - "Or install to a user-writable path: dotnet maui android install --sdk-path %LOCALAPPDATA%\\Android\\sdk" + "Or install to a user-writable path: maui android install --sdk-path %LOCALAPPDATA%\\Android\\sdk" ] } } @@ -570,8 +570,8 @@ Elevation is only triggered when the user explicitly specifies a system path via | WSL2 | ✓ (experimental) | — | Partial | ✓ | When emulator/simulator unavailable: -- `dotnet maui doctor` reports capability with reason (e.g., "emulator: unavailable (virtualization disabled)") -- `dotnet maui android emulator start` fails fast with `E2010` "Hardware acceleration unavailable" +- `maui doctor` reports capability with reason (e.g., "emulator: unavailable (virtualization disabled)") +- `maui android emulator start` fails fast with `E2010` "Hardware acceleration unavailable" --- @@ -632,7 +632,7 @@ When emulator/simulator unavailable: - Maps commands to core service calls - Formats output for human consumption (colors, tables, progress bars) - Supports `--json` for machine-readable output -- Entry point: `dotnet maui` command +- Entry point: `maui` command #### Core Services @@ -698,7 +698,7 @@ User: maui doctor --json > **See [IDE Integration](./maui-devtools-ide-integration.md)** for detailed VS Code and Visual Studio UI flows, status panels, and menu integrations. -**Summary**: IDEs spawn `dotnet maui` as a child process, invoke `dotnet maui doctor --json` on workspace open, display issues in their problems/error list panels, and provide commands for environment setup with progress notifications. +**Summary**: IDEs spawn `maui` as a child process, invoke `maui doctor --json` on workspace open, display issues in their problems/error list panels, and provide commands for environment setup with progress notifications. ### 6.5 Concurrency Model @@ -721,7 +721,7 @@ When multiple SDK installations are detected: 5. Default location (`~/Library/Android/sdk` on macOS, `%LOCALAPPDATA%\Android\Sdk` on Windows) **Conflict Handling**: -- `dotnet maui doctor` reports all detected SDKs with recommendation +- `maui doctor` reports all detected SDKs with recommendation - `--sdk-path` flag available on all android commands for one-off override **Android Studio Coexistence**: @@ -769,7 +769,7 @@ Errors are classified into three categories: }, "remediation": { "type": "auto_fixable", - "command": "dotnet maui android sdk accept-licenses", + "command": "maui android sdk accept-licenses", "manual_steps": null }, "docs_url": "https://learn.microsoft.com/dotnet/maui/troubleshoot/E2001", @@ -820,7 +820,7 @@ When the tool encounters an error it doesn't recognize: "eligible": true, "context": { "doctor_report": { ... }, - "failed_command": "dotnet maui android emulator create ...", + "failed_command": "maui android emulator create ...", "environment": { ... }, "native_tool_output": "..." } @@ -849,13 +849,13 @@ This is the **Copilot escalation trigger** — structured data that AI agents ca ```bash # Default: Human-readable (stderr for errors, stdout for results) -dotnet maui doctor +maui doctor # Machine-readable: JSON to stdout (errors included in JSON, not stderr) -dotnet maui doctor --json +maui doctor --json # CI mode: JSON output, no prompts, warnings become errors -dotnet maui doctor --ci +maui doctor --ci ``` **JSON output envelope:** @@ -877,12 +877,12 @@ dotnet maui doctor --ci ### 7.1 CLI Commands -The tool is invoked as `dotnet maui `, integrating naturally with the .NET CLI. Platform-specific commands use the target framework moniker pattern (`ios`, `android`, `maccatalyst`, `windows`). +The tool is invoked as `maui ` as a standalone CLI tool. Platform-specific commands use the target framework moniker pattern (`ios`, `android`, `maccatalyst`, `windows`). #### Command Hierarchy ``` -dotnet maui +maui ├── doctor # Check environment health │ ├── --fix # Auto-fix all detected issues │ ├── --platform

# Filter: dotnet, android, apple, windows @@ -985,36 +985,36 @@ dotnet maui **Command Examples**: ```bash # Cross-platform commands -dotnet maui doctor -dotnet maui doctor --fix -dotnet maui device list # List all devices (physical + emulators + simulators) -dotnet maui device list --platform android # Android devices and emulators -dotnet maui device list --platform ios # iOS simulators and physical devices -dotnet maui device screenshot --device emulator-5554 +maui doctor +maui doctor --fix +maui device list # List all devices (physical + emulators + simulators) +maui device list --platform android # Android devices and emulators +maui device list --platform ios # iOS simulators and physical devices +maui device screenshot --device emulator-5554 # Android-specific -dotnet maui android sdk install platforms;android-34 -dotnet maui android emulator create --name Pixel_8 --device pixel_8 -dotnet maui android emulator start --name Pixel_8 --wait -dotnet maui device logs --device emulator-5554 +maui android sdk install platforms;android-34 +maui android emulator create --name Pixel_8 --device pixel_8 +maui android emulator start --name Pixel_8 --wait +maui device logs --device emulator-5554 # Apple-specific (macOS only) -dotnet maui apple install # Check Xcode + runtimes -dotnet maui apple install --accept-licenses # Also accept Xcode license -dotnet maui apple install --runtime 18.5 --accept-licenses # Full bootstrap -dotnet maui apple simulator list -dotnet maui apple simulator start -dotnet maui apple runtime check -dotnet maui apple runtime list -dotnet maui apple runtime list --available # Show downloadable runtimes -dotnet maui apple runtime install 18.5 # Install specific runtime -dotnet maui apple xcode check -dotnet maui apple xcode list -dotnet maui apple xcode select /Applications/Xcode.app -dotnet maui apple xcode accept-licenses +maui apple install # Check Xcode + runtimes +maui apple install --accept-licenses # Also accept Xcode license +maui apple install --runtime 18.5 --accept-licenses # Full bootstrap +maui apple simulator list +maui apple simulator start +maui apple runtime check +maui apple runtime list +maui apple runtime list --available # Show downloadable runtimes +maui apple runtime install 18.5 # Install specific runtime +maui apple xcode check +maui apple xcode list +maui apple xcode select /Applications/Xcode.app +maui apple xcode accept-licenses # Windows-specific -dotnet maui windows developer-mode status +maui windows developer-mode status ``` #### Global Options (Available on All Commands) @@ -1071,29 +1071,29 @@ All commands follow a consistent exit code scheme: | Command | Description | Inputs | Output | Exit Codes | |---------|-------------|--------|--------|------------| -| `dotnet maui doctor` | Check environment health | `--fix`, `--platform`, `--json` | Status report | 0=healthy, 1=issues, 2=error | -| `dotnet maui device list` | List available devices | `--platform`, `--json` | Device list | 0=success, 2=error | -| `dotnet maui device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 5=no device, 2=error | -| `dotnet maui android sdk list` | List SDK packages | `--available`, `--all`, `--json` | Package list | 0=success, 2=error | -| `dotnet maui android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 5=not found, 2=error | -| `dotnet maui android emulator create` | Create emulator | `--name`, `--device`, `--package` | Emulator name | 0=success, 1=exists, 2=error | -| `dotnet maui android emulator start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | -| `dotnet maui android emulator stop` | Stop emulator | `` | Status | 0=success, 5=not found, 2=error | -| `dotnet maui android emulator delete` | Delete emulator | `--name` | Status | 0=success, 5=not found, 2=error | -| `dotnet maui apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | -| `dotnet maui apple simulator start` | Start simulator | `` | UDID | 0=success, 5=not found, 2=error | -| `dotnet maui apple simulator stop` | Stop simulator | `` | Status | 0=success, 5=not found, 2=error | -| `dotnet maui apple simulator create` | Create simulator | ` ` | UDID | 0=success, 2=error | -| `dotnet maui apple simulator delete` | Delete simulator | `` | Status | 0=success, 5=not found, 2=error | -| `dotnet maui apple runtime list` | List iOS runtimes | `--available`, `--all`, `--json` | Runtime list | 0=success, 2=error | -| `dotnet maui apple runtime check` | Check runtime status | `--json` | Status report | 0=success, 2=error | -| `dotnet maui apple runtime install` | Install iOS runtime | `` | Progress, result | 0=success, 2=error | -| `dotnet maui apple xcode check` | Check Xcode status | `--json` | Status report | 0=success, 2=error | -| `dotnet maui apple xcode list` | List Xcode installations | `--json` | Installation list | 0=success, 2=error | -| `dotnet maui apple xcode select` | Switch active Xcode | `` | Confirmation | 0=success, 3=permission denied | -| `dotnet maui apple xcode accept-licenses` | Accept Xcode license | `--json` | Status | 0=success, 3=permission denied | -| `dotnet maui apple install` | Set up Apple environment | `--runtime`, `--accept-licenses` | Progress, result | 0=success, 2=error | -| `dotnet maui android sdk accept-licenses` | Accept SDK licenses | `--json` | Status | 0=success, 2=error | +| `maui doctor` | Check environment health | `--fix`, `--platform`, `--json` | Status report | 0=healthy, 1=issues, 2=error | +| `maui device list` | List available devices | `--platform`, `--json` | Device list | 0=success, 2=error | +| `maui device screenshot` | Capture screenshot | `--device`, `--output`, `--wait` | File path | 0=success, 5=no device, 2=error | +| `maui android sdk list` | List SDK packages | `--available`, `--all`, `--json` | Package list | 0=success, 2=error | +| `maui android sdk install` | Install SDK package | ``, `--accept-licenses` | Progress, result | 0=success, 5=not found, 2=error | +| `maui android emulator create` | Create emulator | `--name`, `--device`, `--package` | Emulator name | 0=success, 1=exists, 2=error | +| `maui android emulator start` | Start emulator | `--name`, `--wait`, `--cold-boot` | Device serial | 0=success, 5=not found, 2=error | +| `maui android emulator stop` | Stop emulator | `` | Status | 0=success, 5=not found, 2=error | +| `maui android emulator delete` | Delete emulator | `--name` | Status | 0=success, 5=not found, 2=error | +| `maui apple simulator list` | List simulators | `--runtime`, `--device-type`, `--state` | Simulator list | 0=success, 2=error | +| `maui apple simulator start` | Start simulator | `` | UDID | 0=success, 5=not found, 2=error | +| `maui apple simulator stop` | Stop simulator | `` | Status | 0=success, 5=not found, 2=error | +| `maui apple simulator create` | Create simulator | ` ` | UDID | 0=success, 2=error | +| `maui apple simulator delete` | Delete simulator | `` | Status | 0=success, 5=not found, 2=error | +| `maui apple runtime list` | List iOS runtimes | `--available`, `--all`, `--json` | Runtime list | 0=success, 2=error | +| `maui apple runtime check` | Check runtime status | `--json` | Status report | 0=success, 2=error | +| `maui apple runtime install` | Install iOS runtime | `` | Progress, result | 0=success, 2=error | +| `maui apple xcode check` | Check Xcode status | `--json` | Status report | 0=success, 2=error | +| `maui apple xcode list` | List Xcode installations | `--json` | Installation list | 0=success, 2=error | +| `maui apple xcode select` | Switch active Xcode | `` | Confirmation | 0=success, 3=permission denied | +| `maui apple xcode accept-licenses` | Accept Xcode license | `--json` | Status | 0=success, 3=permission denied | +| `maui apple install` | Set up Apple environment | `--runtime`, `--accept-licenses` | Progress, result | 0=success, 2=error | +| `maui android sdk accept-licenses` | Accept SDK licenses | `--json` | Status | 0=success, 2=error | ### 7.2 JSON Output Schemas @@ -1204,33 +1204,33 @@ The unified device model for all platforms (physical devices, emulators, simulat |---------|---------|-------|-------------|---------------------| | `doctor` | ✓ | ✓ | No | None | | `doctor --fix` | ✓ | ✓ | Sometimes* | `environment.modify` | -| `dotnet maui device list` | ✓ | ✓ | No | None | -| `dotnet maui device screenshot` | ✓ | ✓ | No | `device.capture` | -| `dotnet maui device logs` | ✓ | ✓ | No | `device.logs` | -| `dotnet maui android sdk list` | ✓ | ✓ | No | None | -| `dotnet maui android sdk install` | ✓ | ✓ | Sometimes* | `environment.modify` | -| `dotnet maui android sdk accept-licenses` | ✓ | ✓ | No | `environment.modify` | -| `dotnet maui android emulator create` | ✓ | ✓ | No | `device.create` | -| `dotnet maui android emulator start` | ✓ | ✓ | No | None | -| `dotnet maui android emulator stop` | ✓ | ✓ | No | None | -| `dotnet maui android emulator delete` | ✓ | ✓ | No | `device.create` | -| `dotnet maui android install` | ✓ | ✓ | Sometimes* | `environment.modify` | -| `dotnet maui android jdk check` | ✓ | ✓ | No | None | -| `dotnet maui android jdk install` | ✓ | ✓ | Sometimes* | `environment.modify` | -| `dotnet maui android jdk list` | ✓ | ✓ | No | None | -| `dotnet maui apple simulator list` | — | ✓ | No | None | -| `dotnet maui apple simulator start` | — | ✓ | No | None | -| `dotnet maui apple simulator stop` | — | ✓ | No | None | -| `dotnet maui apple simulator create` | — | ✓ | No | `device.create` | -| `dotnet maui apple simulator delete` | — | ✓ | No | `device.create` | -| `dotnet maui apple install` | — | ✓ | Sometimes* | `environment.modify` | -| `dotnet maui apple runtime check` | — | ✓ | No | None | -| `dotnet maui apple runtime list` | — | ✓ | No | None | -| `dotnet maui apple runtime install` | — | ✓ | Yes (admin) | `environment.modify` | -| `dotnet maui apple xcode check` | — | ✓ | No | None | -| `dotnet maui apple xcode list` | — | ✓ | No | None | -| `dotnet maui apple xcode select` | — | ✓ | Yes (sudo) | `environment.modify` | -| `dotnet maui apple xcode accept-licenses` | — | ✓ | Yes (sudo) | `environment.modify` | +| `maui device list` | ✓ | ✓ | No | None | +| `maui device screenshot` | ✓ | ✓ | No | `device.capture` | +| `maui device logs` | ✓ | ✓ | No | `device.logs` | +| `maui android sdk list` | ✓ | ✓ | No | None | +| `maui android sdk install` | ✓ | ✓ | Sometimes* | `environment.modify` | +| `maui android sdk accept-licenses` | ✓ | ✓ | No | `environment.modify` | +| `maui android emulator create` | ✓ | ✓ | No | `device.create` | +| `maui android emulator start` | ✓ | ✓ | No | None | +| `maui android emulator stop` | ✓ | ✓ | No | None | +| `maui android emulator delete` | ✓ | ✓ | No | `device.create` | +| `maui android install` | ✓ | ✓ | Sometimes* | `environment.modify` | +| `maui android jdk check` | ✓ | ✓ | No | None | +| `maui android jdk install` | ✓ | ✓ | Sometimes* | `environment.modify` | +| `maui android jdk list` | ✓ | ✓ | No | None | +| `maui apple simulator list` | — | ✓ | No | None | +| `maui apple simulator start` | — | ✓ | No | None | +| `maui apple simulator stop` | — | ✓ | No | None | +| `maui apple simulator create` | — | ✓ | No | `device.create` | +| `maui apple simulator delete` | — | ✓ | No | `device.create` | +| `maui apple install` | — | ✓ | Sometimes* | `environment.modify` | +| `maui apple runtime check` | — | ✓ | No | None | +| `maui apple runtime list` | — | ✓ | No | None | +| `maui apple runtime install` | — | ✓ | Yes (admin) | `environment.modify` | +| `maui apple xcode check` | — | ✓ | No | None | +| `maui apple xcode list` | — | ✓ | No | None | +| `maui apple xcode select` | — | ✓ | Yes (sudo) | `environment.modify` | +| `maui apple xcode accept-licenses` | — | ✓ | Yes (sudo) | `environment.modify` | *OS Elevation required for: installing Android SDK/JDK to system locations (e.g., `Program Files`), installing Xcode runtimes, switching Xcode, accepting Xcode licenses From 270133d8d996de028b4ed436ccf44f4d84e7a857 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 19 Feb 2026 16:40:08 +0000 Subject: [PATCH 22/34] Add reference to Xamarin.Android.Tools.AndroidSdk reuse --- docs/design/maui-devtools-spec.md | 46 +++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 2ba50825fa4d..bf211fc66b15 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.11-draft +**Version**: 2.12-draft **Status**: Proposal **Last Updated**: 2026-02-16 @@ -647,7 +647,7 @@ When emulator/simulator unavailable: | Provider | Responsibility | |----------|----------------| -| Android Provider | Wraps `sdkmanager`, `avdmanager`, `adb`, `emulator` | +| Android Provider | Wraps `sdkmanager`, `avdmanager`, `adb`, `emulator`. Uses [`Xamarin.Android.Tools.AndroidSdk`](https://github.com/dotnet/android-tools) for SDK/JDK discovery (see §6.8). | | Apple Provider | Wraps `xcrun simctl`, `xcode-select`, `xcodebuild` | | Windows Provider | Wraps Windows SDK detection and VS build tools | @@ -720,6 +720,8 @@ When multiple SDK installations are detected: 4. Android Studio configured path (`~/.android/sdk` or registry) 5. Default location (`~/Library/Android/sdk` on macOS, `%LOCALAPPDATA%\Android\Sdk` on Windows) +> **Note:** This precedence order is implemented by `Xamarin.Android.Tools.AndroidSdk` (`AndroidSdkInfo`), ensuring consistent SDK resolution across MAUI DevTools, IDE extensions, and build tasks. See §6.8 for details. + **Conflict Handling**: - `maui doctor` reports all detected SDKs with recommendation - `--sdk-path` flag available on all android commands for one-off override @@ -738,7 +740,44 @@ When an existing SDK is detected: 3. **Non-Destructive**: Never delete or modify user's existing SDK without explicit consent 4. **Override Support**: `--sdk-path` for non-standard locations -### 6.8 Error Contract Specification +### 6.8 Shared Libraries & Code Reuse + +The Android Provider layer reuses the **[`Xamarin.Android.Tools.AndroidSdk`](https://github.com/dotnet/android-tools)** NuGet package (`dotnet/android-tools`) for SDK and JDK discovery. This library is the same shared component used by the .NET for Android build tooling and IDE extensions, ensuring consistent behavior across the ecosystem. + +#### What We Reuse from `Xamarin.Android.Tools.AndroidSdk` + +| Capability | Class | Why Reuse | +|-----------|-------|-----------| +| **Android SDK path discovery** | `AndroidSdkInfo` + `AndroidSdkBase` | Probes 15+ locations: `ANDROID_HOME`, `ANDROID_SDK_ROOT`, Windows registry (HKLM/HKCU for VS-installed SDKs), macOS Homebrew, Linux `/usr/lib/android-sdk`, Android Studio paths. Validates by checking for `adb` executable. | +| **JDK discovery** | `JdkInfo` + `*JdkLocations.cs` | Finds Microsoft OpenJDK, Eclipse Adoptium, Azul, Oracle, VS-bundled JDKs. Checks Windows registry (32/64-bit views), macOS `/usr/libexec/java_home`, Linux `update-java-alternatives`. Returns version, vendor, home path. | +| **SDK path validation** | `AndroidSdkBase.ValidateAndroidSdkLocation()` | Executable-based validation (checks for `adb`) rather than simple directory existence. | +| **Process/executable utilities** | `ProcessUtils` | PATHEXT-aware executable discovery (`FindExecutablesInDirectory`). | +| **Android version mapping** | `AndroidVersion` / `AndroidVersions` | Maps API levels ↔ version names/codenames for human-readable output. | + +#### What Remains in MAUI DevTools (Not in `android-tools`) + +| Capability | Rationale | +|-----------|-----------| +| **`sdkmanager` CLI wrapper** | `android-tools` discovers on-disk state; DevTools drives `sdkmanager` for install/uninstall/list operations. | +| **`avdmanager` / `emulator` management** | AVD create/start/stop/delete and emulator lifecycle are DevTools-only features. | +| **`adb` device management** | Device listing, logcat streaming, screenshot capture are DevTools-specific. | +| **JDK installation** | `android-tools` only discovers JDKs. DevTools adds download and install of Microsoft OpenJDK. | +| **OS elevation model** | UAC/sudo handling for SDK installs into protected paths (see §5.4). | +| **Apple & Windows providers** | Entirely DevTools-specific; `android-tools` is Android-only. | + +#### Future: Contributing Back to `android-tools` + +Where functionality matures in DevTools and would benefit the broader .NET Android ecosystem, we plan to contribute it upstream to `dotnet/android-tools`: + +| Candidate | Current Home | Benefit of Upstreaming | +|-----------|-------------|----------------------| +| **JDK installation** | DevTools `JdkManager` | IDEs and build tasks could auto-install missing JDKs instead of just reporting errors. | +| **`sdkmanager` wrapper** | DevTools `SdkManager` | IDE extensions could install SDK packages programmatically using a shared, tested API. | +| **License acceptance** | DevTools `SdkManager.AcceptLicensesAsync()` | Unattended CI scenarios across all .NET Android tooling. | + +This approach ensures DevTools benefits from the battle-tested discovery logic in `android-tools` while contributing installation and management capabilities back to the ecosystem over time. + +### 6.9 Error Contract Specification **This is the highest-priority architectural element.** Every consumer (AI agents, CI pipelines, IDEs, humans) depends on predictable error handling. @@ -1376,6 +1415,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| +| 2.12-draft | 2026-02-19 | Added §6.8 Shared Libraries & Code Reuse — documents reuse of `Xamarin.Android.Tools.AndroidSdk` for SDK/JDK discovery and plan to contribute JDK installation, sdkmanager wrapper, license acceptance back to `dotnet/android-tools` | | 2.10-draft | 2026-02-10 | Added `apple install` bootstrap command (Xcode + license + runtime), `runtime check`, `runtime list --available/--all`, `runtime install `, `xcode check`, `xcode accept-licenses`; changed `doctor --category` → `doctor --platform`; changed `emulator stop ` → `emulator stop ` for consistency | | 2.9-draft | 2026-02-10 | Unified command naming: renamed `avd` → `emulator` for Android, `simulator boot` → `simulator start`, `simulator shutdown` → `simulator stop` for Apple — consistent start/stop verbs across platforms | | 2.8-draft | 2026-02-09 | Synced with implementation: renamed `bootstrap` → `install` per PR feedback; removed `deploy`, `config`, `diagnostic-bundle` commands (covered by `dotnet run`/`dotnet build`); removed telemetry section (vNext); added Xcode list/select, XcodeInstallation schema, Android device field semantics, `type`/`state`/`details` to MauiDevice | From e4ff231df14df8e45d8ef0f899a212f826e7d860 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 19 Feb 2026 17:09:13 +0000 Subject: [PATCH 23/34] Commit reuse of android-platform --- docs/design/maui-devtools-spec.md | 92 ++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 15 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index bf211fc66b15..f49193bad707 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.12-draft +**Version**: 2.13-draft **Status**: Proposal **Last Updated**: 2026-02-16 @@ -750,32 +750,93 @@ The Android Provider layer reuses the **[`Xamarin.Android.Tools.AndroidSdk`](htt |-----------|-------|-----------| | **Android SDK path discovery** | `AndroidSdkInfo` + `AndroidSdkBase` | Probes 15+ locations: `ANDROID_HOME`, `ANDROID_SDK_ROOT`, Windows registry (HKLM/HKCU for VS-installed SDKs), macOS Homebrew, Linux `/usr/lib/android-sdk`, Android Studio paths. Validates by checking for `adb` executable. | | **JDK discovery** | `JdkInfo` + `*JdkLocations.cs` | Finds Microsoft OpenJDK, Eclipse Adoptium, Azul, Oracle, VS-bundled JDKs. Checks Windows registry (32/64-bit views), macOS `/usr/libexec/java_home`, Linux `update-java-alternatives`. Returns version, vendor, home path. | +| **JDK installation** | `JdkInstaller` *(planned)* | Will be contributed from `android-platform-support`'s `JavaDependencyInstaller`. Downloads Microsoft OpenJDK from manifest feed, extracts, validates. | +| **`sdkmanager` wrapper** | `SdkManager` *(planned)* | Will be contributed from `android-platform-support`. Wraps `sdkmanager` CLI for install/uninstall/list/update operations and license acceptance. | | **SDK path validation** | `AndroidSdkBase.ValidateAndroidSdkLocation()` | Executable-based validation (checks for `adb`) rather than simple directory existence. | | **Process/executable utilities** | `ProcessUtils` | PATHEXT-aware executable discovery (`FindExecutablesInDirectory`). | | **Android version mapping** | `AndroidVersion` / `AndroidVersions` | Maps API levels ↔ version names/codenames for human-readable output. | -#### What Remains in MAUI DevTools (Not in `android-tools`) +#### What We Reuse from `android-platform-support` (Internal) + +The **`android-platform-support`** repository (internal, `devdiv/android-platform-support`) contains the shared SDK installer backend used by VS for Mac, the Android SDK Manager UI, and the Device Manager. Key components we can reuse or draw from: + +| Capability | Project / Class | Why Reuse | +|-----------|----------------|-----------| +| **Manifest feed parsing** | `XamarinRepository` + `GoogleV2Repository` | Parses the Xamarin Android Manifest Feed and Google's `repository2-3.xml`. Provides download URLs, checksums, and version metadata — no hardcoded URLs needed (see §6.8.1). | +| **License acceptance** | `AndroidLicensesStorage` | Battle-tested subprocess orchestration of `sdkmanager --licenses`. Handles interactive Y/N prompts, writes license hashes to `$SDK_ROOT/licenses/`, platform-specific `sdkmanager.bat` vs `sdkmanager`. | +| **AVD discovery** | `Mono.AndroidTools` / `AndroidVirtualDeviceManager` | Filesystem watcher-based AVD enumeration. Read-only; create/start/stop/delete remain in DevTools. | +| **Manifest caching** | `LocalManifestProvider` | Offline/CI support: caches downloaded manifests to disk with fallback URLs. | +| **Progress reporting** | `Xamarin.Installer.Common` / `InstallationProgressEventArgs` | Structured progress events (0-100%) for CLI and IDE consumption. | + +> **Note:** `android-platform-support` also contains `AndroidSDKInstaller` (full SDK install pipeline) and `Mono.AndroidTools` / `AdbClient` (raw TCP ADB protocol). These are not reused initially — DevTools will bootstrap by unzipping command-line tools from the manifest feed and then delegating to `sdkmanager` for package operations, and will use the `adb` CLI for device communication. We may revisit reusing these components in the future. +> +> JDK installation (`JavaDependencyInstaller`) and `sdkmanager` wrapper logic will be contributed from `android-platform-support` to the public `dotnet/android-tools` package, where DevTools will consume them (see table above). + +#### 6.8.1 Manifest-Driven Downloads & Checksum Verification + +**No download URLs are hardcoded.** All SDK and JDK download URLs are resolved from manifest feeds at runtime: + +| Feed | URL | Contents | +|------|-----|----------| +| **Xamarin Android Manifest** | `https://aka.ms/AndroidManifestFeed/d{version}` (e.g., `d18-0`) | JDK archives (Microsoft OpenJDK), platform-tools, command-line tools, emulator — with per-platform/architecture URLs and SHA-1 checksums | +| **Google SDK Repository** | `https://dl.google.com/android/repository/repository2-3.xml` | SDK platforms, build-tools, system images, add-ons — Google's official package index with SHA-1 checksums | + +Every download is verified against the manifest's checksum before installation: + +``` +1. Resolve package → manifest feed lookup +2. Download archive → temp file +3. Compute SHA-1 of downloaded file +4. Compare against manifest checksum → mismatch = abort + error +5. Extract (unzip) to SDK directory +6. For SDK packages: delegate to extracted sdkmanager for install/update +``` + +**Bootstrap flow for `android install`:** +1. Read manifest feed → resolve command-line tools URL + checksum for current OS/arch +2. Download & SHA-1 verify command-line tools archive +3. Unzip to `$ANDROID_HOME/cmdline-tools/latest/` +4. Use the now-available `sdkmanager` to install remaining packages (platforms, build-tools, emulator, system images) + +This ensures: +- **No stale URLs** — feed is updated centrally via aka.ms redirect; DevTools always gets current URLs +- **Tamper detection** — SHA-1 verification catches corrupted or modified downloads +- **Consistency** — same manifest feed already used by VS SDK Manager, VS for Mac, and `android-platform-support` + +The manifest feed parsing infrastructure already exists in `android-platform-support`'s `XamarinRepository` and `GoogleV2Repository` classes. + +#### What Remains in MAUI DevTools (Not in Shared Libraries) | Capability | Rationale | |-----------|-----------| -| **`sdkmanager` CLI wrapper** | `android-tools` discovers on-disk state; DevTools drives `sdkmanager` for install/uninstall/list operations. | -| **`avdmanager` / `emulator` management** | AVD create/start/stop/delete and emulator lifecycle are DevTools-only features. | -| **`adb` device management** | Device listing, logcat streaming, screenshot capture are DevTools-specific. | -| **JDK installation** | `android-tools` only discovers JDKs. DevTools adds download and install of Microsoft OpenJDK. | +| **SDK bootstrap (command-line tools)** | DevTools downloads and unzips command-line tools from the manifest feed to bootstrap a fresh SDK. Subsequent package operations use the `sdkmanager` wrapper from `android-tools`. | +| **ADB device communication** | DevTools shells out to the `adb` CLI for device listing, logcat streaming, and screenshot capture. Simpler than integrating `Mono.AndroidTools`' raw TCP ADB protocol for now. | +| **CLI command routing** | `System.CommandLine`-based CLI layer, output formatting, `--json`/`--verbose` modes. | +| **`avdmanager` / `emulator` lifecycle** | AVD create/start/stop/delete — `android-platform-support` has read-only AVD discovery but no lifecycle management. | +| **`device screenshot`** | Not implemented in `Mono.AndroidTools`; DevTools uses `adb exec-out screencap`. | | **OS elevation model** | UAC/sudo handling for SDK installs into protected paths (see §5.4). | -| **Apple & Windows providers** | Entirely DevTools-specific; `android-tools` is Android-only. | +| **Apple & Windows providers** | Entirely DevTools-specific; shared Android libraries are Android-only. | + +#### Contributing to `dotnet/android-tools` + +The following capabilities will be moved from `android-platform-support` to the public `Xamarin.Android.Tools.AndroidSdk` package in `dotnet/android-tools`, making them available for DevTools and the broader ecosystem: + +| Capability | Source in `android-platform-support` | Benefit | +|-----------|--------------------------------------|---------| +| **JDK installation** | `JavaDependencyInstaller` | IDEs, build tasks, and DevTools can auto-install missing JDKs instead of just reporting errors. | +| **`sdkmanager` wrapper** | `AndroidSDKInstaller` + `SdkManager` logic | Shared API for install/uninstall/list operations — used by DevTools CLI, IDE extensions, and CI. | +| **License acceptance** | `AndroidLicensesStorage` | Unattended CI scenarios across all .NET Android tooling. | -#### Future: Contributing Back to `android-tools` +DevTools will consume these from the `Xamarin.Android.Tools.AndroidSdk` NuGet package once upstreamed. -Where functionality matures in DevTools and would benefit the broader .NET Android ecosystem, we plan to contribute it upstream to `dotnet/android-tools`: +#### Future Considerations -| Candidate | Current Home | Benefit of Upstreaming | -|-----------|-------------|----------------------| -| **JDK installation** | DevTools `JdkManager` | IDEs and build tasks could auto-install missing JDKs instead of just reporting errors. | -| **`sdkmanager` wrapper** | DevTools `SdkManager` | IDE extensions could install SDK packages programmatically using a shared, tested API. | -| **License acceptance** | DevTools `SdkManager.AcceptLicensesAsync()` | Unattended CI scenarios across all .NET Android tooling. | +| Candidate | Target | Benefit | +|-----------|--------|---------| +| **Device screenshot** | `android-platform-support` | Complement existing ADB operations in `Mono.AndroidTools`. | +| **ADB protocol integration** | DevTools | Replace `adb` CLI calls with `Mono.AndroidTools`' raw TCP protocol for better performance if needed. | -This approach ensures DevTools benefits from the battle-tested discovery logic in `android-tools` while contributing installation and management capabilities back to the ecosystem over time. +This approach ensures DevTools benefits from the battle-tested discovery and installation logic in shared libraries while contributing new capabilities back to the ecosystem over time. ### 6.9 Error Contract Specification @@ -1415,6 +1476,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| +| 2.13-draft | 2026-02-19 | Expanded §6.8: added `android-platform-support` reuse table (SDK installer, ADB protocol, manifest parsing, license acceptance), added §6.8.1 Manifest-Driven Downloads & Checksum Verification — no hardcoded URLs, SHA-1 verification from Xamarin/Google manifest feeds | | 2.12-draft | 2026-02-19 | Added §6.8 Shared Libraries & Code Reuse — documents reuse of `Xamarin.Android.Tools.AndroidSdk` for SDK/JDK discovery and plan to contribute JDK installation, sdkmanager wrapper, license acceptance back to `dotnet/android-tools` | | 2.10-draft | 2026-02-10 | Added `apple install` bootstrap command (Xcode + license + runtime), `runtime check`, `runtime list --available/--all`, `runtime install `, `xcode check`, `xcode accept-licenses`; changed `doctor --category` → `doctor --platform`; changed `emulator stop ` → `emulator stop ` for consistency | | 2.9-draft | 2026-02-10 | Unified command naming: renamed `avd` → `emulator` for Android, `simulator boot` → `simulator start`, `simulator shutdown` → `simulator stop` for Apple — consistent start/stop verbs across platforms | From 973fd9b7825230fdd27203a83e6baebe9abd7d6d Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 19 Feb 2026 17:33:54 +0000 Subject: [PATCH 24/34] Update spec with feedback for reuse --- docs/design/maui-devtools-ai-integration.md | 16 +++++------ docs/design/maui-devtools-ide-integration.md | 12 ++++---- docs/design/maui-devtools-spec.md | 29 ++++++++------------ 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/docs/design/maui-devtools-ai-integration.md b/docs/design/maui-devtools-ai-integration.md index 37e79fb82ce0..430f759eecf1 100644 --- a/docs/design/maui-devtools-ai-integration.md +++ b/docs/design/maui-devtools-ai-integration.md @@ -29,12 +29,12 @@ This tool is designed for three consumers in priority order: ```bash # Human-friendly (default) -dotnet maui doctor +maui doctor # ✓ .NET SDK 9.0.100 # ✗ Android SDK not found # Machine-friendly (for AI/CI) -dotnet maui doctor --json +maui doctor --json # { "status": "unhealthy", "checks": [...], "errors": [...] } ``` @@ -53,7 +53,7 @@ dotnet maui doctor --json **Journey**: 1. User asks: "My Android build is failing with 'SDK not found'" -2. Agent invokes: `dotnet maui doctor --json --platform android` +2. Agent invokes: `maui doctor --json --platform android` 3. Agent receives structured response: ```json { @@ -64,7 +64,7 @@ dotnet maui doctor --json "severity": "error", "message": "Android SDK not found", "fixable": true, - "fix_command": "dotnet maui android sdk install --recommended" + "fix_command": "maui android sdk install --recommended" } ] } @@ -145,7 +145,7 @@ Opening Copilot with diagnostic context... Run: gh copilot explain "MAUI SDK install failure E4001" Or copy this diagnostic summary: - dotnet maui doctor --json --verbose > /tmp/maui-diag.json + maui doctor --json --verbose > /tmp/maui-diag.json gh copilot explain --file /tmp/maui-diag.json ``` @@ -357,16 +357,16 @@ MAUI DevTools is designed with AI agents as first-class consumers: ```python # 1. Discover available devices -devices = run("dotnet maui device list --platform android --json") +devices = run("maui device list --platform android --json") # 2. Select appropriate device (first online emulator) device = next(d for d in devices if d["status"] == "Online" and d["type"] == "Emulator") # 3. Build and deploy (with user confirmation via IDE) -run(f"dotnet maui deploy --device {device['id']} --project ./MyApp.csproj") +run(f"maui deploy --device {device['id']} --project ./MyApp.csproj") # 4. Capture screenshot for verification -run(f"dotnet maui device screenshot --device {device['id']} --output ./screenshot.png") +run(f"maui device screenshot --device {device['id']} --output ./screenshot.png") ``` ### Error Contract for AI Agents diff --git a/docs/design/maui-devtools-ide-integration.md b/docs/design/maui-devtools-ide-integration.md index 4d3d573a9cda..0522144f2a26 100644 --- a/docs/design/maui-devtools-ide-integration.md +++ b/docs/design/maui-devtools-ide-integration.md @@ -42,8 +42,8 @@ This document details how IDEs (Visual Studio, VS Code) integrate with MAUI Dev ``` **Extension Responsibilities**: -1. Spawn `dotnet maui` process on activation -2. Send `dotnet maui doctor --json` request on workspace open +1. Spawn `maui` process on activation +2. Send `maui doctor --json` request on workspace open 3. Display issues in Problems panel 4. Register "MAUI: Setup Environment" command 5. Show progress notifications during fixes @@ -195,7 +195,7 @@ Tools ### Error List Integration -Issues detected by `dotnet maui doctor` appear in Visual Studio's Error List window: +Issues detected by `maui doctor` appear in Visual Studio's Error List window: | Severity | Code | Description | Project | |----------|------|-------------|---------| @@ -227,7 +227,7 @@ When running in interactive mode (terminal), the tool prompts for missing inform **Example: Emulator Creation with Missing Parameters**: ``` -$ dotnet maui android emulator create +$ maui android emulator create ? Emulator name: My_Pixel_5 @@ -248,13 +248,13 @@ Creating emulator 'My_Pixel_5'... done **Non-Interactive Mode**: ``` -$ dotnet maui android emulator create --non-interactive +$ maui android emulator create --non-interactive Error: --name is required in non-interactive mode ``` **Example: Large Download Confirmation**: ``` -$ dotnet maui doctor --fix +$ maui doctor --fix The following will be installed: • system-images;android-34;google_apis;x86_64 (2.6 GB) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index f49193bad707..ef64abf6d5f8 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -101,7 +101,7 @@ This tool eliminates that friction by providing a single, authoritative source f **DP1: Delegate to Native Toolchains** — Do not reimplement. Use `sdkmanager`, `avdmanager`, `adb`, `emulator` for Android; `xcrun simctl`, `xcode-select` for Apple; Windows SDK installer for Windows. Native tools are authoritative, reduce maintenance burden, and ensure consistency. -**DP2: Consolidate Existing VS Repositories** — Replace `ClientTools.android-acquisition` and `android-platform-support` with unified `maui android` commands across VS, VS Code, CLI, and CI. +**DP2: Reuse & Consolidate** — Leverage [`dotnet/android-tools`](https://github.com/dotnet/android-tools) for SDK/JDK discovery. Move proven code from `android-platform-support` (internal) to the public `android-tools` package for JDK installation, SDK bootstrap, and license acceptance. **DP3: Stateless Architecture** — Each command reads state, acts, and exits. Uses file-system caching (`~/.maui/cache/`) with TTLs for performance. @@ -750,8 +750,8 @@ The Android Provider layer reuses the **[`Xamarin.Android.Tools.AndroidSdk`](htt |-----------|-------|-----------| | **Android SDK path discovery** | `AndroidSdkInfo` + `AndroidSdkBase` | Probes 15+ locations: `ANDROID_HOME`, `ANDROID_SDK_ROOT`, Windows registry (HKLM/HKCU for VS-installed SDKs), macOS Homebrew, Linux `/usr/lib/android-sdk`, Android Studio paths. Validates by checking for `adb` executable. | | **JDK discovery** | `JdkInfo` + `*JdkLocations.cs` | Finds Microsoft OpenJDK, Eclipse Adoptium, Azul, Oracle, VS-bundled JDKs. Checks Windows registry (32/64-bit views), macOS `/usr/libexec/java_home`, Linux `update-java-alternatives`. Returns version, vendor, home path. | -| **JDK installation** | `JdkInstaller` *(planned)* | Will be contributed from `android-platform-support`'s `JavaDependencyInstaller`. Downloads Microsoft OpenJDK from manifest feed, extracts, validates. | -| **`sdkmanager` wrapper** | `SdkManager` *(planned)* | Will be contributed from `android-platform-support`. Wraps `sdkmanager` CLI for install/uninstall/list/update operations and license acceptance. | +| **JDK installation** | `JdkInstaller` *(planned)* | Based on `android-platform-support`'s `JavaDependencyInstaller`. Downloads Microsoft OpenJDK from manifest feed, extracts, validates. Will be moved to `android-tools`. | +| **SDK bootstrap & management** | `SdkManager` *(planned)* | New implementation inspired by `android-platform-support`'s SDK installer. Downloads and unzips command-line tools from the manifest feed, then uses the extracted `sdkmanager` for package operations. Will be moved to `android-tools`. | | **SDK path validation** | `AndroidSdkBase.ValidateAndroidSdkLocation()` | Executable-based validation (checks for `adb`) rather than simple directory existence. | | **Process/executable utilities** | `ProcessUtils` | PATHEXT-aware executable discovery (`FindExecutablesInDirectory`). | | **Android version mapping** | `AndroidVersion` / `AndroidVersions` | Maps API levels ↔ version names/codenames for human-readable output. | @@ -810,33 +810,26 @@ The manifest feed parsing infrastructure already exists in `android-platform-sup | Capability | Rationale | |-----------|-----------| | **SDK bootstrap (command-line tools)** | DevTools downloads and unzips command-line tools from the manifest feed to bootstrap a fresh SDK. Subsequent package operations use the `sdkmanager` wrapper from `android-tools`. | -| **ADB device communication** | DevTools shells out to the `adb` CLI for device listing, logcat streaming, and screenshot capture. Simpler than integrating `Mono.AndroidTools`' raw TCP ADB protocol for now. | +| **ADB device communication** | DevTools shells out to the `adb` CLI for device listing, logcat streaming, and screenshot capture. | | **CLI command routing** | `System.CommandLine`-based CLI layer, output formatting, `--json`/`--verbose` modes. | -| **`avdmanager` / `emulator` lifecycle** | AVD create/start/stop/delete — `android-platform-support` has read-only AVD discovery but no lifecycle management. | -| **`device screenshot`** | Not implemented in `Mono.AndroidTools`; DevTools uses `adb exec-out screencap`. | +| **`avdmanager` / `emulator` lifecycle** | AVD create/start/stop/delete and emulator lifecycle management. | +| **`device screenshot`** | DevTools uses `adb exec-out screencap` for Android screenshots. | | **OS elevation model** | UAC/sudo handling for SDK installs into protected paths (see §5.4). | | **Apple & Windows providers** | Entirely DevTools-specific; shared Android libraries are Android-only. | #### Contributing to `dotnet/android-tools` -The following capabilities will be moved from `android-platform-support` to the public `Xamarin.Android.Tools.AndroidSdk` package in `dotnet/android-tools`, making them available for DevTools and the broader ecosystem: +Capabilities currently in `android-platform-support` (internal) will be moved to the public `Xamarin.Android.Tools.AndroidSdk` package in `dotnet/android-tools`: | Capability | Source in `android-platform-support` | Benefit | |-----------|--------------------------------------|---------| | **JDK installation** | `JavaDependencyInstaller` | IDEs, build tasks, and DevTools can auto-install missing JDKs instead of just reporting errors. | -| **`sdkmanager` wrapper** | `AndroidSDKInstaller` + `SdkManager` logic | Shared API for install/uninstall/list operations — used by DevTools CLI, IDE extensions, and CI. | +| **SDK bootstrap & management** | `AndroidSDKInstaller` | Shared API for downloading command-line tools and managing SDK packages — used by DevTools CLI, IDE extensions, and CI. | | **License acceptance** | `AndroidLicensesStorage` | Unattended CI scenarios across all .NET Android tooling. | -DevTools will consume these from the `Xamarin.Android.Tools.AndroidSdk` NuGet package once upstreamed. +DevTools will consume these from the `Xamarin.Android.Tools.AndroidSdk` NuGet package once moved. -#### Future Considerations - -| Candidate | Target | Benefit | -|-----------|--------|---------| -| **Device screenshot** | `android-platform-support` | Complement existing ADB operations in `Mono.AndroidTools`. | -| **ADB protocol integration** | DevTools | Replace `adb` CLI calls with `Mono.AndroidTools`' raw TCP protocol for better performance if needed. | - -This approach ensures DevTools benefits from the battle-tested discovery and installation logic in shared libraries while contributing new capabilities back to the ecosystem over time. +This approach ensures DevTools benefits from the battle-tested discovery logic in `android-tools` while contributing new capabilities back to the ecosystem over time. ### 6.9 Error Contract Specification @@ -1476,7 +1469,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| -| 2.13-draft | 2026-02-19 | Expanded §6.8: added `android-platform-support` reuse table (SDK installer, ADB protocol, manifest parsing, license acceptance), added §6.8.1 Manifest-Driven Downloads & Checksum Verification — no hardcoded URLs, SHA-1 verification from Xamarin/Google manifest feeds | +| 2.13-draft | 2026-02-19 | Expanded §6.8: added §6.8.1 Manifest-Driven Downloads & Checksum Verification — no hardcoded URLs, SHA-1 verification from Xamarin/Google manifest feeds. JDK install and SDK bootstrap planned for `dotnet/android-tools`. | | 2.12-draft | 2026-02-19 | Added §6.8 Shared Libraries & Code Reuse — documents reuse of `Xamarin.Android.Tools.AndroidSdk` for SDK/JDK discovery and plan to contribute JDK installation, sdkmanager wrapper, license acceptance back to `dotnet/android-tools` | | 2.10-draft | 2026-02-10 | Added `apple install` bootstrap command (Xcode + license + runtime), `runtime check`, `runtime list --available/--all`, `runtime install `, `xcode check`, `xcode accept-licenses`; changed `doctor --category` → `doctor --platform`; changed `emulator stop ` → `emulator stop ` for consistency | | 2.9-draft | 2026-02-10 | Unified command naming: renamed `avd` → `emulator` for Android, `simulator boot` → `simulator start`, `simulator shutdown` → `simulator stop` for Apple — consistent start/stop verbs across platforms | From 5007cb7ad0bbfaefa455fb8a0d8bb0e8dc735a50 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 19 Feb 2026 19:41:42 +0000 Subject: [PATCH 25/34] Implement more feedback --- docs/design/maui-devtools-ai-integration.md | 390 -------------------- docs/design/maui-devtools-spec.md | 71 +--- 2 files changed, 3 insertions(+), 458 deletions(-) delete mode 100644 docs/design/maui-devtools-ai-integration.md diff --git a/docs/design/maui-devtools-ai-integration.md b/docs/design/maui-devtools-ai-integration.md deleted file mode 100644 index 430f759eecf1..000000000000 --- a/docs/design/maui-devtools-ai-integration.md +++ /dev/null @@ -1,390 +0,0 @@ -# MAUI Dev Tools — AI Agent Integration - -**Parent Document**: [MAUI Dev Tools Specification](./maui-devtools-spec.md) - -This document details how AI agents (GitHub Copilot, IDE assistants) interact with MAUI Dev Tools. - ---- - -## Table of Contents - -1. [Design Principle: Machine-First Output](#1-design-principle-machine-first-output) -2. [AI Agent Persona & Journey](#2-ai-agent-persona--journey) -3. [Copilot-Assisted Troubleshooting](#3-copilot-assisted-troubleshooting) -4. [Permission Model](#4-permission-model) -5. [AI Agent Considerations](#5-ai-agent-considerations) - ---- - -## 1. Design Principle: Machine-First Output - -**Every command MUST support `--json` output with a stable, versioned schema.** - -This tool is designed for three consumers in priority order: -1. **AI Agents** (GitHub Copilot, IDE assistants) — need structured data to reason about -2. **CI/CD Pipelines** — need deterministic exit codes and parseable output -3. **Human Developers** — need readable summaries with color and formatting - -**Implication**: If an error message is ambiguous plain text, AI agents will fail to use the tool reliably. Every failure must be expressed as structured data. - -```bash -# Human-friendly (default) -maui doctor -# ✓ .NET SDK 9.0.100 -# ✗ Android SDK not found - -# Machine-friendly (for AI/CI) -maui doctor --json -# { "status": "unhealthy", "checks": [...], "errors": [...] } -``` - -**Required flags for all commands**: -| Flag | Purpose | -|------|---------| -| `--json` | Output structured JSON instead of human-readable text | -| `--dry-run` | Show what would be done without executing (enables "what will this do?" UX) | -| `--ci` | Strict mode: no interactive prompts, non-zero exit on warnings, machine-readable only | - ---- - -## 2. AI Agent Persona & Journey - -**Profile**: Copilot agent assisting a developer with a build error. - -**Journey**: -1. User asks: "My Android build is failing with 'SDK not found'" -2. Agent invokes: `maui doctor --json --platform android` -3. Agent receives structured response: - ```json - { - "status": "unhealthy", - "issues": [ - { - "id": "ANDROID_SDK_MISSING", - "severity": "error", - "message": "Android SDK not found", - "fixable": true, - "fix_command": "maui android sdk install --recommended" - } - ] - } - ``` -4. Agent explains the issue and asks: "Would you like me to install the Android SDK?" -5. User confirms; agent invokes fix command with permission gate -6. Agent verifies fix by re-running doctor - -**Key Requirements**: -- Structured JSON output with stable schema -- Fix commands included in diagnostic output -- Permission gates for destructive operations -- Correlation IDs for tracing - ---- - -## 3. Copilot-Assisted Troubleshooting - -When automated fixes fail or issues are too complex for deterministic resolution, the tool can escalate to GitHub Copilot for AI-assisted troubleshooting. This provides a graceful fallback that combines structured diagnostics with conversational problem-solving. - -### Escalation Triggers - -The tool escalates to Copilot when: - -| Trigger | Example | Escalation Action | -|---------|---------|-------------------| -| Fix failed | SDK install fails with network error | Offer "Ask Copilot for help" | -| Unknown issue | Unrecognized error code from `adb` | Auto-suggest Copilot assistance | -| Complex diagnosis | Multiple interrelated issues | Recommend Copilot review | -| User request | User clicks "Get AI Help" | Open Copilot with context | - -### Context Handoff - -When escalating to Copilot, the tool provides structured context: - -```json -{ - "escalation_type": "fix_failed", - "tool_version": "1.2.0", - "doctor_report": { /* full doctor.status output */ }, - "failed_operation": { - "command": "android.sdk.install", - "params": { "packages": ["platforms;android-34"] }, - "error": { - "code": "E4001", - "message": "Download failed: Connection reset", - "details": "Failed after 3 retries to dl.google.com" - } - }, - "environment": { - "os": "macOS 15.0", - "proxy_configured": true, - "network_type": "corporate" - }, - "attempted_fixes": [ - { "action": "retry_download", "result": "failed" }, - { "action": "clear_cache", "result": "failed" } - ] -} -``` - -### CLI Integration - -```bash -$ maui doctor --fix -... -✖ Failed to install Android SDK - -Error: Connection reset while downloading (E4001) - -Attempted fixes: - • Retry download (3 times) - failed - • Clear download cache - failed - -Would you like to get help from Copilot? [Y/n] y - -Opening Copilot with diagnostic context... -Run: gh copilot explain "MAUI SDK install failure E4001" - -Or copy this diagnostic summary: - maui doctor --json --verbose > /tmp/maui-diag.json - gh copilot explain --file /tmp/maui-diag.json -``` - -### MCP Tool Integration - -When running as an MCP server, the tool exposes actions that Copilot can invoke (with user approval): - -```json -{ - "tools": [ - { - "name": "maui_doctor_status", - "description": "Check MAUI development environment health", - "requires_approval": false - }, - { - "name": "maui_doctor_fix", - "description": "Attempt to fix detected environment issues", - "requires_approval": true - } - ] -} -``` - -### Example Copilot Conversation - -``` -User: My MAUI Android build keeps failing with SDK errors - -Copilot: Let me check your MAUI environment. - [Calling maui_doctor_status...] - - I found several issues: - 1. ❌ Android SDK not found at expected location - 2. ⚠️ ANDROID_HOME environment variable not set - - It looks like the Android SDK may not be installed, or it's - installed in a non-standard location. - - Would you like me to: - a) Install the Android SDK to the default location - b) Help you configure ANDROID_HOME to point to an existing SDK - -User: Install it please - -Copilot: I'll install the Android SDK with recommended components. - [Requesting approval for maui_doctor_fix...] - - ✓ User approved - - [Calling maui_doctor_fix with issue_id="ANDROID_SDK_MISSING"...] - - ✓ Android SDK installed successfully - ✓ ANDROID_HOME configured - - Your environment is now ready. Try building again! -``` - -### Fallback Hierarchy - -``` -┌─────────────────────────────────────────────────────────────┐ -│ 1. Automated Fix (maui doctor --fix) │ -│ Tool attempts deterministic fix based on known patterns │ -├─────────────────────────────────────────────────────────────┤ -│ 2. Guided Manual Fix │ -│ Tool provides step-by-step instructions for user │ -├─────────────────────────────────────────────────────────────┤ -│ 3. Copilot-Assisted Troubleshooting │ -│ AI helps diagnose complex/unknown issues conversationally│ -├─────────────────────────────────────────────────────────────┤ -│ 4. Community/Support Escalation │ -│ Link to GitHub issues, docs, or support channels │ -└─────────────────────────────────────────────────────────────┘ -``` - -### Privacy Considerations - -When escalating to Copilot: - -- **Opt-in**: User must explicitly request Copilot assistance -- **Data minimization**: Only relevant diagnostic data shared -- **Redaction**: PII (paths, device names) redacted per privacy rules -- **Transparency**: User can view exact data being shared before sending -- **Local option**: `--offline-diagnosis` generates report without sending to Copilot - ---- - -## 4. Permission Model - -### Permission Gates - -When invoked by an AI agent, certain operations require explicit user confirmation. The complete mapping of commands to permission gates is defined in the **[Capabilities Model (§7.3)](./maui-devtools-spec.md#73-capabilities-model)** in the main specification. - -**Permission summary by gate**: - -| Permission | Operations | Confirmation UI | -|------------|-----------|-----------------| -| None | `doctor.status`, `device.list`, `sdk.list`, `simulator.list`, `runtime.list`, `xcode.list` | — | -| `device.capture` | `device.screenshot` | IDE prompt | -| `device.logs` | `device.logs` (streaming) | IDE prompt | -| `device.create` | `android.emulator.create/delete`, `apple.simulator.create/delete` | IDE prompt | -| `environment.modify` | `doctor.fix`, `android.sdk.install`, `android.install`, `android.jdk.install`, `apple.install`, `apple.runtime.install`, `apple.xcode.select`, `apple.xcode.accept-licenses` | IDE prompt with details | - -**Permission Flow**: -``` -┌─────────────────────────────────────────────────────────────┐ -│ AI Agent Request │ -│ "Install Android SDK build-tools" │ -├─────────────────────────────────────────────────────────────┤ -│ │ -│ The AI assistant wants to install: │ -│ • build-tools;34.0.0 (52 MB) │ -│ │ -│ This will modify your Android SDK installation. │ -│ │ -│ [Allow] [Allow Once] [Deny] │ -│ │ -│ □ Remember this choice for this session │ -└─────────────────────────────────────────────────────────────┘ -``` - -### Sandbox Boundaries - -AI agent calls are sandboxed: -- Cannot access arbitrary file system paths -- Cannot execute arbitrary commands -- Limited to defined API surface -- All actions logged with agent identifier - -**Safe Paths** (agents may read/write only within): -- Project root directory -- Temp directory (`$TMPDIR` / `%TEMP%`) -- SDK directories (Android SDK, Xcode Developer directory) -- Tool cache directory (`~/.maui-devtools/`) - -**Path Validation**: -- Reject paths containing `..` -- Reject absolute paths outside safe paths -- Validate in CLI Layer before dispatching to services - -### Permission Storage - -| Context | Storage Location | Lifetime | -|---------|------------------|----------| -| IDE Session | In-memory | Until IDE closes | -| Terminal | Per-command | Single invocation | -| CI | Environment variable `MAUI_DEVTOOLS_ALLOW_MODIFY=1` | Pipeline run | -| Persistent | `~/.config/maui-devtools/permissions.json` | Until revoked | - -**Persistent Permission Schema**: -```json -{ - "schema_version": 1, - "agents": { - "github-copilot": { - "environment.modify": "allow", - "device.create": "prompt", - "device.capture": "allow" - }, - "default": { - "environment.modify": "prompt", - "device.create": "prompt", - "device.capture": "prompt" - } - } -} -``` - -**Permission Values**: -- `allow`: Permitted without prompt -- `prompt`: Requires user confirmation each time -- `deny`: Blocked (agent receives permission error) - -### Elevation Handling - -> **See [Elevation Model (§5.4)](./maui-devtools-spec.md#54-security)** in the main spec for full platform-specific elevation flows. - -When an operation requires OS elevation, AI agents have additional constraints: - -| Scenario | AI Agent Behavior | -|----------|-------------------| -| Elevation needed (Windows UAC) | Agent receives `E5001` error. Cannot auto-approve UAC. Must inform user and suggest running from elevated terminal or using default user-writable paths. | -| Elevation needed (macOS sudo) | Agent receives `E5001` error. Cannot provide sudo password. Must inform user and suggest running the command manually. | -| Default paths (no elevation) | Agent can proceed normally with `environment.modify` permission gate. | -| CI environment (`--ci` flag) | Assumes pre-authorized. No elevation prompts — fails with `E5001` if permissions insufficient. | - -**Key rule**: Elevated operations are **never auto-approved** by AI agents. The agent must always inform the user and provide alternatives (e.g., installing to a user-writable default path instead). - ---- - -## 5. AI Agent Considerations - -The dotnet/sdk spec explicitly mentions AI agents: - -> "This has become more relevant in the AI era, as someone is going to expect AIs in 'agent mode' to build and run their app." - -MAUI DevTools is designed with AI agents as first-class consumers: - -| Requirement | How DevTools Addresses It | -|-------------|---------------------------| -| Structured output | All commands support `--json` with stable schema | -| Discoverability | `--list-devices` provides machine-parseable device list | -| Non-interactive | `--non-interactive` mode with helpful error messages | -| Deterministic | Same inputs produce same outputs; idempotent operations | -| Permission gates | Explicit confirmation for modifications (see §4) | - -**AI Agent Workflow Example**: - -```python -# 1. Discover available devices -devices = run("maui device list --platform android --json") - -# 2. Select appropriate device (first online emulator) -device = next(d for d in devices if d["status"] == "Online" and d["type"] == "Emulator") - -# 3. Build and deploy (with user confirmation via IDE) -run(f"maui deploy --device {device['id']} --project ./MyApp.csproj") - -# 4. Capture screenshot for verification -run(f"maui device screenshot --device {device['id']} --output ./screenshot.png") -``` - -### Error Contract for AI Agents - -AI agents depend on predictable error handling. Every error includes: - -| Field | Purpose | -|-------|---------| -| `code` | Unique error code (e.g., `E1001`) | -| `category` | Error category for routing | -| `message` | Human-readable description | -| `remediation` | Suggested fix actions | - -**Remediation Types**: - -| Type | Meaning | AI Agent Behavior | -|------|---------|-------------------| -| `automatic` | Tool can fix this automatically | Call `doctor.fix` with issue ID | -| `manual` | Requires user action | Present instructions to user | -| `escalate` | Tool doesn't know how to fix | Trigger Copilot Handoff | -| `unknown` | Tool doesn't recognize this error | Escalate to Copilot Handoff | diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index ef64abf6d5f8..1f17337541cc 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -116,7 +116,6 @@ This tool eliminates that friction by providing a single, authoritative source f | **CI Engineer** | DevOps configuring pipelines | `--non-interactive`, JSON output, deterministic exit codes | | **AI Agent** | GitHub Copilot, IDE assistants | Structured JSON for diagnosis, permission-gated fixes | -> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed AI agent personas and permission model. --- @@ -414,7 +413,6 @@ IDE consumers can use the `type: "progress"` messages to update progress bars an |----|-------------| | NFR-P1 | `doctor` command must complete in <5s when no network calls needed | | NFR-P2 | Device list must complete in <2s | -| NFR-P3 | Downloaded artifacts must be cached locally | | NFR-P4 | Read operations must use direct file parsing (not CLI wrappers) for performance | **Performance Implementation Notes**: @@ -537,41 +535,11 @@ Elevation is only triggered when the user explicitly specifies a system path via | NFR-PR2 | File paths must be redacted in telemetry (keep structure only) | | NFR-PR3 | Telemetry must be opt-in with clear disclosure | -### 5.6 Accessibility - -| ID | Requirement | -|----|-------------| -| NFR-A1 | CLI output must work with screen readers (avoid relying solely on color) | -| NFR-A2 | All status indicators must have text equivalents | -| NFR-A3 | IDE integration must follow platform accessibility guidelines | - -### 5.7 Network & Offline Support +### 5.6 Network & Proxy Support | ID | Requirement | |----|-------------| | NFR-N1 | Respect system proxy settings (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) | -| NFR-N2 | Support custom CA certificates for corporate SSL inspection | -| NFR-N3 | Provide `--offline` mode for doctor to skip network checks | -| NFR-N4 | Support `--local-source ` for installing from pre-downloaded artifacts | -| NFR-N5 | Large downloads must support HTTP Range requests for resumability | -| NFR-N6 | Cache downloaded installers with configurable location and size limits | - -### 5.8 Container & Headless Environments - -| Environment | Android Emulator | iOS Simulator | Doctor | SDK Install | -|-------------|------------------|---------------|--------|-------------| -| macOS native | ✓ | ✓ | ✓ | ✓ | -| Windows native | ✓ | — | ✓ | ✓ | -| Docker (Linux) | ✓ (with KVM) | — | ✓ | ✓ | -| Docker (macOS) | ❌ No nested virt | ❌ No CoreSimulator | Partial | Partial | -| GitHub Actions macOS | ✓ | ✓ | ✓ | ✓ | -| GitHub Actions Windows | ✓ (with HAXM) | — | ✓ | ✓ | -| Azure DevOps Hosted | ✓ | ✓ (macOS only) | ✓ | ✓ | -| WSL2 | ✓ (experimental) | — | Partial | ✓ | - -When emulator/simulator unavailable: -- `maui doctor` reports capability with reason (e.g., "emulator: unavailable (virtualization disabled)") -- `maui android emulator start` fails fast with `E2010` "Hardware acceleration unavailable" --- @@ -647,7 +615,7 @@ When emulator/simulator unavailable: | Provider | Responsibility | |----------|----------------| -| Android Provider | Wraps `sdkmanager`, `avdmanager`, `adb`, `emulator`. Uses [`Xamarin.Android.Tools.AndroidSdk`](https://github.com/dotnet/android-tools) for SDK/JDK discovery (see §6.8). | +| Android Provider | Wraps `sdkmanager`, `avdmanager`, `adb`, `emulator`. Uses [`Xamarin.Android.Tools.AndroidSdk`](https://github.com/dotnet/android-tools) for SDK/JDK discovery (see §6.8). Additional features (JDK install, SDK bootstrap, license acceptance) will be consumed from `android-tools` as they become available. | | Apple Provider | Wraps `xcrun simctl`, `xcode-select`, `xcodebuild` | | Windows Provider | Wraps Windows SDK detection and VS build tools | @@ -700,38 +668,7 @@ User: maui doctor --json **Summary**: IDEs spawn `maui` as a child process, invoke `maui doctor --json` on workspace open, display issues in their problems/error list panels, and provide commands for environment setup with progress notifications. -### 6.5 Concurrency Model - -| Aspect | Behavior | -|--------|----------| -| Read Operations | Parallelized (multiple simultaneous queries allowed) | -| Write Operations | Serialized (single writer at a time) | -| Lock File | `$TMPDIR/maui-devtools.lock` prevents concurrent writes | -| Request Timeout | Requests waiting >30s for lock rejected with `E5010` | - -### 6.6 SDK Conflict Resolution - -When multiple SDK installations are detected: - -**Android SDK Precedence** (first match wins): -1. `ANDROID_HOME` environment variable -2. `ANDROID_SDK_ROOT` environment variable -3. Visual Studio configured path (Windows) -4. Android Studio configured path (`~/.android/sdk` or registry) -5. Default location (`~/Library/Android/sdk` on macOS, `%LOCALAPPDATA%\Android\Sdk` on Windows) - -> **Note:** This precedence order is implemented by `Xamarin.Android.Tools.AndroidSdk` (`AndroidSdkInfo`), ensuring consistent SDK resolution across MAUI DevTools, IDE extensions, and build tasks. See §6.8 for details. - -**Conflict Handling**: -- `maui doctor` reports all detected SDKs with recommendation -- `--sdk-path` flag available on all android commands for one-off override - -**Android Studio Coexistence**: -- Detect Android Studio installation -- Warn if both AS and tool would manage same SDK -- Offer to adopt AS's SDK rather than installing duplicate - -### 6.7 Migration from Existing Setups +### 6.5 Migration from Existing Setups When an existing SDK is detected: @@ -1337,7 +1274,6 @@ The unified device model for all platforms (physical devices, emulators, simulat | `device.create` | Create or delete emulators/simulators | Prompt | | `environment.modify` | Install, update, or configure SDK/JDK/runtime components | Prompt | -> **See [AI Agent Integration](./maui-devtools-ai-integration.md) §4** for permission storage, persistent permission schema, and sandbox boundaries. --- @@ -1393,7 +1329,6 @@ Total download size: 10.7 GB ### 8.3 Copilot-Assisted Troubleshooting -> **See [AI Agent Integration](./maui-devtools-ai-integration.md)** for detailed Copilot escalation triggers, context handoff schema, MCP tool integration, and example conversations. **Summary**: When automated fixes fail, the tool can escalate to GitHub Copilot with structured diagnostic context. The fallback hierarchy is: Automated Fix → Guided Manual Fix → Copilot-Assisted Troubleshooting → Community/Support Escalation. From 66d865c8c0768bd45387153ee9dd3e565b3bb4f5 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 19 Feb 2026 19:43:11 +0000 Subject: [PATCH 26/34] Add some details for ide integration --- docs/design/maui-devtools-ide-integration.md | 2 +- docs/design/maui-devtools-spec.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/design/maui-devtools-ide-integration.md b/docs/design/maui-devtools-ide-integration.md index 0522144f2a26..4d33929ce4be 100644 --- a/docs/design/maui-devtools-ide-integration.md +++ b/docs/design/maui-devtools-ide-integration.md @@ -50,10 +50,10 @@ This document details how IDEs (Visual Studio, VS Code) integrate with MAUI Dev ### Visual Studio Extension -- Uses CLI invocation for communication - Integrates with Visual Studio's environment detection UI - Surfaces issues in Error List window - Provides menu items in Tools > MAUI submenu +- Can consume the Android/iOS provider packages directly (as a library) or invoke the `maui` CLI -- either way, the business logic is shared. This avoids duplicating environment detection and fix logic between VS and the CLI. --- diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 1f17337541cc..1c8d72ac6494 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1395,7 +1395,6 @@ All telemetry and logs follow these redaction rules: | Document | Description | |----------|-------------| -| [AI Agent Integration](./maui-devtools-ai-integration.md) | Copilot integration, permission model, MCP tools | | [IDE Integration](./maui-devtools-ide-integration.md) | VS Code and Visual Studio UI flows | --- From f0e2743ca2ccf1f7065135eb14e2a9a105304d73 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Mon, 23 Feb 2026 14:46:38 +0000 Subject: [PATCH 27/34] Update docs/design/maui-devtools-spec.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/design/maui-devtools-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 1c8d72ac6494..ae940128740a 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -479,7 +479,7 @@ When the tool detects that the target install path requires elevation (e.g., `Pr | Context | Mechanism | Details | |---------|-----------|---------| | Terminal | `sudo` | Tool re-invokes itself with `sudo` for the specific operation that needs it (e.g., `sudo xcode-select -s `) | -| IDE (VS Code / VS for Mac) | Authorization Services | IDE presents system password dialog via `AuthorizationExecuteWithPrivileges` or equivalent | +| IDE (e.g., VS Code) | OS-managed elevation | IDE invokes a privileged helper or re-launches the tool in an elevated context, relying on supported macOS mechanisms and system authentication UI | | CI | Pre-authorized | CI agents typically run with required permissions; use `--ci` flag to skip interactive prompts | ``` From cb795400fd45e00d61c3b954c7d2a8529242d1b8 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Mon, 23 Feb 2026 14:49:13 +0000 Subject: [PATCH 28/34] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/design/maui-devtools-ide-integration.md | 2 +- docs/design/maui-devtools-spec.md | 23 +++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/design/maui-devtools-ide-integration.md b/docs/design/maui-devtools-ide-integration.md index 4d33929ce4be..776009529d05 100644 --- a/docs/design/maui-devtools-ide-integration.md +++ b/docs/design/maui-devtools-ide-integration.md @@ -135,7 +135,7 @@ When a fix operation fails: │ Unable to install Android SDK automatically. │ │ │ │ Error: Connection reset while downloading from │ -│ dl.google.com (E4001) │ +│ dl.google.com (E3004) │ │ │ │ Attempted: │ │ • Retry download (3 times) │ diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index ae940128740a..f742c037bab6 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -215,7 +215,7 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-DL4 | Support `--platform` filter | P1 | | FR-DL5 | Support `--json` output | P0 | -### 4.6 Install State Machine +### 4.7 Install State Machine **Critical**: The tool must handle the "install gap" — the chicken-and-egg problem where native tools (sdkmanager, xcrun) don't exist yet. @@ -413,7 +413,7 @@ IDE consumers can use the `type: "progress"` messages to update progress bars an |----|-------------| | NFR-P1 | `doctor` command must complete in <5s when no network calls needed | | NFR-P2 | Device list must complete in <2s | -| NFR-P4 | Read operations must use direct file parsing (not CLI wrappers) for performance | +| NFR-P3 | Read operations must use direct file parsing (not CLI wrappers) for performance | **Performance Implementation Notes**: - Android SDK detection: Parse `package.xml` and `source.properties` directly instead of invoking `sdkmanager --list` (which has 3-10s JVM startup time) @@ -422,9 +422,12 @@ IDE consumers can use the `type: "progress"` messages to update progress bars an **Shell Quoting Implementation Notes**: - Package identifiers contain semicolons (e.g., `system-images;android-35;google_apis;arm64-v8a`) -- When calling `avdmanager` or `sdkmanager`, arguments with semicolons must be properly quoted -- Use single quotes with escaped inner quotes: `--package '{escapedImage}'` -- This prevents shell interpretation of semicolons as command separators +- When calling `avdmanager` or `sdkmanager`, arguments with semicolons **SHOULD** be passed directly to the child process as an argument list (not via a shell) so that semicolons are not interpreted as command separators. +- If shell invocation is unavoidable, quoting **MUST** be documented per shell: + - POSIX shells (`bash`, `zsh`): `--package 'system-images;android-35;google_apis;arm64-v8a'` + - Windows `cmd.exe`: `--package "system-images;android-35;google_apis;arm64-v8a"` + - PowerShell: `--package 'system-images;android-35;google_apis;arm64-v8a'` +- Correct quoting prevents shell interpretation of semicolons as command separators. ### 5.4 Security @@ -458,12 +461,11 @@ When the tool detects that the target install path requires elevation (e.g., `Pr 2. It launches a **new elevated process** via `ProcessStartInfo` with `Verb = "runas"`, which triggers the standard UAC prompt 3. The elevated child process performs the install operation 4. The parent process monitors the child and reports progress/result -5. If the user declines UAC, the tool returns error `E5001` +5. If the user declines UAC, the tool returns error `E2001` ``` ┌─────────────────────────────────────────────────────────────┐ -│ maui android install --sdk-path "C:\Program Files\ │ -│ Android\sdk" │ +│ maui android install --sdk-path "C:\Program Files\Android\sdk" │ ├─────────────────────────────────────────────────────────────┤ │ 1. Detect: target path requires elevation │ │ 2. Prompt: "Installing to a system path requires admin │ @@ -774,17 +776,18 @@ This approach ensures DevTools benefits from the battle-tested discovery logic i #### Error Taxonomy -Errors are classified into three categories: +Errors are classified into four categories: | Category | Prefix | Responsibility | Example | |----------|--------|----------------|---------| | **Tool** | `E1xxx` | Bug in this tool | E1001: Internal state corruption | | **Platform** | `E2xxx` | Native tool or SDK issue | E2001: sdkmanager license not accepted | | **User** | `E3xxx` | User action required | E3001: Xcode not installed | +| **Unknown** | `E0xxx` | Source cannot be reliably determined (e.g., truncated or partial native output) | E0001: Unknown native tool failure | #### Error Object Schema -**Every error MUST be expressible as this JSON structure:** +**Every error MUST be expressible as this JSON structure; `category` MUST be one of `tool`, `platform`, `user`, or `unknown`.** ```json { From 9568a013c8c93e15ffc311496baf1486d80c7904 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 25 Feb 2026 10:58:23 +0000 Subject: [PATCH 29/34] Replace --ci/--non-interactive with --interactive (align with dotnet CLI) Adopts the same interactivity pattern as dotnet/sdk: --interactive defaults to true for terminals, false when CI env vars are detected (TF_BUILD, GITHUB_ACTIONS, CI, etc.) or Console.IsOutputRedirected. References dotnet/sdk CommonOptions.CreateInteractiveOption implementation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/maui-devtools-spec.md | 43 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index f742c037bab6..edbf2ec4de9b 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -105,7 +105,7 @@ This tool eliminates that friction by providing a single, authoritative source f **DP3: Stateless Architecture** — Each command reads state, acts, and exits. Uses file-system caching (`~/.maui/cache/`) with TTLs for performance. -**DP4: Machine-First Output** — Every command supports `--json` with stable schema. Priority: AI agents > CI/CD > humans. Required flags: `--json`, `--dry-run`, `--ci`. +**DP4: Machine-First Output** — Every command supports `--json` with stable schema. Priority: AI agents > CI/CD > humans. Required flags: `--json`, `--dry-run`, `--interactive`. ### Target Personas @@ -113,7 +113,7 @@ This tool eliminates that friction by providing a single, authoritative source f |---------|---------|----------| | **Windows Developer** | .NET dev, new to Android | One-click install of all Android dependencies | | **macOS Developer** | Building iOS apps, has Xcode | Detection of runtime/simulator state, guided fixes | -| **CI Engineer** | DevOps configuring pipelines | `--non-interactive`, JSON output, deterministic exit codes | +| **CI Engineer** | DevOps configuring pipelines | `--interactive false`, JSON output, deterministic exit codes | | **AI Agent** | GitHub Copilot, IDE assistants | Structured JSON for diagnosis, permission-gated fixes | @@ -482,7 +482,7 @@ When the tool detects that the target install path requires elevation (e.g., `Pr |---------|-----------|---------| | Terminal | `sudo` | Tool re-invokes itself with `sudo` for the specific operation that needs it (e.g., `sudo xcode-select -s `) | | IDE (e.g., VS Code) | OS-managed elevation | IDE invokes a privileged helper or re-launches the tool in an elevated context, relying on supported macOS mechanisms and system authentication UI | -| CI | Pre-authorized | CI agents typically run with required permissions; use `--ci` flag to skip interactive prompts | +| CI | Pre-authorized | CI agents typically run with required permissions; `--interactive` defaults to `false` when CI env vars are detected | ``` ┌─────────────────────────────────────────────────────────────┐ @@ -887,8 +887,8 @@ maui doctor # Machine-readable: JSON to stdout (errors included in JSON, not stderr) maui doctor --json -# CI mode: JSON output, no prompts, warnings become errors -maui doctor --ci +# CI mode: JSON output, no prompts +maui doctor --json --interactive false ``` **JSON output envelope:** @@ -920,7 +920,7 @@ maui │ ├── --fix # Auto-fix all detected issues │ ├── --platform

# Filter: dotnet, android, apple, windows │ ├── --json # Output as JSON -│ └── --ci # CI mode (no prompts, fail-fast) +│ └── --interactive false # Disable prompts (auto-detected in CI) │ ├── device │ ├── list # List all devices across platforms @@ -1058,18 +1058,25 @@ maui windows developer-mode status |--------|-------------|----------| | `--json` | Output as JSON (machine-readable) | **Mandatory on all commands** ✅ | | `--dry-run` | Show what would be done without executing | **Mandatory on write commands** ✅ | -| `--ci` | Strict mode: no prompts, warnings become errors, JSON output forced | Recommended ✅ | +| `--interactive` | Control interactive prompts (default: `true` for terminals, `false` in CI or when output is redirected — see below) | **Mandatory on all commands** ✅ | | `--verbose` / `-v` | Enable verbose logging | Optional ✅ | -| `--non-interactive` | Disable prompts; fail if input needed | Optional (vNext) | | `--correlation-id` | Set correlation ID for tracing | Optional (vNext) | | `--offline` | Skip network operations; use cached data only | Optional (vNext) | -**`--ci` Mode Behavior**: -- Forces `--json` output (human-readable disabled) -- Forces `--non-interactive` (no stdin prompts) -- Elevates warnings to errors (exit code 1 → 2) -- Includes full diagnostic context in error output -- Ideal for CI/CD pipelines and AI agent consumption +**`--interactive` Detection (aligned with `dotnet` CLI)**: + +The `--interactive` flag follows the same pattern as the `dotnet` CLI ([`CommonOptions.CreateInteractiveOption`](https://github.com/dotnet/sdk/blob/main/src/Cli/Microsoft.DotNet.Cli.Definitions/Common/CommonOptions.cs)): + +- **Default: `true`** when running in a terminal (stdin/stdout not redirected, no CI env vars detected) +- **Default: `false`** when CI environment is detected OR `Console.IsOutputRedirected` is `true` +- **CI detection**: checks well-known environment variables — `TF_BUILD` (Azure Pipelines), `GITHUB_ACTIONS`, `CI` (generic), `TRAVIS`, `CIRCLECI`, `TEAMCITY_VERSION`, AWS CodeBuild (`CODEBUILD_BUILD_ID` + `AWS_REGION`), Jenkins (`BUILD_ID` + `BUILD_URL`), Google Cloud Build (`BUILD_ID` + `PROJECT_ID`), JetBrains Space (`JB_SPACE_API_URL`) +- **Explicit override**: `--interactive false` to suppress prompts, `--interactive` to force prompts in CI +- Accepts an optional boolean argument (`--interactive true`, `--interactive false`) or acts as a zero-arity flag (`--interactive` = `true`) + +When `--interactive` is `false`: +- No stdin prompts (fail with error if input is required and not provided via flags) +- Operations that require confirmation (e.g., downloads >100MB) must use `--accept-licenses` or `--yes` flags +- All required parameters must be provided via command-line arguments **`--dry-run` Mode Output**: ```json @@ -1311,10 +1318,10 @@ $ maui android emulator create Creating emulator 'My_Pixel_5'... done ``` -**Non-Interactive Mode**: +**Non-Interactive Mode** (auto-detected in CI, or explicit `--interactive false`): ``` -$ maui android emulator create --non-interactive -Error: --name is required in non-interactive mode +$ maui android emulator create --interactive false +Error: --name is required in non-interactive mode (--interactive is false) ``` **Example: Large Download Confirmation**: @@ -1383,7 +1390,7 @@ All telemetry and logs follow these redaction rules: |----------|---------| | P1 | Visual Studio extension integration | | P1 | iOS runtime installation guidance | -| P1 | `--non-interactive`, `--correlation-id`, `--offline` global options | +| P1 | `--correlation-id`, `--offline` global options | | P2 | Emulator snapshot management | | P2 | Windows SDK management | | P2 | Linux host support (Android only) | From 45f02f0f0388b011e5227e36d7bbd98408a5df36 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 25 Feb 2026 11:39:53 +0000 Subject: [PATCH 30/34] Standardize --platform values: android, ios, maccatalyst, windows Aligns platform filter values with .NET MAUI TFMs across doctor, device list, and all --platform references. Adds platform values reference table with host availability. Removes 'dotnet' and 'apple' as platform values in favor of the TFM-aligned names. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/maui-devtools-spec.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index edbf2ec4de9b..59cdf51066d6 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -135,7 +135,7 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-D8 | Produce machine-readable JSON output with stable schema | P0 | | FR-D9 | Provide `--fix` flag to automatically remediate fixable issues | P0 | | FR-D10 | Prompt for confirmation before downloads >100MB | P0 | -| FR-D11 | Support `--platform` filter (android, ios, windows, maccatalyst) — multiple allowed | P1 | +| FR-D11 | Support `--platform` filter (`android`, `ios`, `maccatalyst`, `windows`) — multiple allowed | P1 | | FR-D12 | Verify available disk space before attempting large downloads | P0 | | FR-D13 | Support `--fix ` for targeted fixes | P1 | | FR-D14 | Detect multiple SDK installations and report conflicts | P1 | @@ -212,7 +212,7 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-DL1 | `device list` shows all available devices across platforms | P0 | | FR-DL2 | Include device type (physical/emulator/simulator), platform, state | P0 | | FR-DL3 | Include unique identifier (serial/UDID) for targeting | P0 | -| FR-DL4 | Support `--platform` filter | P1 | +| FR-DL4 | Support `--platform` filter (`android`, `ios`, `maccatalyst`, `windows`) | P1 | | FR-DL5 | Support `--json` output | P0 | ### 4.7 Install State Machine @@ -918,13 +918,13 @@ The tool is invoked as `maui ` as a standalone CLI tool. Platform-speci maui ├── doctor # Check environment health │ ├── --fix # Auto-fix all detected issues -│ ├── --platform

# Filter: dotnet, android, apple, windows +│ ├── --platform

# Filter: android, ios, maccatalyst, windows │ ├── --json # Output as JSON │ └── --interactive false # Disable prompts (auto-detected in CI) │ ├── device │ ├── list # List all devices across platforms -│ │ ├── --platform # Filter by platform +│ │ ├── --platform # Filter by platform (android, ios, maccatalyst, windows) │ │ └── --json # Output as JSON │ ├── screenshot # Capture screenshot │ │ ├── --device # Target device @@ -1023,6 +1023,7 @@ maui doctor --fix maui device list # List all devices (physical + emulators + simulators) maui device list --platform android # Android devices and emulators maui device list --platform ios # iOS simulators and physical devices +maui device list --platform maccatalyst # Mac Catalyst devices maui device screenshot --device emulator-5554 # Android-specific @@ -1092,6 +1093,19 @@ When `--interactive` is `false`: } ``` +#### Platform Filter Values + +The `--platform` flag accepts these values, aligned with .NET MAUI target framework monikers: + +| Value | Matches | Available On | +|-------|---------|--------------| +| `android` | Android physical devices and emulators | All hosts | +| `ios` | iOS simulators and physical devices | macOS only | +| `maccatalyst` | Mac Catalyst apps | macOS only | +| `windows` | Windows devices | Windows only | + +Multiple values can be specified: `--platform android --platform ios` + #### Exit Code Standard All commands follow a consistent exit code scheme: From eeea156cf51ed7c8f755e0e28cd0b80d546cdf42 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 25 Feb 2026 12:25:32 +0000 Subject: [PATCH 31/34] Replace apple install with apple check, singular accept-license - Xcode can't be installed programmatically; 'install' was misleading - 'apple check' verifies Xcode, runtimes, and environment status - Singular 'accept-license' matches xcodebuild -license accept - Android SDK keeps plural 'accept-licenses' (multiple SDK licenses) - Updated command tree, usage examples, command table, permissions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/maui-devtools-spec.md | 48 +++++++++++++------------------ 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 59cdf51066d6..e56b1b35140d 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -321,7 +321,7 @@ maui android emulator create MyEmulator maui android emulator create MyEmulator --package "system-images;android-35;google_apis;arm64-v8a" ``` -#### Apple Install +#### Apple Check | State | Detection | Behavior | |-------|-----------|----------| @@ -329,27 +329,22 @@ maui android emulator create MyEmulator --package "system-images;android-35;goog | `CLI_ONLY` | Only Command Line Tools installed | Error: "Full Xcode required for simulators" | | `READY` | `xcrun simctl list` succeeds | Delegate all operations to native tools | -**Important**: Apple install is limited because: -- Xcode cannot be installed fully unattended (App Store or interactive install with Apple ID credentials) -- Xcode license can be accepted programmatically (`xcodebuild -license accept`) via `apple xcode accept-licenses` +**Important**: Apple cannot be fully bootstrapped because: +- Xcode cannot be installed programmatically (App Store or interactive install with Apple ID credentials) +- Xcode license can be accepted programmatically (`xcodebuild -license accept`) via `apple xcode accept-license` ```bash -# Basic setup check -maui apple install - -# Accept licenses automatically -maui apple install --accept-licenses - -# Also install a specific iOS runtime -maui apple install --runtime 18.5 --accept-licenses +# Check Xcode, runtimes, and environment status +maui apple check ``` This command: 1. Verifies Xcode installation -2. Checks and optionally accepts Xcode license (`--accept-licenses`) +2. Checks Xcode license status 3. Lists installed runtimes -4. Installs a specific iOS runtime if `--runtime ` is provided -5. Reports overall status and next steps +4. Reports overall status and next steps + +Use `maui apple xcode accept-license` and `maui apple runtime install ` for remediation. #### Windows Install @@ -974,9 +969,7 @@ maui │ └── --name # Emulator name │ ├── apple # Apple platform commands (macOS only) -│ ├── install # Set up Apple development environment -│ │ ├── --runtime # iOS runtime version to install -│ │ └── --accept-licenses # Accept Xcode license automatically +│ ├── check # Check Xcode, runtimes, and environment status │ ├── simulator │ │ ├── list # List simulators │ │ │ ├── --runtime # Filter by runtime @@ -1003,7 +996,7 @@ maui │ ├── check # Check Xcode installation and license │ ├── list # List installed Xcode versions │ ├── select # Switch active Xcode installation -│ └── accept-licenses # Accept Xcode license agreement +│ └── accept-license # Accept Xcode license agreement │ ├── windows # Windows-specific commands (Windows only) │ ├── sdk @@ -1033,9 +1026,7 @@ maui android emulator start --name Pixel_8 --wait maui device logs --device emulator-5554 # Apple-specific (macOS only) -maui apple install # Check Xcode + runtimes -maui apple install --accept-licenses # Also accept Xcode license -maui apple install --runtime 18.5 --accept-licenses # Full bootstrap +maui apple check # Check Xcode, runtimes, environment maui apple simulator list maui apple simulator start maui apple runtime check @@ -1045,7 +1036,7 @@ maui apple runtime install 18.5 # Install specific runtime maui apple xcode check maui apple xcode list maui apple xcode select /Applications/Xcode.app -maui apple xcode accept-licenses +maui apple xcode accept-license # Windows-specific maui windows developer-mode status @@ -1076,7 +1067,7 @@ The `--interactive` flag follows the same pattern as the `dotnet` CLI ([`CommonO When `--interactive` is `false`: - No stdin prompts (fail with error if input is required and not provided via flags) -- Operations that require confirmation (e.g., downloads >100MB) must use `--accept-licenses` or `--yes` flags +- Operations that require confirmation (e.g., downloads >100MB) must use `--accept-license` or `--yes` flags - All required parameters must be provided via command-line arguments **`--dry-run` Mode Output**: @@ -1145,8 +1136,8 @@ All commands follow a consistent exit code scheme: | `maui apple xcode check` | Check Xcode status | `--json` | Status report | 0=success, 2=error | | `maui apple xcode list` | List Xcode installations | `--json` | Installation list | 0=success, 2=error | | `maui apple xcode select` | Switch active Xcode | `` | Confirmation | 0=success, 3=permission denied | -| `maui apple xcode accept-licenses` | Accept Xcode license | `--json` | Status | 0=success, 3=permission denied | -| `maui apple install` | Set up Apple environment | `--runtime`, `--accept-licenses` | Progress, result | 0=success, 2=error | +| `maui apple xcode accept-license` | Accept Xcode license | `--json` | Status | 0=success, 3=permission denied | +| `maui apple check` | Check Xcode, runtimes, environment | `--json` | Status report | 0=success, 2=error | | `maui android sdk accept-licenses` | Accept SDK licenses | `--json` | Status | 0=success, 2=error | ### 7.2 JSON Output Schemas @@ -1277,14 +1268,14 @@ The unified device model for all platforms (physical devices, emulators, simulat | `maui apple simulator stop` | — | ✓ | No | None | | `maui apple simulator create` | — | ✓ | No | `device.create` | | `maui apple simulator delete` | — | ✓ | No | `device.create` | -| `maui apple install` | — | ✓ | Sometimes* | `environment.modify` | +| `maui apple check` | — | ✓ | No | None | | `maui apple runtime check` | — | ✓ | No | None | | `maui apple runtime list` | — | ✓ | No | None | | `maui apple runtime install` | — | ✓ | Yes (admin) | `environment.modify` | | `maui apple xcode check` | — | ✓ | No | None | | `maui apple xcode list` | — | ✓ | No | None | | `maui apple xcode select` | — | ✓ | Yes (sudo) | `environment.modify` | -| `maui apple xcode accept-licenses` | — | ✓ | Yes (sudo) | `environment.modify` | +| `maui apple xcode accept-license` | — | ✓ | Yes (sudo) | `environment.modify` | *OS Elevation required for: installing Android SDK/JDK to system locations (e.g., `Program Files`), installing Xcode runtimes, switching Xcode, accepting Xcode licenses @@ -1427,6 +1418,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| +| 2.14-draft | 2026-02-20 | Replaced `apple install` with `apple check` (Xcode can't be installed programmatically); renamed `accept-licenses` → `accept-license` (singular) for Apple/Xcode to match `xcodebuild -license accept`; Android SDK keeps plural `accept-licenses` | | 2.13-draft | 2026-02-19 | Expanded §6.8: added §6.8.1 Manifest-Driven Downloads & Checksum Verification — no hardcoded URLs, SHA-1 verification from Xamarin/Google manifest feeds. JDK install and SDK bootstrap planned for `dotnet/android-tools`. | | 2.12-draft | 2026-02-19 | Added §6.8 Shared Libraries & Code Reuse — documents reuse of `Xamarin.Android.Tools.AndroidSdk` for SDK/JDK discovery and plan to contribute JDK installation, sdkmanager wrapper, license acceptance back to `dotnet/android-tools` | | 2.10-draft | 2026-02-10 | Added `apple install` bootstrap command (Xcode + license + runtime), `runtime check`, `runtime list --available/--all`, `runtime install `, `xcode check`, `xcode accept-licenses`; changed `doctor --category` → `doctor --platform`; changed `emulator stop ` → `emulator stop ` for consistency | From c0f414d436209c3d2b9f6fa4691c9496b3bd2d5d Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Wed, 25 Feb 2026 12:27:22 +0000 Subject: [PATCH 32/34] Restore apple install with accept-license and runtime flags - apple install: optionally accepts Xcode license and installs runtimes - apple check: read-only environment status (no modifications) - Could prompt user to install Xcode in the future - Singular accept-license for Apple (matches xcodebuild -license accept) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/maui-devtools-spec.md | 41 ++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index e56b1b35140d..0d28aeb29bff 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -321,30 +321,35 @@ maui android emulator create MyEmulator maui android emulator create MyEmulator --package "system-images;android-35;google_apis;arm64-v8a" ``` -#### Apple Check +#### Apple Install | State | Detection | Behavior | |-------|-----------|----------| -| `MISSING` | No Xcode.app at `/Applications/Xcode*.app` | Error: "Install Xcode from App Store" (cannot auto-install) | +| `MISSING` | No Xcode.app at `/Applications/Xcode*.app` | Error: "Install Xcode from App Store" (cannot auto-install today; could prompt user in future) | | `CLI_ONLY` | Only Command Line Tools installed | Error: "Full Xcode required for simulators" | | `READY` | `xcrun simctl list` succeeds | Delegate all operations to native tools | -**Important**: Apple cannot be fully bootstrapped because: -- Xcode cannot be installed programmatically (App Store or interactive install with Apple ID credentials) -- Xcode license can be accepted programmatically (`xcodebuild -license accept`) via `apple xcode accept-license` +**Important**: Xcode itself cannot be installed programmatically today (App Store or interactive install with Apple ID credentials). The `install` command focuses on what _can_ be automated: +- Xcode license acceptance (`xcodebuild -license accept`) via `--accept-license` +- iOS simulator runtime installation via `--runtime ` +- In the future, could prompt the user to install Xcode ```bash -# Check Xcode, runtimes, and environment status -maui apple check +# Check environment and report status +maui apple install + +# Accept Xcode license and install a specific runtime +maui apple install --accept-license --runtime 18.5 ``` This command: -1. Verifies Xcode installation -2. Checks Xcode license status +1. Verifies Xcode installation (reports error with guidance if missing) +2. Optionally accepts Xcode license (`--accept-license`) 3. Lists installed runtimes -4. Reports overall status and next steps +4. Optionally installs a specific iOS runtime (`--runtime `) +5. Reports overall status and next steps -Use `maui apple xcode accept-license` and `maui apple runtime install ` for remediation. +`maui apple check` provides a read-only status check without modifying anything. #### Windows Install @@ -969,6 +974,9 @@ maui │ └── --name # Emulator name │ ├── apple # Apple platform commands (macOS only) +│ ├── install # Set up Apple environment (license, runtimes) +│ │ ├── --accept-license # Accept Xcode license +│ │ └── --runtime # iOS runtime version to install │ ├── check # Check Xcode, runtimes, and environment status │ ├── simulator │ │ ├── list # List simulators @@ -1026,7 +1034,10 @@ maui android emulator start --name Pixel_8 --wait maui device logs --device emulator-5554 # Apple-specific (macOS only) -maui apple check # Check Xcode, runtimes, environment +maui apple install # Check environment, report status +maui apple install --accept-license # Also accept Xcode license +maui apple install --accept-license --runtime 18.5 # Accept license + install runtime +maui apple check # Read-only status check maui apple simulator list maui apple simulator start maui apple runtime check @@ -1137,7 +1148,8 @@ All commands follow a consistent exit code scheme: | `maui apple xcode list` | List Xcode installations | `--json` | Installation list | 0=success, 2=error | | `maui apple xcode select` | Switch active Xcode | `` | Confirmation | 0=success, 3=permission denied | | `maui apple xcode accept-license` | Accept Xcode license | `--json` | Status | 0=success, 3=permission denied | -| `maui apple check` | Check Xcode, runtimes, environment | `--json` | Status report | 0=success, 2=error | +| `maui apple install` | Set up Apple environment | `--accept-license`, `--runtime` | Progress, result | 0=success, 2=error | +| `maui apple check` | Read-only environment status | `--json` | Status report | 0=success, 2=error | | `maui android sdk accept-licenses` | Accept SDK licenses | `--json` | Status | 0=success, 2=error | ### 7.2 JSON Output Schemas @@ -1268,6 +1280,7 @@ The unified device model for all platforms (physical devices, emulators, simulat | `maui apple simulator stop` | — | ✓ | No | None | | `maui apple simulator create` | — | ✓ | No | `device.create` | | `maui apple simulator delete` | — | ✓ | No | `device.create` | +| `maui apple install` | — | ✓ | Sometimes* | `environment.modify` | | `maui apple check` | — | ✓ | No | None | | `maui apple runtime check` | — | ✓ | No | None | | `maui apple runtime list` | — | ✓ | No | None | @@ -1418,7 +1431,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| -| 2.14-draft | 2026-02-20 | Replaced `apple install` with `apple check` (Xcode can't be installed programmatically); renamed `accept-licenses` → `accept-license` (singular) for Apple/Xcode to match `xcodebuild -license accept`; Android SDK keeps plural `accept-licenses` | +| 2.14-draft | 2026-02-25 | Restored `apple install` with `--accept-license` and `--runtime` flags (optionally accepts license, installs runtimes; could prompt for Xcode install in future); added `apple check` as read-only status; singular `accept-license` for Apple/Xcode matching `xcodebuild -license accept`; Android SDK keeps plural `accept-licenses` | | 2.13-draft | 2026-02-19 | Expanded §6.8: added §6.8.1 Manifest-Driven Downloads & Checksum Verification — no hardcoded URLs, SHA-1 verification from Xamarin/Google manifest feeds. JDK install and SDK bootstrap planned for `dotnet/android-tools`. | | 2.12-draft | 2026-02-19 | Added §6.8 Shared Libraries & Code Reuse — documents reuse of `Xamarin.Android.Tools.AndroidSdk` for SDK/JDK discovery and plan to contribute JDK installation, sdkmanager wrapper, license acceptance back to `dotnet/android-tools` | | 2.10-draft | 2026-02-10 | Added `apple install` bootstrap command (Xcode + license + runtime), `runtime check`, `runtime list --available/--all`, `runtime install `, `xcode check`, `xcode accept-licenses`; changed `doctor --category` → `doctor --platform`; changed `emulator stop ` → `emulator stop ` for consistency | From 681a670593f0eafaf69b9752eb246ba9450472a1 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 26 Feb 2026 00:57:42 +0000 Subject: [PATCH 33/34] Sync full spec: JDK 21 default, fix adb screencap -p Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/cli.md | 296 +++++++++++++++++++++++------- docs/design/maui-devtools-spec.md | 25 +-- 2 files changed, 239 insertions(+), 82 deletions(-) diff --git a/docs/design/cli.md b/docs/design/cli.md index d2477d8a6370..51339fe18b92 100644 --- a/docs/design/cli.md +++ b/docs/design/cli.md @@ -1,18 +1,21 @@ --- -description: "Design document for the dotnet-maui CLI tool for AI-assisted development" +description: "Design document for the maui CLI tool" date: 2026-01-07 +updated: 2026-02-25 --- -# dotnet-maui CLI Design Document +# `maui` CLI Design Document ## Overview -The `dotnet-maui` CLI is a command-line tool that provides simple -commands for capturing screenshots, viewing logs, and inspecting the -visual tree of running .NET MAUI applications. While designed to -enable AI agents to iteratively develop and validate applications, -these commands are equally useful for developers who want quick access -to debugging and inspection capabilities from the terminal. +The `maui` CLI is a command-line tool for .NET MAUI development that provides two main capabilities: + +1. **Environment setup** — manages Android SDK/JDK, Xcode runtimes, simulators, and emulators +2. **App inspection** — captures screenshots, streams logs, and inspects the visual tree of running apps + +It is designed for three consumers: **AI agents**, **CI/CD pipelines**, and **humans**. + +**Full specification**: [PR #33865](https://github.com/dotnet/maui/pull/33865) — covers architecture, error contracts, IDE integration, JSON schemas, and vNext roadmap. ## Motivation @@ -24,51 +27,38 @@ simctl io booted screenshot`, while Android uses `adb exec-out screencap`. Similarly, log access, visual tree inspection, and device management all have platform-specific implementations. -The `dotnet-maui` CLI provides a unified interface across Android, +The `maui` CLI provides a unified interface across Android, iOS, macOS, Windows, and Mac Catalyst, making these operations simple and consistent for both developers and AI agents. +### Design Principles + +1. **Delegate to native toolchains** — wraps `sdkmanager`, `adb`, `xcrun simctl`, etc. +2. **Reuse shared libraries** — leverages [`dotnet/android-tools`](https://github.com/dotnet/android-tools) (`Xamarin.Android.Tools.AndroidSdk`) for SDK/JDK discovery, and contributes new capabilities (JDK installation, SDK bootstrap, license acceptance) back to it. +3. **Machine-first output** — every command supports `--json` +4. **Stateless** — each command reads state, acts, and exits +5. **Complement `dotnet run`** — uses the same device identifiers and framework options as [`dotnet run` for .NET MAUI][dotnet-run-spec] + ## Goals -1. **Screenshot capture**: Enable AI agents to capture screenshots of +1. **Environment setup**: Manage Android SDK/JDK, Xcode runtimes, + simulators, and emulators from a single tool + +2. **Screenshot capture**: Enable AI agents to capture screenshots of running .NET MAUI applications to validate visual changes -2. **Log access**: Provide unified access to platform-specific device +3. **Log access**: Provide unified access to platform-specific device logs (logcat, Console, etc.) -3. **Visual tree inspection**: Allow agents to inspect the runtime +4. **Visual tree inspection**: Allow agents to inspect the runtime visual tree structure and properties (.NET MAUI visual tree) -4. **Developer experience**: Integrate seamlessly with existing +5. **Developer experience**: Integrate seamlessly with existing `dotnet` CLI workflows, this should fit in with `dotnet run`, `dotnet watch`, etc. ## Installation and Invocation -The CLI will be available through multiple invocation methods to -support different workflows: - -### Method 1: Direct Tool Invocation - -```bash -dotnet-maui screenshot -o screenshot.png -``` - -### Method 2: .NET CLI - -```bash -dotnet maui screenshot -o screenshot.png -``` - -### Method 3: `dotnet tool exec` or `dnx` - -```bash -dotnet tool exec -y Microsoft.Maui.Cli screenshot -o screenshot.png -dnx -y Microsoft.Maui.Cli screenshot -o screenshot.png -``` - -### Installation - ```bash # As a global tool dotnet tool install --global Microsoft.Maui.Cli @@ -81,9 +71,10 @@ dotnet tool restore # Inline install and invocation dotnet tool exec -y Microsoft.Maui.Cli screenshot -o screenshot.png -dnx -y Microsoft.Maui.Cli screenshot -o screenshot.png ``` +The tool installs as `maui` on PATH. All commands in this document use the `maui` form. + The .NET workload specification includes support for automatically installing tools from workloads via the `tools-packs` feature (see [workload manifest specification][workload-spec]). However, this @@ -92,15 +83,126 @@ could be automatically installed when the `maui` workload is installed, eliminating the need for manual tool installation. Until then, manual installation via `dotnet tool install` will be how -we prove out the `dotnet-maui` CLI. +we prove out the `maui` CLI. [workload-spec]: https://github.com/dotnet/designs/blob/566ad4cafcc578d6389c215c61924ee9e07dcb29/accepted/2020/workloads/workload-manifest.md#tools-packs -## Command Structure +## Global Options -### Global Options +All commands support: -The `dotnet-maui` CLI follows the conventions established by [`dotnet +| Flag | Description | +|------|-------------| +| `--json` | Structured JSON output | +| `--verbose` | Detailed logging | +| `--interactive` | Control interactive prompts (default: `true` for terminals, `false` in CI or when output is redirected) | +| `--dry-run` | Preview actions without executing | +| `--platform

` | Filter by platform: `android`, `ios`, `maccatalyst`, `windows` | + +**Interactivity detection** follows the same pattern as `dotnet` CLI — auto-detects CI environments (`TF_BUILD`, `GITHUB_ACTIONS`, `CI`, etc.) and checks `Console.IsOutputRedirected`. + +## Environment Setup Commands + +### Android + +| Command | Description | +|---------|-------------| +| `maui android install` | Install JDK + SDK + recommended packages | +| `maui android install --accept-licenses` | Non-interactive install | +| `maui android install --packages ` | Install specific packages | +| `maui android jdk check` | Check JDK status | +| `maui android jdk install` | Install OpenJDK 21 | +| `maui android jdk list` | List installed JDKs | +| `maui android sdk list` | List installed packages | +| `maui android sdk list --available` | Show available packages | +| `maui android sdk install ` | Install package(s) | +| `maui android sdk accept-licenses` | Accept all licenses | +| `maui android sdk uninstall ` | Uninstall a package | +| `maui android emulator list` | List emulators | +| `maui android emulator create ` | Create emulator (auto-detects system image) | +| `maui android emulator start ` | Start emulator | +| `maui android emulator stop ` | Stop emulator | +| `maui android emulator delete ` | Delete emulator | + +Install paths and defaults are handled by [`dotnet/android-tools`](https://github.com/dotnet/android-tools). + +### Apple (macOS only) + +| Command | Description | +|---------|-------------| +| `maui apple install [--accept-license] [--runtime ]` | Optionally accepts Xcode license and installs simulator runtimes. Could prompt user to install Xcode in the future | +| `maui apple check` | Check Xcode, runtimes, and environment status | +| `maui apple xcode check` | Check Xcode installation and license | +| `maui apple xcode list` | List Xcode installations | +| `maui apple xcode select ` | Switch active Xcode | +| `maui apple xcode accept-license` | Accept Xcode license | +| `maui apple simulator list` | List simulators | +| `maui apple simulator create ` | Create simulator | +| `maui apple simulator start ` | Start simulator | +| `maui apple simulator stop ` | Stop simulator | +| `maui apple simulator delete ` | Delete simulator | +| `maui apple runtime check` | Check runtime status | +| `maui apple runtime list` | List installed runtimes | +| `maui apple runtime list --all` | List all runtimes (installed and downloadable) | +| `maui apple runtime install ` | Install an iOS runtime | + +> **License flag naming**: Android uses `accept-licenses` (plural) because `sdkmanager` requires accepting multiple SDK component licenses. Apple uses `accept-license` (singular) because `xcodebuild -license accept` accepts one unified Xcode license agreement. + +### Implementation References + +The `maui` CLI delegates to shared libraries for platform operations: + +**Android** — [`dotnet/android-tools`](https://github.com/dotnet/android-tools) (`Xamarin.Android.Tools.AndroidSdk`): + +| Feature | Implementation | +|---------|---------------| +| SDK discovery, bootstrap & license acceptance | [`SdkManager`](https://github.com/dotnet/android-tools/pull/275) | +| JDK discovery & installation | [`JdkInstaller`](https://github.com/dotnet/android-tools/pull/274) | +| ADB device management | [`AdbRunner`](https://github.com/dotnet/android-tools/pull/282) | +| AVD / Emulator management | [`AvdManagerRunner`](https://github.com/dotnet/android-tools/pull/283), [`EmulatorRunner`](https://github.com/dotnet/android-tools/pull/284) | + +**Apple** — wraps native toolchains directly: + +| Feature | Native tool | +|---------|------------| +| Simulator management | `xcrun simctl` (list, create, boot, shutdown, delete) | +| Runtime management | `xcrun simctl runtime` (list, add) | +| Xcode management | `xcode-select`, `xcodebuild -license` | +| Device detection | `xcrun devicectl list devices` (physical), `xcrun simctl list` (simulators) | + +Apple operations use [AppleDev.Tools][appledev-tools] for `simctl` and `devicectl` wrappers. + +### Device List + +The `maui` CLI also provides a unified device listing across all platforms: + +| Command | Description | +|---------|-------------| +| `maui device list` | List all connected devices, emulators, and simulators | +| `maui device list --platform android` | List Android devices and emulators only | +| `maui device list --platform ios` | List iOS simulators and devices only | +| `maui device list --json` | Machine-readable output for IDE/agent consumption | + +### Exit Codes + +All commands use consistent exit codes: + +| Code | Meaning | +|------|---------| +| 0 | Success | +| 1 | General error | +| 2 | Environment/configuration error | +| 3 | Permission denied (elevation required) | +| 4 | Network error (download failed) | +| 5 | Resource not found | + +## App Inspection Commands (Future) + +> **Note**: App inspection commands are planned for a future release. The initial release focuses on environment setup and device management. + +### Device Selection Options + +App inspection commands will follow the conventions established by [`dotnet run` for .NET MAUI][dotnet-run-spec], using the same device selection and framework options: @@ -146,7 +248,7 @@ Captures a screenshot of the currently running .NET MAUI application. **Usage:** ```bash -dotnet maui screenshot [options] +maui screenshot [options] ``` **Options:** @@ -158,17 +260,16 @@ dotnet maui screenshot [options] Initial implementation targets Android and iOS/Mac Catalyst, with Windows and macOS support planned as described below. -- **Android**: Uses `adb screencap` -- **iOS/Mac Catalyst**: Uses `simctl io screenshot` for simulator, and device capture via Xcode tooling (future implementation) +- **Android**: Uses `adb exec-out screencap -p` +- **iOS/Mac Catalyst**: Uses `xcrun simctl io booted screenshot ` for simulator; physical device capture via Xcode tooling (future) - **Windows** (planned): Uses Windows screen capture APIs to capture the active app window or full screen. - **macOS** (planned): Uses macOS screen capture APIs or command-line tooling to capture the active app window or full screen. ### Future Commands -To keep scope small for initial version, future commands are: - -- `dotnet maui log` or `logs` -- `dotnet maui tree` for displaying the visual tree +- `maui screenshot` for capturing screenshots of running apps +- `maui logs` for streaming device logs +- `maui tree` for inspecting the visual tree ## Integration with `dotnet run` and `dotnet watch` @@ -180,12 +281,10 @@ The CLI is designed to work seamlessly with existing .NET workflows: # Terminal 1: Run application with hot reload dotnet watch run -# Terminal 2: Monitor logs -dotnet maui logs --follow --filter "MyApp" - -# Terminal 3: Inspect application -dotnet maui screenshot --output iteration1.png -dotnet maui tree --format json +# Terminal 2: Inspect application +maui screenshot --output iteration1.png +maui logs --follow --filter "MyApp" # future +maui tree --json # future ``` ### AI Agent Workflow @@ -198,13 +297,13 @@ dotnet maui tree --format json sleep 2 # 3. Capture screenshot -dotnet maui screenshot -o current.png +maui screenshot -o current.png -# 4. Analyze visual tree -dotnet maui tree --format json +# 4. Analyze visual tree (future) +maui tree --json -# 5. Check logs for errors -dotnet maui logs --level error +# 5. Check logs for errors (future) +maui logs --level error # 6. Agent analyzes outputs and decides next steps ``` @@ -220,10 +319,10 @@ dotnet maui logs --level error ### iOS / Mac Catalyst - **Device Detection**: `xcrun simctl list devices` (simulators), - `xcrun devicectl list devices` (physical devices) + `xcrun devicectl list devices` (physical devices) — via [AppleDev.Tools][appledev-tools] - **Screenshots**: `xcrun simctl io booted screenshot ` - (simulators), iOS devices (future implementation) + (simulators), iOS physical devices (future) - **Logs**: `xcrun simctl spawn booted log stream` or Console.app (simulators), `mlaunch --logdev` (physical devices) @@ -243,6 +342,63 @@ The CLI is designed for development and debugging scenarios only: (like screenshots and logs), the CLI should not be usable against production applications +## IDE Integration + +The `maui` CLI is designed to be the shared backend for IDE extensions, eliminating duplicate environment detection and setup logic across tools. + +### Architecture + +IDEs spawn `maui` as a child process and consume its `--json` output: + +``` +┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ +│ VS Code ext │ │ Visual Studio │ │ AI Agent │ +│ (vscode-maui) │ │ extension │ │ (Copilot, etc.) │ +└────────┬─────────┘ └────────┬──────────┘ └────────┬─────────┘ + │ │ │ + └───────────┬───────────┴────────────────────────┘ + │ + ┌──────▼──────┐ + │ maui CLI │ ← single tool, --json output + │ │ + │ ┌─────────┐ │ + │ │android- │ │ ← NuGet library (in-process) + │ │tools │ │ + │ └─────────┘ │ + └──────┬──────┘ + │ spawns native tools + ┌───────────┼───────────┐ + ▼ ▼ ▼ + ┌───────────┐ ┌──────────┐ ┌──────────┐ + │ adb │ │ xcrun │ │ Windows │ + │ sdkmanager│ │ simctl │ │ SDK │ + └───────────┘ └──────────┘ └──────────┘ +``` + +### How IDEs Use It + +| Workflow | CLI command | IDE behavior | +|----------|------------|--------------| +| Workspace open | `maui apple check --json`, `maui android jdk check --json` | Show environment status in status bar / problems panel | +| Environment fix | `maui android install --json` | Display progress bar, stream `type: "progress"` messages | +| Device picker | `maui device list --json` | Populate device dropdown / selection UI | +| Emulator launch | `maui android emulator start --json` | Show notification, update device list on completion | + +### Benefits of Reuse + +- **Consistent behavior** — VS Code, Visual Studio, and CLI all use the same detection and setup logic +- **Single maintenance point** — bug fixes and new features propagate to all consumers +- **AI-ready** — agents use the same `--json` output that IDEs consume +- **No protocol overhead** — simple process spawn + stdout, no daemon or RPC needed + +### Current Status + +| Integration | Status | +|-------------|--------| +| VS Code extension (`vscode-maui`) | ✅ In progress | +| Visual Studio extension | Planned (vNext) | +| GitHub Copilot / AI agents | ✅ Supported via `--json` output | + ## Future Goals ### MCP Server @@ -262,7 +418,8 @@ if there's demonstrated need. ### More Subcommands -There are other .NET MAUI CLI tools such as: +Environment setup commands (Android SDK/JDK, Xcode, emulators, +simulators) are now included above. These were inspired by: - .NET MAUI "Check" / "Doctor" - https://github.com/Redth/dotnet-maui-check @@ -270,15 +427,14 @@ There are other .NET MAUI CLI tools such as: - Android SDK Management - https://github.com/Redth/AndroidSdk.Tools -These could easily be added down the road. - -Future commands: +Future app inspection commands: -- `dotnet maui log` or `logs` for viewing console output -- `dotnet maui tree` for displaying the visual tree +- `maui logs` for viewing console output +- `maui tree` for displaying the visual tree +- `maui screenshot` for capturing screenshots -**Decision**: Start with just a few subcommands and expand in the -future. +**Decision**: Environment setup ships first. App inspection commands +follow in a future release. ## References diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index 0d28aeb29bff..b6ae4d53eee5 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,8 +1,8 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.13-draft +**Version**: 2.15-draft **Status**: Proposal -**Last Updated**: 2026-02-16 +**Last Updated**: 2026-02-26 --- @@ -159,7 +159,7 @@ This tool eliminates that friction by providing a single, authoritative source f | FR-A13 | Capture screenshot from device/emulator | P0 | | FR-A14 | Install full Android environment (JDK + SDK) from scratch | P0 | | FR-A15 | Detect JDK installation and version | P0 | -| FR-A16 | Install OpenJDK if missing (version 17 default, 21 supported) | P0 | +| FR-A16 | Install OpenJDK if missing (default: version 21) | P0 | | FR-A17 | Use platform-appropriate default paths when env vars not set | P0 | ### 4.3 Apple (Xcode) Management @@ -245,7 +245,7 @@ The tool can fully install an Android development environment from scratch, incl └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ Missing? Download Download Operational - OpenJDK 17 cmdline-tools (delegate) + OpenJDK 21 cmdline-tools (delegate) ``` **Default Installation Paths** (when env vars not set): @@ -259,7 +259,7 @@ The tool can fully install an Android development environment from scratch, incl | State | Detection | Behavior | |-------|-----------|----------| -| `JDK_MISSING` | No `java` in PATH, no JDK at default paths | Install OpenJDK 17 to default path | +| `JDK_MISSING` | No `java` in PATH, no JDK at default paths | Install OpenJDK 21 to default path | | `SDK_MISSING` | `ANDROID_HOME` not set, no SDK at standard paths | Install command-line tools to default path | | `PARTIAL` | SDK exists but `sdkmanager` missing/broken | Repair SDK or reinstall cmdline-tools | | `READY` | `java -version` succeeds AND `sdkmanager --list` succeeds | Delegate all operations to native tools | @@ -277,7 +277,7 @@ maui android install --packages "platform-tools,build-tools;35.0.0,platforms;and ``` This command: -1. Checks for JDK; if missing, downloads and installs OpenJDK 17 +1. Checks for JDK; if missing, downloads and installs OpenJDK 21 2. Sets `JAVA_HOME` for the session (prints guidance for permanent setup) 3. Downloads Android command-line tools (if missing) 4. Accepts SDK licenses non-interactively (if `--accept-licenses`) @@ -289,7 +289,7 @@ This command: # Check JDK status maui android jdk check -# Install OpenJDK (default: version 17) +# Install OpenJDK (default: version 21) maui android jdk install maui android jdk install --version 21 @@ -388,7 +388,7 @@ Long-running operations (install, SDK install, JDK install) emit step-by-step pr Console output: ``` [1/4] Checking JDK installation... -[2/4] Installing JDK 17... +[2/4] Installing JDK 21... [3/4] Checking SDK installation... [4/4] Installing SDK packages: platform-tools, build-tools;35.0.0 ✓ Bootstrap completed successfully @@ -400,7 +400,7 @@ JSON output (`--json`): "type": "progress", "step": 2, "total_steps": 4, - "message": "Installing JDK 17...", + "message": "Installing JDK 21...", "percentage": 50 } ``` @@ -752,7 +752,7 @@ The manifest feed parsing infrastructure already exists in `android-platform-sup | **ADB device communication** | DevTools shells out to the `adb` CLI for device listing, logcat streaming, and screenshot capture. | | **CLI command routing** | `System.CommandLine`-based CLI layer, output formatting, `--json`/`--verbose` modes. | | **`avdmanager` / `emulator` lifecycle** | AVD create/start/stop/delete and emulator lifecycle management. | -| **`device screenshot`** | DevTools uses `adb exec-out screencap` for Android screenshots. | +| **`device screenshot`** | DevTools uses `adb exec-out screencap -p` for Android screenshots. | | **OS elevation model** | UAC/sudo handling for SDK installs into protected paths (see §5.4). | | **Apple & Windows providers** | Entirely DevTools-specific; shared Android libraries are Android-only. | @@ -942,12 +942,12 @@ maui │ │ ├── --accept-licenses # Non-interactively accept licenses │ │ ├── --packages # Comma-separated packages to install │ │ ├── --jdk-path

# JDK installation directory -│ │ ├── --jdk-version # JDK version (default: 17) +│ │ ├── --jdk-version # JDK version (default: 21) │ │ └── --sdk-path # SDK installation directory │ ├── jdk # JDK management │ │ ├── check # Check JDK installation status │ │ ├── install # Install OpenJDK -│ │ │ ├── --version # JDK version (default: 17) +│ │ │ ├── --version # JDK version (default: 21) │ │ │ └── --path # Installation directory │ │ └── list # List installed JDK versions │ ├── sdk @@ -1431,6 +1431,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| +| 2.15-draft | 2026-02-26 | Changed default JDK version from 17 to 21 throughout; fixed `adb exec-out screencap` → `adb exec-out screencap -p` | | 2.14-draft | 2026-02-25 | Restored `apple install` with `--accept-license` and `--runtime` flags (optionally accepts license, installs runtimes; could prompt for Xcode install in future); added `apple check` as read-only status; singular `accept-license` for Apple/Xcode matching `xcodebuild -license accept`; Android SDK keeps plural `accept-licenses` | | 2.13-draft | 2026-02-19 | Expanded §6.8: added §6.8.1 Manifest-Driven Downloads & Checksum Verification — no hardcoded URLs, SHA-1 verification from Xamarin/Google manifest feeds. JDK install and SDK bootstrap planned for `dotnet/android-tools`. | | 2.12-draft | 2026-02-19 | Added §6.8 Shared Libraries & Code Reuse — documents reuse of `Xamarin.Android.Tools.AndroidSdk` for SDK/JDK discovery and plan to contribute JDK installation, sdkmanager wrapper, license acceptance back to `dotnet/android-tools` | From 67450cc4d923690f330d6e63ac906db12bc41d76 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 26 Feb 2026 19:21:38 +0000 Subject: [PATCH 34/34] Sync full spec with merged summary spec (PR #34217) - Move device list, screenshot, logs to vNext - Update IDE integration: VS consumes android-tools NuGet directly - Remove runtime list --available (can't enumerate downloadable runtimes) - Replace maui doctor --json IDE reference with specific check commands Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/maui-devtools-spec.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/design/maui-devtools-spec.md b/docs/design/maui-devtools-spec.md index b6ae4d53eee5..addaaca4bcf6 100644 --- a/docs/design/maui-devtools-spec.md +++ b/docs/design/maui-devtools-spec.md @@ -1,6 +1,6 @@ # MAUI Dev Tools Client — Product Specification -**Version**: 2.15-draft +**Version**: 2.16-draft **Status**: Proposal **Last Updated**: 2026-02-26 @@ -668,7 +668,7 @@ User: maui doctor --json > **See [IDE Integration](./maui-devtools-ide-integration.md)** for detailed VS Code and Visual Studio UI flows, status panels, and menu integrations. -**Summary**: IDEs spawn `maui` as a child process, invoke `maui doctor --json` on workspace open, display issues in their problems/error list panels, and provide commands for environment setup with progress notifications. +**Summary**: IDEs consume the `maui` CLI (VS Code, AI agents) or the underlying `android-tools` NuGet library directly (Visual Studio). On workspace open, they invoke environment checks (`maui apple check --json`, `maui android jdk check --json`), display issues in problems panels, and provide commands for environment setup with progress notifications. ### 6.5 Migration from Existing Setups @@ -996,7 +996,6 @@ maui │ ├── runtime │ │ ├── check # Check runtime installation status │ │ ├── list # List runtimes -│ │ │ ├── --available # Show runtimes available for download │ │ │ └── --all # Show all (installed + available) │ │ └── install # Install iOS runtime │ │ └── # Runtime version @@ -1042,7 +1041,6 @@ maui apple simulator list maui apple simulator start maui apple runtime check maui apple runtime list -maui apple runtime list --available # Show downloadable runtimes maui apple runtime install 18.5 # Install specific runtime maui apple xcode check maui apple xcode list @@ -1141,7 +1139,7 @@ All commands follow a consistent exit code scheme: | `maui apple simulator stop` | Stop simulator | `` | Status | 0=success, 5=not found, 2=error | | `maui apple simulator create` | Create simulator | ` ` | UDID | 0=success, 2=error | | `maui apple simulator delete` | Delete simulator | `` | Status | 0=success, 5=not found, 2=error | -| `maui apple runtime list` | List iOS runtimes | `--available`, `--all`, `--json` | Runtime list | 0=success, 2=error | +| `maui apple runtime list` | List iOS runtimes | `--all`, `--json` | Runtime list | 0=success, 2=error | | `maui apple runtime check` | Check runtime status | `--json` | Status report | 0=success, 2=error | | `maui apple runtime install` | Install iOS runtime | `` | Progress, result | 0=success, 2=error | | `maui apple xcode check` | Check Xcode status | `--json` | Status report | 0=success, 2=error | @@ -1395,17 +1393,17 @@ All telemetry and logs follow these redaction rules: | P0 | iOS simulator listing and start/stop/create/delete | ✅ Implemented | | P0 | iOS runtime listing | ✅ Implemented | | P0 | Xcode installation listing and selection | ✅ Implemented | -| P0 | Unified `device list` command (emulators, simulators, physical devices) | ✅ Implemented | -| P0 | `device screenshot` command | ✅ Implemented | | P0 | JSON output for all commands | ✅ Implemented | | P0 | VS Code extension integration | ✅ In progress | -| P1 | Device log streaming | ✅ Implemented | | P1 | Interactive prompting | Planned | ### vNext (v1.x / v2.0) | Priority | Feature | |----------|---------| +| P0 | Unified `device list` command (emulators, simulators, physical devices) | +| P0 | `device screenshot` command | +| P1 | Device log streaming | | P1 | Visual Studio extension integration | | P1 | iOS runtime installation guidance | | P1 | `--correlation-id`, `--offline` global options | @@ -1431,6 +1429,7 @@ All telemetry and logs follow these redaction rules: | Version | Date | Changes | |---------|------|---------| +| 2.16-draft | 2026-02-26 | Synced with merged summary spec (PR #34217): moved `device list`, `device screenshot`, `device logs` to vNext; updated IDE integration to reflect VS consuming `android-tools` NuGet directly; removed `runtime list --available` (no way to enumerate downloadable runtimes); replaced `maui doctor --json` IDE reference with specific check commands | | 2.15-draft | 2026-02-26 | Changed default JDK version from 17 to 21 throughout; fixed `adb exec-out screencap` → `adb exec-out screencap -p` | | 2.14-draft | 2026-02-25 | Restored `apple install` with `--accept-license` and `--runtime` flags (optionally accepts license, installs runtimes; could prompt for Xcode install in future); added `apple check` as read-only status; singular `accept-license` for Apple/Xcode matching `xcodebuild -license accept`; Android SDK keeps plural `accept-licenses` | | 2.13-draft | 2026-02-19 | Expanded §6.8: added §6.8.1 Manifest-Driven Downloads & Checksum Verification — no hardcoded URLs, SHA-1 verification from Xamarin/Google manifest feeds. JDK install and SDK bootstrap planned for `dotnet/android-tools`. |