Repository navigation
Stop tracking generated command wrappers and schema snapshots - #997
Conversation
Generate wrappers before standalone npm compile, watch, test, and docs commands. Preserve explicit schema generation in integrated builds and keep the published JavaScript and declarations unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The generation and packaging paths are consistent, and targeted Pester and npm test suites pass.
Review effort: Balanced
Findings: None
What changed in this PR
Stops tracking generated npm command wrappers while preserving generation, compilation, testing, documentation, and packaging workflows.
Changes:
- Adds automatic wrapper generation to standalone npm commands.
- Preserves explicit schemas during integrated builds.
- Adds regression tests and Node 18-compatible path resolution.
| File | Description |
|---|---|
src/winapp-npm/src/winapp-commands.ts |
Removes generated wrappers from version control. |
src/winapp-npm/scripts/generate-commands.mjs |
Uses Node 18-compatible directory resolution. |
src/winapp-npm/package.json |
Adds generation hooks and integrated-build bypasses. |
src/winapp-npm/.gitignore |
Ignores generated wrapper source. |
scripts/tests/npm-codegen.Tests.ps1 |
Tests fresh generation and failure handling. |
scripts/tests/build-cli.Tests.ps1 |
Verifies explicit schemas remain preserved. |
scripts/tests/artifact-workflow.Tests.ps1 |
Checks packaging compilation bypasses hooks. |
scripts/package-npm.ps1 |
Compiles without rerunning generation. |
scripts/build-cli.ps1 |
Prevents lifecycle hooks replacing live-schema output. |
AGENTS.md |
Documents the new generated-source workflow. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Build Metrics ReportValidation passed. All required build and validation jobs succeeded. Binary Sizes
.NET Test Results (TRX reports)Other suites are reflected in the overall validation status above. ✅ 8062 passed, 37 skipped out of 8099 tests in 1219.9s (-18.0s vs. baseline) Test Coverage✅ 86.4% line coverage, 81% branch coverage · ✅ no change vs. baseline CLI Startup Time51ms median (x64, Try This BuildInstalls the MSIX for your architecture, replacing any previously installed build. Needs the GitHub CLI — the command offers to install it and sign you in if it is missing. & ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) 997Switching between builds often?Put the tool on your PATH once: & ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) -AddToPathThen this build is just: winapp-pr 997Run Updated 2026-10-07 01:24:53 UTC · commit |
Preserve removal of generated command wrappers; retain current command changes in the schema and generator. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use live CLI schemas for npm generation and validation, and maintain the npm API guide by hand. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> # Conflicts: # AGENTS.md
Resolve conflicts with main: - Accept main's removal of generated docs/cli-schema.json, src/winapp-npm/src/winapp-commands.ts and generate-docs.mjs (microsoft#997); perf wrappers are now generated at build time from the branch's generate-commands.mjs changes. - Take main's rewritten npm guide and document the perfAnalyze json partial-result exception there. - Keep main's root command description and help groups, adding the perf command and a Performance help group. - Keep both sets of NativeMethods entries. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
## Description
`winapp run` only built `.csproj` projects. Pointing it at a Visual
Studio C++ project failed, because the .NET SDK has no C++ project
system.
Now `winapp run` accepts:
- a `.vcxproj`,
- a folder whose only runnable app is a `.vcxproj` (C# libraries or test
projects beside it don't get in the way),
- a `.sln`/`.slnx` whose only runnable app is a `.vcxproj`. If the
solution also has a runnable C# app, the C# app is still picked (C# test
projects don't outrank a C++ app); `--project <name>` selects the C++
one.
winapp finds Visual Studio's `MSBuild.exe` with `vswhere` (VS/Build
Tools 2022 17.8+, the first with `-getProperty`, with the MSVC tools for
the target architecture; for a WinUI/UWP project, the newest install
whose MSBuild has the "Windows Store" C++ application type), restores
`packages.config`, builds, reads `OutDir`/`TargetPath`/AppX properties,
and then uses the existing packaged (loose-layout register + AUMID) or
unpackaged (launch `TargetPath`) path. `-c`, `--arch` (→
`x64`/`ARM64`/`Win32`; `-p Platform=ARM64` also selects the architecture
when `--arch` isn't given), `-p`, `--no-build`, `--no-restore`,
`--detach` and `--json` work as for `.csproj`. The Windows App Runtime
version comes from `packages.config`. C++ inputs don't need the .NET
SDK. `--aot` and `--framework` are rejected as .NET-only.
Build output is quiet: MSBuild runs at quiet verbosity (warnings and
errors only), with a spinner and elapsed time in a real terminal, and a
short command echo. `--verbose` shows MSBuild's full output and the
exact command. (C++/WinRT logs ~500 lines on a first build at
`minimal`.)
Before registering a packaged layout, winapp now also installs framework
packages the build's `.appxrecipe` resolved and the manifest depends on,
when missing or older — as Visual Studio's deploy does. C++ Debug apps
depend on `Microsoft.VCLibs.140.00.Debug.UWPDesktop`; without it,
registration on a clean machine (CI) failed with `0x80073CF3`.
Self-contained apps are unaffected (their manifest has no runtime
dependency). Package locations on network shares or mapped network
drives are ignored without being probed, so a crafted recipe can't make
winapp authenticate to a remote host.
A C# app that references a C++ project (e.g. a native DLL, transitively
and including `ReferenceOutputAssembly="false"` references) still can't
be built by `dotnet` (`MSB4278`). winapp now detects it before restoring
and says what works instead of surfacing the raw error. Conditional
references (e.g. a Visual Studio-only native reference) are ignored,
since dotnet skips them. `winapp package` suggests packaging the MSBuild
output folder instead of `--no-build`, because `dotnet publish
--no-build` still loads the C++ reference.
```text
> winapp run App.csproj # App.csproj -> Native.vcxproj (C++ DLL)
❌ 'App.csproj' references the C++ project 'Native.vcxproj', which dotnet can't build. Build it with Visual Studio or MSBuild.exe (Visual Studio or Build Tools 2022 17.8+ with the "Desktop development with C++" workload), then re-run this command with --no-build.
> MSBuild.exe App.csproj -restore -p:Platform=x64 ; winapp run App.csproj --no-build
Native Add(2,3) = 5
```
Before this PR the same command printed only `error MSB4278: The
imported file "$(VCTargetsPath)\Microsoft.Cpp.Default.props" does not
exist ...`.
Missing prerequisites produce actionable errors: no VS/Build Tools or no
C++ tools (with a `winget` command for Build Tools), and build failures
caused by a missing platform toolset (`MSB8020`) or Windows SDK
(`MSB8036`).
`ProjectRunResolution` now carries the evaluated `Configuration` and
`Platform` alongside the existing
`TargetDir`/`AppxRecipePath`/`AppxManifestPath`, so later work (e.g.
DevTools XAML source mapping) can locate C++ build artifacts the same
way it does for `.csproj`.
New sample `samples/cpp-winui-app`: the Visual Studio **WinUI Blank App
(Packaged)** C++/WinRT template (XAML UI, `packages.config`, WinAppSDK
2.3.1) with a button that shows the package identity, plus a Pester test
and CI matrix entry.
## Usage Example
Observed on this machine (VS 2026 Enterprise, x64). Before:
```text
> winapp run CppWinUIApp.vcxproj
❌ '...\CppWinUIApp.vcxproj' is not a runnable input. Pass a .cs file-based app, a .csproj, a .sln/.slnx solution, a directory containing one, or a build-output folder.
> winapp run . --json
{ "Error": "The manifest contains a placeholder for the executable but no .exe files were found in the input folder. ..." }
```
After (sample folder):
```text
> winapp run . --detach
🔎 CppWinUIApp.vcxproj · Debug | x64 · CppWinUIApp.slnx (only runnable project)
🔧 Building CppWinUIApp.vcxproj (Debug | x64)...
MSBuild.exe CppWinUIApp.vcxproj -restore -p:Configuration=Debug -p:Platform=x64
⠋ MSBuild is running... 28s ← transient spinner, replaced by the next line
✅ Built CppWinUIApp in 85.6s
✅ cpp-winui-app-sample_md30f2v49kz6j launched (PID: 13892)
> winapp run CppWinUIApp.vcxproj --detach --json # incremental, 10s
{ "AUMID": "cpp-winui-app-sample_md30f2v49kz6j!App", "ProcessId": 476 }
> winapp run . --no-build --detach # 4s, no MSBuild build
✅ cpp-winui-app-sample_md30f2v49kz6j launched (PID: 27208)
```
The launched app's XAML UI works with identity (via `winapp ui`, no real
input):
```text
> winapp ui invoke "Show package identity" -a 37880
Invoked btn-identitybutton-6f2e via InvokePattern
> winapp ui search "Package family name" -a 37880
IdentityText Text "Package family name: cpp-winui-app-sample_md30f2v49kz6j"
```
Missing prerequisites (VS hidden by pointing `%ProgramFiles(x86)%`
elsewhere; toolset/SDK via `-p`):
```text
> winapp run .
❌ Building a C++ project (.vcxproj) needs Visual Studio or Build Tools for Visual Studio 2022 version 17.8 or later with the MSVC C++ build tools for x64, but no Visual Studio or Build Tools for Visual Studio installation was found.
- Install Visual Studio with the "Desktop development with C++" workload. WinUI 3 apps also need the "WinUI application development" workload with "C++ WinUI app development tools".
- Or install Build Tools for Visual Studio: winget install Microsoft.VisualStudio.BuildTools --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.ComponentGroup.UWP.VC.BuildTools --includeRecommended"
> winapp run . -p WindowsTargetPlatformVersion=10.0.99999.0
❌ Build failed for CppWinUIApp.vcxproj. The Windows SDK version this project targets is not installed (MSB8036). Install it with the Visual Studio Installer or winget (e.g. winget install Microsoft.WindowsSDK.10.0.26100), or build against an installed one with -p:WindowsTargetPlatformVersion=<version>.
> winapp run . -p PlatformToolset=v999 --json
{ "Error": "Build failed for CppWinUIApp.vcxproj. The C++ build tools (platform toolset) this project targets are not installed (MSB8020). ..." }
> winapp run . -p Platform=ARM64 --no-build # selects arm64
🔎 CppWinUIApp.vcxproj · Debug | arm64 · CppWinUIApp.slnx (only runnable project)
> winapp run . --arch x64 -p Platform=ARM64
❌ -p Platform targets arm64, but --arch/--runtime selects x64. Pass only one of them.
> winapp run . # folder with only a C++ DLL project
❌ NativeLib.vcxproj in '...\NativeLib' builds a library, not an app, so there is nothing to run. Run the app project that uses it, or pass a build-output folder that contains an app.
```
Unpackaged C++ console app (hand-written minimal `.vcxproj`):
```text
> winapp run . -- hello world
✅ Built HelloConsole in 1.5s
✅ No Windows App SDK reference — runtime not needed
✅ Launched HelloConsole (PID: 23904)
Hello from a C++ console app, 2 arg(s)
(exit code 7 propagated)
```
## Related Issue
Part of #680. Covers `.vcxproj` as the **entry** project. For a C# app
that references a C++ project, winapp now detects it and says what to
do; actually building that mix with MSBuild is a follow-up, as is the
NativeAOT-publish preflight from the issue comment.
## Type of Change
- ✨ New feature
## Checklist
- [x] New tests added for new functionality
(`ProjectRunServiceCppTests`: input resolution, MSBuild arguments,
packaging, prerequisite errors, vswhere discovery, packages.config,
recipe frameworks, C# → C++ reference detection)
- [x] Tested locally on Windows
- [x] Main [README.md](../README.md) updated
- [x] [docs/usage.md](../docs/usage.md) updated
- [x] [Language-specific guides](../docs/guides) updated (`cpp.md`
pointer)
- [x] [Sample projects updated](../samples) (new `cpp-winui-app` +
Pester test + CI matrix)
- [x] Shipped skills updated in `plugins/winapp/skills/`
(`winapp-setup`, `winapp-troubleshoot`)
## Screenshots / Demo
CLI change; textual output above.
## Additional Notes
**Validation (local):**
- `scripts\build-cli.ps1` (warnings-as-errors test build):
`WinApp.Cli.Tests` 7129 total, 0 failed. `WinApp.UIAutomation.Tests` had
1 failure,
`RecordAsync_FirstScreenFrame_AcceptsAModalDialogTheTargetOwns`, which
also fails when run alone on this shared desktop; this PR doesn't touch
UIAutomation. `validate-plugin-package.ps1` passes. After merging #997
(generated schema and npm wrappers are no longer tracked), this PR
changes no generated files. After review fixes:
`ProjectRunService*`/`RunCommand*`/`PackageCommand*`/`MsixService*`
tests 1144 total, 0 failed (WAE build).
- `samples\cpp-winui-app\test.Tests.ps1` with the locally built npm
package (isolated npm prefix): 4/4 passed — build + register + detached
launch with a visible window, `--no-build --no-launch`, missing-VS
error, and a plain MSBuild build of the sample.
- `scripts\tests\artifact-workflow.Tests.ps1`: 25/25.
- CI: `samples / cpp-winui-app` on `windows-latest` (VS 2022) failed
registration with `0x80073CF3` (missing
`Microsoft.VCLibs.140.00.Debug.UWPDesktop`) before the framework step
and passes 4/4 with it (the test runs `--json`, which hides the install
status line). Locally, the install path was exercised by raising the
recipe's VCLibs version: `📦 Installing framework package
Microsoft.VCLibs.140.00.Debug.UWPDesktop 14.0.99999.0...` followed by
successful registration.
- Mixed C# → C++ DLL project (hand-written): the new error above with
and without `--json`; after `MSBuild.exe` the `--no-build` run printed
`Native Add(2,3) = 5`.
**Limitations / observations:**
- The `winget` Build Tools command was not executed (multi-GB install on
a shared machine); its component IDs come from the Build Tools
workload/component reference.
- With VS 2026 (MSBuild 18.9) on this machine, the template's
`Microsoft.Windows.SDK.BuildTools.MSIX` task fails with `MSB4061` ("Type
must be a type provided by the runtime") when the project sits under a
long path (reproduced at ~157-char project dir; works from
`%TEMP%\cwa`). That's an MSBuild/MSIX tooling issue independent of
winapp — the same `msbuild` command fails the same way — so live runs
used a short path.
- Every scenario above was also captured in real Windows Terminal
windows; the quiet build, short command echo, `-p Platform` and
library-folder changes came from reviewing those screenshots.
---------
Co-authored-by: Nikola Metulev <711864+nmetulev@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Zach Teutsch <88554871+zateutsch@users.noreply.github.com>
Description
Remove the large generated files that repeatedly conflict when parallel PRs change CLI commands. Generated npm wrappers and CLI schemas are now ignored build outputs, and the npm API documentation becomes a maintained, task-oriented guide at the same URL.
Command definitions remain the source of truth. npm compilation, watch, and tests generate wrappers from an available CLI binary; with no binary, they build and run the Debug CLI using .NET. Integrated builds use their explicitly extracted live schema without rerunning those hooks. The published npm package still contains the generated JavaScript and TypeScript declarations; public CLI commands and npm APIs are unchanged.
The fast, build-free plugin check validates structure, frontmatter, and links. The existing Windows post-build documentation check validates command examples against the freshly built CLI. Builds no longer rewrite the npm guide, and schema-extraction failures fail the build instead of succeeding with a warning.
Usage Example
On Windows with Node and the .NET SDK installed:
Observed: with generated wrappers and both matching CLI binaries absent, npm built the Debug CLI, generated wrappers without a checked-in schema, and passed all 303 tests. Generated output stayed ignored.
For machine-readable definitions of the installed CLI, use:
The maintained npm guide teaches common tasks and how to discover the complete typed API in the installed package.
Related Issue
N/A.
Type of Change
Checklist
plugins/winapp/skills/(if CLI commands/workflows changed) — N/A: installed CLI workflows unchanged.Screenshots / Demo
N/A: nonvisual build and documentation changes; observed command behavior is described above.
Additional Notes
Fresh-checkout npm development requires Windows and the .NET SDK when no built CLI is available. Installing and using the published npm package does not acquire this requirement.
winapp --cli-schemaremains available; the repository JSON snapshot and generated documentation scripts are removed.Validation on Windows:
Invoke-Pester -Path .\scripts\tests— passed, 253/253 tests, with zero skipped or not run. Regressions cover generation without snapshots, failure propagation, build-free and live-schema plugin checks, documentation preservation, and retired schema links.src\winapp-npm,npm run lint,npm run format:check,npm run compile, andnpm test— passed; 303/303 npm tests. Guide links are checked and every TypeScript example compiles against the actual public API. Tests also passed through the real no-binary Debug bootstrap..\scripts\build-cli.ps1 -SkipTests -SkipMsix— passed on the final merged source, publishing x64/ARM64 NativeAOT executables, the npm tarball, all four NuGet packages, and an ignored artifact schema. The maintained guide was unchanged anddocs\cli-schema.jsonwas not recreated..\scripts\validate-llm-docs.ps1 -CliPath .\artifacts\cli\win-arm64\winapp.exe— passed, including current command examples and plugin manifest versions..\scripts\validate-mslearn-docs.ps1— passed, with existing unrelated callout-style warnings. The npm guide retains its existing publishing status.getWinappPath()call, and its packaged native--versioncommand. The published CLI's--versionand--cli-schemaalso passed inside Windows Sandbox.The older-Node directory-resolution regression emulates the missing property; it is not a native Node 18 run. Full C# tests, UI end-to-end tests, sample suites, and MSIX packaging were not run locally; those remain covered by the PR's existing CI.