mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 10:09:43 +02:00
523409ed068dfd52c90a2e57935ccd1a17f7b52a
910 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
523409ed06 |
Add AI-assisted PR triage (#49911)
## Summary of the Pull Request Adds AI-assisted pull request triage using GitHub Agentic Workflows. A bounded Copilot pass summarizes each PR and classifies screenshots, GIFs, or video as required, recommended, or unnecessary. Deterministic publishing validates the exact PR evidence hash, closing issue references, merge conflicts, draft state, and supplied visual evidence before updating one canonical comment. The workflow manages only `Needs-Review` and `Needs-Author-Feedback`. Missing issue references are advisory; invalid references, merge conflicts, and missing required visual evidence block readiness. Existing resource-management automation continues to close inactive PRs awaiting author feedback. ## PR Checklist - [ ] Closes: #xxx - [x] **Communication:** Discussed the intended PR intake flow and comment format - [x] **Tests:** Added/updated and all pass - [x] **Localization:** No product strings added - [x] **Dev docs:** Added workflow documentation - [x] **New binaries:** Not applicable - [x] **Documentation updated:** Repository automation documentation updated ## Validation Steps Performed - `node --check .github/scripts/pr-intake/pr-intake.mjs` - `node --test .github/scripts/pr-intake/tests/pr-intake.test.mjs` — 23 passing - `gh aw compile pr-intake` with gh-aw v0.86.2 - Read-only preprocessing against PR #49905 confirmed four changed files, no visual-evidence hint, and `mergeable=false` / `mergeable_state=dirty` is detected as a blocking conflict Copilot-Session: 3067a641-aa79-4f96-8d9f-eaa1c6d9b3cf |
||
|
|
8088120b06 |
Improve issue triage product-label detection (#49905)
## Summary Issues that put the module in a `[Module]` title prefix (a common PowerToys convention) but omit the bug template's **"Area(s) with issue?"** section were left **Unclassified** with no `Product-*` label — e.g. #49899 *"[Screen Ruler] Settings crashes ..."* got no `Product-Screen Ruler` label despite the title. Root cause: product-label detection was purely deterministic and narrow. `parse_area` (`.github/scripts/issue-triage/issue-context.py`) only read the template area section or a 6-entry keyword map, and the agent prompt instructed the model to copy that candidate verbatim (and send `None` otherwise). The `[Module]` title convention was never consulted. ## Change (two layers) **1. Deterministic title-prefix matching (primary).** Parse the leading `[Module]` bracket(s) in the title and match against existing `Product-*` labels; upgrade the detected area when the body has no area signal. Fully deterministic and auditable — this alone fixes Screen Ruler and every other bracketed title. **2. Constrained AI fallback (secondary).** Expose the repo's `Product-*` labels as `Available product labels` in the deterministic evidence, and allow the agent — **only when the deterministic candidate is `None`** — to select the single best-matching existing label. This is safe because the publisher already validates the agent's `product_label` against the real label set, so the agent can only ever **add a valid existing label**, never invent one or remove/change others. The workflow prompt is `{{#runtime-import}}`-ed from `issue-triage.md`, so the lock file changes only by its `body_hash` (sync check); recompiled with the repo's current gh-aw `v0.84.3` to avoid unrelated version drift. ## Tests New unit tests in `tests/test_issue_context.py`: - `test_title_prefix_maps_to_existing_product_label` - `test_available_product_labels_are_sorted_and_filtered` - `test_prepare_labels_bracketed_title_without_area_section` All 30 tests pass (`python -m unittest tests.test_issue_context`). ## Files - `.github/scripts/issue-triage/issue-context.py` — title-prefix detection, available-label list, wiring - `.github/scripts/issue-triage/tests/test_issue_context.py` — new tests - `.github/workflows/issue-triage.md` — prompt allows constrained fallback - `.github/workflows/issue-triage.lock.yml` — recompiled (`body_hash` only) Generated with the GitHub Copilot CLI. Co-authored-by: niels9001 <niels9001@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 26025067-259e-43e3-9dc7-a9fc4b5ba58b |
||
|
|
105ef0abcb |
Add Daily Dedupe Digest workflow driven by AI Issue Triage output (#49907)
## Summary Rewrites the Daily Dedupe Digest as a lightweight aggregator over the existing **AI Issue Triage** workflow, superseding #48244. Instead of running its own `gpt-4o-mini` duplicate-detection pass, this workflow treats the triage workflow as the single source of truth. AI Issue Triage already: - posts a canonical comment per issue (marker `<!-- powertoys-ai-triage:canonical:v1 -->`) containing a `### 🔁 Possible duplicates` section, and - files a *pending* native duplicate-close suggestion pointing at the strongest canonical candidate. The digest simply collects those and drops them into one daily review issue. ## Behavior Runs daily (`0 8 * * *`) and via `workflow_dispatch`. Each run: 1. Ensures the `dedupe-digest` label exists. 2. Builds a candidate set from **carry-over** issues remembered in the previous digest (hidden `<!-- dup:ISSUE=.. CANON=.. -->` markers) plus **fresh** open issues updated in the lookback window (default 26h). 3. Re-validates each candidate against its *live* triage comment — issues that are closed or labeled `duplicate` / `Resolution-Duplicate` drop out automatically. 4. Opens a **new** issue each day, assigned to `@niels9001`, listing every flagged issue (the duplicate → to close) with its suggested canonical issue (→ keep) and the triage reason. Links to each triage summary comment are included. 5. Closes the previous digest, superseded by the new one. 6. If nothing is flagged, it closes the previous digest and creates none. ## Notes - No model calls / no `models: read` permission — only `issues: write`. - Untrusted issue/comment text is sanitized (HTML comments, control chars, angle brackets stripped) before being written into the digest, to avoid marker injection. - Tunable via `env`: assignee, label, title prefix, lookback hours, scan/flag caps, resolved-duplicate labels. Supersedes #48244. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: niels9001 <niels9001@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 26025067-259e-43e3-9dc7-a9fc4b5ba58b |
||
|
|
5485e27a0c |
Bump AI Issue Triage gh-aw engine and image versions (#49885)
## Summary The **AI Issue Triage** agentic workflow ([run 31779057901](https://github.com/microsoft/PowerToys/actions/runs/31779057901/job/94700789335)) failed at the **Execute GitHub Copilot CLI** step. The Copilot CLI binary was missing at `/usr/local/bin/copilot` inside the AWF firewall agent container: ``` [copilot-harness] pre-flight: command not found: /usr/local/bin/copilot (F_OK check failed — binary does not exist at this path) [copilot-harness] attempt 1: failed to start process '/usr/local/bin/copilot': spawn /usr/local/bin/copilot ENOENT [copilot-harness] attempt 1: no output produced — not retrying ``` With no output produced, the harness exited with code 1 and the job failed. ## Change Recompiled the workflow with `gh aw upgrade` (gh-aw `v0.84.3` → `v0.86.2`), which refreshes the pinned engine, images and actions — including the agent container image that ships the Copilot CLI binary. | Component | Before | After | | --- | --- | --- | | `github/gh-aw-actions/setup` | `v0.84.3` | `v0.86.2` | | gh-aw compiler | `v0.84.3` | `v0.86.2` | | AWF firewall (agent/api-proxy/squid) | `0.27.43` | `0.27.44` | | Copilot CLI (agent) | `1.0.77` | `1.0.79` | | `gh-aw-mcpg` | `v0.4.7` | `v0.4.9` | | `github-mcp-server` | `v1.8.0` | `v1.9.0` | All container images are digest-pinned; digests were verified against GHCR. ## Files - `.github/workflows/issue-triage.md` — engine/action version normalization - `.github/workflows/issue-triage.lock.yml` — recompiled lock file - `.github/aw/actions-lock.json` — bumped `gh-aw-actions/setup` pin Generated with the GitHub Copilot CLI. Co-authored-by: niels9001 <niels9001@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 26025067-259e-43e3-9dc7-a9fc4b5ba58b |
||
|
|
57b01a1c4e |
Add issue triage actions (#49828)
## Summary of the Pull Request Replaces the retired GitHub Models-based automatic issue triage and deduplication flows with the GitHub Agentic Workflow proven in the `niels9001/powertoys-ai-triage-sandbox`. This PR also: - aligns `Needs-Author-Feedback` closure to 7 days for issues and PRs; - removes the automatic GitHub Models issue/PR labeler; - removes the automatic GitHub Models new-issue deduplicator; - removes the Azure Pipelines XAML Styler verification step while retaining the local styling script. This is a draft because production rollout still requires the appropriate privacy and Responsible AI reviews. ## Issue triage rules ### Triggers and refresh behavior - Runs when an issue is opened, edited, or reopened. - Runs when the issue author attaches a `PowerToysReport_*.zip` in a comment. - Maintainers can force regeneration with `/triage refresh`. - Ignores unrelated comments, unchanged issue edits, PR comments, and bot-initiated reopens. - Uses per-issue concurrency so a newer run supersedes an older run. - Maintains one canonical triage comment instead of adding repeated bot comments. ### Comment format - Separates **For the issue author** from **For the PowerToys team**. - Mentions the author once and lists each requested action as a bullet. - Distinguishes blocking **Needed** actions from non-blocking **Recommended** actions. - Shows the product, issue kind, reported PowerToys version, concise summary, diagnostic findings, possible duplicates, and collapsed investigation checks. - Ends with a short disclosure that triage is AI-assisted and maintainers make final decisions. ### Classification and labels - Detects PowerToys bug-template issues deterministically. - Reads the selected product area and adds a matching primary `Product-*` label. - Handles production aliases such as FancyZones Editor and File Explorer preview/thumbnail areas. - Product labeling is additive: existing product and maintainer labels are never removed. - Normalizes the reported PowerToys version and adds a matching version label when one exists. - Applies `Needs-Author-Feedback` only when blocking information or an English translation is required. - Removes `Needs-Author-Feedback` when the issue becomes actionable. ### PowerToys version rule - Compares the reported version with the latest stable PowerToys GitHub release. - Older versions receive a recommended update-and-retest action. - Current versions, newer preview/dev versions, missing versions, and release lookup failures are not flagged as outdated. - Updating is advisory and does not block triage by itself. ### Reproduction rule - Concrete actions plus an observed result are sufficient. - Concise steps can use the separate Actual Behavior section as the observed result. - Passive or intermittent failures are sufficient when the timing/trigger and observed failure are clear. - Vague statements without an actionable scenario remain insufficient. - Clearly non-English steps are not treated as missing; reproduction is reassessed after the author translates the issue. ### Language rule - Classifies author-written prose as English, non-English, or uncertain. - Ignores template headings, code, logs, filenames, URLs, hidden comments, and quoted text. - Clearly non-English issues ask the author to translate the title and description to English. - Short, mixed, code-heavy, or uncertain text is not flagged. ### Diagnostic report rule - A report is **required** for diagnostic-heavy failures: crashes, hangs, startup/load failures, installation/update failures, performance failures, and service/driver/shell-integration failures. - A report is **optional** for clear reproducible UI/visual defects. - A report is **recommended**, but not blocking, for other actionable bugs. - Missing or rejected reports block only when the deterministic requirement is `REQUIRED`. ### Diagnostic report privacy and safety - Accepts only PowerToys report attachment URLs matching the expected pattern. - Enforces archive size, decompressed size, file-count, per-file, path traversal, and encryption limits. - Selects only bounded relevant metadata and product-log evidence. - Redacts email addresses, IP addresses, user paths, URLs, GUIDs, SIDs, identity fields, tokens, secrets, and passwords. - Sends only the sanitized evidence to Copilot. - Never sends the raw ZIP or extracted files to Copilot, logs, artifacts, or repository storage. - Deletes the temporary archive after processing. ### Duplicate rule - Searches only older issues using focused product, title/body, and exact technical-signal queries. - Ranks candidates deterministically before Copilot runs. - Copilot judges only the supplied candidates and returns at most five high-confidence matches. - Similar product area alone is not enough; the underlying request or failure must match. - The model never closes an issue directly. - The workflow submits the strongest match as a native GitHub duplicate-close suggestion. - **When a maintainer accepts the suggestion, GitHub automatically closes the issue as a duplicate and links it to the selected canonical issue.** - Declining the suggestion leaves the issue open. - A defensive safeguard reopens the issue and fails the run if GitHub applies the close without holding it for review. ### AI cost and permission controls - Uses the `small` model alias. - Maximum 5 turns and 10 AI credits per run. - Maximum 300 AI credits per day. - Maximum 5 runs per user per 60-minute window. - Content hashing skips unchanged work before inference. - The agent receives only `contents: read`, `issues: read`, and `copilot-requests: write`. - A separate validated safe-output job receives `issues: write`. ## Seven-day author-feedback lifecycle The existing Microsoft GitHub Policy Service configuration remains responsible for stale closure: - Open issues with `Needs-Author-Feedback` and no activity for 7 days are closed with an explanatory comment. - Open PRs with `Needs-Author-Feedback` and no activity for 7 days are closed with an explanatory comment. - An author comment removes `Needs-Author-Feedback` and returns the issue/PR to team triage. - An author push removes `Needs-Author-Feedback` from a PR. - Manually removing the label immediately makes the issue or PR ineligible for scheduled closure. ## Deprecated automation - Deletes `.github/workflows/automatic-issue-deduplication.yml`. - Deletes `.github/workflows/auto-labeler.yml`. - Automatic PR product labeling from the old Models workflow is intentionally not replaced in this PR; a production PR ownership/path map should be agreed separately. - Keeps the manual batch deduplication workflow unchanged. - Removes the passive XAML Styler verification step from `.pipelines/v2/templates/job-build-project.yml`. - Keeps `.pipelines/applyXamlStyling.ps1` available for local developer use. ## Validation Steps Performed - Compiled `.github/workflows/issue-triage.md` with `gh aw compile`. - Ran 32 focused Python tests for issue parsing, duplicate retrieval, version checks, reproduction rules, language signals, archive validation, report selection, redaction, and output privacy. - Parsed the changed workflow and resource-management YAML. - Verified the required production labels exist. - Tested the workflow against the latest 20 PowerToys issues in the sandbox; all 20 produced one canonical comment. - Verified live variants for outdated versions, intermittent/passive reproduction, non-English issues, rejected and analyzed reports, optional UI reports, and title-only issues. ## PR Checklist - [ ] **Communication:** Discussed with core contributors. - [x] **Tests:** Added/updated and all focused tests pass. - [ ] **Privacy / Responsible AI:** Complete required production reviews before enabling. - [x] **Localization:** No product UI strings are added. - [x] **Dev docs:** Updated repository automation documentation. - [x] **New binaries:** None. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 18a9b8ad-fd7e-4b9d-a06c-5e350bcde9d7 Copilot-Session: fd512b9b-db6f-4004-a65b-aa49404d568d |
||
|
|
69a600e249 |
feat(File Explorer): Add configurable local image rendering to Markdown previewer (#47857)
## Summary - Adds a "Show local images" toggle in PowerToys Settings (File Explorer > Markdown) - When enabled, renders images referenced via relative paths or local file paths in the Markdown preview pane - Serves validated local image files on a WebView2 virtual host (`https://localmdimages/`) directly from the handler's resource filter - Supports local paths and UNC/network share paths - Default: OFF (preserves existing behavior) - GPO support: Admins can force-enable or force-disable via Group Policy Fixes #40787 Fixes #3713 ## Security model | Scenario | Behavior | |----------|----------| | Setting OFF (default) | All images blocked, info bar shown. Raw HTML `src` is rewritten to `#` in this state too, so a `data:` image cannot render (it is resolved internally and never reaches the resource filter) | | Setting ON + relative path (`media/img.png`) | Resolved against .md directory, rendered if under that tree | | Setting ON + path traversal (`../../secret.png`) | Blocked — resolved with `Path.GetFullPath` and checked with `Path.GetRelativePath`, including percent-encoded traversal on the serving side | | Setting ON + junction/symlink below the allowed path | Blocked — each component of the resolved path is rejected if it carries `FileAttributes.ReparsePoint`, since lexical containment alone does not prevent redirection | | Setting ON + UNC relative path (`images/pic.png` on `\\server\share`) | Allowed within share root | | Setting ON + remote URL (`https://evil.com/track.png`) | Always blocked | | data:/javascript: URI | Always blocked, in both setting states | | `srcset` on a raw HTML `<img>` | Attribute removed, in both setting states — its candidates are not validated by the `src` sanitizer | | Script execution | Always disabled (`IsScriptEnabled = false`) | | Mark-of-the-Web (MotW) | Explorer blocks preview of MotW-tagged files before our code runs (OS-level protection) | ## GPO Policy - Policy name: `MarkdownAllowLocalImages` - Registry: `HKLM\SOFTWARE\Policies\PowerToys\MarkdownAllowLocalImages` (DWORD: 1=enabled, 0=disabled) - ADMX category: **PowerToys > File Explorer Preview** - Uses `getConfiguredValue()` (individual module setting pattern, no global utility fallback) ## Screenshots ### Settings UI — new toggle _"Show local images" toggle nested under the Markdown preview section (File Explorer add-ons). Captured from a Debug build of this branch (the Settings app only runs standalone in Debug builds):_ <img width="1904" height="1014" alt="07-settings-ui-toggle" src="https://raw.githubusercontent.com/st-gr/PowerToys/pr-47857-assets/07-settings-ui-toggle.png" /> ### Settings UI — locked by GPO _With the `MarkdownAllowLocalImages` policy set to Disabled, the toggle is forced Off and grayed out, and the "managed by your organization" info bar appears:_ <img width="1904" height="1014" alt="08-settings-ui-gpo-locked" src="https://raw.githubusercontent.com/st-gr/PowerToys/pr-47857-assets/08-settings-ui-gpo-locked.png" /> ### GPO in Group Policy Editor _New "File Explorer Preview" category under PowerToys, showing the policy and its description:_ <img width="1472" height="847" alt="01-gpedit-category" src="https://github.com/user-attachments/assets/54acb539-345b-4512-9685-35930966a142" /> ### GPO set to Enabled _Policy enabled state in gpedit.msc:_ <img width="1473" height="848" alt="02-gpedit-policy-enabled" src="https://github.com/user-attachments/assets/883f6b22-179d-4311-983d-2d835e4d897a" /> ### Preview with local images rendered _Markdown preview with local image rendering enabled — relative path image renders:_ <img width="1430" height="881" alt="03-preview-images-shown" src="https://github.com/user-attachments/assets/4a7ac7f0-d57d-4feb-bf2f-7e3c9093ab52" /> ### Info bar for blocked remote images _When the document contains remote (http/https) image URLs, they are always blocked and an info bar is shown:_ <img width="1412" height="1035" alt="04-preview-infobar" src="https://github.com/user-attachments/assets/0f798bbc-ae1b-43bf-b343-394080fff8e3" /> ### GPO disabled — all images blocked _With GPO set to disabled, all images (local and remote) are blocked. Info bar reads "Some pictures have been blocked...":_ <img width="1417" height="704" alt="05-gpo-disabled-blocked" src="https://github.com/user-attachments/assets/1c7a09a7-f4b9-467c-a0c0-f670680d6a2d" /> ### Mark-of-the-Web protection _Files copied from a network source carry a Zone Identifier (MotW). Explorer blocks the preview entirely before our code runs — an OS-level security layer:_ <img width="1114" height="591" alt="06-MotW-tagged" src="https://github.com/user-attachments/assets/09cc2055-1e12-4c11-81fb-abd83ab8249c" /> ## Implementation Two layers were blocking images: 1. **Markdig AST layer** (`HTMLParsingExtension.cs`): replaced image URLs with `#` 2. **WebView2 layer** (`MarkdownPreviewHandlerControl.cs`): returned HTTP 403 for all non-HTML requests Changes: - `HTMLParsingExtension`: conditionally resolves markdown `` images to virtual host URLs with path traversal protection - `MarkdownHelper`: regex-rewrites relative `src=""` in raw HTML `<img>` tags to virtual host URLs - `MarkdownPreviewHandlerControl`: serves `https://localmdimages/` requests in the `WebResourceRequested` handler — the URL is resolved back to a file path, re-validated for containment against the allowed base path (document directory, or share root for UNC), and the bytes are returned via `CreateWebResourceResponse` with the proper content type. Note: `SetVirtualHostNameToFolderMapping` is deliberately NOT used for images — WebView2 Runtime 150+ no longer serves files from UNC/network folder mappings (verified by A/B test on 150.0.4078.48); serving from the handler works uniformly for local and UNC paths - Settings UI: new toggle nested under the Markdown preview expander, with GPO lock support - Handler `Settings.cs`: reads `EnableMdLocalImages` via `SettingsUtils`, GPO override via `GPOWrapper` - GPO: `gpo.h` individual module setting, ADMX/ADML with `FileExplorerPreview` category ## Known limitation Peek also renders Markdown through `FilePreviewCommon.MarkdownHelper`, but calls it without the local-images arguments, so **Peek does not show local images even when the setting is enabled** — it keeps the existing behavior of blocking every image. With the setting on, the same file therefore renders differently in the preview pane (images shown) and in Peek (images blocked). This is deliberate for now: wiring the setting through Peek means changing a module that is otherwise untouched by this PR. Verified that Peek itself is unaffected — it still renders Markdown correctly against the shared assembly, with images blocked as before. ## Test plan - [x] Toggle OFF: images blocked, "pictures blocked" info bar shows (existing behavior) - [x] Toggle ON with relative paths: `` renders - [x] Toggle ON with HTML img: `<img src="images/test.png">` renders - [x] Toggle ON with path traversal: `` — blocked - [x] Toggle ON with remote URL: `` — blocked, info bar shown - [x] UNC path: preview works on `\\server\share\...\file.md` with relative images - [x] UNC path with `../` within share: allowed (resolves within share root) - [x] Regression tested on WebView2 Runtime 150.0.4078.48: local + UNC images render, blocked cases (traversal, data:, remote, encoded traversal) stay blocked - [x] GPO Enabled: images forced on - [x] GPO Disabled: images forced off - [x] GPO Not Configured: user controls toggle - [x] gpedit.msc: policy appears under PowerToys > File Explorer Preview - [x] MotW-tagged files: Explorer blocks preview before our code runs - [x] Settings UI toggle locked when GPO configured (grayed out for both forced states) - [x] Other preview handlers (Monaco, SVG, PDF) unaffected 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
5193a1e497 |
Pin GitHub Actions to full-length commit SHAs (#49848)
Just like it says on the tin. |
||
|
|
b605fd35c5 |
New+ Rename and Desktop icon positioning improvements (#48083)
New+ Rename and Desktop icon positioning improvements. Manually tested on Windows 11. Windows 10 updates have NOT been tested. ## Summary of the Pull Request * Obtain cursor position early in the lifecycle of the context menu * Busy wait until copy is complete and shell is aware of icon * If context menu is on desktop, reposition the icon using the cursor position obtained scaled using monitor appropriate DPI * Slight refactor to help port code from New++ to New+ ## PR Checklist - [x] Closes: #36440 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [n/a] **Localization:** All end-user-facing strings can be localized - [n/a] **Dev docs:** Added/updated - [n/a] **New binaries:** Added on the required places - [n/a] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [n/a] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [n/a] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [n/a] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [n/a] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments * n/a ## Validation Steps Performed **Windows 11** * x64: Manually tested * ARM64: Not tested **Windows 10** * Not tested --------- Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 41b6b39b-b620-4e02-b7ca-8ae470a9c1e2 |
||
|
|
e48152c52d |
[UITests] Add UITest.Next suites (Image Resizer, Peek, File Explorer add‑ons, File Locksmith) + local‑VM tooling and CI test‑signing (#49671)
## Summary Adds end‑to‑end UI tests on the `Microsoft.PowerToys.UITest.Next` (winappcli) framework for three modules, grows the shared `.Next` test framework with the helpers those suites needed, and adds the CI plumbing that lets shell‑extension tests exercise the **real** Windows 11 modern context menu. Also ships two agent skills that document how to write and run these tests. Product runtime behavior is **unchanged** — the only product edits are test‑observability hooks in Peek and a unit‑test project exclude. Closes: https://github.com/microsoft/PowerToys/issues/40660 https://github.com/microsoft/PowerToys/issues/49424 https://github.com/microsoft/PowerToys/issues/40661 ## What's added ### New UI test suites - **Image Resizer** — `src/modules/imageresizer/tests/ImageResizer.UITests`: context‑menu enable/disable tracking, the resize dialog, custom presets, every fit mode, every unit, filename format, keep‑date, shrink‑only, replace‑in‑place, and orientation. - **Peek** — `src/modules/peek/Peek.UITests.Next`: file‑preview coverage across image/text/archive/ markdown types with per‑arch visual baselines. - **File Explorer add‑ons** — `src/modules/previewpane/PreviewPane.UITests`: Preview Pane handlers and thumbnail providers. ### `UITestAutomation.Next` framework - New helpers: `ExplorerShell` (Shell selection/view‑mode interop), `WaitHelper` (structured stable waits), `WindowControl` (foreground/context‑menu/process control), `VisualAssert` (image compare), `WindowHelper`. - Updates to `Session`, `UITestBase`, `SettingsConfigHelper`, `WinappCli`. - New `UITestAutomation.Next.UnitTests` project covering the new wait/settings/CLI helpers. ### CI — sign sparse MSIX so the modern menu registers - **`.pipelines/signSparsePackages.ps1`** — self‑signs each sparse context‑menu MSIX with a publisher‑matching test certificate and force‑trusts it (machine stores), so `AddPackageByUriAsync` succeeds on otherwise‑unsigned PR builds. Robust `signtool` discovery with a NuGet fallback; test‑only trust that asserts no security. - Wired into **`.pipelines/v2/templates/job-test-project.yml`** as a best‑effort step covering the run‑in‑place, machine‑install, and per‑user‑install locations. Signs nothing it can't (skips already‑signed packages) and never fails the job. ### Product changes (test observability only) - **Peek `FilePreview.xaml` / `.xaml.cs`** — a named `LoadingIndicator` and a hidden automation peer that exposes the current preview state as text, so tests can read load state deterministically. No runtime behavior change. - **`ImageResizer.UnitTests.csproj`** — exclude the sibling `ImageResizer.UITests\**` folder from the unit‑test compilation. ### Agent skills & docs - **New `ui-tests-local-vm` skill** — run `.Next` suites in persistent dockur/windows VMs: setup, agentic loop, image customization, troubleshooting, the shell‑extension **signing** reference, plus controller/guest scripts and VM templates. - **Updated `ui-tests-migration` skill** — WinAppDriver/Selenium → `.Next` porting guidance (CI stability, Explorer/shell‑extension test design, patterns & pitfalls). - **`doc/devdocs/development/ui-tests.md`** — updated for the `.Next` workflow. ## Testing - All three suites pass locally and in CI across **x64 Win10**, **x64 Win11**, and **arm64** (machine and per‑user install legs). ## Reviewer notes - No product runtime behavior changes; product edits are limited to the Peek test hooks above. - The CI signing step is a **test‑only** trust anchor (self‑signed, scoped to the agent) and is best‑effort, so it can only add modern‑menu coverage and never regress the job. |
||
|
|
68a2a0d57b |
[Modules] Handle WM_ENDSESSION in run_message_loop daemons (GrabAndMove, AlwaysOnTop, FancyZones) (#48404)
## Summary Companion PR to #48378 (runner). Fixes the same `APPLICATION_HANG_QUIESCE_*_PowerToys.exe!run_message_loop` WER bucket in the other PowerToys daemons whose top-level windows ignored `WM_ENDSESSION`. ## Root cause (same as #48378) `run_message_loop` (`src/common/utils/window.h`) calls `GetMessageW` which only returns `0` on `WM_QUIT`. If a daemon's WndProc lets `WM_ENDSESSION` fall through to `DefWindowProc`, no `WM_QUIT` is ever posted on logoff/shutdown, the loop blocks, CSRSS hits the quiesce timeout (~5s), `TerminateProcess` fires, and Watson logs `APPLICATION_HANG_QUIESCE`. ## `run_message_loop` callsite audit 8 production callsites. Persistent daemons that own a top-level window and were affected: | Module | Status before | Fix here | |---|---|---| | `runner` | hang | Fixed in #48378 | | `GrabAndMove` | hang (tray icon, NIM_DELETE in WM_DESTROY) | ✅ `main.cpp` | | `AlwaysOnTop` | hang | ✅ `AlwaysOnTop.cpp` | | `FancyZones` | hang | ✅ `FancyZones.cpp` | | `KeyboardManagerEngine` | n/a | No top-level window → OS skips WM_ENDSESSION and TerminateProcess directly; no hang bucket possible | | `ZoomIt` | already handled | SysInternals heritage | | `PowerLauncher` | already handled | Managed `SessionEnding` event | | `MeasureTool`, `Notifications` | transient/spawned on demand | Not a shutdown-time daemon | ## Fix pattern For `AlwaysOnTop` and `FancyZones` (no tray icon to clean up) — minimal: ```cpp case WM_ENDSESSION: if (wparam) PostQuitMessage(0); // wparam==FALSE => shutdown vetoed return 0; ``` For `GrabAndMove` (has `Shell_NotifyIcon` cleanup in `WM_DESTROY` that must not run on shutdown) — use a `g_session_ending` flag and skip the tray-icon delete in `WM_DESTROY`, mirroring runner's `tray_icon.cpp` pattern from #48378. No shared header: each module's `WM_DESTROY` cleanup is module-specific; the abstraction would be too thin and would hide the variance in what to *skip*. ## Why no logging on the shutdown path Same reasoning as #48378 review feedback — `spdlog::flush_on(info)` synchronously flushes to disk; emitting log lines from `WM_ENDSESSION`/`WM_DESTROY` burns the ~5s quiesce budget for no diagnostic value (Watson already records the bucket on failure). ## Verification - Built clean (Debug|x64): GrabAndMove.vcxproj, AlwaysOnTop.vcxproj, FancyZonesLib.vcxproj — all exit 0. - Runner counterpart fix (#48378) verified end-to-end with real reboot + WM_ENDSESSION injection; quiesce 1–8 ms. Same OS-level mechanism applies here. ## Related - #48378 — runner fix (this PR's companion) - #48363 — original community fix (over-engineered; this approach is the minimal correct one) --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
a87f5b07a9 |
Advanced Paste additional customizations and PhiSilica provider (#46727)
## Summary Adds an on-device **Phi Silica (Windows AI) paste provider** to Advanced Paste and richer per-action customization, plus the **package-identity plumbing** that lets the unpackaged Advanced Paste app use Windows AI APIs. > Note: this supersedes the earlier "self-contained MSIX package installed/registered by the > WiX installer" approach. Advanced Paste is **not** packaged or installed as a standalone > MSIX. It keeps shipping as the existing unpackaged, self-contained WinUI 3 executable in > `WinUI3Apps/` and acquires **package identity at runtime from the existing PowerToys sparse > package** — there are no installer or ESRP MSIX repack changes. ## Advanced Paste features - **New Phi Silica paste provider** (`CustomActions/PhiSilicaPasteProvider.cs`): an on-device AI provider backed by the Windows AI Phi Silica language model — no cloud endpoint or API key required. Registered as a new `AIServiceType` via `PasteAIProviderFactory` / `AIServiceTypeRegistry`. - **Additional custom actions** (`AdvancedPasteAdditionalAction`): user-defined actions with their own prompt, system prompt, AI provider, and shortcut — plus an optional "coaching" prompt/system-prompt/provider/shortcut and shortcut-conflict detection. - **Built-in default prompts** (`AdvancedPasteDefaultPrompts`) and updates to `AdvancedPasteCustomAction`, `PasteFormat(s)`, `OptionsViewModel`, and `PasteFormatExecutor` to support per-action provider selection and system prompts. - **Settings UI** (`AdvancedPastePage.xaml`/`.xaml.cs`, `Resources.resw`): configure the Phi Silica provider, choose a provider per action, edit system/coaching prompts, and a Phi Silica availability/readiness experience — Settings queries the Advanced Paste executable via `--check-phi-silica`, and a **"Download model"** action triggers `--prepare-phi-silica` to fetch the model and then re-probes. ## Package identity for Windows AI (replaces the MSIX-install approach) - Phi Silica is a **Limited Access Feature (LAF)** that can only be unlocked by a process with a registered **package identity**. Advanced Paste runs unpackaged, so it obtains identity from the existing **`Microsoft.PowerToys.SparseApp`** sparse package (`src/PackageIdentity/`): a new `<Application Id="PowerToys.AdvancedPasteUI">` entry in `AppxManifest.xml` maps it to `PowerToys.AdvancedPaste.exe`, with matching updates to `BuildSparsePackage.ps1`. - **LAF unlock** at runtime via `PhiSilicaLafHelper.cs`. The token/attestation are baked at build time by the `GeneratePhiSilicaLafCredentials` MSBuild target into `PhiSilicaLafCredentials.g.cs` — local **dev defaults** live in `src/PhiSilicaLaf.props` (imported from `Directory.Build.props`) and the **production secret** is injected via `/p:` in the release pipeline. - New **`AdvancedPaste.dev.manifest` / `AdvancedPaste.prod.manifest`** application manifests (selected by `CIBuild`) declaring full-trust and the system AI models capability. ## Build & pipeline - **Windows App SDK** moved to the coherent **stable `2.2.0`** line and **added `Microsoft.WindowsAppSDK.AI` `2.2.3`** (the Phi Silica APIs). Foundation `2.1.0` carries the sparse-identity PRI fix, and the stable AI build matches the OS Windows AI runtime. - **Independent versioning** for Advanced Paste (`src/modules/AdvancedPaste/custom.props`, XES one-store versioning, `AdvancedPasteVersion`). A `steps-setup-versioning.yml` step is added for Advanced Paste in `job-build-project.yml`, ordered **before** CmdPal to avoid a version-collision installer failure (WIX0103). - `release.yml` passes `PhiSilicaLafToken`/`PhiSilicaLafAttestation` into the main build; spell-check allow-list/patterns updated. - Removed now-unneeded dependencies: the `Microsoft.Windows.Compatibility` reference and the `Common.UI` "force matching DLL versions" hack. <img width="1073" height="716" alt="image" src="https://github.com/user-attachments/assets/9364d86a-c0d1-4a08-a669-d98cbcb4b140" /> <img width="1038" height="308" alt="image" src="https://github.com/user-attachments/assets/00eef1dd-b407-4841-bd64-f54f8a145c46" /> <img width="194" height="405" alt="image" src="https://github.com/user-attachments/assets/d2f9c5bb-2507-4112-b3e0-56da681f88ea" /> <img width="489" height="453" alt="image" src="https://github.com/user-attachments/assets/811d1afd-9993-48be-824e-82bb56c5ceca" /> [Video clip internal](https://onedrive.cloud.microsoft/✌️/a@9n6nl3fp/S/cQpvAHrL5M9ZR6eUawztyfyBEgUCwCF-aKg9TbKyyGWP4c0KMA) [Build internal](https://microsoft.visualstudio.com/Dart/_build/results?buildId=149920754&view=artifacts&pathAsName=false&type=publishedArtifacts) --------- Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> |
||
|
|
e0010c5642 |
Ready for Review - [Mouse Jump] - port upstream WinUI3 code to Mouse Jump (microsoft#48290) (#48393)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Changes for #48290 to convert Mouse Jump to a WinUI app and remove all
remaining dependencies on WinForms, based on work already done in the
original "FancyMouse" project
(https://github.com/mikeclayton/FancyMouse).
## Notes for reviewers
* the new WinUI build of the app is output into the "/WinUI3Apps"
subfolder
* there's 2 new assemblies that need to be added to the installation as
well - MouseJump.HotKeys.dll and MouseJump.Models.dll. I'm not sure how
to add those to the installer for signing / shipping...
---
### Summary of changes
* New thumbnail layout and rendering code
* WinUI rewrite (winforms version still committed)
* MouseJump.Kicker (dev launch tool)
* CsWin32 for interop
* New assemblies - code reorganised
---
### 1. New layout code
Incorporates latest FancyMouse core layout and rendering logic into
Mouse Jump:
* includes **support** for multiple devices in layout algorithms
* preview still only shows local machine though
* prerequisite for long-term goal #34126
<img width="650" height="709" alt="image"
src="https://github.com/user-attachments/assets/9d1d996d-ed05-4471-b8a5-bd93442f70dc"
/>
### 2. WinUI rewrite
Port latest stable FancyMouse WinUI implementation into Mouse Jump.
Existing WinForms UI left in-situ side-by-side for now - easy to delete
if not needed.
### 3. MouseJump.Kicker
A small dev utility to start Mouse Jump without needing to build the
runner project:
<img width="283" height="274" alt="image"
src="https://github.com/user-attachments/assets/c81bb3f5-5008-48ce-8bc0-eef18413dee6"
/>
### 4. Cswin32 for interop
All win32 interop is now accessed via CsWin32 bindings.
The original win32 bindings were heavily influenced by CsWin32 generated
code (e.g. ```BOOL```, ```HWND```, etc structs), so there's not actually
much change other than deleting a lot of boilerplate code.
### 5. New assemblies
Some code has been reorganised into new assemblies to make it easier to
keep Mouse Jump in sync with upstream FancyMouse
* MouseJump.HotKeys
* MouseJump.Models
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes #48290
- [x] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end user facing strings can be localized
- all ui strings come from Resources.resw
- [x] **Dev docs:** Added/updated
- no changes required
- [x] **New binaries:** Added on the required places
- no changes required
- [x] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [x] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [x] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [x] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [x] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
- no changes required
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- **Workflow tests**
- [x] Automated tests passing locally
- [x] Minimal actions workflow (spelling check) passing for PR
- [ ] Full actions workflow (msbuild) passing for PR
- **UI tests**
- [x] Happy path
- [x] preview image appears when activated
- [x] clicking the preview image moves the mouse cursor to the correct
location
- [x] right-click dismisses the preview image without moving the mouse
- [x] pressing escape dismisses the preview image without moving the
mouse
- [x] left or right clicking another application / desktop dismisses the
preview image without moving the mouse
- [x] Works on multiple monitors with different dpi scaling settings
(e.g. 100% vs 150%)
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1411869418
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1412834413
- [x] Handling negative coordinates on non-primary monitors if higher or
"lefter" than primary monitor
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1404931694
- [x] Mouse crosshair moves when Mouse Jump moves the cursor (mouse
clicks *and* keyboard shortcuts)
* #24523
* #24527
- [x] Activating when the preview window is already visible moves the
form to the new mouse position
- [x] Number and key shortcuts (1-9, Home / End, Left / Right Arrow)
jump to the appropriate monitor
- [x] Number-pad shortcuts (1-9 jump to the appropriate monitor
- **Settings tests**
- [x] Changing thumbnail size settings updates the size of the thumbnail
- [x] Changing preview type between Compact, Bezelled and Custom shows
the correct preview type
- [x] Changing custom preview settings shows the correct settings
- [ ] Launching with settings version 1.0 upgrades settings to version
1.1, with "Bezelled" as the default style and the "Custom" settings
preconfigured to match "Bezelled"
- **Lifecycle tests**
- [x] Starting PowerToys Runner launches MouseJump exe when enabled, and
not when disabled
- [x] Enabling / disabling Mouse Jump in settings starts / stops
MouseJump exe
- [x] Exiting PowerToys Runner stops MouseJump exe
- [x] Killing runner exe via Task Manager stops MouseJump exe
- [x] Stopping Visual Studio local debug run stops MouseJump exe
- note - runner needs to be in *non*-admin mode otherwise Visual Studio
debugger disconnects at launch
- [x] Hotkey and size settings are automatically reloaded when config
file is modified from Settings UI
- [ ] ~~Hotkey and size settings are automatically reloaded when config
file is modified manually (e.g. in notepad) while runner and
MouseJumpUI.exe are running~~
- **[Internal Test
Suite](
|
||
|
|
558e633c59 |
Add preview release versioning and update channel support (#49414)
## Summary - Publish scheduled `main` builds as GitHub prereleases while keeping manual `main` runs as preview validation builds. - Add an opt-in Settings switch for prerelease update checks; stable updates remain the default. - Use one MSI-safe version across bundles, MSI packages, binaries, symbols, and package manifests. - Prevent preview releases from triggering Microsoft Store, WinGet, or public-symbol publication. - Label preview builds explicitly in Settings, update notifications, and What's New. ## Build intent | Source | Trigger | Intent | | --- | --- | --- | | `main` | Scheduled | Publish a preview release | | `main` | Manual | Validate a preview build without publishing | | `stable` | Manual | Produce a stable release | | Other branches | Any supported trigger | Produce a private validation build | ## MSI-safe release versioning Windows Installer compares only `major.minor.build` and ignores the fourth version component. Preview and stable release builds therefore use: ```text major.minor.YDDDB.0 ``` - `Y`: zero-based number of calendar years since `ReleaseTrainEpoch`. - `DDD`: three-position calendar day of year. - `B`: daily release sequence `1-9`. - The fourth component is always `0`. With `ReleaseTrainVersion=0.100` and `ReleaseTrainEpoch=2026-01-01`: ```text 0.100.2111.0 = July 30, 2026, release build 1 0.100.3659.0 = December 31, 2026, release build 9 0.100.10011.0 = January 1, 2027, release build 1 ``` The allocator formats `DDD` as exactly three digits before converting the MSI component to its numeric representation. Leading zeros may not be displayed because Windows version components are numeric; decoding remains positional: ```text B = component % 10 DDD = (component / 10) % 1000 Y = component / 10000 ``` `ReleaseTrainVersion` and `ReleaseTrainEpoch` are checked in under `src/Version.props`. The epoch remains January 1 of the active epoch year and advances on the first release-train minor change in a new year. ## Daily release counter Azure DevOps persists the daily sequence server-side using a counter keyed as `release-YYYYMMDD`. - `main` and `stable` share the same daily counter. - Other branches do not evaluate or consume the release counter. - Failed or canceled `main`/`stable` runs may leave gaps. - The build fails when the daily sequence exceeds `9`. - The counter date and encoded `YDDD` date both use `pipeline.startTime`. Private branches retain independent `0.0.<extended-day><NN>.0` validation versions. ## Update behavior - Stable users continue to query GitHub's stable latest-release path. - Users who explicitly enable preview updates can select newer GitHub prereleases. - Preview releases and notifications are labeled as PowerToys Preview. - What's New separates preview entries from stable release history and hides previews by default. ## Validation - 17 Pester tests cover `main`, `stable`, private branches, year rollover, epoch reset, monotonicity, override validation, sequence limits, and date alignment. - Version propagation verified `0.100.2111.0` in `Version.props` and all affected AppX/MSIX manifests. - Azure DevOps pipeline dry-runs succeeded for both `refs/heads/main` and `refs/heads/stable`. - The affected native version project builds successfully. - PR CI is green for x64, ARM64, Command Palette SDK, dependency review, telemetry detection, and CLA. ## Remaining end-to-end checks - Install two locally or officially produced installers with consecutive MSI-visible `YDDDB` versions and verify the upgrade preserves binaries, package registrations, hardlinks, and shell integrations. - On the first natural post-merge `main` or `stable` run, verify the production counter value and resolved version in the release logs. ## Local GPO verification Validated locally with the signed `v0.100.2171` build from Azure DevOps build [153961073](https://microsoft.visualstudio.com/Dart/_build/results?buildId=153961073). These checks cover the administrative-template integration and Settings behavior. ### Policy enabled: preview updates are disabled With `PreviewUpdatesDisabled=1`, **Include prerelease updates** is forced off and locked, and Settings displays the managed-by-your-organization notice.  ### Policy removed: the user preference is preserved After removing `PreviewUpdatesDisabled` and restarting PowerToys, the previously selected preview-update preference is restored and editable. The policy suppresses the preference without overwriting it.  ### Group Policy Editor After importing the updated ADMX/ADML templates, **Disable preview build updates** appears under **Microsoft PowerToys > Installer and Updates**. The policy dialog documents that **Enabled** blocks preview updates, while **Disabled** or **Not Configured** leaves the choice available to the user.  --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ad8b7909-0472-4464-bdee-deaeca726f94 Copilot-Session: 8e04a72e-3b0f-4ac4-8156-d04ea9b8bb85 |
||
|
|
97aeab4e96 |
[Shortcut Guide] Add support for Greenshot (#49407)
## Summary of the Pull Request Adds a Shortcut Guide manifest for **Greenshot**. - **New manifest:** `src/modules/ShortcutGuide/ShortcutGuide.Ui/Assets/ShortcutGuide/Manifests/Greenshot.Greenshot.en-US.yml`: 32 shortcuts for `Greenshot.exe`, grouped into five sections: * **Capture:** Capture region, Capture last region, Capture window, Capture fullscreen, Capture Internet Explorer tab * **While selecting a region:** switch region/window mode, select a child window element, toggle magnifier, confirm selection, cancel capture * **Editor - draw:** rectangle/ellipse/line/arrow/freehand/highlight/obfuscate/crop/text/selection tools, enlarge screenshot, crop to visible elements, paste image from clipboard * **Editor - text:** insert line break, delete previous word, select all text, finish editing * **Editor - export:** save, save as, copy image to clipboard, print, e-mail - **No code changes.** The manifest is auto-included via the existing `Manifests/*.yml` glob in `ShortcutGuide.Ui.csproj`. - `BackgroundProcess: true`, matching the bundled PowerToys-itself manifest, since Greenshot's core value is its global capture hotkeys, which work regardless of the currently focused window. - Introduces a `<PrtScn>` token for the Print Screen key (not previously needed by any bundled manifest, since Greenshot's capture shortcuts are all built around it) alongside the existing `<Space>`, `<Enter>`, `<Esc>`, `<Backspace>`, `<PageDown>` named-key tokens. ## PR Checklist - [ ] **Closes:** #ISSUE_NUMBER - [ ] **Communication:** discussed in the linked issue - [ ] **Tests:** N/A for data; relies on the existing manifest deserialization path - [x] **Localization:** all end-user-facing strings can be localized - [ ] **Dev docs:** N/A, no schema changes - [ ] **New binaries:** N/A - [ ] **Documentation updated:** N/A - [x] **Local run:** see issue screenshot ## Detailed Description of the Pull Request / Additional comments The Shortcut Guide displays per-app shortcuts from YAML manifests, matched to the foreground window (or shown continuously for background processes) via `WindowFilter`/`BackgroundProcess`. Adding support for an app is purely additive: drop a `<PackageName>.<locale>.yml` file in the `Manifests` folder and it's picked up by the existing build glob and index generator. - `PackageName: Greenshot.Greenshot` is the WinGet package identifier; `WindowFilter: "Greenshot.exe"` is the process name (confirmed against a signed 1.3.315 build). - `Name: Greenshot` is the display name shown in the Shortcut Guide app picker. - Shortcut names follow the repo's sentence-case convention (capitalize only the first word plus proper nouns/product names). - Five shortcuts are marked `Recommended`: Capture region, Capture last region, Capture window, Save, Copy image to clipboard — the capture and export actions used most often. - Shortcut source: Greenshot's official help page (https://getgreenshot.org/help/), cross-checked against the unofficial `defkey.com` reference. ## Validation Steps Performed - **Source fidelity:** every shortcut and modifier combination matches the official Greenshot help page one-to-one; no unofficial-source shortcuts were added without confirming them against the official page. --- Closes #49406 --------- Co-authored-by: Korb <korwin+git@pm.me> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com> |
||
|
|
1980ca5ece |
[Runner][Interop] Authenticate Settings/Quick Access named-pipe clients before dispatch (CWE-732/CWE-862) (#49527)
## Summary of the Pull Request
The Runner is the **server** for the two-way named pipes it uses to talk
to `PowerToys.Settings.exe` and the Quick Access host, and it dispatched
privileged JSON commands (`killrunner`, `restart_elevation`,
`module_status`, `powertoys`, `language`, ...) **without authenticating
the caller**. When PowerToys runs elevated ("Run as administrator"), the
pipe DACL grants the shared **Logon SID**, so **any same-user Medium-IL
process could connect and inject commands** — a local privilege
escalation (CWE-732 / CWE-862). The pipe DACL cannot distinguish the
legitimate Medium-IL Settings child from a same-user attacker (identical
user SID, integrity level, and logon session), so this PR authenticates
the connecting process's **binary identity** before any dispatch.
## PR Checklist
- [x] **Tests:** Added/updated and all pass (native gate tests + C#
regression)
- [x] **Localization:** No new end-user-facing strings (only a
diagnostic runner log line)
- [x] **New binaries:** None — the new code compiles into the existing
`PowerToys.Interop` and `runner` binaries; tests were added to the
existing `Common.Utils.UnitTests` project
## Detailed Description of the Pull Request / Additional comments
New `src/common/interop/pipe_caller_auth.{h,cpp}` adds
`interop_auth::AuthenticateClient`, invoked from
`TwoWayPipeMessageIPC::handle_pipe_connection` **before** a message is
queued (fail-closed). A connecting client is accepted only if it is:
- under the **Runner-relative install directory**
(`get_module_folderpath()\WinUI3Apps`, so it adapts to installed and
dev-build layouts),
- an **allow-listed basename** (`PowerToys.Settings.exe` /
`PowerToys.QuickAccess.exe`),
- the Runner's **exact file version** (anti-downgrade), and
- **Microsoft Authenticode-signed**.
The signature is anchored to the **LOCAL MACHINE root store**
(`HCCE_LOCAL_MACHINE` +
`CertVerifyCertificateChainPolicy(AUTHENTICODE)`) rather than
`WinVerifyTrust`'s default user+machine union: the Runner runs as the
same user as a potential attacker and would otherwise trust a forged
signer added to `CurrentUser\Root`. Verdicts are cached per `(pid,
process-creation-time, policy)` with a short TTL so the check isn't
re-run on every message (each `send` opens a new connection). Rejections
are logged.
The gate is added via an **additive** `start(HANDLE, CallerPolicy)`
overload; the managed `start(nullptr)` path is unchanged (gate
disabled), so there is **no ABI break** to `PowerToys.Interop`.
`PIPE_REJECT_REMOTE_CLIENTS` is also set. In **Debug** builds only the
signature check is relaxed (directory/basename/version stay enforced) so
local unsigned builds still connect; the relaxation is compiled out of
Release.
**Scope:** this PR covers the two elevated Runner-server pipes (Settings
+ Quick Access), which are the actual EoP surface. The reverse
Runner->Settings response direction, the duplicated Workspaces
transport, and the AdvancedPaste/PowerDisplay module pipes are
intentionally out of scope and can be handled as follow-ups.
## Validation Steps Performed
**Automated**
- **Native unit tests** (`Common.Utils.UnitTests`,
`PipeCallerAuthTests`): legitimate self-caller accepted; wrong
basename/directory rejected with the reject-log callback firing; version
reading. 6/6 pass.
- **C# regression** (`Microsoft.Interop.Tests.TestSend`): managed
gate-disabled round-trip still works.
- **Builds:** runner Debug + Release, `PowerToys.Interop` Debug +
Release, and the test project all build/link clean.
**Official signed build (validates the Release-only signature path that
local Debug builds skip)**
- Queued the internal "PowerToys Signed YAML Release Build" for this
branch — **green** (`result: succeeded`). The produced installers are
Authenticode `Valid`, signer `Microsoft Corporation`.
**Manual testing on the signed installer (elevated Runner) — passed**
- Installed the signed build and ran the Runner **as administrator**.
Settings and Quick Access open and are fully functional; settings apply,
module toggles work, and the hotkey-conflict request/response
round-trips.
- **No** `Rejected unauthenticated ...` lines during legitimate use →
the genuine signed `PowerToys.Settings.exe` is accepted by the
machine-root signature + version + directory checks (verified in
`RunnerLogs\runner-log_*.log`, requests dispatched normally).
- **Security (negative) check:** a non-elevated `powershell.exe`
discovered the runner pipe via the pipe namespace and attempted
`{"killrunner":true}`; the write failed ("Pipe is broken") because the
Runner rejected the caller and disconnected before dispatch.
`PowerToys.exe` stayed running and logged: `Rejected unauthenticated
Settings pipe client: pid=... image='...\powershell.exe'
reason=bad-directory`.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1d8f85ec-aaee-468a-9348-ba79b059cbaf
|
||
|
|
ba2e89c428 |
PowerDisplay: Fall back to persisted VCP values when a monitor read fails (#49445)
## Summary of the Pull Request On a monitor whose DDC/CI engine answers intermittently, every discovery pass starts from nothing. A panel that reported its brightness a minute ago can lose that control — or drop out of the flyout entirely — because one pass happened to fail. This persists every range-valid VCP value read off a monitor, keyed by its canonical DevicePath. In Maximum compatibility mode a later discovery falls back to that value when the hardware will not answer. Scope is intermittent failure, not permanent failure: the cache can only replay a value the hardware answered at least once, so a panel that never reads a code successfully sees no change. This partially addresses #49342. ## PR Checklist - [x] Closes: #49342 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized — this PR adds none - [ ] **Dev docs:** Added/updated - [x] **New binaries:** Added on the required places — none added, so no signing JSON, installer WXS or CI YML change is required - [ ] **Documentation updated** ## Detailed Description of the Pull Request / Additional comments ### What is stored `MonitorStateManager` implements `IKnownGoodVcpStore`, so the cache rides in the existing `monitor_state.json` next to the user's saved brightness rather than in a new file. Each entry is a `KnownGoodVcpFeature`: code, current, maximum, and when it was last read. Only range-valid observations are stored, so the common `current=0 / max=0` garbage reply never enters — it fails `VcpFeatureValue.IsValid`. Writes are not gated on Maximum compatibility mode, only reads are. A monitor that reads cleanly today can start failing after a cable or dock change, and a lazily populated cache would be empty on exactly the first pass that needs it. ### How a cached value is used `VcpDiscoveryEvidence.Reconcile` gains the cache as a third source alongside the parsed capabilities string and this pass's probe: | this pass | cache | result | | --- | --- | --- | | read succeeded | — | live value wins, cache refreshed | | replied, range unusable | hit | cached value applied, `MonitorReadFlags` left clear | | no reply | hit | cached value applied, `MonitorReadFlags` left clear | | code never probed (caps parsed) | hit | value applied only after one live read is attempted | The last row matters: on the caps-parsed path nothing has confirmed the cached value this pass, so the hardware is asked first. On the probe path it has already been asked, and re-reading would be pure I2C noise. `MonitorReadFlags` stays clear for anything the hardware did not answer, so a cached value never masquerades as an observation — which #49577 depends on, since it made the restore path write whenever the flag is unset. One consequence is worth naming: the flyout draws a slider at the cached position while `powerdisplay get` reports that setting as unknown, because `MonitorDtoProjector` gates on `supported && read`. ### Keeping the cache current `RefreshKnownGoodAfterWrite` restamps an entry after a successful `SetVCPFeature`, so a slider move cannot leave the cache holding the pre-write value. It refreshes only an entry a real read established, and only when the value was scaled against the maximum that entry holds — a monitor whose discovery read failed still carries a placeholder max, and writing that back would mis-scale every later write. `RemoveKnownGoodFeatures` clears the cache for monitors a settings reconciliation observably dropped, leaving the user's saved values alone. Cleanup is driven by an observed drop, never by absence from the rebuilt list: a missing or corrupt `settings.json` yields a defaults object indistinguishable from a real one, and pruning by absence would wipe every monitor not connected at that instant. A re-observation that changes nothing refreshes the in-memory timestamp but does not mark the file dirty, so a discovery pass no longer rewrites `monitor_state.json` for a moved timestamp alone. ## Validation Steps Performed - `PowerDisplay.Lib`, `PowerDisplay.Lib.UnitTests` and `PowerDisplay` built for x64 Debug with VS MSBuild — 0 errors, 0 warnings; `PowerDisplay.Lib.UnitTests.dll` under `vstest.console.exe`: **301 passed, 0 failed** - **Affected-hardware validation on the AOC Q27G3XMN is still pending.** That monitor, or an equivalent controllable DDC/CI setup, was not available locally. The paths this PR changes are reachable only on hardware whose capabilities string is unusable or whose VCP reads fail intermittently, so this is the main outstanding risk. --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Copilot-Session: 6ea38c04-6f68-4c42-91d9-8a03b49bdd81 |
||
|
|
160492abcf |
docs(skills): recommend WindowEx for WinUI 3 migrations (#49303)
## Summary of the Pull Request Updates the WPF-to-WinUI 3 migration skill to make the established PowerToys windowing pattern explicit: - Default WinUI 3 top-level windows to `WinUIEx.WindowEx` or an existing PowerToys base derived from it, such as `TransparentWindow` for transient overlays. - Keep supported size, presenter, title bar, topmost, backdrop, and persistence behavior declarative in XAML instead of manual `AppWindow` / `OverlappedPresenter` code-behind. - Document the centrally managed `<PackageReference Include="WinUIEx" />`, WPF-to-`WindowEx` property mappings, and existing repository examples. - Add a value-converter decision guide that prefers `VisualStateManager`, direct `x:Bind` conversion, WinUI theme resources, and `CommunityToolkit.WinUI.Converters` over mechanically porting WPF converters. This follows the migration-skill feedback from @niels9001 in [PR #49174](https://github.com/microsoft/PowerToys/pull/49174#discussion_r3535181101). ## PR Checklist - [x] **Communication:** This change follows review feedback from a core contributor in PR #49174. - [x] **Tests:** The updated guidance passed 5/5 fresh agent migration scenarios. - [x] **Dev docs:** Added/updated. ## Detailed Description of the Pull Request / Additional comments `SKILL.md` now states the default PowerToys pattern and limits raw `AppWindow` / presenter code to behavior that `WindowEx` does not expose. The package mapping reference records the exact centrally managed dependency. The windowing reference adds a complete XAML example, a WPF-to-`WindowEx` mapping table, regular-window examples, and the `TransparentWindow` overlay exception. The XAML migration reference now also documents converter selection and reuse: control state belongs in `VisualState`s, count visibility can share one Toolkit `DoubleToVisibilityConverter` with `ConverterParameter=True`, and corner-radius converter resources come from `XamlControlsResources`. This is an atomic documentation-only change; no product code or dependencies are modified. ## Validation Steps Performed - Verified the documented `WindowEx` APIs and `TransparentWindow` inheritance against the repository and compiled WinUIEx assembly. - Verified all cited repository paths, the Markdown anchor, and central package management entry. - Ran five fresh current-branch agent scenarios; all selected `<PackageReference Include="WinUIEx" />` without a version, `WindowEx`, XAML-declared properties, and `CenterOnScreen()` only where required. - Ran a focused converter migration scenario before and after the guidance update; the updated skill selected `VisualState`s, one reusable Toolkit numeric converter, and existing WinUI corner-radius resources without custom converters. - Ran `git diff --check` with no errors. - Completed an independent read-only review with no findings. - Product builds and unit tests were not run because this change only updates agent guidance. --------- Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: fe9b24eb-99f0-43e8-aaa4-839f4579f6f9 Copilot-Session: d5afc36b-3356-46af-b8cb-071b87a64532 |
||
|
|
8f63402400 |
PowerDisplay: Adjust brightness by scrolling over the tray icon (#49446)
## Summary of the Pull Request Scrolling the mouse wheel over the Power Display tray icon adjusts brightness, without opening the flyout. - New **Tray icon mouse wheel** setting: `Off` / `Primary display` / `All displays`, defaulting to **`Off`**. It is scoped to the tray icon — the flyout sliders accept wheel input regardless, as they always have. The existing **Mouse wheel increment** setting supplies the per-notch step. - **Off by default.** The gesture consumes a wheel notch that would otherwise reach the window under the pointer, and acting on it installs a system-wide `WH_MOUSE_LL` hook. Neither is something an existing installation should acquire silently on upgrade. With the setting `Off` no hook is ever installed and no notch is ever consumed, so this PR changes no existing behaviour until the user opts in: 1958 insertions, 2 deletions, and both deletions are refactors of lines this feature reuses. - **No feedback UI.** Brightness is self-evidencing — you scroll and the screen changes — so the display itself is the feedback. The notification icon is untouched: same tooltip, same text, same legacy notification-icon protocol. ## PR Checklist - [x] Closes: #49410 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [x] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx No new binaries or projects — everything lands in existing assemblies. Communication is unchecked because #49410 is still Needs-Triage. ## Detailed Description of the Pull Request / Additional comments ### Why a low-level hook The Shell does not forward `WM_MOUSEWHEEL` to a notification icon's callback window under any `NOTIFYICON_VERSION`, and a click-through overlay placed over the icon cannot receive wheel input either. `TrayIconMouseWheelListener` therefore installs a `WH_MOUSE_LL` hook — but only transiently, and only when it will act on the result: - Nothing is installed at all while the setting is `Off`, which is the default. - Installed in `EnsureHook()` when the UI thread confirms the pointer is inside the rectangle from `Shell_NotifyIconGetRect` **and** `CanAdjustBrightnessFromTrayWheel` says some monitor can accept a brightness write. - Removed in `DisarmCore()` as soon as either condition stops holding, the pointer leaves the rectangle, or the mode changes. - A notch is consumed (the hook proc returns non-zero) only while armed and only for points inside the armed rectangle, so a wheel event Power Display will not act on still reaches the window under the cursor. The hook runs on a dedicated background thread with its own message loop; the proc itself only enqueues a sample and posts a drain request. Deltas are marshalled to the UI thread in batches, and `WheelDeltaAccumulator` folds high-resolution deltas (precision wheels, touchpads) into whole notches. Each sample carries the hover generation it was captured under, so samples from a hover the UI thread has already retired are discarded rather than applied late. ### Hover detection The Shell sends `WM_MOUSEMOVE` to the icon's callback window while the pointer is over it. `TrayIconService.HandleTrayMouseMove` resolves the rectangle with `Shell_NotifyIconGetRect` and caches it for a second, because that message repeats for every pixel of travel. `TrayIconService` gains nothing else: no protocol change, no new hover UI, no polling. The rest of the file — and `MainWindow.xaml` — is untouched. ### Linked brightness While linked brightness is on, a notch has to move the whole group, so it goes through `MainViewModel.LinkedBrightness` rather than the individual monitor setters. The new master value is taken from the planner's value for the monitor the wheel named, **not** from the current master. The master is positional only — `SeedInitialLinkedBrightness` takes it from the lowest-numbered linked monitor and never writes hardware, and every monitor-list rebuild re-seeds it — so it can sit arbitrarily far from the monitor the wheel is aimed at. Stepping it relative to itself would apply a wrong-sized or wrong-signed change, and a master already clamped at 0/100 would swallow the notch while writing nothing at all. The setting description calls out that linked brightness widens the scope, so `Primary display` is not literally a single display while it is on. ### What is deliberately not here An earlier revision of this PR showed the target and percentage in a custom overlay as you scrolled. Doing that meant the standard Shell tooltip would not do (it cannot be shown on demand), which meant an own window, which meant suppressing the Shell tooltip so the two did not collide, which meant `NOTIFYICON_VERSION_4`, which changed the callback packing and made the app responsible for all hover text — including for keyboard and touch users, who never reach a cursor-anchored overlay and would have been left with no visible tooltip at all. That chain was about half the diff, for a readout that adds little on top of watching the screen change. It is gone. If a readout is wanted later it can be argued on its own merits, separately from this feature. The same revision also gated the flyout sliders on this setting. That bundled two unrelated things behind one switch — turning off tray scrolling would also have stopped the contrast and volume sliders responding to the wheel — so the setting is now scoped to the tray icon and named accordingly. An earlier revision also routed the tray **Exit** action through `Shutdown()`. That fixes a pre-existing teardown leak which has nothing to do with this feature, so it now lives in #49580 and is out of scope here. This branch does not depend on it: the hook thread is a background thread and the process is ending either way. ## Validation Steps Performed - Unit tests: `PowerDisplay.Lib.UnitTests` 215 passed, `Settings.UI.UnitTests` 165 passed. - Builds: `PowerDisplay` and Settings UI, x64 Debug, no warnings. - Automated coverage is in `PowerDisplay.Lib.UnitTests`: target selection per mode, wheel accumulation including negative deltas, partial notches and direction reversal, half-open rectangle containment, and settings serialization and round-trip for the new mode, including that a settings file predating the feature loads as `Off`. `Settings.UI.UnitTests` covers the view-model index mapping and pins the enum values to the ComboBox item order. - The Win32 glue in `TrayIconService` and `TrayIconMouseWheelListener` is not unit tested. Manual passes performed: scrolling over the icon in both modes, the icon parked in the notification overflow, high-resolution wheel input, brightness boundaries, live monitor refresh while hovering, tray icon hidden and re-enabled, Explorer restart, the context menu and left-click, `Off` stopping tray scrolling while the flyout sliders keep working, and confirming a notch that Power Display will not act on still reaches the window under the cursor. Not verified, needing hardware this branch has not been run on: - Multiple taskbars, where the tray icon is on a secondary display and `Primary display` mode adjusts a monitor the user may not be looking at. - Mixed-DPI setups, for the `Shell_NotifyIconGetRect` rectangle and the hook's physical-pixel hit test. --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Copilot-Session: 5d7f36fe-d175-4aa9-a3c7-b370d952d1d3 |
||
|
|
bb99c30edc |
New module: AltWindowCycle (#48281)
## Summary of the Pull Request Introduces a new utility: AltWindowCycle to quickly switch between windows from the same process using Alt + `. In release notes give @wzhudev coauthor credits as he also had an earlier PR It works like Alt + Tab, but scoped to the app you’re already in. Perfect for juggling multiple browser windows, terminals, or editor instances. https://github.com/user-attachments/assets/cd42f6af-fa5d-4f08-8f68-3c4e75c16d94 <img width="1835" height="971" alt="image" src="https://github.com/user-attachments/assets/adea59cb-6c8d-4b44-87e2-0a792c4c0b4f" /> ## PR Checklist - [x] Closes: https://github.com/microsoft/PowerToys/issues/278 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments This PR adds AltWindowCycle (in-proc module + Settings integration), then addresses follow-up check-spelling feedback without changing runtime behavior: - allow-list update for `ROOTOWNER` - comment text adjustment for forbidden-pattern compliance - local identifier rename (`wpx` → `whitePx`) for spelling compliance ## Validation Steps Performed - Verified `ROOTOWNER` is present in `.github/actions/spell-check/allow/code.txt` - Verified `wpx` is removed and updated occurrences in `src/modules/AltWindowCycle/AltWindowCycle.cpp` - Ran targeted diff/verification for both updated files - Ran final validation (code review + CodeQL trivial-change path) - Ran secret scan for changed files --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Clint Rutkas <crutkas@users.noreply.github.com> Copilot-Session: dd5080ea-5001-4efb-87f8-1e7218e10a4e |
||
|
|
bc2d09abe8 |
PowerDisplay: Pace and retry the maximum-compatibility VCP probe (#49579)
## Summary of the Pull Request In Maximum compatibility mode, when a monitor's capabilities string is missing or unparsable, discovery falls back to probing each continuous VCP code directly. That probe issues **one** `GetVCPFeatureAndVCPFeatureReply` per code, back to back, and treats any failure as final. On a panel whose DDC/CI engine answers intermittently, a single transient I2C fault permanently drops that control for the whole discovery pass — and if every code happens to fault, the monitor disappears from the flyout entirely. This replaces the probe with `VcpFeatureProbeService`: - **paced** — 100 ms between transactions, instead of hammering the I2C bus back to back - **retried** — up to 3 attempts, but only for failures another attempt can plausibly get past - **classified** — `DdcErrorClassifier` decides what "transient" means, so the retry budget is not burned on a definitive `DDCCI_VCP_NOT_SUPPORTED` or on a dead physical-monitor handle - **aborted early** — a handle-class error stops the remaining codes rather than issuing more requests against a handle already known to be invalid Extracted from #49445, which bundles this with a persisted discovery cache and a discovery restructure it does not depend on. This piece stands alone and addresses one of the root causes in #49342 by itself. ## PR Checklist - [ ] Closes: #xxx — partially addresses #49342; the remaining causes are in #49445 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized — this PR adds none - [ ] **Dev docs:** Added/updated - [x] **New binaries:** Added on the required places — none added; no new project, so no signing JSON, installer WXS or CI YML change is required - [ ] **Documentation updated** ## Detailed Description of the Pull Request / Additional comments ### What is and is not retried `DdcErrorClassifier` names the DDC/CI error codes after `winerror.h` and splits them into two sets. `DdcErrorClassifierTests` pins both the membership of each set **and** the numeric value of every constant against `winerror.h`, so a typo cannot move production and tests together and leave the suite green. Retried — framing, arbitration and timing faults on the I2C bus: `I2C_ERROR_TRANSMITTING_DATA`, `I2C_ERROR_RECEIVING_DATA`, `DDCCI_INVALID_DATA`, `MCA_INTERNAL_ERROR`, `DDCCI_INVALID_MESSAGE_COMMAND`, `DDCCI_INVALID_MESSAGE_LENGTH`, `DDCCI_INVALID_MESSAGE_CHECKSUM`, `DDCCI_CURRENT_CURRENT_VALUE_GREATER_THAN_MAXIMUM_VALUE`, `ERROR_TIMEOUT`. Not retried, each for a stated reason recorded on the predicate: `DDCCI_VCP_NOT_SUPPORTED` is the device's final answer; `I2C_NOT_SUPPORTED` and `I2C_DEVICE_DOES_NOT_EXIST` are permanent bus-level facts; `MCA_INVALID_CAPABILITIES_STRING` belongs to the capabilities path, not to a VCP read; and the two handle-class codes must abort rather than retry. ### Behaviour preserved `FetchCapabilitiesWithFallbackAsync` keeps its signature and still returns `(string, VcpCapabilities?)`, so nothing outside the probe changes. `BuildCapabilitiesFromProbe` synthesizes the same shape `DdcCiNative.ProbeSupportedVcpFeatures` used to, and decides membership the same way: a code counts as supported when the device *replied*, not when the value was usable. A reply proves the opcode is implemented even if the reported range cannot scale a percentage — an unimplemented code fails with `DDCCI_VCP_NOT_SUPPORTED` instead. The set of probed codes moves from a private array in `DdcCiNative` to `NativeConstants.ContinuousVcpCodes`, where the follow-up work in #49445 also needs it. ### Cost The probe only runs in Maximum compatibility mode, and only when the capabilities string is already unusable — so this adds no I2C traffic to a monitor that parses normally. For a monitor that does reach it, the worst case grows from 3 transactions to 9 plus 900 ms of pacing, and it is bounded: a definitive refusal stops after one attempt, and a handle-class error stops the whole probe. ### What is deliberately left out The probe's values are still discarded — `BuildMonitorFromPhysical` re-reads each code immediately afterwards. Reusing them needs a carrier for the observed value, which is `VcpDiscoveryEvidence` in #49445. `VcpFeatureProbeService` already returns everything that needs (`VcpProbeObservation` carries the value, the attempt count and the last error); this PR simply does not consume it yet. ## Validation Steps Performed - built `PowerDisplay.Lib.UnitTests` for x64 Debug with VS MSBuild — 0 errors, 0 warnings - ran `PowerDisplay.Lib.UnitTests.dll` with `vstest.console.exe`: **223 passed, 0 failed** (186 on `main` + 37 added here) - `VcpFeatureProbeServiceTests` drives the pacing, the retry budget, the transient/definitive split, cancellation before and during the inter-transaction delay, a throwing native read, and that reads run off the caller's thread — all through an injected reader and an injected delay, so no hardware is needed - no hardware validation performed: reaching this path needs a panel whose capabilities string is unusable **and** whose VCP reads fail intermittently --------- Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> |
||
|
|
44fd627c3a |
Tighten IContextMenu::GetCommandString in Image Resizer (#48399)
## Summary Corrects `IContextMenu::GetCommandString` handling in the Image Resizer shell extension. ## Changes - `GCS_VERBW` copies the Unicode canonical verb with `StringCchCopyW`, preserving copy failures. - Only `GCS_VALIDATEA` and `GCS_VALIDATEW` return `S_OK`. - ANSI verb requests, help-text requests, and unknown request types return `E_NOTIMPL`. - ANSI string verbs are intentionally not advertised because `InvokeCommand` cannot execute them. - Updates spell-check expectations for the Windows constants used by this implementation. ## Validation The authoritative local versions of all three changed files are pushed together. A Windows build was not run in this Linux environment. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
5c9c93d56d |
feat(powerdisplay): add CLI for monitor control (#48632)
## Summary of the Pull Request Adds `PowerToys.PowerDisplay.Cli.exe`, a scriptable interface for controlling monitors through the running PowerDisplay process. It supports `list`, `get`, `set`, `up`, `down`, `capabilities`, `profiles`, and `apply-profile`. The CLI communicates over an authenticated, per-session named pipe; PowerDisplay remains responsible for DDC/CI and WMI access. ## PR Checklist - [x] Closes: #48713 - [x] **Communication:** Discussed with core contributors - [x] **Tests:** Added/updated and all pass - [x] **Localization:** Core errors are localizable; some help and output text remains English-only - [ ] **Dev docs:** N/A; built-in CLI help is the command reference - [x] **New binaries:** Added on the required places - [x] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) - [x] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetupVNext/Resources.wxs) - [x] **YML for CI pipeline:** N/A; test assemblies are auto-discovered - [x] **YML for signed pipeline:** N/A; signing is driven by `ESRPSigning_core.json` - [ ] **Documentation updated:** N/A ## Detailed Description of the Pull Request / Additional comments - Adds an AOT-compatible CLI and shared request/response contracts. - Uses a secured named-pipe server in PowerDisplay, with stable exit codes and a bounded request timeout. - Supports saved profiles by their existing stable profile IDs. - Adds solution, signing, installer, and unit-test project integration. ## Validation Steps Performed - PowerDisplay Lib, Contracts, CLI, and IPC unit-test suites pass. - Native AOT publish completes without analyzer warnings. - Manually validated the CLI on two DDC/CI monitors, including the PowerDisplay-unavailable path. - Rebuilt the PowerDisplay GUI after the shared-library changes. --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
d5fe397b05 |
Follow-up: UITest framework Next - stability improvements (#49242)
This pull request addresses several CI flakiness and reliability issues in the UI test automation harness, especially around foreground window handling and build artifact resolution. The main improvements ensure that UI interactions (like real mouse clicks) reliably target the correct window, even in complex CI and build environments, and that test code accurately locates module executables regardless of output layout. **Foreground window handling and input reliability:** * Added `Session.EnsureForeground()` and improved `WindowControl.TryBringToForeground()` to reliably raise the target window above others, defeating the Win32 foreground lock using `AttachThreadInput` and related APIs. This prevents coordinate-based clicks from landing on the wrong window, a common cause of CI test flakiness. (`src/common/UITestAutomation.Next/Session.cs`, `src/common/UITestAutomation.Next/WindowControl.cs`, `src/common/UITestAutomation.Next/Element/Element.cs`, `.github/skills/ui-tests-migration/references/ci-stability.md`, `src/modules/MeasureTool/Tests/ScreenRuler.UITests.Next/TestHelper.cs`) [[1]](diffhunk://#diff-713524f4ead9951000b3578248f2740088729981051b68c3fa3655ebb548f20fR91-R118) [[2]](diffhunk://#diff-60be6ec24a99f8974cff00414fc47ea1e60e3ab9aee706b5d6845eb8df19165fR59-R76) [[3]](diffhunk://#diff-60be6ec24a99f8974cff00414fc47ea1e60e3ab9aee706b5d6845eb8df19165fL247-R332) [[4]](diffhunk://#diff-3c00581cb1d2b6a4302b8378b87c27cdad2f87c2aefc37eec0bdc6c39af9291aR100-R103) [[5]](diffhunk://#diff-98e5aea12baaac99aba10e7dd341ed3f2efdd24cb80b29306bb500816de09e2fR96-R114) [[6]](diffhunk://#diff-d8766b48614fe4a99e3f100e69e611ca2464de6ba0be257586c12d51f9278ed0L498-R504) **Build artifact and executable path resolution:** * Refactored `ModuleInfo.GetDevelopmentPath()` to dynamically walk up from the test assembly and find the module executable in various build output layouts, including CI artifacts and local builds. This eliminates hardcoded path offsets and makes test launches robust to different build structures. (`src/common/UITestAutomation/ModuleInfo.cs`) * Updated `ModuleConfigData.GetModulePath()` to use the improved path resolution and fall back to installed builds if necessary, ensuring that test runs can always locate the correct executable. (`src/common/UITestAutomation/ModuleConfigData.cs`) * Simplified `SessionHelper` so that `locationPath` is always empty, leveraging the fact that module paths are now absolute. (`src/common/UITestAutomation/SessionHelper.cs`) [[1]](diffhunk://#diff-c001f0fd3432c8b6102c3120597fc48f24902eaa0d755f51adfa7646344b3833L7-L10) [[2]](diffhunk://#diff-c001f0fd3432c8b6102c3120597fc48f24902eaa0d755f51adfa7646344b3833L46-R54) These changes collectively improve test reliability, especially in CI environments, and make the harness more resilient to changes in build output structure. --------- Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
4881f23545 |
Add PR Needs-Author-Feedback lifecycle to fabricbot configuration (#49151)
## Summary Adds fabricbot rules to manage the `Needs-Author-Feedback` label lifecycle for **pull requests**, complementing the existing issue management rules in `resourceManagement.yml`. This is a **simpler alternative** to the GitHub Actions workflow approach (PR #48812), trading advanced features (draft conversion, author-specific activity tracking) for zero-maintenance fabricbot automation. ## Behavior ### Flow diagram ``` ┌──────────────────────────────────────────────────────────────────────┐ │ Maintainer adds "Needs-Author-Feedback" label to a PR │ └──────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ ┌──────────────────────────────────┐ │ 7 days, no activity │────►│ Add "Status-No recent activity" │ │ │ │ + post warning comment │ └─────────────────────────────────────┘ └──────────────────────────────────┘ │ │ ▼ ▼ ┌─────────────────────────────────────┐ ┌──────────────────────────────────┐ │ 7 more days (14 total), no activity│────►│ Close PR + post closing comment │ └─────────────────────────────────────┘ └──────────────────────────────────┘ ┌──────────────────────────────────────────────────────────────────────┐ │ Author pushes commits OR comments on PR (at any point) │ └──────────────────────────────────────────────────────────────────────┘ │ ▼ Remove "Needs-Author-Feedback" → Add "Needs-Triage" Remove "Status-No recent activity" (if present) ``` ### Scheduled searches (every 6 hours) | Condition | Action | |-----------|--------| | PR + `Needs-Author-Feedback` + 7 days inactive + no `Status-No recent activity` | Add `Status-No recent activity` label + warning comment | | PR + `Needs-Author-Feedback` + `Status-No recent activity` + 7 more days inactive | Post closing comment + close PR | ### Event responders | Trigger | Action | |---------|--------| | Author comments on PR (`Issue_Comment` + `issueAuthor`) | Remove `Needs-Author-Feedback`, add `Needs-Triage` + `Needs-Team-Response` | | Author pushes commits (`Pull_Request` + `Synchronize` + `issueAuthor`) | Remove `Needs-Author-Feedback`, add `Needs-Triage` | | Any PR update activity | Remove `Status-No recent activity` | ### Bot messages **Warning (at 7 days):** > This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **7 days**. It will be closed if no further activity occurs **within 7 days of this comment**. To keep this PR active, please push your changes or leave a comment. **Closing (at 14 days):** > This pull request has been automatically closed because it has been marked as requiring author feedback but has not had any activity for **14 days**. If you would like to continue working on this, please reopen the PR and push your changes. ## Comparison with GitHub Actions workflow (PR #48812) | Feature | This PR (fabricbot) | PR #48812 (Actions) | |---------|-------------------|-------------------| | Convert to draft at 7 days | ❌ Not supported | ✅ Via GraphQL | | Close at 14 days | ✅ | ✅ | | Author-specific activity tracking | ❌ Any activity resets timer | ✅ Only author activity counts | | Bot comment resets timer | ⚠️ Yes (fabricbot limitation) | ✅ No (filtered out) | | Maintenance burden | None (fabricbot managed) | Low (workflow file) | | Testing before merge | ❌ No local testing | ✅ `workflow_dispatch` + dry-run | | Review comment detection | ❌ Only issue comments | ✅ Reviews + inline comments | ## Trade-offs **Pros:** - Zero maintenance — fabricbot is a managed service - Consistent with existing issue management patterns in the same file - No workflow YAML to debug or maintain **Cons:** - No draft conversion (fabricbot cannot call GraphQL) - `noActivitySince` counts **all** activity — bot comments, maintainer comments, and label changes all reset the inactivity timer - Cannot distinguish author activity from other activity - No way to test locally or with dry-run before merge ## Relationship to existing automation Mirrors the existing issue rules (lines 11-43) which use the same pattern: - Issues: 5 days → warning, 5 more days → close - PRs (this change): 7 days → warning, 7 more days → close Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
85f698677a |
[UITests] AI migration skill + ScreenRuler tests example port. (#48842)
This PR is build on top of https://github.com/microsoft/PowerToys/pull/48717 and https://github.com/microsoft/PowerToys/pull/48467 It adds the ui-tests-migration skill which should be used to migrate the old UITest module by module to use new .Next UI framework. As an example, the screen ruller tests was ported here. --------- Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
4395b1d0ca |
[skill] Generalize verification skill into 2 scenarios (module checklist / PR validation) (#48848)
## Summary of the Pull Request Generalizes the `powertoys-verification` agent skill from "one module checklist" into a **single shared engine that serves two verification scenarios**, using the *shared engine + per-scenario reference docs* design (no duplication of the winapp mechanics): - **A — Module checklist**: verify a supplied module checklist against the installed build. - **B — PR validation**: derive each PR's checklist from its description + diff, then drive it. A single **bits sub-decision** picks the target — drive the **installed** build when the PR's code is already shipped (a merged PR, or a whole release/hotfix set, e.g. the 0.100.1 14-PR sign-off), or **build + sideload** the affected module when it isn't (an unmerged or not-yet-released PR, e.g. #45242). Both scenarios share the same `winapp ui` drive techniques, helper scripts, per-module profiles, taxonomy, and report format. They differ mainly on **what bits you run**, so the only new content is a thin scenario layer. ## PR Checklist - [ ] **Closes:** N/A (follow-up to the merged `powertoys-verification` skill) - [x] **Communication:** design discussed and agreed before implementation - [x] **Tests:** N/A — docs/skill-only change; validated link/constraint checks (see below) - [x] **Localization:** N/A - [x] **Dev docs:** this PR *is* skill documentation - [x] **New binaries:** none ## Detailed Description of the Pull Request / Additional comments **`SKILL.md` (shared engine)** — broaden `description` + "When to use" to cover both scenarios, add a **Step-0 scenario router** (plus, for B, the bits sub-decision "is the PR's code in the build under test?"), keep the supplied-checklist read **Scenario-A-only**, and make the bootstrap/placeholders/"What NOT to do" scenario-aware. **`references/scenarios/`:** - `index.md` — router table (A/B); the **"bits under test" contract** (the one real conflict: installed-and-immutable, vs build-and-sideload when the PR's code isn't in the build, echoed in the report header so the evidence chain is trustworthy); and a verdict-vocabulary mapping (engine `PASS/FAIL/BLOCKED` <-> legacy labels). - `module-checklist.md` (A) — supplied checklist, installed bits. - `pr-validation.md` (B, **new — merges the former release-PR and active-PR docs**) — derive each PR's checklist from `gh pr view/diff`; the **bits sub-decision**; a **PR-discovery model with a size gate** (auto-verify hotfix-sized sets <=25; for full ~100-PR releases, scope-and-confirm instead of blind-looping) and a non-runtime-PR pre-filter; per-PR folders + roll-up; and the **build + sideload** front-end (in-repo worktree helper + build commands), unpackaged (run the built runner, dismiss the expected partial-build dialogs) vs packaged/CmdPal (`Add-AppxPackage -Register`) deploy recipes, prove-your-bits, and restore-to-shipped cleanup. Removed the separate `release-pr-signoff.md` and `active-pr-validation.md` (folded into `pr-validation.md`). The existing engine docs (`winapp-ui-testing.md`, `pre-flight.md`, `reporting-format.md`), per-module profiles, and helper scripts are reused unchanged — single source of truth. The `BITS:` header version is a `<version>` placeholder (not pinned to a release). ## Validation Steps Performed - `SKILL.md` within authoring limits: **331 lines** (< 500) and **description 999 chars** (< 1024). - All relative markdown links in `references/scenarios/*.md` resolve, and every engine doc they cite exists. - Scenario B exercised end-to-end both ways: the 0.100.1 14-PR sign-off (8 PASS / 6 BLOCKED, installed bits) and PR #45242 (Advanced Paste, 3/3 PASS, build + sideload). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
f740d0b3e5 |
Build(deps): Bump actions/dependency-review-action from 4 to 5 (#47907)
Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4 to 5. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/dependency-review-action/releases">actions/dependency-review-action's releases</a>.</em></p> <blockquote> <h2>5.0.0</h2> <p>This is a new major version of the Dependency Review Action which updates the runtime to node24. This requires a minimum Actions Runner version <a href="https://github.com/actions/runner/releases/tag/v2.327.1">v2.327.1</a> to run.</p> <h2>What's Changed</h2> <ul> <li>Add .github/copilot-instructions.md for Copilot coding agent by <a href="https://github.com/ahpook"><code>@ahpook</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1067">actions/dependency-review-action#1067</a></li> <li>Update Node.js runtime from 20 to 24 by <a href="https://github.com/scottschreckengaust"><code>@scottschreckengaust</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1084">actions/dependency-review-action#1084</a></li> <li>Bump spdx-license-ids from 3.0.20 to 3.0.23 by <a href="https://github.com/mongolyy"><code>@mongolyy</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1091">actions/dependency-review-action#1091</a></li> <li>docs: bump actions/checkout from v4 to v6 in workflow examples by <a href="https://github.com/Marukome0743"><code>@Marukome0743</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1077">actions/dependency-review-action#1077</a></li> <li>fix: patched version display for advisories with non-strict semver ranges (e.g. Maven beta versions) by <a href="https://github.com/tspascoal"><code>@tspascoal</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1076">actions/dependency-review-action#1076</a></li> <li>Resolve security findings by <a href="https://github.com/AshelyTC"><code>@AshelyTC</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1094">actions/dependency-review-action#1094</a></li> <li>v5.0.0 release branch by <a href="https://github.com/ahpook"><code>@ahpook</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1098">actions/dependency-review-action#1098</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/scottschreckengaust"><code>@scottschreckengaust</code></a> made their first contribution in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1084">actions/dependency-review-action#1084</a></li> <li><a href="https://github.com/mongolyy"><code>@mongolyy</code></a> made their first contribution in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1091">actions/dependency-review-action#1091</a></li> <li><a href="https://github.com/Marukome0743"><code>@Marukome0743</code></a> made their first contribution in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1077">actions/dependency-review-action#1077</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/dependency-review-action/compare/v4.9.0...v5.0.0">https://github.com/actions/dependency-review-action/compare/v4.9.0...v5.0.0</a></p> <h2>Dependency Review Action 4.9.0</h2> <p>This feature release contains a couple of notable changes:</p> <ul> <li>There is a new configuration option <code>show_patched_versions</code> which will add a column to the output, showing the fix version of each vulnerable dependency. Thanks <a href="https://github.com/felickz"><code>@felickz</code></a>!</li> <li>Runs which do not display OpenSSF scorecards no longer fetch scorecard information; previously it was fetched regardless of whether or not it was displayed, causing unneccessary slowness. Great catch <a href="https://github.com/jantiebot"><code>@jantiebot</code></a>!</li> <li>There are a couple of fixes to purl parsing which should improve match accuracy for <code>allow-package-dependency</code> lists, including case (in)sensitivity and url-encoded namespaces Thanks <a href="https://github.com/juxtin"><code>@juxtin</code></a>!</li> </ul> <h2>What's Changed</h2> <ul> <li>Compare normalized purls to account for encoding quirks by <a href="https://github.com/juxtin"><code>@juxtin</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1056">actions/dependency-review-action#1056</a></li> <li>Make purl comparisons case insensitive by <a href="https://github.com/juxtin"><code>@juxtin</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1057">actions/dependency-review-action#1057</a></li> <li>Feat: Add <code>Patched Version</code> to <code>Vulnerabilities</code> summary by <a href="https://github.com/felickz"><code>@felickz</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1045">actions/dependency-review-action#1045</a></li> <li>fix: only get scorecard levels if user wants to see the OpenSSF scorecard by <a href="https://github.com/jantiebot"><code>@jantiebot</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1060">actions/dependency-review-action#1060</a></li> <li>Bump actions/stale from 10.1.0 to 10.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1058">actions/dependency-review-action#1058</a></li> <li>Bump actions/checkout from 4 to 6 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1021">actions/dependency-review-action#1021</a></li> <li>Updates for release 4.9.0 by <a href="https://github.com/ahpook"><code>@ahpook</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1064">actions/dependency-review-action#1064</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/jantiebot"><code>@jantiebot</code></a> made their first contribution in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1060">actions/dependency-review-action#1060</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/dependency-review-action/compare/v4.8.3...v4.9.0">https://github.com/actions/dependency-review-action/compare/v4.8.3...v4.9.0</a></p> <h2>4.8.3</h2> <h2>Dependency Review Action v4.8.3</h2> <p>This is a bugfix release that updates a number of upstream dependencies and includes a fix for the earlier feature that detected oversized summaries and upload them as artifacts, which could occasionally crash the action.</p> <p>We have also updated the release process to use a long-lived <code>v4</code> <strong>branch</strong> for the action, instead of a force-pushed tag, which aligns better with git branching strategies; the change should be transparent to end users.</p> <h2>What's Changed</h2> <ul> <li>GitHub Actions can't push to our protected main by <a href="https://github.com/dangoor"><code>@dangoor</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1017">actions/dependency-review-action#1017</a></li> <li>Bump actions/stale from 9.1.0 to 10.1.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/dependency-review-action/pull/995">actions/dependency-review-action#995</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
74e6c3ad79 |
[UITests] New framework around WinApp CLI, no WinAppDriver or Selenium. (#48467)
# Add winappcli-based UI test harness (no WinAppDriver / Selenium) ## Summary Introduces a new UI test harness — `Microsoft.PowerToys.UITest.Next` — that drives PowerToys modules through Microsoft's [winappcli](https://github.com/microsoft/WinAppCli) (UI Automation CLI) instead of WinAppDriver + Selenium. Engine is a single executable shelled out from C#; no third-party NuGet packages, no driver process, no Appium server. Adds two real consumers: a full ColorPicker end-to-end scenario and a Settings shell navigation smoke test. This is opt-in and additive — the existing `UITestAutomation` library and the WinAppDriver-based test projects are untouched. Both can coexist while we evaluate the new harness. Inspired in part by [#48414](https://github.com/microsoft/PowerToys/pull/48414), which lands the same architectural bet (winappcli, AutomationId selectors, no WinAppDriver) at a smaller scope. This PR generalizes it into a reusable library. ## Why WinAppDriver + Selenium is a legacy pre-agentic solution that is no longer actively maintained. It's unreliable, heavyweight, and slow. To achieve 100% UI test coverage, we should leverage modern, reliable solutions, and WinApp CLI is a strong candidate. ## What's in this PR ### Harness library — [`src/common/UITestAutomation.Next/`](src/common/UITestAutomation.Next/) | File | Purpose | |---|---| | [`WinappCli.cs`](src/common/UITestAutomation.Next/WinappCli.cs) | Process wrapper around `winapp.exe`. `Invoke` / `InvokeAssertSuccess` / `InvokeJson` / `IsAvailable` / `TryResolveExecutable`. `Result` carries the args and emits `DescribeFailure()` like `winapp ui invoke X -w 12345 -> exit 1; stderr: ...` | | [`Session.cs`](src/common/UITestAutomation.Next/Session.cs) | Test session, scoped by either HWND (`-w`) or process (`-a`) via `TargetScope`. `Find<T>` / `FindAll<T>` / `Inspect` / `Screenshot` / `SendKeys`. `Session.FromProcess(...)` factory for the single-window-per-process case | | [`SessionHelper.cs`](src/common/UITestAutomation.Next/SessionHelper.cs) | Owns the launch + window-readiness flow. Static `EnsureRunning(scope, timeout)` returns whether the call had to launch (so cleanup only kills what we started). Uses `UseShellExecute=true` so child handles don't keep MSTest hanging | | [`UITestBase.cs`](src/common/UITestAutomation.Next/UITestBase.cs) | MSTest base class. Pre-flights `WinappCli.IsAvailable()` once per process and fails fast with the install hint if `winapp.exe` isn't on PATH | | [`Element/*.cs`](src/common/UITestAutomation.Next/Element/) | `Element`, `Button`, `ToggleSwitch`, `TextBox`, `NavigationViewItem`, `Window`. `Click` / `MouseClick` / `Focus` / `GetProperty` / `GetValue` / `HelpText` / `WaitForProperty` / `WaitForGone` plus coords (`X`/`Y`/`Width`/`Height`) | | [`By.cs`](src/common/UITestAutomation.Next/By.cs) | `By.Name` / `By.AccessibilityId` / `By.Id` / `By.Slug` | | [`Windows.cs`](src/common/UITestAutomation.Next/Windows.cs) | `WindowsFinder.ListAll` / `ListByApp` / `WaitForWindowByApp` / `WaitForWindowByProcess`. Notes the winappcli bug where unfiltered `list-windows` drops untitled windows | | [`WindowControl.cs`](src/common/UITestAutomation.Next/WindowControl.cs) | Tolerant Win32 helpers — `TryCloseByApp` / `TryFocusByApp` / `SafeCloseAndFocus` / `TryKillProcess` — for `finally` blocks | | [`KeyboardHelper.cs`](src/common/UITestAutomation.Next/KeyboardHelper.cs) | Hybrid `keybd_event` + `SendKeys.SendWait` chord sender — required for global PowerToys hotkeys | | [`MouseHelper.cs`](src/common/UITestAutomation.Next/MouseHelper.cs) | `MoveTo` / `LeftClick` / `RightClick` / `LeftClickAt` Win32 wrappers | | [`ClipboardHelper.cs`](src/common/UITestAutomation.Next/ClipboardHelper.cs) | STA-thread `Clipboard` access with `WaitForText` | | [`ModuleConfigData.cs`](src/common/UITestAutomation.Next/ModuleConfigData.cs) | `PowerToysModule` enum + path/process-name resolution | ### Tests **[`src/modules/colorPicker/ColorPicker.UITests/`](src/modules/colorPicker/ColorPicker.UITests/)** — replaces the previous empty `UITest-ColorPicker` stub. One test, [`ColorPickerEndToEndTests.NavigateReadShortcutActivateAndCapture`](src/modules/colorPicker/ColorPicker.UITests/ColorPickerEndToEndTests.cs), drives the full E2E: 1. Navigate to the Color Picker page via the dashboard utilities stack 2. Toggle the module OFF, verify `PowerToys.ColorPickerUI` exits; toggle ON, verify it respawns 3. Read the activation shortcut from the page's `ShortcutControl` (`EditButton.HelpText`) 4. Clear clipboard, park cursor, send the chord 5. Wait for the picker overlay window 6. Read the displayed HEX from a hidden XAML automation peer (see below) 7. Left-click to capture; assert the clipboard value matches the peer's HEX 8. Wait for the editor window and assert the captured color appears in its tree **[`src/settings-ui/Settings.UITests/`](src/settings-ui/Settings.UITests/)** — `SettingsNavigationSmokeTests.NavigationItem_NavigatesWithoutCrashing` is one `[TestMethod]` parameterized with `[DynamicData]`, producing 31 discrete results — one per `NavigationViewItem` in [`ShellPage.xaml`](src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml). For each item: navigate, settle 250ms, assert `PowerToys.Settings` is still alive. Catches FailFast regressions in `ShellViewModel.Frame_NavigationFailed` that pure-logic unit tests can't reach (the failure path needs a `NavigationFailedEventArgs` which is a sealed WinRT projection). ### Product change **[`src/modules/colorPicker/ColorPickerUI/Views/MainView.xaml`](src/modules/colorPicker/ColorPickerUI/Views/MainView.xaml)** — adds a hidden `TextBlock` automation peer: ```xml <TextBlock x:Name="ColorHexAutomationPeer" AutomationProperties.AutomationId="ColorHexAutomationPeer" IsHitTestVisible="False" Opacity="0" Text="{Binding ColorText}" /> ``` The visible `ColorTextBlock` has `AutomationProperties.Name="{Binding ColorName}"`, which masks the HEX value in the UIA tree (you see "White" instead of `#FFFFFF`). This zero-impact peer mirrors `ColorText` so tests can read the actually-displayed HEX. `Opacity=0` + `IsHitTestVisible=False` keep it out of the visual layout and out of accessibility focus. ### Project wiring - [`PowerToys.slnx`](PowerToys.slnx) — registers `UITestAutomation.Next` under `/common/`, `ColorPicker.UITests` under `/modules/colorpicker/Tests/`, and `Settings.UITests` under `/settings-ui/Tests/`. Original `UITest-ColorPicker` stub csproj removed. - [`.github/actions/spell-check/expect.txt`](.github/actions/spell-check/expect.txt) — adds `winapp` / `winappcli`. ### Not in this PR - No pipeline changes. `winapp.exe` is expected to be pre-staged on the test agent image. If it's missing, `UITestBase` fails the first test with the install hint (`winget install Microsoft.winappcli`) rather than producing 30 opaque per-test errors. - No changes to the legacy `UITestAutomation` library or any of the existing `*.UITests` projects. ## Validation - All three projects build clean on `x64|Debug` (empty `build.<config>.<plat>.errors.log`): - `src/common/UITestAutomation.Next/` - `src/modules/colorPicker/ColorPicker.UITests/` - `src/settings-ui/Settings.UITests/` - Both tests run in Test Explorer / `dotnet test` via Microsoft.Testing.Platform (already enabled repo-wide in `Directory.Build.props`). - Local runs: ColorPicker E2E green; Settings smoke green across all 31 nav items. - `winapp 0.3.2` from `winget install Microsoft.winappcli`. ## Notes for reviewers - **`UseShellExecute = true`** in `SessionHelper.EnsureRunning` is intentional — `false` makes child processes inherit the test host's stdin/stdout/stderr handles, which keeps MTP/Test Explorer marking the run as "in progress" until the spawned PowerToys exits. - **Process-scope (`-a`) targeting** in the Settings smoke test handles single-instance handoff: the EXE you launch may exit with code 0 immediately after signalling an existing owner, so the alive check uses `Process.GetProcessesByName` rather than the launcher PID. - **AutomationId-only selectors** in the Settings smoke list keep the test localization-independent. Parent groups have `SelectsOnInvoked="False"` and only expand on click — `Element.Click` tries `InvokePattern → TogglePattern → SelectionItemPattern → ExpandCollapsePattern` so the same call works for both leaves and groups. - **Untitled-window discovery**: filtered `winapp ui list-windows -a <name>` returns windows that the unfiltered call drops (e.g. ColorPicker editor). `WindowsFinder.ListByApp` uses the filtered form. Reported upstream. ## Before Merge - Add the `winappcli` install step to the UI-test pipeline. |
||
|
|
f5c6f50e30 |
[Quick Accent] Add Belarusian Latin and Belarusian Cyrillic character sets (#48344)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request This PR adds support for Łacinka (Belarusian Latin) and Belarusian Cyrillic character sets to Quick Accent. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #36571 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments This is a standard character set addition, with new entries in the Language enum, the sets themselves added to CharacterMappings.All and new resource strings for the user-facing names in the Settings page. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed (Manual tests.) - Confirmed that the new character set entries were present in the Quick Accent settings page list. - Tested that each of the characters in both the sets could be selected and typed. |
||
|
|
af45c3ec7c |
Add press-and-hold activation mode to Quick Accent (#48937)
## Summary of the Pull Request Adds an opt-in **press-and-hold** activation mode to Quick Accent, like iOS / macOS: hold an accent-capable letter (e.g. `a`) and after a short, configurable delay the accent picker opens automatically — no separate trigger key (Space/arrows) required. This is purely additive. The existing trigger-key modes (`Left/Right arrow`, `Space`, `Both`) and all serialized settings values are unchanged. https://github.com/user-attachments/assets/faec298c-e42c-4fd1-84bd-6e74d1b481a0 ### What it does - Holding a letter types the base letter immediately, then arms the picker. After the **Hold duration** (default **500 ms**) the toolbar appears. - Navigate the options with the arrow keys / Space, then **release the letter** to insert the selected accent (it replaces the base letter). - A quick tap types just the letter. Holding and releasing without selecting leaves the base letter as-is. - `Ctrl` / `Alt` / `AltGr` / `Win` + letter combinations are left untouched, so shortcuts like `Ctrl+A` still work. ## PR Checklist - [ ] **Closes:** N/A — feature enhancement (happy to link a tracking issue if one is preferred) - [x] **Communication:** Discussed direction with maintainers; coordinated with #48891 (see below) - [ ] **Tests:** No automated tests added — the activation decision lives in the C++ low-level keyboard hook and isn't reachable from the existing managed unit-test project. Validated manually (steps below). Open to guidance on the preferred test surface. - [x] **Localization:** All new end-user strings are in `Settings.UI/Strings/en-us/Resources.resw` with translator comments. - [x] **Dev docs:** `doc/devdocs/modules/quickaccent.md` updated with the new mode. - [x] **New binaries:** None. - [x] **Documentation updated:** Dev docs updated; public Learn docs can follow once shipped. ## Detailed Description of the Pull Request / Additional comments - **`PowerAccentKeyboardService` (C++ hook):** - Append `PressAndHold` to the internal `PowerAccentActivationKey` enum (value `3`, appended to preserve serialized `0/1/2`). - Add a `holdDuration` setting and `UpdateHoldDuration(Int32)` to the WinRT projection (`.idl`). - In `OnKeyDown`, arm the picker on the held letter itself; the base letter still types on first press and auto-repeat is swallowed (reuses the existing `m_toolbarVisible` repeat guard from #36853). - In `OnKeyUp`, use the hold duration as the minimum-hold release threshold for this mode (trigger modes keep using `inputTime`). - Modifier guard: Ctrl/Alt/AltGr/Win do not arm the mode. - **Settings model (`Settings.UI.Library`):** append `PressAndHold` to `PowerAccentActivationKey`; add `hold_duration_ms` (`IntProperty`, default 500). Existing `settings.json` without the field falls back to the 500 ms default. - **`PowerAccent.Core`:** read and forward the hold duration to the hook, and use it as the popup delay when `PressAndHold` is active. - **Settings UI:** add the **"Press and hold the letter"** activation option and a **"Hold duration (ms)"** control that is shown only when that mode is selected. ### Enum sync note `PowerAccentActivationKey` exists in both the C++ hook and the managed settings library and is kept in sync by integer value. `PressAndHold` was **appended** (never reordered) so existing serialized settings (`0/1/2`) keep their meaning. ### Coordination with #48891 (Quick Accent WinUI migration) This lands as its own atomic change on `main`. The overlap with the in-progress WinUI migration (#48891) is tiny: only `PowerAccent.cs`'s mode-aware popup delay (a single `Task.Delay` line). The C++ hook, settings enum/model, and Settings UI are not touched by #48891, so it can rebase onto this with minimal effort. ## Validation Steps Performed - Built the full chain in `Debug|x64`: - `PowerAccent.UI.csproj` → rebuilds the C++ `PowerAccentKeyboardService` projection (incl. `UpdateHoldDuration`) + `PowerAccent.Core` + `Settings.UI.Library`. **0 errors.** - `PowerToys.Settings.csproj` → Settings UI XAML / ViewModel / `.resw` (XamlIndexBuilder search index regenerated). **0 errors.** - Manual trial of the running module (`PowerToys.PowerAccent.exe`) with `activation_key = 3`: - Hold `a` → base letter types immediately; picker opens after ~500 ms; arrows/Space navigate; releasing inserts the accent (replacing the base letter). - Quick tap → base letter only. Hold + release without selecting → base letter remains. - `Ctrl+A` / `Alt`+letter unaffected. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
d6319516d0 |
[Skills] Fix wpf-to-winui3-migration SKILL.md failing to load (#49059)
## Summary of the Pull Request The `wpf-to-winui3-migration` agent skill failed to load. The `description` field in its `SKILL.md` YAML frontmatter was an **unquoted** plain scalar containing `Keywords: ` (a colon followed by a space). YAML interprets `: ` as a mapping key/value separator, so the skill loader failed with: > failed to parse YAML frontmatter: mapping values are not allowed in this context at line 2 column 651 Because `.claude/skills` is a symlink to `.github/skills`, the CLI enumerates the same file twice, so this single defect surfaced as **two** skill load errors (`skill_error_count: 2`). Fix: wrap the `description` value in single quotes so the colon is treated literally. No wording changes; the description stays 926 characters (well under the 1024 limit). ## PR Checklist - [ ] Closes: #xxx — N/A, trivial metadata fix, no tracking issue - [x] **Communication:** Metadata-only fix; no design discussion needed - [ ] **Tests:** N/A — no test harness for skill frontmatter; validated by YAML parsing (see below) - [x] **Localization:** N/A — not end-user-facing - [ ] **Dev docs:** N/A - [ ] **New binaries:** N/A ## Detailed Description of the Pull Request / Additional comments `.github/skills/wpf-to-winui3-migration/SKILL.md` line 3 changed from: ```yaml description: Guide for migrating ... after migration. Keywords: WPF, WinUI, ... SoftwareBitmap. ``` to: ```yaml description: 'Guide for migrating ... after migration. Keywords: WPF, WinUI, ... SoftwareBitmap.' ``` The three other top-level skills already quote (or avoid `: ` in) their descriptions, so only this one was affected. Single quotes are used because the description contains no quote characters, so no escaping is required. ## Validation Steps Performed - Reproduced the loader error from the Copilot CLI logs: `mapping values are not allowed in this context at line 2 column 651`. - Parsed the frontmatter of all 9 `SKILL.md` files with a YAML parser: before = 1 failure (this file), after = **0 failures**. - Confirmed parsed `name` (`wpf-to-winui3-migration`), `description` (926 chars, ≤ 1024), and `license` are intact and the literal `Keywords: WPF...` text is preserved. Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
4a27c5d5f9 |
New+: Fix French translation guidance (Nouveau+ not Nouveauté+) (#47225)
## Summary of the Pull Request
French translation of "New+" was rendered as "Nouveauté+" ("Novelty+")
instead of "Nouveau+" ("New+"), inconsistent with how Windows itself
translates the "New" context menu item in French. This updates
translator guidance comments in the English resource files to explicitly
call out the correct French form.
## PR Checklist
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
## Detailed Description of the Pull Request / Additional comments
Translator-facing `<comment>` fields updated across three resource files
to explicitly state the correct French translation and flag the wrong
one:
- **`NewShellExtensionContextMenu/resources.resx`** and
**`NewShellExtensionContextMenu.win10/resources.resx`** —
`context_menu_item_new`:
> _"…e.g. Danish it would become Ny+, **French it would become Nouveau+
(not Nouveauté+)**"_
- **`Settings.UI/Strings/en-us/Resources.resw`** — five `NewPlus.*` /
`Oobe_NewPlus.*` strings:
> _"…Localize product name in accordance with Windows New. **e.g. French
would be Nouveau+ (not Nouveauté+)**"_
Actual `.lcl` translation files are managed by the CDPX localization
pipeline; these comment updates feed directly into the guidance the
localization team sees when updating those files.
## Validation Steps Performed
Comment-only changes to XML resource files; no runtime behavior
affected. Verified all targeted entries were updated and no existing
checked-in `Nouveauté` strings remain in the repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
|
||
|
|
70ff4013b9 |
Add Shortcut Guide V2 manifest spec link to copilot-instructions.md (#48967)
Adds a reference to the WinGet Manifest Keyboard Shortcuts schema spec in `.github/copilot-instructions.md` so AI agents know where to find the correct field definitions, file naming conventions, and the `+` prefix rule when creating or editing Shortcut Guide V2 manifest files. ## Summary of the Pull Request Adds a new `## Shortcut Guide V2 Manifests` section to `.github/copilot-instructions.md` linking to [`doc/specs/WinGet Manifest Keyboard Shortcuts schema.md`](../doc/specs/WinGet%20Manifest%20Keyboard%20Shortcuts%20schema.md). This ensures agents authoring new manifest files follow the correct schema and naming scheme (e.g., `<PackageId>.<locale>.yml`, `+` prefix for apps without a WinGet package). ## PR Checklist - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments `.github/copilot-instructions.md` gains a dedicated section: ```markdown ## Shortcut Guide V2 Manifests When creating or editing Shortcut Guide keyboard shortcut manifest files, follow the schema and naming conventions in the spec: - [WinGet Manifest Keyboard Shortcuts schema](<../doc/specs/WinGet Manifest Keyboard Shortcuts schema.md>) – manifest file format, field definitions, file naming, and the `+` prefix convention for apps without a WinGet package ``` No production code changes. ## Validation Steps Performed - Verified the relative link resolves to the correct spec file in the repository. - Confirmed the section is correctly placed before "Detailed Documentation". --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
7a04d4c270 |
[ShortcutGuide] Add DaVinci Resolve keyboard shortcut manifest (#48651) (#48652)
Adds a shortcut manifest for DaVinci Resolve (professional video editing and color grading application by Blackmagic Design) so it appears in the Shortcut Guide overlay when the app is focused. The manifest contains 88 of the most commonly used DaVinci Resolve keyboard shortcuts organized into 8 categories: | Section | Shortcuts | Highlights | |---------|-----------|------------| | Popular shortcuts | 25 | Page navigation (F5-F8), Playback (JKL, Space), Edit basics (Cut, Blade, Ripple Delete) | | Timeline navigation | 13 | Frame/clip/track navigation, zoom, edit point jumping | | Edit | 14 | Cut/Copy/Paste/Duplicate, Render in Place, Compound Clip | | Color | 17 | Node management (Alt+S/P/L), viewer modes (1-5), Grade/Keyframe | | Fairlight | 8 | Mute/Solo/Record/Automation, Bounce Mix | | Fusion | 8 | View switching (1-4), Merge, Keyframe | | Media | 8 | Import, Smart Bin, Reveal in Explorer, Rename | | Deliver | 5 | Render Queue, Start Render, Output settings | The manifest follows the same YAML schema as existing manifests. No code changes needed -- manifests are auto-discovered at startup. |
||
|
|
6dd1ce5dd1 |
Dev/crutkas/ripple v2.1 + spelling allow-list follow-up (#48232)
## Summary of the Pull Request Adds a follow-up metadata fix to the existing Mouse Highlighter ripple v2.1 work by allowing the term `xhair` in repo spell-check configuration. ## PR Checklist - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments - Added `xhair` to `.github/actions/spell-check/expect.txt`. - This addresses spelling feedback on MouseHighlighter ripple/crosshair code without changing runtime behavior. - No functional changes to Mouse Highlighter logic were made in this follow-up commit. ## Validation Steps Performed - Verified the only content change is the new `xhair` entry in spell-check expected words. - Ran secret scanning on changed file (`.github/actions/spell-check/expect.txt`) with no findings. - Ran parallel validation: - Code Review: no issues. - CodeQL: skipped as trivial metadata-only change. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
64f1243bdf |
Skip auto-labeling PRs that already have labels (#48877)
## Summary The auto-labeler workflow now skips pull requests that already have labels applied before running the AI classification. This avoids overwriting or duplicating labels that were manually set by contributors or maintainers. ## Changes - Added a check in `labelIssue()` that returns early for PRs with existing labels, logging which labels are already present. - Issues continue to be labeled regardless (only PRs get the skip logic). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
9ee0c7259b |
CmdPal: Dock Auto-hide (#48565)
This pull request introduces a new "Auto-hide" feature for the dock, allowing users to collapse the dock until they hover over its screen edge. The changes include updates to the settings model, UI, localization resources, and automated tests to support and verify this new functionality. **Show me:** https://github.com/user-attachments/assets/689625e8-9050-4a54-9c4b-9e303a3da63a **Conflicted?** "What if I have Taskbar and Dock on the same side and both with auto-hide turned on?" <img width="1437" height="264" alt="Screenshot 2026-06-14 144814" src="https://github.com/user-attachments/assets/bd037a11-0653-4b9a-bd21-625aca03b901" /> Closes #46239 --------- Co-authored-by: root <root@io.bbq> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
7e877558b9 |
Add powertoys-module-verification agent skill (#48717)
## Summary of the Pull Request
Adds a new **GitHub Copilot Agent Skill**,
`powertoys-module-verification`, under `.github/skills/`. It packages
the workflow, drive techniques, helper scripts, and per-module reference
data an AI agent uses to verify a single PowerToys module's
release-checklist items end-to-end (each checkbox → a structured PASS /
FAIL / BLOCKED verdict with evidence).
This is **docs/automation tooling only** — no product code, binaries, or
end-user strings are touched.
## PR Checklist
- [ ] Closes: #xxx
- [x] **Communication:** Internal tooling for release sign-off; happy to
adjust scope/placement based on review.
- [x] **Tests:** N/A — documentation/skill bundle only (no product code
paths). The 12 bundled `.ps1` helpers are agent utilities, not part of
the product build/test.
- [x] **Localization:** N/A — no end-user-facing strings.
- [x] **New binaries:** N/A — no binaries added.
- [x] **Dev docs:** This PR *is* developer-facing documentation/tooling.
## Detailed Description of the Pull Request / Additional comments
Layout follows the repo's Agent Skill guidelines
(`.github/instructions/agent-skills.instructions.md`) and matches the
existing skills under `.github/skills/`:
```
.github/skills/powertoys-module-verification/
├── SKILL.md # single entry doc (name/description/license frontmatter)
├── LICENSE.txt # Apache 2.0 (matches existing skills)
├── scripts/ # 12 PowerShell helper utilities used by the agent
└── references/
├── winapp-ui-testing.md # UIA-mechanics prerequisite doc
├── pre-flight.md / reporting-format.md / environment-setup.md / explorer-context-menu-flow.md
├── modules/ # per-module verification profiles
└── release-checklist/ # per-module checklists + index
```
Notes for reviewers:
- **`references/winapp-ui-testing.md`** is 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. Provenance is recorded in the file header. Its skill frontmatter
was intentionally stripped so it is treated as a reference doc, not a
separately-discovered skill.
- **Checklist scope:** only modules already verified end-to-end (with a
sign-off report) are included for now — Environment Variables, File
Locksmith, Image Resizer, New+, Peek, PowerRename. Remaining modules'
checklists will be added as each is verified.
- No existing files are modified; this is purely additive under
`.github/skills/`.
## Validation Steps Performed
- Validated the bundle against the Agent Skill checklist in
`.github/instructions/agent-skills.instructions.md`: valid `name` (≤64
chars) + `description` + `license` frontmatter; `SKILL.md` body under
the 500-line guidance; single `SKILL.md`; `scripts/` + `references/`
resource buckets; all resource references use relative paths.
- Verified internal cross-references resolve after the migration (no
stale `helpers/`, `Winapp-SKILL.md`, or absolute-path tokens;
`src/modules/...` source citations left intact).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||
|
|
5c63486dcb |
build(deps): bump actions/checkout from 6 to 7 (#48743)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>What's Changed</h2> <ul> <li>block checking out fork pr for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> <li>getting ready for checkout v7 release by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li> <li>update error wording by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p> <h2>v6.0.3</h2> <h2>What's Changed</h2> <ul> <li>Update changelog by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> <li>Fix checkout init for SHA-256 repositories by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>Update changelog for v6.0.3 by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/yaananth"><code>@yaananth</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p> <h2>v6.0.2</h2> <h2>What's Changed</h2> <ul> <li>Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID is set by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2355">actions/checkout#2355</a></li> <li>Fix tag handling: preserve annotations and explicit fetch-tags by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6.0.1...v6.0.2">https://github.com/actions/checkout/compare/v6.0.1...v6.0.2</a></p> <h2>v6.0.1</h2> <h2>What's Changed</h2> <ul> <li>Update all references from v5 and v4 to v6 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2314">actions/checkout#2314</a></li> <li>Add worktree support for persist-credentials includeIf by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li> <li>Clarify v6 README by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2328">actions/checkout#2328</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6...v6.0.1">https://github.com/actions/checkout/compare/v6...v6.0.1</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <h2>v7.0.0</h2> <ul> <li>Block checking out fork PR for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> </ul> <h2>v6.0.3</h2> <ul> <li>Fix checkout init for SHA-256 repositories by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <h2>v6.0.2</h2> <ul> <li>Fix tag handling: preserve annotations and explicit fetch-tags by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li> </ul> <h2>v6.0.1</h2> <ul> <li>Add worktree support for persist-credentials includeIf by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li> </ul> <h2>v6.0.0</h2> <ul> <li>Persist creds to a separate file by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li> <li>Update README to include Node.js 24 support details and requirements by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li> </ul> <h2>v5.0.1</h2> <ul> <li>Port v6 cleanup to v5 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li> </ul> <h2>v5.0.0</h2> <ul> <li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li> </ul> <h2>v4.3.1</h2> <ul> <li>Port v6 cleanup to v4 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li> </ul> <h2>v4.3.0</h2> <ul> <li>docs: update README.md by <a href="https://github.com/motss"><code>@motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li> <li>Update README.md by <a href="https://github.com/nebuk89"><code>@nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li> <li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> </ul> <h2>v4.2.2</h2> <ul> <li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li> <li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li> </ul> <h2>v4.2.1</h2> <ul> <li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
968a7ac4b6 |
[Peek] Stop fail-fast in AppWindow.Closing path; reset cached preview-handler factories on release (#48564)
## Summary
Harden Peek's `AppWindow.Closing` path so a stale cached preview-handler
factory can't fail-fast the Peek process. Also clean up the matching
path in RegistryPreview.
## Background
Spotted while reading through Peek's `MainWindow` teardown sequence and
the `ShellPreviewHandlerPreviewer` cache for an unrelated review of how
Peek manages out-of-process preview-handler lifetimes.
The Peek `MainWindow` subscribes to `AppWindow.Closing`. The handler
doesn't actually close the window — it sets `args.Cancel = true` and
calls `Uninitialize()`, which in turn calls
`ShellPreviewHandlerPreviewer.ReleaseHandlerFactories()`.
`ReleaseHandlerFactories()` looked like this:
```csharp
public static void ReleaseHandlerFactories()
{
foreach (var factory in HandlerFactories.Values)
{
try { Marshal.FinalReleaseComObject(factory); } catch { }
}
}
```
Two problems:
1. The static `HandlerFactories` dictionary is never cleared. After
`FinalReleaseComObject`, the entries still point at separated RCWs. A
subsequent activation that races with this cleanup (or a second close in
the same process) can pick up the dead RCW from the cache.
2. The cached factory had `LockServer(true)` called on it when it was
first cached, but the matching `LockServer(false)` was never paired.
Any managed exception that escapes a WinRT event callback is projected
back to CFlat as a failed HRESULT and the CsWinRT dispatcher fail-fasts
the process. So a single `InvalidComObjectException` (HRESULT
0x80131527) thrown out of `Uninitialize()` is enough to terminate Peek.
## Changes
* **`ShellPreviewHandlerPreviewer.ReleaseHandlerFactories`** — snapshot
then clear the dictionary up front so that a subsequent call (or a
concurrent `LoadPreviewAsync`) can't pick up a stale RCW. Call
`LockServer(false)` before `FinalReleaseComObject` to mirror the
cache-time `LockServer(true)`. Both COM calls remain individually
wrapped because the RCW may already be unreachable during process
teardown.
* **`Peek.UI/MainWindow.xaml.cs` — `AppWindow_Closing`** — wrap the body
in try/catch + `Logger.LogError`. Any future exception in
`Uninitialize()` (or its callees) will now log instead of fail-fasting
the process.
* **`RegistryPreview/MainWindow.Events.cs` — `AppWindow_Closing`** —
same defensive try/catch, plus null-guard `jsonWindowPlacement` before
`SetNamedValue`. The placement dictionary can legitimately be null on
first run or after a corrupt placement file; previously that would NRE →
fail-fast.
## Risk
Low. The `ReleaseHandlerFactories` change matches the documented
`LockServer`/`FinalReleaseComObject` pairing and only widens the
lifetime window of the cache by `Clear()`-ing earlier; nothing in Peek
calls this method outside of teardown. The two try/catch wrappers
strictly add defense — the success path is unchanged.
## Validation
Spot-built locally; this repo's `dotnet restore` runtime-pack issue
(unrelated to this PR — same NU1102 pattern that's affecting other open
PRs) prevents a full `Build.cmd` here. The C++ side of Peek is
untouched.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
ADO:
https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/58765809/
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Boliang Zhang <122517415+LegendaryBlair@users.noreply.github.com>
|
||
|
|
dd26d86580 |
[FancyZones] Fix stuck drag state and swallowed keys when a window is destroyed mid-drag (#48569)
## Summary Fixes a class of "stuck drag" bugs in FancyZones where closing or destroying a window **while it is being dragged** leaves FancyZones in a half-dragging state — zone overlays stay on screen and subsequent keystrokes (notably number keys) are swallowed or misrouted. ## What this changes - **Subscribe to and dispatch `EVENT_OBJECT_DESTROY`.** `FancyZonesApp` never subscribed to the destroy event, and the consumer's `WM_PRIV_WINDOWDESTROYED` branch could therefore never fire. The event is now registered and routed through `HandleWinHookEvent`. - **Abort the drag (without snapping) when the dragged window is destroyed.** On `WM_PRIV_WINDOWDESTROYED`, if the destroyed HWND is the one being dragged, call the new `WindowMouseSnap::Abort()` (tears down overlays/highlights/transparency) instead of `MoveSizeEnd()`, which would try to snap the now-dead HWND and corrupt zone state. Dragging state is then disabled. - **Always clear dragging state in `MoveSizeEnd()`**, even when the snapper was already null, so the state can't get stranded. - **Require Win+Ctrl+Alt to switch layouts while dragging.** Previously any digit switched layouts while `dragging` was true; if drag state was stuck this "stole" number keys from the focused app. This is the root-cause fix for the number-key-stealing symptom. - **Only swallow the bare Shift key during a drag**, not `Shift+<other>` combos, so real keystrokes are no longer eaten by an in-progress drag. ## Testing - Builds Release x64 (FancyZones) clean against current `main`. - Manually verified drag → close window mid-drag no longer leaves overlays up or steals number keys. (FancyZones has no unit-test harness for this path.) This is one of a small set of related "stuck key / stuck state" hardening fixes; each stands alone. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com> |
||
|
|
32ad98a0dd |
[PowerDisplay] Detect built-in panel when driven by the discrete GPU (#48637)
## Summary of the Pull Request On dual-GPU laptops, Power Display stopped detecting the built-in panel (and adjusting its brightness) when the **discrete GPU** drives the display — it showed "can't detect the display". This fixes that by classifying displays by **capability** (does WMI brightness work on it?) instead of by the nominal `OutputTechnology` value, which the discrete GPU misreports for the internal panel. ## PR Checklist - [x] Closes: #48587 - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized (no new user-facing strings added) - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places ## Detailed Description of the Pull Request / Additional comments ### Root cause On a hybrid / MUX laptop, when the **discrete GPU** drives the built-in eDP panel, `QueryDisplayConfig` reports the panel's `DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY` as `DISPLAYPORT_EXTERNAL` (`10`) instead of the `INTERNAL` flag (`0x80000000`) it reports under the integrated GPU. It is the *same physical panel* (same EDID) — only the reported connector type changes with the active GPU. PR #47740 introduced a strict classifier: `OutputTechnology` → internal/external, then **internal → WMI-only, external → DDC/CI-only, with no fallback**. So under the discrete GPU the built-in panel was classified *external* and sent to DDC/CI only — but a laptop eDP panel does not speak DDC/CI, so it was dropped and Power Display reported it couldn't detect any monitor. (`WmiMonitorBrightness` still exposes that panel regardless of which GPU drives it, so the panel was actually controllable — it just never got routed to WMI.) ### Fix: classify by capability, not by nominal output technology - **`MonitorManager`** now runs **WMI discovery first** over the full `QueryDisplayConfig` inventory. Every display `WmiMonitorBrightness` exposes is treated as internal (WMI-controlled); whatever WMI does **not** claim is routed to DDC/CI. The `OutputTechnology`-based classifier is gone. - **`WmiController`** matches the system-wide `WmiMonitorBrightness` results against the full inventory by `Monitor.Id`. The persisted `Monitor.Id` is still taken from the matched `DevicePath` (byte-identical to the DDC route and to prior releases), so saved brightness/per-monitor settings survive upgrades. - New **`MonitorIdentity.FromInstanceName`** reduces a WMI `InstanceName` to the same canonical `Monitor.Id` as `FromDevicePath`; the separate `PnpHardwareKey` helper is removed. - **Deleted** `DisplayClassifier` and `MonitorDisplayInfo.IsInternal` (net ~150 fewer lines). ### Accepted trade-off A monitor that exposes **both** `WmiMonitorBrightness` **and** DDC/CI is now controlled via WMI only and won't get DDC-only features (contrast / volume / input source / color temperature / power). This is uncommon (typical laptop panels are WMI-only; typical external monitors are DDC-only) and is a deliberate decision: it removes the entire class of `OutputTechnology` misclassification bugs while keeping the performance win of not DDC-probing internal panels. ## Validation Steps Performed - Built the Power Display app (`PowerDisplay.csproj`) and `PowerDisplay.Lib.UnitTests` (x64 / Debug) with MSBuild — both succeed, including after merging latest `main` (Windows App SDK 2.2.0). - Ran the unit test suite: **128/128 pass**, including new `FromInstanceName` tests — the `FromInstanceName == FromDevicePath` equivalence invariant and a concrete #48587 regression case (the BOE panel reported as `OutputTechnology=10`). - Traced the fix against the reporter's diagnostic logs: the panel that previously went `OutputTechnology=10 → External → DDC → dropped` is now claimed by WMI and controllable. - Reviewed the diff for regressions (Monitor.Id persistence, monitor blacklist, mirror mode, dual-internal-panel devices, external-only desktops). --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
a0e53de825 |
feat(shortcut-guide): add Postman manifest and fix numbered-key display (#48461)
## Summary of the Pull Request Adds a Shortcut Guide manifest for **Postman** and fixes a rendering bug where single-digit keys in manifests displayed incorrectly. - **Fix numbered-key rendering** — `src/modules/ShortcutGuide/ShortcutGuide.Ui/Converters/ShortcutDescriptionToKeysConverter.cs`: a single digit (`0`–`9`) in a manifest's `Keys` was treated as a Windows virtual-key code instead of the literal digit. Since VK `1` is the left mouse button, VK `9` is Tab, and VK `0` is undefined, shortcuts such as `Ctrl+0` (reset zoom) and `Ctrl+9` (last tab) rendered as blank/incorrect glyphs. Single digits are now rendered as the literal character. - **Add Postman shortcuts** — `src/modules/ShortcutGuide/ShortcutGuide.Ui/Assets/ShortcutGuide/Manifests/Postman.Postman.en-US.yml`: new manifest for `Postman.exe` covering Tabs, Sidebar, Request, Interface, Window and modals, and Console. Auto-included via the existing `Manifests/*.yml` glob in `ShortcutGuide.Ui.csproj`. - **Show tab-number ranges** — Edge, Chrome, Firefox, and Postman manifests: the "switch to a specific tab" entry used the literal key `1`, which (after the fix above) read as `Ctrl + 1`. It now uses a `1 - 8` range so the keycap conveys "any tab number 1 through 8". The separate "last tab" (`9`) and "reset zoom" (`0`) entries remain literal single keys. - **Add unit tests** — new `ShortcutGuide.UnitTests` (MSTest) project covering `ShortcutDescriptionToKeysConverter.GetKeysList`, including the single-digit regression. ## PR Checklist - [x] Closes: #48460 - [ ] **Communication:** I've discussed this with core contributors already. <!-- Filed #48460; the v0.100 announcement invites app-shortcut contributions via PR. --> - [x] **Tests:** Added/updated and all pass <!-- New ShortcutGuide.UnitTests (MSTest); 8 tests pass locally via vstest.console. --> - [x] **Localization:** All end-user-facing strings can be localized <!-- Shortcut names live in per-language manifest files (`*.en-US.yml`); other locales fall back to en-US, consistent with existing manifests. --> - [ ] **Dev docs:** Added/updated <!-- N/A: no behavior requiring dev-doc changes. --> - [ ] **New binaries:** Added on the required places <!-- N/A: the new manifest is a data asset under an already-shipped, globbed folder. The new test project is auto-discovered by the existing `**\*UnitTest*.dll` VSTest glob, so no CI pipeline change is required. --> - [ ] **Documentation updated:** <!-- N/A --> ## Detailed Description of the Pull Request / Additional comments The Shortcut Guide displays per-app shortcuts from YAML manifests, matched to the foreground window via `WindowFilter`. Keys are converted to keycaps by `ShortcutDescriptionToKeysConverter`. Numeric key strings were unconditionally parsed as virtual-key codes, so literal-digit shortcuts rendered wrong. The fix adds a `>= 0 and <= 9` case that emits the digit character as-is; non-digit numeric codes (arrows, etc.) are unchanged. The new Postman manifest exercises this with `Ctrl+0` / `Ctrl+9`. The browser/Postman "specific tab" entries were updated from the literal `1` to the `1 - 8` range string, rendered verbatim by `KeyVisual` (the same path used by the existing `Number (1-9)` key in the Windows Explorer manifest). A new `ShortcutGuide.UnitTests` (MSTest) project covers the converter: single digits render literally (regression test), modifier ordering, non-numeric passthrough (e.g. `1 - 8`), and arrow-key VK mapping. ## Validation Steps Performed Built and ran locally (x64 Debug): - Built `ShortcutGuideModuleInterface`, `ShortcutGuide.Ui`, and `ShortcutGuide.IndexYmlGenerator`; launched the Debug `PowerToys.exe`. - Triggered Shortcut Guide (`Win+Shift+/`) with **Postman** focused: the Postman section renders with all categories, and `Ctrl+1` / `Ctrl+9` / `Ctrl+0` display correctly (previously blank/incorrect). - Verified the "specific tab" entry renders as `Ctrl + 1 - 8` in **Edge**, **Chrome**, **Firefox**, and **Postman**. - Built `ShortcutGuide.UnitTests` and ran via `vstest.console.exe`: **8/8 tests pass**. <img width="845" height="1432" alt="PowerToys Shortcut Guide Running Postman" src="https://github.com/user-attachments/assets/6359617e-3e2c-48b0-8005-b3684594ec94" /> Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
c41ac6df87 |
Add Pitjantjatjara language support to Quick Accent (#48561)
Closes #45025 ## [QuickAccent] Add Pitjantjatjara / Yankunytjatjara Language Support ### Summary This pull request adds support for Pitjantjatjara/Yankunytjatjara to the Quick Accent feature. Pitjantjatjara/Yankunytjatjara is an Australian Aboriginal language spoken in the Western and South Australian deserts. ### What's New - Users can now access Pitjantjatjara/Yankunytjatjara retroflex consonant characters (ḻ, ṉ, ṟ, ṯ) through Quick Accent - Language is available in the Quick Accent settings dropdown menu - Full localization support for UI display ### Why This Matters Pitjantjatjara/Yankunytjatjara uses unique retroflex consonants that are essential for: - **Correct pronunciation:** Retroflex sounds are phonetically distinct from regular consonants - **Written accuracy:** Proper character representation in educational materials - **Cultural preservation:** Supporting Aboriginal language documentation and teaching - **Accessibility:** Users without specialized keyboards can now type these characters easily ### Character Mappings The implementation adds 4 retroflex consonants: - **L → ḻ** (Retroflex lateral approximant) - **N → ṉ** (Retroflex nasal) - **R → ṟ** (Retroflex approximant) - **T → ṯ** (Retroflex stop) ### Files Changed 1. **Language.cs** - Added `PJT` enum value 2. **CharacterMappings.cs** - Added language entry with character mappings and display order 3. **Resources.resw** - Added localized UI string 4. **expect.txt** - Added language name to spell-check whitelist ### Testing - ✅ Language appears in Quick Accent settings dropdown - ✅ Retroflex characters appear when holding L/N/R/T + activation key - ✅ No build errors or warnings |
||
|
|
459bd56fb6 |
Grab and Move: tight warning-gold overlay border + Always On Top 4px default (#48474)
## Summary Refines the **Grab and Move** drag/resize overlay so it matches the polish of **Always on Top (AoT)**, and lowers the AoT default border thickness. Created at the request of @crutkas. Two related border-refinement changes, kept in one PR because the Grab and Move "double layer" is designed around AoT's border. https://github.com/user-attachments/assets/0b605f92-60bd-44a0-a540-70e6d425146a ### 1. Always on Top - default border thickness 15 -> 4 The default highlight border was `15px`, which is visually heavy. Dropped to `4px` for a tighter, Fluent-style frame. - `src/modules/alwaysontop/AlwaysOnTop/Settings.h` (C++ default) - `src/settings-ui/Settings.UI.Library/AlwaysOnTopProperties.cs` (`DefaultFrameThickness`) - Existing users keep their configured value; only fresh installs / "reset" pick up `4`. Slider range (1-30) is unchanged. ### 2. Grab and Move - tight, warning-gold overlay (fill + border) Previously the overlay was a full translucent **white wash** sized to `GetWindowRect`, which includes the invisible resize-border / shadow margins (~7px) - so it sat *off* the visible window. It now hugs the visible frame, mirroring AoT: - **Keeps the translucent white wash** over the visible window (the familiar "grabbed" feedback) and adds a tight **warning-gold border on top**. Both hug the visible frame and are rounded to match the window corners. - **Tight geometry:** anchored to `DWMWA_EXTENDED_FRAME_BOUNDS` (inset by the invisible-border margins) instead of `GetWindowRect`. - **Corner detection:** matches the window's corner radius via `DWMWA_WINDOW_CORNER_PREFERENCE` (same mapping AoT uses); border thickness and radius scale with the target window DPI. - **Distinct accent:** Fluent **warning gold `#FFB900`** - the literal equivalent of WinUI [`SystemFillColorCaution`](https://learn.microsoft.com/en-us/windows/apps/design/style/color) (used as a `ThemeResource` for warnings across the Settings UI; a Win32 layered window can't resolve a `ThemeResource`, so a literal is required). Keeps Grab and Move visually distinct from AoT's accent-blue. - **Double layer, for free:** the Grab and Move border is drawn just **inside** the visible edge, while AoT draws its border just **outside** the visible edge. The two naturally stack into a clean double layer, so Grab and Move stays a constant **4px** with no AoT detection / window enumeration. Rendering keeps the existing GDI + `UpdateLayeredWindow` per-pixel-alpha path and adds **GDI+** (a Windows system library - no new third-party dependency) for the antialiased, rounded fill and border. Frame metrics are computed **once per drag/resize** (never in the mouse-move hot path). The optional geometry label is unchanged. ## Before / After | | Before | After | |---|---|---| | Grab and Move overlay | Full white wash, offset from the window edge | Same wash, now tight to the visible frame + gold border, corner-matched | | AoT default border | 15px | 4px | | AoT + Grab and Move together | white wash over AoT border | GM gold inside the edge + AoT accent outside it = double layer | ## Validation - Builds clean (exit 0, 0 warnings/errors) for **x64 Debug**: `GrabAndMove`, `AlwaysOnTop`, and `Settings.UI.Library` (Code Analysis / C26451 clean). - Smoke-tested live by running the standalone module exes: tight gold border + wash on Alt-drag / Alt-right-drag, AoT 4px border, and the inside/outside double layer on a pinned window. - WARNING: still **draft** pending broader visual validation (border tightness across DPIs, the exact gold, rounded vs square corners, AoT z-order during fast drags - AoT renders from a separate process and follows on a ~100ms timer). Screenshots to be added. ## Follow-up (not in this PR) AoT and Grab and Move remain **separate** overlay systems (AoT: persistent per-window Direct2D border; Grab and Move: transient GDI/`UpdateLayeredWindow` overlay). They can't share one runtime window, but the frame-geometry + corner-detection + DPI helpers are worth extracting into `src/common` (seeded by AoT's `WindowCornersUtil`/`ScalingUtils`). Tracked separately to keep this PR atomic (`src/common` is an ABI-careful area). ## Notes - No IPC/JSON schema changes; no new settings. - No new third-party dependencies (GDI+ is a system library). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
d2aa24786d |
[DOCS] Add auto-generated github page for dev docs (#48752)
This pull request introduces a new, automated workflow for building and publishing the developer documentation website using [docmd](https://docmd.io/). The static site is now generated from `doc/devdocs`, built in the `doc/devdocs-website` folder, and deployed to GitHub Pages via a GitHub Actions workflow. The build output is not committed to the repository but is instead published as an artifact. Supporting configuration files, documentation, and `.gitignore` entries are also added to streamline local development and CI/CD. **Automated build and deployment:** * Added `.github/workflows/regenerate-devdocs-website.yml` to build the static site with docmd and deploy it to GitHub Pages automatically on changes to `doc/devdocs` or `doc/devdocs-website`, or via manual trigger. **Project setup and configuration:** * Added `doc/devdocs-website/package.json` to define the Node.js project, pin the docmd version, and provide scripts for local development and builds. * Added `doc/devdocs-website/docmd.config.json` to configure docmd (site title, source, output directory, base path). * Added `doc/devdocs-website/.npmrc` to disable lockfile generation, ensuring fresh dependency installs each build. **Documentation and housekeeping:** * Added `doc/devdocs-website/README.md` with instructions for editing, building, and publishing the docs website. * Added `doc/devdocs-website/.gitignore` to exclude the generated `site/` output from version control. |
||
|
|
d31d0ab168 |
Update labeling action to support pull requests (#48733)
This pull request updates the `auto-labeler.yml` GitHub Actions workflow to improve reliability and maintain compatibility. The most important changes are an upgrade to the `actions/github-script` version and improved error handling when applying labels, ensuring the workflow does not fail due to restricted permissions. **Dependency upgrade:** * Upgraded `actions/github-script` from version 7 to version 9 in the `Apply area labels with AI` step, ensuring continued support and access to the latest features and security updates. **Error handling improvements:** * Added a `try/catch` block around the label application logic to gracefully handle cases where the workflow lacks permission to write labels (e.g., due to restricted integration tokens), logging a message and skipping the operation instead of failing the entire workflow. |
||
|
|
486015d400 |
Add permissions for PR labeling (#48731)
This pull request makes minor adjustments to the `.github/workflows/auto-labeler.yml` GitHub Actions workflow, focusing on permissions and event triggers. Workflow configuration updates: * Added `pull-requests: write` permission to the workflow to ensure it has the necessary access for managing pull requests. * Removed the `edited` event from the list of triggers for `pull_request_target`, so the workflow will no longer run when a pull request is edited. |
||
|
|
a294e73bb6 |
[CmdPal] Animated notification (#48176)
## Summary of the Pull Request Gives the CmdPal toast notification a glow-up: it now slides in/out with a nice fade, has acrylic + a soft shadow, and stops fighting with `SizeToContent`. Along the way, the toast guts got refactored into a couple of reusable bits that live in `PowerToys.Common.UI.Controls` so other PowerToys utilities can grab them for their own transient overlays: - **`TransparentWindow`** — a `WindowEx`-derived host that strips the native frame, hides from taskbar/Alt-Tab, uses `TransparentTintBackdrop` for transparency, and runs show/hide implicit animations on its content. Supply your own animations via `ShowAnimations` / `HideAnimations`, or take the defaults (fade + slide). - **`TransparentCard`** — a templated `ContentControl` with acrylic (`AlwaysActiveDesktopAcrylicBackdrop`), rounded corners, border, and shadow. Drop whatever XAML you want inside. - **`AlwaysActiveDesktopAcrylicBackdrop`** — small `SystemBackdrop` wrapper so the acrylic doesn''t go grey when the window isn''t focused (transient overlays are never focused). CmdPal''s `ToastWindow` is now basically a 16-line wrapper: derives from `TransparentWindow`, drops a bound `TextBlock` inside, and handles its own 2.5s auto-hide timer + bottom-center positioning. https://github.com/user-attachments/assets/3a62080c-22f0-480c-ac4d-028bcc32f07d ## PR Checklist - [x] Closes: #40886 - [x] **Communication:** I''ve discussed this with core contributors already. - [ ] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places ## Detailed Description of the Pull Request / Additional comments A couple of design notes worth calling out: - The window is sized slightly bigger than the visible card (~24px breathing room on each side) so the shadow and slide animation have room to render without clipping. That buffer area is transparent but NOT click-through — kept it small on purpose. We explored `SetWindowRgn` and `EnableWindow` tricks to make it click-through too, but neither plays nicely with WinUI 3''s DesktopWindowXamlSource. Small transparent frame is the pragmatic compromise. - Animations use the Toolkit''s implicit `ShowAnimations` / `HideAnimations` so there''s zero animation code in `ToastWindow.xaml.cs`. - `TransparentCard.xaml` is registered in `Themes/Generic.xaml` — required for templated controls in a library project; `<GenerateLibraryLayout>` alone doesn''t auto-merge per-control xaml. ## Validation Steps Performed - Built clean (arm64 Debug). - Triggered a CmdPal toast manually: fades + slides in, hangs for 2.5s, fades + slides out. - Acrylic stays active when the window isn''t focused (toasts are never focused). - Shadow renders fully without clipping. --------- Co-authored-by: niels9001 <niels9001@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
e8fee90f49 |
Enhance labeling action to support pull requests (#48729)
This pull request updates the auto-labeling workflow to support both issues and pull requests, improves clarity in logs and prompts, and renames the workflow file for broader applicability. The changes enhance automation for triaging by enabling area label assignment to new or updated pull requests in addition to issues. **Expanded triage coverage and workflow improvements:** * The workflow now triggers on both issue and pull request events (`opened`, `reopened`, `edited`, `synchronize`), allowing automatic area labeling for pull requests as well as issues. (`.github/workflows/auto-labeler.yml`, [.github/workflows/auto-labeler.ymlL1-R7](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL1-R7)) * The concurrency group logic has been updated to handle pull request events separately from issues, ensuring that rapid updates to a PR or issue are managed correctly. (`.github/workflows/auto-labeler.yml`, [.github/workflows/auto-labeler.ymlR24-R26](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eR24-R26)) **User experience and clarity enhancements:** * Console logs and prompt messages now refer generically to "item" or distinguish between "Issue" and "Pull request" as appropriate, improving clarity in workflow output and AI prompts. (`.github/workflows/auto-labeler.yml`, [[1]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL41-R44) [[2]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL58-R79) [[3]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL139-R146) [[4]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL212-R217) * The system prompt for the AI labeling assistant has been updated to clarify that both issues and pull requests should be classified and labeled. (`.github/workflows/auto-labeler.yml`, [.github/workflows/auto-labeler.ymlL127-R133](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL127-R133)) **File naming:** * The workflow file has been renamed from `.github/workflows/auto-label-issues.yml` to `.github/workflows/auto-labeler.yml` to reflect its broader scope. (`.github/workflows/auto-labeler.yml`, [.github/workflows/auto-labeler.ymlL1-R7](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL1-R7)) |