* chore(tweaks): clarify Activity History tweak description
* fix(tweaks): preserve clipboard history
---------
Co-authored-by: Chris Titus <contact@christitus.com>
* Add tweak to block Logitech Download Assistant auto-install
Mirrors the WPFTweaksRazerBlock folder-deny approach: clear
C:\Program Files\LogiDownloadAssistant, recreate it empty, and deny
Everyone write access so the Windows Update software-component package
cannot re-deliver the payload. UndoScript removes the deny ACE.
Unlike the Razer tweak, no global SearchOrderConfig/DisableCoInstallers
registry changes: those alter driver search system-wide and do not stop
software-component packages.
Fixes#5029
* Harden Logi block tweak per review: SID, 64-bit path, exit codes
- Use the locale-independent *S-1-1-0 SID instead of the English
"Everyone" name, which fails to resolve on non-English Windows.
- Resolve the 64-bit Program Files directory via ProgramW6432 with a
ProgramFiles fallback, so a 32-bit host cannot target the x86 folder.
- Throw when icacls exits non-zero so Invoke-WinUtilScript logs the
failure instead of reporting the tweak as completed.
- Skip the undo icacls call when the folder no longer exists.
* fix(iso): inject drivers per package
Add each root package folder separately so one bad driver cannot fail the rest. The batch form is roughly four times faster. That cost is accepted for one deterministic code path
* Preserve retained nested driver packages
* Discard partial driver injection attempts
* Remove excluded nested driver INFs
---------
Co-authored-by: Chris Titus <contact@christitus.com>
* docs: fix typo in contributing image asset and markdown references
* docs: fix typos and grammatical phrasing in documentation
* fix(config): correct typographical errors in tweak and app descriptions
* fix(scripts): resolve typos and grammatical errors in PowerShell sources
* fix: address review feedback on Outlook description, WinUtil capitalization, and grammar
* fix(win11-creator): filter unserviceable and stale drivers before injection
Add-Driver aborts the whole batch when one exported package is bad,
which broke ISO creation for anyone with an Extension-class or stale
duplicate driver in their store (#4971, #4982). Exclude both before
the single Add-Driver call instead of guessing per-vendor.
* fix(win11-creator): address driver filtering review feedback
Accept date-only DriverVer entries instead of treating them as
unknown. Use the full folder path as the dedup fallback key so two
unrelated packages can't collide on a shared leaf name. Discard the
logger's own output inside the selector so an emitting -Log callback
can't inflate the survivor count. Skip driver injection instead of
failing the whole ISO build when nothing is left to inject.
Also extracts the repeated DISM mock setup in the driver tests into
one shared harness, and asserts that excluded packages are actually
deleted from the export root before Add-Driver runs, not just logged.
* fix: address remaining code review comments
* feat(github): Prettify bug report template
* Let the people know that if they include anything private and share it, that makes them stupid, because AI told me to do that and that's NOT THAT OBVIOUS(sarcasm sign)
* Fix backward compatibility for old-style JSON config imports
* Refactor sidebar UI generation and add tests for Get-WinUtilVariables
* Fix appnavigation config test following UI generation refactor
* Restore global sync state in variables tests
* fix(impex): migrate supported legacy selections
Keep modern imports strict while allowing legacy backups to skip retired entries with clear logging and user feedback. Add fixtures covering partial and all-retired imports.
* test: strengthen UI and global state coverage
Exercise app category rendering through Initialize-WPFUI and restore global sync without leaking test state.
* fix(impex): ignore legacy metadata fields
Limit legacy selection migration to supported WPF key families so unrelated string metadata does not produce false retired-setting warnings.
* docs: clarify legacy config imports
Distinguish strict modern flat imports from partial legacy object migration, including single-setting export shape and historical groups.
---------
Co-authored-by: Chris Titus <contact@christitus.com>
* Add Get-WinUtilEntryToolTip helper for preset-key tooltips
* Show preset JSON key in app and tweak tooltips
* Match apps search against preset key for consistency with tweaks
* Limit preset-key tooltips to preset-representable controls
Comboboxes and package-manager radio buttons cannot appear in a preset
file. Update-WinUtilSelections routes a flat list of keys by the
WPFInstall/WPFTweaks/WPFToggle/WPFFeature/WPFAppx prefixes, so a preset
can carry neither a combobox selected value nor a radio group choice;
WingetRadioButton and ChocoRadioButton do not even carry a WPF prefix.
Advertising those control names as preset keys invited users to add keys
that fall through the switch and abort the whole import.
Revert the combobox label and radio button tooltips to the plain
description, and add tests that fail if the key is reattached to a
control the preset importer cannot accept.
* fix: address preset key review feedback
* docs: clarify preset key search scope
---------
Co-authored-by: Chris Titus <contact@christitus.com>
* fix(apps): WARP prettify
Updated Cloudflare WARP entry with new key and modified description and link.
* Fine, Chris, let's leave property name as full
* Rename 'cloudflare-warp' to 'CloudflareWARP'
---------
Co-authored-by: Chris Titus <contact@christitus.com>
* feat(github): revival of triage tools
* fix(github): workflow doc fix
* fix(github): PR detection
* fix(gh): wontfix preserve bug label
Removed state_reason from issue update when adding wontfix label.
* fix(gh): doc cleaning
* one more thing
* fix(gh): prevent Gabi moment
That's the only thing I will agree with this piece of hardware
* Fix syntax error in triage-tools.yaml
* fix(github): restrict triage commands to issues
---------
Co-authored-by: Chris Titus <contact@christitus.com>
* Add EmulationStation and Tailscale entries to applications.json
* Update config/applications.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update config/applications.json
I'm so sorry I'm late I've had to take a break from this for a bit of health related stuff.
Co-authored-by: Ivan Lepekha <57459428+FluffyPunk@users.noreply.github.com>
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Ivan Lepekha <57459428+FluffyPunk@users.noreply.github.com>
* feat(apps): Added Battle.net
Just Blizzard. Well, we can hate them, but their launcher is unique
* You know, being smart is a hard work...
* titusTypo
* fix: link apps to their own site instead of a repo or store page
- the icon comes from the link's domain, so every GitHub hosted app showed
the same octocat and the two store apps showed the Microsoft Store tile
- point 16 apps at the project's own site, and LibreWolf at librewolf.net
rather than its old gitlab.io address
- left on GitHub where the site turned out to redirect back to the repo
(fnm, MSEdgeRedirect, Deskflow) or has no icon to serve (gsudo,
simplewall, ungoogled-chromium, DISMTools)
* fix: point Teams at teams.live.com so it shows the Teams logo
- the marketing page on microsoft.com serves the generic Microsoft favicon,
which Edge already uses
* fix: keep GlazeWM and Lua on the pages that match what is installed
- glazewm.com is not the project's own site: the repo declares no homepage,
glzr.io never references it, and it runs on unrelated hosting
- lua.org is the language, while the package is Lua for Windows
* fix: keep Teams on the Microsoft product page
- the package is Microsoft.Teams, the work product, while teams.live.com is
the consumer edition
FontScalingSlider had no AutomationProperties.Name, so screen readers
announce it as an unnamed slider with only a raw numeric value.
Completes the accessible-name coverage of the font scaling popup.
ThemeButton, FontScalingButton, SearchBar, and SearchBarClearButton had
no AutomationProperties.Name, so screen readers (Narrator, NVDA)
announce them as raw glyph text ("N/A", Unicode E8D3), an unnamed edit
field, and a button called "X". Completes the top-bar naming pass
started for SettingsButton and the window controls.
* Containerize the docs site's npm tooling
Run Astro/Starlight dev, build, and preview commands through Docker
(docs/Dockerfile, docker-compose.yml, service winutil-astro) instead
of bare npm on the host, and document the required commands and
rationale in docs/README.md.
* Document Docker-only npm policy for agents
Add a Dependency Installs, Builds, And Dev Servers section to
AGENTS.md requiring docs/ tooling to run through Docker rather than
directly on the host, point SPEC.md's Docs Site section at the new
Dockerfile/docker-compose.yml, and renumber the remaining AGENTS.md
sections to stay sequential.
* Harden docs Docker dev environment
Tightened docs-container safety and clarified contributor workflow. The docs Docker image now switches to the non-root `node` user after setting ownership, and compose now binds Astro to `127.0.0.1` instead of all interfaces. Updated AGENTS and docs README instructions to explain the security boundary of the bind mount and to require rebuilding plus `docker compose down -v` after dependency changes so `node_modules` is reseeded correctly.
* Clarify docs secret handling in AGENTS
Updates AGENTS.md to tighten docs security guidance: secrets must not be stored anywhere under `docs/`, because `docs/.dockerignore` only affects image build context and does not protect files from the Docker Compose bind mount used for docs dev/build commands.
* Fix preview command to expose port in Docker
The previous preview command didn't expose the port outside the container. Adding --service-ports and binding to 0.0.0.0 makes the preview server accessible from the host.
* Update dns.json
* Fix Mullvad DNS review issues
* Add Mullvad secondary resolvers
* Register DoH before changing adapter DNS
* Report DNS failures to tweak workflow
* Handle non-terminating DNS assignment failures
* Preserve DNS fallback and document Mullvad options
---------
Co-authored-by: Chris Titus <contact@christitus.com>
* Fix UI automation peer wrapping and category focusability
* Add accessibility name to SettingsButton
* Avoid nesting ScrollViewer in generated panels with outer viewers
Inspect targetGrid and its parent hierarchy in Invoke-WPFUIElements to avoid adding an inner ScrollViewer when an outer ScrollViewer already exists.
* Turn the Install category filters into toggle chips
- Replace the filter buttons with toggles that show which ones are active
- Add ctrl click to select more than one category
- Keep the search box and the category filter independent of each other
- Expand matching categories while a filter is active
* Fix the filter interactions the category chips missed
- Pass the selected categories to the lazy rendering batches, the old call
used a parameter that no longer exists and threw while typing
- Keep the category filter when switching tabs, the chips stayed checked
while the filter itself was dropped
- Put a category back to collapsed once the filter that expanded it is gone
* Document the Install category filters
- Add a guide section for the chips, ctrl click and clearing the filter
- Note that search and the category chips apply together
* Correct the category filter guide wording
- Clearing by clicking the chip only applies when it is the only one selected
- Only categories with matches expand, and only auto expanded ones re-collapse
* Point OpenSSH key setup at the file sshd actually reads
The Remote Access feature created %USERPROFILE%\.ssh\authorized_keys and
told the user to put their public keys there. sshd does not read that
file for a member of the administrators group; the "Match Group
administrators" block in sshd_config sends those logons to
C:\ProgramData\ssh\administrators_authorized_keys instead. WinUtil always
relaunches itself elevated, so the account it was setting up is always an
administrator, and key auth for it never worked.
The function tried to work around that by commenting the block out, but
those regexes anchor on $, and .NET puts $ before the \n of a CRLF pair.
The sshd_config Windows ships is CRLF throughout, so the replace was a
silent no-op on a stock install. On an sshd_config with LF endings it did
apply, and that is worse than not working: sshd gives an administrator
logon a full token with no UAC prompt, which is why Windows keeps those
keys in ProgramData behind an ACL that requires elevation to write.
Moving the lookup into the profile lets anything running as the user at
medium integrity append a key and get an elevated shell unprompted.
Use administrators_authorized_keys and give it the ACL sshd requires
(inheritance off, Administrators and SYSTEM only, by SID so localized
installs work). Where the sshd_config edit did land, undo it and copy any
keys out of the profile file first so key auth is not cut off mid-session.
Keys are only copied when the block needs restoring, so a default config
never grants access sshd was not already granting.
Also stop creating the profile .ssh directory: under elevation it was the
elevating administrator's profile, not necessarily the caller's.
* Document where to put SSH keys for the OpenSSH server feature
* Make UI helpers no-op when no window exists
The -Preset and -Config paths run Invoke-WinUtilAutoRun before the XAML
form is created and before PresentationCore is loaded, so every call into
Invoke-WPFUIThread failed with InvokeMethodOnNull and every call into
Set-WinUtilTweaksProgressIndicator failed to resolve [Windows.Visibility].
The errors were non-terminating, so tweaks still applied, but each run
filled the log with noise.
Loading presentationframework earlier does not help: Visibility lives in
PresentationCore, which only loads once a WPF object is instantiated, and
the XAML-named progress controls do not exist in these paths either.
Guarding the two helpers covers Invoke-WPFtweaksbutton, Invoke-WPFundoall
and Invoke-WPFFeatureInstall, which the existing per-call-site $hasUI
convention never reached.
* Suppress stray console output from automation runs
Invoke-WPFRunspace returns an IAsyncResult that no caller uses, and
Set-WinUtilRegistry was the only New-PSDrive call site that did not
suppress its output. A GUI click handler discards both, but the -Preset
and -Config paths call the workflows directly, so an async handle dump
and a PSDrive table landed in the user's log.
The handle itself is kept because pester/runspace.Tests.ps1 asserts that
Invoke-WPFRunspace returns a single IAsyncResult, so the suppression goes
at the four call sites reachable from Invoke-WinUtilAutoRun.
* Add project learning for window-free UI helpers
Tabs other than Install build their checkboxes lazily on first visit.
Import populates $sync.selected* and calls Reset-WPFCheckBoxes, but
that only touches checkboxes that already exist in $sync, so any tab
not yet visited gets its controls built later with default (unchecked)
state and never reflects the import. Re-apply Reset-WPFCheckBoxes right
after a tab's controls are built so it picks up existing selections.
mpv has no official Windows installer; winget id shinchiro.mpv is the
de facto standard Windows build. Choco mpv/mpv.install are flagged
"Possibly broken" upstream, so winget is the sole install source.
* Add SEO metadata to docs home
Add a robots.txt sitemap directive and JSON-LD SoftwareApplication metadata to the docs homepage to improve search engine discovery and rich results.
* Add social preview metadata
Add Open Graph and Twitter image metadata for the docs site and include a new shared social preview image. Also set the homepage title metadata to match the documentation branding.