imgbot
26791
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
98060b08a6 |
Add Windows managed local account server flow (#48721) (#49924)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48721 Part 2 of https://github.com/fleetdm/fleet/issues/43488 # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Windows devices can now create and securely escrow managed local account passwords during enrollment. * Added Windows managed local account status and password availability to host details. * Device-reported setup errors are surfaced with helpful details. * Account creation is automatically requested when supported by the device, plan, and configuration. * **Bug Fixes** * Windows accounts are excluded from password rotation workflows. * Re-enrollment correctly triggers account creation when needed. * Passwords remain available when settings change after enrollment. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a4d058384c |
Add CrystalDiskMark as a Windows FMA (#50415)
**Related issue:** Resolves #50322 Adds CrystalDiskMark as a Windows Fleet-maintained app, from winget `CrystalDewWorld.CrystalDiskMark` (9.0.3, Inno Setup, machine scope, x64). Found in a customer's ManageEngine ServiceDesk Plus Windows deployment catalog with no Fleet equivalent. ## Identity — read out of the Inno header, not the manifest The winget manifest carries no `AppsAndFeaturesEntries`, so the ARP identity had to come from the installer itself. I LZMA-decompressed the Inno setup-data block and read the header directly: | Header field | Value | |---|---| | `AppName` | `CrystalDiskMark` | | `AppVerName` | `CrystalDiskMark 9.0.3` | | `AppVersion` | `9.0.3` | | `AppPublisher` | `Crystal Dew World` | | `AppId` | `CrystalDiskMark9` | | `UninstallDisplayName` | *(empty)* | | `DefaultDirName` | `{pf}\CrystalDiskMark9` | With `UninstallDisplayName` empty, Inno falls back to `AppVerName` for the ARP `DisplayName` — so this registers as **`CrystalDiskMark 9.0.3`**, version-suffixed, and the exists query is a prefix match (`fuzzy_match_name: true`). That the name is version-suffixed isn't inferred from "Inno usually does this." The Aoi edition's header sets `AppVerName` to `CrystalDiskMark 9.0.3 Aoi Edition` while its `AppName` is `CrystalDiskMark Aoi Edition` — the compiler's synthesized default would have been `CrystalDiskMark Aoi Edition 9.0.3`, so the script is setting `AppVerName` deliberately, and Setup will write exactly that string. `AppPublisher` matches the winget locale `Publisher` verbatim, so no `program_publisher` override is needed, and `DisplayVersion` is `AppVersion` = `9.0.3`, which reconciles with the FMA version with no validator exception. Generated query: ```sql SELECT 1 FROM programs WHERE name LIKE 'CrystalDiskMark %' AND publisher = 'Crystal Dew World'; ``` ## Silent flags — the `[Run]` entries were decoded, not assumed The header contains three `[Run]` entries with `{cm:LaunchProgram,CrystalDiskMark9}` descriptions (one per architecture), which is exactly the shape that has hung silent Inno installs for us before. I parsed the entry structure through to the flag bytes: - wait enum = `1` → `nowait` - flags = `0x14` → bit 2 `postinstall` + bit 4 `skipifsilent` So `/VERYSILENT /SUPPRESSMSGBOXES /NORESTART` will not launch the GUI, and there is no post-install hang to work around. The install script still uses the poll-and-kill wrapper rather than `-Wait`, plus an ARP-registration wait, since the installer can return before the registry entry lands. `/ALLUSERS` is deliberately omitted: `DefaultDirName` is `{pf}`, which requires admin install mode already, so the switch would be a no-op. ## Uninstall `UninstallString` is Inno's quoted `unins000.exe` path, but the script uses the three-branch defensive parser (quoted / unquoted-with-spaces / bare token) anyway. Two app-specific bits: - The 12 `DiskMark*.exe` binaries are stopped first — the uninstaller won't proceed while the `CrystalDiskMark9` mutex is held. - The script waits for the registry entry to disappear rather than trusting the exit code. Inno's uninstaller relaunches itself from a temp copy and the original process returns early, so its exit code is not a completion signal. ## Icon The setup exe's `MAINICON` is Inno's stock CD-and-box artwork, not the app's, so the icon was extracted from `DiskMark64.exe`'s own resources (`innoextract` → `wrestool -t 14 -n 130` → `icotool`, 256×256 32-bit). ## Two things for reviewers 1. **This carries a shared-code change to the winget ingester** (`normalizeSourceForgeURL`). A bare SourceForge project file URL serves non-browser clients a 133KB HTML landing page with a 200, so the first validator run downloaded that instead of the installer and failed on the hash. Only the `.../download` form serves the binary. WinSCP works today only because its manifest happens to carry the suffix, so the fix normalizes in the ingester rather than depending on manifest authors. WinSCP regenerates byte-identical and is the only other SourceForge-hosted app in the catalog; `TestNormalizeSourceForgeURL` covers both shapes. Details in [this comment](https://github.com/fleetdm/fleet/pull/50415#issuecomment-5162501140). 2. **The Aoi and Shizuku editions share this package's `AppId` and install directory.** They occupy the same ARP slot (`CrystalDiskMark9_is1`), can't be co-installed, and will match the exists query as `CrystalDiskMark 9.0.3 <Edition>`. I treated that as correct rather than something to exclude — it is the same product at the same version — but flagging it in case we'd rather pin to the plain edition. ## Verification - Inno header dumped offline; `AppVerName` / `AppPublisher` / `AppVersion` read directly, `[Run]` flag bytes decoded. - Generated SHA matches the winget installer manifest (`1a255154…917e5e`), and the download was verified through the exact code path the validator uses (`maintained_apps.DownloadInstaller` with `http.DefaultClient`) — 4,523,144 bytes, hash matches. - `apps.json` valid, description filled, icon generated and inserted alphabetically in `index.ts` under the key `crystaldiskmark`. - `go test ./ee/maintained-apps/...` passes; `GOOS=windows go build ./cmd/maintained-apps/validate/` builds; `gofmt`/`go vet` clean. `make lint-go-incremental` could not run in my environment (`custom-gcl` fails to clone golangci-lint, pre-existing and unrelated). - First validator run failed on the download issue above and is fixed; the full validator pass (install → detect → uninstall on a Windows host) still needs to go green before this leaves draft. # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops ## Testing - [ ] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added CrystalDiskMark as a supported Windows application, including installation, uninstallation, detection, categorization, and software catalog details. * Added CrystalDiskMark branding to the software interface. * Improved SourceForge installer URL handling by automatically appending download paths when needed. * **Bug Fixes** * Preserved existing download URLs, query parameters, and unsupported or malformed URLs during normalization. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> |
||
|
|
e86fa44965 | Show button if there's only one action, instead of an actions dropdown (#48337) | ||
|
|
1dc1a51313 |
Fix Windows Git FMA patch policy never detecting outdated installs (#50424)
**Related issue:** Resolves #50283 Git for Windows registers itself in the Windows uninstall registry as exactly `Git` — its Inno Setup script has set `UninstallDisplayName={#APP_NAME}` since [build-extra#365](https://github.com/git-for-windows/build-extra/pull/365) (2021). The generated queries matched `programs.name LIKE 'Git %'`, which cannot match that name, so the patch policy's `NOT EXISTS (...)` was always true and every host reported `Pass` regardless of installed version — update automations never fired. The same mismatch meant an existing Git install couldn't be matched to the maintained app. The input now uses the custom fuzzy pattern `Git%`, which also covers the pre-2021 `Git <version>` DisplayName form (the oldest installs, which are exactly what a patch policy needs to flag), and relies on the existing `publisher = 'The Git Development Community'` guard to exclude GitHub Desktop, Git LFS, GitKraken and Git Extensions. This is the same match the app's own uninstall script and the FMA Windows CI workflow already use. Instances that already created this policy pick up the corrected query when the next Git version becomes active, since the patch policy query is regenerated from the active installer. # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`. ## Testing Verified the `LIKE` semantics in SQLite against real-world `programs` rows (old pattern misses `Git`, new pattern matches both DisplayName forms, publisher guard still excludes GitHub Desktop / Git LFS / GitKraken / Git Extensions), and confirmed winget's `PackageVersion` matches the registry `DisplayVersion` for Git so up-to-date hosts still pass. `outputs/git/windows.json` was regenerated with the ingester rather than hand-edited. Not manually QA'd on a Windows host — relying on `test-fma-windows` validation. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved Git for Windows detection across supported environments. * Outdated installations can now be correctly identified and included in update automation, including registrations named “Git.” * Existing publisher and version checks remain unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f37e78f2f3 |
Edit image caption in Linux inventory article (#50429)
Removed unnecessary text from the image caption in the article. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] Timeouts are implemented and retries are limited to avoid infinite loops - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [ ] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [ ] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [ ] Confirmed that the fix is not expected to adversely impact load test results - [ ] Alerted the release DRI if additional load testing is needed ## Database migrations - [ ] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [ ] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [ ] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). ## New Fleet configuration settings - [ ] Setting(s) is/are explicitly excluded from GitOps If you didn't check the box above, follow this checklist for GitOps-enabled settings: - [ ] Verified that the setting is exported via `fleetctl generate-gitops` - [ ] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [ ] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [ ] Verified that any relevant UI is disabled when GitOps mode is enabled ## fleetd/orbit/Fleet Desktop - [ ] Verified compatibility with the latest released version of Fleet (see [Must rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md)) - [ ] If the change applies to only one platform, confirmed that `runtime.GOOS` is used as needed to isolate changes - [ ] Verified that fleetd runs on macOS, Linux and Windows - [ ] Verified auto-update works from the released version of component to the new version (see [tools/tuf/test](../tools/tuf/test/README.md)) |
||
|
|
e83c2689f5 |
CIS Benchmarks: Update macOS benchmarks
Resolves #45644 Bring the macOS CIS benchmark policies up to the current CIS releases: - macOS 14 Sonoma: v3.0.0 -> v3.1.0 - macOS 15 Sequoia: v2.0.0 -> v2.1.0 - macOS 26 Tahoe: v1.0.0 -> v1.1.0 Policy changes: - 2.7.1: rescope the screen saver hot corners check to the current console user and move it to Level 1, per the updated CIS audit. - 3.4: relax audit log retention to >= 30 days (no size requirement); parse the day value anchored to `expire-after:` so a mixed directive such as `7d OR 30d` is correctly rejected. - 5.1.7: exclude the non-accessible /Library/AppStore directory and its descendants from the world-writable Library check. - 5.6: update for the new secure-token audit (verify root has no AuthenticationAuthority). - 5.3.1: add the internal APFS volume encryption check (Manual -> Automated) on macOS 26; remove the deprecated CoreStorage 5.3.2 check on macOS 14/15. - 2.10.1: correct the screen saver inactivity threshold to <= 900s (15 minutes) to match the CIS audit. Limitations documented (no reliable fleetd data source): - 5.3.2 (external APFS/HFS+ encryption): apfs_volumes exposes no internal/external indicator. - 5.3.3 (FAT32/ExFAT): CIS Manual audit. |
||
|
|
6c3de12f69 |
Base Orbit enrollment end user auth on server policy
EnrollOrbit now determines end user authentication requirements from
server policy rather than the client-supplied X-Fleet-Capabilities
header, which is treated as an informational hint.
Adds the mdm.allow_orbit_end_user_auth_bypass setting (enabled by
default) controlling whether hosts that do not complete end user
authentication may enroll into a team that requires it; set it to false
to strictly enforce end user auth. The setting also governs installers
built with fleetctl package --bypass-end-user-auth.
|
||
|
|
7abc0f6e7f |
Add article: Linux crossed 10% in North America, and your inventory might have missed it (#50412)
**Related issue:** NA New thought-leadership article pegged to Statcounter's July 2026 data showing Linux desktop share at 10.65% in North America. The angle is deliberately honest rather than triumphant: most of the month-over-month jump came from Statcounter reclassifying an "Unknown" traffic bucket, not from a mass migration. That measurement problem is the bridge into Fleet's argument, since the same blind spot that hid Linux from web analytics hides Linux hosts from asset inventories that discover devices through Apple and Windows enrollment channels. Includes a Cloudflare Radar chart as a second, independent data source. Cloudflare puts North American Linux desktop requests at 6.3% over the trailing year, well below Statcounter's figure, but both show a step change in the same weeks. The disagreement between the two sources reinforces the article's point that Linux is hard to count from the outside. Intended for use in ads and other traffic-driving placements. Notes for reviewers: - Capability claims (LUKS2 enforcement on Ubuntu/Kubuntu/Fedora with escrowed recovery keys, `.deb`/`.rpm`/`.tar.gz` and script-only packages, vulnerability detection including CISA KEV, remote script execution, remote lock and wipe, self-service, supported distro list) are grounded against `website/views/pages/linux-management.ejs`. Please confirm they are still accurate. - The article states that encryption enforcement covers a narrower set of distributions than the overall support list, which is intentional. - Statcounter figures are cited via Linuxiac; a Sources section attributes both Statcounter and Cloudflare Radar, and the chart carries inline attribution and a capture date. - `publishedOn` is set to `2026-08-02`. Bump if this merges later. - Byline is set to Allen Houchins. # Checklist for submitter - [ ] Content reviewed for Fleet voice and style (`content-style`) and article format (`fleet-article-formatting`) - [ ] Capability claims verified against the Linux management page and docs - [ ] Source attribution confirmed for Statcounter, Linuxiac, and Cloudflare Radar - [ ] Article renders correctly on the website, including the chart image |
||
|
|
86f4619faf |
Add Microsoft ODBC Driver 17 for SQL Server as a Windows FMA (#50342)
**Related issue:** Resolves #50326 Adds Microsoft ODBC Driver 17 for SQL Server as a Windows Fleet-maintained app, from winget `Microsoft.msodbcsql.17` (17.11.1.1, MSI, machine scope, x64, en-US). Found in a customer's ManageEngine ServiceDesk Plus Windows deployment catalog with no Fleet equivalent. ## The install would fail without a custom script The MSI refuses to install unless `IACCEPTMSODBCSQLLICENSETERMS=YES` is passed. This is not just a winget convention — the MSI carries the condition and the matching error string: ``` IACCEPTMSODBCSQLLICENSETERMS ~= IACCEPTMSODBCSQLLICENSETERMS=YES command-line parameter is missing. ``` Fleet's default MSI install script passes only `/quiet /norestart /i`, so without the small custom script in this PR every install would fail. Uninstall is still the auto-generated upgrade-code script, which is correct as-is. ## Verification Identity read from the MSI Property table: ``` ProductName Microsoft ODBC Driver 17 for SQL Server Manufacturer Microsoft Corporation ProductCode {ACBA503E-64A9-4A8A-A6CC-63656F395618} UpgradeCode {0123A210-9B73-46E7-B5CE-7F33630300E7} ALLUSERS 1 ``` - Installer SHA confirmed against a local download (`0f642870…bd4e`). - `ALLUSERS=1` means it always installs per-machine. - The generated uninstall script correctly picked up the **x64** UpgradeCode — note the x86 build uses a different one, so an arch mix-up here would silently fail to uninstall. **No version pinning is needed in the exists query.** When I scoped this I expected to need `AND version LIKE '17.%'` the way the Amazon Corretto FMAs do, but the `ProductName` already carries the major version, so `Microsoft ODBC Driver 17 for SQL Server` and `...18...` are naturally distinct entries. Simple equality is correct and unambiguous. ## Two notes for reviewers **Icon quality.** The MSI's `ARPPRODUCTICON` stream tops out at 32×32, so the 128×128 asset here is an upscale and looks soft. It is the authentic Add/Remove Programs icon, but if we would rather fall back to the generic software icon than ship a blurry one, drop the icon files and I will regenerate without them. **Icon map key needed a manual fix.** The generator derives its key from the slug and produced `"microsoft odbc driver 17"`, but lookups use the lowercased catalog name — `"microsoft odbc driver 17 for sql server"`. Corrected by hand. Same generator gap hit Paint.NET in #50340. **Dependency.** The manifest declares `Microsoft.VCRedist.2015+.x64`. The ingester ignores winget `Dependencies`, but unlike HandBrake (#50323) we do ship a matching FMA (`vc-redist-x64/windows`), and the redistributable is present on most Windows hosts already. Noting it rather than treating it as a blocker. # Checklist for submitter - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Microsoft ODBC Driver 17 for SQL Server to the maintained software catalog. * Added Windows installation and upgrade support for version 17.11.1.1. * Added the software’s icon and catalog display details. * Included silent installation, logging, license acceptance, and reboot handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
407db89ff5 |
Update Fleet-maintained apps (#50411)
Automated ingestion of latest Fleet-maintained app data. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved macOS uninstall cleanup for Dockside, ExifCleaner, Franz, LinearMouse, Safe Exam Browser, Smultron, Stats, Teleport Connect, and Zappy. - Uninstallation now removes additional app support files, caches, preferences, recent-document data, containers, logs, and related settings. - **Updates** - Updated Firefox Nightly to a newer macOS build. - Updated NetNewsWire from version 7.1.1 to 7.1.2 with refreshed download verification. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com> |
||
|
|
332d8a2cee |
Add Microsoft Access Database Engine 2016 Redistributable as a Windows Fleet-maintained app (#50365)
**Related issue:** Resolves #50325 Adds Microsoft Access Database Engine 2016 Redistributable as a Windows Fleet-maintained app, from winget `Microsoft.AccessDatabaseEngine2016` (16.0.5044.1000, x64). Found in a customer's Windows deployment catalog with no Fleet equivalent. ## No ingester change was needed after all When I scoped this I expected to need a one-line change, because winget types the installer as `portable`, which is not in the ingester's `vendorTypes` or `fileTypes`. I tested it first: `"installer_type": "portable"` with an empty scope matches cleanly, and since the generated output carries no installer type (Fleet infers `.exe` from the URL), the result is correct as-is. This is the first FMA input to use `portable`. If reviewers would rather not establish that precedent, adding `portable` alongside `wix`/`nullsoft`/`inno` in `vendorTypes` would let the type fall through to the URL extension and the input could then say `exe`. Both work. I chose the one that touches no shared code. ## Identity: winget's name is wrong twice over winget's locale manifest says `Microsoft Access Database Engine 2016 Redistributable`. The MSI says: ``` ProductName Microsoft Access database engine 2016 (English) Manufacturer Microsoft Corporation ProductCode {90160000-00D1-0409-1000-0000000FF1CE} UpgradeCode {00160000-00D1-0000-1000-0000000FF1CE} ALLUSERS 1 ``` Two traps: the real name is lowercase `database engine`, and it carries an `(English)` locale suffix with the LCID (`0409`) embedded in the ProductCode. osquery's `=` on TEXT is case-sensitive, so the winget-derived name would have matched nothing. ## x64 only, deliberately The customer deploys both architectures, but **x86 and x64 register the identical DisplayName**. I confirmed this by extracting both installers: | Arch | ProductName | UpgradeCode | |---|---|---| | x64 | `Microsoft Access database engine 2016 (English)` | `{00160000-00D1-0000-1000-0000000FF1CE}` | | x86 | `Microsoft Access database engine 2016 (English)` | `{00160000-00D1-0000-0000-0000000FF1CE}` | They differ only by product and upgrade code. Two FMAs could not be told apart by an exists query, so installing one would make the other report itself installed. Shipping x64 only avoids that. This also corrects my earlier note on the issue suggesting the architecture go in the catalog name; that would distinguish the catalog entries but not the detection queries, so it would not have helped. The uninstall script resolves the product from the x64 upgrade code rather than a product code, so it removes the x64 build and leaves an x86 install alone. ## The Office conflict is handled, not hidden This redistributable refuses to install when Office of the opposite bitness is present. Following the same approach @allenhouchins set out for HandBrake in #50323, the install script checks the Click-to-Run platform first and exits with an actionable message instead of a bare installer failure: ``` 32-bit Microsoft Office is installed on this host (Click-to-Run platform: x86). The 64-bit Access Database Engine cannot be installed alongside it. Use the 32-bit redistributable instead. ``` **A green validator here proves less than usual.** The CI runner has no Office installed, so it exercises the happy path only. The conflict this app is known for cannot be reproduced there. That is a limitation of the environment, not evidence the app is safe on managed hosts, and it is the main thing worth weighing before merging. ## Other notes - Installer SHA confirmed against a local download of `accessdatabaseengine_X64.exe` (`04e96c9f…03de`). - The download is a self-extracting package. Its `setup.cmd` runs `InstallUCRT.exe` and then `msiexec %1 /i AceRedist.msi`, which is why `/quiet` reaches the MSI. - **No icon.** The MSI has no `ARPPRODUCTICON` and no Icon table, so there is nothing to extract. The app falls back to the generic software icon, which suits a redistributable with no user-facing app. # Checklist for submitter - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Microsoft Access Database Engine 2016 Redistributable as a supported Windows application. * Added silent installation and uninstallation workflows with architecture checks, registration detection, timeout handling, and standard success-code support. * Included package metadata, version information, download verification, Developer tools categorization, and reliable installation-state detection. * Added handling for existing installations and validated installer outcomes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Allen Houchins <allenhouchins@mac.com> |
||
|
|
5fa8a0a9ea |
Add Microsoft .NET Desktop Runtime 10 as a Windows FMA (#50361)
**Related issue:** Resolves #50360 Adds Microsoft .NET Desktop Runtime 10 as a Windows Fleet-maintained app, from winget `Microsoft.DotNet.DesktopRuntime.10` (10.0.10, WiX burn bundle, x64). This closes the gap opened by HandBrake (#50323 / #50352). HandBrake requires the .NET **Desktop** Runtime and its install script now hard-fails without it, but Fleet had no FMA that could satisfy that — we ship `microsoft-dotnet-runtime-8`/`-10`, which are the *base* runtime, a different package with its own Add/Remove Programs entry. The customer's ManageEngine catalog also deploys the Desktop Runtime directly. ## Verification The winget manifest supplies `AppsAndFeaturesEntries`, and I confirmed each value against the real installer by extracting the burn bundle's registration data: ``` Microsoft Windows Desktop Runtime 10.0.10 (x64) Publisher="Microsoft Corporation" Version="10.0.10.50000" ``` - Installer SHA confirmed against a local download (`e82fc901…84d1`). - The `DisplayName` carries both version and architecture, so the exists query uses the same `LIKE 'Microsoft Windows Desktop Runtime 10.%' AND name LIKE '%(x64)'` shape as the existing base-runtime FMAs. - The bundle exposes several ProductCodes (the bundle plus its MSI components), which is exactly the shape the existing uninstall script already documents and handles. **`use_display_version_for_patch` is required here.** The registry `DisplayVersion` is `10.0.10.50000` but the winget package version is `10.0.10`. Without the flag the patch policy would compare against the marketing version and mis-order against what osquery reports. The generated patched query correctly compares against `10.0.10.50000`. ## Reuse rather than duplication - **Scripts:** this reuses `microsoft_dotnet_runtime_install.ps1` / `_uninstall.ps1` unchanged. The Desktop Runtime is the same burn bundle shape, and the uninstaller already resolves the bundle from the injected `$PACKAGE_ID` with a Package Cache fallback. Those scripts are already shared by the two base-runtime FMAs, so this follows the existing pattern rather than adding a near-identical copy. - **Icon:** reuses the existing `MicrosoftDotnetRuntime` component and its `.NET` artwork. The burn bundle only carries a 32×32 icon, so extracting one would have meant shipping a blurry upscale of the same logo. The new map key is `"microsoft .net desktop runtime"` (no version). Icon lookup is a loose *prefix* match — `s === key || s.startsWith(key + " ")` — so one key covers 10 and any future major, mirroring how `"microsoft .net runtime"` already serves both base-runtime FMAs. It is longer than that key, and lookup sorts longest-first, so the desktop runtime cannot be mis-matched to the base runtime icon. # Checklist for submitter - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Microsoft .NET Desktop Runtime 10 to the Windows software catalog. * Added support for installing and uninstalling the x64 desktop runtime, including version detection and reboot handling. * Added a dedicated Microsoft .NET Runtime icon for the software listing. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b35904ccfa |
Add HandBrake as a Windows FMA (#50352)
**Related issue:** Resolves #50323 Adds HandBrake as a Windows Fleet-maintained app, from winget `HandBrake.HandBrake` (1.11.2, NSIS, machine scope, x64). Found in a customer's ManageEngine ServiceDesk Plus Windows deployment catalog with no Fleet equivalent. Per @allenhouchins' guidance on the issue, the `.NET Desktop Runtime 10` prerequisite is handled in the install script with a clear failure message rather than left to fail silently after install. ## The prerequisite check HandBrake's own installer text states it plainly: > HandBrake requires Microsoft .NET *Desktop* Runtime 10. If this is not installed, you will be prompted to install it when you first run the app. The installer neither bundles nor installs that runtime, and the FMA ingester drops winget's `Dependencies` field. Without a check, Fleet would install HandBrake, register it in Add/Remove Programs, report success, and the user would hit a runtime prompt on first launch. The script now checks `%ProgramFiles%\dotnet\shared\Microsoft.WindowsDesktop.App\10.*` and exits 1 with an actionable message when it is absent. Two things worth reviewers' judgement: - **We fail rather than warn.** The vendor does prompt the user at first run, so an install without the runtime is recoverable by hand. I chose to fail because in a SYSTEM-context managed deployment an end-user runtime prompt is a support ticket, and a truthful "install failed, here is why" is more useful than a silently unusable app. Easy to soften to a warning + `Exit 0` if we would rather defer to the vendor's prompt. - **We ship no `.NET Desktop Runtime` FMA today.** Fleet has `microsoft-dotnet-runtime-8`/`-10`, but those are the *base* runtime, not the Desktop runtime — a separate package with its own ARP entry. So there is currently no in-product way to satisfy this prerequisite; an admin has to deploy the runtime by other means. That gap is worth its own issue. ## Identity — two traps, both from reading the vendor's NSIS script HandBrake's [`Installer64.nsi`](https://github.com/HandBrake/HandBrake/blob/master/win/CS/HandBrake.Nsis.Installer/Installer64.nsi) writes only four values: ```nsis Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" ... WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\HandBrake.exe" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" ``` 1. **`DisplayName` is version-suffixed** (`HandBrake 1.11.2`), so the exists query is a prefix match, not equality. 2. **No `Publisher` is ever written.** The default generated query would have pinned `publisher = 'The HandBrake Team'` from the winget locale manifest and matched nothing, forever, while the validator still passed. The exists query is overridden to drop the publisher clause. `UninstallString` is also an unquoted path containing spaces (`C:\Program Files\HandBrake\uninst.exe`), which the defensive parser in the uninstall script handles by capturing through `.exe`. The uninstall script additionally waits for the registry entry to disappear: a silent NSIS uninstaller returns before removal completes, so its exit code alone is not a reliable completion signal. ## Verification - Installer SHA confirmed against a local download (`6becb8e5…f8cd`); the URL is GitHub Releases, so none of the SourceForge trouble from #50322 applies. - **No icon work needed.** Reusing the catalog name `HandBrake` means this shares the existing `handbrake` icon with `handbrake-app/darwin`, and the two group together in the FMA library. # Checklist for submitter - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added HandBrake 1.11.2 to the Windows maintained applications catalog. * Added support for silent installation and uninstallation, including version detection and installer verification. * Added validation for the required .NET Desktop Runtime 10 prerequisite. * Added handling for installation completion, reboot-required results, and uninstall status reporting. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
194df72c90 |
Add Scribe as a Windows Fleet-maintained app (#50341)
**Related issue:** Resolves #50331 Adds Scribe as a Windows Fleet-maintained app, from winget `ColonyLabs.ScribeDesktopCapture` (6.7.23.0, MSI, machine scope, x64). Found in a customer's ManageEngine ServiceDesk Plus Windows deployment catalog with no Fleet equivalent. The simplest of this batch: a plain machine-scope MSI, so the install and upgrade-code uninstall scripts are auto-generated and no custom scripts are needed. ## Verification Identity read directly from the MSI Property table rather than inferred from winget: ``` ProductName Scribe Manufacturer Colony Labs, Inc ProductCode {87a51b1f-554d-414d-92a4-002a0916c91c} UpgradeCode {351EF756-3AF5-4117-8697-53AB61427040} ALLUSERS 2 ``` `Manufacturer` matches the winget locale `Publisher` exactly, so no `program_publisher` override is needed. `ALLUSERS=2` confirms per-machine install when elevated, which is how Fleet runs it. No `ARPSYSTEMCOMPONENT`, so this is a real product entry and not a bootstrapper. - Installer SHA confirmed against a local download of `Scribe_6.7.23.msi` (`41004c21…9b74`). - Icon extracted from the MSI's own `Scribe for Windows.exe` resource, not sourced from the web. ## Note on the name `Scribe` is a generic `DisplayName`, so the exists query pins `publisher = 'Colony Labs, Inc'` to avoid matching an unrelated product of the same name. This is **not** related to `timescribe/darwin`, which is already in the catalog — different vendor, different product. It deliberately does not share that catalog name or icon. # Checklist for submitter - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Scribe to the maintained applications catalog for Windows. * Added support for installing and uninstalling Scribe MSI packages, including version detection and installer metadata. * Added reliable installation handling with logging, elevated execution, restart control, and support for standard successful installer exit codes. * Added the Scribe app icon to the software interface. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Allen Houchins <allenhouchins@mac.com> |
||
|
|
da1947cd1f |
Add Paint.NET as a Windows Fleet-maintained app (#50340)
**Related issue:** Resolves #50330 Adds Paint.NET as a Windows Fleet-maintained app, from winget `dotPDN.PaintDotNet` (5.1.12, machine scope, x64). Found in a customer's ManageEngine ServiceDesk Plus Windows deployment catalog with no Fleet equivalent. ## Identity: winget's metadata is wrong here The winget locale manifest gives `PackageName: paint.net` (lowercase). The actual registry `DisplayName` is **`Paint.NET`**, read straight out of the MSI Property table: ``` ProductName Paint.NET Manufacturer dotPDN LLC UpgradeCode {04A40F40-A207-4B48-AED7-6AA532E43275} ALLUSERS 2 ``` There is no `ARPDISPLAYNAME` override and no `ARPSYSTEMCOMPONENT`, so `ProductName` is what lands in Add/Remove Programs. Taking the winget name at face value would have produced an exists query that silently never matches. `ALLUSERS=2` confirms it installs per-machine when run elevated, which is how Fleet runs it. ## This is a zip-wrapped installer Paint.NET publishes **only** `.zip` assets — there is no bare `.exe` or `.msi` on the vendor's GitHub releases. So this uses `installer_type: zip` with custom scripts, following the existing precedent of `agent-ransack`, `adobe-acrobat-pro`, `vnc-server`, and `vnc-viewer`. The install script extracts the archive and runs the nested installer with `/auto`, the vendor's silent switch per the manifest's `InstallerSwitches`. **Uninstall resolves the product from the UpgradeCode, not the ProductCode.** Paint.NET's ProductCode changes with every release, and the `.exe` and `.msi` variants register *different* ProductCodes. The UpgradeCode is stable — I verified it is identical across 5.1.10 and 5.1.12 — so `RelatedProducts` on it removes whichever variant is present. ## One thing reviewers may want to change The manifest offers six installers; three are x64/machine/zip and differ only by `NestedInstallerType` (`exe`, `wix`, `portable`). The ingester's selection loop takes the **first** match and breaks, so it picks the `.install.x64.exe` bootstrapper. The `.winmsi.x64.zip` variant is arguably the better FMA target — a plain MSI with predictable ARP behaviour — but there is no way to express "prefer this nested type" in the input today. Selecting it would need an ingester change, so I did not do it here. Worth a follow-up if we hit trouble with the bootstrapper. ## Verification - Zip SHA confirmed against a local download (`3cd861b5…c867`); archive contains exactly one file, `paint.net.5.1.12.install.x64.exe`. - Icon extracted from that installer's own 256px resource, not sourced from the web. - Icon map key is `"paint.net"`, the lowercased catalog name. The icon generator derives its key from the slug and produced `"paint dot net"`, which would never have matched at runtime — corrected by hand. # Checklist for submitter - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Paint.NET to the Windows software catalog. * Added support for installing, upgrading, detecting, and uninstalling Paint.NET. * Added Paint.NET branding and an icon to the software interface. * Included Paint.NET version 5.1.12 with verified download metadata and Productivity categorization. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Allen Houchins <allenhouchins@mac.com> |
||
|
|
2833401d12 |
Add Dante Controller as a macOS FMA (#50378)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #50377 # What this does Adds **Dante Controller** as a macOS Fleet-maintained app, from Homebrew cask [`dante-controller`](https://formulae.brew.sh/cask/dante-controller) (4.18.1.1). The cask ships a DMG containing `DanteController.pkg`, so `installer_format: "dmg"` with the standard mount-and-`installer -pkg` install script — the same shape as AdGuard, Adobe Acrobat Pro, and other existing DMG+pkg FMAs. Uninstall is fully generated from the cask's directives (2 `launchctl` services, 8 `pkgutil` receipt IDs, 3 zap trash paths) — no custom scripts. Windows is out of scope: no `Audinate.DanteController` winget package exists. See #50377 for the full feasibility analysis, including why Dante Virtual Soundcard was excluded on both platforms. ## Notes - **Identity verified against the real installer**, not cask metadata. Extracted `DanteController.pkg` from the DMG and read the app bundle's `Info.plist`: `CFBundleIdentifier` = `com.audinate.dante.DanteController`, confirming the input's `unique_identifier`. This needed checking because the cask's preferences path uses a *different* domain (`com.audinate.dante.controller`). - `CFBundleShortVersionString` and `CFBundleVersion` are both `4.18.1.1`, matching the cask version, so the exists/patched queries reconcile with osquery's `apps` table. - Installer SHA confirmed against a local download of the DMG (`4515cd12…38ff`) — matches both the cask and the generated output. - **Arch split.** The cask ships separate arm64/x64 DMGs; the brew API's top-level URL (which the ingester pins) is the arm64 build. This matches the behavior of the ~173 existing darwin FMAs with arch-specific URLs. - **`auto_updates true`.** Dante Updater self-patches, so hosts may drift ahead of the FMA-pinned version. - Ships a new catalog icon, extracted from the app bundle's own `.icns` — not sourced from the web. # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] FMA CI validator (install → detect → uninstall) **passes** on the macOS runner — [run 30682752130](https://github.com/fleetdm/fleet/actions/runs/30682752130/job/91322957939) (`Found app: 'Dante Controller' at /Applications/Dante Controller.app, Version: 4.18.1.1` → `All 1 apps were successfully validated.`) - [x] Generated output verified locally: installer SHA matches the cask, exists/patched queries checked against the app bundle's `Info.plist`, `apps.json` is valid JSON with a description filled in. - [x] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
31e3f51fa4 |
Update Fleet-maintained apps (#50406)
Automated ingestion of latest Fleet-maintained app data. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Updates** - Updated app catalogs with the latest releases for Actual, BoltAI, Bome Network, DBeaver Community, Dockside, ExifCleaner, Firefox Nightly, LinearMouse, Ocenaudio, OpenRCT2, Spokenly, Stats, WinDirStat, and Zed. - Added refreshed installer links, version detection, and integrity checks for the updated packages. - Updates cover macOS and Windows, including DBeaver Community and Zed on both platforms. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com> |
||
|
|
001b57cb9d |
Optimize memory usage in CVE chart cron job (#50385)
Resolves #50266. At production numbers the table looks like this - 20,691 CVEs × 83,000 hosts, ~268M raw (cve, host) rows (software + OS joins combined): ``` ┌─────────────────────────┬─────────────────────────┬───────────────────────┐ │ Shape of host IDs │ Old (map[string][]uint) │ New (roaring bitmaps) │ ├─────────────────────────┼─────────────────────────┼───────────────────────┤ │ Dense (contiguous runs) │ 2,479 MB │ 4.5 MB │ ├─────────────────────────┼─────────────────────────┼───────────────────────┤ │ Sparse (random) │ 2,488 MB │ 282 MB │ └─────────────────────────┴─────────────────────────┴───────────────────────┘ ``` A few things worth noting about how these map to your real data: - The old cost is shape-independent: ~2.5 GB retained just for the result map (268M rows × 8 bytes plus append slack), and the peak during collection is higher still because append doubling leaves garbage behind. That's the number that was blowing up the cron. - The new sparse figure is an overstated worst case. Your 268M rows include duplicates — multiple vulnerable software rows per host for the same CVE (the multi-kernel case) and overlap between the software and OS joins. The old code retained every raw row; the bitmap dedupes on Add, so it's bounded by unique pairs, and real fleets with AUTO_INCREMENT host IDs sit much closer to the dense row than the sparse one. - The new representation also has a hard ceiling the old one doesn't: a roaring bitmap over 83k host IDs maxes out around 16 KB per CVE regardless of contents, so even a pathological dataset caps at ~330 MB for all 20,691 CVEs — versus the old form growing linearly with join rows, unbounded. TL;DR: At scale the change is roughly a 550× reduction in the realistic (dense) case, and at minimum ~9× in the theoretical worst case. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [X] Added/updated automated tests - [X] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [X] Confirmed that the fix is not expected to adversely impact load test results - [X] Alerted the release DRI if additional load testing is needed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Performance** - Reduced memory usage for CVE chart data collection. - Improved efficiency when processing large CVE and affected-host datasets. - **Bug Fixes** - Preserved correct CVE filtering, duplicate-host handling, disabled-fleet exclusions, and empty-result behavior. - Added coverage for CVEs sourced from both software and operating-system data. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1ed4b5c89a |
Update Evernote macOS version to 11.27.5 (#50395)
**Related issue:** Resolves # # Checklist for submitter - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [ ] QA'd all new/changed functionality manually --- ## Summary Updates the Evernote macOS application version from 11.20.2 to 11.27.5 in the maintained apps configuration. This change updates both the version identifier and the corresponding SQL query that checks for patched versions. ## Changes - Updated `ee/maintained-apps/outputs/evernote/darwin.json`: - Version bumped from `11.20.2` to `11.27.5` - Updated the `patched` query to check against the new version `11.27.5` instead of `11.20.2` This ensures that Fleet's vulnerability detection and patching workflows correctly identify whether Evernote on macOS is up-to-date with the latest version. https://claude.ai/code/session_01F85XismGHNQj3ZEn7zPNpD Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
352d1f9070 |
Unfreeze NVIDIA GeForce NOW (macOS) (#50392)
Automated unfreeze probe. Removes `"frozen": true` and regenerates the output manifest so `test-fma-darwin-pr-only` can validate `nvidia-geforce-now/darwin` at its current upstream version. Frozen since: 2026-06-15 (#47645, automated FMA update run) Version: 2.0.85.133 -> 2.0.87.131 Upstream Homebrew cask reports 2.0.87.131, which is newer than the pinned 2.0.85.133, so this is a genuine forward bump rather than a regression. Note: the regenerated manifest also picks up a newer `uninstall_script_ref`, because the frozen output missed the script-template updates that landed on main while it was pinned. Draft until validation reports. Merge only if the FMA checks are green and the validate shard actually ran for this slug. **Related issue:** NA # Checklist for submitter - [x] QA'd all new/changed functionality manually — pending CI validation, see above. --- _Generated by [Claude Code](https://claude.ai/code/session_01F3HnFWdGjLMbqHdxWZXBAo)_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
570ab3e4ce |
Update Fleet-maintained apps (#50394)
Automated ingestion of latest Fleet-maintained app data. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Updates** - Updated release metadata for 24 maintained applications across macOS and Windows. - Added the latest available versions of apps including 3DF Zephyr Free, BoltAI, ChatGPT, Firefox Nightly, Microsoft Edge, Shotcut, Telegram, Teleport Connect, Typora, and Zappy. - Refreshed download links and verification checksums to ensure installations use the correct release packages. - Updated Teleport Suite’s macOS installation package to match version 18.10.3. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com> |
||
|
|
f7ffc07062 |
Improved software ingestion performance (#50354)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #50305 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [x] Alerted the release DRI if additional load testing is needed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Performance Improvements** * Improved software ingestion performance by optimizing software title lookups. * Reduced unnecessary database scanning while preserving matching for bundle identifiers, names, and Windows upgrade codes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1dafb29265 |
Bump frozen Adobe Acrobat Pro (macOS) to installer-delivered 26.001.21691 (#50370)
Automated unfreeze probe, revised after validation. The full unfreeze failed: the Homebrew cask reports 26.001.21771 (tracking Adobe's updater manifest), but Adobe's version-less web installer DMG still delivers 26.001.21691, so the validator's post-install osquery check failed at 26.001.21771 — the same installer-lags-manifest behavior that caused the original freeze. This PR instead pins the output manifest to 26.001.21691 (the version the DMG actually installs, confirmed by the 2026-08-01 validator run) and keeps `"frozen": true` so the nightly ingester doesn't bump it back to the cask version. Frozen since: 2025-12-02 (#36609 — "product updated but installer was not, causing validation issues") Version: 26.001.21662 -> 26.001.21691 (cask claims 26.001.21771; installer not updated yet) Note: the regenerated manifest also picks up a newer `uninstall_script_ref`, because the frozen output missed the script-template updates that landed on main while it was pinned. Draft until validation reports. Merge only if the FMA checks are green and the validate shard actually ran for this slug. **Related issue:** NA # Checklist for submitter - [x] QA'd all new/changed functionality manually — pending CI validation, see above. --- _Generated by [Claude Code](https://claude.ai/code/session_01EBxhs5D65LRUwCEJejBLJH)_ --------- Co-authored-by: allenhouchins <allen@fleetdm.com> |
||
|
|
24b24ae699 |
Unfreeze Logi Options+ (macOS) (#50372)
Automated unfreeze probe. Removes `"frozen": true` and regenerates the output manifest so `test-fma-darwin-pr-only` can validate `logi-options+/darwin` at its current upstream version. Frozen since: 2026-04-03 (#42984, automated FMA update run) Version: 2.4.903778 -> 2.5.926888 Note: the regenerated manifest also picks up a newer `uninstall_script_ref`, because the frozen output missed the script-template updates that landed on main while it was pinned. Draft until validation reports. Merge only if the FMA checks are green and the validate shard actually ran for this slug. **Related issue:** NA # Checklist for submitter - [x] QA'd all new/changed functionality manually — pending CI validation, see above. --- _Generated by [Claude Code](https://claude.ai/code/session_01EBxhs5D65LRUwCEJejBLJH)_ Co-authored-by: allenhouchins <allen@fleetdm.com> |
||
|
|
2747d82328 |
Unfreeze Keeper Password Manager (macOS) (#50371)
Automated unfreeze probe. Removes `"frozen": true` and regenerates the output manifest so `test-fma-darwin-pr-only` can validate `keeper-password-manager/darwin` at its current upstream version. Frozen since: 2026-02-10 (#39623, automated FMA update run) Version: 18.2.1 -> 18.5.0 Draft until validation reports. Merge only if the FMA checks are green and the validate shard actually ran for this slug. **Related issue:** NA # Checklist for submitter - [x] QA'd all new/changed functionality manually — pending CI validation, see above. --- _Generated by [Claude Code](https://claude.ai/code/session_01EBxhs5D65LRUwCEJejBLJH)_ Co-authored-by: allenhouchins <allen@fleetdm.com> |
||
|
|
3d29b69eb6 |
Update Fleet-maintained apps (#50369)
Automated ingestion of latest Fleet-maintained app data. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Updates** * Updated Windows packages for AWS CLI, AWS SAM CLI, Brave Browser, DataGrip, and Postman to their latest versions. * Updated macOS packages for Fellow, Microsoft Edge, Postman, and Typora. * Refreshed installer links, version checks, and checksums to support reliable downloads and verification. * Updated versions include AWS CLI 2.36.14, AWS SAM CLI 1.165.0, Brave 151.1.93.129, DataGrip 2026.2.2, Fellow 5.7.2, Edge 151.0.4129.59, Postman 12.21.10, and Typora 1.14.8. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com> |
||
|
|
45abf8c9ad |
Add software installer upload/download progress to GitOps runs (#50250)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45728 Changes: - Adds a new redis key to keep track of downloaded packages. It starts out with an empty list and gets filled with each download. Each update writes the entire struct at once to the key. - Adds logging in the fleetctl gitops client to show which packages were downloaded - Fixes the categories key potentially expiring # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - ❌ Timeouts are implemented and retries are limited to avoid infinite loops - Right now the batch will write the whole slice of all packages to a single redis key for every package in the loop. Looks like performance is acceptable for now (500 packages), but maybe this will need to be limited. - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features - Added per-package software download progress in fleetctl GitOps. - Progress now reports downloading, completed, skipped, and failed packages during real and dry runs. - Installation output now distinguishes applying and applied stages. ## Bug Fixes - Improved download error messages and cached-package handling. - Prevented duplicate progress messages and ensured tracking issues do not interrupt successful software batches. ## Tests - Expanded coverage for progress reporting, failures, dry runs, package types, and authorization scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f082237518 |
Add Lenovo System Update as a Windows FMA (#50339)
**Related issue:** Resolves #50324 Adds Lenovo System Update as a Windows Fleet-maintained app, from winget `Lenovo.SystemUpdate` (5.08.03.59, Inno Setup, machine scope, x86-only). Found in a customer's ManageEngine ServiceDesk Plus Windows deployment catalog with no Fleet equivalent. Distinct from `lenovo-dock-manager/windows`, which we already ship. ## Verification - Installer SHA confirmed against a local download of `system_update_5.08.03.59.exe` (`e66794dc…53e0d`), served from `download.lenovo.com` — a pinned vendor URL, so none of the SourceForge mirror trouble from #50322 applies. - Registry `DisplayName` determined offline as a bare `Lenovo System Update`: `innoextract --info` reports `AppVerName` when set and falls back to `AppName`, and Inno writes that same value to `DisplayName`. This installer reports no version suffix, unlike CrystalDiskMark in #50322 which reports `"CrystalDiskMark 9.0.3"`. That is why the exists query here is an exact match rather than a prefix. - Icon extracted from the installer's own `Tvsukernel.exe` resource, not sourced from the web. - The uninstall script targets the Inno registry key directly via the manifest's `ProductCode` (`TVSU_is1` — a key name, not a GUID) using the `$PACKAGE_ID` substitution, rather than string-matching `DisplayName`. ## Two things reviewers should weigh in on **1. The exists query deliberately omits the publisher.** House style usually pins `publisher = '...'`, but the registry `Publisher` is not determinable offline for Inno, and the validator's log prints only the name and version — so I could not confirm it. A wrong publisher makes the exists query silently never match while the validator still passes, which is the exact failure mode called out in the FMA docs. `name = 'Lenovo System Update'` is unambiguous on its own. Happy to add the publisher clause if someone can confirm the registry value on a real Lenovo host. **2. This may not be validatable on the CI runner.** Lenovo System Update is a vendor tool for Lenovo hardware, and the runner is a generic Azure VM. If the installer refuses to run on non-Lenovo hardware this will fail the way Dell Display and Peripheral Manager did in #50020 (which was dropped for exactly this reason, and is being retried on a client-OS runner in #50313). Leaving this in draft until the validator reports. # Checklist for submitter - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Lenovo System Update to the maintained Windows software catalog. * Added support for silent installation and uninstallation, including status verification and reboot-success handling. * Added Lenovo System Update metadata, download information, categorization, and application icon. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
bf26771ff1 | Delete articles/seamless-mdm-migration.md (#49029) | ||
|
|
5370bd2283 |
Update rest-api.md list hosts targeted in batch script (#50291)
Adds required to `status` Resolves #50290 |
||
|
|
ba7168f54b |
Website: update contact source (#50356)
Changes: - Updated the contact source used for contacts created by the deliver-webinar-access-request action (Webinar » Website - Gated video) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Webinar access requests are now categorized as “Website - Gated video” in Salesforce. - Updated contact and account records use the new source label consistently. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b22477ed26 | GTM ops SLAs (#50351) | ||
|
|
eac1f4d326 |
Update Fleet-maintained apps (#50347)
Automated ingestion of latest Fleet-maintained app data. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Updates** - Refreshed available versions and verified download information for 30 maintained applications across macOS and Windows. - Updated Adobe Acrobat Reader, Beekeeper Studio, BoltAI, ChatWise, CMake, Cursor, Dataflare, Eclipse Temurin JDK/JRE, Firefox Developer Edition/Nightly, iMazing, Krita, Mockoon, Netron, Notesnook, pgAdmin 4, Podman Desktop, Postman, Raycast, Setapp, Shotcut, Spokenly, Superhuman, and Typora. - Installation and uninstallation behavior remains unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com> |
||
|
|
46aed2da6b |
Website: Update software-management.ejs so that we mention the 1000+ apps in the catalog (#50345)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated the software management page to link to Fleet’s software catalog. * Clarified that the catalog includes 1,000+ apps. * Noted automatic updates across macOS, Windows, and additional platforms. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
68c467a280 |
Update territories (#50349)
Centralize territory spreadsheet |
||
|
|
2fd2a02e2d |
Split MDM platform helpers by Android semantics (#50185)
**Related issue:** Resolves #46118 |
||
|
|
cb44e287f2 | Fix high-severity CodeQL and Scorecard code scanning alerts (#50333) | ||
|
|
0dc8c382c5 |
Add 'linux' as platform for labels (#50270)
Resolves #44088. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [X] Added/updated automated tests - [X] QA'd all new/changed functionality manually. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Linux as a label platform option. * Linux labels now apply across supported distributions, including Ubuntu, Debian, RHEL, CentOS, and generic Linux hosts. * Updated platform names for improved clarity and consistency. * **Bug Fixes** * Improved platform matching so Linux labels apply consistently to compatible hosts. * Removed the obsolete Zorin platform option. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
25d4120857 | Bump postcss from 8.5.10 to 8.5.23 in /ee/fleetd-chrome (#49906) | ||
|
|
07457475b6 |
fleet-mcp: align Render blueprint with the deployed service (#50317)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #43544 This blueprint has drifted from the deployed `fleet-mcp` service in two ways. `FLEET_LIVE_QUERY_REST_PERIOD=25s` is too short for a hosted service aimed at a whole fleet: enough targeted hosts are asleep or offline that `run_live_query` returns a near-empty result before they check in, reading as "no data" rather than "still waiting." And `plan: starter` disagrees with the Standard instance the service actually runs on, so a blueprint sync risked silently downgrading it. Both fields carry literal values, making them blueprint-managed, so a dashboard override would be reverted on the next sync. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Configuration** * Updated the hosted Fleet deployment to use the standard plan. * Increased the live-query interval to 15 minutes. * Clarified configuration guidance for Fleet server alignment and hosted Fleet behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d628cb338b | Bump Go and npm dependencies to resolve high-severity code scanning alerts (#50314) | ||
|
|
45fa8be602 |
Website: add press logos to /ai (#50281)
Adds press logos below "The road to AI in IT" report card. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** NA # Checklist for submitter - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a press coverage section to the AI in IT page. * Displays logos for Apple World Today, Cybersecurity Insiders, and IT Brief, linking to related articles. * Added responsive layouts for desktop, tablet, and mobile screens. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
773c162a50 |
Configuration profiles guide: document label scoping (#49494)
## Summary - Adds a **Target hosts with labels** section to the Configuration profiles guide (`articles/custom-os-settings.md`). - Documents the three targeting modes (**Include all**, **Include any**, **Exclude any**), that only one can be used per profile, and that profiles are inherently platform-scoped (no label needed to keep a profile on the right platform). - Shows the flow across Fleet UI, GitOps (`labels_include_all` / `labels_include_any` / `labels_exclude_any`, with a YAML example), and the Fleet API. - Bumps `publishedOn` to the current date. Author unchanged. ## Why Prospects and customers hit this gap when trying to scope a profile to a subset of hosts: the label include/exclude syntax lived only in the YAML and REST API reference docs, with no walkthrough in the guide. ## Test plan - [ ] Article renders correctly on the fleetdm.com preview - [ ] All links resolve - [ ] Meta tags present with updated `publishedOn` date - [ ] Style guide compliance verified |
||
|
|
c3474e7a50 |
Standardize API key label casing (#48978)
Update the Manage Users API key display label from "API Key" to "API key" for consistent capitalization in the UI. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] Timeouts are implemented and retries are limited to avoid infinite loops - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [ ] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [ ] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [ ] Confirmed that the fix is not expected to adversely impact load test results - [ ] Alerted the release DRI if additional load testing is needed ## Database migrations - [ ] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [ ] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [ ] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). ## New Fleet configuration settings - [ ] Setting(s) is/are explicitly excluded from GitOps If you didn't check the box above, follow this checklist for GitOps-enabled settings: - [ ] Verified that the setting is exported via `fleetctl generate-gitops` - [ ] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [ ] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [ ] Verified that any relevant UI is disabled when GitOps mode is enabled ## fleetd/orbit/Fleet Desktop - [ ] Verified compatibility with the latest released version of Fleet (see [Must rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md)) - [ ] If the change applies to only one platform, confirmed that `runtime.GOOS` is used as needed to isolate changes - [ ] Verified that fleetd runs on macOS, Linux and Windows - [ ] Verified auto-update works from the released version of component to the new version (see [tools/tuf/test](../tools/tuf/test/README.md)) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Style** * Updated the API key label wording for consistency in the admin user page. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fc2b0eada1 |
Update link for installing custom app guide (#50194)
- Better link |
||
|
|
70a802360c | Frontend: document form validation rules and error copy register (#49041) | ||
|
|
f2a6dd04ef |
Fix "ID" capitalization (#49130)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Corrected the capitalization of the “Android Enterprise ID” tooltip label in Android MDM settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b452a5a5f3 |
Add exclusions for libexpat on fleetdm/wix (#50301)
Fixes: https://github.com/fleetdm/fleet/actions/runs/30610975232 New run: https://github.com/fleetdm/fleet/actions/runs/30632404621. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Security** * Added vulnerability assessments for five CVEs affecting a transitive XML-parsing dependency. * Recorded that the application is not affected because vulnerable XML processing cannot be controlled by an attacker. * Updated security transparency records with supporting applicability justifications. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7837b8ec8f |
Add AOMEI Backupper Standard as a Windows Fleet-maintained app (#50021)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** #50020 # What this does Adds **AOMEI Backupper Standard** as a Windows Fleet-maintained app. One of the 11 apps split out of #48501 that failed the FMA validator; #50016 shipped the 6 that passed. ## Why it was failing Install and detection were already fine on the SYSTEM-context Windows runner — the validator installed it and osquery found `AOMEI Backupper` 8.4.0. **Uninstall** was the failure: ``` ERROR msg="Error uninstalling app: exit status 1" app="AOMEI Backupper Standard" ERROR msg="Output: Uninstaller for 'AOMEI Backupper Standard' not found." ``` AOMEI unified the ARP `DisplayName` across editions around v7.4 — the registry entry reads `AOMEI Backupper`, with no `Standard` suffix. The uninstall script searched for the catalog name and matched nothing. `unique_identifier` was already corrected to `AOMEI Backupper`; this fixes the uninstall script to match. ## Notes - **Edition matching.** `AOMEI Backupper` also matches the paid Pro/Workstation/Server editions — AOMEI shares the DisplayName across editions and no registry value distinguishes them. Detecting the free edition specifically isn't possible from inventory. - **Non-pinned installer URL.** `https://www2.aomeisoftware.com/download/adb/AOMEIBackupperStd.exe` is a "latest" URL, so the pinned SHA will drift when AOMEI ships a new build until the FMA auto-update bumps it. - x86-only installer, so it lands in `C:\Program Files (x86)`. The validator's "no changes detected in `C:\Program Files`" line is an expected warning, not a failure. # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops ## Testing - [x] FMA CI validator (install → detect → uninstall) **passes** on the SYSTEM-context Windows runner — [run 30383902487](https://github.com/fleetdm/fleet/actions/runs/30383902487) (`All checks passed`) - [x] Generated output verified locally: manifest SHA matches the winget manifest, exists/patched queries reviewed for name + publisher correctness, `apps.json` is valid JSON with a description filled in. - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added **AOMEI Backupper Standard** (version **8.4.0.0.0**) to the Windows software catalog, including verified installer download (SHA-256). - Introduced dedicated silent **install** and **uninstall** support, with version gating and idempotent uninstall behavior when the app isn’t present. - Added a **new software icon** and updated the listing so the correct icon now appears for this product. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Allen Houchins <allenhouchins@mac.com> |
||
|
|
43bff98998 |
Add Gpg4win as a Windows FMA (#50026)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** #50020 # What this does Adds **Gpg4win** as a Windows Fleet-maintained app. One of the 11 apps split out of #48501 that failed the FMA validator; #50016 shipped the 6 that passed. ## Why it was failing Same root cause as GNU Privacy Guard (#50025) — Gpg4win bundles GnuPG. The install worked; the *script* never returned: ``` 20:30:53 INFO msg="Executing install script..." app=Gpg4win 20:40:53 ERROR msg="Error executing install script: exit status 1" # exactly 10:00 later 20:40:53 INFO msg="New application detected at: C:\Program Files\Gpg4win" ``` Ten minutes on the nose is the validator's `executeScript` timeout. **`Start-Process -Wait` waits for the process *and all of its descendants***, and Gpg4win leaves `gpg-agent`, `dirmngr`, `keyboxd` and `scdaemon` resident (plus Kleopatra), so `-Wait` never returns. The same run left `gpg4win-5.0.2.exe` locked in the validator's temp dir, confirming a live child process. The install script now follows the pattern already established by [`ollama_install.ps1`](ee/maintained-apps/inputs/winget/scripts/ollama_install.ps1): start with `-PassThru` (no `-Wait`), wait on the installer process alone with a 7-minute cap (below the caller's 10-minute script budget), poll for the Add/Remove Programs entry, then stop the leftovers. The uninstall script stops those processes up front (they hold file locks that make the uninstall fail), uses NSIS's `_?=<dir>` switch so the uninstaller runs in place rather than relaunching itself detached from `%TEMP%`, and polls the ARP key to confirm removal. ## Notes - **Versioned ARP name.** The registry `DisplayName` is `Gpg4win (5.0.2)`, so the input uses `fuzzy_match_name` and the exists query is `name LIKE 'Gpg4win %'`. The uninstall script matches the same prefix. - x86-only installer. Publisher `The Gpg4win Project`. - Ships a new catalog icon and website asset. # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops ## Testing - [x] FMA CI validator (install → detect → uninstall) **passes** on the SYSTEM-context Windows runner — [run 30384125610](https://github.com/fleetdm/fleet/actions/runs/30384125610) (`All checks passed`) - [x] Generated output verified locally: manifest SHA matches the winget manifest, exists/patched queries reviewed for name + publisher correctness, `apps.json` is valid JSON with a description filled in. - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added Gpg4win as a supported Windows application. - Added Gpg4win version 5.0.2 with Security categorization. - Added a Gpg4win icon to the software interface. - Introduced silent install and uninstall support with process cleanup, timeouts, and registry-based verification to confirm install/removal outcomes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |