Add dotnet-maui plugin with dotnet-maui-doctor skill#199
Add dotnet-maui plugin with dotnet-maui-doctor skill#199jfversluis wants to merge 12 commits intodotnet:mainfrom
Conversation
Add a new .agents/skills/dotnet-maui-doctor skill bundle. Includes SKILL.md describing an autonomous workflow to detect and remediate .NET MAUI environment issues and platform-specific reference docs for installation commands, platform requirements, troubleshooting, Microsoft OpenJDK guidance, and a WorkloadDependencies discovery guide that pulls authoritative versions from NuGet. Documents validation/remediation steps for .NET SDK, workloads, JDK, Android SDK, Xcode, and Windows SDK (macOS/Windows/Linux) and includes a temporary recommendation to prefer Microsoft OpenJDK (JDK 21) until manifests are updated.
Introduce the dotnet-maui plugin and move the dotnet-maui-doctor skill under plugins/ layout. Update marketplace, CODEOWNERS, and README accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
10 scenarios covering: macOS/Linux/Windows setup, JDK vendor enforcement, workload update/repair guardrails, dynamic version discovery, JAVA_HOME misconception, Android SDK diagnosis, out-of-scope decline, and stale workload remediation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove 'Resist hardcoding' (penalizes skill — baseline gives more useful direct answer) and 'Decline runtime bug' (skill makes agent refuse to help). Rework Android SDK scenario to test CI-oriented package discovery where baseline lacks knowledge. Replace vocabulary-level NuGet/API assertions with outcome-focused rubric items across all scenarios. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace temporary JDK 21 workaround notes with guidance to use the
version from WorkloadDependencies.json. Replace hardcoded JDK paths
in troubleshooting.md with {VERSION} placeholders.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/evaluate |
Skill Validation Results
Model: claude-opus-4.6 | Judge: claude-opus-4.6 |
…fitting - JAVA_HOME: rewrite prompt to request conceptual answer (prevents tool timeout) - macOS Xcode: add installation source guidance, remove equal-penalty assertion - Remove irrelevant workload update/repair assertions from 3 off-topic scenarios - Keep workload assertions in 5 scenarios where workload management is the topic Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Updated eval scenarios to address CI results:
Could you re-run |
|
/evaluate |
Rewrite prompt from conceptual yes/no question (which the agent answered from wrong general knowledge without activating the skill) to a scenario where the user is about to apply incorrect Stack Overflow advice. This mirrors the successful workload guardrail pattern. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/evaluate |
- Replace literal '--version' assertions with broader 'version|pin' pattern - Rephrase Xcode rubric from skill-specific source to version control risk - Rephrase version discovery rubric from 'NuGet API' to outcome-focused - Rephrase workload install rubric from '--version flag' to 'pinned version' Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/evaluate |
The JAVA_HOME eval scenario scored poorly because the agent couldn't read the reference file (references/microsoft-openjdk.md) and fell back on general knowledge, which incorrectly says JAVA_HOME must be set. Changes: - Task 5: Add inline JAVA_HOME guidance with decision table showing that JAVA_HOME is NOT required and MAUI auto-detects JDK installations - Common Pitfalls: Add 'Unnecessary JAVA_HOME' entry with unset commands This ensures the agent knows JAVA_HOME is unnecessary even when reference files can't be loaded. File stays at 210 lines (limit: 500). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add JAVA_HOME guidance directly to Task 5, Task 9, and Common Pitfalls so the agent knows JAVA_HOME is not required even when reference files can't be read. Based on Redth's original microsoft-openjdk.md reference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Introduces a new dotnet-maui plugin and adds the dotnet-maui-doctor skill (with supporting reference documentation and eval scenarios) using the repository’s plugins/ + tests/ layout.
Changes:
- Added
plugins/dotnet-maui/plugin manifest and thedotnet-maui-doctorskill bundle (SKILL.md + reference docs). - Added
tests/dotnet-maui/dotnet-maui-doctor/eval.yamlwith 8 cross-platform evaluation scenarios. - Registered the new plugin in the marketplace listing, CODEOWNERS, and README.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
plugins/dotnet-maui/plugin.json |
New plugin manifest for dotnet-maui. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/SKILL.md |
Skill definition + workflow and guardrails for MAUI environment diagnosis. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/workload-dependencies-discovery.md |
NuGet-based process for dynamically discovering workload dependency requirements. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands.md |
Cross-platform installation command reference for SDK/workloads/JDK/Android SDK. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-macos.md |
macOS-specific installation guidance (Xcode, simulators). |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-windows.md |
Windows-specific guidance for Windows SDK detection/installation. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/microsoft-openjdk.md |
Microsoft OpenJDK detection paths and JAVA_HOME guidance. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-macos.md |
macOS requirements summary for MAUI workloads and dependencies. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-windows.md |
Windows requirements summary for MAUI workloads and dependencies. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-linux.md |
Linux requirements/limitations summary (Android-only). |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting.md |
Common MAUI setup/build troubleshooting guide. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting-macos.md |
macOS-specific troubleshooting and diagnostic commands. |
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting-windows.md |
Windows-specific troubleshooting and diagnostic commands. |
tests/dotnet-maui/dotnet-maui-doctor/eval.yaml |
Eval scenarios to validate behavior/guardrails across macOS/Linux/Windows. |
.github/plugin/marketplace.json |
Added dotnet-maui to the plugin marketplace index. |
.github/CODEOWNERS |
Added ownership entries for the new plugin and tests folders. |
README.md |
Listed the new plugin in the repository “What’s Included” table. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "name": "dotnet-maui", | ||
| "version": "0.1.0", | ||
| "description": "Skills for .NET MAUI development: environment setup, diagnostics, and troubleshooting.", | ||
| "skills": "./skills/" |
There was a problem hiding this comment.
Other plugin manifests in this repo include an agents entry alongside skills (e.g., plugins/dotnet/plugin.json, plugins/dotnet-msbuild/plugin.json). If this plugin intentionally has no agents, consider still including an explicit "agents" path (and/or adding an empty agents/ folder) to keep plugin manifests consistent and avoid tooling assuming the key exists.
| "skills": "./skills/" | |
| "skills": "./skills/", | |
| "agents": "./agents/" |
There was a problem hiding this comment.
Intentionally omitted — this plugin has no agents, and adding an empty agents/ directory with a dangling path in the manifest would be misleading. The other plugins that include agents actually have agent definitions in that folder. If/when we add agents to this plugin, we'll add both the directory and the manifest entry.
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands.md
Show resolved
Hide resolved
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands-macos.md
Outdated
Show resolved
Hide resolved
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/workload-dependencies-discovery.md
Show resolved
Hide resolved
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting.md
Outdated
Show resolved
Hide resolved
plugins/dotnet-maui/skills/dotnet-maui-doctor/references/troubleshooting.md
Outdated
Show resolved
Hide resolved
- Fix cmd.exe syntax in installation-commands.md (use PowerShell $env:) - Replace hardcoded simulator device/runtime with placeholders - Add System.IO.Compression.FileSystem assembly load for PS 5.1 compat - Clarify workload reinstall example is macOS-specific (omit ios on Linux) - Replace hardcoded android-35 with $API_LEVEL placeholder Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/evaluate |
ViktorHofer
left a comment
There was a problem hiding this comment.
This is good to go from an infra perspective. The eval results also look good. Please get reviews from maui folks as well.
|
|
||
| **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. |
There was a problem hiding this comment.
Does something need to mention you will need to manually login with your Apple account? (it has 2FA)
There was a problem hiding this comment.
Probably worth adding a note so it can tell the developer what to expect.
| ### Detect Windows SDK | ||
|
|
||
| ```powershell | ||
| Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots" -ErrorAction SilentlyContinue | ||
| ``` |
There was a problem hiding this comment.
Is this the right command, it just reports random things for me:
> Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots" -ErrorAction SilentlyContinue
{599B5A52-33FD-0EA6-D7F2-E62F2058A21C} : Application Verifier x64 External Package (DesktopEditions) x64
KitsRoot10 : C:\Program Files (x86)\Windows Kits\10\
{9624EAC7-C752-8DC3-33D7-6911F0889062} : Application Verifier x64 External Package (OnecoreUAP) x64
AppVerifier64BitAutomationRoot : C:\Program Files\Application Verifier\
{ACB8119F-54A6-C93C-CA2F-3A1476EE8869} : Application Verifier x64 External Package (DesktopEditions) x64
{C53ECC06-72B1-FEBF-D241-038A4BC83E57} : Application Verifier x64 External Package (OnecoreUAP) x64
{A6FC8F56-AEE7-CC1C-28D6-A17567A48D75} : Application Verifier x64 External Package (DesktopEditions) x64
{27C8EF42-3846-AFCF-2F6D-8C145F75C8EF} : Application Verifier x64 External Package (OnecoreUAP) x64
{A891E3DB-0F4D-B1C1-EC88-CF1C8ABAF8CB} : Application Verifier x64 External Package (DesktopEditions) x64
{D9009790-F40A-C423-CCB8-65ECEC9A9FA9} : Application Verifier x64 External Package (OnecoreUAP) x64
{AAD4ECCF-69C7-CA36-E72C-BB00821FB9FA} : Application Verifier x64 External Package (DesktopEditions) x64
{F0B26EED-55C0-CCDD-F474-34FFFD3F3AB2} : Application Verifier x64 External Package (OnecoreUAP) x64
{43D478B3-5651-284E-0CA3-C3AC2C1CDFC9} : Application Verifier x64 External Package (DesktopEditions) x64
{6A220D0F-7788-4295-2445-FF790A88060D} : Application Verifier x64 External Package (OnecoreUAP) x64
{C0B0A1D9-9045-54FE-86F6-1B0F836E665E} : Application Verifier x64 External Package (DesktopEditions) x64
{674C8368-9677-55A8-FAD9-A86A3073E60D} : Application Verifier x64 External Package (OnecoreUAP) x64
{D75B3C63-F3BB-5EC1-45A7-15C00BBB9D3F} : Application Verifier x64 External Package (DesktopEditions) x64
{601DDF69-FCF4-F568-946A-C17046C946E4} : Application Verifier x64 External Package (OnecoreUAP) x64
{20C01991-CCD1-2C06-7A9A-B10A9B4AF807} : Windows App Certification Kit Native Components x64
{C7F2EF85-ACD3-0480-6BC2-0C3B45A8F1C1} : Universal CRT Tools x64 x64
{FB7C4DC7-7641-04B7-6639-589757B86783} : Windows SDK DirectX x64 Remote x64
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits
PSChildName : Installed Roots
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
Some are Windows SDK things, just worth checking if this the official way.
There was a problem hiding this comment.
I was debating removing this windows SDK part already, maybe we can just leave it out for now.
| ```bash | ||
| # Discover NuGet search endpoint from service index | ||
| NUGET_SEARCH_URL=$(curl -s "https://api.nuget.org/v3/index.json" | \ | ||
| jq -r '.resources[] | select(.["@type"]=="SearchQueryService") | .["@id"]' | head -1) | ||
|
|
||
| # Query for latest workload set | ||
| # SDK band = first 2 segments of SDK version (e.g., 10.0 from 10.0.102) | ||
| curl -s "$NUGET_SEARCH_URL?q=Microsoft.NET.Workloads.$SDK_BAND&prerelease=false" | \ | ||
| jq '.data[] | select(.id | test("^Microsoft.NET.Workloads.$SDK_BAND.[0-9]+$")) | {id, version}' | ||
|
|
||
| # Convert NuGet version to CLI version: | ||
| # NuGet A.B.C → CLI A.0.B (e.g., NuGet 10.102.0 → CLI 10.0.102) | ||
| ``` |
There was a problem hiding this comment.
This looks like a manual bash version of the dotnet workload search version 10.0.103 command, can AI use that instead?
If that doesn't work, can we file an issue on dotnet/sdk?
There was a problem hiding this comment.
I believe this would be running dotnet workload search version 10.0.100 since it will have determined the major sdk version's "band" would be 10.0.100 since the sdk could be 10.0.102, 10.0.103, etc.
If you search with the sdk version exactly, you'll get exactly that manifest version back, not anything newer, which I am not sure is exactly the result we want? Though it could be ok I suppose.
Though looking at the command it does seem that dotnet workload search version --format json will return the newest N (you can use --take to scope it to 1 too) workload set versions. This is maybe more what we want.
> dotnet workload search version --format json --take 1
[{"workloadVersion":"10.0.103"}]
That would eliminate the need to look up a the NUGET_SEARCH_URL and then the subsequent request for the versions of the workload set package.
So yeah, I think this would be a good simplification. It could be updated in this file as well as the workload-dependencies-discovery.md file.
| To unset: | ||
| ```bash | ||
| # macOS/Linux | ||
| unset JAVA_HOME | ||
|
|
||
| # Windows PowerShell | ||
| Remove-Item Env:JAVA_HOME | ||
| ``` |
There was a problem hiding this comment.
JAVA_HOME isn't required, but I don't think we have to tell AI to unset it?
Maybe it could just report this as an "anomoly" if it finds an unexpected JDK in $JAVA_HOME?
There was a problem hiding this comment.
Yeah perhaps just a bit of guidance so that if it detects a non-MS OpenJDK being set to that, only then do we bother trying to unset it. Though, if we aren't even checking it, does it matter if it's set?
| Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots" -ErrorAction SilentlyContinue | ||
|
|
||
| # JDK detection (Windows-specific) | ||
| Get-ChildItem "C:\Program Files\Microsoft" -Filter "jdk-*" -ErrorAction SilentlyContinue |
There was a problem hiding this comment.
can this use $env:ProgramFiles
|
|
||
| Detection: | ||
| ```powershell | ||
| Get-ChildItem "C:\Program Files\Microsoft" -Filter "jdk-*" -ErrorAction SilentlyContinue |
| # Option 2: Point to Microsoft JDK (Windows PowerShell) | ||
| $env:JAVA_HOME = "C:\Program Files\Microsoft\jdk-{VERSION}" | ||
| # Or remove it: Remove-Item Env:JAVA_HOME |
There was a problem hiding this comment.
I'm confused why we remove and re-set $JAVA_HOME, maybe it's better to just report something is wrong. An "anamoly" if we find a different JDK in $JAVA_HOME.
There was a problem hiding this comment.
@jonathanpeppers do we ever look at JAVA_HOME for our own tooling to find a JDK? If there's no registry key set, no Monodroid config set, etc... Do we just search known paths and not check JAVA_HOME? I think if that is truly the case, then yes, we could remove anything suggesting to set / unset JAVA_HOME and just forget about that part. Actually we probably would need to do the opposite and note to never care about JAVA_HOME and what it's set to.
There was a problem hiding this comment.
It will look for $JAVA_HOME before looking for hardcoded/known paths, but nothing sets this env var -- a developer would have to set it themselves.
| 2. Set `JAVA_HOME` to Microsoft JDK path: | ||
| - macOS: `/Library/Java/JavaVirtualMachines/microsoft-{VERSION}.jdk/Contents/Home` | ||
| - Windows: `C:\Program Files\Microsoft\jdk-{VERSION}\` | ||
| - Linux: `/usr/lib/jvm/msopenjdk-{VERSION}` |
There was a problem hiding this comment.
I don't think we really ever need to set $JAVA_HOME. Maybe an example of what this fixes would help me understand?
| # Check common environment variables | ||
| echo $ANDROID_HOME | ||
| echo $ANDROID_SDK_ROOT |
There was a problem hiding this comment.
We never set these, and neither does Android Studio.
Is the purpose to just find out if a user has set these themselves?
There was a problem hiding this comment.
ANDROID_HOME is also deprecated: https://developer.android.com/tools/variables#envar
There was a problem hiding this comment.
Should we expand a bit to articulate known paths this might exist instead? I agree, probably checking for these isn't super useful outside of may CI/CD environments.
Closes #14
Summary
Introduces the
dotnet-mauiplugin and moves thedotnet-maui-doctorskill (originally from #14 by @Redth) into the correctplugins/directory structure.What's included
plugins/dotnet-maui/plugin.json— New plugin manifestplugins/dotnet-maui/skills/dotnet-maui-doctor/— Skill + 11 reference docs covering:tests/dotnet-maui/dotnet-maui-doctor/eval.yaml— 8 eval scenarios covering all platforms, guardrails, and edge casesmarketplace.json,CODEOWNERS,README.mdChanges from #14
.agents/skills/toplugins/dotnet-maui/skills/per @timheuer's feedbackWhen to Use/When Not to Use/Inputs/Common Pitfallssections to SKILL.mdjq/unzipas explicit prerequisitesEval scenarios
mauiworkload, MS OpenJDKmaui-androidnotmaui, no iOS workloadsinstall --versionsdkmanager.bat, PowerShell commands, Windows SDKNote
The
eval.yamlhas not yet been run through the skill validator (eng/skill-validator). This requires .NET 10 SDK and authenticated GitHub access. Happy to run it once the infrastructure is available or if a maintainer can assist.Continues work from #14 by @Redth — his original commits are preserved.
cc @Redth @timheuer @jeffschwMSFT