You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Have you checked that there aren't other open pull requests for the same changes?
Have you tested that the committed code can be executed without errors?
Have you confirmed that this issue is caused by UniGetUI itself, and not by the package manager or the package involved?
If the same issue can be reproduced outside UniGetUI with the relevant package manager or with the package itself, please report it there first. UniGetUI should only be used to track issues that are specific to UniGetUI's behavior or integration.
Aligns the Devolutions Agent package broker integration with the broker's request validation, and makes broker outcomes understandable to the user.
Send resolved package versions to the package broker (BrokerRequestBuilder)
The broker evaluates version conditions against the version in the request, so UniGetUI now sends the version it already knows:
the version the user selected;
otherwise the listed version, for an install;
otherwise the target version, for an update.
No version is sent:
for uninstalls;
for Scoop and vcpkg;
for pre-release installs;
for managers without broker version rules;
when the known version would not be accepted for that manager.
A version saved for installs never blocks an update or an uninstall.
Fields the broker refuses for a role or a manager are left out:
pre-release, hash-check skip and architecture for uninstalls;
architecture for Scoop updates;
the source URL for managers that identify their source by name;
blank custom parameters.
Scope and architecture are sent when chosen.
The PowerShell -AllowClobber retry is not sent, because the broker accepts no PowerShell parameter. The command conflict is reported instead.
"Update all" already creates one operation per package.
elevation-dependent rules: per-user managers, and pre/post commands on elevated or machine-scope operations.
The broker stays the authority. A request it would reject is not sent, and the failure lists every problem.
The installation options dialog previews the same problems live: it dry-runs the request builder after applying the manager's elevation requirements. Changes are announced through the shared accessibility live region.
WinGet custom installer arguments
The dialog warns when --override/--custom, or any custom argument on an elevated operation, goes through the Devolutions Agent. These arguments reach an installer running with administrator rights, and the organization's policy may block them.
validation failures, with the broker's message and details;
paused (no valid policy) versus busy (after the client's retries);
Forbidden, keeping the broker's reason (for example policy validity);
administrator required;
request too large, unsupported option, timeout, invalid response.
The capabilities request is made up front. If the broker refuses this client (401/403, for example an unsigned build), the operation explains why and raises BrokerUnavailable, which now carries the specific title.
In the policy editor, a save refused because an elevated administrator is required, or because the client is not authorized, gets a specific message.
The pipe transport, server verification and retry handling are unchanged. New strings were added to lang_en.json only.
Validation (from src/):
dotnet test UniGetUI.PackageEngine.Tests/UniGetUI.PackageEngine.Tests.csproj /p:Platform=x64 --filter "FullyQualifiedName~Broker|FullyQualifiedName~PackageOperationsTests": passed (448 for the Windows target, 436 for net10.0).
dotnet test UniGetUI.PackageEngine.Tests/UniGetUI.PackageEngine.Tests.csproj /p:Platform=x64 (full): passed for net10.0. On the Windows target, only PowerShellOperationLauncherTests.TheScopeRetryMarkersSurviveTheLauncher failed; it also fails on main in my environment.
dotnet test UniGetUI.Tests/UniGetUI.Tests.csproj /p:Platform=x64: passed (553).
dotnet format whitespace and dotnet format style UniGetUI.Windows.slnx --no-restore --verify-no-changes on the changed files: passed.
Send the resolved package version to the package broker: the version the
user selected, else the listed version for installs and the target version
for updates, omitting versions the broker does not accept for the manager
and never sending one for uninstalls or for managers that pin their own.
Validate package broker request fields before sending them (install
location, versions, package identifiers, source names, custom parameters,
architecture) and explain each problem in the operation failure and in the
installation options dialog.
Warn in the installation options dialog when WinGet custom installer
arguments go through the Devolutions Agent.
Explain package broker policy decisions and errors: show the denying rule
and reason, validation messages, paused and busy states, and authorization
failures, including when the broker refuses the capabilities request and
when a policy change requires an elevated administrator.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…eration
Share the brokered install location resolver with the installation options dialog, validate versions of managers with broker version rules only against those rules, and bound Bun version length.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
These live results can be overwritten by an older refresh. Every edit starts a fire-and-forget RefreshCommandPreviewAsync, and each call performs multiple asynchronous loads; if a previous call completes after a later one, it assigns validation text for stale options and may leave the dialog showing or hiding the wrong broker warning. Add a monotonically increasing refresh generation or cancellation token and only publish results from the latest invocation.
Include metadata-driven elevation in custom argument warnings
This warning only treats the checkbox value as elevation, but the broker path also elevates when WinGet metadata sets package.OverridenOptions.RunAsAdministrator in ApplyElevationRequirements (PackageOperations.cs:392-400, WinGetPkgOperationHelper.cs:217-275). Because command preview applies that metadata before this method runs, an installer that automatically requires elevation can still receive arbitrary custom arguments without the promised warning. Match the same elevation predicate used by the operation.
Restrict pre-release suppression to install operations
Pre-release suppression currently applies to updates as well as installs. InstallOptions.PreRelease can remain enabled on an update, so this returns null instead of sending the known NewVersionString, contrary to the intended exception for pre-release installs only. Restrict this branch to OperationType.Install.
Preserve authorization failure details in broker error dialogs
The new authorization failure is raised through BrokerUnavailable, whose only production subscriber still opens SimpleErrorDialog with the hard-coded title “Agent broker unavailable” (AvaloniaBootstrapper.cs:140-150). For a 401/403 the agent is available but rejecting this client, so the immediate user-facing dialog loses the specific authorization title computed above and remains misleading. Carry the full failure description (or otherwise pass its title) through this notification path.
Publish only the latest options-dialog broker check, use the operation's elevation predicate for the WinGet custom arguments warning, keep the target version for pre-release updates, and pass the specific failure title to the broker notification dialog.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Addressed the four 'previously missed' review notes in 1e2b9af: (1) the options dialog publishes only the latest broker check (refresh generation); (2) the WinGet custom-arguments warning uses the operation's elevation predicate (package requirement or checkbox, respecting ProhibitElevation); (3) the pre-release exception now only applies to installs, so updates keep their target version; (4) BrokerUnavailable now carries the full title and message, so a refused client shows the authorization title instead of 'Agent broker unavailable'.
BrokerPaused is mapped to HTTP 503 by the broker server, including the “active policy is unavailable” path. Because this branch also accepts ErrorCode.BrokerPaused, a real paused response is always described as “busy” and the BrokerPaused switch case below is unreachable; the 409 test does not match the wire contract. Reserve this branch for an unstructured 503 so structured paused responses get the paused explanation.
Validate or strip source URLs before broker submission
This validates only the source name, but BrokerRequestBuilder still forwards package.Source.Url. The broker rejects non-null source URLs for Chocolatey, npm, pip, PowerShell, and PowerShell 7, while UniGetUI's default sources for all five managers have URLs, so normal requests for these managers still pass this preflight and are then rejected by the broker. Build a name-only RequestSource for those managers or mirror the broker's URL rules before submission.
Validate PowerShell custom and broker-added parameters
PowerShell custom parameters still bypass this preflight even though the broker's PowerShell command builder rejects every non-empty custom parameter. This also affects the automatic -AllowClobber retry because BrokerRequestBuilder appends it after Validate returns, so that retry is sent and rejected. Align the PowerShell parameter mapping with the broker and ensure broker-added parameters are validated too.
Omit the source URL for managers that identify sources by name, validate the custom parameters that are actually sent (including the PowerShell AllowClobber retry) and refuse them for managers that accept none, and tell a busy broker apart from a paused one.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Addressed the three 'previously missed' notes in 75688c3: (1) a structured BrokerPaused response is described as paused unless its message reports the busy state, and only an unstructured 503 is treated as busy; tests now use the 503 wire status. (2) The source URL is omitted for managers that identify their source by name (Chocolatey, PowerShell, PowerShell 7, npm, Bun, Cargo, .NET Tool, pip, vcpkg). This also covers the pip change from #5466, merged from main. (3) The custom parameters that are actually sent, including the AllowClobber retry, are validated, and they are refused with an explanation for managers whose broker command builder accepts none.
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🟡 Changes recommended
The asynchronous broker notices do not use the established accessibility announcement service, and validator documentation conflicts with its behavior.
Route changed broker validation problems (assertive) and custom-argument warnings (polite) through AccessibilityAnnouncementService, and describe the managers that refuse custom parameters as an explicit list.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🔵 Needs a closer look
Request validation still permits broker-rejected identifiers, parameters, and Bun versions, while irrelevant saved versions can block updates or uninstalls.
ResolveVersion omits versions for updates and uninstalls, but Build still validates options.Version before calling it. A saved install-only value such as /latest therefore prevents an uninstall/update even though that value would not be sent. Gate both earlier version guards on role == Install, or validate only the resolved version.
This manager-specific switch omits the broker API's universal PackageIdentifier constraints. For example, a WinGet identifier longer than 256 characters passes IsOptionSafeIdentifier and this method, but the broker rejects it while deserializing the request; non-ASCII identifiers have the same gap for several managers. Apply the API-wide length/ASCII allowlist before the manager-specific rules so these requests fail locally with the promised explanation.
The broker's custom-parameter type requires each value to contain 1–512 characters, but this validation only checks manager-specific content. A WinGet or Scoop argument longer than 512 characters therefore passes locally and is sent, only to be rejected during broker deserialization. Enforce the shared bounds before the manager-specific checks (and either omit or reject empty entries).
This regex is looser than the broker's SemVer parser: it accepts numeric prerelease identifiers with leading zeroes (for example 1.2.3-01) and arbitrarily large numeric components, both of which the broker rejects. As a result, Bun requests advertised as valid locally still fail remotely. Use SemVer validation with the same canonical numeric rules and bounds as the broker.
Check package identifiers, custom parameters and versions against the API-wide length and character rules, use canonical SemVer rules for Bun, drop empty custom parameters, and ignore a saved install version for updates and uninstalls.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Addressed the four 'previously missed' notes in b26f7c3: (1) the saved version is only checked, and only sent, for installs, so a stale value can no longer block an update or an uninstall; (2) package identifiers are checked against the broker API's universal 256-byte length and ASCII character set before the manager-specific rules; (3) custom parameters are bounded to 512 bytes, and empty entries are dropped from the request; (4) Bun versions follow canonical SemVer: no leading zeros in numeric pre-release identifiers, and release components must fit 64 bits.
This validation turns PowerShell's automatic CommandAlreadyAvailable recovery into a deterministic second failure. PowerShellPkgOperationHelper.GetResult sets the internal PowerShell_AllowClobber flag and returns AutoRetry; the next broker attempt appends -AllowClobber above, then fails here because PowerShell rejects all custom parameters. The resulting message tells users to remove an argument that is not present in their installation options. Brokered execution should suppress this unsupported retry or surface the original command-conflict failure directly.
Align UTF-8 byte limit enforcement with error message
The limit is enforced in UTF-8 bytes but reported as characters. For example, a 300-character CJK argument exceeds 512 bytes and produces the false claim that it is longer than 512 characters. Either compare parameter.Length if the broker limit is character-based, or change the localized message to say UTF-8 bytes.
The broker accepts no PowerShell custom parameter, so the AllowClobber retry is no longer sent: the operation explains the command conflict instead. The options dialog orders whole refreshes (command preview included), and length limits are reported in bytes, as the broker counts them.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Addressed the two 'previously missed' notes in 1377556. (1) The PowerShell AllowClobber retry is no longer sent through the broker: when that retry comes up, the operation reports the command conflict and explains that -AllowClobber can't be used through the Devolutions Agent. (2) Length limits are now reported in bytes, matching how the broker counts them.
The dialog validates before applying the manager-specific elevation requirements that the real broker path applies at PackageOperations.cs:402-410. For a WinGet package whose installer metadata forces elevation, FindProblems therefore misses elevated pre/post-command rejection, and the later custom-argument warning also sees runsElevated == false; the operation then rejects options the dialog showed as acceptable. Apply the same elevation-requirement step before running the preview validation (without blocking the UI thread).
Addressed the 'previously missed' note about elevation in 72852d0. The live dialog check now calls the manager's ApplyElevationRequirements off the UI thread before running FindProblems, as the brokered operation does. A WinGet installer that must run elevated is therefore checked, and warned about, as elevated.
The broker builder drops whitespace-only custom parameters, but this warning counts them and tells the user they will be passed to WinGet. Inherited or deserialized options containing only blank entries therefore show a false elevated-arguments warning. Use the same IsNullOrWhiteSpace filter as the request builder.
Test depends on unisolated ProhibitElevation setting
This assertion depends on the developer/runner setting ProhibitElevation being false. RequestsElevation deliberately ignores RunAsAdministrator when that setting is enabled (BrokerRequestValidator.cs:176-178), and this test class does not isolate or override the settings store, so Build succeeds instead of throwing under that valid configuration. Run this class with the isolated-settings fixture or explicitly scope ProhibitElevation to false for the test.
This issue also appears on line 811 of the same file.
Addressed the two 'previously missed' notes in 50d8e6f: (1) the elevated WinGet custom-arguments warning ignores blank arguments, using the same IsNullOrWhiteSpace filter as the request builder; (2) the elevation-dependent builder tests now set ProhibitElevation to false for their duration and restore it afterwards, so they don't depend on the machine's settings.
PreRelease is never validated by manager or role. Npm exposes pre-release selection in UniGetUI, but the broker rejects every npm request with PreRelease=true; similarly, several managers reject it on uninstall. Because the dialog keeps this saved selection when switching profiles, these requests show no live issue and are still sent to be rejected. Add manager/role validation for this flag or clear it when unsupported.
Validate architecture by manager and operation role
The architecture check only rejects arm32, but it misses manager/operation restrictions. For example, UniGetUI enables x86/x64/arm64 for Scoop updates, while the broker accepts Scoop architecture only for installs. Such an update passes FindProblems and the client's manager-level capability check, then is rejected by the execute endpoint. Validate architecture against both manager and role (or omit it when that role cannot use it).
Validate machine scope against manager restrictions
Machine scope is not covered by the manager restrictions here. Npm and Scoop both expose custom scopes in UniGetUI, so selecting the global scope maps to Scope.Machine, but the broker supports only Scope.User for those managers. The live validator therefore reports no problem; execution later fails capability validation instead of listing the invalid field. Mirror the broker's per-manager scope restrictions here.
Validate original PowerShell source name without trimming
Trimming PowerShell source names before validation creates a false negative. The original sourceName is serialized unchanged, while the broker explicitly rejects any source name with leading or trailing whitespace before policy evaluation. For example, " PSGallery" passes this check and is then rejected remotely. Validate the original spelling instead of its trimmed copy.
Report options the broker's command builder refuses for the manager (machine or user scope, architecture, pre-release, interactive, hash-check skip, install location, uninstall-previous, Cargo actions), stop sending pre-release, hash-check skip and architecture where the role ignores them, and check source names as sent.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Addressed the four 'previously missed' notes in e8fc724. The validator now mirrors the broker's per-manager option rules for the values that are actually sent: machine or user scope, architecture (Scoop on install only; never on uninstall), pre-release, interactive, hash-check skip, install location, uninstall-previous, and Cargo's close-apps and pre/post actions. Pre-release, hash-check skip and architecture are no longer sent for uninstalls, matching the local path. PowerShell source names are checked as sent, without trimming.
bool packageManagerPicksTheBuild = manager is ManagerName.Npm or ManagerName.Bun or ManagerName.Cargo
or ManagerName.Pip or ManagerName.Vcpkg;
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
If the same issue can be reproduced outside UniGetUI with the relevant package manager or with the package itself, please report it there first. UniGetUI should only be used to track issues that are specific to UniGetUI's behavior or integration.
Aligns the Devolutions Agent package broker integration with the broker's request validation, and makes broker outcomes understandable to the user.
Send resolved package versions to the package broker (
BrokerRequestBuilder)-AllowClobberretry is not sent, because the broker accepts no PowerShell parameter. The command conflict is reported instead.Validate package broker request fields (
BrokerRequestValidator, new)WinGet custom installer arguments
--override/--custom, or any custom argument on an elevated operation, goes through the Devolutions Agent. These arguments reach an installer running with administrator rights, and the organization's policy may block them.Explain package broker policy decisions (
BrokerFailureDescriber, new)Forbidden, keeping the broker's reason (for example policy validity);BrokerUnavailable, which now carries the specific title.The pipe transport, server verification and retry handling are unchanged. New strings were added to
lang_en.jsononly.Validation (from
src/):dotnet test UniGetUI.PackageEngine.Tests/UniGetUI.PackageEngine.Tests.csproj /p:Platform=x64 --filter "FullyQualifiedName~Broker|FullyQualifiedName~PackageOperationsTests": passed (448 for the Windows target, 436 fornet10.0).dotnet test UniGetUI.PackageEngine.Tests/UniGetUI.PackageEngine.Tests.csproj /p:Platform=x64(full): passed fornet10.0. On the Windows target, onlyPowerShellOperationLauncherTests.TheScopeRetryMarkersSurviveTheLauncherfailed; it also fails onmainin my environment.dotnet test UniGetUI.Tests/UniGetUI.Tests.csproj /p:Platform=x64: passed (553).dotnet format whitespaceanddotnet format style UniGetUI.Windows.slnx --no-restore --verify-no-changeson the changed files: passed.pwsh ./scripts/translation/Verify-Translations.ps1: passed.Not tested: end to end against a running Devolutions Agent with the updated broker, and the dialog notices in the running app.