Add Microsoft.Maui.Client tool for cross-platform device and SDK management#34498
Add Microsoft.Maui.Client tool for cross-platform device and SDK management#34498
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34498Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34498" |
a9c263a to
56f2265
Compare
🤖 AI Summary📊 Expand Full Review📋 Report — Final Recommendation📝 Review Session — Update sdk ·
|
| # | Commit | Description |
|---|---|---|
| 1 | 131e905 |
Clean up dead code, duplicates, and boilerplate |
| 2 | 0e8e0ef |
Split AndroidCommands.cs (1,438→187 lines) into partials |
| 3 | 3e35aa2 |
Consolidate env var setup + 656 format fixes |
| 4 | 18b7e24 |
Fix tests broken by dead code cleanup |
| 5 | ced7e2f |
Remove CS1591 suppression, clean NuGet.config |
| 6 | 12c9a5e |
Fix security (command injection), resource leaks, error handling |
| 7 | dd89798 |
Log exceptions in all 23 catch blocks via Trace.WriteLine |
| 8 | 7014f20 |
Fix thread safety, null guard, extract magic numbers |
| 9 | 2bde4f5 |
Add SanitizeArg tests, fix unused options, shell injection |
| 10 | 091fb64 |
Fix DoctorService command parsing + JdkManager directory safety |
| 11 | d966b4f |
Remove redundant private modifiers, document coding conventions |
| 12 | dbc8e71 |
Add tool + tests to solution and pack filters |
| 13 | 645d725 |
Add tests to Helix pipeline |
Key Fixes by Category
🔴 Security (3 fixes)
- Command injection in LogsCommand via unsanitized filter/device params → Added
SanitizeArg() - Shell injection in XcodeSelect path → Sanitized
- JdkManager arbitrary directory deletion → Added
ValidateInstallPath()
🟡 Correctness (3 fixes)
- DoctorService.TryFixAsync passing full command string as filename → Added
ParseCommand() - Program.cs Services setter race condition → Added lock
- ProcessRunner obsolete method with broken semantics → Removed
🔵 Resource Management (2 fixes)
- HttpClient created per-call in JdkManager → Made static
- Process handle leak in AvdManager → Added Dispose()
🟢 Infrastructure (3 fixes)
- Tool not packaged in CI → Added to sln + pack solution filters
- Tests not running on Helix → Added to eng/helix.proj
- 656 formatting violations → Fixed via dotnet format
Test Coverage
- 118 total tests (31 new: 13 SanitizeArg, 7 ParseCommand, 4 ValidateInstallPath, 7 others)
- 117 pass, 1 pre-existing failure (unrelated)
- Tests now run on Helix (Windows + macOS)
Multi-Model Review
- Gemini 3 Pro + GPT-5.1 + Claude Sonnet 4.5 independently reviewed the API surface
- All 3 agreed on 5 critical findings (command hierarchy, God Interface, missing setup command)
- Ideas filed as Issue #34619
Build Status
- ✅ 0 warnings, 0 errors
- ✅ Format clean
- ✅ Pack produces
Microsoft.Maui.Client.*.nupkg
There was a problem hiding this comment.
Pull request overview
This PR introduces a new cross-platform .NET global tool, Microsoft.Maui.Client (command name: maui), intended to provide a unified CLI for MAUI environment diagnostics (“doctor”), device enumeration, log streaming, and Android/Apple environment management. It also adds a dedicated unit test project and wires it into Helix.
Changes:
- Add
src/Tools/Microsoft.Maui.Clientimplementation (commands, providers, services, models, output formatters, utilities). - Add
src/Tools/tests/Microsoft.Maui.Client.UnitTestswith fakes and coverage for core helpers and DI setup. - Integrate the new test project into Helix and update build metadata/versioning inputs for tool dependencies.
Reviewed changes
Copilot reviewed 70 out of 75 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Tools/Microsoft.Maui.Client/Microsoft.Maui.Client.csproj | New global tool project definition (packable tool, dependencies). |
| src/Tools/Microsoft.Maui.Client/Program.cs | CLI entry point, command registration, global options, exception handling. |
| src/Tools/Microsoft.Maui.Client/ServiceConfiguration.cs | DI registration and test service provider helpers. |
| src/Tools/Microsoft.Maui.Client/Commands/AndroidCommands.cs | Android command group + interactive install package selection helpers. |
| src/Tools/Microsoft.Maui.Client/Commands/AndroidCommands.Install.cs | Android environment install workflow (interactive + CI/dry-run). |
| src/Tools/Microsoft.Maui.Client/Commands/AndroidCommands.Jdk.cs | JDK check/install/list commands. |
| src/Tools/Microsoft.Maui.Client/Commands/AndroidCommandsTests.cs | Unit tests for Android command shape/option parsing. |
| src/Tools/Microsoft.Maui.Client/Commands/CommandExtensions.cs | Helper for retrieving command-local option values. |
| src/Tools/Microsoft.Maui.Client/Commands/DeviceCommand.cs | maui device list/logs subcommands. |
| src/Tools/Microsoft.Maui.Client/Commands/DoctorCommand.cs | maui doctor checks + optional --fix. |
| src/Tools/Microsoft.Maui.Client/Commands/LogsCommand.cs | Top-level maui logs streaming implementation and colorization. |
| src/Tools/Microsoft.Maui.Client/Commands/VersionCommand.cs | maui version output in JSON or formatted form. |
| src/Tools/Microsoft.Maui.Client/Errors/ErrorCodes.cs | Structured error code taxonomy for the tool. |
| src/Tools/Microsoft.Maui.Client/Errors/MauiToolException.cs | Tool exception type with remediation metadata. |
| src/Tools/Microsoft.Maui.Client/Models/Device.cs | Cross-platform device schema and related enums/constants. |
| src/Tools/Microsoft.Maui.Client/Models/DoctorReport.cs | Doctor report schema and check/fix metadata. |
| src/Tools/Microsoft.Maui.Client/Models/ErrorResult.cs | JSON error contract and exception-to-error conversion. |
| src/Tools/Microsoft.Maui.Client/Models/Platforms.cs | Platform string constants + normalization/validation helpers. |
| src/Tools/Microsoft.Maui.Client/Output/IOutputFormatter.cs | Formatter interface for JSON vs console output. |
| src/Tools/Microsoft.Maui.Client/Output/JsonOutputFormatter.cs | JSON formatting and serialization options. |
| src/Tools/Microsoft.Maui.Client/Providers/Android/Adb.cs | Wrapper around android-tools ADB device enumeration and stop. |
| src/Tools/Microsoft.Maui.Client/Providers/Android/AndroidEnvironment.cs | ABI/API mapping + env var composition helpers. |
| src/Tools/Microsoft.Maui.Client/Providers/Android/AvdManager.cs | AVD management wrapper around android-tools runners. |
| src/Tools/Microsoft.Maui.Client/Providers/Android/IAndroidProvider.cs | Android provider abstraction + related records. |
| src/Tools/Microsoft.Maui.Client/Providers/Android/IJdkManager.cs | JDK manager abstraction. |
| src/Tools/Microsoft.Maui.Client/Providers/Android/SdkManager.cs | SDK package management wrapper around android-tools. |
| src/Tools/Microsoft.Maui.Client/Providers/Apple/AppleProvider.cs | Apple provider built on xcrun simctl + xcode-select. |
| src/Tools/Microsoft.Maui.Client/Providers/Apple/IAppleProvider.cs | Apple provider abstraction + runtime model. |
| src/Tools/Microsoft.Maui.Client/Providers/Apple/Simctl.cs | simctl process wrapper + JSON parsing to device/runtime models. |
| src/Tools/Microsoft.Maui.Client/Providers/Apple/XcodeSelect.cs | xcode-select and Xcode discovery/switching helper. |
| src/Tools/Microsoft.Maui.Client/Services/DeviceManager.cs | Cross-platform device aggregation + AVD/emulator metadata merging. |
| src/Tools/Microsoft.Maui.Client/Services/IDeviceManager.cs | Device manager abstraction. |
| src/Tools/Microsoft.Maui.Client/Services/DoctorService.cs | Doctor checks, categorization, and --fix command execution helper. |
| src/Tools/Microsoft.Maui.Client/Services/IDoctorService.cs | Doctor service abstraction. |
| src/Tools/Microsoft.Maui.Client/Utils/PlatformDetector.cs | OS/arch detection and default tool path discovery. |
| src/Tools/Microsoft.Maui.Client/Utils/ProcessRunner.cs | Process execution helper (sync/async), sanitization, elevation helpers. |
| src/Tools/Microsoft.Maui.Client/Scripts/demo-all.sh | Scripted demo runner for CLI scenarios. |
| src/Tools/Microsoft.Maui.Client/Scripts/demo-android-emulator.sh | Android emulator demo script. |
| src/Tools/Microsoft.Maui.Client/Scripts/demo-android-sdk.sh | Android SDK demo script. |
| src/Tools/Microsoft.Maui.Client/Scripts/demo-apple.sh | Apple/macOS demo script. |
| src/Tools/Microsoft.Maui.Client/Scripts/demo-interactive-install.sh | Demonstrates interactive UX flows. |
| src/Tools/Microsoft.Maui.Client/Scripts/demo-json-scripting.sh | Demonstrates --json usage for scripting. |
| src/Tools/Microsoft.Maui.Client/Scripts/demo-overview.sh | Quick “version/doctor/device” overview script. |
| src/Tools/Microsoft.Maui.Client/Scripts/demo-simulator-boot.sh | Boots/shuts down an iOS simulator demo. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/Microsoft.Maui.Client.UnitTests.csproj | New unit test project for the tool. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/AndroidProviderTests.cs | Tests for Android provider fakes and behaviors. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/DeviceManagerTests.cs | Tests for device aggregation/merge behavior. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/DoctorServiceTests.cs | Tests for doctor check aggregation/summary. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/ErrorCodesTests.cs | Tests for error code formatting/grouping. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/MauiToolExceptionTests.cs | Tests for exception/remediation shaping. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/OutputFormatterTests.cs | Tests for JSON + Spectre formatter behaviors. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/PlatformsTests.cs | Tests for platform normalization/validation. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/ProcessRunnerTests.cs | Tests for argument sanitization + command parsing + JDK path validation. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/ServiceConfigurationTests.cs | Tests for DI registrations and override behavior. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/Fakes/FakeAndroidProvider.cs | Test fake Android provider with call tracking. |
| src/Tools/tests/Microsoft.Maui.Client.UnitTests/Fakes/FakeAppleProvider.cs | Test fake Apple provider with call tracking. |
| eng/helix.proj | Add new tool unit tests to Helix test list. |
| eng/Versions.props | Add versions for new tool dependencies. |
| eng/Version.Details.xml | Add dependency tracking entries for new tool dependencies. |
| eng/Microsoft.Maui.Packages.slnf | Include tool project in packaging solution filter. |
| eng/Microsoft.Maui.Packages-mac.slnf | Include tool project in mac packaging solution filter. |
| NuGet.config | Add an additional restore feed needed for new tool dependencies. |
| .github/copilot-instructions.md | Document C# repo conventions for Copilot guidance. |
|
🧪 PR Test EvaluationOverall Verdict: The 79 unit tests are well-structured and cover the most critical paths (security, Android commands, core services), but Apple commands and several CLI command handlers have zero test coverage despite a
📊 Expand Full EvaluationPR Test Evaluation ReportPR: #34498 — Add Microsoft.Maui.Client tool for cross-platform device and SDK management Overall VerdictThe unit tests are well-structured and appropriately cover security-sensitive code, Android commands, core services, and output formatting. However, 1. Fix Coverage —
|
🧪 PR Test EvaluationOverall Verdict: The unit tests provide solid coverage of the new CLI tool's core logic, but
📊 Expand Full EvaluationPR Test Evaluation ReportPR: #34498 — MAUI CLI Client Tool (Android) Overall VerdictThe unit tests are well-structured and use a good fake/mock pattern ( 1. Fix Coverage —
|
🟡 NEW Findings Not Yet on the PRM1 —
|
|
@simonrozsival great questions: xharness comparison: xharness is focused on running tests on devices/simulators — it orchestrates test execution, collects results, and handles device allocation for CI pipelines. This tool ( dnx / tool name: The tool command name is |
🧪 PR Test Evaluation❌ Cannot evaluate: this PR's branch does not include the evaluate-pr-tests skill ( Fix: rebase your fork on the latest Note 🔒 Integrity filtering filtered 1 itemIntegrity filtering activated and filtered the following item during workflow execution.
|
🧪 PR Test Evaluation❌ Cannot evaluate: this PR's branch does not include the evaluate-pr-tests skill ( Fix: rebase your fork on the latest
|
- Split FixInfo.Command into fileName+arguments in TryFixAsync via ParseCommand(), fixing broken multi-word auto-fix commands (e.g., 'dotnet workload install maui' was passed as filename) - Add ValidateInstallPath() to JdkManager to prevent recursive deletion of system/home/shallow directories via --path option - Add 18 tests: ParseCommand (7) + ValidateInstallPath (4) + SanitizeArg existing coverage maintained Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ols ref - Bump Xamarin.Android.Tools.AndroidSdk to 1.0.143-preview.8 from CI feed - Remove Xamarin.Apple.Tools.MaciOS PackageReference (not used by CLI code yet) - Build succeeds: 0 warnings, 0 errors Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove Moq dependency and replace all Mock<T> usage with simple FakeAndroidProvider and FakeAppleProvider stubs. This avoids the Moq dependency and makes test setup more explicit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Honor --ci flag by skipping interactive prompts in all commands (install, sdk install, emulator create/start/stop/delete) - Fix iOS log filter double-quoting when filter contains spaces by escaping quotes directly instead of using SanitizeArg - Fix Services property race condition by always acquiring lock (remove broken double-checked locking pattern) - Fix process leak in StartAvdAsync by killing emulator process on cancellation before re-throwing OperationCanceledException Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove TakeScreenshotAsync from all layers: - Adb: delete TakeScreenshotAsync method - AndroidProvider: delete TakeScreenshotAsync method - IAndroidProvider: delete TakeScreenshotAsync from interface - IDeviceManager: delete TakeScreenshotAsync from interface - DeviceManager: delete TakeScreenshotAsync and TakeAppleScreenshotAsync - DeviceCommand: delete CreateScreenshotCommand and its registration - FakeAndroidProvider: delete TakeScreenshotAsync and tracking field Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move test project from src/Tools/Microsoft.Maui.Client.Tests to src/Tools/tests/Microsoft.Maui.Client.UnitTests (repo convention) - Rename csproj to Microsoft.Maui.Client.UnitTests.csproj - Update ProjectReference path to ../../Microsoft.Maui.Client/ - Update InternalsVisibleTo from Tests to UnitTests - Update namespace in all test files from Microsoft.Maui.Client.Tests to Microsoft.Maui.Client.UnitTests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove 95 explicit 'private' modifiers per editorconfig rule (dotnet_style_require_accessibility_modifiers = never) - Add C# Coding Conventions section to copilot-instructions.md documenting: no private, var usage, file-scoped namespaces, _camelCase fields, braces, no this. qualifier, predefined types Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The tool and test projects were not included in the main solution or the pack solution filters, so the tool was never packaged during CI builds. - Add Microsoft.Maui.Client to Microsoft.Maui.sln (Tools folder) - Add Microsoft.Maui.Client.UnitTests to Microsoft.Maui.sln - Add to eng/Microsoft.Maui.Packages.slnf (Windows pack) - Add to eng/Microsoft.Maui.Packages-mac.slnf (macOS pack) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add the test project to eng/helix.proj XUnitProject list so tests run on Helix infrastructure during CI. Also add explicit xunit package reference matching the pattern of other test projects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove LogsCommand.cs, 'device logs' subcommand, and logs screenshot. The logs feature will be added in a future phase. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CI restores for net10.0 (from _MauiDotNetTfm) but projects targeted net9.0, causing NETSDK1005 asset mismatch. Use $(_MauiDotNetTfm) to match repo SDK. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the default System.CommandLine help renderer with a custom SpectreHelpBuilder that uses Spectre.Console markup for colored output: - Yellow section headers (Description, Usage, Options, Commands) - Green option aliases and command names - Dim annotations for platform-specific commands (macOS) - Alphabetically sorted subcommands The custom help is triggered before the parser runs by checking args for help aliases, then resolving the target command and rendering via SpectreHelpBuilder. This avoids fighting System.CommandLine's internal help middleware. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove Apple provider (IAppleProvider, AppleProvider, Simctl, XcodeSelect), Apple commands, Apple error codes (E22xx), Apple health checks in DoctorService, Apple device listing in DeviceManager, FakeAppleProvider test fake, and macOS annotation logic in SpectreHelpBuilder. Apple/macOS support will be added in a separate follow-up PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
….Details.xml - ProcessRunner: Use ProcessStartInfo.ArgumentList instead of manual string quoting (addresses @rolfbjarne feedback). RunSync/RunAsync now take string[] args. SanitizeArg no longer quotes, only validates. - Move package versions to eng/Versions.props (addresses @PureWeen feedback): SystemCommandLine, SpectreConsole, plus test project's Spectre.Console.Testing. - System.CommandLine stays on beta (2.0.0-beta4.22272.1) — stable 2.0.x has breaking API changes requiring substantial migration. - Align eng/Version.Details.xml android-tools entry to 1.0.143-preview.8 to match eng/Versions.props (addresses Copilot review feedback). - Update DoctorService.ParseCommand to return string[] args array. - All 118 tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Full API migration from System.CommandLine 2.0.0-beta4.22272.1 to the stable 2.0.5 release. Key changes: - CommandLineBuilder pipeline → rootCommand.Parse(args).InvokeAsync() - SetHandler(InvocationContext) → SetAction(ParseResult, CancellationToken) - context.ExitCode = N → return N from handler (Task<int> overload) - context.GetCancellationToken() → CancellationToken parameter - GetValueForOption/Argument → GetValue - AddGlobalOption → Option.Recursive = true + Add - Option/Argument constructors → object initializer syntax - Remove System.CommandLine.Builder and Invocation namespaces All 118 tests pass. No behavioral changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1bedb66 to
cb25e55
Compare
🧪 PR Test EvaluationOverall Verdict: The 118 unit tests are well-structured and cover the most critical paths (security, command structure, DI), but several significant behaviors — including
📊 Expand Full EvaluationPR Test Evaluation ReportPR: #34498 — Add Microsoft.Maui.Client tool for cross-platform device and SDK management Overall VerdictTests are good quality (hand-written fakes, xUnit conventions, security-critical paths well covered), but notable gaps exist in 1. Fix Coverage —
|
The previous 'dotnet sln add' introduced x64 and x86 platform configurations to the entire solution, which breaks Android/iOS multi-target builds (CS0246: 'Android' namespace not found). Restored clean sln from main and manually added tool projects with Any CPU configs only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…sync
The test was asserting status != Unhealthy but RunAllChecksAsync always
runs dotnet SDK/workload checks that fail on Helix machines (no MAUI
workload installed). Changed to use RunCategoryChecksAsync('android')
which only exercises the mocked android provider checks.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🧪 PR Test EvaluationOverall Verdict: ✅ Tests are adequate The PR introduces a new
📊 Expand Full EvaluationPR Test Evaluation ReportPR: #34498 — Microsoft.Maui.Client CLI tool (Android support) Overall Verdict✅ Tests are adequate Tests are well-structured, use the correct type (unit tests), follow xUnit conventions, and cover the key business logic via a thoughtfully designed 1. Fix Coverage — ✅Tests cover all major subsystems introduced by the PR:
Gap: The real 2. Edge Cases & Gaps —
|
| Test File | Fix File(s) Covered |
|---|---|
AndroidCommandsTests |
AndroidCommands*.cs |
AndroidProviderTests |
IAndroidProvider, FakeAndroidProvider infrastructure |
DeviceManagerTests |
DeviceManager.cs |
DoctorServiceTests |
DoctorService.cs |
ErrorCodesTests |
ErrorCodes.cs |
MauiToolExceptionTests |
MauiToolException.cs |
OutputFormatterTests |
JsonOutputFormatter.cs, SpectreOutputFormatter.cs |
PlatformsTests |
Platforms.cs |
ProcessRunnerTests |
ProcessRunner.cs, DoctorService.ParseCommand, JdkManager.ValidateInstallPath |
ServiceConfigurationTests |
ServiceConfiguration.cs, Program.cs |
Recommendations
-
Fix the
Task.Delay(100)flakiness inInstallAsync_ReportsProgress— use a synchronization primitive instead of an arbitrary delay to avoid intermittent CI failures. -
Add a test for
RunCategoryChecksAsync("windows")on a non-Windows host to cover theSkippedstatus branch inDoctorService. -
Consider adding integration tests for the real
AndroidProviderimplementation against actualadb/avdmanagerbinaries, even if only run on Android-capable CI agents. The command injection protection inProcessRunner.SanitizeArgis only validated in unit tests today.
Warning
⚠️ Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
dc.services.visualstudio.com
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "dc.services.visualstudio.com"See Network Configuration for more information.
Note
🔒 Integrity filtering filtered 1 item
Integrity filtering activated and filtered the following item during workflow execution.
This happens when a tool call accesses a resource that does not meet the required integrity or secrecy level of the workflow.
- pr:Add Microsoft.Maui.Client tool for cross-platform device and SDK management #34498 (
pull_request_read: Resource 'pr:Add Microsoft.Maui.Client tool for cross-platform device and SDK management #34498' has lower integrity than agent requires. Agent would need to drop integrity tags [unapproved:all approved:all] to trust this resource.)
🧪 Test evaluation by Evaluate PR Tests
…ails.xml Apple support was removed from this PR and deferred to a follow-up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🧪 PR Test EvaluationOverall Verdict: The unit test suite is well-structured and covers the main components of the new
📊 Expand Full EvaluationPR Test Evaluation ReportPR: #34498 — Microsoft.Maui.Client CLI tool (Android SDK/JDK/emulator management) Overall VerdictThe tests cover core data models and service contracts well using a clean 1. Fix Coverage —
|
1. DeviceManager.GetRunningDeviceOrThrowAsync now uses IsRunning instead of checking State == Booted. Android maps online devices to Connected not Booted, so they were never found. 2. DoctorCommand --fix now re-runs checks after applying fixes and bases exit code on post-fix results. Previously always exited with failure even after successful fixes. 3. Remove 'apple' from --platform option help text since the service throws for that value. Apple support deferred to follow-up PR. 4. Honor --accept-licenses flag in android install. Both Spectre and non-Spectre paths now skip license acceptance unless the flag is set. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🧪 PR Test EvaluationOverall Verdict: ✅ Tests are adequate This PR introduces a new
📊 Expand Full EvaluationPR Test Evaluation ReportPR: #34498 — Microsoft.Maui.Client CLI tool (Android developer tooling) Overall Verdict✅ Tests are adequate The PR uses the correct test type (xUnit unit tests) with a well-designed 1. Fix Coverage — ✅The tests cover the major components of the new CLI tool:
Tests would catch regressions in all of these code paths. 2. Edge Cases & Gaps —
|
| Fix Area | Test Coverage |
|---|---|
AndroidCommands*.cs |
AndroidCommandsTests — all subcommands and options |
DoctorService.cs |
DoctorServiceTests, ProcessRunnerTests.DoctorServiceParseCommandTests |
ProcessRunner.cs (SanitizeArg) |
ProcessRunnerTests — thorough injection scenarios |
DeviceManager.cs |
DeviceManagerTests — merge logic fully covered |
JsonOutputFormatter.cs, SpectreOutputFormatter.cs |
OutputFormatterTests |
ServiceConfiguration.cs |
ServiceConfigurationTests |
Platforms.cs |
PlatformsTests |
MauiToolException.cs, ErrorCodes.cs |
MauiToolExceptionTests, ErrorCodesTests |
AndroidProvider.cs |
Only via FakeAndroidProvider (concrete class untested) |
Recommendations
- Consider replacing
Task.Delay(100)inInstallAsync_ReportsProgresswith a synchronousIProgress(T)implementation or aTaskCompletionSourceapproach to avoid timing-dependent assertions. - Add a Windows-specific system directory test in
JdkManagerValidateInstallPathTests(e.g.,C:\Windows) to match the Unix coverage. - Watch
RunAllChecksAsync_IncludesDotNetChecks— it runs realdotnetCLI commands; if CI agents have unusual .NET SDK configurations this could surface as a flaky test.
Warning
⚠️ Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
dc.services.visualstudio.com
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "dc.services.visualstudio.com"See Network Configuration for more information.
Note
🔒 Integrity filtering filtered 2 items
Integrity filtering activated and filtered the following items during workflow execution.
This happens when a tool call accesses a resource that does not meet the required integrity or secrecy level of the workflow.
- pr:Add Microsoft.Maui.Client tool for cross-platform device and SDK management #34498 (
pull_request_read: Resource 'pr:Add Microsoft.Maui.Client tool for cross-platform device and SDK management #34498' has lower integrity than agent requires. Agent would need to drop integrity tags [approved:all unapproved:all] to trust this resource.) - pr:Add Microsoft.Maui.Client tool for cross-platform device and SDK management #34498 (
pull_request_read: Resource 'pr:Add Microsoft.Maui.Client tool for cross-platform device and SDK management #34498' has lower integrity than agent requires. Agent would need to drop integrity tags [unapproved:all approved:all] to trust this resource.)
🧪 Test evaluation by Evaluate PR Tests
|
/azp run |
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Summary
Add the
mauiCLI tool (Microsoft.Maui.Client) — a cross-platform command-line tool for managing Android development environments, devices, and emulators. This tool powers the VS Code MAUI extension acquisition experience and can also be used standalone.Built with Spectre.Console for rich terminal UI including interactive prompts, progress bars, colored tables, and tree views. All commands support
--jsonfor machine-readable output (consumed by the VS Code extension).Important
Apple/macOS support (Xcode management, iOS simulators, runtime management) has been intentionally removed from this PR to keep the scope focused on Android. Apple support will be added in a follow-up PR once the macios-devtools package APIs are finalized.
Screenshots
maui --helpmaui doctor— Environment diagnosticsmaui device list— Cross-platform device listingmaui android install— Interactive SDK setupSpec PRs
maui device listcommand spec to CLI design doc #34277Key Features
maui doctor--fixto auto-resolve issues and--platformto scope checks.maui android sdk checkmaui android installmaui android jdk check/installmaui android avd list/create/deletemaui android emulator start/stopmaui device listmaui version--json--dry-run--verboseArchitecture
Security
ArgumentList(not shell-interpolated strings) to prevent command injectionJdkManager.ValidateInstallPath()prevents arbitrary directory operationsDoctorService.ParseCommand()safely splits command strings into fileName + argumentsProcessRunnerusesUseShellExecute = falsewith direct process invocationTesting
eng/helix.projFakeAndroidProviderfor full controldotnet test src/Tools/tests/Microsoft.Maui.Client.UnitTestsCI Integration
Microsoft.Maui.sln(Any CPU only — no x64/x86)eng/Microsoft.Maui.Packages.slnf,eng/Microsoft.Maui.Packages-mac.slnf)eng/helix.proj(Windows.10.Amd64.Open + osx.15.arm64.maui.open)eng/Versions.propsandeng/Version.Details.xmlHow to Test
Dependencies Added
System.CommandLineSpectre.ConsoleXamarin.Android.Tools.AndroidSdkFuture Improvements
See Issue #34619 for multi-model API design ideas including:
IAndroidProviderinto focused interfaces (SDK, JDK, Device, Emulator)maui setupunified bootstrap commandmaui configfor persistent settings