Skip to content

Stop tracking generated command wrappers and schema snapshots - #997

Merged
Nikola Metulev (nmetulev) merged 6 commits into
mainfrom
nmetulev-generated-command-conflicts
Oct 7, 2026
Merged

Nikola Metulev (nmetulev) merged 6 commits into
mainfrom
nmetulev-generated-command-conflicts

Conversation

@nmetulev

@nmetulev Nikola Metulev (nmetulev) commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

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:

Set-Location src\winapp-npm
npm ci
npm run compile
npm test

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:

winapp --cli-schema

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

  • 📝 Documentation
  • 🔧 Config/build
  • ♻️ Refactoring
  • 🧪 Test update

Checklist

  • New tests added for new functionality (if applicable)
  • Tested locally on Windows
  • Main README.md updated (if applicable)
  • docs/usage.md updated (if CLI commands changed) — N/A: CLI commands unchanged.
  • Language-specific guides updated (if applicable) — N/A.
  • Sample projects updated to reflect changes (if applicable) — N/A.
  • Shipped skills updated in 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-schema remains 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.
  • From src\winapp-npm, npm run lint, npm run format:check, npm run compile, and npm 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 and docs\cli-schema.json was 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.
  • Actual final npm tarball — passed export/declaration checks, an exported getWinappPath() call, and its packaged native --version command. The published CLI's --version and --cli-schema also 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.

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>
Copilot AI balanced review requested due to automatic review settings October 6, 2026 03:23
@nmetulev Nikola Metulev (nmetulev) added the agent-preparing Agent is addressing feedback or completing required validation and CI label Oct 6, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Build Metrics Report

Validation passed. All required build and validation jobs succeeded.

Binary Sizes

Artifact Baseline Current Delta
CLI (ARM64) 57.42 MB 57.42 MB ✅ 0.0 KB (0.00%)
CLI (x64) 57.46 MB 57.46 MB ✅ 0.0 KB (0.00%)
MSIX (ARM64) 23.86 MB 23.86 MB 📉 -0.0 KB (-0.00%)
MSIX (x64) 25.32 MB 25.32 MB 📈 +0.5 KB (+0.00%)
NPM Package 49.76 MB 49.76 MB 📉 -0.8 KB (-0.00%)
NuGet Package 49.86 MB 49.86 MB 📈 +0.8 KB (+0.00%)

.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 Time

51ms median (x64, winapp --version) · 📉 -12ms vs. baseline

Try This Build

Installs 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))) 997
Switching between builds often?

Put the tool on your PATH once:

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) -AddToPath

Then this build is just:

winapp-pr 997

Run winapp-pr with no arguments to pick from a list of open PRs.


Updated 2026-10-07 01:24:53 UTC · commit 099b276 · workflow run

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
@nmetulev Nikola Metulev (nmetulev) changed the title Stop tracking generated npm command wrappers Stop tracking generated command wrappers and schema snapshots Oct 6, 2026
@nmetulev Nikola Metulev (nmetulev) added ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge and removed agent-preparing Agent is addressing feedback or completing required validation and CI labels Oct 6, 2026
@nmetulev
Nikola Metulev (nmetulev) merged commit b57bf2d into main Oct 7, 2026
38 checks passed
@nmetulev
Nikola Metulev (nmetulev) deleted the nmetulev-generated-command-conflicts branch October 7, 2026 02:21
Nikola Metulev (nmetulev) added a commit to dotMorten/winappCli that referenced this pull request Oct 7, 2026
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>
Nikola Metulev (nmetulev) added a commit that referenced this pull request Oct 8, 2026
## 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants