| name | maui-ai-debugging |
| description | End-to-end workflow for building, deploying, inspecting, and debugging .NET MAUI and MAUI Blazor Hybrid apps as an AI agent. Use when: (1) Building or running a MAUI app on iOS simulator, Android emulator, Mac Catalyst, or Linux/GTK, (2) Deploying a MAUI app to a device/emulator/simulator, (3) Inspecting or interacting with a running MAUI app's UI (visual tree, element tapping, filling text, screenshots, property queries), (4) Debugging Blazor WebView content inside a MAUI app via CDP, (5) Managing iOS simulators or Android emulators (create, boot, list, install), (6) Setting up the MauiDevFlow agent and CLI in a MAUI project (including Linux/GTK apps), (7) Completing a build-deploy-inspect-fix feedback loop for MAUI app development, (8) Handling iOS permission dialogs, system alerts, and app-level alerts via simctl privacy or accessibility tree detection, (9) Managing multiple simultaneous MAUI apps via the broker daemon. Covers: maui-devflow CLI, androidsdk.tool (android), appledev.tools (apple), adb, xcrun simctl, xdotool (Linux), and dotnet build/run for all MAUI target platforms including Linux/GTK.
|
MAUI AI Debugging
Build, deploy, inspect, and debug .NET MAUI apps from the terminal. This skill enables a complete
feedback loop: build → deploy → inspect → fix → rebuild.
Prerequisites
dotnet tool install --global Redth.MauiDevFlow.CLI || dotnet tool update --global Redth.MauiDevFlow.CLI
dotnet tool install --global androidsdk.tool
dotnet tool install --global appledev.tools
Keep the skill up to date: maui-devflow update-skill. For full update and version checking
procedures, see references/setup.md.
Integrating MauiDevFlow into a MAUI App
For complete setup instructions, see references/setup.md.
Quick summary:
- Add NuGet packages (
Redth.MauiDevFlow.Agent, and Redth.MauiDevFlow.Blazor for Blazor Hybrid)
- For Linux/GTK apps (detected via
grep -i 'GirCore\|Maui\.Gtk' *.csproj), use Agent.Gtk and Blazor.Gtk instead
- Register in
MauiProgram.cs inside #if DEBUG
- For Blazor Hybrid: chobitsu.js is auto-injected (no manual script tag needed)
- For Mac Catalyst: ensure
network.server entitlement
- For Android: run
adb reverse for broker + agent ports
- For Linux: no special network setup needed (direct localhost)
Core Workflow
1. Ensure a Device/Simulator/Emulator is Running
iOS Simulator:
xcrun simctl list devices booted
xcrun simctl boot <UDID>
Android Emulator:
android avd list
android avd start --name <avd-name>
Mac Catalyst / Linux/GTK: No device setup needed — runs as desktop app.
2. Detect the TFM
IMPORTANT: Before building, detect the correct Target Framework Moniker from the project.
Do NOT assume net10.0 — many projects use net9.0, net8.0, etc.
grep -i 'TargetFrameworks' *.csproj Directory.Build.props 2>/dev/null
Use the detected version (e.g. net9.0) in all build commands. The examples use $TFM.
3. Build and Deploy
CRITICAL: dotnet build -t:Run blocks until the app exits. You MUST launch it
asynchronously and then poll for the app to be ready. Do NOT wait for the process to finish —
it never will (until the app is closed).
Correct launch pattern:
- Start
dotnet build -t:Run in an async/background shell (e.g., mode: "async")
- Read output from the async shell periodically to watch for build completion / app launch
- Poll
maui-devflow MAUI status (or maui-devflow list) until the agent connects
- If the agent doesn't appear after ~60-90 seconds, check the async shell output for build errors
dotnet build -f $TFM-ios -t:Run -p:_DeviceName=:v2:udid=<UDID>
dotnet build -f $TFM-android -t:Run
dotnet build -f $TFM-maccatalyst -t:Run
dotnet run --project <path-to-gtk-project>
Build + Run can take 30-120+ seconds. Use initial_wait: 120 or higher for async monitoring.
Device/simulator compatibility: The TFM compile target does NOT mean you need a matching
emulator/simulator version. Apps run on any device at or above SupportedOSPlatformVersion.
Use whatever emulator/simulator is available.
For Android emulators, set up port forwarding after deploy:
adb reverse tcp:19223 tcp:19223
adb forward tcp:<port> tcp:<port>
4. Verify Connectivity
After launching the app asynchronously, poll for the agent to connect:
maui-devflow list
maui-devflow MAUI status
maui-devflow cdp status
Poll maui-devflow MAUI status every few seconds until it succeeds. If it hasn't connected
after ~60-90 seconds, read the async shell output to check for build/launch errors.
The list command shows all agents registered with the broker, including their platform,
TFM, and assigned port. Use this to find the port for --agent-port when multiple apps run.
5. Inspect and Interact
Typical inspection flow:
maui-devflow MAUI tree — see the full visual tree with element IDs, types, text, bounds
maui-devflow MAUI query --automationId "MyButton" — find specific elements
maui-devflow MAUI element <id> — get full details (type, bounds, visibility, children)
maui-devflow MAUI property <id> Text — read any property by name
maui-devflow MAUI screenshot --output screen.png — visual verification
Property inspection is more reliable than screenshots for verifying exact runtime values:
maui-devflow MAUI property <id> BackgroundColor
maui-devflow MAUI property <id> IsVisible
Live editing (no rebuild needed):
maui-devflow MAUI set-property <id> TextColor "Tomato"
maui-devflow MAUI set-property <id> FontSize "24"
Supports: string, bool, int, double, Color (named/hex), Thickness, enums. Changes persist
until the app restarts — safe for experimentation.
Typical interaction flow:
maui-devflow MAUI fill <entryId> "text" — type into Entry/Editor fields
maui-devflow MAUI tap <buttonId> — tap buttons, checkboxes, list items
maui-devflow MAUI clear <entryId> — clear text fields
- Take screenshot to verify result
Blazor WebView (if applicable):
maui-devflow cdp snapshot — DOM tree as accessible text (best for AI)
maui-devflow cdp Input fill "css-selector" "text" — fill inputs
maui-devflow cdp Input dispatchClickEvent "css-selector" — click elements
maui-devflow cdp Runtime evaluate "js-expression" — run JS
Live CSS/DOM editing in Blazor (no rebuild needed):
maui-devflow cdp Runtime evaluate "document.querySelector('h1').style.color = 'tomato'"
maui-devflow cdp Runtime evaluate "document.documentElement.style.setProperty('--bg-color', '#1a1a2e')"
6. Reading Application Logs
MauiDevFlow automatically captures all ILogger output and WebView console.* calls
to rotating log files, retrievable remotely:
maui-devflow MAUI logs
maui-devflow MAUI logs --limit 50
maui-devflow MAUI logs --source webview
maui-devflow MAUI logs --source native
Debugging workflow: Reproduce the issue → maui-devflow MAUI logs --limit 20 → check for
errors. Add temporary ILogger calls for more detail, rebuild, reproduce, and fetch logs again.
7. Rebuild
After editing source code, rebuild: dotnet build -f $TFM-<platform> -t:Run ... (in async shell)
→ poll maui-devflow MAUI status until connected → inspect. If the build fails, see
references/troubleshooting.md.
Command Reference
maui-devflow MAUI (Native Agent)
Global options: --agent-host (default localhost), --agent-port (auto-discovered via broker), --platform.
These options work on any subcommand position: maui-devflow MAUI status --agent-port 10224
or maui-devflow --agent-port 10224 MAUI status — both are valid.
| Command | Description |
|---|
MAUI status | Agent connection status, platform, app name |
MAUI tree [--depth N] | Visual tree (IDs, types, text, bounds). Depth 0=unlimited |
MAUI query --type T --automationId A --text T | Find elements (any/all filters) |
MAUI tap <elementId> | Tap an element |
MAUI fill <elementId> <text> | Fill text into Entry/Editor |
MAUI clear <elementId> | Clear text from element |
MAUI screenshot [--output path.png] | PNG screenshot |
MAUI property <elementId> <prop> | Read property (Text, IsVisible, FontSize, etc.) |
MAUI set-property <elementId> <prop> <value> | Set property (live editing — colors, text, sizes, etc.) |
MAUI element <elementId> | Full element JSON (type, bounds, children, etc.) |
MAUI navigate <route> | Shell navigation (e.g. //native, //blazor) |
MAUI logs [--limit N] [--skip N] [--source S] | Fetch application logs (newest first). Source: native, webview, or omit for all |
Element IDs come from MAUI tree or MAUI query. AutomationId-based elements use their
AutomationId directly. Others use generated hex IDs. When multiple elements share the same
AutomationId, suffixes are appended: TodoCheckBox, TodoCheckBox_1, TodoCheckBox_2, etc.
maui-devflow cdp (Blazor WebView CDP)
Global options: --agent-host (default localhost), --agent-port (auto-discovered via broker).
CDP commands use the same agent port — all communication goes through a single port.
| Command | Description |
|---|
cdp status | CDP connection status |
cdp snapshot | Accessible DOM text (best for AI agents) |
cdp Browser getVersion | Browser/WebView version info |
cdp Runtime evaluate <expr> | Evaluate JavaScript |
cdp DOM getDocument | Full DOM document |
cdp DOM querySelector <sel> | Find first matching element |
cdp DOM querySelectorAll <sel> | Find all matching elements |
cdp DOM getOuterHTML <sel> | Get outer HTML of element |
cdp Page navigate <url> | Navigate to URL |
cdp Page reload | Reload page |
cdp Page captureScreenshot | Screenshot as base64 |
cdp Input dispatchClickEvent <sel> | Click element by CSS selector |
cdp Input insertText <text> | Insert text at focused element |
cdp Input fill <selector> <text> | Focus + fill text into element |
maui-devflow Broker & Discovery
The broker is a background daemon that manages port assignments for all running agents.
The CLI auto-starts the broker on first use — no manual setup needed.
| Command | Description |
|---|
list | Show all registered agents (ID, app, platform, TFM, port, uptime) |
broker status | Broker daemon status and connected agent count |
broker start | Start broker daemon (auto-started by CLI — rarely needed manually) |
broker stop | Stop broker daemon |
broker log | Show broker log file |
How port discovery works: When you run any MAUI or cdp command, the CLI:
- Auto-starts the broker if not running
- Queries the broker for agents matching the current project (
.csproj in cwd)
- If one agent matches → uses its port automatically
- If multiple match → prints a disambiguation table to stderr
- Falls back to
.mauidevflow config file → default 9223
Multiple apps simultaneously: The broker assigns unique ports from range 10223–10899.
Use maui-devflow list to see all agents, then target a specific one:
maui-devflow MAUI status --agent-port 10224
Platform Details
For detailed platform-specific setup, simulator/emulator management, and troubleshooting:
Multi-Project / Custom Ports
With the broker (recommended): The broker automatically assigns ports to agents from
range 10223–10899. No manual port configuration needed — just build and run your apps.
Use maui-devflow list to see assigned ports. The CLI auto-discovers the right agent
when run from the project directory.
Legacy .mauidevflow config (fallback): If the broker isn't available:
{ "port": 9225 }
Port priority: Explicit --agent-port > Broker discovery > .mauidevflow config > Default 9223.
Tips
- Always use
maui-devflow MAUI screenshot or maui-devflow cdp Page captureScreenshot for
screenshots. These capture the app's UI in-process from the rendering layer — the app does NOT
need to be in the foreground or focused. Never use osascript to bring windows to the front
for screenshots; it's unnecessary and unreliable.
- Avoid
osascript unless absolutely necessary. The maui-devflow CLI provides commands for
nearly everything: screenshots, tapping, text input, navigation, and property inspection. Only
use osascript for OS-level operations that maui-devflow cannot do (e.g., toggling dark mode,
dismissing macOS crash-recovery dialogs).
- Use
AutomationId on important MAUI controls for stable element references.
- The visual tree only reflects what's currently rendered. Off-screen items in CollectionView
may not appear until scrolled into view.
- For Blazor Hybrid,
cdp snapshot is the most AI-friendly way to read page state.
- Build times: Mac Catalyst ~5-10s, iOS ~30-60s, Android ~30-90s, Linux/GTK ~5-10s.
- After Android deploy, always run
adb reverse tcp:19223 for broker + adb forward for agent.
- Both MAUI native and CDP commands share a single port — no separate WebSocket endpoint.