Fix #467: ambiguous '-app' parsing and silent partial process matches#477
Conversation
Fixes #467. System.CommandLine treats '-app' as the short option '-a' with attached value 'pp' (POSIX bundling). Combined with UiSessionService.TryResolveProcess's silent partial-name fallback, that meant 'winapp ui inspect -app tauri-app' could resolve to an unrelated process (e.g. Microsoft Teams) without any indication. - Add OptionTypoValidator to flag tokens like '-app' when '--app' exists on the resolved command path, and reject them with a helpful error before invocation. Skipped for commands that intentionally pass through unknown tokens (tool, ms-store). - Promote partial-match and auto-window-selection log messages from Debug to Information in UiSessionService so users see when 'pp' got partial-matched to ApplicationFrameHost or when one of multiple windows was auto-selected. - Add OptionTypoValidatorTests covering positive/negative cases, attached-value form, '--' terminator, and negative numbers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Per follow-up on #467: instead of relying solely on the OptionTypoValidator heuristic, disable EnablePosixBundling at the parser level via a shared WinAppParserConfiguration so that '-app tauri-app' can never be silently reinterpreted as '-a pp'. - Add WinAppParserConfiguration.Default with EnablePosixBundling = false. - Wire it into the two production parse sites: Program.cs (main parse + --help fallback) and CompleteCommand.cs (shell completion). Tests parse with long-form options only and are unaffected. - Keep OptionTypoValidator as defense-in-depth: with bundling off, '-app foo' would otherwise produce 'Unrecognized command or argument foo' from System.CommandLine, which points at the wrong token. The validator still surfaces the clearer 'Did you mean --app?' message before invocation. - Update the validator's secondary error line and code comments to reflect the new behavior. Verified with the full 771-test suite (all green) and manual smoke tests of -app, -a, --app, and --help paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR addresses issue #467 where winapp ui inspect -app ... could be mis-parsed (POSIX short-option bundling) and then silently resolve to the wrong process via partial process-name matching, leading to inspecting an unintended app.
Changes:
- Introduces a shared
WinAppParserConfiguration.DefaultwithEnablePosixBundling = falseand wires it into the main CLI parse sites. - Adds
OptionTypoValidatorto detect single-dash long-option typos (e.g.-app→--app) and emit a clearer error message before invocation. - Promotes partial-match and auto-window selection logging to
Informationto surface ambiguous/heuristic resolution to users, and adds unit tests for the typo validator.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/winapp-CLI/WinApp.Cli/Services/UiSessionService.cs | Surfaces auto-window selection and partial process-name match behavior via Information logs. |
| src/winapp-CLI/WinApp.Cli/Program.cs | Uses shared parser config; adds pre-invocation typo detection/error messaging for -app-style mistakes. |
| src/winapp-CLI/WinApp.Cli/Helpers/WinAppParserConfiguration.cs | New centralized ParserConfiguration disabling POSIX bundling. |
| src/winapp-CLI/WinApp.Cli/Helpers/OptionTypoValidator.cs | New helper to detect single-dash long-option typos while respecting pass-through commands and --. |
| src/winapp-CLI/WinApp.Cli/Commands/CompleteCommand.cs | Ensures completion parsing uses the same shared parser configuration as the main entrypoint. |
| src/winapp-CLI/WinApp.Cli.Tests/OptionTypoValidatorTests.cs | Adds coverage for typo detection scenarios and edge cases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Build Metrics ReportBinary Sizes
Test Results✅ 780 passed, 1 skipped out of 781 tests in 414.7s (+7 tests, -16.8s vs. baseline) Test Coverage❌ 21.4% line coverage, 36.5% branch coverage · ✅ no change vs. baseline CLI Startup Time45ms median (x64, Updated 2026-04-21 18:05:19 UTC · commit |
1. Gate OptionTypoValidator on parseResult.Errors.Count > 0 (Program.cs)
so commands that legitimately accept '-foo'-shaped positional values
don't get a false-positive typo error. The original bug case still
triggers because POSIX bundling is now off, so '-app foo' produces an
unmatched-token parse error before the validator runs.
2. Use WinAppParserConfiguration.Default in OptionTypoValidatorTests so
tests parse with the same configuration as production (POSIX bundling
disabled). Without this, tests would not catch a regression in the
parser configuration.
3. Rename duplicate {Hwnd} placeholder in UiSessionService auto-select
log template to {ExplicitHwnd} so structured logging properties are
unambiguous.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Addressed all three distinct review points in 9c13294:
Manual smoke check (Release publish):
Full suite still 771/771 passing. Switching back to my other branch now. |
Fixes #467.
Problem
winapp ui inspect -app tauri-app --depth 6was silently inspecting the wrong app (e.g. Microsoft Teams) instead of the Tauri app, with no indication anything was wrong.Two compounding issues:
-ais a registered short alias of--app, so System.CommandLine parsed-appas the short option-awith attached valuepp(POSIX-aValueform). Result:app="pp",selector="tauri-app". Zero unmatched tokens, soTreatUnmatchedTokensAsErrorshad nothing to reject.UiSessionService.TryResolveProcess("pp")falls back top.ProcessName.Contains("pp", OrdinalIgnoreCase). Many running processes match (ApplicationFrameHost, etc.); whichever happens to have a foreground/main window wins. The selection was logged atDebugonly, so users had no signal that a partial match had occurred.Fix
WinAppParserConfiguration.Default(EnablePosixBundling = false), wired into the two production parse sites (Program.cs,CompleteCommand.cs). Tests use long-form options exclusively and are unaffected. Searched the repo for attached-value short-option usage (-w7932630,-aFoo, etc.) — none in docs, samples, scripts, or skills.OptionTypoValidatoras defense-in-depth. With bundling off, the parser would otherwise consume-appas the positionalselectorargument and emitUnrecognized command or argument 'tauri-app'— which points at the wrong token. The validator inspects the parsed command's long-option namespace, detects single-dash tokens that match a known long option (e.g.-app↔--app), and exits with a clearer message before invocation:TreatUnmatchedTokensAsErrors=falseso pass-through commands liketoolandms-storeare unaffected. Skips negative numbers and tokens after--.Debug→InformationinUiSessionServiceso users see when a short/typoed--appvalue resolved to an unrelated process, with the matched PID/process name and a hint to use-w <HWND>or the full process name to disambiguate. Same change for the auto-window-selection path when one process owns multiple windows.Verification
OptionTypoValidatorTests(7 cases): typo detection, attached-value form (-app=foo), valid short/long options, unknown clusters with no matching long,--terminator, negative numbers.-app something→ friendly typo error, exit 1 ✅-a something(valid short) → works ✅--app something→ works ✅--helpandui inspect --help→ unaffected ✅scripts/build-cli.ps1regenerated CLI schema and skills cleanly with no surface changes.