Commit Graph
1679 Commits
Author SHA1 Message Date
Omar 41e4f35897 Automate WinUtil title screen generation (#4965)
* feat: add title screen generation tooling

Add local automation for capturing WinUtil in Light and Dark themes
and generating the composite title-screen image.

* ci: automate title screen updates

Add a manual Windows workflow that compiles WinUtil, generates the
Light and Dark composite, and opens an image-only pull request.

* docs: update AGENTS.md and SPEC.md with title-screen generation details

* fix: address review comments

Tested image is correct, SHA-256 hash is identical to the previously verified output.

* fix: deselect bitmap before reading capture pixels
2026-09-02 16:10:44 -05:00
OmarandChris Titus d1a61790a1 Preserve clipboard history when disabling activity history (#5035)
* chore(tweaks): clarify Activity History tweak description

* fix(tweaks): preserve clipboard history

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2026-09-02 16:05:02 -05:00
owenn 87dd643176 Use well-known SIDs for icacls tweak principals (#5045) 2026-09-02 15:14:56 -05:00
Malin Fossum 8f7b12bc0d Add tweak to block Logitech Download Assistant auto-install (#5034)
* 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.
2026-09-02 15:01:13 -05:00
catsmoker 88071f2849 Add File Converter application to multimedia tools (#5036) 2026-09-02 14:59:29 -05:00
OmarandChris Titus df858c4cd7 Inject Win11 Creator drivers per package instead of one batch (#5048)
* 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>
2026-09-02 12:09:18 -05:00
Chris Titus cc5e31460b Update sponsors in README (#5051) 2026-09-02 10:35:44 -05:00
Noah Webber d0f7689504 Kitchen sink changes (#5040)
* 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
2026-09-02 10:14:51 -05:00
Omar 22e1dc9b09 Filter unserviceable and stale drivers before Win11 Creator injection (#5016)
* 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
2026-09-02 10:11:20 -05:00
Ivan Lepekha c00f1eb7b3 feat(github): Prettify bug report template (#5050)
* 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)
2026-09-02 10:10:01 -05:00
f54b22da2c feat(github): let people know about dotnet for sponsors (#5044)
* Money goes brrrrr

Added note about sponsors with recurring subscriptions.

* Update README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Chris Titus <contact@christitus.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-08-31 16:00:42 -05:00
Chris Titus e15e2be1c4 Update sponsors in README (#5042) 2026-08-31 10:32:33 -05:00
Chris Titus 34f7ce5a0e Update sponsors in README (#5032) 2026-08-24 10:42:42 -05:00
Chris Titus 086aecf4b7 chore: Update generated dev docs and JSON links (#5014) 26.08.19 2026-08-19 17:24:59 -05:00
NikhilandChris Titus 436773df73 Fix legacy json import compatibility, UI sidebar refactor, and improved test coverage (#4911)
* 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>
2026-08-19 17:13:14 -05:00
4b2fe55a7a fix(system): correct service, update repair, and legacy imports (#4966)
* fix(system): correct sc.exe argument syntax, reg deletion, and ipv6 dns guard

* fix(impex): exclude legacy Install metadata from flattened import

* fix(service): throw on non-zero LASTEXITCODE from sc.exe config

* refactor(dns): revert unnecessary ipv6 guard per review feedback

* test(impex): cover legacy config imports

---------

Co-authored-by: WinUtil Contributor <contributor@winutil.local>
Co-authored-by: Chris Titus <contact@christitus.com>
2026-08-19 16:54:24 -05:00
Malin FossumandChris Titus b8b81edcdb Show preset JSON key in app, tweak, and feature tooltips (#4995)
* 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>
2026-08-19 16:26:11 -05:00
Ivan LepekhaandChris Titus a7074963a6 fix(apps): warp prettify (#5013)
* 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>
2026-08-19 16:11:04 -05:00
Ivan LepekhaandChris Titus 032ce8ead0 feat(github): revival of triage tools (#5007)
* 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>
2026-08-19 16:03:06 -05:00
792122e998 fix: preserve selections when config import is invalid (#4994)
* fix: validate imports before replacing selections

* test: cover atomic config imports

* docs: explain stale config imports

---------

Co-authored-by: Guilherme de Oliveira Rocha <contatoguilhermeoliveira@protonmail.com>
Co-authored-by: Chris Titus <contact@christitus.com>
2026-08-19 15:30:46 -05:00
2d0fd43bd3 Add EmulationStation and Tailscale entries to applications.json (#4973)
* 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>
2026-08-19 14:04:14 -05:00
Manreet Singh 219b2fe137 Added Cloudflare WARP to pro tools (#5011) 2026-08-19 14:03:22 -05:00
Ivan Lepekha 527eefb114 feat(apps): Added Battle.net (#4996)
* 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
2026-08-19 14:02:30 -05:00
MyDrift d1b8470af2 Link apps to their own site instead of a repo or store page (#5010)
* 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
2026-08-19 14:00:57 -05:00
Malin Fossum 6066675f93 Add accessible name to font scaling slider (#4993)
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.
2026-08-19 14:00:12 -05:00
Malin Fossum b21d416161 Add accessible names to remaining top-bar controls (#4992)
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.
2026-08-19 13:59:45 -05:00
Abdullah Mansour 87a0eb8637 Fix location service startup type (#4972)
* fix(tweaks): use canonical location service startup type

* test(tweaks): pin location service startup type
2026-08-19 13:50:34 -05:00
Omar 8500ed116f Fix OSCDIMG detection (#4983)
* fix: detect machine-wide OSCDIMG installations

* fix: repeat OSCDIMG discovery after installation
2026-08-19 13:49:38 -05:00
Omar d16ee0e9f1 chore: remove fullscreen optimizations tweak (#5000) 2026-08-19 13:46:34 -05:00
Chris Titus 5ba8686dd7 Update sponsors in README (#5003) 2026-08-18 10:40:06 -05:00
Chris Titus 3f1850f623 Update sponsors in README (#4988) 2026-08-16 10:35:29 -05:00
Chris Titus 0dbe39bc7d Update sponsors in README (#4985) 2026-08-15 10:35:25 -05:00
Chris Titus 91972b0853 Update support section with new product information 2026-08-14 08:44:10 -05:00
dependabot[bot] aee3e7a1f4 chore(deps): bump js-yaml from 4.3.0 to 4.3.1 in /docs (#4970)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.0 to 4.3.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.1/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.3.0...4.3.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.3.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-11 17:55:18 -05:00
Sean (ANGRYxScotsman) ea5de27b6c Update issue templates with prefilled titles (#4960)
* Prefill title on bug report issue template

* Prefill title on feature request issue template

* Trim trailing space from issue template titles
2026-08-10 09:48:43 -05:00
Sean (ANGRYxScotsman) 2752fe2e03 updated title-screen pic (#4959) 2026-08-10 09:44:30 -05:00
Sean (ANGRYxScotsman) 1458327638 Containerize docs site tooling for security and update documentation (#4942)
* 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.
2026-08-09 20:11:35 -05:00
Kai Davids Schell ea7fcf9d2b Per anthropic docs include agents.md with a direct import rather than instruction (#4958) 2026-08-09 20:06:01 -05:00
Graham DavidandChris Titus 0aa4ab3a40 Adding Mullvad to DNS (#4927)
* 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>
2026-08-09 19:43:19 -05:00
makhlwf afc3e1eec2 Fix screen reader button accessibility and category navigation (#4944)
* 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.
2026-08-09 18:02:53 -05:00
Chris Titus 53fc260cc0 Fix WinOneShot ComboItems compatibility (#4957)
* Fix WinOneShot ComboItems compatibility

* Align ComboItems validation with renderer
2026-08-09 16:47:45 -05:00
Omar bc607b6c91 Make MPO tweak a three-state control (#4897)
* refactor: make MPO tweak a three-state control

* docs: explain MPO tweak states

* docs: address code review comments

* refactor: make Multiplane Overlay config-driven
2026-08-09 14:02:42 -05:00
Vale_ThandFallenGME 7f18b4fd60 Add Roblox entry to applications.json (#4931)
Added The Game Roblox to the Application list.

Co-authored-by: FallenGME <125669256+FallenGME@users.noreply.github.com>
2026-08-09 13:19:23 -05:00
MyDrift 32ab9f0ab0 Turn the Install category filters into toggle chips (#4926)
* 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
2026-08-09 13:13:21 -05:00
Ashvin 9fdadd1c8f Point OpenSSH key setup at the file sshd actually reads (#4936)
* 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
2026-08-09 13:08:33 -05:00
Phuc To 6de45a38b9 Fix UI helper errors during headless -Preset and -Config runs (#4941)
* 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
2026-08-09 13:06:17 -05:00
Vinicius Costa Amorim 8860caf357 fix: apply imported config selections to lazily-built tabs (#4938)
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.
2026-08-09 12:59:13 -05:00
PChaicotandChris Titus 8fb078da4c Add foobar2000 back into applications.json (#4932)
* Add foobar2000 back

* Add Fast Node Manager entry to applications.json

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2026-08-09 12:57:25 -05:00
Vinicius Costa Amorim 95e3a54405 feat: add mpv to Multimedia Tools app list (#4940)
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.
2026-08-09 12:53:11 -05:00
Sean (ANGRYxScotsman) c817d3329a Enhance SEO and social metadata for documentation homepage (#4923)
* 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.
2026-08-09 12:48:15 -05:00