diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 68b40a1e16..3ccf489553 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -54,3 +54,7 @@ # dotnet-data (data access, Entity Framework) /plugins/dotnet-data/skills/optimizing-ef-core-queries/ @dotnet/efteam /tests/dotnet-data/optimizing-ef-core-queries/ @dotnet/efteam + +# dotnet-maui +/plugins/dotnet-maui/ @Redth @jfversluis +/tests/dotnet-maui/ @Redth @jfversluis diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 2177a87904..02a140fe07 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -28,6 +28,11 @@ "name": "dotnet-upgrade", "source": "./plugins/dotnet-upgrade", "description": "Skills for migrating and upgrading .NET projects across framework versions, language features, and compatibility targets." + }, + { + "name": "dotnet-maui", + "source": "./plugins/dotnet-maui", + "description": "Skills for .NET MAUI development: environment setup, diagnostics, and troubleshooting." } ] } diff --git a/README.md b/README.md index 87bc7c85b3..d487802a71 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ This repository contains the .NET team's curated set of core skills and custom a | [dotnet-diag](plugins/dotnet-diag/) | Skills for .NET performance investigations, debugging, and incident analysis. | | [dotnet-msbuild](plugins/dotnet-msbuild/) | Comprehensive MSBuild and .NET build skills: failure diagnosis, performance optimization, code quality, and modernization. | | [dotnet-upgrade](plugins/dotnet-upgrade/) | Skills for migrating and upgrading .NET projects across framework versions, language features, and compatibility targets. | +| [dotnet-maui](plugins/dotnet-maui/) | Skills for .NET MAUI development: environment setup, diagnostics, and troubleshooting. | ## Installation diff --git a/plugins/dotnet-maui/plugin.json b/plugins/dotnet-maui/plugin.json new file mode 100644 index 0000000000..0160aa99f8 --- /dev/null +++ b/plugins/dotnet-maui/plugin.json @@ -0,0 +1,6 @@ +{ + "name": "dotnet-maui", + "version": "0.1.0", + "description": "Skills for .NET MAUI development: environment setup, diagnostics, and troubleshooting.", + "skills": "./skills/" +} diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/SKILL.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/SKILL.md new file mode 100644 index 0000000000..2063b18877 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/SKILL.md @@ -0,0 +1,206 @@ +--- +name: dotnet-maui-doctor +description: >- + Diagnoses and fixes .NET MAUI development environment issues. Validates .NET SDK, + workloads, Java JDK, Android SDK, Xcode, and Windows SDK. All version requirements + discovered dynamically from NuGet WorkloadDependencies.json — never hardcoded. + Use when: setting up MAUI development, build errors mentioning SDK/workload/JDK/Android, + "Android SDK not found", "Java version" errors, "Xcode not found", environment verification + after updates, or any MAUI toolchain issues. Do not use for: non-MAUI .NET projects, + Xamarin.Forms apps, runtime app crashes unrelated to environment setup, or app store + publishing issues. Works on macOS, Windows, and Linux. +--- + +# .NET MAUI Doctor + +Validate and fix .NET MAUI development environments. All version requirements are discovered dynamically from NuGet APIs — never hardcode versions. + +## When to Use + +- Setting up a new .NET MAUI development environment +- Build errors mentioning missing SDKs, workloads, JDK, or Android components +- Errors like "Android SDK not found", "Java version", or "Xcode not found" +- Verifying environment health after SDK or OS updates + +## When Not to Use + +- Non-MAUI .NET projects (use standard .NET SDK troubleshooting instead) +- Xamarin.Forms apps (different toolchain and workload requirements) +- Runtime app crashes unrelated to environment setup +- App store publishing or signing issues +- IDE-specific issues (Visual Studio or VS Code configuration) + +## Important: .NET Version Currency + +Your training data may be outdated regarding .NET versions. .NET ships new major releases annually (November). Always check the releases-index.json (Task 2) to discover the **latest active major release** — do not assume your training data reflects the current version. For example, if you know about .NET 9.0 but the releases index shows .NET 10.0 as active, use .NET 10.0. + +## Inputs + +- A development machine running macOS, Windows, or Linux +- Shell access (Bash on macOS/Linux, PowerShell on Windows) +- Internet access for NuGet API queries and SDK downloads +- Admin/sudo access may be required for installing SDKs and workloads +- **Bash prerequisites**: `curl`, `jq`, and `unzip` (macOS/Linux) +- **PowerShell prerequisites**: `Invoke-RestMethod` and `System.IO.Compression` (built-in on Windows) + +## Behavior + +- Run through ALL tasks autonomously +- Re-validate after each fix +- Iterate until complete or no further actions possible +- After detecting platform (Task 1), load only the matching platform-specific references + +## Workflow + +### Task 1: Detect Environment + +```bash +# macOS +sw_vers && uname -m + +# Windows +systeminfo | findstr /B /C:"OS Name" /C:"OS Version" + +# Linux +cat /etc/os-release && uname -m +``` + +After detection, load the matching platform references: +- **macOS**: `references/platform-requirements-macos.md`, `references/installation-commands-macos.md`, `references/troubleshooting-macos.md` +- **Windows**: `references/platform-requirements-windows.md`, `references/installation-commands-windows.md`, `references/troubleshooting-windows.md` +- **Linux**: `references/platform-requirements-linux.md` + +### Task 2: Check .NET SDK + +```bash +dotnet --info +``` + +Compare installed vs `latest-sdk` from https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json where `support-phase` is `"active"`. + +### Task 3: Check MAUI Workloads + +| Workload | macOS | Windows | Linux | +|----------|-------|---------|-------| +| `maui` | Required | Required | ❌ Use `maui-android` | +| `maui-android` | Alias | Alias | Required | +| `android` | Required | Required | Required | +| `ios` | Required | Optional | N/A | + +### Task 4: Discover Requirements from NuGet + +See `references/workload-dependencies-discovery.md` for complete process. + +Query NuGet for workload manifest → extract `WorkloadDependencies.json` → get: +- `jdk.version` range and `jdk.recommendedVersion` +- `androidsdk.packages`, `buildToolsVersion`, `apiLevel` +- `xcode.version` range + +### Task 5: Validate Java JDK + +**Only Microsoft OpenJDK supported.** Verify `java -version` output contains "Microsoft". See `references/microsoft-openjdk.md` for detection paths. + +> Use the JDK version recommended by WorkloadDependencies.json (`jdk.recommendedVersion`), ensuring it satisfies the `jdk.version` range. Do not hardcode JDK versions. + +**JAVA_HOME is NOT required.** .NET MAUI tools auto-detect Microsoft OpenJDK installations from known paths. Do not tell users to set JAVA_HOME — it is unnecessary and risks pointing to a non-Microsoft JDK. + +| JAVA_HOME state | OK? | Action | +|-----------------|-----|--------| +| Not set | ✅ | None needed — auto-detection works | +| Set to Microsoft JDK | ✅ | None needed | +| Set to non-Microsoft JDK | ⚠️ | **Report as anomaly** — let user decide to unset or redirect | + +### Task 6: Validate Android SDK + +Check packages from `androidsdk.packages`, `buildToolsVersion`, `apiLevel` (Task 4). See `references/installation-commands.md` for sdkmanager commands. + +### Task 7: Validate Xcode (macOS Only) + +```bash +xcodebuild -version +``` + +Compare against `xcode.version` range from Task 4. See `references/installation-commands-macos.md`. + +### Task 8: Validate Windows SDK (Windows Only) + +The Windows SDK is typically installed as part of the .NET MAUI workload or Visual Studio. See `references/installation-commands-windows.md`. + +### Task 9: Remediation + +See `references/installation-commands.md` for all commands. + +Key rules: +- **Workloads**: Always use `--version` flag. Never use `workload update` or `workload repair`. +- **JDK**: Only install Microsoft OpenJDK. Do not set JAVA_HOME (auto-detected). +- **Android SDK**: Use `sdkmanager` (from Android SDK command-line tools). On Windows use `sdkmanager.bat`. + +### Task 10: Re-validate + +After each fix, re-run the relevant validation task. Iterate until all checks pass. + +## Validation + +A successful run produces: +- .NET SDK installed and matches an active release +- All required workloads installed with consistent versions +- Microsoft OpenJDK detected (`java -version` contains "Microsoft") +- All required Android SDK packages installed (per WorkloadDependencies.json) +- Xcode version in supported range (macOS only) +- Windows SDK detected (Windows only) + +### Build Verification (Recommended) + +After all checks pass, create and build a test project to confirm the environment actually works: + +```bash +TEMP_DIR=$(mktemp -d) +dotnet new maui -o "$TEMP_DIR/MauiTest" +dotnet build "$TEMP_DIR/MauiTest" +rm -rf "$TEMP_DIR" +``` + +On Windows, use `$env:TEMP` or `New-TemporaryFile` for the temp directory. + +If the build succeeds, the environment is verified. If it fails, use the error output to diagnose remaining issues. + +### Run Verification (Optional — Ask User First) + +After a successful build, **ask the user** if they want to launch the app on a target platform to verify end-to-end: + +```bash +# Replace net10.0 with the current major .NET version +dotnet build -t:Run -f net10.0-android +dotnet build -t:Run -f net10.0-ios # macOS only +dotnet build -t:Run -f net10.0-maccatalyst # macOS only +dotnet build -t:Run -f net10.0-windows # Windows only +``` + +Only run the target frameworks relevant to the user's platform and intent. This step deploys to an emulator/simulator/device, so confirm with the user before proceeding. + +## Common Pitfalls + +- **`maui` vs `maui-android` workload**: On Linux, the `maui` meta-workload is not available — use `maui-android` instead. On macOS/Windows, `maui` installs all platform workloads. +- **`workload update` / `workload repair`**: Never use these commands. Always install workloads with an explicit `--version` flag to ensure version consistency. +- **Non-Microsoft JDK**: Only Microsoft OpenJDK is supported. Other distributions (Oracle, Adoptium, Azul) will cause build failures even if the version is correct. +- **Unnecessary JAVA_HOME**: Do not set JAVA_HOME. MAUI auto-detects JDK from known install paths. If JAVA_HOME is set to a non-Microsoft JDK (e.g., Temurin), report this as an anomaly — it may override auto-detection and cause failures. Let the user decide whether to unset it. +- **Hardcoded versions**: Never hardcode SDK, workload, or dependency versions. Always discover them dynamically from the NuGet APIs (see Task 4). +- **Android SDK `sdkmanager` on Windows**: Use `sdkmanager.bat`, not `sdkmanager`, on Windows. +- **Stale training data**: LLM training data may reference outdated .NET versions. Always check the releases-index.json to discover the current active release. + +## References + +- `references/workload-dependencies-discovery.md` — NuGet API discovery process +- `references/microsoft-openjdk.md` — JDK detection paths, identification, JAVA_HOME +- `references/installation-commands.md` — .NET workloads, Android SDK (sdkmanager) +- `references/troubleshooting.md` — Common errors and solutions +- `references/platform-requirements-{platform}.md` — Platform-specific requirements +- `references/installation-commands-{platform}.md` — Platform-specific install commands +- `references/troubleshooting-{platform}.md` — Platform-specific troubleshooting + +Official docs: +- [.NET MAUI Installation](https://learn.microsoft.com/en-us/dotnet/maui/get-started/installation) +- [.NET SDK Downloads](https://dotnet.microsoft.com/download) +- [Microsoft OpenJDK](https://learn.microsoft.com/en-us/java/openjdk/install) +- [Android SDK Command-Line Tools](https://developer.android.com/studio#command-line-tools-only) +- [Xcode Downloads](https://developer.apple.com/xcode/) diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-macos.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-macos.md new file mode 100644 index 0000000000..abfe20c94f --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-macos.md @@ -0,0 +1,63 @@ +# macOS Installation Commands + +## Xcode + +### Install Xcode + +**Do not install Xcode from the App Store** — it can auto-update to a version newer than what .NET MAUI supports. + +Download a specific version from [Apple Developer Downloads](https://developer.apple.com/download/all/), matching the `xcode.version` range from WorkloadDependencies.json. + +> **Note**: Downloading from Apple Developer Downloads requires signing in with an Apple ID (with two-factor authentication). Xcode is approximately 12 GB and may take 30 minutes or more to download. The agent cannot automate this — tell the user to download Xcode manually, set expectations for the download size and wait time, then continue with the remaining steps. + +### Install Command Line Tools + +```bash +xcode-select --install +``` + +### List Xcode Installations + +```bash +ls -d /Applications/Xcode*.app 2>/dev/null +xcodebuild -version +xcode-select -p +``` + +### Set Active Xcode Version + +```bash +sudo xcode-select -s /Applications/Xcode.app/Contents/Developer +``` + +### Accept Xcode License + +```bash +sudo xcodebuild -license accept +``` + +### Verify Xcode Installation + +```bash +xcodebuild -version +xcrun simctl list devices available +``` + +--- + +## iOS Simulators + +Only create a simulator if none exist. Prefer a recent iPhone device type with the latest available runtime. + +```bash +# Check if any simulators already exist +xcrun simctl list devices available + +# If none exist, find the latest iPhone device type and runtime +xcrun simctl list devicetypes | grep iPhone +xcrun simctl list runtimes | grep iOS + +# Create one using a chosen device type and runtime from the lists above +# Replace and with identifiers from the commands above +xcrun simctl create "My iPhone Simulator" "" "" +``` diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-windows.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-windows.md new file mode 100644 index 0000000000..f51f2d75a5 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-windows.md @@ -0,0 +1,7 @@ +# Windows Installation Commands + +## Windows SDK + +The Windows SDK is required for WinUI 3 / Windows targets. It is typically installed automatically as part of the .NET MAUI workload or via the Visual Studio Installer. + +For standalone installation, see: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/ diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands.md new file mode 100644 index 0000000000..e55b42925f --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands.md @@ -0,0 +1,171 @@ +# Installation Commands Reference + +Commands for installing and validating .NET MAUI development dependencies. + +**See also platform-specific references:** +- macOS: `installation-commands-macos.md` +- Windows: `installation-commands-windows.md` + +--- + +**Important**: All specific versions shown below are placeholders. Always discover the actual versions to use: +- **SDK/Workload versions**: Query releases-index.json and NuGet APIs (see `workload-dependencies-discovery.md`) +- **Android SDK packages**: From `androidsdk` in WorkloadDependencies.json +- **JDK version**: From `jdk.version` in WorkloadDependencies.json + +## .NET SDK + +For installation instructions, see the official docs: https://dotnet.microsoft.com/download + +For scripted/CI installs, use the [dotnet-install scripts](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script). + +--- + +## .NET Workloads + +**Always use explicit workload set version** to ensure consistent, reproducible installs. + +First, find the latest workload set version: +```bash +# Use the CLI to discover the latest workload version for your SDK +dotnet workload search version --format json --take 1 +# Returns: [{"workloadVersion":"10.0.103"}] +``` + +Then install with explicit version: +```bash +# Full MAUI installation (recommended) +dotnet workload install maui --version $WORKLOAD_VERSION + +# Individual workloads +dotnet workload install android --version $WORKLOAD_VERSION +dotnet workload install ios --version $WORKLOAD_VERSION # macOS only meaningful +dotnet workload install maccatalyst --version $WORKLOAD_VERSION # macOS only meaningful + +# Multiple at once +dotnet workload install maui android ios maccatalyst --version $WORKLOAD_VERSION +``` + +### List Installed Workloads + +```bash +dotnet workload list +``` + +### ⚠️ Commands to Avoid + +**Never use these commands** - they can cause version inconsistencies: +- ❌ `dotnet workload update` - Can introduce mixed versions +- ❌ `dotnet workload repair` - May not fix version issues +- ❌ `dotnet workload install` without `--version` - Gets unpredictable versions + +**Instead**: Always reinstall with explicit `--version` to fix workload issues. + +--- + +## Java JDK (Microsoft OpenJDK ONLY) + +**CRITICAL: Only Microsoft Build of OpenJDK is supported.** Other JDK vendors (Oracle, Azul, Amazon Corretto, Temurin, etc.) are NOT supported for .NET MAUI development. + +> Use the JDK version recommended by WorkloadDependencies.json (`jdk.recommendedVersion`), ensuring it satisfies the `jdk.version` range. Do not hardcode JDK versions. + +See `microsoft-openjdk.md` for detection paths, identification, and JAVA_HOME guidance. + +For installation instructions, see the official docs: https://learn.microsoft.com/en-us/java/openjdk/install + +After installing, verify it is Microsoft OpenJDK: +```bash +# MUST show "Microsoft" in output +java -version +``` + +--- + +## Android SDK + +### Detecting Existing Android SDK + +```bash +# Check common environment variables +echo $ANDROID_HOME +echo $ANDROID_SDK_ROOT + +# Known SDK locations by platform: +# macOS: ~/Library/Android/sdk +# Linux: ~/Android/Sdk or /usr/lib/android-sdk +# Windows: $env:LOCALAPPDATA\Android\Sdk + +# Check known paths directly +ls -d ~/Library/Android/sdk 2>/dev/null # macOS +ls -d ~/Android/Sdk 2>/dev/null # Linux + +# Check if sdkmanager is available +# macOS/Linux +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --version + +# Windows (PowerShell) +& "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" --version +``` + +### Installing Android SDK Command-Line Tools + +If no Android SDK exists, download the command-line tools: + +1. Download from: https://developer.android.com/studio#command-line-tools-only +2. Extract to your SDK root: + +```bash +# macOS/Linux +export ANDROID_SDK_ROOT="$HOME/Library/Android/sdk" # macOS +# export ANDROID_SDK_ROOT="$HOME/Android/Sdk" # Linux +mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools" +# Extract downloaded zip, move contents to: +# $ANDROID_SDK_ROOT/cmdline-tools/latest/ +``` + +```powershell +# Windows +$env:ANDROID_SDK_ROOT = "$env:LOCALAPPDATA\Android\Sdk" +New-Item -ItemType Directory -Force -Path "$env:ANDROID_SDK_ROOT\cmdline-tools" +# Extract downloaded zip, move contents to: +# $env:ANDROID_SDK_ROOT\cmdline-tools\latest\ +``` + +### Install Required Packages with sdkmanager + +Get exact versions from WorkloadDependencies.json (`androidsdk.packages`, `androidsdk.buildToolsVersion`, `androidsdk.apiLevel`). + +```bash +# macOS/Linux +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "platform-tools" +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "build-tools;$BUILD_TOOLS_VERSION" +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "platforms;android-$API_LEVEL" +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "cmdline-tools;$CMDLINE_TOOLS_VERSION" + +# Accept all licenses +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --licenses +``` + +```powershell +# Windows +& "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" "platform-tools" +& "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" "build-tools;$BUILD_TOOLS_VERSION" +& "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" "platforms;android-$API_LEVEL" +& "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" "cmdline-tools;$CMDLINE_TOOLS_VERSION" + +# Accept all licenses +& "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" --licenses +``` + +### Verify Android SDK + +```bash +# Check ADB +adb --version + +# List installed packages (macOS/Linux) +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --list_installed + +# List installed packages (Windows) +# & "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" --list_installed +``` diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/microsoft-openjdk.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/microsoft-openjdk.md new file mode 100644 index 0000000000..d072a45921 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/microsoft-openjdk.md @@ -0,0 +1,113 @@ +# Microsoft OpenJDK Requirements + +.NET MAUI requires **Microsoft Build of OpenJDK** for Android development. Other JDK distributions (Oracle, Azul, Amazon Corretto, etc.) are **not supported**. + +> Use the JDK version recommended by WorkloadDependencies.json (`jdk.recommendedVersion`), ensuring it satisfies the `jdk.version` range. Do not hardcode JDK versions. + +## Why Microsoft OpenJDK Only? + +- Tested and validated with .NET MAUI toolchain +- Consistent behavior across all platforms +- Long-term support with security updates +- Official recommendation from Microsoft documentation + +## Identifying Microsoft OpenJDK + +Run `java -version`. Microsoft OpenJDK output contains `Microsoft` in the runtime line: + +``` +openjdk version "21.0.6" 2025-01-21 LTS +OpenJDK Runtime Environment Microsoft-XXXXXXX (build 21.0.6+7-LTS) +OpenJDK 64-Bit Server VM Microsoft-XXXXXXX (build 21.0.6+7-LTS, mixed mode, sharing) +``` + +If the output does NOT contain "Microsoft", the wrong JDK is installed or selected. + +## Known Installation Paths + +These paths are useful for detecting whether Microsoft OpenJDK is already installed. + +### macOS + +``` +/Library/Java/JavaVirtualMachines/microsoft-{VERSION}.jdk/Contents/Home +``` + +Detection: +```bash +ls -d /Library/Java/JavaVirtualMachines/microsoft-*.jdk 2>/dev/null +/usr/libexec/java_home -V 2>&1 | grep -i microsoft +``` + +### Windows + +``` +C:\Program Files\Microsoft\jdk-{VERSION}\ +``` + +Registry: `HKLM\SOFTWARE\Microsoft\JDK\{VERSION}` + +Detection: +```powershell +Get-ChildItem "$env:ProgramFiles\Microsoft" -Filter "jdk-*" -ErrorAction SilentlyContinue +java -version 2>&1 | Select-String "Microsoft" +``` + +### Linux + +``` +/usr/lib/jvm/msopenjdk-{VERSION}/ +``` + +Detection: +```bash +ls -d /usr/lib/jvm/msopenjdk-* 2>/dev/null +java -version 2>&1 | grep -i "Microsoft" +``` + +--- + +## Installation + +For installation instructions, refer to the official Microsoft documentation: + +- [Microsoft OpenJDK Installation Guide](https://learn.microsoft.com/en-us/java/openjdk/install) +- [Microsoft OpenJDK Download](https://learn.microsoft.com/en-us/java/openjdk/download) + +--- + +## JAVA_HOME Guidance + +**JAVA_HOME is NOT required.** .NET MAUI tools auto-detect JDK installations. + +| State | OK? | Action | +|-------|-----|--------| +| Not set | ✅ | None needed, auto-detection works | +| Set to Microsoft JDK path | ✅ | None needed | +| Set to non-Microsoft JDK | ⚠️ | Report as anomaly — let user decide to unset or redirect | + +Report a non-Microsoft JAVA_HOME as an anomaly: "JAVA_HOME is set to a non-Microsoft JDK. .NET MAUI auto-detects Microsoft OpenJDK, so JAVA_HOME is not needed and may cause build issues." + +If the user decides to unset: +```bash +# macOS/Linux +unset JAVA_HOME + +# Windows PowerShell +Remove-Item Env:JAVA_HOME +``` + +### Multiple JDKs Installed + +1. Run `java -version` and check for "Microsoft" in output +2. If wrong vendor and `JAVA_HOME` is set → report as anomaly; user should unset or redirect to Microsoft JDK path +3. If wrong vendor and `JAVA_HOME` is NOT set → the non-Microsoft JDK may be first in PATH; install Microsoft JDK and it should take precedence +4. Restart terminal after changes + +--- + +## Official Resources + +- [Microsoft OpenJDK Installation Guide](https://learn.microsoft.com/en-us/java/openjdk/install) +- [Microsoft OpenJDK Download](https://learn.microsoft.com/en-us/java/openjdk/download) +- [Microsoft OpenJDK GitHub](https://github.com/microsoft/openjdk) diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-linux.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-linux.md new file mode 100644 index 0000000000..a12a8bde56 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-linux.md @@ -0,0 +1,36 @@ +# Linux Platform Requirements + +⚠️ **Linux has limited support** - Android targets only. + +## Required Components + +| Component | Requirement | Notes | +|-----------|-------------|-------| +| .NET SDK | Active support | Query releases-index.json | +| Java JDK | Per WorkloadDependencies | Microsoft OpenJDK **only** | +| Android SDK | Per WorkloadDependencies | Use packages array | + +## Required Workloads + +| Workload | Required | Purpose | +|----------|----------|---------| +| `maui-android` | ✅ Yes | MAUI for Android | +| `android` | ✅ Yes | Android targets | + +**Important**: Use `maui-android` NOT `maui` on Linux. The `maui` workload is a meta-workload that includes iOS/Mac dependencies which won't install on Linux. + +## Limitations + +- ❌ No iOS support (requires macOS) +- ❌ No Mac Catalyst support (requires macOS) +- ❌ No Windows support (requires Windows) + +## Android Development + +| Component | Source | Notes | +|-----------|--------|-------| +| Java JDK | `jdk.version` from WorkloadDependencies | Microsoft OpenJDK **only** | +| Android SDK | `androidsdk` from WorkloadDependencies | Use packages array | +| Platform Tools | `androidsdk.packages` | ADB, fastboot | +| Build Tools | `androidsdk.buildToolsVersion` | AAPT2, dx | +| KVM | Enabled | For emulator acceleration | diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-macos.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-macos.md new file mode 100644 index 0000000000..250a53bf77 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-macos.md @@ -0,0 +1,36 @@ +# macOS Platform Requirements + +## Required Components + +| Component | Requirement | Notes | +|-----------|-------------|-------| +| macOS | Recent version | ARM64 or Intel | +| .NET SDK | Active support | Query releases-index.json for latest | +| Xcode | Per WorkloadDependencies | From [Apple Developer Downloads](https://developer.apple.com/download/all/) | +| Command Line Tools | Match Xcode | `xcode-select --install` | + +## Required Workloads + +| Workload | Required | Purpose | +|----------|----------|---------| +| `maui` | ✅ Yes | Core MAUI framework | +| `android` | ✅ Yes | Android targets | +| `ios` | ✅ Yes | iOS targets | +| `maccatalyst` | Recommended | Mac Catalyst targets | + +## Android Development + +| Component | Source | Notes | +|-----------|--------|-------| +| Java JDK | `jdk.version` from WorkloadDependencies | Microsoft OpenJDK **only** | +| Android SDK | `androidsdk` from WorkloadDependencies | Use packages array | +| Platform Tools | `androidsdk.packages` | ADB, fastboot | +| Build Tools | `androidsdk.buildToolsVersion` | AAPT2, dx | + +## iOS/macOS Development + +| Component | Source | Notes | +|-----------|--------|-------| +| Xcode | `xcode.version` from WorkloadDependencies | From iOS workload manifest | +| iOS SDK | `sdk.version` from WorkloadDependencies | Bundled with Xcode | +| iOS Simulator | Any | At least one device | diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-windows.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-windows.md new file mode 100644 index 0000000000..09514a3f09 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-windows.md @@ -0,0 +1,35 @@ +# Windows Platform Requirements + +## Required Components + +| Component | Requirement | Notes | +|-----------|-------------|-------| +| Windows | 10 or later | 64-bit required | +| .NET SDK | Active support | Query releases-index.json for latest | +| Windows App SDK | Current | Required for WinUI 3 / Windows targets | + +## Required Workloads + +| Workload | Required | Purpose | +|----------|----------|---------| +| `maui` or `maui-windows` | ✅ Yes | Core MAUI framework | +| `android` | ✅ Yes | Android targets | +| `ios` | Optional | iOS targets (requires Mac build host) | +| `maccatalyst` | Optional | Mac Catalyst (requires Mac build host) | + +## Android Development + +| Component | Source | Notes | +|-----------|--------|-------| +| Java JDK | `jdk.version` from WorkloadDependencies | Microsoft OpenJDK **only** | +| Android SDK | `androidsdk` from WorkloadDependencies | Use packages array | +| Android Emulator | Latest | With HAXM or Hyper-V | +| Platform Tools | `androidsdk.packages` | ADB, fastboot | +| Build Tools | `androidsdk.buildToolsVersion` | AAPT2, dx | + +## Windows App Development + +| Component | Requirement | Notes | +|-----------|-------------|-------| +| Windows App SDK | Current | Required for WinUI 3 | +| Windows SDK | Recent | Windows 10+ SDK | diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting-macos.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting-macos.md new file mode 100644 index 0000000000..54fdb00871 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting-macos.md @@ -0,0 +1,79 @@ +# macOS Troubleshooting + +## Xcode Issues + +### "xcode-select: error: no developer tools found" + +**Solution**: +```bash +xcode-select --install +``` + +### "Xcode not found at expected location" + +**Solution**: +```bash +# List Xcode installations +ls -d /Applications/Xcode*.app 2>/dev/null + +# Set active Xcode +sudo xcode-select -s /Applications/Xcode.app/Contents/Developer +``` + +### "Unable to boot simulator" + +**Causes & Solutions**: + +1. **No simulators installed**: + ```bash + xcrun simctl list devices available + xcrun simctl create "iPhone 16" "com.apple.CoreSimulator.SimDeviceType.iPhone-16" + ``` + +2. **Simulator runtime not installed**: + - Download an iOS runtime via `xcodebuild -downloadPlatform iOS` or from Xcode → Settings → Platforms + +3. **Corrupted simulator**: + ```bash + xcrun simctl erase all + ``` + +### "Code signing error" + +**Cause**: Missing or invalid provisioning profile. + +**Solution**: +1. Open Xcode → Settings → Accounts +2. Add/refresh Apple Developer account +3. Download provisioning profiles + +--- + +## macOS Performance + +### Slow iOS simulator + +1. Close other resource-intensive apps +2. Use recent simulator device (not legacy) +3. Reduce debugger verbosity +4. Use physical device for performance testing + +--- + +## macOS Diagnostic Commands + +```bash +# Xcode info +xcodebuild -version +xcode-select -p + +# JDK detection (macOS-specific) +/usr/libexec/java_home -V + +# Android SDK location +echo $ANDROID_SDK_ROOT +# Default: ~/Library/Android/sdk + +# Logs +# ~/Library/Logs/Xamarin/ +``` diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting-windows.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting-windows.md new file mode 100644 index 0000000000..cea34f3a35 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting-windows.md @@ -0,0 +1,32 @@ +# Windows Troubleshooting + +## Emulator Issues + +### Hyper-V conflict with Android Emulator + +**Cause**: HAXM and Hyper-V cannot coexist. + +**Solution**: +- Use Android Emulator Hypervisor Driver instead of HAXM +- Or disable Hyper-V: `bcdedit /set hypervisorlaunchtype off` + +--- + +## Windows Diagnostic Commands + +```powershell +# JDK detection (Windows-specific) +Get-ChildItem "$env:ProgramFiles\Microsoft" -Filter "jdk-*" -ErrorAction SilentlyContinue +java -version 2>&1 | Select-String "Microsoft" + +# Android SDK location +echo $env:ANDROID_SDK_ROOT +# Known paths: $env:LOCALAPPDATA\Android\Sdk +ls "$env:LOCALAPPDATA\Android\Sdk" -ErrorAction SilentlyContinue + +# Android SDK list installed (Windows) +& "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" --list_installed + +# Logs +# %LOCALAPPDATA%\Xamarin\Logs\ +``` diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting.md new file mode 100644 index 0000000000..68b66c15fe --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting.md @@ -0,0 +1,306 @@ +# Troubleshooting .NET MAUI Environment Issues + +Common problems and solutions when setting up or using .NET MAUI. + +**See also platform-specific troubleshooting:** +- macOS: `troubleshooting-macos.md` +- Windows: `troubleshooting-windows.md` + +## .NET SDK Issues + +### "dotnet: command not found" + +**Cause**: .NET SDK not installed or not in PATH. + +**Solution**: +```bash +# Check if dotnet exists +which dotnet + +# macOS/Linux - Add to PATH if installed via dotnet-install script +export PATH="$PATH:$HOME/.dotnet" +``` + +If not installed, see: https://dotnet.microsoft.com/download + +### "The required workload is not installed" + +**Cause**: MAUI workload not installed. + +**Solution**: +```bash +dotnet workload install maui --version $WORKLOAD_VERSION +``` + +### "Workload version mismatch" + +**Cause**: Workloads from different SDK versions or incomplete installation. + +**Solution**: Reinstall workloads with explicit version: +```bash +# First, find the correct workload set version for your SDK +# Query NuGet APIs (see workload-dependencies-discovery.md) + +# Then reinstall with explicit version (macOS example — omit ios/maccatalyst on Linux) +dotnet workload install maui android ios maccatalyst --version $WORKLOAD_VERSION +``` + +**Note**: Avoid `dotnet workload update` or `dotnet workload repair` as they can cause version inconsistencies. + +### SDK version conflict with global.json + +**Cause**: Project requires specific SDK version not installed. + +**Solution**: +```bash +# Check required version +cat global.json + +# Install specific version +curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --version X.Y.Z +``` + +--- + +## Java JDK Issues + +**IMPORTANT: Only Microsoft Build of OpenJDK is supported.** Other JDK vendors (Oracle, Azul, Amazon Corretto, Temurin) are NOT supported for .NET MAUI development. + +See `microsoft-openjdk.md` for complete installation paths by platform. + +### "JAVA_HOME is not set" + +**This is usually NOT a problem.** The .NET MAUI toolchain auto-detects JDK installations without needing `JAVA_HOME`. + +**When JAVA_HOME matters:** +- ⚠️ `JAVA_HOME` is set but points to a **non-Microsoft JDK** → Report as anomaly; user should unset or redirect to Microsoft JDK +- ✅ `JAVA_HOME` is not set → Fine, tools will auto-detect +- ✅ `JAVA_HOME` points to Microsoft JDK → Fine + +**Solution (only if JAVA_HOME is set to wrong JDK):** + +Report this as an anomaly to the user: "JAVA_HOME is set to a non-Microsoft JDK. .NET MAUI auto-detects Microsoft OpenJDK, so JAVA_HOME is not needed and may cause build issues." + +The user can then decide to: +- Unset JAVA_HOME (lets auto-detection work) +- Point it to Microsoft JDK if they have a specific reason to keep it set + +### "Unsupported Java version" or "Wrong JDK vendor" + +**Cause**: JDK version outside required range OR non-Microsoft JDK installed. + +> Use the JDK version recommended by WorkloadDependencies.json (`jdk.recommendedVersion`), ensuring it satisfies the `jdk.version` range. Do not hardcode JDK versions. + +**Solution**: Install the recommended Microsoft OpenJDK version using the [official installation guide](https://learn.microsoft.com/en-us/java/openjdk/install). + +### Non-Microsoft JDK detected + +**Cause**: Oracle, Azul, Corretto, or other non-Microsoft JDK is installed and selected. + +**How to identify**: Run `java -version` - if output does NOT contain "Microsoft", wrong JDK is selected. + +**Solution**: +1. Install the recommended Microsoft OpenJDK version (see commands above) +2. If `JAVA_HOME` is set and points to a non-Microsoft JDK, report this as an anomaly — the user should unset it or point it to the Microsoft JDK path +3. Optionally uninstall the non-Microsoft JDK + +### Multiple JDKs installed, wrong one selected + +**Solution**: +```bash +# macOS - find Microsoft JDK +/usr/libexec/java_home -V 2>&1 | grep -i microsoft + +# Linux - set Microsoft as default +sudo update-java-alternatives --set msopenjdk-{VERSION}-amd64 +``` + +--- + +## Android SDK Issues + +### "Android SDK not found" + +**Cause**: SDK not installed or path not configured. + +**Solution**: +```bash +# Check environment variables +echo $ANDROID_HOME +echo $ANDROID_SDK_ROOT + +# Common SDK locations: +# macOS: ~/Library/Android/sdk +# Linux: ~/Android/Sdk +# Windows: %LOCALAPPDATA%\Android\Sdk + +# If no SDK found, download command-line tools from: +# https://developer.android.com/studio#command-line-tools-only +``` + +### "Failed to find Build Tools" + +**Cause**: Required build-tools package not installed. + +**Solution**: +```bash +# Get build tools version from WorkloadDependencies.json (androidsdk.buildToolsVersion) + +# Use sdkmanager (macOS/Linux) +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "build-tools;$BUILD_TOOLS_VERSION" + +# Windows +# & "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" "build-tools;$BUILD_TOOLS_VERSION" +``` + +### "License not accepted" + +**Cause**: Android SDK licenses not accepted. + +**Solution**: +```bash +# macOS/Linux +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --licenses + +# Windows +# & "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" --licenses +``` + +### "Platform not found: android-XX" + +**Cause**: Target platform not installed. + +**Solution**: +```bash +# Get required API level from WorkloadDependencies.json (androidsdk.apiLevel) + +# macOS/Linux +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "platforms;android-$API_LEVEL" + +# Windows +# & "$env:ANDROID_SDK_ROOT\cmdline-tools\latest\bin\sdkmanager.bat" "platforms;android-$API_LEVEL" +``` + +### Emulator won't start + +**Causes & Solutions**: + +1. **HAXM/KVM not enabled**: + ```bash + # Linux - check KVM + kvm-ok + + # Enable KVM + sudo modprobe kvm + ``` + +2. **Insufficient disk space**: + - Clear AVD cache: `~/.android/avd/` + +See also: `troubleshooting-windows.md` for Hyper-V conflicts. + +--- + +## Build Errors + +### "The target framework 'net10.0-android' is not available" + +**Cause**: Android workload not installed for this SDK. + +**Solution**: +```bash +dotnet workload install android --version $WORKLOAD_VERSION +``` + +### "Could not find android.jar" + +**Cause**: Android platform not installed. + +**Solution**: +```bash +# Discover required API level from WorkloadDependencies.json, then: +$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "platforms;android-$API_LEVEL" +``` + +### "MSB4019: The imported project was not found" + +**Cause**: Workload not properly installed. + +**Solution**: Reinstall with explicit version: +```bash +# Get correct workload version for your SDK band from NuGet APIs, then: +dotnet workload install maui --version $WORKLOAD_VERSION +``` + +### "NETSDK1147: To build this project, the following workloads must be installed" + +**Solution**: Install the listed workloads with explicit version: +```bash +dotnet workload install [workload-name] --version $WORKLOAD_VERSION +``` + +--- + +## Performance Issues + +### Slow builds + +**Solutions**: +1. Enable incremental builds (default) +2. Use Hot Reload during development +3. Build only necessary platforms: + ```bash + dotnet build -f net10.0-android + ``` + +### Slow Android emulator + +**Solutions**: +1. Enable hardware acceleration (HAXM/KVM/Hyper-V) +2. Use x86_64 system image (not ARM on Intel) +3. Increase emulator RAM in AVD settings +4. Use physical device for testing + +--- + +## Environment Variable Reference + +| Variable | Purpose | Required | Notes | +|----------|---------|----------|-------| +| `JAVA_HOME` | JDK location | No | Report as anomaly if set to non-Microsoft JDK | +| `ANDROID_HOME` | Android SDK location | No | Auto-detected | +| `ANDROID_SDK_ROOT` | Android SDK location | No | Alternative to ANDROID_HOME | +| `DOTNET_ROOT` | .NET SDK location | No | Usually auto-detected | +| `PATH` | Must include dotnet | Yes | Required for CLI access | + +**Key point about JAVA_HOME:** +- ✅ Not set → Fine, tools auto-detect Microsoft JDK +- ✅ Set to Microsoft JDK path → Fine +- ⚠️ Set to non-Microsoft JDK → Anomaly — report to user + +**Note**: The .NET MAUI toolchain auto-detects most paths. Only set these manually if auto-detection fails or wrong JDK is being selected. + +--- + +## Getting Help + +### Diagnostic Commands + +```bash +# Full .NET info +dotnet --info + +# Workload status +dotnet workload list + +# JDK info +java -version +``` + +See platform-specific troubleshooting files for additional diagnostic commands. + +### Resources + +- [.NET MAUI GitHub Issues](https://github.com/dotnet/maui/issues) +- [Stack Overflow - maui tag](https://stackoverflow.com/questions/tagged/maui) +- [.NET MAUI Documentation](https://learn.microsoft.com/en-us/dotnet/maui/) diff --git a/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/workload-dependencies-discovery.md b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/workload-dependencies-discovery.md new file mode 100644 index 0000000000..7c2bed87b6 --- /dev/null +++ b/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/workload-dependencies-discovery.md @@ -0,0 +1,249 @@ +# Workload Dependencies Discovery + +This reference describes how to discover authoritative version requirements from NuGet APIs. All JDK, Android SDK, and Xcode requirements come from WorkloadDependencies.json - never hardcode versions. + +## Workload Aliases + +| Alias | Full ID | +|-------|---------| +| ios | microsoft.net.sdk.ios | +| android | microsoft.net.sdk.android | +| maccatalyst | microsoft.net.sdk.maccatalyst | +| macos | microsoft.net.sdk.macos | +| tvos | microsoft.net.sdk.tvos | +| maui | microsoft.net.sdk.maui | + +--- + +## Discovery Process + +### Step 1: Get Latest SDK Version + +**Bash:** +```bash +curl -s "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json" | \ + jq '.["releases-index"][] | select(.["channel-version"]=="{MAJOR}.0")' +``` + +**PowerShell:** +```powershell +$releases = Invoke-RestMethod "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json" +$releases.'releases-index' | Where-Object { $_.'channel-version' -eq '{MAJOR}.0' } +``` + +Response fields: +| Field | Description | +|-------|-------------| +| `channel-version` | Major.minor (e.g., "10.0") | +| `latest-sdk` | Current stable SDK version | +| `support-phase` | "active", "maintenance", "eol" | + +Extract `latest-sdk` and derive SDK band: +- `10.0.102` → band `10.0.100` (hundreds digit) +- `10.0.205` → band `10.0.200` + +### Step 2: Find Workload Set Version + +Use the `dotnet workload search version` command to discover the latest workload set version: + +```bash +dotnet workload search version --format json --take 1 +# Returns: [{"workloadVersion":"10.0.103"}] +``` + +```powershell +dotnet workload search version --format json --take 1 | ConvertFrom-Json +``` + +The returned `workloadVersion` is the CLI version to use with `--version` flag. + +To convert this to the NuGet package version (needed for Steps 3-4): +- CLI `10.0.102` → NuGet `10.102.0` (remove middle `.0.`, combine) +- The NuGet package is: `Microsoft.NET.Workloads.{band}` where band = CLI version (e.g., `Microsoft.NET.Workloads.10.0.100`) + +### Step 3: Download Workload Set Manifest + +**Bash:** +```bash +curl -o workloadset.nupkg "https://api.nuget.org/v3-flatcontainer/microsoft.net.workloads.{band}/{version}/microsoft.net.workloads.{band}.{version}.nupkg" +unzip -p workloadset.nupkg data/microsoft.net.workloads.workloadset.json +``` + +**PowerShell:** +```powershell +Invoke-WebRequest "https://api.nuget.org/v3-flatcontainer/microsoft.net.workloads.{band}/{version}/microsoft.net.workloads.{band}.{version}.nupkg" -OutFile workloadset.nupkg +Add-Type -AssemblyName System.IO.Compression.FileSystem +$zip = [System.IO.Compression.ZipFile]::OpenRead("workloadset.nupkg") +$entry = $zip.Entries | Where-Object { $_.FullName -eq "data/microsoft.net.workloads.workloadset.json" } +$reader = [System.IO.StreamReader]::new($entry.Open()) +$reader.ReadToEnd() | ConvertFrom-Json +$reader.Dispose(); $zip.Dispose() +``` + +Contents format: `"{workload_id}": "{manifestVersion}/{sdkBand}"` + +Example: +```json +{ + "microsoft.net.sdk.android": "35.0.50/9.0.100", + "microsoft.net.sdk.ios": "26.2.10191/10.0.100", + "microsoft.net.sdk.maui": "10.0.10/10.0.100" +} +``` + +### Step 4: Download Workload Manifest + +Build package id: `{WorkloadId}.Manifest-{sdkBand}` + +Examples: +- `Microsoft.NET.Sdk.iOS.Manifest-10.0.100` +- `Microsoft.NET.Sdk.Android.Manifest-9.0.100` + +**Bash:** +```bash +curl -o manifest.nupkg "https://api.nuget.org/v3-flatcontainer/{packageid}/{version}/{packageid}.{version}.nupkg" +unzip -p manifest.nupkg data/WorkloadDependencies.json +``` + +**PowerShell:** +```powershell +Invoke-WebRequest "https://api.nuget.org/v3-flatcontainer/{packageid}/{version}/{packageid}.{version}.nupkg" -OutFile manifest.nupkg +Add-Type -AssemblyName System.IO.Compression.FileSystem +$zip = [System.IO.Compression.ZipFile]::OpenRead("manifest.nupkg") +$entry = $zip.Entries | Where-Object { $_.FullName -eq "data/WorkloadDependencies.json" } +$reader = [System.IO.StreamReader]::new($entry.Open()) +$reader.ReadToEnd() | ConvertFrom-Json +$reader.Dispose(); $zip.Dispose() +``` + +### Step 5: Parse WorkloadDependencies.json + +**Android workload** (`microsoft.net.sdk.android`): +```json +{ + "microsoft.net.sdk.android": { + "jdk": { + "version": "[17.0,22.0)", + "recommendedVersion": "21.0.8" + }, + "androidsdk": { + "packages": ["build-tools;35.0.0", "platform-tools", "platforms;android-35", "cmdline-tools;13.0"], + "apiLevel": "35", + "buildToolsVersion": "35.0.0", + "cmdLineToolsVersion": "13.0" + } + } +} +``` + +**iOS workload** (`microsoft.net.sdk.ios`): +```json +{ + "microsoft.net.sdk.ios": { + "xcode": { + "version": "[26.2,)", + "recommendedVersion": "26.2" + }, + "sdk": { + "version": "26.2" + } + } +} +``` + +### Version Range Notation + +| Notation | Meaning | +|----------|---------| +| `[17.0,22.0)` | >= 17.0 AND < 22.0 | +| `[26.2,)` | >= 26.2 (no upper bound) | + +Brackets: `[` = inclusive, `(` = exclusive + +--- + +## Complete Example + +**Goal**: Find requirements for .NET 10 + +### Bash + +```bash +# Step 1: Get SDK info +curl -s "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json" | \ + jq '.["releases-index"][] | select(.["channel-version"]=="10.0") | .["latest-sdk"]' +# Result: "10.0.102" → band "10.0.100" + +# Step 2: Get latest workload set version +dotnet workload search version --format json --take 1 +# Result: [{"workloadVersion":"10.0.102"}] +# NuGet version: 10.102.0 + +# Step 3: Download workload set manifest +curl -so workloadset.nupkg "https://api.nuget.org/v3-flatcontainer/microsoft.net.workloads.10.0.100/10.102.0/microsoft.net.workloads.10.0.100.10.102.0.nupkg" +unzip -p workloadset.nupkg data/microsoft.net.workloads.workloadset.json | jq '."microsoft.net.sdk.android"' +# Result: "35.0.50/9.0.100" + +# Step 4: Download Android manifest +curl -so android.nupkg "https://api.nuget.org/v3-flatcontainer/microsoft.net.sdk.android.manifest-9.0.100/35.0.50/microsoft.net.sdk.android.manifest-9.0.100.35.0.50.nupkg" +unzip -p android.nupkg data/WorkloadDependencies.json | jq '.["microsoft.net.sdk.android"]' +``` + +### PowerShell + +```powershell +# Step 1: Get SDK info +$releases = Invoke-RestMethod "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json" +$sdkInfo = $releases.'releases-index' | Where-Object { $_.'channel-version' -eq '10.0' } +$latestSdk = $sdkInfo.'latest-sdk' +# Result: "10.0.102" → band "10.0.100" + +# Step 2: Get latest workload set version +$workloadVersion = (dotnet workload search version --format json --take 1 | ConvertFrom-Json).workloadVersion +# Result: "10.0.102" +# NuGet version: 10.102.0 + +# Step 3: Download workload set manifest and extract +Invoke-WebRequest "https://api.nuget.org/v3-flatcontainer/microsoft.net.workloads.10.0.100/10.102.0/microsoft.net.workloads.10.0.100.10.102.0.nupkg" -OutFile workloadset.nupkg +Add-Type -AssemblyName System.IO.Compression.FileSystem +$zip = [System.IO.Compression.ZipFile]::OpenRead("workloadset.nupkg") +$entry = $zip.Entries | Where-Object { $_.FullName -eq "data/microsoft.net.workloads.workloadset.json" } +$reader = [System.IO.StreamReader]::new($entry.Open()) +$manifest = $reader.ReadToEnd() | ConvertFrom-Json +$reader.Dispose(); $zip.Dispose() +$manifest.'microsoft.net.sdk.android' +# Result: "35.0.50/9.0.100" + +# Step 4: Download Android manifest and extract WorkloadDependencies +Invoke-WebRequest "https://api.nuget.org/v3-flatcontainer/microsoft.net.sdk.android.manifest-9.0.100/35.0.50/microsoft.net.sdk.android.manifest-9.0.100.35.0.50.nupkg" -OutFile android.nupkg +$zip = [System.IO.Compression.ZipFile]::OpenRead("android.nupkg") +$entry = $zip.Entries | Where-Object { $_.FullName -eq "data/WorkloadDependencies.json" } +$reader = [System.IO.StreamReader]::new($entry.Open()) +$reader.ReadToEnd() | ConvertFrom-Json +$reader.Dispose(); $zip.Dispose() +``` + +**Result**: Authoritative JDK, Android SDK, and Xcode requirements from live NuGet data. + +--- + +## NuGet API Reference + +| Operation | Endpoint | +|-----------|----------| +| .NET releases | `https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json` | +| NuGet service index | `https://api.nuget.org/v3/index.json` | +| Download package | `https://api.nuget.org/v3-flatcontainer/{id}/{version}/{id}.{version}.nupkg` | + +**Workload version discovery**: Use `dotnet workload search version --format json --take 1` instead of querying NuGet search APIs directly. The NuGet download URLs are still needed for Steps 3-4 (manifest extraction). + +**Important**: Package IDs must be lowercase in download URLs. + +--- + +## Best Practices + +- **ALWAYS** fetch live data from NuGet APIs +- **NEVER** hardcode version requirements +- **ALWAYS** include SDK band with manifest versions +- Show exact URLs used for transparency diff --git a/tests/dotnet-maui/dotnet-maui-doctor/eval.yaml b/tests/dotnet-maui/dotnet-maui-doctor/eval.yaml new file mode 100644 index 0000000000..f3148dce9e --- /dev/null +++ b/tests/dotnet-maui/dotnet-maui-doctor/eval.yaml @@ -0,0 +1,172 @@ +scenarios: + - name: "Plan macOS MAUI setup with Xcode" + prompt: | + I have a clean macOS machine and want to start developing .NET MAUI apps + for iOS and Android. I can't run commands right now, but I need a complete + setup plan. Tell me exactly what I need to install, how to discover the + right versions, and how to verify everything works. Please provide the + official recommended installation sources. + assertions: + - type: "output_contains" + value: "Xcode" + - type: "output_matches" + pattern: "(?i)apple developer|developer\\.apple\\.com" + - type: "output_contains" + value: "Microsoft" + - type: "output_matches" + pattern: "(?i)version|pin" + rubric: + - "Warns about the risk of uncontrolled Xcode version updates and recommends a specific download source" + - "Recommends the 'maui' workload (not 'maui-android') since this is macOS" + - "Specifies Microsoft OpenJDK as the only supported Java distribution" + - "Verifies version requirements using CLI tools or official documentation rather than relying on hardcoded versions" + - "Pins workloads to a specific version to ensure reproducible environment setup" + - "Does not recommend 'dotnet workload update' or 'dotnet workload repair' as the primary installation method" + timeout: 120 + + - name: "Plan Linux MAUI environment for Android" + prompt: | + I'm on a headless Linux CI server and need to build my MAUI app for Android. + I have the .NET SDK installed but nothing else. + Give me a specific plan to set up the environment, including how to find + the correct versions for everything. + assertions: + - type: "output_contains" + value: "maui-android" + - type: "output_contains" + value: "Microsoft" + - type: "output_matches" + pattern: "(?i)version|pin" + - type: "output_matches" + pattern: "sdkmanager|android command-line tools" + rubric: + - "Recommends 'maui-android' workload, not the 'maui' meta-workload which fails on Linux" + - "Does not suggest iOS or Mac Catalyst workloads for Linux" + - "Specifies Microsoft OpenJDK as the only supported Java distribution" + - "Verifies version requirements using CLI tools or official documentation rather than relying on hardcoded versions" + - "Does not recommend 'dotnet workload update' or 'dotnet workload repair' as the primary installation method" + timeout: 120 + + - name: "Guardrail against workload update and repair" + prompt: | + My .NET MAUI project stopped building after a .NET SDK update. I think my + workloads are out of date. Should I run `dotnet workload update` or + `dotnet workload repair` to fix this? + assertions: + - type: "output_matches" + pattern: "(?i)version|pin" + rubric: + - "Explicitly warns against using dotnet workload update and dotnet workload repair" + - "Recommends reinstalling workloads pinned to a specific version to ensure consistency" + - "Explains that workload update/repair can cause version inconsistencies" + - "Provides a method to determine the correct workload version for the current SDK" + timeout: 120 + + - name: "Diagnose non-Microsoft JDK causing build failure" + prompt: | + I'm on macOS and my .NET MAUI Android build fails with a Java-related error. + I have Adoptium Temurin JDK 17.0.12 installed and JAVA_HOME points to it. + `java -version` shows `OpenJDK Runtime Environment Temurin-17.0.12+7`. + What's wrong and how do I fix it? + assertions: + - type: "output_contains" + value: "Microsoft" + - type: "output_not_matches" + pattern: "(?i)Temurin.{0,20}(fine|correct|ok|good|supported)" + - type: "output_matches" + pattern: "JAVA_HOME" + rubric: + - "Identifies that the JDK vendor is the problem, not the version number" + - "Recommends installing Microsoft Build of OpenJDK specifically" + - "Advises unsetting JAVA_HOME or redirecting it to the Microsoft JDK path" + - "Does not suggest Adoptium, Oracle, or other non-Microsoft JDKs as acceptable" + timeout: 120 + + - name: "Plan complete MAUI setup on Windows" + prompt: | + I'm setting up .NET MAUI development on Windows 11 from scratch. I need + to target both Android and Windows. I can't run commands right now — give + me a complete step-by-step plan with all the PowerShell commands I'll need, + including how to discover the right versions dynamically. + assertions: + - type: "output_matches" + pattern: "sdkmanager\\.bat" + - type: "output_matches" + pattern: "(?i)version|pin" + - type: "output_contains" + value: "Microsoft" + - type: "output_not_matches" + pattern: "workload update|workload repair" + rubric: + - "Uses sdkmanager.bat (not sdkmanager) for Android SDK management on Windows" + - "Uses dotnet CLI commands (e.g. dotnet workload search) to discover workload versions rather than hardcoding or querying external APIs directly" + - "Does not hardcode specific SDK, workload, JDK, or Android version numbers as current" + - "Recommends the 'maui' workload (not 'maui-android') for Windows" + timeout: 120 + + - name: "Prevent incorrect JAVA_HOME configuration" + prompt: | + My .NET MAUI Android build on macOS shows a 'JAVA_HOME is not set' warning. + I found a Stack Overflow answer telling me to add + `export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home` + to my shell profile. Is this the right fix? What should I actually do? + assertions: + - type: "output_matches" + pattern: "(?i)not required|not necessary|optional|auto.?detect|don't need to set" + - type: "output_contains" + value: "Microsoft" + - type: "output_not_matches" + pattern: "(?i)Temurin.{0,20}(fine|correct|ok|good|right)" + rubric: + - "Warns against setting JAVA_HOME to the Adoptium Temurin JDK path from the Stack Overflow answer" + - "Explains that JAVA_HOME is not required because .NET MAUI auto-detects JDK installations" + - "Clarifies that setting JAVA_HOME to a non-Microsoft JDK can cause build failures" + - "Recommends Microsoft OpenJDK as the correct JDK if one needs to be explicitly configured" + timeout: 120 + + - name: "Determine required Android SDK packages for specific .NET version" + prompt: | + I'm setting up a CI pipeline for a .NET MAUI Android app. I need to know + exactly which Android SDK packages (build-tools version, API level, + command-line tools version) are required for the MAUI workload that ships + with my current .NET SDK. I don't want to guess or use outdated docs — + how can I programmatically determine the exact package list my SDK needs? + assertions: + - type: "output_matches" + pattern: "build-tools" + - type: "output_matches" + pattern: "(?i)api.?level|platforms;android" + - type: "output_matches" + pattern: "(?i)manifest|workload.?dependenc" + - type: "output_matches" + pattern: "sdkmanager" + rubric: + - "Determines required Android SDK packages based on the installed workload version rather than guessing" + - "Identifies specific package types needed: build-tools, platforms, platform-tools, and command-line tools" + - "Explains the relationship between .NET SDK version, workload manifest version, and Android SDK requirements" + - "Provides a reproducible approach suitable for CI automation" + timeout: 120 + + - name: "Fix stale MAUI workloads after SDK update" + prompt: | + I updated to a newer .NET SDK on Windows 10 and now my .NET MAUI app + fails to build with workload and Android SDK errors. A colleague told me + to run 'dotnet workload update' but I'm not sure that's safe. Please lay + out a diagnostic and fix plan that brings my workloads and Android SDK + into a consistent state for the new SDK. + assertions: + - type: "output_contains" + value: "dotnet --info" + - type: "output_matches" + pattern: "dotnet workload (list|install)" + - type: "output_matches" + pattern: "(?i)version|pin" + - type: "output_not_matches" + pattern: "workload update|workload repair" + rubric: + - "Explains why dotnet workload update and repair are discouraged for MAUI and recommends reinstalling workloads pinned to a specific version" + - "Provides a method to determine which workloads and versions should be installed for the new SDK" + - "Includes checks for Android SDK packages and build tools consistent with the current workload" + - "Provides a step-by-step approach: diagnose current state, discover correct versions, reinstall, re-validate" + - "Emphasizes re-running validation after fixes to confirm a healthy environment" + timeout: 120