-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[spec] Add maui device list command spec to CLI design doc
#34277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| --- | ||
| description: "Design document for the maui CLI tool" | ||
| date: 2026-01-07 | ||
| updated: 2026-02-26 | ||
| updated: 2026-02-27 | ||
| --- | ||
|
|
||
| # `maui` CLI Design Document | ||
|
|
@@ -197,6 +197,170 @@ All commands use consistent exit codes: | |
| | 4 | Network error (download failed) | | ||
| | 5 | Resource not found | | ||
|
|
||
| ## Device Discovery | ||
|
|
||
| ### `maui device list` | ||
|
|
||
| Lists connected devices, running emulators, and available simulators | ||
| across all platforms from a single command. | ||
|
|
||
| **Usage:** | ||
|
|
||
| ```bash | ||
| maui device list [--platform <p>] [--json] | ||
| ``` | ||
|
|
||
| **Options:** | ||
|
|
||
| - `--platform <PLATFORM>`: Filter by platform (`android`, `ios`, | ||
| `maccatalyst`). If omitted, lists all platforms. | ||
| - `--json`: Structured JSON output for machine consumption. | ||
|
|
||
| **Human-readable output:** | ||
|
|
||
| ``` | ||
| ID Description Type Platform Status | ||
| emulator-5554 Pixel 7 - API 35 Emulator android Online | ||
| 0A041FDD400327 Pixel 7 Pro Device android Online | ||
| 94E71AE5-8040-4DB2-8A9C-6CD24EF4E7DE iPhone 16 - iOS 26.0 Simulator ios Shutdown | ||
| FBF5DCE8-EE2B-4215-8118-3A2190DE1AD7 iPhone 14 - iOS 26.0 Simulator ios Booted | ||
| AF40CC64-2CDB-5F16-9651-86BCDF380881 My iPhone 15 Device ios Paired | ||
| ``` | ||
|
|
||
| **JSON output (`--json`):** | ||
|
|
||
| ```json | ||
| { | ||
| "devices": [ | ||
| { | ||
| "id": "emulator-5554", | ||
| "description": "Pixel 7 - API 35", | ||
| "type": "Emulator", | ||
| "platform": "android", | ||
| "status": "Online" | ||
| }, | ||
| { | ||
| "id": "FBF5DCE8-EE2B-4215-8118-3A2190DE1AD7", | ||
| "description": "iPhone 14 - iOS 26.0", | ||
| "type": "Simulator", | ||
| "platform": "ios", | ||
| "status": "Booted" | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| The `id` field is the same identifier accepted by `dotnet run --device | ||
| <id>`, so output from `maui device list` can be piped directly into a | ||
| run command. | ||
|
|
||
| ### Two Approaches to Device Enumeration | ||
|
|
||
| There are two ways to enumerate devices, each suited to different | ||
| scenarios. | ||
|
|
||
| #### Approach A: Via `dotnet run --list-devices` (project-based) | ||
|
|
||
| The .NET SDK (≥ .NET 11) provides `dotnet run --list-devices`, which | ||
| calls the [`ComputeAvailableDevices`][compute-android] MSBuild target | ||
| defined by each platform workload ([spec][dotnet-run-spec]): | ||
|
|
||
| - **Android** ([dotnet/android]): calls `adb devices`, returns | ||
| serial, description, type (Device/Emulator), status, model | ||
| - **Apple** ([dotnet/macios]): calls `simctl list` and `devicectl | ||
| list`, returns UDID, description, type (Device/Simulator), | ||
| OS version, RuntimeIdentifier | ||
|
|
||
| This approach **requires a project file** — MSBuild evaluates the | ||
| `.csproj` to locate the correct workload targets. It also operates | ||
| **per-framework**: you select a target framework first, then get | ||
| devices for that platform only. | ||
|
|
||
| [dotnet/android]: https://github.com/dotnet/android | ||
| [dotnet/macios]: https://github.com/dotnet/macios | ||
|
|
||
| #### Approach B: Direct native tool invocation (project-free) | ||
|
|
||
| The `maui` CLI calls the same native tools directly — `adb devices`, | ||
| `xcrun simctl list devices`, `xcrun devicectl list devices` — without | ||
| evaluating any MSBuild project. This returns a unified, cross-platform | ||
| device list in a single call. | ||
|
|
||
| #### Comparison | ||
|
|
||
| | | Approach A (MSBuild) | Approach B (Native CLI) | | ||
| |---|---|---| | ||
| | **Project required** | Yes — needs `.csproj` | No | | ||
| | **Cross-platform** | One platform per call (per TFM) | All platforms in one call | | ||
| | **Metadata** | Rich (RuntimeIdentifier, workload-specific fields) | Standard (id, description, type, status) | | ||
| | **Speed** | Slower (MSBuild evaluation + restore) | Fast (<2s, direct process calls) | | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I doubt listing devices for all platforms will beat 2 seconds, do we have a measurement?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a working version now on vscode it s what it looks like :) I can try give you a exact number |
||
| | **ID compatibility** | Source of truth for `dotnet run --device` | Same native IDs — compatible | | ||
| | **Requires workloads** | Yes (platform workload must be installed) | Only native tools (`adb`, `simctl`) | | ||
| | **Extensible** | Workloads add new device types automatically | Must add support per platform | | ||
|
|
||
| #### Scenarios Without a Project | ||
|
|
||
| Several real workflows need device enumeration **before** a project | ||
| exists or **outside** any project context: | ||
|
|
||
| 1. **AI agent bootstrapping** — An agent starting a "vibe coding" | ||
| session needs to discover available targets before scaffolding a | ||
| project. It cannot call `dotnet run --list-devices` because there | ||
| is no `.csproj` yet. | ||
|
Comment on lines
+306
to
+309
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand, why does it need to know the devices before a project exists? What is it going to do with the list of devices?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you share a screenshot/example?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can look at maui ci for example ,we list first the devices to understand if we need to create a emulator to then pass to appium script
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But you have the repo cloned and have a project?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the future, you should
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Far point on xharness, dotnet test is definitely the future there 👍 The main scenarios I keep coming back to are the ones where there truly is no project:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jonathanpeppers so you fine to merge this ? We can then in future maybe do a little better? if needed. We most have this merge already on android-tools so is just a case of the client tool use it. Also we would need to update the client spec in the future as seems screenshot for example is now on MauiDevFlow on the maui labs repository
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would focus on getting the first command -- and making the CLI actually exist before merging this.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Merging now the cli exist on maui-labs |
||
|
|
||
| 2. **IDE startup** — VS Code opens a workspace with no MAUI project | ||
| loaded. The extension needs to populate its device picker to show | ||
| the user what's available. A project-free query is the only option. | ||
|
|
||
| 3. **Environment validation** — A developer runs `maui device list` | ||
| to answer "can I see my phone?" without needing to be inside any | ||
| project directory. This is a diagnostic step, not a build step. | ||
|
|
||
| 4. **CI pipeline setup** — A CI script checks that the expected | ||
| emulator or simulator is running before invoking `dotnet run`. | ||
| The check should not depend on a specific project file. | ||
|
|
||
| 5. **Multi-project solutions** — A solution contains both Android and | ||
| iOS projects. The developer wants a single unified device list | ||
| rather than running `--list-devices` per project. | ||
|
|
||
| 6. **Cross-platform overview** — `dotnet run --list-devices` shows | ||
| devices for one TFM at a time. A developer switching between | ||
| Android and iOS wants to see everything at once. | ||
|
|
||
| #### Recommended Approach | ||
|
|
||
| `maui device list` uses **Approach B** (direct native tool invocation) | ||
| as its primary implementation: | ||
|
|
||
| - It works anywhere — no project, no workload targets, no MSBuild | ||
| evaluation overhead. | ||
| - Device identifiers are the same native IDs used by | ||
| `ComputeAvailableDevices`, so they are fully compatible with | ||
| `dotnet run --device`. | ||
| - The `maui` CLI already wraps these native tools for other commands | ||
| (environment setup, emulator management), so device listing is a | ||
| natural extension. | ||
|
|
||
| When a project **is** available and the user wants framework-specific | ||
| device filtering, `dotnet run --list-devices` remains the right tool — | ||
| it provides richer metadata (RuntimeIdentifier) and benefits from | ||
| workload-specific logic. The two approaches are complementary: | ||
|
|
||
| ``` | ||
| maui device list → "What devices exist on this machine?" | ||
| dotnet run --list-devices → "What devices can run this project?" | ||
| ``` | ||
|
|
||
| **Platform Implementation:** | ||
|
|
||
| | Platform | Native tool | What is enumerated | | ||
| |----------|------------|-------------------| | ||
| | Android | `adb devices -l` | Physical devices and running emulators | | ||
| | iOS (simulators) | `xcrun simctl list devices --json` | All simulators (booted + shutdown) | | ||
| | iOS (physical) | `xcrun devicectl list devices` | Connected physical devices | | ||
| | Mac Catalyst | (host machine) | The Mac itself | | ||
|
|
||
| ## App Inspection Commands (Future) | ||
|
|
||
| > **Note**: App inspection commands are planned for a future release. The initial release focuses on environment setup and device management. | ||
|
|
@@ -268,7 +432,6 @@ Initial implementation targets Android and iOS/Mac Catalyst, with Windows and ma | |
|
|
||
| ### Future Commands | ||
|
|
||
| - `maui device list` for unified device/emulator/simulator listing across platforms | ||
| - `maui screenshot` for capturing screenshots of running apps | ||
| - `maui logs` for streaming device logs | ||
| - `maui tree` for inspecting the visual tree | ||
|
|
@@ -292,6 +455,9 @@ maui tree --json # future | |
| ### AI Agent Workflow | ||
|
|
||
| ```bash | ||
| # 0. Discover available devices (no project needed) | ||
| maui device list --json | ||
|
|
||
| # 1. Make code changes | ||
| # ... agent modifies MainPage.xaml ... | ||
|
|
||
|
|
@@ -392,7 +558,7 @@ Visual Studio consumes the `Xamarin.Android.Tools.AndroidSdk` NuGet package from | |
| |----------|------------|--------------| | ||
| | 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` (future) | Populate device dropdown / selection UI | | ||
| | Device picker | `maui device list --json` | Populate device dropdown / selection UI | | ||
| | Emulator launch | `maui android emulator start <name> --json` | Show notification, update device list on completion | | ||
|
|
||
| ### Benefits | ||
|
|
@@ -440,12 +606,11 @@ simulators) are now included above. These were inspired by: | |
|
|
||
| Future commands: | ||
|
|
||
| - `maui device list` for unified device listing | ||
| - `maui logs` for viewing console output | ||
| - `maui tree` for displaying the visual tree | ||
| - `maui screenshot` for capturing screenshots | ||
|
|
||
| **Decision**: Environment setup ships first. Device listing and app inspection commands | ||
| **Decision**: Environment setup and device listing ship first. App inspection commands | ||
| follow in a future release. | ||
|
|
||
| ## References | ||
|
|
@@ -454,9 +619,13 @@ follow in a future release. | |
| - [dotnet run for .NET MAUI specification][dotnet-run-spec] | ||
| - [Workload manifest specification][workload-spec] | ||
| - [AppleDev.Tools][appledev-tools] - Wraps simctl and devicectl commands | ||
rmarinho marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - [ComputeAvailableDevices (Android)][compute-android] - Android workload MSBuild target | ||
| - [ComputeAvailableDevices (Apple)][compute-apple] - Apple workload MSBuild target | ||
| - [System.CommandLine documentation](https://learn.microsoft.com/dotnet/standard/commandline/) | ||
| - [Android Debug Bridge (ADB)](https://developer.android.com/studio/command-line/adb) | ||
| - [simctl command-line tool](https://nshipster.com/simctl/) | ||
|
|
||
| [vibe-wpf]: https://github.com/jonathanpeppers/vibe-wpf | ||
| [appledev-tools]: https://github.com/Redth/AppleDev.Tools | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Xamarin.MacDev? |
||
| [compute-android]: https://github.com/dotnet/android/blob/main/Documentation/docs-mobile/building-apps/build-targets.md#computeavailabledevices | ||
| [compute-apple]: https://github.com/dotnet/macios/blob/main/docs/building-apps/build-targets.md#computeavailabledevices | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you need to list all the platforms in one call? This will be really slow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vscode does that