diff --git a/.github/skills/powertoys-module-verification/LICENSE.txt b/.github/skills/powertoys-verification/LICENSE.txt similarity index 100% rename from .github/skills/powertoys-module-verification/LICENSE.txt rename to .github/skills/powertoys-verification/LICENSE.txt diff --git a/.github/skills/powertoys-module-verification/SKILL.md b/.github/skills/powertoys-verification/SKILL.md similarity index 83% rename from .github/skills/powertoys-module-verification/SKILL.md rename to .github/skills/powertoys-verification/SKILL.md index 9857a64c3763..6be4a0338a66 100644 --- a/.github/skills/powertoys-module-verification/SKILL.md +++ b/.github/skills/powertoys-verification/SKILL.md @@ -1,25 +1,47 @@ --- -name: powertoys-module-verification -description: "Verify a single PowerToys module's release checklist items end-to-end. Drive each checkbox via UIA / Named Events / settings.json edits / clipboard inspection / GPO / SendInput. Output a structured PASS / FAIL / BLOCKED verdict per item with evidence (FAIL distinguishes product defects from stale/ambiguous checklist items). Combine standard winapp ui mechanics (see references/winapp-ui-testing.md) with PT-specific recipes and the helper .ps1 files shipped with this skill." +name: powertoys-verification +description: "Verify PowerToys behavior end-to-end with the winapp CLI across three scenarios: (A) a single module's full release checklist; (B) sign-off of the PRs in a release or hotfix (derive each PR's checklist from its description + diff, drive the installed build); (C) an active/unmerged PR (build + sideload the affected module, then validate). Drive each item via UIA invoke / Named Events / settings.json edits / clipboard / GPO / SendInput, and emit a structured PASS / FAIL / BLOCKED verdict per item with evidence (FAIL distinguishes product defects from stale/ambiguous checklist items). Use when asked to verify a PowerToys module checklist, sign off a release or hotfix's PRs, validate a PowerToys PR, or QA installed/sideloaded PowerToys bits. Combines generic winapp ui mechanics (references/winapp-ui-testing.md) with PT-specific recipes, per-scenario playbooks (references/scenarios/), and the helper .ps1 files shipped with this skill." license: Complete terms in LICENSE.txt --- ## When to use this skill -Use this skill when you need to **verify every checklist item for a single PowerToys module** for a release sign-off — e.g. "verify all 18 Color Picker items", "verify all 88 Command Palette items". Each item produces a PASS / FAIL / BLOCKED verdict with evidence (UIA enumeration, log line, settings.json diff, screenshot, etc.). +Use this skill whenever you need to **verify PowerToys behavior with the winapp CLI** and emit a +structured PASS / FAIL / BLOCKED verdict with evidence (UIA enumeration, log line, settings.json +diff, screenshot, etc.). It runs in **three scenarios** that share the same drive techniques, +helpers, taxonomy and report format — and differ only on what the checklist is, what bits you test, +and the test discipline: -The **checklist to verify is supplied with the task** (the calling prompt points you at the module's checklist file). This skill is the *how* — the drive techniques, helpers, taxonomy, and reporting format — independent of any specific checklist. +| Scenario | Trigger | Checklist source | Bits under test | +|---|---|---|---| +| **A — Module checklist** | "verify all `` items", "sign off Color Picker" | Supplied file (`references/release-checklist/.md`) | Installed shipped artifact (read-only) | +| **B — Release/hotfix PR sign-off** | "verify the PRs in this release/hotfix", "sign off 0.X.Y" | **Derived** from each PR's description + diff | Installed shipped artifact (read-only) | +| **C — Active PR validation** | "validate PR #N", "build it and test the fix" | **Derived** from one PR's description + diff | **Your local build, sideloaded** | + +> **Step 0 for every run — pick the scenario.** Read **`references/scenarios/index.md`** (the +> router + the per-scenario "bits under test" contract + the verdict-vocabulary mapping), then read +> the one matching scenario doc (`references/scenarios/{module-checklist,release-pr-signoff,active-pr-validation}.md`). +> This `SKILL.md` is the *shared engine* (drive techniques, helpers, taxonomy, pitfalls) common to +> all three. + +Each item produces a PASS / FAIL / BLOCKED verdict with evidence. For **A** the checklist is +supplied; for **B / C** you derive it from the PR(s). The skill is the *how* — independent of any +specific checklist. ## Required reads (in order) -1. **`references/winapp-ui-testing.md`** — the **prerequisite** UIA mechanics doc (winapp ui verbs, scripted batch testing, file pickers, accessibility audits, screenshots, click-vs-invoke, PostMessage, SendInput cb=40, stunted-UIA recovery, settings-mutation safety contract). **Read this first** — this skill assumes you know its content and only adds PT-specific extensions. -2. **This `SKILL.md`** — the PT-specific playbook: the 3-bucket drive-technique selector (Step 2), classification taxonomy, critical pitfalls, helper-script catalog. -3. **`references/modules/.md` IF IT EXISTS** — per-module entry-paths, item-by-item recipes, common BLOCKED traps, fixture lists, source citations. **Always check `references/modules/` first.** If no profile exists, fall back to this SKILL.md and create one after you finish (template in `references/modules/README.md`). -4. **`references/explorer-context-menu-flow.md` IF your module registers an Explorer right-click entry** (PowerRename, File Locksmith, Image Resizer, New+, Preview Pane, RegistryPreview) — shared synthetic-right-click + UIA-invoke + multi-file-selection flow + module-caption table. Helper: `scripts/pt-explorer-contextmenu.ps1`. -5. **`references/pre-flight.md`** — pre-flight checks, bootstrap snippet, state-hygiene cleanup, final wrap-up, hard rules. -6. **`references/reporting-format.md`** — per-item table template, top-of-report summary, step-table rules, anti-patterns, worked example. -7. **`references/environment-setup.md`** — RDP/sleep/screensaver/session-attachment gotchas. Cite in BLK-ENV verdicts. -8. **`references/release-checklist/.md`** — the checklist for the module under test (one file per module; see `references/release-checklist/index.md` for the full list). Each item carries `[ADMIN: …]` + `[CLARITY: …]` metadata. **This file IS the set of items to verify.** +1. **`references/scenarios/index.md`** — **read FIRST**: the scenario router (A/B/C), the + per-scenario **"bits under test" contract** (installed-and-immutable for A/B vs build-and-sideload + for C), and the verdict-vocabulary mapping. Then read the **one** matching scenario doc: + `references/scenarios/module-checklist.md` (A) · `release-pr-signoff.md` (B) · `active-pr-validation.md` (C). +2. **`references/winapp-ui-testing.md`** — the **prerequisite** UIA mechanics doc (winapp ui verbs, scripted batch testing, file pickers, accessibility audits, screenshots, click-vs-invoke, PostMessage, SendInput cb=40, stunted-UIA recovery, settings-mutation safety contract). **Read this first** — this skill assumes you know its content and only adds PT-specific extensions. +3. **This `SKILL.md`** — the shared engine: the 3-bucket drive-technique selector (Step 2), classification taxonomy, critical pitfalls, helper-script catalog. +4. **`references/modules/.md` IF IT EXISTS** — per-module entry-paths, item-by-item recipes, common BLOCKED traps, fixture lists, source citations. **Always check `references/modules/` first.** If no profile exists, fall back to this SKILL.md and create one after you finish (template in `references/modules/README.md`). +5. **`references/explorer-context-menu-flow.md` IF your module registers an Explorer right-click entry** (PowerRename, File Locksmith, Image Resizer, New+, Preview Pane, RegistryPreview) — shared synthetic-right-click + UIA-invoke + multi-file-selection flow + module-caption table. Helper: `scripts/pt-explorer-contextmenu.ps1`. +6. **`references/pre-flight.md`** — pre-flight checks, bootstrap snippet, state-hygiene cleanup, final wrap-up, hard rules. +7. **`references/reporting-format.md`** — per-item table template, top-of-report summary, step-table rules, anti-patterns, worked example. +8. **`references/environment-setup.md`** — RDP/sleep/screensaver/session-attachment gotchas. Cite in BLK-ENV verdicts. +9. **`references/release-checklist/.md` — SCENARIO A ONLY** — the supplied checklist for the module under test (one file per module; see `references/release-checklist/index.md`). Each item carries `[ADMIN: …]` + `[CLARITY: …]` metadata. **This file IS the set of items to verify.** For B/C the checklist is derived from the PR(s) instead (see the scenario doc). ## Helper scripts shipped with this skill @@ -39,7 +61,7 @@ The **checklist to verify is supplied with the task** (the calling prompt points Dot-source them **all** at once in your bootstrap (the `Get-ChildItem` loop loads every helper — see **Step 1 — Bootstrap**): ```powershell -$skill = '' # the folder containing SKILL.md, e.g. \.github\skills\powertoys-module-verification +$skill = '' # the folder containing SKILL.md, e.g. \.github\skills\powertoys-verification Get-ChildItem "$skill\scripts" -Filter '*.ps1' | ForEach-Object { . $_.FullName } ``` @@ -63,8 +85,11 @@ Get-ChildItem "$skill\scripts" -Filter '*.ps1' | ForEach-Object { . $_.FullName $rn = Test-PtRunnerAdmin "PT runner: PID=$($rn.Pid) Elevated=$($rn.Elevated)" | Tee-Object $report -Append -# The checklist items to verify are supplied with the task (see the calling prompt). -# Read that module's checklist file and iterate its items (see Step 6 — Verifier loop). +# The checklist source depends on the scenario (see references/scenarios/): +# A - read the supplied references/release-checklist/.md +# B - derive 1-3 items from each PR's `gh pr view/diff` (release-pr-signoff.md) +# C - derive items from the PR, after build+sideload (active-pr-validation.md) +# Then iterate the items (see Step 6 - Verifier loop). ``` ## Step 2 — Drive techniques @@ -247,20 +272,28 @@ Print the **moved** report path (under `…\PowerToys\Module-Signoff\`) as the l ## Invocation & placeholders -This skill auto-activates when you ask to verify a PowerToys module's checklist (e.g. "verify all Color Picker items"). **One module per run** — never chain multiple modules into one report. Resolve these placeholders for the module under test: +This skill auto-activates for any of the three scenarios above (verify a module checklist, sign off +a release/hotfix's PRs, or validate a PR). **Step 0: resolve the scenario via +`references/scenarios/index.md` and set the `BITS:` contract** before driving anything. Scope rule: +**one module per run for Scenario A**, **one PR per report folder for B/C**. Resolve these +placeholders: | Placeholder | Substitute with | |---|---| | `` | Exact display name, e.g. `Color Picker`, `Command Palette`, `PowerToys Run`, `FancyZones` (see `references/release-checklist/index.md`). | -| `` | Lowercase-kebab-case for file lookup, e.g. `color-picker`, `command-palette`, `power-rename` — used for BOTH `references/release-checklist/.md` (checklist) and `references/modules/.md` (profile, if any). | +| `` | Lowercase-kebab-case for file lookup, e.g. `color-picker`, `command-palette`, `power-rename` — used for BOTH `references/release-checklist/.md` (A's checklist) and `references/modules/.md` (profile, if any). | | `` | settings.json sub-dir under `%LOCALAPPDATA%\Microsoft\PowerToys\` (e.g. `AdvancedPaste`, `FancyZones`, `PowerToys Run` (with space)). | -| `` | Total item count for this module. | +| `` | Scenario A: total item count for the module. Scenario B/C: the GitHub PR number. | -**Execution order:** `references/pre-flight.md` → per item, the §2 drive-stack (this file) → `references/reporting-format.md` per-item table → Step 6 verifier loop → `references/pre-flight.md` §Final wrap-up → Step 7 archive → print the final report path. +**Execution order:** `references/scenarios/index.md` (pick scenario + set `BITS`) → the matching +`references/scenarios/.md` (inputs, discipline, deploy steps for C) → `references/pre-flight.md` +→ per item, the §2 drive-stack (this file) → `references/reporting-format.md` per-item table → +Step 6 verifier loop → `references/pre-flight.md` §Final wrap-up → Step 7 archive → print the final report path. ## What NOT to do -- Do NOT chain multiple modules in one report — one module per run. +- Do NOT skip Step 0 — drive nothing until you've set the scenario and the `BITS:` contract. A run that mutates the wrong bits (sideloads in B, or drives the installed binary in C) is invalid regardless of the verdict. +- Do NOT chain multiple modules in one report (Scenario A) — one module per run. For B/C, one PR per report folder. - Do NOT mark an item BLOCKED without a concrete, named obstacle (see §3 and `references/pre-flight.md` §Hard rules). - Do NOT invent steps for a VAGUE checklist item — if the spec is too ambiguous to judge, that is FAIL (cause=checklist), not a guess. - All other rules (foreground guard, always restore mutated state, etc.) live in `references/pre-flight.md` §Hard rules — follow them. @@ -293,7 +326,7 @@ This skill auto-activates when you ask to verify a PowerToys module's checklist | Module | Module-owned file (under `…\PowerToys\\`) | Key style | PT-store `settings.json` keys (UI/`Get-PtModuleSettings`) | |---|---|---|---| | PowerRename | `power-rename-settings.json` (+ `power-rename-last-run-data.json`, `search-mru.json`, `replace-mru.json`) | `ShowIcon`, `ExtendedContextMenuOnly`, `PersistState`, `MRUEnabled`, `MaxMRUSize`, `UseBoostLib` | `bool_show_icon_on_menu`, `bool_show_extended_menu`, `bool_persist_input`, `bool_mru_enabled`, `int_max_mru_size`, `bool_use_boost_lib` | -| File Locksmith | `file-locksmith-settings.json` | `ShowInExtendedContextMenu` | `bool_show_extended_context_menu` | +| File Locksmith | `file-locksmith-settings.json` | `showInExtendedContextMenu` | `bool_show_extended_context_menu` | | Image Resizer | `image-resizer-settings.json` | (resize sizes/encoder/etc.) | mirrored `imageresizer*` keys | | New+ | `NewPlus\settings.json` (sub-folder **`NewPlus`**, verified on disk + `constants.h` `powertoy_name=L"NewPlus"`) | `HideFileExtension`, `HideStartingDigits`, `TemplateLocation`, `ReplaceVariables`, `BuiltInNewHidePreference` | mirrored `newplus*` keys | diff --git a/.github/skills/powertoys-module-verification/references/environment-setup.md b/.github/skills/powertoys-verification/references/environment-setup.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/environment-setup.md rename to .github/skills/powertoys-verification/references/environment-setup.md diff --git a/.github/skills/powertoys-module-verification/references/explorer-context-menu-flow.md b/.github/skills/powertoys-verification/references/explorer-context-menu-flow.md similarity index 94% rename from .github/skills/powertoys-module-verification/references/explorer-context-menu-flow.md rename to .github/skills/powertoys-verification/references/explorer-context-menu-flow.md index 59b88ea58a71..7aea2936dd47 100644 --- a/.github/skills/powertoys-module-verification/references/explorer-context-menu-flow.md +++ b/.github/skills/powertoys-verification/references/explorer-context-menu-flow.md @@ -29,7 +29,7 @@ Net: for a context-menu module, **most items are behavior → CLI-first**; the * **Hard prerequisite — unlocked interactive desktop.** Synthetic right-click injects into the session input stream, so it requires foreground. If the workstation is locked / RDP minimized (`GetForegroundWindow()=0`), this flow is `BLK-ENV` — there is no foreground-free way to open a context menu. `Open-PtExplorerContextMenu` throws a clear BLK-ENV error in that case. (A 4-hour idle auto-lock is the common culprit — see `references/environment-setup.md`.) **Other constraints:** -- **Settings for these modules live in a module-OWNED file, not the PT-store `settings.json`** — see `SKILL.md` pitfall #18. The context-menu handler reads e.g. `power-rename-settings.json` / `file-locksmith-settings.json` / `image-resizer-settings.json` / `New\settings.json` at launch; editing the PT-store `\settings.json` (what `Get-PtModuleSettings` reads) often has **no effect** on the live handler. Drive icon/extended-menu/feature toggles via the module-owned file + relaunch (restart runner+Explorer for the menu handlers), then restore. +- **Settings for these modules live in a module-OWNED file, not the PT-store `settings.json`** — see `SKILL.md` pitfall #18. The context-menu handler reads e.g. `power-rename-settings.json` / `file-locksmith-settings.json` / `image-resizer-settings.json` / `NewPlus\settings.json` at launch; editing the PT-store `\settings.json` (what `Get-PtModuleSettings` reads) often has **no effect** on the live handler. Drive icon/extended-menu/feature toggles via the module-owned file + relaunch (restart runner+Explorer for the menu handlers), then restore. - This is the **Win11 packaged** context menu (`Microsoft.UI.Content.PopupWindowSiteBridge` / "PopupHost"). The packaged module commands appear **only** here — not in classic `Shell.Application.Verbs()` and not via `CoCreate` of the command CLSID (`REGDB_E_CLASSNOTREGISTERED`). On Win10, or under "Show more options", you'd get the classic menu instead (different structure). - The menu exists in the UIA tree **only while open** — you must open it with real input first; you can't enumerate it cold. - A menu-launched module UI runs **non-elevated** (Explorer's integrity), even if your agent shell is elevated. Mind elevation-visibility (e.g. a non-elevated File Locksmith can't see higher-IL processes — match locker integrity with `scripts/pt-nonelevated.ps1`). @@ -79,7 +79,7 @@ Match the **visible caption**, not the AutomationId (Explorer assigns per-sessio |---|---|---| | File Locksmith | `PowerToys.FileLocksmithUI.exe` | ✓ `Unlock with File Locksmith` (NB: **not** the checklist's "What's using this file?") | | PowerRename | `PowerToys.PowerRename.exe` | ✓ `Rename with PowerRename` | -| Image Resizer | `PowerToys.ImageResizer.exe` | `Resize images` (verify via `Get-PtContextMenuItems` — caption shifted across versions) | +| Image Resizer | `PowerToys.ImageResizer.exe` | ✓ `Resize with Image Resizer` (source string `ImageResizer_Context_Menu_Entry`; verify via `Get-PtContextMenuItems` — caption shifted across versions) | | New+ | (creates from template) | `New+` (submenu) | > Tip: if a module's caption is unknown, enable the module, open the menu on an applicable file, and run `Get-PtContextMenuItems` to read the exact string — then hard-match it for present/absent assertions. diff --git a/.github/skills/powertoys-module-verification/references/modules/README.md b/.github/skills/powertoys-verification/references/modules/README.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/modules/README.md rename to .github/skills/powertoys-verification/references/modules/README.md diff --git a/.github/skills/powertoys-module-verification/references/modules/file-locksmith.md b/.github/skills/powertoys-verification/references/modules/file-locksmith.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/modules/file-locksmith.md rename to .github/skills/powertoys-verification/references/modules/file-locksmith.md diff --git a/.github/skills/powertoys-module-verification/references/modules/image-resizer.md b/.github/skills/powertoys-verification/references/modules/image-resizer.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/modules/image-resizer.md rename to .github/skills/powertoys-verification/references/modules/image-resizer.md diff --git a/.github/skills/powertoys-module-verification/references/modules/new-plus.md b/.github/skills/powertoys-verification/references/modules/new-plus.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/modules/new-plus.md rename to .github/skills/powertoys-verification/references/modules/new-plus.md diff --git a/.github/skills/powertoys-module-verification/references/modules/peek.md b/.github/skills/powertoys-verification/references/modules/peek.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/modules/peek.md rename to .github/skills/powertoys-verification/references/modules/peek.md diff --git a/.github/skills/powertoys-module-verification/references/modules/power-rename.md b/.github/skills/powertoys-verification/references/modules/power-rename.md similarity index 93% rename from .github/skills/powertoys-module-verification/references/modules/power-rename.md rename to .github/skills/powertoys-verification/references/modules/power-rename.md index 5fa48a9521bf..4c64b139f517 100644 --- a/.github/skills/powertoys-module-verification/references/modules/power-rename.md +++ b/.github/skills/powertoys-verification/references/modules/power-rename.md @@ -37,15 +37,23 @@ Use the canonical flow from `references/explorer-context-menu-flow.md` Recipe. T ```powershell . "$skill\scripts\pt-explorer-contextmenu.ps1" -$hwnd = Open-PtExplorerContextMenu -FolderPath 'D:\fixtures' -FileNames 'a.txt' -$items = Get-PtContextMenuItems -MenuHwnd $hwnd -$has = $items | Where-Object Name -match 'Rename with PowerRename' +# Disposable fixtures folder (same convention as Entry-path 1) +$fx = New-Item -ItemType Directory -Path "$env:TEMP\pr-fixture-$(Get-Random)" +'x' | Set-Content "$($fx.FullName)\a.txt" +# Open Explorer on it and grab its CabinetWClass HWND +Start-Process explorer.exe $fx.FullName; Start-Sleep 4 +$hwnd = (winapp ui list-windows --json | ConvertFrom-Json | + Where-Object { $_.className -eq 'CabinetWClass' -and $_.title -match [regex]::Escape($fx.Name) } | + Select-Object -First 1).hwnd +$menu = Open-PtExplorerContextMenu -ExplorerHwnd $hwnd -FileName 'a.txt' +$items = Get-PtContextMenuItems -MenuHwnd $menu # returns MenuItem name strings +$has = $items | Where-Object { $_ -match 'Rename with PowerRename' } # assert $has -> entry present ``` ### 3. Shell COM classic verb (does NOT work on Win11 stock install) ```powershell -Invoke-PtShellVerb -Path 'D:\fixtures\a.txt' -NamePattern 'PowerRename' # -> False +Invoke-PtShellVerb -Path "$($fx.FullName)\a.txt" -NamePattern 'PowerRename' # -> False (reuses $fx from Entry-path 2) ``` Returns False on Win11 because PT registers PR only via IExplorerCommand, not as a classic HKCR shell verb. **Use only for negative checks** (and prefer the synthetic-menu enumeration above, which observes the actual Tier-1 menu). diff --git a/.github/skills/powertoys-module-verification/references/pre-flight.md b/.github/skills/powertoys-verification/references/pre-flight.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/pre-flight.md rename to .github/skills/powertoys-verification/references/pre-flight.md diff --git a/.github/skills/powertoys-module-verification/references/release-checklist/environment-variables.md b/.github/skills/powertoys-verification/references/release-checklist/environment-variables.md similarity index 98% rename from .github/skills/powertoys-module-verification/references/release-checklist/environment-variables.md rename to .github/skills/powertoys-verification/references/release-checklist/environment-variables.md index 311d50571537..ee4be68c55cd 100644 --- a/.github/skills/powertoys-module-verification/references/release-checklist/environment-variables.md +++ b/.github/skills/powertoys-verification/references/release-checklist/environment-variables.md @@ -30,7 +30,7 @@ Each item is annotated with two metadata tags: - [ ] **[ADMIN: NO]** (L801) Add new profile with no variables and name it "Test_profile_1" (referenced below by name) - [ ] **[ADMIN: NO]** (L802) Edit "Test_profile_1": Add one new variable to profile e.g. name: "profile_1_variable_1" value: "profile_1_value_1" - [ ] **[ADMIN: NO]** (L803) Add new profile "Test_profile_2": From "Add profile dialog" add two new variables (profile_2_variable_1:profile_2_value_1 and profile_2_variable_2:profile_2_value_2). Set profile to enabled and click Save. Open OS Environment variables window and confirm that all variables from the profile are applied correctly. Also, confirm that "Applied variables" list contains all variables from the profile. -- [ ] **[ADMIN: NO]** (L804) Apply "Test_profile_1" while "Test_profile_2" is still aplpied. Open OS Environment variables window and confirm that all variables from Test_profile_2 are unapplied and that all variables from Test_profile_1 are applied. Also, confirm that state of "Applied variables" list is updated correctly. +- [ ] **[ADMIN: NO]** (L804) Apply "Test_profile_1" while "Test_profile_2" is still applied. Open OS Environment variables window and confirm that all variables from Test_profile_2 are unapplied and that all variables from Test_profile_1 are applied. Also, confirm that state of "Applied variables" list is updated correctly. - [ ] **[ADMIN: NO]** (L805) Unapply applied profile. Open OS Environment variables window and confirm that all variables from the profile are unapplied correctly. Also, confirm that "Applied variables" list does not contain variables from the profile. - [ ] **[ADMIN: NO]** (L808) To "Test_profile_1" add one existing variable from USER variables, e.g. TMP. After adding, change it's value to e.g "test_TMP" (or manually add variable named TMP with value test_TMP). - [ ] **[ADMIN: NO]** (L809) Apply "Test_profile_1". Open OS Environment variables window and confirm that TMP variable in USER variables has value "test_TMP". Confirm that there is backup variable "TMP_PowerToys_Test_profile_1" with original value of TMP var. Also, confirm that "Applied variables" list is updated correctly - there is TMP profile variable, and backup User variable.. diff --git a/.github/skills/powertoys-module-verification/references/release-checklist/file-locksmith.md b/.github/skills/powertoys-verification/references/release-checklist/file-locksmith.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/release-checklist/file-locksmith.md rename to .github/skills/powertoys-verification/references/release-checklist/file-locksmith.md diff --git a/.github/skills/powertoys-module-verification/references/release-checklist/image-resizer.md b/.github/skills/powertoys-verification/references/release-checklist/image-resizer.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/release-checklist/image-resizer.md rename to .github/skills/powertoys-verification/references/release-checklist/image-resizer.md diff --git a/.github/skills/powertoys-module-verification/references/release-checklist/index.md b/.github/skills/powertoys-verification/references/release-checklist/index.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/release-checklist/index.md rename to .github/skills/powertoys-verification/references/release-checklist/index.md diff --git a/.github/skills/powertoys-module-verification/references/release-checklist/new-plus.md b/.github/skills/powertoys-verification/references/release-checklist/new-plus.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/release-checklist/new-plus.md rename to .github/skills/powertoys-verification/references/release-checklist/new-plus.md diff --git a/.github/skills/powertoys-module-verification/references/release-checklist/peek.md b/.github/skills/powertoys-verification/references/release-checklist/peek.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/release-checklist/peek.md rename to .github/skills/powertoys-verification/references/release-checklist/peek.md diff --git a/.github/skills/powertoys-module-verification/references/release-checklist/power-rename.md b/.github/skills/powertoys-verification/references/release-checklist/power-rename.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/release-checklist/power-rename.md rename to .github/skills/powertoys-verification/references/release-checklist/power-rename.md diff --git a/.github/skills/powertoys-module-verification/references/reporting-format.md b/.github/skills/powertoys-verification/references/reporting-format.md similarity index 100% rename from .github/skills/powertoys-module-verification/references/reporting-format.md rename to .github/skills/powertoys-verification/references/reporting-format.md diff --git a/.github/skills/powertoys-verification/references/scenarios/active-pr-validation.md b/.github/skills/powertoys-verification/references/scenarios/active-pr-validation.md new file mode 100644 index 000000000000..2f96116e8e89 --- /dev/null +++ b/.github/skills/powertoys-verification/references/scenarios/active-pr-validation.md @@ -0,0 +1,108 @@ +# Scenario C — Active (unmerged) PR validation + +**Use when:** the task asks you to validate a PR whose code is **not in the installed build** — +e.g. "verify PR #N", "build it and check the fix", an open/unmerged PR under review. Here you +**build the affected module and run your own bits**, then drive them with the same engine. + +This is the only scenario whose discipline is **inverted** from A/B: building & deploying unreleased +code is the entire point, not a violation. The immutability rule still protects *unrelated* +installed bits you didn't build. + +## Bits under test + +``` +BITS: local build of @ , sideloaded +``` + +Before the first drive command, prove the running module is **your build**, not the shipped one +(path under the build output / a dev version string), and record it in the report header. A run +that accidentally drove the installed binary is invalid (see `index.md` → bits contract). + +--- + +## Step 0 — Read the PR + +```powershell +gh pr view --repo microsoft/PowerToys --json title,body,files,headRefName,headRepositoryOwner,state +gh pr diff --repo microsoft/PowerToys +``` + +Derive the observable claim(s) → 1–3 checklist items (same as Scenario B Step 1). From +`--json files`, identify the **affected project(s)** (`.csproj` / `.vcxproj`) so you build only what +changed, not the whole repo. + +## Step 1 — Get the code + build + +**Preferred (repo-portable):** materialize the PR's branch as an isolated worktree with the +in-repo helper, then build only the affected project (mirrors `AGENTS.md` → Build): + +```powershell +cd +gh pr checkout # creates/locates the PR branch locally +tools\build\New-WorktreeFromBranch.ps1 -Branch # in-repo, isolated worktree (also used by FixIssue.agent.md) +git submodule update --init --recursive # once +tools\build\build-essentials.cmd # first build / NuGet restore +# then build ONLY the affected project folder: +tools\build\build.ps1 -Platform x64 -Configuration Release # run from the changed .csproj/.vcxproj dir +``` + +**Exit code 0 = success (treat as absolute).** On non-zero, read +`build...errors.log` next to the project, fix or report. If the environment lacks +the toolchain (VS 2022 17.4+/2026, Windows SDK) and the build cannot complete, the verdict is +**BLOCKED** (environmental: `BLK-ENV`/INCONCLUSIVE) — never PASS on an unbuilt PR. + +## Step 2 — Deploy / run your build (by module type) + +Do **not** copy build output into `C:\Program Files\PowerToys\` or the Store package dir. Run the +built bits from the build output instead. + +### Unpackaged module (most: FancyZones, PowerToys Run, ColorPicker, Peek, KBM, …) + +The runner loads module DLLs from its own folder, so just run the **freshly built runner** from the +build output (this is the repo's own F5 dev path): + +```powershell +Get-Process PowerToys -EA SilentlyContinue | Stop-Process -Force # stop the installed runner +Start-Process "\x64\Release\PowerToys.exe" # your build's runner + module DLLs +# confirm you're on YOUR bits: +(Get-Process PowerToys | Select-Object -First 1).Path # must point under the build output +``` + +### Packaged module (Command Palette / CmdPal — MSIX) + +Enable Developer Mode, then register your build's loose layout (or install the produced `.msix`). +Because the shipped package version may collide, remove it first and restore on cleanup: + +```powershell +$shipped = Get-AppxPackage Microsoft.CommandPalette +$shipped | Remove-AppxPackage # remove shipped (restore later) +Add-AppxPackage -Register "\AppxManifest.xml" # register your loose build +(Get-AppxPackage Microsoft.CommandPalette).InstallLocation # must point under the build output +``` + +## Step 3 — Drive + classify + +Same engine as A/B: pick the `SKILL.md` §2 bucket per item, drive, classify with `SKILL.md` §3. +The **live-drive floor** applies (≥4 `winapp ui …` rows + ≥1 post-state screenshot for any +user-visible surface). Because you control the build, you can also exercise the **failing** state +the PR fixes (e.g. revert-and-rebuild, or compare against the installed shipped build) to make a +PASS decisive rather than merely "the fix is present". + +## Step 4 — Restore the machine to the shipped build (cleanup) + +```powershell +Get-Process PowerToys -EA SilentlyContinue | Stop-Process -Force # stop your built runner +Start-Process "$env:LOCALAPPDATA\PowerToys\PowerToys.exe" # or Program Files install +# Packaged: re-add the shipped package +Add-AppxPackage -DisableDevelopmentMode -Register ` + "C:\Program Files\WindowsApps\\AppxManifest.xml" # or reinstall the shipped .msix +``` + +Leave the box on the shipped build; disclose any residue in the report. + +## Report + +`{Module}-PR{Number}/report.md` with the `BITS: local build …` header (incl. the sha/branch and +the proof-of-your-bits path), the per-item table (`../reporting-format.md`), the build summary +(exit code, project built), and a §G retrospective. A PR with a user-visible surface and zero +`winapp ui …` rows is not validated. diff --git a/.github/skills/powertoys-verification/references/scenarios/index.md b/.github/skills/powertoys-verification/references/scenarios/index.md new file mode 100644 index 000000000000..55cd3ea9ec0d --- /dev/null +++ b/.github/skills/powertoys-verification/references/scenarios/index.md @@ -0,0 +1,73 @@ +# Scenario router + +This skill runs in **three scenarios**. They share ~80% of the machinery (the `winapp ui` drive +techniques in `../winapp-ui-testing.md`, the helper scripts, the per-module profiles in +`../modules/`, the classification taxonomy, state hygiene, and the report format). They differ on +only four axes. **Pick the scenario first, read its doc, then run the shared engine in `SKILL.md`.** + +| Axis | A — Module checklist | B — Release/hotfix PR sign-off | C — Active PR validation | +|---|---|---|---| +| **PR state** | n/a | **merged** PRs already in a shipped/draft build | **unmerged / open** PR not yet in any build | +| **Checklist source** | Supplied file (`../release-checklist/.md`) | **Derived** from the PRs in a release/hotfix | **Derived** from one PR's description + diff | +| **Bits under test** | Installed shipped artifact (READ-ONLY) | Installed shipped artifact (READ-ONLY) | **Your local build, sideloaded** (the point is unreleased code) | +| **Discipline** | Mutate only via user-facing UI; restore in `finally{}` | Same as A | **Inverted** — you MUST build & deploy unreleased bits | +| **Scope** | 1 module, exhaustive (e.g. 88 items) | N PRs, derive+verify each, per-PR folders | 1 PR, deep | + +| If the task is… | Scenario | Read | +|---|---|---| +| "verify all `` checklist items", "sign off Color Picker", a supplied checklist file | **A** | [`module-checklist.md`](./module-checklist.md) | +| "verify the PRs in this release / hotfix / draft release / milestone", "sign off 0.X.Y" | **B** | [`release-pr-signoff.md`](./release-pr-signoff.md) | +| "validate an **unmerged / open** PR #N", "review this PR's fix before merge", "build it and test the fix" | **C** | [`active-pr-validation.md`](./active-pr-validation.md) | + +If the task is ambiguous between B and C, the deciding question is **"is this PR already merged +and shipped in the installed build, or is it still open/unmerged?"** — merged & installed ⇒ B +(drive the shipped bits), open/unmerged ⇒ C (build & sideload it first). A bare "validate PR #N" is +**C** when the PR is still open; if it has already merged into the build under test, treat it as a +one-PR Scenario B instead. + +--- + +## The one contract that differs by scenario — declare it first + +The only real conflict between scenarios is **what "the bits under test" are** and therefore what +you are allowed to touch. Resolve it explicitly at the start of every run and **echo it in the +report header** so a reviewer can trust the evidence chain: + +``` +BITS: installed shipped artifact 0.100.1.0 (read-only) # Scenario A / B +BITS: local build of @ , sideloaded # Scenario C +``` + +- **A / B — installed artifact is immutable.** Forbidden: copying source-built files into the + install or `%LOCALAPPDATA%\...\PowerToys\...`, pre-seeding caches the app/installer owns, + editing module `settings.json` to bypass a Settings-UI step, registering/unregistering + COM/MSIX, killing helper processes except as a documented user action. Allowed: anything a real + user does through the shipped UI (toggles, hotkeys, set-value into Settings fields), read-only + probes, screenshots — always capture pre-state and restore in `finally{}`. If the documented + user flow does not produce the claimed outcome, that is **FAIL** — do not "rescue" it by editing + install state. +- **C — you are testing unreleased code, so building & sideloading is the whole point.** The A/B + immutability rule does **not** apply to your own build. It still applies to *unrelated* installed + bits you didn't build. Restore the machine to the shipped build when done (see scenario C doc). + +> A run that mutates the wrong `BITS` (e.g. sideloads in B, or runs the shipped binary in C) is +> **invalid regardless of the verdict**. Set `BITS` before the first drive command. + +--- + +## Verdict vocabulary (one taxonomy, two label sets) + +The shared engine in `SKILL.md` Step 3 uses **PASS / FAIL(product|checklist) / BLOCKED(reason)**. +Scenario B's legacy reports sometimes use **PASS / FAIL / Don't-know-what-to-test / Incapable**. +They map 1:1 — use the `SKILL.md` set and treat the legacy labels as aliases: + +| Engine (`SKILL.md` §3) | Legacy B alias | Meaning | +|---|---|---| +| PASS | PASS | Drove the behavior; matches the claim. | +| FAIL (cause=product) | FAIL | Shipped/built behavior contradicts the claim → file a bug. | +| FAIL (cause=checklist) | Don't know what to test | The item/spec is too vague or stale to judge → fix the checklist, quote the ambiguity. | +| BLOCKED (`BLK-*`) | Incapable of Testing | Couldn't run the check after ≥2 entry-paths → name the concrete obstacle. | + +Whichever label set the caller asks for, keep the **evidence rules identical**: no "source verified +/ live deferred / pre-existing / probably / unlikely" weasel-words to justify a PASS — those flip +the verdict to FAIL or BLOCKED-with-a-named-environmental-reason. diff --git a/.github/skills/powertoys-verification/references/scenarios/module-checklist.md b/.github/skills/powertoys-verification/references/scenarios/module-checklist.md new file mode 100644 index 000000000000..e699d17e871c --- /dev/null +++ b/.github/skills/powertoys-verification/references/scenarios/module-checklist.md @@ -0,0 +1,42 @@ +# Scenario A — Single-module release checklist + +**Use when:** the task supplies (or points at) a module's checklist and asks you to verify every +item — e.g. "verify all 18 Color Picker items", "sign off Command Palette's 88 items". + +This is the skill's original scenario; `SKILL.md` Steps 1–7 are written for it, so this doc is +short — it only nails down the inputs and the report shape. + +## Bits under test + +``` +BITS: installed shipped artifact (read-only) +``` + +Installed artifact is immutable; mutate only through the shipped UI and restore in `finally{}` +(see `index.md` → "bits contract" and `../pre-flight.md` §Hard rules). + +## Inputs + +| Input | Source | +|---|---| +| Checklist (the set of items) | `../release-checklist/.md` — **this file IS the items to verify.** Each item carries `[ADMIN: …]` + `[CLARITY: …]` metadata. See `../release-checklist/index.md` for the full module list. | +| Per-module recipes | `../modules/.md` if it exists (entry-paths, item recipes, BLOCKED traps, fixtures). **Check this first.** If absent, fall back to the `SKILL.md` §2 drive-stack and author one afterwards (template in `../modules/README.md`). | + +## Run order + +1. `../pre-flight.md` — pre-flight + bootstrap (`SKILL.md` Step 1). +2. For each checklist item: pick a bucket from the verb (`SKILL.md` §2.A/§2.B/§2.C), drive it, then + classify (`SKILL.md` §3). One verdict + evidence per item. +3. `../reporting-format.md` — per-item table + top-of-report summary + §G retrospective. +4. `../pre-flight.md` §State hygiene + §Final wrap-up. +5. `SKILL.md` Step 7 — archive the workspace to the sign-off folder. + +## Scope rule + +**One module per run.** Never chain multiple modules into one report. (For "verify a whole +release", that's **Scenario B**, which fans out across PRs/modules with per-PR folders.) + +## Report + +Use `../reporting-format.md` verbatim. Header must include the `BITS:` line and the module's total +item count ``. diff --git a/.github/skills/powertoys-verification/references/scenarios/release-pr-signoff.md b/.github/skills/powertoys-verification/references/scenarios/release-pr-signoff.md new file mode 100644 index 000000000000..4fd2f70e0ac9 --- /dev/null +++ b/.github/skills/powertoys-verification/references/scenarios/release-pr-signoff.md @@ -0,0 +1,105 @@ +# Scenario B — Release / hotfix PR sign-off + +**Use when:** the task asks you to verify the PRs that shipped in a release or hotfix, against an +**already-installed** build — e.g. "sign off 0.100.1", "verify the 14 PRs in this draft release", +"validate the hotfix PRs". You derive each PR's checklist from its own description/diff, then drive +it like one checklist item. + +## Bits under test + +``` +BITS: installed shipped artifact (read-only) +``` + +Same immutability rule as Scenario A — you are validating the **shipped artifact**, not source. +Forbidden / allowed list is in `index.md` → "bits contract" and `../pre-flight.md` §Hard rules. +The classic failure this scenario exists to catch (e.g. an installer that dropped a `Manifests\` +subfolder) only surfaces if you run the **documented user flow** and report FAIL when it doesn't +produce the claimed outcome — never paper over it by editing install state. + +--- + +## Step 0 — Acquire the PR set (discovery model) + +A full release can carry ~100 PRs; a hotfix ~10–25. Blindly looping 100 is the wrong default. +Resolve the set with the **smallest, most explicit source available**, then apply the size gate. + +### Input modes (prefer the most explicit one the caller gave you) + +| Mode | Source | How to enumerate | +|---|---|---| +| **1. Explicit set** *(preferred)* | PR numbers, a sign-off doc, or a draft/published release whose notes list the PRs | Parse the PR numbers directly. For a release: `gh api repos/microsoft/PowerToys/releases/` → extract `#NNNNN` from `.body`. | +| **2. Discoverable source** | A milestone, a release tag, or a commit/tag range | `gh pr list --repo microsoft/PowerToys --search "milestone:0.X" --state merged --limit 200 --json number,title,labels,files` · or for a range: `git log .. --oneline` then extract `(#NNNNN)` merge refs. | +| **3. Caller defers entirely** | "verify the latest release" with no list | Resolve to a concrete release/milestone first (mode 1/2). If you cannot, **ask** rather than guess. | + +### Size gate (the guardrail) + +Let `N` = enumerated candidate count, `MAX_AUTO = 25` (hotfix-sized; tune per request). + +- **`N ≤ MAX_AUTO`** → proceed: derive + verify each PR (this is the hotfix case — doing all is valid). +- **`N > MAX_AUTO`** → **STOP. Do not blind-loop.** Present the candidate list grouped by + module/area with counts, and require the caller to **scope** before deep-verifying: by module, + by label (e.g. `Needs-Verification`, priority), or an explicit subset. Confirm, then verify the + scoped set. **Depth beats throughput** — deeply verifying 20 PRs and leaving a clear queue of the + rest beats 100 shallow "source-verified" reports. + +### Pre-filter non-runtime PRs + +Before counting against the gate, set aside PRs with **no user-observable runtime surface** — list +them as `exempt` (not BLOCKED, not PASS) with the reason, don't spend drive cycles on them: + +- docs-only, CI/pipeline/build-only, dependency bumps, localization/translation-only, + release-signing/installer-plumbing with nothing to click. + +Detect via labels and changed-file paths (`gh pr view N --json files,labels`). Everything else +(anything a user opens/toggles/presses/types/previews) goes into the deep-verify set and is subject +to the live-drive floor below. + +--- + +## Step 1 — Per PR: derive the checklist, then drive it + +For each PR in the (possibly scoped) set: + +```powershell +gh pr view --repo microsoft/PowerToys --json title,body,files,labels,state,mergedAt +gh pr diff --repo microsoft/PowerToys # read the diff — it tells you what actually changed +``` + +Turn the description + diff into **1–3 concrete checklist items** (the observable claim(s) the PR +makes), then drive each with the `SKILL.md` §2 bucket selector and classify with `SKILL.md` §3. +If, after the description AND the diff, you still cannot tell what to verify → **FAIL +(cause=checklist)** ("Don't know what to test"), quoting the ambiguity — do not guess. + +You may `grep`/`view` a **read-only** local clone of `microsoft/PowerToys` (on `stable` or the +release tag) for source context (XAML AutomationIds, .cs referenced by the PR). You do **not** run +code from the clone against the installed build — that would be Scenario C. + +### Live-drive floor (anti-shallow-verification) + +If the PR has a verb a real user performs (open/toggle/press/drag/right-click/type/preview/paste/ +invoke/install/pin/search/record/scroll), the steps table MUST contain **≥4 `winapp ui …` rows** +and **≥1 `winapp ui screenshot` of the post-state**. A PR with a user-visible surface and zero +`winapp ui …` rows is **not validated**. "Source verified; live deferred" is a weasel-word that +downgrades the verdict (see `index.md` → verdict vocabulary). + +## Step 2 — Per-PR artifacts + report + +One folder per PR: `{Module}-PR{Number}/` (e.g. `CmdPal-PR48689/`). All screenshots and the PR's +`report.md` go there. The verdict lives **inside** `report.md`, not in the folder name. Use the +`../reporting-format.md` per-item table; the `winapp invoke` column is a hard contract — a literal +`winapp ui …` command or `—` (never a `Select-String`/`gh`/`Test-Path` in that column). + +## Step 3 — Roll-up + +Top-level summary table: PR · Module · verdict · one-line evidence, plus the `exempt` and +(if `N > MAX_AUTO`) the un-scoped **queue** of PRs not yet verified. Include the `BITS:` line and a +§G retrospective (run friction). Restore all mutated state and confirm the runner is healthy before +declaring done. + +## Worked reference + +The 0.100.1 14-PR sign-off (8 PASS / 6 BLOCKED) is a canonical Scenario-B run: derived each PR's +checklist from its release-notes line + diff, drove the installed bits, and blocked the +hardware/visual-only items (DDC/CI, dual-GPU, audio, transient capture overlays) with named +reasons. diff --git a/.github/skills/powertoys-module-verification/references/winapp-ui-testing.md b/.github/skills/powertoys-verification/references/winapp-ui-testing.md similarity index 99% rename from .github/skills/powertoys-module-verification/references/winapp-ui-testing.md rename to .github/skills/powertoys-verification/references/winapp-ui-testing.md index b5627abda170..e0606f0655d1 100644 --- a/.github/skills/powertoys-module-verification/references/winapp-ui-testing.md +++ b/.github/skills/powertoys-verification/references/winapp-ui-testing.md @@ -1,6 +1,6 @@ # WinUI UI-testing mechanics (winapp ui) -> **Provenance:** Adapted from the `winui-ui-testing` skill in [microsoft/win-dev-skills](https://github.com/microsoft/win-dev-skills) (MIT, © Microsoft Corporation and Contributors), with PowerToys-specific edits. This is a **reference doc** for the `powertoys-module-verification` skill — it is intentionally not a standalone skill (no frontmatter), so it is not separately discovered. +> **Provenance:** Adapted from the `winui-ui-testing` skill in [microsoft/win-dev-skills](https://github.com/microsoft/win-dev-skills) (MIT, © Microsoft Corporation and Contributors), with PowerToys-specific edits. This is a **reference doc** for the `powertoys-verification` skill — it is intentionally not a standalone skill (no frontmatter), so it is not separately discovered. Automated UI testing for WinUI 3 apps — generate a batch test script, run all tests in one pass, read results. Covers element assertions, interactions, value checking (TextBox, ComboBox, ToggleSwitch), file pickers, flyouts, dialogs, persistence, and accessibility audits. diff --git a/.github/skills/powertoys-module-verification/scripts/pt-admin-probe.ps1 b/.github/skills/powertoys-verification/scripts/pt-admin-probe.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-admin-probe.ps1 rename to .github/skills/powertoys-verification/scripts/pt-admin-probe.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-clipboard-diff.ps1 b/.github/skills/powertoys-verification/scripts/pt-clipboard-diff.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-clipboard-diff.ps1 rename to .github/skills/powertoys-verification/scripts/pt-clipboard-diff.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-cmdpal-recycle.ps1 b/.github/skills/powertoys-verification/scripts/pt-cmdpal-recycle.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-cmdpal-recycle.ps1 rename to .github/skills/powertoys-verification/scripts/pt-cmdpal-recycle.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-explorer-com.ps1 b/.github/skills/powertoys-verification/scripts/pt-explorer-com.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-explorer-com.ps1 rename to .github/skills/powertoys-verification/scripts/pt-explorer-com.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-explorer-contextmenu.ps1 b/.github/skills/powertoys-verification/scripts/pt-explorer-contextmenu.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-explorer-contextmenu.ps1 rename to .github/skills/powertoys-verification/scripts/pt-explorer-contextmenu.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-foreground-guard.ps1 b/.github/skills/powertoys-verification/scripts/pt-foreground-guard.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-foreground-guard.ps1 rename to .github/skills/powertoys-verification/scripts/pt-foreground-guard.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-nonelevated.ps1 b/.github/skills/powertoys-verification/scripts/pt-nonelevated.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-nonelevated.ps1 rename to .github/skills/powertoys-verification/scripts/pt-nonelevated.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-sendinput-chord.ps1 b/.github/skills/powertoys-verification/scripts/pt-sendinput-chord.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-sendinput-chord.ps1 rename to .github/skills/powertoys-verification/scripts/pt-sendinput-chord.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-session-diagnose.ps1 b/.github/skills/powertoys-verification/scripts/pt-session-diagnose.ps1 similarity index 91% rename from .github/skills/powertoys-module-verification/scripts/pt-session-diagnose.ps1 rename to .github/skills/powertoys-verification/scripts/pt-session-diagnose.ps1 index 689b1a505565..3e420e3b1e5f 100644 --- a/.github/skills/powertoys-module-verification/scripts/pt-session-diagnose.ps1 +++ b/.github/skills/powertoys-verification/scripts/pt-session-diagnose.ps1 @@ -3,9 +3,13 @@ # Tells you in one go: am I on the active console session, can I see foreground windows, # and can I use Shell COM. If not, prints the exact psexec mitigation command. -Add-Type 'using System; using System.Runtime.InteropServices; +# Guard Add-Type so this script can be dot-sourced / re-run in the same session without +# throwing "type already exists" on the second invocation. +if (-not ('WTS' -as [type])) { + Add-Type 'using System; using System.Runtime.InteropServices; public class WTS { [DllImport("kernel32.dll")] public static extern uint WTSGetActiveConsoleSessionId(); } public class FG { [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); }' +} Write-Host "--- Logged-on users + sessions ---" -ForegroundColor Cyan quser 2>&1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-shared-events.ps1 b/.github/skills/powertoys-verification/scripts/pt-shared-events.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-shared-events.ps1 rename to .github/skills/powertoys-verification/scripts/pt-shared-events.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-shell-verbs.ps1 b/.github/skills/powertoys-verification/scripts/pt-shell-verbs.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-shell-verbs.ps1 rename to .github/skills/powertoys-verification/scripts/pt-shell-verbs.ps1 diff --git a/.github/skills/powertoys-module-verification/scripts/pt-state.ps1 b/.github/skills/powertoys-verification/scripts/pt-state.ps1 similarity index 100% rename from .github/skills/powertoys-module-verification/scripts/pt-state.ps1 rename to .github/skills/powertoys-verification/scripts/pt-state.ps1