diff --git a/docs/design/cli.md b/docs/design/cli.md
index c61fbb07a61f..ec396c2dba94 100644
--- a/docs/design/cli.md
+++ b/docs/design/cli.md
@@ -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
] [--json]
+```
+
+**Options:**
+
+- `--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
+`, 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) |
+| **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.
+
+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 --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
+- [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
+[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