* 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.
* docs: correct Win11 Creator behavior after the ISO workflow refactor
The creator stopped stripping unused editions, loading offline registry
hives, and running component store cleanup in #4862. It now copies the
ISO contents and applies the selected edition through sources\ei.cfg and
autounattend.xml, leaving install.wim alone unless drivers are injected.
Update the guide and the architecture reference to match, and note that
the output ISO is close to the size of the source.
* docs: align disk space, driver injection, and stuck-run guidance
The disk space block still carried the pre-refactor 10-15 GB workspace,
2.5-3.5 GB output, and ~25 GB total, which contradicted the copy-based
numbers in the data flow. Restate them against the source ISO size.
Driver injection never touches boot.wim. It adds every exported driver
to the selected install.wim index and stages only the storage packages
in $WinpeDriver$ for WinPE, so correct both the guide and the reference.
The stuck-run troubleshooting entry pointed at a WIM dismount that only
happens when driver injection is enabled.
* docs: narrow this PR back to the edition and output size claims
The earlier commits rewrote the surrounding Win11 Creator sections,
which went well beyond what #4918 was about and presented the rest of
the section as reviewed when it had not been.
Restore the untouched text and keep only the claims that promised a
size reduction or edition removal: the strip-editions and component
store bullets, the two data flow lines, and the modified ISO size.
* Replace FOSS dot with a corner badge on app entries
- Add New-WinUtilFossBadge, the open source keyhole on a green backdrop
- Mark FOSS apps with a corner triangle instead of a dot after the name
- Give the FOSS legend a circle badge and move it below the buttons
- Sort Note entries last, they shared a rank with checkboxes before
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Update functions/private/Initialize-InstallAppEntry.ps1
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Centralize agent instructions in SPEC
Move the full coding-agent contract and repository guidance from `AGENTS.md` into `SPEC.md`, and reduce `AGENTS.md` to a simple pointer to the canonical instructions. Add lightweight `CLAUDE.md`, `GEMINI.md`, and `.github/copilot-instructions.md` files so different assistants consistently bootstrap through the same repo-specific guidance.
* Clarify auto-generated docs path scope in SPEC
Narrowed rule #3 to specify exact auto-generated subdirectories (tweaks/ and features/) rather than the entire code-reference/ directory, and clarified that other hand-written pages (e.g. architecture.mdx) may be edited directly.
* Remove archived docs from gitignore
Drop the old `docs-old` Hugo ignore rules from `.gitignore`, reflecting that the archived docs build artifacts no longer need special handling there.
* Add local env files to docs .gitignore
Add .env.local and .env.*.local patterns to prevent local environment files from being committed.
* Clarify test and git hygiene guidance
Update `SPEC.md` to run Pester in CI mode and tighten repository hygiene instructions around ignored files. The git guidance now points contributors to the actual `.gitignore` files and clarifies that `docs/public/` contains tracked static assets rather than generated output.
* Split agent workflow from project spec
Move repository working instructions into `AGENTS.md` and refocus `SPEC.md` on the stable WinUtil project contract. This separates agent-specific guidance from architecture, build, runtime, docs, testing, and release details so both documents have clearer ownership.
* docs: clarify Pester, ScriptAnalyzer, and source-of-truth rules
Expand AGENTS.md with context on why -SkipPublisherCheck is needed for Pester installation, why winutil.ps1 should be deleted before running ScriptAnalyzer, and clarify that the source-of-truth rule applies only to compiled-script behavior — repository metadata files are edited directly.
* Clarify Pester install command and -SkipPublisherCheck reason
Expands the explanation for why -SkipPublisherCheck is needed (catalog-signed vs Authenticode-signed), clarifies it does not skip download integrity, and adds -Repository PSGallery to pin the trusted source explicitly.
* feat: restore document category
Moves existing document-focused apps into the Document category and adds its filter chip.
* feat: restore document applications
Restores reviewed document-focused apps removed in PR #4451.
* chore: update apps list as per code review comments
This also updates the link for PDF24 Creator
* test: verify document category filter wiring
Covers the Document filter handler and config category presence.
* fix: categorize Calibre as multimedia
Keeps the e-book reader in Multimedia Tools.
* fix: repair popup install binding, dialog titles, presets switch, radio groups, JSON, tests
- Invoke-WPFInstall: add param block so the right-click app popup binds
-PackagesToInstall. It previously dropped the argument into $args and
installed the whole selected list instead of the clicked app (or warned
that nothing was selected).
- Replace undefined $AppTitle with "WinUtil" in Install/UnInstall warning
boxes, matching the XAML window title and sibling dialogs.
- tweaks.json: remove stray nested "link" inside the WPFToggleScrollbars
registry entry (dead property; registry entries expose only the six
consumed fields).
- Invoke-WPFPresets: fix dead switch cases to the wildcard-pattern
convention so selectedFeatures/selectedToggles clear correctly.
- Invoke-WPFUIElements: store the group StackPanel in radioButtonGroups so
grouped radio buttons share one container (else branch was unreachable).
- sanity.Tests.ps1: pass the Windows PowerShell parser script via
-EncodedCommand; -Command string marshaling corrupted backticks/quotes and
produced false parse failures.
- install-workflow.Tests.ps1: remove the AppTitle workaround and update
title assertions to "WinUtil"; drop orphaned cleanup lines.
- Add CHANGES.md with technical and plain-language explanations.
Verified: each bug reproduced against HEAD, fixes demonstrated to change
behavior, full Pester suite 471/471.
* Delete
* test: cover the explicit popup install parameter path
Add a regression test invoking Invoke-WPFInstall -PackagesToInstall with a
package different from the default sync.selectedApps selection and assert
the runspace receives the explicit object, mirroring the Initialize-WPFUI
popup call shape. Existing default-path coverage is unchanged.
Add the `YouTubeEmbed` component import to `docs/src/content/docs/guides/tweaks.mdx` so the guide can use embedded YouTube content without missing-component build issues.
Update image links in `.github/CONTRIBUTING.md` and `.github/READMEITALIAN.md` from `../docs/...` to `/docs/...` so screenshots resolve correctly when viewed from the `.github` directory context on GitHub.
The homepage uses Starlight's splash template, which has no sidebar and
therefore never gets Starlight's own mobile menu toggle - on narrow
viewports there was no way to reach any nav link at all. Add a small
toggle + panel in the header (only rendered on pages without a sidebar)
exposing the same links as the desktop nav, and group it with the
search icon so mobile actions sit together instead of spread across
the header.
Also add the Store and Forums links to the real sidebar config so
they're reachable on mobile on every other page too (previously only
in the desktop-only top nav), and pull both URLs from a shared
site-links.ts so the sidebar config and header can't drift apart.
* Update Applications tab screenshots
Replace outdated install/uninstall/show-installed screenshots and add
new ones for upgrade-all, clear-selection, selected-apps counter, and
collapse/expand categories.
* Update Applications guide with new screenshots and sections
Point each tab at its refreshed screenshot, reorder tabs to match the
sidebar button order in the app, and document the Upgrade All,
Selected Apps counter, and Collapse/Expand Categories controls.
* Add missing Updates tab screenshot
The image was referenced by the Updates guide but was never checked
into the repo.
* Reorder screenshots to follow their intro paragraph
Move the tab screenshot below the introductory text on the Tweaks and
Updates guide pages, matching the paragraph-then-screenshot layout
used elsewhere in the docs.
---------
Co-authored-by: Chris Titus <contact@christitus.com>
* Fix the same arrow-icon alignment issue on the "Read the Docs" button
Same root cause as the hero/final-CTA buttons: the label was plain
markdown text, which MDX wrapped in a <p>, and the icon was missing
the size/nudge applied elsewhere. Match it to the other two buttons.
* Rename known-issues page slug to knownissues
Update the sidebar config, nav dropdown, and every internal link that
pointed at /known-issues/ to match.
* Fix image paths in root-level markdown to match the new docs site
The Hugo docs site (docs/assets/images/...) has been replaced by the
Astro site (docs/src/assets/...); update CONTRIBUTING.md,
READMEITALIAN.md, and README.md to point at the new asset locations.
* Remove unused houston.webp asset
Leftover Starlight default-theme asset with no references anywhere
in the docs site.
* Fix docs site reference in generator docs
Updates `tools/devdocs-generator.md` to describe link generation correctly: links now point to the Astro/Starlight documentation site instead of the old Hugo site.
* Point docs homepage CTAs to guides hub
Updates the docs landing page CTA links to use `/guides/` instead of `/guides/getting-started/` in the hero action and both “Get Started”/“Read the Docs” buttons, routing users to the guides index.
* Add reusable YouTube embeds to docs guides
Introduces a new `YouTubeEmbed.astro` component for responsive 16:9 video embeds using the privacy-enhanced `youtube-nocookie.com` domain. The User Guide index and Tweaks guide now import and use this component instead of plain YouTube links, and the component includes styling that overrides Starlight’s iframe reset so embedded videos render at the correct size.
* Fix YouTube embed iframe height via not-content
Add the `not-content` class to the embed wrapper so Starlight's markdown reset no longer overrides `iframe { height: auto }`. Drop the `@layer starlight.core` wrapper and `!important` overrides that were compensating for the same issue.
* Clarify docs comments across Astro components
Adds and refines inline comments in the docs site config, custom Starlight components, and theme styles to better explain layout structure, navigation dropdown behavior, hero composition, and theme initialization. Also normalizes a few multi-line comments into single-line form for readability without changing functionality.
* Set secondary docs button background color
Update `.wu-btn-secondary` in the docs theme to use `var(--sl-color-gray-6)` instead of a transparent background, improving button visibility and contrast while keeping existing border and hover behavior.
* Move User Guides into docs dropdown
Updates the docs header navigation so the “User Guides” link is grouped under the existing “Documentation” dropdown instead of appearing as a separate top-level nav item. This keeps related documentation links together and simplifies the top navigation.
* Fix hero margin and center trust section
Remove the automatic 1.5rem top margin Starlight adds between the hero and the content column. Also flex-center the trust section so its content is properly aligned.
* Disable edit links in generated dev docs
Update `tools/devdocs-generator.ps1` to include `editUrl: false` in the frontmatter for generated tweak and feature docs pages. This prevents Starlight from showing edit links on these auto-generated pages.
* Move docs update PRs to pre-release flow
The docs Pages workflow is simplified to only build and deploy the docs site: it now triggers only on docs changes, drops extra permissions/default shell settings, and removes the dev-docs generation + auto-PR steps. The pre-release workflow now owns that automation by expanding its PR step to include generated code-reference docs alongside JSON link updates, with updated commit/title/body text and a documentation label.
* Shorten generated docs source note
Simplify the autogenerated DevDocs notice so generated pages only warn against direct edits while still linking back to the source file.
* Improve docs header dropdown behavior
Reworked the header nav dropdown triggers to use native `<details>/<summary>` instead of buttons, then updated menu visibility logic to use `details[open]` for no-JS support on touch and keyboard while preserving hover behavior. Also renamed the “Developer Docs” link to “Code Reference” and tightened related CSS comments.
* Refresh contribution and docs workflow docs
Updated contributor-facing docs to use consistent Markdown admonition blocks, cleaned Mermaid fence formatting, and fixed minor wording/capitalization in contribution steps. Clarified `devdocs-generator` behavior so workflow ownership is explicit: generation now documented as part of `pre-release.yaml` (via docs-update PR), while `docs.yaml` is documented as build/deploy only.
* Fix contributing guide grammar
Correct the "it's" to "its" typo in both contributing guides so the pull request guidance is consistent across the GitHub and docs versions.
* feat: Add DoH templates for DNS providers in configuration
* feat: Implement DoH support for DNS configuration and management
* feat(pester): enhance DNS tests to include DoH server address handling and template application
* fix: address codex feedback
* fix: update existing DoH server entries
* fix: enable DoH auto-upgrade
* fix: handle DNS setup failures
* fix: remove DoH state on DHCP reset
* refactor: simplify Win11 Creator ISO workflow
Keep no-driver ISO generation on the fast copy-only path.
Inject exported drivers with one selected-index WIM mount, one Add-Driver pass, and one commit.
Limit WinPE staging to boot-storage drivers and improve workflow validation coverage.
* refactor: stage Win11 setup script fallback
Copy the prepared setup script payloads into sources/$//Setup/Scripts so setup media does not depend solely on answer-file extension extraction.
Keep the existing autounattend execution path unchanged and cover the fallback files in the Win11 Creator tests.
* refactor: address codex feedback
* refactor: run ISO verification in runspace
Rename the ISO logger to Write-WinUtilISOLog so the shared runspace pool imports it automatically. Run Mount & Verify off the WPF thread with dispatcher-safe UI updates, and add Pester coverage for the runspace and logger contract.
* refactor: address ISO review feedback
Keep the selected ISO stable during background verification. Apply ContentDeliveryManager settings to both the first account and the default profile. Block FAT32 USB creation when install.esd exceeds the supported file size.
* refactor: address ISO setup edge cases
Set BypassNRO before OOBE so local account setup is available during Windows Setup.
Detect registered DISM mounts during driver-injection cleanup so partial mount failures are discarded.
* refactor: address ISO review edge cases
Use the actual FAT32 file limit for install.esd USB checks.
Disable ISO modification while mount verification is running.
Apply unsupported-hardware notice suppression to the first user profile.
* refactor: stage ISO setup safeguards earlier
Set device encryption and reserved-storage registry guards before OOBE.
Enable the OEM configuration-set fallback when setup scripts are staged there.
* Update functions/private/Invoke-WinUtilISOUSB.ps1
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>
* refactor: implement FilterChipStyle for Install tab category filters
- Created a dedicated FilterChipStyle style block with custom padding, cursor, and height definitions
- Applied FilterChipStyle to all category filter buttons
- Added a new 'Filters' TextBlock section title aligned with the sidebar actions
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Chris Titus <contact@christitus.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>