Skip to content

Commit 9f7a49d

Browse files
Expand headless CLI automation surface
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f5c4e21 commit 9f7a49d

9 files changed

Lines changed: 1694 additions & 42 deletions

File tree

cli-arguments.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,26 @@
2121
| `--automation status` | Queries the local automation service and returns machine-readable status, including the configured background API transport | 2026.1+ |
2222
| `--automation get-version` | Reads the local automation service build number through the background API | 2026.1+ |
2323
| `--automation get-updates` | Reads the currently available updates through the local automation service and returns structured JSON | 2026.1+ |
24+
| `--automation list-managers` | Lists package managers, readiness, executable metadata, and automation-relevant capability flags | 2026.1+ |
25+
| `--automation list-sources [--manager name]` | Lists known and configured sources, optionally filtered to a single manager | 2026.1+ |
26+
| `--automation add-source --manager name --source-name name [--source-url url]` | Adds a known or custom source through the automation service | 2026.1+ |
27+
| `--automation remove-source --manager name --source-name name [--source-url url]` | Removes a source through the automation service | 2026.1+ |
28+
| `--automation list-settings` | Lists non-sensitive settings with their current boolean/string state | 2026.1+ |
29+
| `--automation get-setting --key key` | Reads a single non-sensitive setting through the automation service | 2026.1+ |
30+
| `--automation set-setting --key key (--enabled true|false \| --value text)` | Sets a boolean or string setting through the automation service | 2026.1+ |
31+
| `--automation clear-setting --key key` | Clears a string-backed setting through the automation service | 2026.1+ |
32+
| `--automation reset-settings` | Resets non-secure settings while preserving the active automation session token | 2026.1+ |
2433
| `--automation list-installed --manager name` | Lists installed packages for the selected manager through the automation service and returns structured JSON | 2026.1+ |
2534
| `--automation search-packages --manager name --query text [--max-results n]` | Searches packages through the automation service and returns structured JSON | 2026.1+ |
35+
| `--automation package-details --manager name --package-id id` | Fetches the package-details payload currently exposed through the automation layer | 2026.1+ |
36+
| `--automation package-versions --manager name --package-id id` | Lists installable versions for a package when the manager supports custom versions | 2026.1+ |
2637
| `--automation install-package --manager name --package-id id [--version v] [--scope scope] [--pre-release]` | Installs a package through the automation service and waits for completion | 2026.1+ |
2738
| `--automation open-window` | Asks the running UniGetUI instance to show the main window | 2026.1+ |
2839
| `--automation open-updates` | Asks the running UniGetUI instance to show the Updates page | 2026.1+ |
2940
| `--automation show-package --package-id id --package-source source` | Opens the package details flow for the specified package | 2026.1+ |
41+
| `--automation list-ignored-updates` | Lists ignored update rules tracked by UniGetUI | 2026.1+ |
42+
| `--automation ignore-package --manager name --package-id id [--version v]` | Adds an ignored-update rule for a package and refreshes the updates view | 2026.1+ |
43+
| `--automation unignore-package --manager name --package-id id [--version v]` | Removes an ignored-update rule for a package and refreshes the updates view | 2026.1+ |
3044
| `--automation update-all` | Queues updates for all packages currently shown as upgradable | 2026.1+ |
3145
| `--automation update-manager --manager name` | Queues updates for all packages handled by the specified manager | 2026.1+ |
3246
| `--automation update-package --manager name --package-id id` | Updates a specific package through the automation service and waits for completion | 2026.1+ |
@@ -48,6 +62,7 @@
4862

4963
- `dotnet src\UniGetUI.Avalonia\bin\Release\net10.0\UniGetUI.Avalonia.dll --headless` starts the local automation daemon without opening any window or requiring a graphical desktop session.
5064
- `dotnet src\UniGetUI.Cli\bin\Release\net10.0\UniGetUI.Cli.dll <command>` is the cross-platform CLI wrapper for the automation service. It automatically prepends `--automation`, so `UniGetUI.Cli status` and `UniGetUI.Cli search-packages --manager ".NET Tool" --query dotnetsay` work directly.
65+
- Current agent-oriented command coverage includes status/version, manager/source inspection, settings inspection and mutation, package search/details/version listing, ignored-update management, and package install/update/uninstall flows.
5166

5267
<br><br>
5368
# `unigetui://` deep link

src/UniGetUI.Interface.BackgroundApi/AutomationCliCommandRunner.cs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,78 @@ TextWriter error
4141
return subcommand switch
4242
{
4343
"status" => await WriteJsonAsync(output, await client.GetStatusAsync()),
44+
"list-managers" => await WriteJsonAsync(
45+
output,
46+
new
47+
{
48+
status = "success",
49+
managers = await client.ListManagersAsync(),
50+
}
51+
),
52+
"list-sources" => await WriteJsonAsync(
53+
output,
54+
new
55+
{
56+
status = "success",
57+
sources = await client.ListSourcesAsync(GetOptionalArgument(args, "--manager")),
58+
}
59+
),
60+
"add-source" => await WriteJsonAsync(
61+
output,
62+
await client.AddSourceAsync(BuildSourceRequest(args))
63+
),
64+
"remove-source" => await WriteJsonAsync(
65+
output,
66+
await client.RemoveSourceAsync(BuildSourceRequest(args))
67+
),
68+
"list-settings" => await WriteJsonAsync(
69+
output,
70+
new
71+
{
72+
status = "success",
73+
settings = await client.ListSettingsAsync(),
74+
}
75+
),
76+
"get-setting" => await WriteJsonAsync(
77+
output,
78+
new
79+
{
80+
status = "success",
81+
setting = await client.GetSettingAsync(
82+
GetRequiredArgument(
83+
args,
84+
"--key",
85+
"The get-setting automation command requires --key."
86+
)
87+
),
88+
}
89+
),
90+
"set-setting" => await WriteJsonAsync(
91+
output,
92+
new
93+
{
94+
status = "success",
95+
setting = await client.SetSettingAsync(BuildSettingRequest(args)),
96+
}
97+
),
98+
"clear-setting" => await WriteJsonAsync(
99+
output,
100+
new
101+
{
102+
status = "success",
103+
setting = await client.ClearSettingAsync(
104+
GetRequiredArgument(
105+
args,
106+
"--key",
107+
"The clear-setting automation command requires --key."
108+
)
109+
),
110+
}
111+
),
112+
"reset-settings" => await WriteJsonAsync(
113+
output,
114+
await client.ResetSettingsAsync()
115+
),
44116
"get-version" => await WriteJsonAsync(
45117
output,
46118
new
@@ -85,6 +157,38 @@ TextWriter error
85157
),
86158
}
87159
),
160+
"package-details" => await WriteJsonAsync(
161+
output,
162+
new
163+
{
164+
status = "success",
165+
package = await client.GetPackageDetailsAsync(BuildPackageActionRequest(args)),
166+
}
167+
),
168+
"package-versions" => await WriteJsonAsync(
169+
output,
170+
new
171+
{
172+
status = "success",
173+
versions = await client.GetPackageVersionsAsync(BuildPackageActionRequest(args)),
174+
}
175+
),
176+
"list-ignored-updates" => await WriteJsonAsync(
177+
output,
178+
new
179+
{
180+
status = "success",
181+
ignoredUpdates = await client.ListIgnoredUpdatesAsync(),
182+
}
183+
),
184+
"ignore-package" => await WriteJsonAsync(
185+
output,
186+
await client.IgnorePackageUpdateAsync(BuildPackageActionRequest(args))
187+
),
188+
"unignore-package" => await WriteJsonAsync(
189+
output,
190+
await client.RemoveIgnoredUpdateAsync(BuildPackageActionRequest(args))
191+
),
88192
"install-package" => await WriteJsonAsync(
89193
output,
90194
await client.InstallPackageAsync(BuildPackageActionRequest(args))
@@ -176,6 +280,52 @@ private static AutomationPackageActionRequest BuildPackageActionRequest(IReadOnl
176280
};
177281
}
178282

283+
private static AutomationSourceRequest BuildSourceRequest(IReadOnlyList<string> args)
284+
{
285+
return new AutomationSourceRequest
286+
{
287+
ManagerName = GetRequiredArgument(
288+
args,
289+
"--manager",
290+
"This automation command requires --manager."
291+
),
292+
SourceName = GetRequiredArgument(
293+
args,
294+
"--name",
295+
"This automation command requires --name."
296+
),
297+
SourceUrl = GetOptionalArgument(args, "--url"),
298+
};
299+
}
300+
301+
private static AutomationSettingValueRequest BuildSettingRequest(IReadOnlyList<string> args)
302+
{
303+
bool? enabled = null;
304+
string? enabledValue = GetOptionalArgument(args, "--enabled");
305+
if (enabledValue is not null)
306+
{
307+
if (!bool.TryParse(enabledValue, out bool parsedEnabled))
308+
{
309+
throw new InvalidOperationException(
310+
"The value supplied to --enabled must be either true or false."
311+
);
312+
}
313+
314+
enabled = parsedEnabled;
315+
}
316+
317+
return new AutomationSettingValueRequest
318+
{
319+
SettingKey = GetRequiredArgument(
320+
args,
321+
"--key",
322+
"This automation command requires --key."
323+
),
324+
Enabled = enabled,
325+
Value = GetOptionalArgument(args, "--value"),
326+
};
327+
}
328+
179329
private static string GetRequiredArgument(
180330
IReadOnlyList<string> arguments,
181331
string argumentName,

0 commit comments

Comments
 (0)