Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
05adb74
Use the Windows App SDK dotnet new templates instead of ours
Copilot Aug 26, 2026
92c2820
Merge origin/main into winappsdk-template-migration
Copilot Sep 17, 2026
b3f9e17
Merge remote-tracking branch 'origin/main' into azchohfi-winappsdk-te…
Copilot Sep 22, 2026
55cc443
fix(cli): report what `mur templates install` actually did
Copilot Sep 23, 2026
9170280
Merge remote-tracking branch 'origin/main' into azchohfi-winappsdk-te…
Copilot Sep 23, 2026
66a64cf
Remove the in-repo dotnet new template package
Copilot Sep 23, 2026
faeeace
Address PR-review findings on the template migration
Copilot Sep 24, 2026
2564f6a
Address Copilot review round 1
Copilot Sep 24, 2026
6f0e971
Harden template detection and credential redaction
azchohfi Sep 24, 2026
696b8b5
Require --source to be a local folder, and fix the CI template guard
azchohfi Sep 24, 2026
1fef63a
Address code-quality findings on the template migration
azchohfi Sep 24, 2026
7dd5346
Restore packaging.md to the solid doc tier
azchohfi Sep 24, 2026
dcf855a
Resolve template versions through the configured feed
azchohfi Sep 24, 2026
a8cdef8
Use Path.Join in the touched test files
azchohfi Sep 24, 2026
08f7137
Validate the version feed, and derive one from an explicit NuGet config
azchohfi Sep 24, 2026
f79ec5e
Filter the service-index resources with Where
azchohfi Sep 24, 2026
58171c7
Revalidate the advertised base address, and test the config feed extr…
azchohfi Sep 24, 2026
becbdf9
Express the service-index scan as a LINQ pipeline
azchohfi Sep 24, 2026
0229ccf
Isolate the scaffolded TestApp from the repo's build rules
azchohfi Sep 24, 2026
44c94f2
Enforce the feed policy across redirects, and stop reporting unusable…
azchohfi Sep 24, 2026
cec8d7d
Mask file-URI query/fragment, cover the install parser, and honour --…
azchohfi Sep 24, 2026
e4bae82
Dispose the stub handler's responses
azchohfi Sep 24, 2026
e7e9de9
Resolve a relative --templates-source against the caller's CWD
azchohfi Sep 24, 2026
bb7163d
Drain both pipes concurrently in RunCapture
azchohfi Sep 24, 2026
a3f3ec0
Mask credentials in URL-like sources that Uri refuses to parse
azchohfi Sep 24, 2026
fbc10d3
State the ShortNames contract, and ground the parser fixtures in the …
azchohfi Sep 24, 2026
c986e1c
Distinguish "installed but unusable" from "install failed"
azchohfi Sep 24, 2026
1038285
Separate the three `mur templates status` failure modes
azchohfi Sep 24, 2026
7c997f4
Pass the configured mirror to the install, not only to version resolu…
azchohfi Sep 24, 2026
3eda953
Keep the mirror out of a local-source install, and match package ids …
azchohfi Sep 24, 2026
be43db8
Replace the constant-condition switch in StatusExitCode
azchohfi Sep 24, 2026
3905500
Install the nupkg itself when --source names a local folder
azchohfi Sep 24, 2026
6bf580c
Retire `mur templates install` in favour of `winapp new`
azchohfi Sep 24, 2026
9916f1e
Fix fallout from retiring the in-repo template installer
azchohfi Sep 24, 2026
03febcf
Restore packaged launch coverage, and fix three migration leftovers
azchohfi Sep 25, 2026
eb16253
Resolve the packaged app by its real identity, and bound the version …
azchohfi Sep 25, 2026
af36a30
Merge origin/main into azchohfi-winappsdk-template-migration
azchohfi Sep 25, 2026
bf9e92d
Assert the scaffolded app actually renders, and fix the packaging goal
azchohfi Sep 25, 2026
713984a
Match the template pack id by line in the bootstrap CI guard
azchohfi Sep 25, 2026
580b789
Resolve winapp in the CI UI assertion too
azchohfi Sep 25, 2026
45e0302
Tear down the smoke app on every failure path
azchohfi Sep 25, 2026
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
206 changes: 179 additions & 27 deletions .github/workflows/bootstrap.yml

Large diffs are not rendered by default.

19 changes: 2 additions & 17 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ jobs:

- name: Pack Devtools NuGet
# Microsoft.UI.Reactor.Devtools is referenced by the scaffolded
# `dotnet new reactorapp` csproj's Debug-only ItemGroup (the devtools menu + the
# `dotnet new reactor` csproj's Debug-only ItemGroup (the devtools menu + the
# Reactor Visual Studio embedded-preview extension both need it). Ship it alongside
# the framework so the template's restore succeeds against the published feed.
# Version is locked to the framework version (spec 022). Packs from the AnyCPU
Expand All @@ -201,21 +201,6 @@ jobs:
-p:Version=${{ steps.version.outputs.version }}
-o artifacts/nupkg

- name: Pack Templates
# MicrosoftUIReactorVersion stamps the framework version that generated
# apps reference (baked into template.json by the csproj's BeforePack
# target). Lock it to the version published in this same run so the
# template can never drift behind the framework — same value used for
# the framework/Advanced/Devtools packs above. Without this it silently
# falls back to the csproj's local-dev default.
run: >
dotnet pack tools\Templates\Microsoft.UI.Reactor.Templates.csproj
--no-build --configuration Release
-p:Version=${{ steps.version.outputs.version }}
-p:MicrosoftUIReactorVersion=${{ steps.version.outputs.version }}
-p:Platform=AnyCPU
-o artifacts/nupkg

- name: Build VSIX
shell: pwsh
run: |
Expand Down Expand Up @@ -381,7 +366,7 @@ jobs:

### `Microsoft.UI.Reactor.Devtools.${{ steps.version.outputs.version }}.nupkg` — optional devtools host (debug + VS preview)

Referenced by the scaffolded `dotnet new reactorapp` csproj in a
Referenced by the scaffolded `dotnet new reactor` csproj in a
Debug-only `ItemGroup`, paired with `RuntimeHostConfigurationOption
Reactor.DevtoolsSupport=true`. Required to light up the right-click
devtools menu in Debug F5 launches and for the Reactor VS embedded
Expand Down
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ Conventions for contributors:
shape acts as a positive control, so a broken probe is reported as unverified rather than
blamed on the deployment. (issue #1268)

- **`mur templates status`** reports whether `dotnet new reactor` actually resolves, rather than
merely whether the template pack id is registered — an installed-but-too-old pack (`0.0.6-alpha`
shipped before the Reactor templates existed) is a PASS on the package check and a failure on the
next scaffold. Exit codes are load-bearing: `0` available, `1` probe failed, `2` pack installed
but too old, `3` pack not installed. It backs `mur doctor` and `bootstrap.ps1`'s verification
step, which give different remediation for each.

### Changed

- **The search index emits every clean `SampleCard` on a page, not just the first
Expand All @@ -65,8 +72,46 @@ Conventions for contributors:

### Deprecated

- **`Microsoft.UI.Reactor.ProjectTemplates` is deprecated on NuGet.org.** Published versions
remain restorable but are marked deprecated with a pointer to `dotnet new reactor`. Scaffold the
replacement with `winapp new -t reactor -n MyApp`, which installs the Windows App SDK template
pack on demand. To install the pack without scaffolding, pin it explicitly —
`dotnet new install Microsoft.WindowsAppSDK.WinUI.CSharp.Templates::<version>` — since it is
prerelease-only and a bare `dotnet new install` resolves stable versions.

### Removed

- **Removed the in-repo `Microsoft.UI.Reactor.ProjectTemplates` package and its
`dotnet new reactorapp` template** (`tools/Templates/`). Reactor's project templates now ship in
the official Windows App SDK `dotnet new` pack
([`Microsoft.WindowsAppSDK.WinUI.CSharp.Templates`](https://www.nuget.org/packages/Microsoft.WindowsAppSDK.WinUI.CSharp.Templates)
`0.0.7-alpha` and later), which provides `reactor`, `reactor-mvu`, `reactor-navview`, and
`reactor-tabview` (microsoft/WindowsAppSDK#6620, microsoft/WindowsAppSDK#6786).

**Behaviour change:** scaffolded apps are now **packaged** (single-project MSIX) rather than
unpackaged, so `dotnet run` launches with full package identity and requires Developer Mode.
No template produces the unpackaged shape any more — scaffold with `dotnet new reactor` and set
`<WindowsPackageType>None</WindowsPackageType>` yourself (see the packaging guide).

`mur pack-local` no longer produces a templates nupkg and its `--framework-version` flag is
gone; the release workflow no longer packs or publishes the package.

- **Removed `mur templates install`.** Installing the Windows App SDK template pack is the
Windows App SDK CLI's job: `winapp new -t reactor -n MyApp` installs the pack on demand and
scaffolds in one step, and `winapp new --list` installs it without scaffolding. `bootstrap.ps1`
now drives that command, and `mur upgrade` reports on the templates instead of installing them.
`mur templates status` (see Added) still backs `mur doctor` and bootstrap's verification.

Reactor carried its own installer because `dotnet new install` has no `--prerelease` switch and
resolves stable-only, which fails outright while the pack is prerelease-only; working around
that meant resolving versions off the NuGet flat container and tiptoeing around
`dotnet new install --force`, which uninstalls the existing pack *before* downloading the
replacement. `winapp` handles all of it, so roughly 700 lines of that machinery are gone.

The `-WinAppSdkTemplatesSource` bootstrap parameter is removed with it — `winapp` has no
local-folder equivalent. `-WinAppSdkTemplatesVersion` still works and now maps to
`winapp new --template-version`.

### Fixed

- **Wrong code and guidance in the shipped agent-kit skills (spec 064 §4, issue
Expand Down
10 changes: 3 additions & 7 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,8 @@
<!--
Single source of truth for the current PUBLIC Microsoft.UI.Reactor package
version. This is the ONE literal to bump at release time (see
docs/contributing/release-runbook.md). Two consumers read it:
1. tools/Templates/Microsoft.UI.Reactor.Templates.csproj — the
MicrosoftUIReactorVersion fallback default derives from it via
$(ReactorPublicVersion), so a scaffolded app's fallback framework
reference and the docs can never disagree.
2. `mur docs compile` (VersionSource.ReadPublicVersion) substitutes it
docs/contributing/release-runbook.md). One consumer reads it:
1. `mur docs compile` (VersionSource.ReadPublicVersion) substitutes it
for the {{reactorVersion}} token in docs/_pipeline/templates/*.md.dt,
so guide prose needs no per-release hand edits.
Keep it a real PUBLISHED public version. Every release is a prerelease, so
Expand Down Expand Up @@ -82,7 +78,7 @@
fails with HTTP 400 at publish time, AFTER earlier packages in the same
push loop have already gone out (the loop is not atomic). Centralizing the
defaults here guarantees every current and future package id (framework,
Advanced, Devtools, ProjectTemplates, …) inherits compliant metadata, so a
Advanced, Devtools, …) inherits compliant metadata, so a
new package can never silently ship without it. Individual csprojs may still
override (the '== '' guard makes these defaults, not forced values).
-->
Expand Down
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,22 @@ Many of the experiments in this repo — the charting stack, accessibility valid

## Quick start

Reactor ships the public preview package [`Microsoft.UI.Reactor`](https://www.nuget.org/packages/Microsoft.UI.Reactor) on NuGet.org; see the [NuGet page](https://www.nuget.org/packages/Microsoft.UI.Reactor) or [GitHub Releases](https://github.com/microsoft/microsoft-ui-reactor/releases) for the current version. The project template is still installed from source for now; `bootstrap.ps1` installs the `mur` CLI, packs/registers the local `reactorapp` template, and that template references the public preview package by default.
Reactor ships the public preview package [`Microsoft.UI.Reactor`](https://www.nuget.org/packages/Microsoft.UI.Reactor) on NuGet.org; see the [NuGet page](https://www.nuget.org/packages/Microsoft.UI.Reactor) or [GitHub Releases](https://github.com/microsoft/microsoft-ui-reactor/releases) for the current version. The project templates ship in the official Windows App SDK `dotnet new` pack, so building an app needs no source checkout:

```powershell
# `winapp` is the Windows App SDK CLI; `winapp new` installs the template pack
# on demand, so there's no separate install step and no version to pin.
winget install Microsoft.WinAppCli
winapp new -t reactor -n MyApp
cd MyApp
dotnet run
```

Scaffolded apps are packaged (single-project MSIX), so `dotnet run` launches them with full package identity — the F5 equivalent. `reactor-mvu`, `reactor-navview`, and `reactor-tabview` start from richer shells (`winapp new --list` prints them all). Requires Developer Mode (Settings → System → For developers).

Prefer plain .NET tooling? `dotnet new install Microsoft.WindowsAppSDK.WinUI.CSharp.Templates::<version>` followed by `dotnet new reactor -n MyApp` does the same thing. The pack is prerelease-only today and `dotnet new install` resolves stable versions unless you pin one explicitly, which is the step `winapp new` removes.

### Contributing to Reactor itself

```powershell
git clone https://github.com/microsoft/microsoft-ui-reactor.git
Expand All @@ -78,7 +93,7 @@ cd microsoft-ui-reactor
# calling the bootstrap system under the correct PowerShell version you're on
& (Get-Process -Id $PID).Path -ExecutionPolicy Bypass -File .\bootstrap.ps1

dotnet new reactorapp -n MyApp
dotnet new reactor -n MyApp
cd MyApp
dotnet run -p:Platform=x64
```
Expand All @@ -97,7 +112,9 @@ dotnet run -p:Platform=x64
> causes `WindowsAppSDKSelfContained` errors. This applies to `dotnet build`,
> `dotnet run`, and `mur check` invocations alike.

`bootstrap.ps1` packs `mur` as a `dotnet tool` global install (cross-shell PATH, no per-arch `$env:Path` edits), packs local framework snapshots plus project templates into `local-nupkgs/`, registers the `dotnet new reactorapp` template, and installs the Reactor agent plugin under `~/.claude/plugins/reactor`. Apps created by the template reference the public `Microsoft.UI.Reactor` package from NuGet.org by default; pass `--MSUIReactorVersion 0.0.0-local` when you intentionally want a scaffolded app to consume the local source-built package instead. The optional `Microsoft.UI.Reactor.Advanced` and `Microsoft.UI.Reactor.Devtools` sibling packages are version-matched to the framework package when published. Re-run `bootstrap.ps1` (or `mur upgrade` for a lighter refresh) after `git pull` when you want updated local templates or CLI/plugin bits. Verify a working developer install with `mur doctor`.
`bootstrap.ps1` packs `mur` as a `dotnet tool` global install (cross-shell PATH, no per-arch `$env:Path` edits), packs local framework snapshots into `local-nupkgs/`, installs the Windows App SDK `dotnet new` template pack via the Windows App SDK CLI (`winapp new --list`, which provides `dotnet new reactor`), and installs the Reactor agent plugin under `~/.claude/plugins/reactor`. Apps created by the template reference the public `Microsoft.UI.Reactor` package from NuGet.org by default; pass `--reactor-version 0.0.0-local` when you intentionally want a scaffolded app to consume the local source-built package instead. To hold the template pack at a known-good version, run `./bootstrap.ps1 -WinAppSdkTemplatesVersion <version>`. The optional `Microsoft.UI.Reactor.Advanced` and `Microsoft.UI.Reactor.Devtools` sibling packages are version-matched to the framework package when published. Re-run `bootstrap.ps1` (or `mur upgrade` for a lighter refresh) after `git pull` when you want updated CLI/plugin bits. Verify a working developer install with `mur doctor`.

> **Scaffolding.** Reactor's templates ship in the official Windows App SDK template pack. `winapp new -t reactor` installs that pack on demand and scaffolds in one step; `dotnet new reactor` works too once the pack is installed. The in-repo `Microsoft.UI.Reactor.ProjectTemplates` package that used to provide `dotnet new reactorapp` has been removed; its published versions are deprecated on NuGet.org.

On networks where the public npm or NuGet registries are unreachable, bootstrap detects a recognised package mirror already configured in the user's `~/.npmrc` and NuGet.Config, verifies unauthenticated package access, and uses it only for the bootstrap process — including the optional Visual Studio extension build. Contributors on an unrestricted network keep the public defaults, unchanged. Any mirror can be selected explicitly with `-NpmRegistry <url>` and `-NuGetConfig <path>`; credentials remain in user configuration and are never written to the repository. Package feed URLs must use HTTPS (except loopback development feeds) and cannot embed credentials, query strings, or fragments. The npm mirror must permit direct package downloads because the Copilot SDK's MSBuild download task cannot forward npm credentials.

Expand Down
3 changes: 0 additions & 3 deletions Reactor.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -494,9 +494,6 @@
<Platform Solution="*|x64" Project="x64" />
</Project>
</Folder>
<Folder Name="/tools/Templates/">
<Project Path="tools/Templates/Microsoft.UI.Reactor.Templates.csproj" />
</Folder>
<Project Path="src/Reactor.Analyzers/Reactor.Analyzers.csproj" />
<Project Path="src/Reactor.Analyzers.Internal/Reactor.Analyzers.Internal.csproj" />
<Project Path="src/Reactor.Compile.Analyzer/Reactor.Compile.Analyzer.csproj" />
Expand Down
25 changes: 17 additions & 8 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,19 +217,25 @@ In selfhost the version is `0.0.0-local` (produced by `mur pack-local` —
see "Which mode are you in?" above). Outside the source clone, replace it
with whatever Microsoft.UI.Reactor version you depend on.

**After `dotnet new reactorapp -n <Name>`, the workspace contains
exactly two source files: `App.cs` (entry point + initial component)
and `<Name>.csproj`.** There is no `Program.cs` and no
`GlobalUsings.cs` — modify `App.cs` in place. The `.csproj` does
**not** enable implicit usings; `App.cs` has its own `using`
directives at the top — the canonical set (System + Reactor +
**After `dotnet new reactor -n <Name>`, the entry point is `App.cs`**
(entry point + initial component), next to `<Name>.csproj`. The template
also emits packaging scaffolding you normally don't touch:
`Package.appxmanifest`, `app.manifest`, `Assets/`, and
`Properties/launchSettings.json` + `Properties/PublishProfiles/`. There is no
`Program.cs` and no `GlobalUsings.cs` — modify `App.cs` in place. `App.cs` has
its own `using` directives at the top — the canonical set (System + Reactor +
Reactor.Core + Reactor.Layout + Xaml + Xaml.Controls + static
Factories) — which is the only place you add new namespaces (e.g. `using System.Linq;` when
you reach for `.Select(...)`). Don't probe the `.csproj` after
scaffolding unless you're adding a `PackageReference` or changing a
property — `Restore succeeded.` in the scaffold stdout is the only
confirmation you need.

Apps from `dotnet new reactor` are **packaged** (single-project MSIX), so
`dotnet run` launches them with package identity and needs Developer Mode on.
The other short names are `reactor-mvu`, `reactor-navview`, and
`reactor-tabview`.

**Verify your edits with `mur check`** before declaring done. From the
project directory: `mur check` (no arguments) runs `dotnet build` and
emits one compressed line per diagnostic with a `→ try:` suggestion
Expand Down Expand Up @@ -258,8 +264,11 @@ next to it pointing at the clone's `local-nupkgs/` (absolute path):
Inside the clone you don't need this — the repo-level `nuget.config`
already configures the feed.

`WindowsPackageType` MUST be `None` (unpackaged, no App.xaml). `UseWinUI`
MUST be `true`. No XAML files of any kind.
For a **hand-authored** csproj like the one above, `WindowsPackageType` MUST be
`None` (unpackaged, no App.xaml) and `UseWinUI` MUST be `true`. Apps scaffolded
by `dotnet new reactor` are packaged instead and omit `WindowsPackageType`
entirely — leave their packaging properties alone. Either way: no XAML files of
any kind.

### Required imports

Expand Down
Loading
Loading