Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,27 @@ jobs:
if not skill_dirs:
errors.append(f"No immediate skill directories found under {skills_root}")
for skill_dir in skill_dirs:
if not (skill_dir / "SKILL.md").is_file():
skill_md = skill_dir / "SKILL.md"
if not skill_md.is_file():
errors.append(f"Immediate skill directory lacks SKILL.md: {skill_dir}")
continue
# Mirrors vally's valid-refs lint used by marketplaces such as
# awesome-copilot: markdown links must resolve inside the skill
# directory. Name sibling skills in plain text instead.
body = re.sub(r"(?ms)^(```|~~~).*?^\1", "", skill_md.read_text(encoding="utf-8"))
body = re.sub(r"`[^`\n]*`", "", body)
targets = re.findall(r"\]\(([^)\s]+)", body) + re.findall(r"(?m)^\s*\[[^\]]+\]:\s*(\S+)", body)
for target in targets:
if re.match(r"^[A-Za-z][A-Za-z0-9+.-]*:", target) or target.startswith("#"):
continue
relative = target.split("#", 1)[0]
if not relative:
continue
resolved = (skill_dir / relative).resolve()
if not resolved.is_relative_to(skill_dir.resolve()):
errors.append(f"{skill_md}: link '{target}' points outside the skill directory; name the other skill in plain text")
elif not resolved.exists():
errors.append(f"{skill_md}: link '{target}' does not exist")

forbidden_portable_paths = (
".claude-plugin",
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ The `version-bump` and `changelog-entry` CI jobs enforce this.

### Fixed

- Replace cross-skill markdown links with plain-text skill names so each skill
is self-contained and passes marketplace link validation (vally `valid-refs`),
which blocked the awesome-copilot listing update. CI now enforces this.

### Removed

### Deprecated
Expand Down
6 changes: 3 additions & 3 deletions plugins/winui/agent-plugin/skills/winui-code-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Run a code review **after the app builds and before committing**. This catches q

### How to Review

Read through the project's XAML and C# files and check each section below. For analyzer setup, see [winui-dev-workflow](../winui-dev-workflow/SKILL.md); if it isn't installed, tell the user its checks didn't run.
Read through the project's XAML and C# files and check each section below. For analyzer setup, see `winui-dev-workflow`; if it isn't installed, tell the user its checks didn't run.

Before reporting an API mismatch or recommending a replacement, verify it against the **restored app project's** references with CLI 0.7+ `winapp find-api`, for example `winapp find-api members NavigationView --filter selected --json --project-dir <app-project-dir>`. See [winui-design](../winui-design/SKILL.md) for batch property checks and project selection; machine-SDK results are not proof of app-package availability.
Before reporting an API mismatch or recommending a replacement, verify it against the **restored app project's** references with CLI 0.7+ `winapp find-api`, for example `winapp find-api members NavigationView --filter selected --json --project-dir <app-project-dir>`. See `winui-design` for batch property checks and project selection; machine-SDK results are not proof of app-package availability.

The analyzer catches a curated set of WinUI 3 / Windows App SDK issues with categorized 4-digit IDs:

Expand Down Expand Up @@ -42,7 +42,7 @@ Use the installed package's diagnostic help links for rule details. Check inheri
### Native AOT / Trimming (When Intended)

- [ ] The published artifact was tested (a Release JIT run is not AOT validation), with IL/CsWinRT warnings fixed rather than suppressed
- [ ] ABI-crossing types are partial; JSON and runtime bindings use source generation — see [source-generator patterns](../winui-packaging/references/sourcegen-patterns.md)
- [ ] ABI-crossing types are partial; JSON and runtime bindings use source generation — see `winui-packaging`'s `references/sourcegen-patterns.md`

### Accessibility

Expand Down
2 changes: 1 addition & 1 deletion plugins/winui/agent-plugin/skills/winui-design/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Don't size the window by setting `Width`/`Height` on the root `Grid` — that cl
<TextBlock Text="{x:Bind Vm.Status, Mode=OneWay}" />
```

In a page/window, `x:Bind` resolves against code-behind (e.g., its `Vm` property), not `DataContext`. Use `x:DataType` on typed **DataTemplates**, not on `Page` to set a VM. Runtime `{Binding}`/`DisplayMemberPath` can be appropriate; for AOT, their source classes may need `partial` plus `[WinRT.GeneratedBindableCustomProperty]`. See [source-generator patterns](../winui-packaging/references/sourcegen-patterns.md) instead of treating all runtime binding as unsupported.
In a page/window, `x:Bind` resolves against code-behind (e.g., its `Vm` property), not `DataContext`. Use `x:DataType` on typed **DataTemplates**, not on `Page` to set a VM. Runtime `{Binding}`/`DisplayMemberPath` can be appropriate; for AOT, their source classes may need `partial` plus `[WinRT.GeneratedBindableCustomProperty]`. See `winui-packaging`'s `references/sourcegen-patterns.md` instead of treating all runtime binding as unsupported.

### `TextBox` two-way needs `UpdateSourceTrigger=PropertyChanged`

Expand Down
10 changes: 5 additions & 5 deletions plugins/winui/agent-plugin/skills/winui-dev-workflow/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ dotnet add .\MyApp.csproj package Microsoft.Windows.SDK.BuildTools.WinUIAnalyzer

Keep `PrivateAssets="all"` on the reference. It loads in normal CLI, IDE, and CI builds; WinApp CLI does not inject it. If the package is unavailable, continue and tell the user its checks for potential runtime issues did not run. Undo only an incomplete reference added by this attempt; do not remove existing references or hide other restore failures.

For other packages, prefer the latest stable unless the project has a version policy or the user requests a specific version. Before coding API assumptions, use `winapp find-api` scoped to the restored app with `--project-dir <app-project-dir>` (or `--project <name>` in a solution); see [winui-design](../winui-design/SKILL.md).
For other packages, prefer the latest stable unless the project has a version policy or the user requests a specific version. Before coding API assumptions, use `winapp find-api` scoped to the restored app with `--project-dir <app-project-dir>` (or `--project <name>` in a solution); see `winui-design`.

### Build & Run (JIT Development)

```powershell
winapp run . --detach --json
```
For UI testing, see [winui-ui-testing](../winui-ui-testing/SKILL.md), which chooses the execution target itself.
For UI testing, see `winui-ui-testing`, which chooses the execution target itself.

Ordinary `winapp run` uses the build/JIT path, **even with `-c Release`**; it does not validate Native AOT. Use an explicit `.csproj` when project selection is ambiguous; see `winapp run --help` for options.

Expand All @@ -48,7 +48,7 @@ For intended AOT deployment, set `<PublishAot>true</PublishAot>` in the app proj
winapp run . --aot -c Release --arch <x64|arm64> --detach --json
winapp run . --aot -c Release --arch <x64|arm64> -p PublishAot=true --detach --json
```
Fix IL/CsWinRT warnings rather than suppressing them. See [AOT/source-generator patterns](../winui-packaging/references/sourcegen-patterns.md).
Fix IL/CsWinRT warnings rather than suppressing them. See `winui-packaging`'s `references/sourcegen-patterns.md`.

### Diagnosing Crashes

Expand Down Expand Up @@ -82,7 +82,7 @@ Run attached with `--debug-output` and **invoke it with `mode: "async"`**, then
| WinApp CLI | 0.7+ |
| Native AOT only | MSVC C++ build tools (Visual Studio or Build Tools, **Desktop development with C++** workload, target-architecture tools); not needed for normal builds |

If WinApp CLI is missing or older than 0.7, install or upgrade it using [winui-setup](../winui-setup/SKILL.md) without asking (it needs no admin rights) and tell the user. Ask before installing anything that needs admin rights — the .NET SDK, Developer Mode, or the [Native AOT toolchain](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/); do not work around them.
If WinApp CLI is missing or older than 0.7, install or upgrade it using `winui-setup` without asking (it needs no admin rights) and tell the user. Ask before installing anything that needs admin rights — the .NET SDK, Developer Mode, or the [Native AOT toolchain](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/); do not work around them.

### Critical Rules

Expand All @@ -93,4 +93,4 @@ If WinApp CLI is missing or older than 0.7, install or upgrade it using [winui-s

### References

- [winui-packaging](../winui-packaging/SKILL.md) — release packaging directly from the project; no development registration required.
- `winui-packaging` — release packaging directly from the project; no development registration required.
6 changes: 3 additions & 3 deletions plugins/winui/agent-plugin/skills/winui-packaging/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: winui-packaging
description: "MSIX packaging, code signing, and distribution for WinUI 3 apps with WinApp CLI 0.7+ — SDK-native project packaging, Native AOT, certificates, self-contained deployment, CI/CD, and Microsoft Store handoff. Use when preparing for release, creating MSIX installers, managing certificates, setting up CI/CD packaging, or publishing to the Microsoft Store."
---

Requires **WinApp CLI 0.7+**. For analyzer setup, see [winui-dev-workflow](../winui-dev-workflow/SKILL.md).
Requires **WinApp CLI 0.7+**. For analyzer setup, see `winui-dev-workflow`.

### Quick Reference

Expand All @@ -23,7 +23,7 @@ Requires **WinApp CLI 0.7+**. For analyzer setup, see [winui-dev-workflow](../wi
- Pass the **explicit project file**, not `.` or a guessed `bin` folder. WinUI project packaging uses SDK-native `dotnet publish` packaging, defaults to **Release**, and preserves project AOT settings.
- Check manifest identity, target architectures, the SDK for the app's TFM, and release warnings.
- For Native AOT, set `<PublishAot>true</PublishAot>` in the project and fix IL/CsWinRT warnings; there is **no `winapp package --aot`**. AOT also needs the MSVC C++ build tools. See [source-generator patterns](references/sourcegen-patterns.md).
- Project packaging rejects `WindowsPackageType=None`; restore the packaged setting first (see [winui-dev-workflow](../winui-dev-workflow/SKILL.md) Critical Rules).
- Project packaging rejects `WindowsPackageType=None`; restore the packaged setting first (see `winui-dev-workflow` Critical Rules).

Do **not** run/register/unregister a development package just to produce release artifacts. Project packaging builds without a development `winapp run --no-launch` step. For WinUI SDK-native packaging, do not pass layout overrides `--manifest`, `--executable`, or `--skip-pri`; fix the project/manifest instead.

Expand Down Expand Up @@ -55,7 +55,7 @@ winapp sign .\MyApp.msix .\prod.pfx --timestamp http://timestamp.digicert.com
`--timestamp` belongs to **`winapp sign`**, not `winapp package`. Use an approved timestamp service and protect the PFX/password.

#### Step 5: Install or Distribute
When installation/testing is part of the task, choose the target per [winui-ui-testing](../winui-ui-testing/SKILL.md) Step 1, and get consent for certificate trust and dependency provisioning on that machine. Packaging alone is not permission to install an app.
When installation/testing is part of the task, choose the target per `winui-ui-testing` Step 1, and get consent for certificate trust and dependency provisioning on that machine. Packaging alone is not permission to install an app.

### Self-Contained Does Not Mean Single-File

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Source Generator Patterns — Detailed Reference

Patterns for Native AOT and trimming in WinUI 3. See [SKILL.md](../SKILL.md) for project packaging and [winui-dev-workflow](../../winui-dev-workflow/SKILL.md) for analyzer setup and publish runs.
Patterns for Native AOT and trimming in WinUI 3. See [SKILL.md](../SKILL.md) for project packaging and `winui-dev-workflow` for analyzer setup and publish runs.

---

Expand Down
2 changes: 1 addition & 1 deletion plugins/winui/agent-plugin/skills/winui-setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ If the user declines or dismisses UAC, continue to the summary and print the com

Report these separately from the base toolchain. `winapp target snapshot sandbox --json` inspects an existing
guest without starting or repairing it; "no target running" alone does not
mean the Windows feature is unavailable. [winui-ui-testing](../winui-ui-testing/SKILL.md)
mean the Windows feature is unavailable. `winui-ui-testing`
Step 1 defines what to do when Windows Sandbox is unavailable.

Enabling Windows Sandbox is a **user action** (admin plus a reboot): ask the user
Expand Down
4 changes: 2 additions & 2 deletions plugins/winui/agent-plugin/skills/winui-ui-testing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: "Automated UI testing for Windows desktop apps — generate a batch

Windows Sandbox keeps synthetic input off the user's desktop; target selection is in Step 1. Discover the installed contract with `winapp run --help`, `winapp target --help`, and `winapp ui <verb> --help`. Use `--on sandbox`, not `--sandbox` or a top-level `sandbox` command. Do not enable Windows features or launch an app without the task's permission.

- Prerequisites and enablement: see [winui-setup](../winui-setup/SKILL.md).
- Prerequisites and enablement: see `winui-setup`.
- Project builds/publishes execute on the **host**; deployment, app launch, and `ui --on sandbox` execute in the **guest**. Run the batch script below on the host, not inside `target exec` (which would double-route).
- Real input and capture require an unlocked host and a connected, nonminimized Sandbox client. Tree inspection may work while input cannot; a readable tree is not an input-readiness check.
- `winapp target snapshot sandbox --json` is a read-only readiness query: it neither starts nor reconnects a guest. Use it to diagnose readiness rather than probing the user's desktop.
Expand All @@ -24,7 +24,7 @@ Core verbs: `list-windows`, `inspect`, `search`, `get-property`, `get-value`, `w

### Step 1: Select a target, then keep the PID and target together

Prefer `sandbox` when Windows Sandbox is available; otherwise tell the user and choose `local`. **If the user explicitly requested Windows Sandbox and it is unavailable, stop** and point them to the enablement steps in [winui-setup](../winui-setup/SKILL.md). A stopped guest does not prove unavailability: `target snapshot` can report no running target while the feature is enabled. App build/test failures are not Sandbox unavailability. The same policy applies to diagnostics: unpackaged apps can't use guest `--debug-output`, so diagnose them locally unless Sandbox was explicitly requested.
Prefer `sandbox` when Windows Sandbox is available; otherwise tell the user and choose `local`. **If the user explicitly requested Windows Sandbox and it is unavailable, stop** and point them to the enablement steps in `winui-setup`. A stopped guest does not prove unavailability: `target snapshot` can report no running target while the feature is enabled. App build/test failures are not Sandbox unavailability. The same policy applies to diagnostics: unpackaged apps can't use guest `--debug-output`, so diagnose them locally unless Sandbox was explicitly requested.

Pass the selected target to the template: it launches with `winapp run . --on sandbox --detach --json` for a guest, or omits `--on sandbox` for local execution. Reuse an already-running app only when its captured target matches the selected target and the guest has not been recreated. Never pass a guest PID to default-host `winapp ui`. If a target becomes unavailable after selection, report it and select again under the same policy; the script itself never retries in another target.

Expand Down
12 changes: 6 additions & 6 deletions plugins/winui/agent-plugin/skills/winui-wpf-migration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "Migrate WPF applications to WinUI 3 — namespace replacement (Sys

### Migration Process

Use the **WinApp CLI 0.7+** prerequisites and per-app analyzer setup in [winui-dev-workflow](../winui-dev-workflow/SKILL.md). The normal SDK path needs .NET 8.0.100 or later **and** the SDK required by the target TFM; Native AOT additionally needs MSVC/Desktop C++ tools. Handle missing prerequisites as described there.
Use the **WinApp CLI 0.7+** prerequisites and per-app analyzer setup in `winui-dev-workflow`. The normal SDK path needs .NET 8.0.100 or later **and** the SDK required by the target TFM; Native AOT additionally needs MSVC/Desktop C++ tools. Handle missing prerequisites as described there.

#### Step 1: Audit the WPF Source
Before writing code, inventory WPF-specific APIs:
Expand All @@ -19,15 +19,15 @@ List: WPF controls used, custom MVVM framework, imaging APIs, threading patterns
```powershell
winapp new --name <AppName> --template winui-mvvm --template-version latest --use-defaults
```
Immediately set `<RootNamespace>` in `.csproj` to match the WPF namespace. Update `x:Class` in `App.xaml`, `MainWindow.xaml` and their code-behind files. Add the analyzer per [winui-dev-workflow](../winui-dev-workflow/SKILL.md). Build to verify before porting any code.
Immediately set `<RootNamespace>` in `.csproj` to match the WPF namespace. Update `x:Class` in `App.xaml`, `MainWindow.xaml` and their code-behind files. Add the analyzer per `winui-dev-workflow`. Build to verify before porting any code.

Before implementing API replacements, restore the app project and check its exact references from the WinUI project directory, not the old WPF project or machine SDK:
```powershell
winapp find-api DispatcherQueue --json --project-dir .
winapp find-api members DispatcherQueue --filter TryEnqueue --json --project-dir .
winapp find-api check-property ListView ItemsSource SelectionMode --json --project-dir .
```
Use `winapp find-ui "<intent>"` for usage samples; see [winui-design](../winui-design/SKILL.md) for project selection and batch API checks.
Use `winapp find-ui "<intent>"` for usage samples; see `winui-design` for project selection and batch API checks.

#### Step 3: Replace Namespaces

Expand Down Expand Up @@ -74,7 +74,7 @@ Get via `DispatcherQueue.GetForCurrentThread()`. No `Application.Current.Dispatc
Delete custom `ObservableObject`/`RelayCommand`/`DelegateCommand`. Use CommunityToolkit.Mvvm:
- `INotifyPropertyChanged` base → `ObservableObject` with `[ObservableProperty]` partial properties (fix MVVMTK0045; don't keep fields)
- Custom `RelayCommand` → `[RelayCommand]` attribute
- Prefer `{x:Bind}` for known types; keep runtime `{Binding}`/`DisplayMemberPath` where needed. See [source-generator patterns](../winui-packaging/references/sourcegen-patterns.md) for binding modes, `x:DataType`, and AOT-safe runtime binding.
- Prefer `{x:Bind}` for known types; keep runtime `{Binding}`/`DisplayMemberPath` where needed. See `winui-packaging`'s `references/sourcegen-patterns.md` for binding modes, `x:DataType`, and AOT-safe runtime binding.
- `DynamicResource` → `{ThemeResource}`

#### Step 8: Replace Resources
Expand All @@ -86,7 +86,7 @@ Delete custom `ObservableObject`/`RelayCommand`/`DelegateCommand`. Use Community

- ❌ NEVER reference `PresentationCore`, `PresentationFramework`, or `System.Windows.Controls` assemblies
- ❌ NEVER add `<UseWPF>true</UseWPF>`
- Keep packaged as the default; see [winui-dev-workflow](../winui-dev-workflow/SKILL.md) Critical Rules for unpackaged experiments.
- Keep packaged as the default; see `winui-dev-workflow` Critical Rules for unpackaged experiments.
- ❌ NEVER delete `Package.appxmanifest`
- ❌ NEVER overwrite `App.xaml` / `App.xaml.cs` — merge WPF code into the WinUI 3 boilerplate
- ✅ Launch with project-mode `winapp run`, not the .exe directly.
Expand All @@ -108,4 +108,4 @@ dotnet build .\MyApp.csproj -p:Platform=x64
winapp run .\MyApp.csproj --detach --json
```

For UI validation, see [winui-ui-testing](../winui-ui-testing/SKILL.md); for crash diagnostics, see [winui-dev-workflow](../winui-dev-workflow/SKILL.md). If AOT is intended, also test the published artifact via the workflow's AOT path; the run above is JIT, even in Release.
For UI validation, see `winui-ui-testing`; for crash diagnostics, see `winui-dev-workflow`. If AOT is intended, also test the published artifact via the workflow's AOT path; the run above is JIT, even in Release.
Loading