Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
159985 stories
·
33 followers

Aspire 13.5.3

1 Share

What's New in Aspire 13.5.3

Patch release for Aspire 13.5 that fixes Dashboard Graph view crashes for resources with multi-path icons and restores missing public URLs for DevTunnel resources.

🐛 Fixes

  • 📊 Dashboard Graph view could crash for Azure Blob resources — Resources such as those created with AddBlobs use icons containing multiple SVG paths, which caused an XML parsing exception and broke the dashboard circuit. The graph now combines multi-path icons correctly. Regression introduced in 13.5. Fixes #19489. (#19585, backport of #19579, @sebastienros)

  • 🌐 DevTunnel public URLs were missing from the Dashboard and MCP snapshots — DevTunnel port resources could report Running and Healthy while showing no public URLs. Proxyless port allocation is now limited to compute and container resources, allowing DevTunnels to publish their actual public endpoints. Regression introduced in 13.5. Fixes #19496. (#19625, backport of #19590, @karolz-ms, @danegsta)

🏷️ Housekeeping

  • 🚀 Bumped branding to 13.5.3

Full Changelog: v13.5.2...v13.5.3

Full commit: b5f143315ffb6968ea939a9978797a5b20e4c688

Read the whole story
alvinashcraft
just a second ago
reply
Pennsylvania, USA
Share this story
Delete

2.4 Experimental (2.4.1-experimental) 🧪

1 Share

Windows App SDK 2.4 Experimental (2.4.1-experimental) 🧪

Windows App SDK 2.4 Experimental is the latest experimental release, headlined by inking support for WinUI 3 and new response statuses for on-device language models. It follows Windows App SDK 2.4.0 stable and generally brings forward the changes from that release alongside the experimental-only additions below.

What's new in WinAppSDK 2.4 Experimental:

  • Inking support for WinUI 3. The new InkCanvas, InkToolbar, and InkPresenter APIs add pen and touch input, clipboard and high-contrast support, stroke input, and unprocessed input to WinUI 3 apps.
  • Language model response statuses. New LanguageModelResponseStatus.LanguageMismatch and LanguageModelResponseStatus.UnsupportedLanguage values let apps distinguish language-related failures when working with the on-device language model.

To see everything that's new and changed, see the full Windows App SDK 2.4 Experimental release notes.

Try it out

Getting started

To get started using Windows App SDK to develop Windows apps, check out the following documentation:


This discussion was created from the release 2.4 Experimental (2.4.1-experimental) 🧪.
Read the whole story
alvinashcraft
13 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Release v0.101.2362.0

1 Share

Hero image of what's new in version 0.100

Installer Hashes

Description Filename sha256 hash
Per user - x64 PowerToysUserSetup-0.101.2362.0-x64.exe D56FA7130FA68AFE553068C15A59A6B24C8DBCC9A0989A43EF0FC5A373230DE3
Per user - ARM64 PowerToysUserSetup-0.101.2362.0-arm64.exe 4C2AE5156B7E4F1F5BA744BA6E1CF6BFE3D9614978356E6B00AA47CAB86350DB
Machine wide - x64 PowerToysSetup-0.101.2362.0-x64.exe F27E4B4B01BFF1A74BFA0116C99F9205F7138DB6F7DFCAA9223FB8B635FE6050
Machine wide - ARM64 PowerToysSetup-0.101.2362.0-arm64.exe BEE299302C0CD59E282BDC92CC8AAF737713EABCCA77BB8BF09F43745D43CD93

Highlights

⚠️ Update: We’re working through an issue with the update rollout, so this PowerToys release may take a little longer than usual to reach everyone. ⚠️

PowerToys 0.101 introduces Window Hopper for quickly moving between windows from the same app, a redesigned update experience with Stable and Insider channels, and compact mode for Command Palette. This release also continues our WinUI 3 modernization, brings on-device Phi Silica transformations to Advanced Paste, and adds a big set of improvements across PowerDisplay and Shortcut Guide.

🪟 Meet Window Hopper

If you regularly have several windows open from the same app, switching between them is now much faster. Window Hopper works like Alt + Tab, but stays within the app you're currently using. Once the utility is enabled, press the configurable Alt + backtick shortcut to cycle through that app's windows without stepping through everything else on your desktop. It is especially useful when you're juggling multiple browser windows, terminals, File Explorer windows, or editor instances.

Window Hopper

PR: #48281 (with coauthor credit to @wzhudev)

🔄 A smoother update experience and the new Insider channel

PowerToys updates now have a clearer home in Settings. Open Settings > General > Update channel to choose between Stable and Insider. Stable remains the default, while Insider lets you opt in to PowerToys Preview builds and try the latest work sooner. The selected channel remains visible when the setting is collapsed, preview builds are clearly labeled, and managed devices can still have preview updates controlled by organizational policy.

We also redesigned the update experience with clearer badges and a compact status surface that tracks each step, from checking and downloading to installation or errors. Bug reports are easier too, with progress updates, quick access to the generated ZIP, and a prefilled GitHub issue.

PowerToys update settings

PRs: #49414, #49722, and #49872

⚡ Command Palette goes compact

Command Palette can now stay out of the way until you need the results. Enable compact mode in Command Palette Settings and the palette opens as a focused search box at a configurable vertical position. Start typing and it expands just enough to show matching results; you can also use Down Arrow or Tab to expand it from the keyboard. Pages that need more room, such as detailed views and confirmation dialogs, still expand fully when required. Compact mode is off by default, so the existing full experience remains unchanged unless you opt in.

Command Palette compact mode

Compact mode is only one part of this Command Palette update:

  • Search and responsiveness: Better ranking, cached Window Walker results, and progressive icon loading make results feel faster and more predictable.
  • Reliability: Improved backdrop switching, icon loading, dock cleanup, and extension-resource management make prolonged use more stable.
  • Dock improvements: Auto-hide reclaims screen space, while the dock clock and an optional bell provide quick access to Notification Center.
  • Richer notifications: Extensions can show toasts with configurable positions, icons, and action buttons.
  • Performance Monitor: New disk activity metrics and clearer network bands make it easier to keep an eye on system performance.
  • Extension Gallery: Deep links can open the gallery or take you directly to a specific extension's installation page.
  • Windows Update commands: Update and restart and Update and shut down appear when Windows is waiting for a reboot.

Massive thanks to @jiripolasek for the sustained Command Palette work across this release!

PRs: #48801, #49177, and #49780

🔄 Quick Accent and Mouse Jump move to WinUI 3

We're continuing to modernize PowerToys utilities with WinUI 3, and this release brings refreshed foundations to Quick Accent and Mouse Jump. Quick Accent keeps its familiar character picker while gaining better theming, accessibility, and DPI-aware placement. It also adds an optional Press and hold the letter activation mode: choose it in Quick Accent Settings, configure the hold duration, then hold an accent-capable letter to open the picker. Use the arrow keys or Space to select a character and release the letter to insert it. A quick tap still types the original letter, and normal Ctrl, Alt, AltGr, and Windows-key shortcuts remain unaffected.

Mouse Jump now uses a WinUI 3 interface with improved multi-monitor and mixed-DPI behavior. Invoke Mouse Jump with your configured shortcut, then click the destination in the preview or use the number keys, Home and End, or the arrow keys to select a monitor from the keyboard. Smaller improvements across the two utilities include more reliable Quick Accent activation, better first-frame rendering, expanded language, currency, punctuation, and IPA character sets, plus updated Mouse Jump layout and release support for both x64 and ARM64.

PRs: #48891, #48937, and #48393 (Thanks, @LegendaryBlair and @mikeclayton!)

🖥️ PowerDisplay gets linked controls and faster access

PowerDisplay can now control the brightness of several monitors together. Turn on linked brightness to get one All Displays slider for every included brightness-capable monitor, while keeping selected displays independent when needed. Individual display cards remain available in an expandable section, and applying a saved profile returns to per-monitor control before restoring its values. You can also opt in to brightness control from the tray icon: choose whether scrolling over it adjusts the primary display or all linked displays, then set the amount each mouse-wheel notch should change.

PowerDisplay linked controls

PowerDisplay can now wake supported monitors by selecting On from the display's power-state control, and a new command-line interface lets you inspect displays, change monitor settings, and apply saved profiles from scripts. This release also improves built-in panel detection on hybrid-GPU systems, makes Maximum compatibility mode more resilient with unreliable monitors, preserves recent setting changes during exit, restores saved brightness, contrast, volume, and color temperature more reliably, and cleans up monitor and tray resources more consistently.

PRs: #48207 (Thanks, @gilnatab!), #48628, and #49446

📋 Advanced Paste brings local AI to custom actions

Advanced Paste now supports on-device transformations with Phi Silica on supported Windows devices, so you can use local AI without configuring a cloud endpoint or API key. In Advanced Paste Settings, check Phi Silica availability and download the model when prompted. You can then choose Phi Silica as the provider for an action, customize its prompt and coaching behavior, and assign a shortcut for quick access. Provider selection, prompts, and shortcuts can all be configured per action, making it easier to mix local and online models for different clipboard workflows.

Advanced Paste Phi Silica settings

You can also hide the AI paste section when you do not use AI features, keeping the Advanced Paste window focused on the actions you need. Custom OpenAI and Azure OpenAI actions now work more reliably with models that do not support the minimal reasoning-effort setting by allowing those services to use their own defaults.

PR: #46727

⌨️ Shortcut Guide adds Windows-key activation and search

Shortcut Guide can now respond when you hold the Windows key. In Settings, choose whether this shows taskbar indicators, opens the full guide, or remains disabled. You can also configure the hold duration and whether the full guide closes when you release the key, while keeping the regular activation shortcut independent.

Shortcut Guide now includes page-local search across shortcut names, descriptions, modifiers, and displayed keys. This makes it much faster to find one command without scanning an entire app's shortcut list.

Shortcut Guide search

The experience also moves to a single transparent overlay, enabling smoother transitions, cleaner click-outside behavior, and taskbar indicators that adapt to taskbars positioned along any screen edge. Shortcut Guide adds coverage for Brave Browser, Zoom Workspace, the new Outlook for Windows, DaVinci Resolve, Greenshot, 1Password, Godot, Obsidian, ON1 Photo RAW, and Postman, alongside fixes for key rendering, navigation, and stability.

Big thanks to @noraa-junker for the Windows-key activation options and continued Shortcut Guide improvements!

PRs: #49661, #49639, and #48683

🎥 ZoomIt adds DemoMirror

ZoomIt introduces DemoMirror, making it easier to present from one display while showing a live view on another. Press Ctrl+9 to mirror the full screen, Ctrl+Shift+9 to select a region, or Ctrl+Alt+9 to mirror the window under your pointer. The mirror includes the mouse pointer, and the optional Track window region setting keeps a mirrored window in view as it moves or resizes.

ZoomIt DemoMirror

ZoomIt also adds webcam background blur, microphone noise cancellation, and brightness controls for recording; WebP and JPEG screenshot and panorama formats; independently configurable Snip Save and Panorama Save shortcuts; and more capable recording, trimming, and automatic snip-copying workflows.

PRs: #49607 (Thanks, @chakrik73!), #48266, and #48818

🖱️ Mouse Highlighter gets composition-powered ripple effects

Mouse Highlighter now includes a Ripple mode with smooth, composition-based effects for mouse clicks. In Settings > Mouse Utilities > Mouse Highlighter, select Ripple and customize its size, intensity, duration, drag trail, and release pulse. Left and right clicks now use green and blue by default, while existing color preferences are preserved.

Ripple rendering, animation, timers, and window ordering now run separately from the low-level mouse hook. This keeps clicks responsive and prevents lost button-up events, stuck ripples, and pressed states during longer sessions.

Mouse Highlighter ripple effects

PRs: #48232, #49699, and #49833

🧩 Other notable changes

  • FancyZones: Custom layout spacing, sensitivity, and zone-count edits now apply immediately, and a new opt-in window rotation mode can move eligible windows left or right across connected displays.
  • Keyboard Manager: Fixed startup and elevated file-picker issues in the new editor, improved Alt and AltGr remapping reliability, and standardized modifier labels as Win, Ctrl, Alt, and Shift.
  • Peek: Added structured Unreal Engine project and plugin previews, optional always-on-top and taskbar visibility settings, restored .tar.gz and .tgz previews, and improved shortcut and shutdown reliability.
  • PowerToys Run: Prevented stale searches from accumulating worker threads and restored recent VS Code workspace discovery, including UNC paths.
  • File Explorer Add-ons: Added policy-controllable Markdown previews for validated relative, local, and UNC image paths, refreshed the Monaco editor, and preserved transparency in SVG thumbnails.
  • Image Resizer: Moved preset editing into a modern save-or-cancel dialog, clarified preset descriptions, improved File Explorer integration, and strengthened the public CLI's validation and diagnostics.
  • New+: Improved template renaming and now places new desktop items near the context-menu pointer with per-monitor DPI awareness.
  • Mouse Without Borders: Improved connections between computers with fresh encryption parameters and stronger session-key derivation while preserving existing pairing settings after every computer is updated.
  • Always On Top and Grab and Move: Improved shutdown and sign-out reliability, prevented potential border-update crashes, and made full-opacity Always On Top borders render consistently.
  • Color Picker: Kept the picker out of its own zoomed preview and improved sampling reliability on displays that report default refresh-rate values.

✨ Big thanks to the community

As always, a big thank-you to everyone who contributed — we couldn't do this release without you! Thanks @Sthitadhi1, @daverayment, @jiripolasek, @Knyrps, @JRScott812, @Subhro-ai, @pratnala, @giruuuuj, @MrBisquit, @DataVoyager-Aditya, @APONTES19, @st-gr, @pedrolamas, @Umoxfo, @LegendaryBlair, @foxmsft, @oMatheusmol, @fluffyspace, @agbuddy7, @mikeclayton, @cgaarden, @Ares9323, @AkazaRenn, @zheng-fan, @noraa-junker, @gilnatab, @Hashim1999164, @thetsaw, @MardSilva, @ScymicX, @jan-jaros, @Greyaircraft, @Derylfabiensyah, @ganmatthew, @class-Avirup, @agsoto, @0utsights, @tburns10, @tuckburns, @Korb, @brycewc, @chakrik73, @SeanKilleen, @MarioHewardt, @flcdrg, @MrRishabhJain, @tonythethompson, @PsychodelEKS, @antonkesy, @gavinzhangth, @Moli13337, @snickler, and @wzhudev for your pull requests!

We're always happy to get your feedback and contributions, whether it's a bug report, a feature idea, or a pull request. Head over to the PowerToys repo to jump in.

🔗 Useful links


Full release notes

Advanced Paste

  • Added on-device Phi Silica transformations and per-action provider, prompt, coaching, and shortcut customization in #46727
  • Added an Advanced Paste setting to hide the AI paste section, giving users a cleaner window when they do not need AI features in #45242
  • Fixed custom OpenAI and Azure OpenAI paste actions on models that do not support the minimal reasoning effort by allowing service defaults in #49840, with regression coverage added in #49867 by @Sthitadhi1

Window Hopper

  • Added Window Hopper for quickly switching among windows from the current application with a configurable Alt+backtick shortcut in #48281

Always On Top

  • Fixed window-border updates during resource transitions, preventing potential Always On Top crashes in #48412
  • Fixed Always On Top borders looking mottled at full opacity, producing a consistently solid frame with the configured shape and thickness in #49698
  • Fixed Grab and Move, Always On Top, and FancyZones hanging during Windows sign-out or shutdown by letting them exit promptly in #48404

Color Picker

  • Fixed the picker window appearing inside the zoomed preview, keeping sampled content unobstructed in #48762 by @daverayment
  • Fixed Color Picker sampling on displays reporting default refresh-rate sentinel values, retaining the 60 Hz fallback instead of producing invalid or one-second timer intervals in #49973

Command Palette

  • Added Down Arrow and Tab expansion shortcuts, making collapsed compact mode easier to use by keyboard in #49177 by @jiripolasek
  • Added Notification Center access from the dock clock and an optional dedicated bell item in #48514 by @Knyrps
  • Added deep links to open the Extension Gallery or a specific extension's installation page in #49780 by @jiripolasek
  • Added compact mode with configurable vertical placement, starting with a focused search box and expanding with results in #48801
  • Added dock auto-hide, reclaiming screen space until the pointer reaches the dock edge in #48565
  • Added consistent sign(x) and sgn(x) calculator functions, making sign calculations easier in #49392 by @jiripolasek
  • Added disk activity, read, and write metrics to Performance Monitor with configurable units and dock support in #48844 by @JRScott812
  • Added combined network traffic across all adapters by default, with an option to select a preferred adapter in #49678 by @jiripolasek
  • Simplified the default Performance Monitor band to CPU and memory and added a separate network speed band in #49674 by @jiripolasek
  • Added notification-position choices, letting users place toasts at preferred screen locations in #49262 by @jiripolasek
  • Added icons and action buttons to extension toasts, enabling richer notifications that pause while hovered in #49260 by @jiripolasek
  • Added disabled placeholders for unavailable Performance Monitor bands, clearly showing why metrics disappeared in #49162 by @jiripolasek
  • Added reciprocal and inverse functions, arbitrary-base logarithms, and n-th roots while fixing inverse-function parsing in #49356 by @Subhro-ai
  • Added Settings and Help to the search-bar context menu, providing faster access alongside editing commands in #49266 by @jiripolasek
  • Added live details-pane updates, showing extension content changes without reopening the item in #48070
  • Added animated acrylic notifications, delivering smoother and more polished transient messages in #48176
  • Added display labels while pinning, making the correct dock easier to identify on multi-monitor systems in #48726
  • Added Enter-key submission for single-line Adaptive Card forms, improving keyboard-only workflows in #48768
  • Limited pin-to-dock choices to enabled displays, preventing pins that appear ineffective in #48723
  • Fixed the hidden compact-mode window frame reappearing after focus changes in #49184
  • Fixed deferred compact-mode page loading, improving navigation, search visibility, and accessibility announcements in #49165 by @jiripolasek
  • Fixed live compact-mode switching, immediately restoring the results list when compact mode is disabled in #49111 by @jiripolasek
  • Fixed quoted bookmark folder paths, reliably opening directories whose names contain spaces in #48955 by @jiripolasek
  • Fixed retained Performance Monitor network items, reducing memory growth during repeated dock refreshes in #48880
  • Fixed confirmation dialogs being clipped or hidden in compact mode by expanding the palette while dialogs are open in #49451
  • Fixed Command Palette crashes when changing the main window backdrop at runtime and improved transparent fallback rendering in #49755 by @jiripolasek
  • Fixed Settings title bar icons using the wrong foreground color after an app theme change in #49750 by @jiripolasek
  • Fixed page icons disappearing when extensions change them at runtime in #49672 by @jiripolasek
  • Improved dock button feedback and spacing, making vertical and icon-only controls clearer in #49703 by @jiripolasek
  • Fixed Extension Gallery pages without homepage links, preventing a crash in #48869
  • Fixed empty icon scaling, preventing crashes when an icon fails to provide dimensions in #49385 by @jiripolasek
  • Fixed Settings breadcrumbs in non-English languages, restoring reliable navigation in #49253 by @jiripolasek
  • Improved search ranking tiers, consistently placing exact, prefix, and acronym matches above weaker results in #49189
  • Prevented collapsed compact mode from executing an unseen selected result in #49182 by @jiripolasek
  • Improved Window Walker responsiveness with cached results, background refreshes, and progressive icon loading in #49317 by @jiripolasek
  • Fixed overlapping dock visual states, producing consistent text, icon, spacing, and alignment in #49319 by @jiripolasek
  • Fixed bookmark titles and icons in the Add band flyout, including a reliable loading fallback in #49336 by @jiripolasek
  • Fixed the Open Command Palette dock item, reliably returning users to the root page in #49095 by @jiripolasek
  • Prevented delayed palette updates from stealing focus from other applications in #49087 by @jiripolasek
  • Fixed the Run command's default alias mapping and migrated existing aliases automatically in #49384 by @jiripolasek
  • Fixed large Extension Gallery screenshot strips, preventing crashes during horizontal scrolling in #48090
  • Fixed pinned bookmark bands after restart, preserving dock customizations through transient loading failures in #48092
  • Fixed stale dock clocks, applying second-display preferences immediately without repetitive screen-reader interruptions in #48253
  • Fixed multi-GPU cycling in Performance Monitor, showing metrics and names for the active GPU in #48503 by @pratnala
  • Fixed performance widgets showing ??? after restart, refreshing values when data becomes available in #48682 by @giruuuuj
  • Prevented duplicate settings history entries, making Back navigation more predictable in #48703
  • Fixed Run history initialization in optimized builds, restoring previously used commands after startup in #48463
  • Prevented repeated shortcut-dialog requests from crashing Command Palette or Settings in #49334 by @jiripolasek
  • Limited expanded compact mode to the current monitor, keeping the palette fully on-screen after display changes in #49532
  • Reduced retained resources during prolonged use, improving Command Palette stability in #48884
  • Improved icon loading responsiveness and allowed failed or interrupted loads to retry in #49738 by @jiripolasek
  • Reduced UI stalls during concurrent icon updates by removing broad icon-cache locking in #49737 by @jiripolasek
  • Reduced unnecessary Performance Monitor refresh work while disk metrics update in #49735 by @jiripolasek
  • Improved cleanup when commands and parameter lists are replaced or fail to initialize, reducing retained extension resources in #49730 by @jiripolasek
  • Improved cleanup of extension objects after navigating away from list pages in #49732 by @jiripolasek
  • Improved cleanup when top-level commands, dock bands, or providers are removed, reloaded, or disabled in #49728 by @jiripolasek
  • Fixed SDK command subscriptions remaining attached after replacement, allowing extension objects to be released in #49731 by @jiripolasek
  • Reduced unnecessary work after settings changes, avoiding unrelated hotkey, backdrop, and dock recreation in #49171 by @jiripolasek
  • Corrected Alt+F4 handling, keeping docks open and adding control over whether the main palette quits in #49708
  • Corrected the Hibernate command icon, clearly distinguishing it from Sleep in #48689 by @MrBisquit
  • Corrected multi-engine GPU calculations, keeping dock usage values at realistic levels in #48710
  • Refactored transient overlays into reusable animated surfaces, preserving polished notifications and enabling consistent future experiences in #48915
  • Removed one-pixel gaps between docks and screen edges, creating flush layouts across Windows versions in #49641 and #48091
  • Refreshed the display list when Dock settings opens, showing newly connected monitors immediately in #49705
  • Restored the previous Performance Monitor widget refresh behavior after restart to avoid regressions in #48835
  • Removed the unintended link icon from the dock clock, keeping its appearance clear in #49309
  • Recognized Origin, Ubisoft Connect, and Xbox internet shortcuts as launchable apps in #49241 by @jiripolasek
  • Removed the separator below the search bar when compact mode is collapsed in #49313 by @jiripolasek
  • Simplified the file picker button label to “Select file” in #49752 by @jiripolasek
  • Stretched expanded palette content vertically, filling the available window instead of shrinking to content in #49109 by @jiripolasek
  • Deduplicated Windows Settings by title and destination, retaining distinct settings while removing true duplicates in #49340 by @jiripolasek
  • Preserved manual result scrolling and selection while more items load, preventing snap-back interruptions in #49354 by @jiripolasek
  • Disabled compact mode by default, opening Command Palette in its full expanded experience in #49186
  • Removed disabled fallback commands from search results, respecting users' fallback preferences in #48777
  • Removed Uninstall actions from protected Windows apps, avoiding unusable commands in #48804
  • Reduced Narrator output when opening Command Palette's More actions menu, providing one clear announcement while retaining useful navigation feedback in #48928
  • Expanded Command Palette's Windows Settings search with localized Control Panel tasks, making tools such as Game Controllers, File History, and Performance Options easy to find and launch in #49252 by @DataVoyager-Aditya and @jiripolasek
  • Consolidated the remaining search-ranking improvements so result scoring is applied consistently across Command Palette in #49832
  • Fixed dock band activation and cleanup races, reducing the chance of bands becoming stuck during rebuilds in #49739 by @jiripolasek
  • Simplified Command Palette settings with clearer General and Personalization sections and removed obsolete extension-discovery UI in #49865
  • Ignored failed package catalog operations instead of treating them as successful extension changes in #49887 by @jiripolasek
  • Fixed docks becoming empty or misconfigured after docking, undocking, or changing monitor topology in #49814
  • Reduced retained resources during dock refreshes by reusing item view models, coalescing refreshes, and cleaning replaced views in #49742 by @jiripolasek
  • Ranked global fallback commands by live title and subtitle matches, allowing exact fallbacks to appear with similarly relevant results in #49983
  • Added Update and restart and Update and shut down system commands that appear when Windows Update is waiting for a reboot in #49437 by @Subhro-ai

Environment Variables

  • Restricted profile changes to the current user's environment, matching the documented scope in #48740
  • Centralized profile and variable validation, preventing invalid registry writes and improving error guidance in #46837 by @daverayment

FancyZones

  • Prevented shutdown and reconfiguration races, improving stability during display changes, dragging, and exit in #48473
  • Ended dragging cleanly when a window closes, removing stuck overlays and restoring intercepted keys in #48569 by @MuyuanMS
  • Applied custom-layout spacing, sensitivity, and zone-count edits immediately without restarting or reapplying in #49433 by @MuyuanMS
  • Added an opt-in monitor window rotation mode for previewing and moving processable windows left or right across connected displays in #48772 by @APONTES19

File Explorer

  • Updated the Monaco Editor used by preview experiences, refreshing language support and editor assets in #48415
  • Aligned the File Explorer Add-ons page and navigation titles for a consistent Settings experience in #49692
  • Added an optional, policy-controllable Markdown preview setting for securely rendering validated relative, local, and UNC image paths in #47857 by @st-gr
  • Preserved SVG alpha transparency in thumbnails instead of rendering transparent areas as black in #49301 by @pedrolamas

File Locksmith

  • Fixed Windows 11 context-menu items not using localized text in #49606 by @Umoxfo
  • Fixed File Locksmith crashing when a listed process executable no longer exists by showing a fallback icon and keeping the process available in #48719 by @LegendaryBlair

Find My Mouse

  • Improved Chinese Find My Mouse translations to retain the familiar Ctrl key label, making activation options easier to understand in #49693

Grab and Move

  • Anchored restored maximized windows to the original grab point for more predictable dragging in #49118 by @foxmsft
  • Refined Grab and Move overlays to hug visible window frames with a warning-gold outline and reduced the default Always On Top border to 4 pixels for cleaner visuals in #48474
  • Matched Grab and Move overlay corners to square windows in remote desktop sessions while preserving rounded corners locally in #48999
  • Allowed modifier-clicks without dragging to reach the target application while retaining window move and resize gestures in #49121 by @foxmsft

Image Resizer

  • Added complete MSIX logo sets for File Locksmith, Image Resizer, and PowerRename so their context-menu icons display correctly across Windows surfaces in #48925
  • Corrected Image Resizer context-menu command reporting to improve File Explorer compatibility and avoid unsupported command responses in #48399
  • Clarified Image Resizer preset descriptions with a consistent mode-and-dimensions format across the resize dialog and Settings in #49694
  • Moved Image Resizer preset editing into a modern confirmation dialog so canceled changes are discarded and settings are written only after saving in #49161
  • Made the public Image Resizer CLI validate options, files, and dimensions strictly, deduplicate equivalent inputs, and report actionable diagnostics in #49854

Keyboard Manager

  • Fixed a startup crash that prevented the new Keyboard Manager editor from opening, while improving early diagnostics and Windows 10 window rendering in #49524
  • Fixed the Keyboard Manager editor's program and folder browse dialogs failing to open when PowerToys is running as administrator in #48876
  • Fixed key-to-text remaps while Alt is held and prevented modifiers from becoming stuck or failed remaps from being dropped in #48571
  • Fixed modifier-to-regular-key remaps being treated as system shortcuts so mappings such as Left Alt to Backspace perform the intended action in #47192 by @oMatheusmol
  • Fixed Ctrl remaining stuck after AltGr was pressed without activating a remapped shortcut, restoring reliable keyboard input in #46672 by @fluffyspace
  • Standardized shortcut modifier display as Win, Ctrl, Alt, and Shift regardless of press order for easier recognition in #49707 by @agbuddy7

Mouse Highlighter

  • Added customizable ripple effects for mouse clicks, making click activity easier to see in #48232
  • Moved ripple rendering, animation, timers, and Z-order work off the low-level mouse hook, preventing lost button-up events and stuck ripple or pressed states in #49699
  • Updated default left- and right-click highlights to green and blue while preserving existing user preferences in #49833

Mouse Jump

  • Modernized Mouse Jump with a WinUI 3 interface, improved multi-monitor and mixed-DPI behavior, and added keyboard shortcuts for selecting monitors in #48393 by @LegendaryBlair and @mikeclayton
  • Updated release signing for the new Mouse Jump binaries so x64 and ARM64 builds complete successfully in #49747 by @LegendaryBlair

Mouse Utilities

  • Clarified the Gliding Cursor description so users understand that its keyboard shortcut positions the pointer and performs a click in #49691

Mouse Without Borders

  • Fixed the German “Drag & Drop” text so Mouse Without Borders displays a normal ampersand instead of an HTML entity in #49687
  • Improved connections between Mouse Without Borders computers while preserving existing pairing settings after every computer is updated, using fresh encryption parameters in #48742 and stronger session-key derivation in #49600

New+

  • Corrected French localization guidance so New+ appears as “Nouveau+” instead of the inaccurate “NouveautĂŠ+” in #47225
  • Updated the New+ attribution text and link to accurately credit the original New++ utility in #49047 by @cgaarden
  • Improved template renaming and positioned new desktop items near the context-menu cursor with per-monitor DPI handling in #48083 by @cgaarden

Peek

  • Added JSON syntax highlighting, folding, and structured navigation for Unreal Engine project and plugin files in Peek in #47931 by @Ares9323
  • Added Peek settings to keep its window on top and show or hide its taskbar and app-switcher icon in #44645 by @AkazaRenn
  • Updated Peek's archive handling, restoring .tar.gz and .tgz previews while improving extracted-size and non-ASCII filename accuracy in #49520
  • Fixed Peek’s close and navigation shortcuts after focus moves into web or native preview content in #48293 by @MuyuanMS
  • Fixed system media controls so Peek appears only for media previews and disappears after switching files or closing in #46899 by @MuyuanMS and @zheng-fan
  • Fixed Monaco registration for Unreal Engine project and plugin files to restore their intended editor support in #49300 by @noraa-junker
  • Improved Peek and Registry Preview shutdown reliability by containing cleanup failures and clearing stale preview-handler resources in #48564 by @LegendaryBlair

PowerDisplay

  • Added linked brightness control to adjust multiple monitors from one slider while allowing selected displays to remain independent in #48207 by @gilnatab
  • Enabled PowerDisplay to wake supported monitors from standby by selecting On in the power-state control in #48628
  • Added stable profile IDs so duplicate names and renames retain reliable PowerDisplay and Light Switch references in #49175
  • Added an opt-in setting to adjust primary or linked display brightness by scrolling over the PowerDisplay tray icon in #49446
  • Added a PowerDisplay setting for choosing how much brightness, contrast, and volume sliders change per mouse-wheel notch in #49002
  • Added a PowerDisplay command-line interface for monitor controls, enabling scripts to inspect displays, change settings, and apply saved profiles in #48632
  • Fixed built-in laptop panel detection when a discrete GPU drives the display, restoring brightness control on hybrid-GPU systems in #48637
  • Improved Maximum compatibility mode by reusing previous successful monitor readings after intermittent communication failures in #49445
  • Prevented recent PowerDisplay setting changes from being lost during exit by coordinating and atomically publishing monitor-state saves in #49629
  • Improved Maximum compatibility mode by reusing probe results, reducing traffic to unreliable monitors and preserving more accurate displayed values in #49596
  • Fixed tray-menu exit cleanup so PowerDisplay removes its icon immediately and restarts cleanly in #49580
  • Improved monitor detection in Maximum compatibility mode by pacing and retrying transient control probes without repeating definitive failures in #49579
  • Prevented monitor-handle resource usage from accumulating when PowerDisplay abandons failed discovery attempts in #49578
  • Fixed monitor setting restoration so saved brightness, contrast, volume, and color temperature are applied even after failed discovery reads in #49577

PowerToys Run

  • Corrected “searchbox” to “search box” in the plugin keyword settings description in #49777 by @Hashim1999164
  • Updated the DiskAnalyzer plugin listing to its current ValleySoft repository and author, restoring access to the maintained project in #48618 by @thetsaw
  • Fixed stale PowerToys Run queries leaking workers during rapid typing, preventing thread growth and eventual out-of-memory failures in #48394
  • Restored recent VS Code workspace discovery across supported variants after storage-location changes, with duplicate results removed in #47505 by @MardSilva
  • Fixed VS Code workspace handling for UNC network paths, allowing shared workspaces to appear and open correctly in #48922 by @ScymicX
  • Added DevDocs and PoetSearch to the third-party plugin directory in #49697 by @jan-jaros and #49946 by @Greyaircraft

Quick Accent

  • Added an optional press-and-hold activation mode, enabling accent selection by holding a letter without disrupting quick taps or shortcuts in #48937
  • Fixed press-and-hold activation showing the picker after another key cancels the pending action in #49701
  • Fixed the final character's selection highlight disappearing when long character lists are scrolled to the end in #49820
  • Modernized the Quick Accent selector with WinUI 3, preserving familiar interactions while improving theming, accessibility, and DPI-aware positioning in #48891
  • Added inverted exclamation and question marks to the relevant Quick Accent menus for Spanish and Catalan in #48599 by @Derylfabiensyah
  • Added the Philippine peso symbol to the P-key menu in the Currency character set in #48444 by @ganmatthew
  • Added Belarusian Latin and Cyrillic character sets, expanding Quick Accent language coverage in #48344 by @daverayment
  • Corrected Bulgarian character mappings and added commonly used currency, quotation, and punctuation symbols in #49344 by @daverayment
  • Added Pitjantjatjara and Yankunytjatjara retroflex consonants to Quick Accent, enabling accurate typing without a specialized keyboard in #48561 by @class-Avirup
  • Fixed the Quick Accent bar appearing blank, clipped, or undersized on its first frame, ensuring wider characters display correctly in #49633
  • Fixed the Quick Accent bar reappearing with a stale frame by cloaking it while hidden, keeping it rendered and removing the fixed reveal delay in #49655
  • Fixed canceled Quick Accent activations leaving letters stuck as held, keeping Keyboard Manager remaps and other shortcuts responsive in #49644 by @agsoto
  • Fixed stale render timers making the Quick Accent toolbar flash or appear too early after repeated key presses in #48944
  • Fixed Quick Accent clipping or shifting the final character when descriptions are disabled, including on scaled displays in #49402 by @0utsights and @daverayment
  • Prevented inserted characters and navigation keys from retriggering PowerToys shortcuts, improving reliability across repeated Quick Accent activations in #48572
  • Corrected and expanded currency mappings for Greek, Hebrew, and Vietnamese character sets in #49343 by @daverayment
  • Expanded and reorganized IPA and Special character mappings, adding more phonetic symbols, punctuation, and per-mille characters in #49030 by @daverayment

Screen Ruler

  • Migrated legacy measurement-unit values and repaired invalid settings, preventing Settings from crashing when leaving the Screen Ruler page in #49898

Settings

  • Added a selector for choosing Stable or Insider update channels in #49722
  • Restored navigation to the General page by applying the correct style to the update-channel description, preventing a XAML parsing failure in #49801 by @LegendaryBlair
  • Resolved the PowerToys install path from the running executable before falling back to the registry, making Settings deep links and Workspaces launches more reliable in #48905
  • Added progress and result feedback to the Bug Report flow, with quick access to the generated ZIP and a prefilled GitHub issue in #48980
  • Improved PowerToys component communication to reduce hangs, stale callbacks, and blocked writes during shutdown in #48902
  • Fixed the FancyZones Settings page bouncing near Excluded apps, making bottom-of-page scrolling smooth and predictable in #47937
  • Improved Settings navigation and search failure handling, preventing unexpected errors from terminating the app in #46688 by @tburns10 and @tuckburns
  • Fixed unreadable What's New headings, links, content, and caption buttons when Windows and PowerToys use different themes in #48910
  • Made attribution wording and the Stereolithography term localizable, enabling more natural translations across Settings in #49690
  • Protected elevated Runner commands by verifying Settings and Quick Access clients before accepting requests, preserving normal communication while rejecting untrusted callers in #49527 by @LegendaryBlair
  • Redesigned update notifications with consistent state badges and a compact status surface for checking, downloading, ready-to-install, and failure states in #49872
  • Moved the NEW badge from Shortcut Guide to Window Hopper so Settings highlights the newly introduced utility in #49995

Shortcut Guide

  • Added Brave Browser shortcuts covering tabs, Brave features, the address bar, and web page navigation in #49615
  • Added correct less-than and greater-than key rendering and prevented crashes from empty or invalid shortcut keys in #49562 by @noraa-junker
  • Added Greenshot capture and editor shortcuts to Shortcut Guide in #49407 by @Korb and @MuyuanMS
  • Added the Win+, desktop peek shortcut to the Windows shortcuts view in #49638
  • Added Zoom Workspace shortcuts to Shortcut Guide, surfacing common meeting, view, mute, video, sharing, and leave controls while Zoom is active in #49062
  • Added email, calendar, navigation, formatting, and editing shortcuts for the new Outlook for Windows in #48821
  • Added common editing, playback, and color-grading shortcuts for DaVinci Resolve in #48652 by @giruuuuj
  • Added navigation, item, account, locking, and view shortcuts for the 1Password desktop app in #48793 by @brycewc
  • Added bundled Godot shortcuts to Shortcut Guide, making common editor commands available at a glance in #48959
  • Added common Obsidian shortcuts to Shortcut Guide, making navigation, tab, and editing commands easier to recall in #48960
  • Added ON1 Photo RAW shortcuts to Shortcut Guide, covering navigation, editing, masking, and other common workflows in #49143
  • Added Postman shortcuts and fixed numbered-key rendering, making tab, request, sidebar, console, and digit-based commands display correctly in #48461 by @brycewc
  • Fixed Shortcut Guide crashing or closing when navigating between sidebar sections in #48481
  • Fixed number-key rendering across bundled app manifests, making displayed shortcuts accurate in Adobe apps, browsers, Slack, Visual Studio Code, Blender, Figma, and Notepad in #48757 by @brycewc
  • Replaced dual windows with a single transparent overlay, delivering smoother transitions, edge-aware taskbar indicators, and an on-screen hold control in #48683 by @noraa-junker
  • Renamed Win+Q as Open Click to Do on Copilot+ PCs while preserving the Windows Search label for Win+S in #48439
  • Added configurable Windows-key hold behavior: disabled, taskbar indicators, or the full guide, with hold duration and close-on-release options in #49661 by @noraa-junker
  • Added accessible page-local search across shortcut names, descriptions, modifiers, and displayed keys in #49639

ZoomIt

  • Added DemoMirror to mirror a screen, region, or hovered window with the pointer onto a second monitor for clearer presentations in #49607 by @chakrik73
  • Added independently configurable ZoomIt Snip Save and Panorama Save shortcuts, preventing derived combinations from overriding common shortcuts such as Ctrl+S in #49075 by @foxmsft and @SeanKilleen
  • Added WebP and JPEG formats for ZoomIt screenshots and panorama captures, with zoomed and actual-size save options where applicable in #48818 by @MarioHewardt
  • Added webcam background blur, microphone noise cancellation, and brightness controls to video recording while restoring Mono audio and reliable standalone shortcuts in #48266 by @foxmsft and @MarioHewardt
  • Added interior video segment deletion, automatic snip copying, and recording borders while improving trim reliability, making ZoomIt capture and editing workflows more capable in #49553 by @chakrik73
  • Fixed repeated or garbled wording in ZoomIt's Chinese description in #47370 by @MuyuanMS
  • Fixed a race that could crash ZoomIt when video recording with audio started before initialization completed in #48685 by @MarioHewardt
  • Fixed custom recording filenames losing numeric suffixes, while timestamped defaults now sort more clearly in #43236 by @daverayment
  • Improved ZoomIt dialog alignment, spacing, and text layout, making configuration screens more consistent and readable in #49210 by @foxmsft
  • Prevented failed audio initialization from racing with recording startup and destabilizing ZoomIt in #49912

Development

  • Added next-generation UI test suites for Image Resizer, Peek, File Explorer add-ons, and File Locksmith, plus local VM tooling and CI test-signing support in #49671
  • Improved release version handling so automatic builds use a clear default and explicit versions can recover from exhausted daily counters in #49745 by @LegendaryBlair
  • Advanced automatic preview builds to the PowerToys 0.101 release train in #49795 by @LegendaryBlair
  • Added opt-in preview update checks while retaining stable updates by default, clearly identifying preview builds and isolating their publishing flows in #49414 by @LegendaryBlair
  • Fixed Runner hangs during Windows shutdown, restart, and sign-out, allowing PowerToys to exit promptly while preserving normal exit cleanup in #48363
  • Removed unused updater constants, simplifying maintenance and reducing dead code in #46974
  • Rejected invalid cached installer filenames that resolve outside the Updates folder, keeping normal updates on the intended path in #48741
  • Restricted each autorun task to its owner, administrators, and the system account while preserving startup and elevated-run behavior in #48739
  • Verified downloaded update installers before launch, rejecting unsigned, corrupted, or unexpected packages in #48903 by @LegendaryBlair and @MuyuanMS
  • Anchored updater shutdown waits to the original PowerToys process, preventing recycled process IDs from delaying or disrupting updates in #46973
  • Added fallback window titles across affected utilities, preventing startup crashes when localized titles are temporarily unavailable in #49069
  • Corrected Bug Report Tool event-detail formatting to safely handle unusually long data and keep report collection reliable in #48398
  • Fixed spelling checks for third-party ZoomIt sources and binary assets, preventing unrelated files from disrupting validation in #48548
  • Hardened centralized keyboard handling against released keys and shutdown races, preventing stuck or ghost hotkey actions in #48570
  • Hardened PowerShell-based resource generation against user profiles and module warnings, making builds more reliable in #46729 by @flcdrg
  • Strengthened navigation-failure tests for missing page and exception details, helping prevent future Settings crashes in #48410
  • Fixed native compilation for the built-in Bookmarks extension by removing invalid COM metadata in #49357 by @jiripolasek
  • Updated Command Palette to version 0.12, aligning packaging and release identification in #49586
  • Reordered the solution filter consistently, preventing unrelated Visual Studio project-order changes in #49337 by @jiripolasek
  • Refactored extension loading into dedicated services, simplifying support for additional extension types in #48417
  • Added a design specification for future ambient-light adaptive brightness on external monitors in #49199 by @MrRishabhJain
  • Enabled ahead-of-time compilation support and trimming-compatible shortcut serialization, improving Shortcut Guide deployment readiness in #49673 by @noraa-junker
  • Improved contributor guidance for Shortcut Guide manifests, helping new app definitions follow the correct schema and naming rules in #48967
  • Added Japanese translation guidance for download and built-in battery terms in Command Palette, improving terminology accuracy in #48649 by @giruuuuj
  • Added Chinese translation guidance that distinguishes Sleep from Hibernate in Command Palette, making system commands clearer in #48653 by @giruuuuj
  • Added native Runner coverage for duplicate module hotkeys, improving regression detection for in-app shortcut conflicts in #48352
  • Added opt-in Escape and focus-loss dismissal to TransparentWindow, enabling consistent light-dismiss behavior without changing existing consumers in #48950
  • Added a ready-to-use settings manager to new extension templates, accelerating configurable extension development in #46028 by @MuyuanMS
  • Added Quick Shell to the community plugin list, making it easier to open saved project folders in any terminal in #49567 by @tonythethompson
  • Improved WPF-to-WinUI 3 guidance with PowerToys windowing and declarative XAML patterns, helping contributors produce more consistent migrations in #49303
  • Corrected Visual Studio 2026 setup components, ensuring automated environments install the required Windows 11 SDK and Windows App SDK tools in #48824
  • Excluded locally generated AI planning files from source control, preventing workspace-only artifacts from being committed in #48633
  • Removed an unused WebView2 WPF reference from non-WPF projects, eliminating recurring WindowsBase conflict warnings during compilation in #49049
  • Handled unexpected Quick Access startup and navigation errors without terminating the flyout, keeping it available for the next launch in #48457
  • Automated inactivity handling for pull requests awaiting author feedback, keeping the contribution queue current in #49151 by @MuyuanMS
  • Expanded automatic area labeling to pull requests, improving repository triage coverage in #48729
  • Expanded WPF-to-WinUI 3 migration guidance with additional API, namespace, XAML, and phased-migration mappings, helping contributors complete ports in #47043
  • Preserved existing pull-request labels during automatic classification, avoiding duplicate or overwritten triage in #48877
  • Updated CI branch filters for stacked pull requests, ensuring changes targeting non-main branches are validated in #49646
  • Restricted GitHub artifacts helper credentials to GitHub API requests, preventing attachment downloads from forwarding tokens to external hosts in #48782
  • Consolidated PowerToys issue-triage queries into a repository-maintained developer document for easier updates in #48744
  • Refreshed the PowerToys README release banner artwork to present current release information more clearly in #48392
  • Fixed standalone project output paths, preventing recursive directories and maximum-path build failures in #49643
  • Updated Adaptive Cards dependencies, bringing newer fixes and improved native compilation support in #49362 by @jiripolasek
  • Updated WebView2 dependencies and aligned native package references to prevent version drift in the Keyboard Manager editor in #49051
  • Normalized the character-mapping file's line endings, preventing false modifications and simplifying contributor workflows in #49203 by @jiripolasek
  • Updated third-party notices for ZoomIt's WebP screenshot encoding, keeping bundled component documentation accurate in #48843 by @MarioHewardt
  • Added an automatically published developer documentation site, making PowerToys contribution guidance easier to browse in #48752
  • Added an early build check for Windows long path support, replacing cryptic build failures with actionable setup guidance in #49028
  • Added a guided migration path for legacy UI tests and ported Screen Ruler as the first example, expanding CI coverage for the new framework in #48842 by @LegendaryBlair
  • Added Awake module-services coverage for timed settings, establishing regression tests for runtime state creation in #48346
  • Added source-link rewriting so developer documentation links work both locally and on the published site in #48754
  • Added a Copilot agent skill for validating PowerToys modules against release checklists with evidence-based results in #48717 by @LegendaryBlair
  • Added tests for Peek’s math and path helpers and clearer errors for invalid modulo divisors in #49105
  • Added Launchy to the third-party PowerToys Run plugin documentation, making the community file and folder launcher easier to discover in #49080 by @PsychodelEKS
  • Added a WinApp CLI-based UI test framework with Color Picker end-to-end and Settings navigation coverage, reducing reliance on legacy test infrastructure in #48467
  • Improved next-generation UI test window targeting and executable discovery, reducing flaky interactions across local and CI environments in #49242 by @LegendaryBlair
  • Fixed malformed skill metadata so WPF-to-WinUI 3 migration guidance loads correctly in Copilot CLI in #49059
  • Corrected grammar and typographical errors across module text, documentation, comments, and tests for clearer wording in #47539 by @antonkesy
  • Improved local C++ build reliability across Windows locales with consistent UTF-8 handling and repository-relative output paths in #49575 by @gavinzhangth
  • Restored the Folder plugin unit-test project to the main solution for x64 and ARM64, ensuring its tests build with standard solution workflows in #46897 by @jiripolasek
  • Fixed broken developer documentation links for File Explorer add-ons, the Calculator plugin, and Runner, making referenced source files and tests easier to find in #49294 by @Moli13337
  • Updated MessagePack to version 3.1.7, delivering the latest maintenance fixes in #49029
  • Migrated CalculatorEngineCommon to standard C++20 coroutines, restoring full builds with newer Visual Studio toolchains in #48790
  • Upgraded Windows App SDK dependencies to version 2.2.0 stable, keeping PowerToys and the Command Palette extension template aligned in #48546
  • Kept shared packages current by updating centrally managed .NET dependencies to version 10.0.9 in #48568 by @snickler, then to version 10.0.10 in #49419 by @snickler
  • Increased the IPC setup wait in interop tests, reducing intermittent CI failures on resource-constrained build agents in #48156 by @daverayment
  • Optimized version-project change detection, avoiding unnecessary rebuilds and speeding up development builds in #49534
  • Aligned Windows Implementation Library package declarations across native projects, eliminating version drift and inconsistent build metadata in #49050
  • Removed obsolete cleanup tooling and its documentation, reducing unsupported maintenance code in #48992 by @noraa-junker
  • Granted the auto-labeler permission to label pull requests and skipped reruns for description-only edits, reducing unnecessary workflow activity in #48731
  • Updated pull-request auto-labeling dependencies and error handling, preventing permission limitations from failing the entire workflow in #48733
  • Unified PowerDisplay and Common Utils test projects with the repository-wide C++ toolset selection, keeping builds consistent across supported Visual Studio versions in #49370
  • Updated the dependency-review workflow to version 5 and Node.js 24, keeping automated dependency checks compatible with current runners in #47907
  • Updated repository workflows to actions/checkout version 7, preventing protected automation contexts from checking out forked code and keeping dependencies current in #48743
  • Removed obsolete planning documents, unofficial installation guidance, and an unused icon to keep the documentation tree current in #48813
  • Expanded the PowerToys verification skill to validate module checklists, installed-build changes, and active PR builds through one shared workflow in #48848 by @LegendaryBlair
  • Stabilized .NET 10 release builds by pinning an exact SDK in #49835, then advancing the SDK and matching runtime packages to 10.0.303 and 10.0.11 in #49847
  • Pinned GitHub Actions to full commit SHAs and added a Dependabot cooldown for safer, reproducible automation in #49848
  • Removed redundant Azure module installation from release symbol publishing in #49861
  • Replaced retired GitHub Models issue automation with agentic issue triage and aligned author-feedback workflows in #49828
  • Updated AI Issue Triage engine and container versions to restore Copilot CLI execution in #49885
  • Added a daily duplicate digest driven by AI Issue Triage output in #49907
  • Added AI-assisted pull request intake that summarizes changes and validates readiness evidence in #49911
  • Improved issue product-label detection using module title prefixes and agent-assisted fallback matching in #49905
  • Refined issue and pull request triage triggers, safe-output publication, draft handling, and Ready for review label behavior in #49924
  • Added automation that converts a successful preview release build into a validated GitHub draft prerelease for human review in #49797 by @LegendaryBlair
  • Removed unused shared UI dependencies, stale API surface, and unreachable settings deep-link aliases in #49895
  • Separated common .NET and WinRT build properties and made common-props verification faster and more robust in #48059 by @daverayment
Read the whole story
alvinashcraft
19 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Preorder the ROG XBOX Ally X20 Starting Today

1 Share

The post Preorder the ROG XBOX Ally X20 Starting Today appeared first on XBOX Wire.

Read the whole story
alvinashcraft
34 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

How to Fix a Leaked API Key: A Developer’s Guide to Git Security

1 Share

Imagine this: you're working late, your code finally works, and you're ready to push it to GitHub.

You run:

git add .
git commit -m "Fix API integration"
git push

A few minutes later, you notice something strange. Your API usage has suddenly increased. Maybe there are unexpected requests, new cloud resources, or even a bill that looks much larger than expected.

Then you find it:

const apiKey = "sk_live_123456789";

Your API key is sitting in a Git repository.

This situation is stressful, but it's fixable.

The most important rule is:

If an API key has been committed to Git, assume it has been copied and compromised, even if you delete it immediately.

Deleting the key from the latest version of your file doesn't make the old key safe. Git keeps previous versions of files in its history, and exposed credentials can be discovered by automated scanners.

In this guide, you'll learn the following:

We'll use this basic workflow throughout the article:

Invalidate → Investigate → Remove → Replace → Prevent

Let's start with what an API key actually is before we get to the most important part: what to do right now after a key is exposed.

What Is an API Key?

An API key is a credential that allows an application to communicate with another service.

For example, an application might use an API key to access:

  • A weather service

  • A payment provider

  • A mapping service

  • An artificial intelligence API

  • A cloud platform

  • A database

  • An email provider

  • A private company API

A key might look something like this:

const apiKey = "your-real-api-key";

Or it might appear in a configuration file:

{
  "apiKey": "your-real-api-key",
  "databasePassword": "your-real-password"
}

API keys are often called secrets because possessing one may allow someone to make requests, access data, create resources, or generate charges on your account.

Not every API key is equally sensitive. Some services provide browser keys that are intentionally visible to users. Those keys should still have appropriate restrictions, quotas, and permissions.

As a general rule:

If a credential can access private data, create resources, modify records, or generate charges, it shouldn't be stored directly in your source code.

The Emergency Response: What to Do First

When you discover a leaked credential, a common reaction is to delete the key from the file and push another commit.

Don't start there.

Your first priority is to make the leaked credential useless.

Use this order of operations:

1. Invalidate the leaked credential
2. Investigate suspicious activity
3. Remove the secret from your code
4. Replace it with a new credential
5. Clean the Git history if necessary
6. Verify the cleanup
7. Add protections against future leaks

Think of an API key like a house key that was dropped in a crowded street.

Deleting a picture of the key doesn't matter if someone already picked up the physical key.

Change the lock first.

Step 1: Revoke or Rotate the Leaked Key

Go to the dashboard of the service that issued the credential.

Depending on the provider, you may see options such as:

  • Revoke

  • Delete

  • Disable

  • Rotate

  • Regenerate

  • Create new key

If the provider supports key rotation, create a replacement credential before disabling the old one if possible. This can reduce application downtime while you update your configuration.

The important thing is that the original credential must no longer be usable.

Do not reuse the leaked key. Don't rename it. Don't encode it. Don't move it to another file and assume it is safe. Don't assume nobody saw it.

Treat it as compromised.

Step 2: Investigate Suspicious Activity

After disabling the credential, check the provider's usage dashboard and logs.

Look for things such as:

  • Sudden spikes in requests

  • Requests from unfamiliar locations

  • Unexpected database queries

  • New cloud resources

  • Changes to permissions

  • Unexpected downloads

  • Unusual payment activity

  • New deployments

  • Requests at times when your application was inactive

If the credential had broad permissions, assume that anything within its permission scope MAY have been accessed or modified.

For example, if a cloud credential could create virtual machines, check whether unexpected machines were created.

If a credential could access a database, review:

  • Authentication logs

  • Read operations

  • Write operations

  • Deleted records

  • Exported data

  • Newly created accounts

  • Permission changes

Also check your billing information if the credential could generate usage-based charges.

Write down what you discover. A simple timeline can help:

10:15 - API key committed
10:23 - Repository pushed publicly
10:41 - Unusual usage detected
10:45 - Key revoked
11:00 - Logs reviewed
11:30 - Replacement key deployed
12:00 - Git history cleaned

This can be especially useful if you need to report the incident to a team or service provider.

Step 3: Remove the Secret From Your Current Code

Once the original credential has been disabled, remove it from your working files.

This is unsafe:

const apiKey = "your-real-api-key";

Instead, load the credential from the environment:

const apiKey = process.env.API_KEY;

if (!apiKey) {
  throw new Error("API_KEY is not configured");
}

In Python:

import os

api_key = os.environ.get("API_KEY")

if not api_key:
    raise RuntimeError("API_KEY is not configured")

The important idea is simple:

Source code → environment variable → secret value

instead of:

Source code → hardcoded secret

Environment variables aren't the only way to manage secrets, but they are a common and practical solution for local development and many deployment environments.

Step 4: Use a .env File for Local Development

For local development, you can store environment variables in a .env file.

For example:

API_KEY=your-local-development-key
DATABASE_URL=your-local-database-url

A Node.js project can load these values with a package such as dotenv.

Install it with:

npm install dotenv

Then:

import "dotenv/config";

const apiKey = process.env.API_KEY;

The important part is that the .env file normally should not be committed to Git.

Add it to .gitignore:

# Environment files
.env
.env.*
!.env.example

# Credential files
*.pem
*.key
credentials.json
service-account.json

# Local development files
.DS_Store

But there's an important detail here: the .gitignore does NOT remove files that Git is already tracking.

If .env has already been committed, adding it to .gitignore won't erase it from Git.

You can stop tracking the file while keeping it on your computer:

git rm --cached .env

Then commit the .gitignore change:

git add .gitignore
git commit -m "Ignore local environment files"

But remember: this only removes the file from future commits. It does not remove the secret from previous commits.

That's where Git history comes in.

Step 5: Create a Safe .env.example

Other developers still need to know which environment variables the application requires.

Instead of committing .env, create .env.example:

API_KEY=
DATABASE_URL=
PORT=3000
LOG_LEVEL=info

This file contains variable names rather than real credentials, so it can be committed to the repository.

You can also provide comments:

# Required API credential
API_KEY=

# PostgreSQL connection string
DATABASE_URL=

# Optional application port
PORT=3000

A new developer can then copy the file:

cp .env.example .env

and provide their own values.

Use clearly fake placeholders in examples:

API_KEY=replace-me-with-your-own-key

Avoid putting realistic-looking production credentials into .env.example.

Step 6: Determine Whether the Secret Is Still in Git History

This is one of the most important parts of fixing a leaked credential.

Suppose your Git history looks like this:

Commit A: Add API key to config.js
Commit B: Update API integration
Commit C: Delete API key

Even though Commit C no longer contains the key, Commit A still does.

Git remembers previous versions of your files.

You can inspect the history of a file with:

git log --all -- config.js

To display a file from an older commit:

git show COMMIT_ID:config.js

You can also search Git history for a known leaked value:

git log --all -S"your-leaked-key" --oneline

If you know the secret was committed, you should assume that it exists somewhere in the repository's history until you've verified otherwise.

When Do You Need to Rewrite Git History?

Not every accidental secret requires a history rewrite. Consider these situations:

The Secret Was Never Committed

If the secret exists only in your working directory and was never committed, you generally don't need to rewrite history.

Remove it, add the appropriate file to .gitignore, and continue.

The Secret Was Committed Locally But Never Pushed

If the secret exists in local commits but hasn't been shared with a remote repository, you may be able to clean up those commits before pushing.

The Secret Was Pushed to a Remote Repository

Treat the credential as compromised. Revoke or rotate it immediately.

Then determine whether removing the secret from the repository's history is appropriate.

The Repository Was Public

Assume that someone or something may already have copied the secret.

This is why revocation comes before Git cleanup.

The Secret Was in a Private Repository

A private repository is safer than a public repository, but it isn't a secret vault.

Credentials can still escape through:

  • Compromised accounts

  • Contractors

  • Integrations

  • CI logs

  • Forks

  • Backups

  • Screenshots

  • Copied code

  • Pull requests

So the safest rule remains:

Never intentionally commit credentials to Git, even in a private repository.

Step 7: Remove the Secret From Git History

If the credential was committed, you may need to remove it from the repository's history.

Before rewriting history, create a backup:

git clone --mirror https://github.com/your-username/your-repository.git repository-backup.git

A mirror clone includes branches and tags, which makes it useful for recovery if something goes wrong.

Option 1: Remove an Entire File

If the secret was stored in a file such as .env, you can remove that file from the entire history:

git filter-repo --path .env --invert-paths

For a file inside a directory:

git filter-repo --path config/production.json --invert-paths

This removes the file from the repository's rewritten history.

Option 2: Replace a Secret Inside a File

Sometimes you need to keep the file but remove the secret from previous versions.

Create a temporary replacements file:

Then run:

git filter-repo --replace-text replacements.txt

You can replace the value with a placeholder:

your-leaked-key==>YOUR_API_KEY_HERE

Be extremely careful with replacements.txt. It contains the original secret, so do not commit it.

Delete it after the cleanup:

rm replacements.txt

On Windows PowerShell:

Remove-Item replacements.txt

For multiple secrets:

old-api-key==>REMOVED_API_KEY
old-database-password==>REMOVED_DATABASE_PASSWORD
old-token==>REMOVED_TOKEN

Then:

git filter-repo --replace-text replacements.txt

Test the cleanup on your backup clone first.

Step 8: Verify That the Secret Is Gone

Never assume the cleanup worked just because the command completed successfully.

Search for the known leaked value again:

git log --all -S"your-leaked-key" --oneline

You can also inspect relevant files and commits:

git log --all -- config.js

and:

git show COMMIT_ID:config.js

If your repository uses branches and tags, make sure you aren't checking only the branch you currently have checked out.

You should also inspect other locations where the secret may have appeared, including pull requests, CI/CD logs, build artifacts, release files, Docker images, package releases, documentation, issue comments, and screenshots

Remember:

Rewriting your repository doesn't erase copies that already exist somewhere else.

That's another reason why the original credential must be revoked.

Step 9: Push the Cleaned History Carefully

Once you've verified the cleanup, you may need to push the rewritten history:

git push --force --all origin
git push --force --tags origin

Important Warning

Force-pushing rewritten history is disruptive. It changes commit hashes and can affect collaborators who have existing clones of the repository.

Before doing this on a shared project:

  1. Tell your collaborators.

  2. Make sure everyone understands that history is being rewritten.

  3. Coordinate the cleanup.

  4. Follow your organization's incident-response process if one exists.

After the rewrite, collaborators may need to reclone the repository:

git clone https://github.com/your-username/your-repository.git

They shouldn't blindly merge their old repository history back into the cleaned repository.

Step 10: Replace the Credential Everywhere

Now create or use the replacement credential. Update every environment where the application runs. Common locations include:

  • Local development

  • Testing

  • Staging

  • Production

  • Docker containers

  • Kubernetes secrets

  • CI/CD systems

  • Hosting platforms

  • Scheduled jobs

  • Serverless functions

A common mistake is updating production but forgetting the deployment pipeline.

For example, your local application may work because .env contains the new key, while your CI/CD system still contains the old one.

Make a checklist:

1. Local development
2. Automated tests
3. Staging
4. Production
5. CI/CD variables
6. Docker configuration
7. Cloud deployment settings
8. Scheduled scripts
9. Serverless functions

After updating the credential, test the application in each important environment.

Step 11: Restrict the Replacement Key

Replacing a leaked credential is only part of the solution.

The new credential should have only the permissions it actually needs.

Useful restrictions can include:

  • Read-only permissions

  • Specific API scopes

  • Allowed IP addresses

  • Allowed domains

  • Environment-specific access

  • Request quotas

  • Rate limits

  • Expiration dates

For example, a weather application may only need permission to read weather data.

It shouldn't have permission to manage users, modify billing, or delete unrelated resources.

This is the principle of least privilege:

Give each credential the smallest amount of access necessary to perform its job.

It's also a good idea to use different credentials for different environments:

local-development-key
testing-key
staging-key
production-key

That way, a development credential leak doesn't automatically expose production resources.

What About Frontend Applications?

This is where API-key security gets confusing.

Frontend code runs on the user's device.

That means users can inspect it.

For example:

const apiKey = "browser-key";

A user can inspect the JavaScript bundle, browser developer tools, or network requests and potentially see the value.

Some services intentionally provide browser API keys that are designed to be publicly visible.

Those keys should still be restricted by things such as:

  • Allowed domains

  • Website origins

  • API operations

  • Usage quotas

  • Referrer restrictions

  • Time limits

But a truly private credential should never be placed in browser code.

Instead of:

fetch("https://private-api.example.com/data", {
  headers: {
    Authorization: "Bearer private-secret-token"
  }
});

have the browser call your own backend:

fetch("/api/data");

Then the backend communicates with the private service:

const response = await fetch(
  "https://private-api.example.com/data",
  {
    headers: {
      Authorization: `Bearer ${process.env.PRIVATE_API_TOKEN}`
    }
  }
);

The backend can then return only the information the browser is allowed to receive.

The important distinction is:

Public/browser credential
        ↓
Can be visible, but should be restricted

Private credential
        ↓
Must remain on a trusted backend or secret-management system

Environment Variables vs Secret Managers

Environment variables are useful, but they're not a universal secret-management solution.

For a small application or local development environment, something like:

API_KEY=your-secret

may be perfectly reasonable.

For larger production systems, you may want a dedicated secret manager.

A secret-management system can provide features such as:

  • Centralized credential storage

  • Access controls

  • Auditing

  • Credential rotation

  • Versioning

  • Separation between environments

  • Integration with deployment systems

The important idea is that your source code shouldn't be responsible for storing production secrets.

Instead:

Application
    ↓
Secret management system
    ↓
Credential

rather than:

Application
    ↓
Hardcoded production credential

Which solution you use depends on the size and requirements of your project.

Add Secret Scanning to Your Workflow

Humans are excellent programmers and occasionally terrible search engines.

Automated secret scanning can catch credentials before they make it into a repository.

Popular tools include:

  • Gitleaks

  • TruffleHog

  • detect-secrets

  • Pre-commit hooks

  • Git hosting secret scanning

  • CI security scanners

For example, you can run Gitleaks locally:

gitleaks detect --source . --verbose

You can also integrate secret scanning into CI.

A basic GitHub Actions workflow might look like this:

name: Secret Scan

on:
  push:
  pull_request:

jobs:
  scan:
    runs-on: ubuntu-latest

    steps:
      - name: Check out repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Scan for secrets
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Review the documentation for your chosen tool and pin versions according to your project's security practices.

Secret scanners can produce false positives, so you may need to configure exceptions for safe test values.

Be careful with allowlists, though. An overly broad exception can hide a real credential.

Use Git Hooks as an Extra Safety Net

You can also scan files before they're committed.

For example, a simple pre-commit script could search for suspicious words:

#!/usr/bin/env bash

if grep -RniE "api[_-]?key|password|secret|token|private[_-]?key" . \
  --exclude-dir=.git \
  --exclude=".env.example"; then

  echo "Possible secret detected. Commit cancelled."
  exit 1
fi

This isn't a complete security scanner, but it can catch obvious mistakes.

For stronger protection, use a dedicated secret-scanning tool through a pre-commit framework.

The goal isn't to make committing miserable. The goal is to make accidentally publishing a credential harder.

Review Your Staged Diff Before Committing

One of the simplest security habits you can develop is checking what you're actually about to commit.

First:

git status

Then stage only the files you intend to commit:

git add src/api.js README.md

Now inspect the staged changes:

git diff --cached

Look for:

  • API keys

  • Passwords

  • Tokens

  • Private URLs

  • Internal hostnames

  • Customer data

  • Debug output

  • Personal information

  • Private certificates

Only commit after the staged diff looks correct:

git commit -m "Load API key from environment"

Be cautious with:

git add .

It can stage files you never intended to publish, including .env files, database exports, generated files, or local configuration.

Common Mistakes Developers Make

Mistake 1: "I Deleted It, So It's Fine"

Deleting a secret from the current version of a file doesn't delete it from Git history.

Correct response: Revoke the credential and clean the repository history when appropriate.

Mistake 2: "The Repository Is Private"

Private repositories aren't vaults.

Credentials can still escape through compromised accounts, integrations, CI logs, forks, backups, or copied code.

Correct response: Don't commit secrets even to private repositories.

Mistake 3: "I'll Just Encode It"

These don't make a credential secret:

const key = atob("c29tZS1rZXk=");

or:

const key = "some-" + "secret-" + "value";

Encoding, splitting, renaming, or hiding a credential doesn't protect it.

If your application can reconstruct the credential, someone analyzing the application may be able to do the same.

Mistake 4: Logging the Secret

Don't do this:

console.log(process.env.API_KEY);

Logs can be stored by your terminal, CI system, hosting provider, monitoring platform, or cloud service.

Instead:

console.log(
  "API key configured:",
  Boolean(process.env.API_KEY)
);

If you absolutely need to inspect a value during debugging, avoid printing the full credential.

For example:

function maskSecret(value) {
  if (!value) return "not configured";
  if (value.length <= 8) return "********";

  return `${value.slice(0, 4)}...${value.slice(-4)}`;
}

console.log(maskSecret(process.env.API_KEY));

Even masked credentials should be handled carefully.

Mistake 5: Using the Same Credential Everywhere

If local development, testing, staging, and production all use the same credential, one leak can affect everything.

Correct response: Use separate credentials with separate permissions.

Mistake 6: Cleaning Only the Current Branch

A secret can remain in:

  • Old branches

  • Tags

  • Pull requests

  • Other references

Correct response: Consider the entire repository when investigating and cleaning a leaked credential.

Mistake 7: Forgetting Build Artifacts

A secret might also appear in:

  • Compiled JavaScript bundles

  • Docker images

  • Downloadable releases

  • Published packages

  • Generated documentation

Correct response: Revoke the credential and identify affected artifacts that may need to be removed or replaced.

A Complete API-Key Incident Checklist

If you discover that you've exposed an API key, use this checklist:

1. Revoke or rotate the leaked key
2. Create a replacement credential
3. Restrict the replacement credential
4. Review provider logs
5. Review billing and usage
6. Check for unauthorized resources
7. Remove the key from current files
8. Add secret files to .gitignore
9. Create or update .env.example
10. Search Git history
11. Check branches and tags
12. Remove the secret from Git history if necessary
13. Verify the old secret is gone
14. Force-push cleaned history if appropriate
15. Check pull requests and forks
16. Check CI and deployment logs
17. Update local configuration
18. Update staging configuration
19. Update production configuration
20. Update CI/CD secrets
21. Run a secret scanner
22. Document the incident
23. Add preventive security checks

The exact steps will depend on your provider and project, but the order matters: Invalidate first. Clean up second.

A Secure Project Structure

A simple Node.js project might look like this:

my-project/
├── src/
│   └── api.js
├── .env
├── .env.example
├── .gitignore
├── package.json
└── README.md

The local .env file contains the actual development value:

API_KEY=your-local-key

The .env.example file contains no real credential:

API_KEY=replace-me-with-your-own-key

The application reads the environment variable:

import "dotenv/config";

const apiKey = process.env.API_KEY;

if (!apiKey) {
  throw new Error("Missing API_KEY environment variable");
}

export async function getData() {
  const response = await fetch(
    "https://api.example.com/data",
    {
      headers: {
        Authorization: `Bearer ${apiKey}`
      }
    }
  );

  if (!response.ok) {
    throw new Error(
      `API request failed: ${response.status}`
    );
  }

  return response.json();
}

And .gitignore keeps the local environment file out of future commits:

.env
.env.*
!.env.example

node_modules/

Finally, your README can explain the setup without exposing credentials:

Step 1: Copy the example environment file on your bash cp .env.example .env

Step 2: Add your own API key to .env.

And last but not least, start your application!

npm start

Final Thoughts

Leaking an API key doesn't mean you're a terrible developer. It just means your development workflow needs better guardrails.

The important thing is knowing how to respond quickly and how to prevent the same mistake from happening again.

Remember the emergency formula:

Invalidate → Investigate → Remove → Replace → Prevent

The important thing is knowing how to respond quickly and how to prevent the same mistake from happening again.

  • Invalidate the leaked credential so it can no longer be used.

  • Investigate your logs, usage, and billing to determine whether it was abused.

  • Remove the secret from your current code and, when necessary, from Git history.

  • Replace it with a new credential that has only the permissions it needs.

  • Prevent future leaks with environment variables, secret managers, secret scanning, and careful Git practices.

Git is excellent at remembering your project's history. That's useful when you accidentally delete an important function. But it's much less useful when that history contains a password.

So keep your code public when appropriate. And keep your secrets somewhere else.

Happy coding!



Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

From Concept to Restaurant Pilot in Under a Year

1 Share

How McDonald’s combined user research, rapid prototyping, and cross-functional collaboration to bring Sesame UX from idea to reality.

by: Ryan Bush, Sr Manager, UX Design & Kartik Patel, Software Engineer II

Quick Bytes

  • Bringing a new Point-of-Sale (POS) experience to life at McDonald’s scale required balancing crew needs, operational complexity, and business priorities
  • Research, prototyping, and real-world testing showed a new approach could improve speed, accuracy, and usability for crew members
  • Sesame UX moved from concept to a live restaurant pilot in under a year, demonstrating measurable improvements and a new approach to innovation at scale

Creating meaningful change at the scale of McDonald’s means navigating deeply entrenched operational practices, specialized technology, and market-specific requirements. Any new idea must not only solve a meaningful problem but also demonstrate value that resonates across a broad and diverse set of stakeholders.

Driving transformative innovation in an organization at this scale requires building shared alignment around the root problem, the opportunity it presents, and the value a proposed solution can create. It also requires using cost-efficient methods to prove to stakeholders the undeniable value of the change, along with a team of determined individuals who can get creative and who aren’t deterred by obstacles or setbacks.

McDonald’s global Point-of-Sale (POS) system, Sesame, is actively used by over one million crew members worldwide. Markets, Owner/Operators, and managers have invested significant time and resources in training crew members to use the system, and thousands of crew members have mastered the POS experience.

With this level of scale and investment, how could an organization evolve the frontend POS experience while building on the strengths of an already proven platform? How could the benefits outweigh the cost of the change?

Building on a foundation used by millions
The Sesame platform has evolved over decades of deployment, enhancement, and optimization, reaching a level of maturity nearly incomparable to most digital platforms. Hundreds of releases have been focused on meeting market requirements, enabling platform integrations, and optimizing the order taker workflow. However, these enhancements have all been implemented within the existing frontend framework.

When the system was first deployed, smartphones didn’t exist, ordering ahead required a phone call to the restaurant, and most digital interactions happened on a personal computer. As technology has advanced, user expectations have evolved too. Crew members raised on smartphones, tablets, and smooth digital experiences have entered the workforce with different expectations for how technology can support their work.

These factors created an opportunity to explore how the experience could continue evolving to support future innovations, simplify key workflows for crew members, enhance onboarding for new hires, and create a foundation that can adapt alongside the evolving needs of restaurants and the business.

The challenge became clear: “How might we modernize the Sesame experience to better support our crew as well as both current and future restaurant innovations?”

Building the case for change
With that challenge in mind, the next step focused on building a business case to prove the value of a new POS experience. This involved many hours of discovery, research, and testing with live users.

To start, it was necessary to understand the baseline metrics. Aggregated and anonymized data helped to identify holistic experience trends for the existing system; however, it lacked user segmentation and context around where the experience was overperforming or underperforming. It was essential to understand how new and experienced users interacted with the existing system — covering order accuracy, error rates, order speed, and onboarding time for new users.

Once this data was captured through extensive user testing, the objective shifted to creating a functional prototype of an improved order taking experience. Using insights from user research and stakeholder expertise, the team created a low-cost, functional prototype to simulate a live order taking experience.

Incorporating learnings from observations and sessions with McOpCo crew members, the design approach intended to reduce the cognitive load required for users to discover items, apply customizations, and place orders. Based on feedback from both new and experienced order takers, the prototype emphasized easier item discovery, more intuitive customization workflows, clearer visual cues throughout the ordering process, and improved opportunities to review orders before completion. Ultimately, the goal was to ensure crew members of all experience levels felt calm, confident, and positive while using the new system.

The new experience included significant optimizations focused on menu organization, item customization, and accuracy confirmation. These improvements culminated in a more logical order flow in which one step leads seamlessly to the next, visual feedback is clear and helpful, and mistakes can be easily corrected. Using a similar cohort of participants from the baseline testing, a second round of testing was conducted with those participants using the prototype.

The results were compelling. Both new and experienced users took orders faster and more accurately using the prototype compared to the existing experience. There were also significant improvements to observed navigability scores and user-reported system usability scores (SUS), demonstrating that the new experience would be easier for crew members to learn and use.

One key to this research was keeping stakeholders across product, design, technology, and operations informed and involved throughout the discovery process. Product and design led the conceptual development, engineering evaluated the effort and architecture implications, and operations validated solution readiness. This shared governance model helped accelerate development, identify challenges earlier, and helped build cross-functional ownership from the beginning to end of feature delivery. Ensuring that the relevant teams played an active role in the research and had a voice in the decision-making process was essential for building momentum and getting all the teams on board with the initiative.

Based on the positive findings from user testing and prototype evaluation, the project was officially approved to move into development.

Meet Sesame UX
The primary barrier to enhancing the POS experience had historically been the challenge presented by modernizing such a mature and tailored platform. Not only was it necessary to integrate with the existing system, but the work needed to be completed on a timeline that made sense for the business.

The initiative became known as Sesame UX. Its first iteration was a simple web app focused on the core ordering process. The approach was to build a self-hosted webpage that could be used for testing and training the crew in this new order taking experience, while continuing to evaluate crew behavior and core order taking flows.

The next step was to create a Proof-of-Concept (POC) to integrate Sesame UX with the existing Sesame platform. While this might sound daunting, it was achieved with minimal hurdles by reusing the existing code to execute core ordering flows. Considering the complexities of systems this size, Sesame had very clear interfaces and design patterns that could be used to seamlessly integrate a modern UI.

While this worked on a small scale, the product would need to be more robust to be viable at a live restaurant. At scale, there would need to be a separation from the frontend and backend of the existing system as this would increase the velocity of ongoing and future development.

For the Minimal Viable Product (MVP), the team focused on separating user experience improvements from platform constraints. This enabled faster development and helped validate outcomes in real environment. The approach also gave the team a controlled way to roll out the feature while minimizing operational risk during deployment.

All this development was completed within a few months. The progress was encouraging; however, there were still major challenges ahead. The scope of the MVP was focused on core ordering functionality, but it didn’t account for the added features that exist in Sesame outside of the ordering experience.

As a result, crew members could encounter scenarios not yet supported by Sesame UX — creating potential disruptions to restaurant operations. To alleviate this, the team developed Sesame UX to support seamless fallback to the legacy system. This enabled Sesame UX to go live in a restaurant without full functional parity with the legacy system while mitigating risks of operational disruptions.

Bringing Sesame UX to the restaurant
Before restaurant deployment, the team visited the McOpCo pilot restaurant to conduct in-person training with the crew members. By allowing them to practice orders using a training prototype, understand the benefits of the new system, and ask questions, the team helped build comfort and confidence ahead of launch.

The experience couldn’t just be better in a testing environment with a prototype; the live product had to provide a notable improvement to the crew experience and restaurant performance. As development progressed, the team needed to build a proactive feedback loop to solve challenges before deploying at a larger scale.

This iterative process includes capturing constant feedback from crew members to understand how the experience could be improved. The feedback is then measured against live data from the pilot restaurant. Prior to deploying each updated version, Sesame UX goes through an extensive testing process that not only involves end-to-end testing but also incorporates human testers to mimic real-world scenarios. With each deployment, the system has seen measurable improvements in overall performance and crew satisfaction.

Where it becomes real
Now piloting in live restaurants, crew members are already experiencing the benefits of Sesame UX. From personalization features such as choosing between light and dark mode to quality-of-life improvements that make work just a little easier, order takers are taking ownership of the new experience, adding to their confidence and comfortability.

For those expert order takers who are so skilled with the legacy system, there is a learning curve and a moment of hesitation when introduced to Sesame UX. However, as seen during our research, in a matter of one shift, skeptics are turned to believers who prefer to use the new system.

There is a long road ahead before Sesame UX can be adopted globally; however, the team is hard at work carving a path to make that reality. With the live product showcased at McDonald’s Worldwide Convention in June, market leads and owner operators around the world had the opportunity to use the new platform and expressed clear desire to adopt as soon as possible, the most common question being “When can we get it?”

While Sesame UX introduces an intuitive, modern point-of-sale experience to the McDonald’s ecosystem, its current state is not the end of the experience optimization. The new experience provides a framework that enables rapid incorporation of future advancements and scaling with the business.

It’s a common saying at McDonald’s that “It’s not real until it’s real in the restaurants.” Discussing projects and products in an office is far removed from making a material difference at thousands of restaurants worldwide.

In less than a year, the initiative to modernize McDonald’s order taking platform went from being a far-fetched goal to being reality. This project is a great illustration that finding creative ways to simulate a restaurant environment, involving crew members early on, and including cross-functional stakeholders throughout the process removes many of the barriers to restaurant deployment that exist when product teams work in a silo. The hope is that this becomes a blueprint for driving innovation towards a shared goal of NEXT, showing how strong collaboration can turn bold ideas into customer impact and help McDonald’s be their first choice, every time.


From Concept to Restaurant Pilot in Under a Year was originally published in McDonald’s Technical Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories