Skip to content

Stream project restore progress during winapp run - #789

Merged
Zach Teutsch (zateutsch) merged 23 commits into
mainfrom
nmetulev-improve-run-progress
Sep 10, 2026
Merged

Zach Teutsch (zateutsch) merged 23 commits into
mainfrom
nmetulev-improve-run-progress

Conversation

@nmetulev

@nmetulev Nikola Metulev (nmetulev) commented Aug 26, 2026 •

Copy link
Copy Markdown
Member

Summary

  • stream pre-build dotnet restore output, using dotnet's native terminal logger when interactive and raw line streaming when redirected
  • keep --quiet restores quiet, preserve JSON stdout, redact displayed commands, and avoid duplicate verbose command output
  • omit resolved Platform from solution-scoped restores so configuration-free .slnx files do not emit MSB4126
  • explain when best-effort restore failures fall back or continue, and preserve subprocess line formatting including blank lines
  • document the output behavior and add real .slnx sample coverage

Validation

  • 199 ProjectRunServiceTests passed in Release
  • real configuration-free WinUISolution.slnx run restored, built, and launched without MSB4126; the solution restore omitted -p:Platform while the project build retained it
  • plugin package validation and git diff --check passed

Environment note

The complete scripts\build-cli.ps1 run reached NativeAOT publish but could not finish on this device because the Visual Studio Desktop Development for C++ linker workload is not installed.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Build Metrics Report

Binary Sizes

Artifact Baseline Current Delta
CLI (ARM64) 44.53 MB 44.51 MB 📉 -20.5 KB (-0.04%)
CLI (x64) 44.49 MB 44.47 MB 📉 -19.5 KB (-0.04%)
MSIX (ARM64) N/A 18.41 MB N/A
MSIX (x64) N/A 19.51 MB N/A
NPM Package N/A 38.30 MB N/A
NuGet Package N/A 38.43 MB N/A

Test Results

✅ 5408 passed, 18 skipped out of 5426 tests in 752.0s (+17 tests, -73.1s vs. baseline)

Test Coverage

✅ 88.2% line coverage, 81.7% branch coverage · ✅ no change vs. baseline

CLI Startup Time

57ms median (x64, winapp --version) · ✅ no change 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))) 789
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 789

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


Updated 2026-09-10 05:07:32 UTC · commit 1034b4d · workflow run

@nmetulev
Nikola Metulev (nmetulev) marked this pull request as ready for review August 26, 2026 04:23
Copilot AI balanced review requested due to automatic review settings August 26, 2026 04:23

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.

Pull request overview

Streams project restore progress alongside build output while preserving stdout for structured and quiet modes.

Changes:

  • Adds live restore streaming with terminal-aware output.
  • Expands restore-path tests and fake service support.
  • Documents restore and build output behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
ProjectRunService.cs Streams pre-build restore output.
ProjectRunServiceTests.cs Tests streamed and inherited restore paths.
FakeDotNetService.cs Simulates streaming output in tests.
docs/usage.md Documents project restore output.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs
Comment thread docs/usage.md Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@nmetulev
Nikola Metulev (nmetulev) force-pushed the nmetulev-improve-run-progress branch from de57385 to 3c6fd63 Compare August 26, 2026 23:22

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The direction here is right, and on a classic .sln this works exactly as intended — restore progress streams, --no-restore is set correctly on the build, and --json stdout stays pure.

One blocker: on .slnx solutions this now surfaces an error MSB4126 on runs that succeed. It's a pre-existing latent failure that the old buffered call was hiding, so the streaming change is doing its job — but the failure itself needs fixing rather than displaying, since .slnx is what dotnet new sln produces by default on .NET 10 and every WinUI/Reactor template trips the condition. Found it running a Microsoft.UI.Reactor app in a two-project solution.

Also a smaller one: --quiet isn't quiet anymore for the restore pass.

Comment thread src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs
Comment thread src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs
Comment thread src/winapp-CLI/WinApp.Cli.Tests/FakeDotNetService.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli.Tests/ProjectRunServiceTests.cs Outdated
@zateutsch

Copy link
Copy Markdown
Contributor

🤖 AI-generated review (winappcli pr-review skill) — verify before acting.

PR Review — nmetulev-improve-run-progress vs origin/main

Decision

Changes required — the restore-progress change creates two user-visible regressions: --quiet now emits informational restore chatter, and best-effort restore failures print alarming NuGet errors even when the app subsequently builds and launches successfully.

Must fix

Quiet mode emits normal restore progress

  • What is wrong: Restore arguments do not apply quiet verbosity, so the new streaming path forwards informational dotnet restore output under --quiet.
  • Show me: winapp run Review.slnx --project App --quiet -p WindowsPackageType=None → stderr contains Determining projects to restore... and Restored ...; expected: warnings and errors only.
  • Why it matters: Quiet automation becomes noisy and violates the documented Warning-level behavior.
  • Smallest fix: Add -v quiet to restore invocations in quiet mode while retaining stderr routing for warnings and errors; add a focused argument/output test.
  • Location: src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.Arguments.cs:23-58, src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs:608-619

Ignored restore failures look fatal

  • What is wrong: Solution and sibling restores are explicitly best-effort, but their raw NuGet errors now stream without a visible message that winapp is continuing. A failed solution restore can also be followed by a failed sibling restore, printing the errors twice before a successful build.
  • Show me: Run a solution whose non-target sibling references an unavailable package → winapp prints error NU1101, retries the sibling and prints another error NU1101, then reports Build succeeded, launches the app, and exits 0.
  • Why it matters: Users see apparent fatal errors and may stop or troubleshoot a feed problem that did not block their requested app.
  • Smallest fix: After each nonzero best-effort restore, print a clear visible message that winapp is continuing and that the target build will report any blocking error; keep the existing fallback behavior.
  • Location: src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs:542-568, src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs:577-594

Non-blocking

Quiet-mode documentation promises suppressed command lines

  • What is wrong: The usage page says quiet mode prints each restore/build invocation to stderr, but the implementation suppresses those invocations and only streams command output.
  • Show me: winapp run App.slnx --quiet → no dotnet restore ... or dotnet build ... line; expected from the documentation: each invocation appears first.
  • Why it matters: Users cannot rely on the documented quiet output when reproducing a failure.
  • Smallest fix: Clarify that quiet mode suppresses invocations while routing restore/build output to stderr; only JSON mode prints the invocation there.
  • Location: docs/usage.md:757-765

Redirected restore output is wrapped instead of streamed as plain lines

  • What is wrong: ansiConsole.WriteLine wraps redirected restore output to Spectre.Console’s profile width.
  • Show me: Redirect a restore containing a long path or feed URL → one dotnet diagnostic is split across multiple roughly 80-column lines; expected: the original append-only dotnet line.
  • Why it matters: CI parsers can miss diagnostics, and paths and URLs become difficult to copy.
  • Smallest fix: Under the existing write lock, write through ansiConsole.Profile.Out.Writer.WriteLine(line) as the build path already does.
  • Location: src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs:632-642

What was exercised

  • dotnet run --project src\winapp-CLI\WinApp.Cli.Tests\WinApp.Cli.Tests.csproj -c Debug -- --filter "FullyQualifiedName~ProjectRunServiceTests" — 191/191 passed.
  • NativeAOT publish for win-arm64 and direct invocation of the published winapp.exe — succeeded.
  • Quiet-mode run against a cold-cache two-project solution — exited 0 and reproduced informational restore output on stderr.
  • Best-effort failure run with an unavailable sibling package and isolated empty feed — printed repeated NU1101 errors, then built, launched, and exited 0.
  • Property command-injection attempt containing & cmd /c — no marker file was created.
  • .\scripts\build-cli.ps1 -SkipTests — native x64/arm64 builds and npm/NuGet packaging completed; generated files were left unchanged.
  • Not exercised: MSIX packaging — the build-tools download failed with the known corporate-network SSL restriction, which does not affect these project-run findings.

@zateutsch Zach Teutsch (zateutsch) 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.

Review attached above.

Honor quiet verbosity during project restores, avoid duplicate verbose invocations, and document JSON and quiet routing.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use scoped disposal for the JSON and quiet restore stderr capture writers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@nmetulev

Copy link
Copy Markdown
Member Author

Zach Teutsch (@zateutsch) Addressed the review findings in the latest commits: quiet restores now use -v quiet; every nonzero best-effort restore now prints an explicit fallback/continuation warning; redirected restore and build lines bypass Spectre wrapping; and the usage/setup docs reflect the actual JSON and quiet contracts. The branch also fixes the .slnx Platform failure and adds real configuration-free .slnx coverage. Release ProjectRunServiceTests pass 199/199.

Comment thread src/winapp-CLI/WinApp.Cli.Tests/ProjectRunServiceTests.cs Fixed
Comment thread src/winapp-CLI/WinApp.Cli.Tests/ProjectRunServiceTests.cs Fixed
Comment thread src/winapp-CLI/WinApp.Cli.Tests/ProjectRunServiceTests.cs Fixed
@zateutsch

Copy link
Copy Markdown
Contributor

🤖 AI-generated review (winappcli pr-review skill) — verify before acting.

PR Review — nmetulev-improve-run-progress vs origin/main

Decision

Changes required — the new whole-solution restore can produce assets for a different MSBuild platform than the subsequent --no-restore project build. The branch otherwise has appropriate scope, documentation, tests, and security handling.

Must fix

Platform-less solution restore can poison the no-restore build

  • What is wrong: After resolving Platform=x64 or ARM64, winapp restores the solution without that platform, then builds the selected project with the platform and --no-restore. Platform-conditioned packages or runtime identifiers are therefore absent from project.assets.json.
  • Show me: A solution containing a project with an x64-only PackageReference: winapp run App.slnx --arch x64 --detach → solution restore omits -p:Platform=x64, then project build adds it with --no-restore and fails with CS0103 or NETSDK1047; expected: the selected project restores under the same platform it builds with.
  • Why it matters: Valid WinUI solutions that worked before this branch can fail with misleading missing-package or missing-assets errors.
  • Smallest fix: Keep omitting Platform from solution restores to avoid MSB4126, but only set the selected build to NoRestore when no platform was resolved. When a platform exists, let the project build perform its normal project-scoped restore.
  • Location: src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs:181

Non-blocking

Quiet fallback warnings contradict the clean-stdout contract

  • What is wrong: The three new restore fallback messages use LogWarning; this logger routes warnings to stdout even under --quiet, while the updated documentation promises clean stdout.
  • Show me: winapp run App.slnx --quiet --detach -p Platform=x64 with a failing solution restore → stdout contains the fallback warning before the detached PID; expected: restore diagnostics remain on stderr.
  • Why it matters: Scripts capturing quiet stdout can receive an unexpected human-readable line.
  • Smallest fix: Write these restore-failure explanations to stderr in quiet mode while retaining normal warning behavior otherwise.
  • Location: src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.cs:518,566,597

What was exercised

  • scripts\build-cli.ps1 — native and npm builds succeeded; the full run reached 4,635 tests, with 70 unrelated failures from missing internal NuGet-feed configuration and one ARM64 crash-dump fixture mismatch.
  • dotnet run --project src\winapp-CLI\WinApp.Cli.Tests\WinApp.Cli.Tests.csproj -c Debug --no-build -- --filter "FullyQualifiedName~ProjectRunServiceTests" — 199 passed, including JSON secret-redaction and stdout/stderr routing coverage.
  • NativeAOT dotnet publish plus direct winapp.exe --version — publish succeeded and the binary ran.
  • Synthetic .slnx and classic .sln projects — reproduced the platform-conditioned package/RID failure; allowing the selected project to restore fixed it, while forwarding Platform to either solution format reproduced MSB4126.
  • Security red-team path: JSON restore with NuGetApiKey=top-secret — stderr contained NuGetApiKey=***, stdout stayed clean, and the secret was absent.
  • Not exercised: the full WinUI sample Pester workflow — the focused runtime reproductions covered the changed restore behavior, but not the sample’s complete packaging flow.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b54e905a-d32e-4e13-8c6d-4da7f9d80335
@nmetulev
Nikola Metulev (nmetulev) requested a balanced review from Copilot September 4, 2026 05:00
Comment thread src/winapp-CLI/WinApp.Cli.Tests/ProjectRunServiceTests.cs Fixed
@zateutsch

Copy link
Copy Markdown
Contributor

PR Re-Review (round 2)

The branch advanced since the last review (4b493998 Merge latest main and address review feedback). This is a re-review, so I focused on critical/high and treated the fix code as re-openable.

Prior findings — status

Prior finding Status
🔴 Build-triggered restore leaks feed credentials ✅ Fixed & verified. --json/--quiet build output now goes through NugetErrorMessage.Redact, and nativeTerminal &= options.NoRestore forces the streamed+redacted path whenever the build might restore.
🟠 User -p Platform=x64 skips build restore ⚠️ Partially fixed — see below. New HasEffectivePlatform fixes the plain form; a packed-property edge remains.
Doc: "exact" invocation ✅ Fixed — docs/usage.md:790 now says "sanitized".
Doc: README directory mode ✅ Fixed — now "directory mode prefers the .slnx migration pair".

Remaining finding

🟠 HIGH — Packed Platform property still reintroduces MSB4126 on a configuration-free .slnx

  • What is wrong: The fix made detection segment-aware (HasEffectivePlatform → UserSpecifiesProperty → PropertySegments, which splits on ; and ,), but the solution Platform-strip is still whole-string: property.StartsWith("Platform=", …). A packed -p value whose Platform isn't the first segment is never stripped from the solution restore.
  • Show me: winapp run WinUISolution.slnx -p Flavor=Retail;Platform=x64 → BuildRestorePassArguments(solution, …) emits -p:Flavor=Retail;Platform=x64 → MSBuild reads solution Platform=x64 → MSB4126 on the configuration-free .slnx. (Conversely -p Platform=x64;Flavor=Retail starts with Platform=, so the whole property is dropped, silently losing Flavor=Retail from the restore.) Expected: strip only the Platform segment, keep the rest.
  • Why it matters: This is the exact error the PR exists to eliminate, and the repo already treats packed -p as a first-class case it defends consistently everywhere else (IsDedicatedFlagProperty). A user hits the failure the PR advertises as fixed — false confidence.
  • Smallest fix: Make the strip segment-aware, reusing the existing PropertySegments/PropertyName helpers — drop only the Platform segment and re-join the survivors, instead of StartsWith. Add tests for Flavor=Retail;Platform=x64 and Platform=x64;Flavor=Retail.
  • Location: src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.Arguments.cs:63-66

Validation

  • dotnet build WinApp.Cli.csproj -c Debug → succeeded, 0 warnings/errors.
  • WinApp.Cli.Tests.exe --filter FullyQualifiedName~ProjectRunService → 203/203 passed, confirming the finding is an uncovered edge, not a broken build. No existing test packs Platform with another segment.
  • Not runtime-reproduced: MSB4126 needs a real .slnx + MSBuild + a packed non-dedicated property. Confirmed instead by direct code trace — the decisive fact ("Flavor=Retail;Platform=x64".StartsWith("Platform=") is false → not stripped) is static and unambiguous.

Everything else (cli-ux, alternatives, necessity, ship-surfaces) was clean or resolved last round and is unchanged.

🤖 Generated with multi-dimensional pr-review (security + correctness re-review + code-path validation).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b54e905a-d32e-4e13-8c6d-4da7f9d80335
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b54e905a-d32e-4e13-8c6d-4da7f9d80335
@nmetulev

Copy link
Copy Markdown
Member Author

Zach Teutsch (@zateutsch) Thanks for the re-review. I validated the packed-property case against the published CLI rather than the internal argument builder. Project mode deliberately rejects a single -p containing ; or , before any restore/build starts:

winapp run WinUISolution.slnx --json -p "Flavor=Retail;Platform=x64" -> exits nonzero with Invalid --property 'Flavor'; no dotnet process is invoked and MSB4126 is not reachable. This is covered by ProjectMode_SemicolonPackedProperty_IsRejectedBeforeBuilding (with equivalent comma coverage), so I did not add segment-aware stripping to a boundary that validated CLI input cannot reach.

The independent re-review did find one separate credential-redaction gap: malformed authenticated URLs could fail URI parsing and be returned unchanged. Commit fb0aeda4a now fails closed to <redacted-url> when an unparseable URL-shaped value contains query or user-info markers. The published-CLI reproduction now reports SECRET_COUNT=0 and two redacted command occurrences; the focused restore/redaction suite passes 244/244.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b54e905a-d32e-4e13-8c6d-4da7f9d80335
@zateutsch

Copy link
Copy Markdown
Contributor

PR Re-Review (round 3)

Reviewed at 4c4cad52. This is a re-review, so critical/high only. Build green; WinApp.Cli.Tests.exe (ProjectRunService + NugetErrorMessage) = 271/271 passed.

Resolved since last round ✅

  • 🔴 Build-triggered restore credential leak — fixed. The --json/--quiet build output now runs through NugetErrorMessage.Redact, and nativeTerminal &= options.NoRestore keeps the unredacted inherited-stdio path off whenever the build might restore.
  • 🟠 Plain -p Platform=x64 skipping the build restore — fixed via the new segment-aware HasEffectivePlatform detection.
  • NugetErrorMessage fail-closed hardening (fb0aeda4) — reviewed, no findings. Unparseable URL-shaped values containing ?/@ now redact to <redacted-url>. Well covered by the new tests.
  • Both doc items ("exact"→"sanitized"; README directory-mode wording) — fixed.

Still open

🟠 HIGH — Packed Platform property still reintroduces MSB4126 on a configuration-free .slnx

  • What is wrong: The fix made detection segment-aware (HasEffectivePlatform → UserSpecifiesProperty → PropertySegments, splitting on ;/,), but the solution Platform-strip is still whole-string property.StartsWith("Platform=", …). Detection and stripping are now inconsistent.
  • Show me: winapp run WinUISolution.slnx -p Flavor=Retail;Platform=x64 → BuildRestorePassArguments(solution, …) emits -p:Flavor=Retail;Platform=x64 → MSBuild reads solution Platform=x64 → MSB4126 on the configuration-free .slnx. The reversed form Platform=x64;Flavor=Retail starts with Platform=, so the whole property is dropped instead — silently losing Flavor=Retail from restore.
  • Why it matters: When it hits, it produces exactly the MSB4126 error this PR's feature is meant to eliminate — reads as a regression against the PR's own promise. The rest of the file already treats packed -p as first-class (IsDedicatedFlagProperty), so this is the one inconsistent site.
  • Likelihood / severity note: trigger conditions are narrow (a packed -p bundling Platform with another property, AND a configuration-free .slnx specifically). Separate -p flags and classic .sln are unaffected. Reasonable to treat as a fast-follow rather than a hard merge-blocker — but it is a cheap fix.
  • Smallest fix: strip only the Platform segment using the existing PropertySegments/PropertyName helpers and re-join survivors, instead of StartsWith. Add tests for Flavor=Retail;Platform=x64 and Platform=x64;Flavor=Retail.
  • Location: src/winapp-CLI/WinApp.Cli/Services/ProjectRunService.Arguments.cs:63-66

Everything else (cli-ux, alternatives, necessity, ship-surfaces) was clean or resolved earlier and is unchanged.

🤖 Generated with multi-dimensional pr-review (security + correctness re-review + code-path validation).

@zateutsch Zach Teutsch (zateutsch) 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.

One hanging problem from last review. Only finding, should be good to go once fixed.

@nmetulev

Copy link
Copy Markdown
Member Author

Zach Teutsch (@zateutsch) I double-checked the remaining packed-Platform finding against the current source, focused tests, and a freshly published NativeAOT CLI. It is not reachable through winapp run.

RunCommand.ProjectMode calls the shared MsBuildPropertyValidator.Validate before constructing ProjectRunOptions or calling IProjectRunService.BuildAndResolveAsync. That validator rejects any single -p containing ; or ,. The internal BuildRestorePassArguments method assumes this validated model; calling it directly bypasses the public command boundary.

Fresh published-binary results:

-p "Flavor=Retail;Platform=x64"
  exit code: 1
  error: Invalid --property 'Flavor'. A single -p cannot pack multiple properties...
  dotnet invocations: 0
  MSB4126 occurrences: 0

-p "Platform=x64;Flavor=Retail"
  exit code: 1
  error: Invalid --property 'Platform'. A single -p cannot pack multiple properties...
  dotnet invocations: 0
  MSB4126 occurrences: 0

The supported syntax behaves correctly:

-p Flavor=Retail -p Platform=ARM64
  exit code: 0
  solution restore: keeps Flavor=Retail, omits Platform
  project build: keeps Flavor=Retail and Platform=ARM64
  MSB4126 occurrences: 0

The relevant validation suite also passes 21/21, including ProjectMode_SemicolonPackedProperty_IsRejectedBeforeBuilding, comma-packed coverage, and the shared MsBuildPropertyValidatorTests.

Because both examples in the finding are rejected before the cited code path, segment-aware stripping would add handling for an invalid state rather than fix a user-reachable regression. Could you please dismiss the changes-requested review or approve the current revision?

@zateutsch
Zach Teutsch (zateutsch) merged commit 122a659 into main Sep 10, 2026
30 of 31 checks passed
@zateutsch
Zach Teutsch (zateutsch) deleted the nmetulev-improve-run-progress branch September 10, 2026 16:36
Nikola Metulev (nmetulev) added a commit that referenced this pull request Sep 21, 2026
## Description

<!-- Briefly describe what this PR does and why -->

Make lifecycle labels describe whether the agent has finished its work,
rather than whether a reviewer has responded:

- Reserve `agent-blocked` for feedback or CI the agent cannot finish
without help, or missing author input.
- Use `ready-for-review` when agent work and technical checks are
complete, including while awaiting re-review of addressed feedback.
- Use labels instead of automated lifecycle/status comments. Keep
operational details in session checkpoints; necessary review-feedback
replies remain required.
- Keep pending approvals distinct without dismissing a human
changes-request review or implying permission to merge.
- Continue configured follow-through while requested re-review is
pending.

The initial independent assessment and ordinary validation/CI waits
remain preparation work.

## Usage Example

<!-- If this PR adds or changes commands, flags, or APIs, include a
short code snippet -->

Illustrative workflow decisions:

| Situation | Lifecycle label |
|---|---|
| Feedback addressed and checks green; reviewer has not reassessed yet |
`ready-for-review` |
| Agent is fixing a finding or waiting for required CI |
`agent-preparing` |
| Agent cannot address feedback/fix CI with available access, or needs
an author decision | `agent-blocked` |

`ready-for-review` does not override GitHub's approval or merge
requirements. Status belongs in the label, not a recurring PR progress
comment.

## Related Issue

<!-- Link to any related issues: Fixes #123, Closes #456, Related to
#789 -->

N/A — requested contributor-workflow policy clarification.

## Type of Change

<!-- Keep the applicable line(s), delete the rest -->

- 📝 Documentation

## Checklist
<!-- Delete the ones that do not apply to your changes -->

- [x] Validated the contributor skill's frontmatter, relative links,
Markdown fences, and label references locally on Windows.
- [x] `git diff --check` passes.

## Screenshots / Demo

<!-- If applicable, add screenshots or GIFs demonstrating the changes
-->

N/A — contributor instructions only; no application or CLI runtime
changes.

## Additional Notes

<!-- Any additional information that reviewers should know -->

The repository label was already renamed from `agent-ready-for-review`
to `ready-for-review` with explicit authorization; existing memberships
were preserved. Its descriptions and the active agents' instructions
were updated to match.

No full NativeAOT build was run for this contributor Markdown-only
change.

## AI Description

<!-- ai-description-start -->
_This section is auto-generated by AI when the PR is opened or updated.
To opt out, delete this entire section including the marker comments._
<!-- ai-description-end -->

---------

Co-authored-by: Nikola Metulev <711864+nmetulev@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Gordon Lam (yeelam-gordon) pushed a commit to yeelam-gordon/winappCli that referenced this pull request Oct 3, 2026
…rosoft#624)

## Description
<img width="499" height="440" alt="image"
src="https://github.com/user-attachments/assets/4d3a7629-2916-4539-9528-f0bbc18d6c6f"
/>

<img width="500" height="443" alt="image"
src="https://github.com/user-attachments/assets/0f967a75-16a3-47e2-9b40-a2bdae699c11"
/>

<!-- Briefly describe what this PR does and why -->

## Usage Example

<!-- If this PR adds or changes commands, flags, or APIs, include a
short code snippet -->
<!-- Example:
```bash
winapp store app list
```
-->

## Related Issue

<!-- Link to any related issues: Fixes microsoft#123, Closes microsoft#456, Related to
microsoft#789 -->

## Type of Change

<!-- Keep the applicable line(s), delete the rest -->

- 🐛 Bug fix
- ✨ New feature
- 💥 Breaking change
- 📝 Documentation
- 🔧 Config/build
- ♻️ Refactoring
- 🧪 Test update

## Checklist
<!-- Delete the ones that do not apply to your changes -->

- [ ] New tests added for new functionality (if applicable)
- [ ] Tested locally on Windows
- [ ] Main [README.md](../README.md) updated (if applicable)
- [ ] [docs/usage.md](../docs/usage.md) updated (if CLI commands
changed)
- [ ] [Language-specific guides](../docs/guides) updated (if applicable)
- [ ] [Sample projects updated](../samples) to reflect changes (if
applicable)
- [ ] Agent skill templates updated in `docs/fragments/skills/` (if CLI
commands/workflows changed)

## Screenshots / Demo

<!-- If applicable, add screenshots or GIFs demonstrating the changes
-->

## Additional Notes

<!-- Any additional information that reviewers should know -->

## AI Description

<!-- ai-description-start -->
This pull request introduces a new sample demonstrating how to create a
WinUI 3 application and window directly from Node.js, using the
Microsoft.UI.Xaml controls projected into JavaScript. It includes
necessary files like `main.js`, `package.json`, and a README for usage
instructions. To run the sample, use the following commands:
```powershell
npm install
npm run restore
npm start
```
<!-- ai-description-end -->

---------

Co-authored-by: Nikola Metulev <nmetulev@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: nmetulev <711864+nmetulev@users.noreply.github.com>
Copilot-Session: 1cf82a54-b9a0-4437-ab3f-ea9af28a68a8
Nikola Metulev (nmetulev) added a commit that referenced this pull request Oct 7, 2026
## Description

<!-- Briefly describe what this PR does and why -->

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

<!-- If this PR adds or changes commands, flags, or APIs, include a
short code snippet -->
<!-- Example:
```bash
winapp store app list
```
-->

On Windows with Node and the .NET SDK installed:

```powershell
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:

```powershell
winapp --cli-schema
```

The maintained [npm guide](../docs/npm-usage.md) teaches common tasks
and how to discover the complete typed API in the installed package.

## Related Issue

<!-- Link to any related issues: Fixes #123, Closes #456, Related to
#789 -->

N/A.

## Type of Change

<!-- Keep the applicable line(s), delete the rest -->

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

## Checklist
<!-- Delete the ones that do not apply to your changes -->

- [x] New tests added for new functionality (if applicable)
- [x] Tested locally on Windows
- [x] Main [README.md](../README.md) updated (if applicable)
- [ ] [docs/usage.md](../docs/usage.md) updated (if CLI commands
changed) — N/A: CLI commands unchanged.
- [ ] [Language-specific guides](../docs/guides) updated (if applicable)
— N/A.
- [ ] [Sample projects updated](../samples) 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

<!-- If applicable, add screenshots or GIFs demonstrating the changes
-->

N/A: nonvisual build and documentation changes; observed command
behavior is described above.

## Additional Notes

<!-- Any additional information that reviewers should know -->

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.

---------

Co-authored-by: Nikola Metulev <711864+nmetulev@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants