Check nuget.org for a newer pks-cli release, show a current-to-latest diff, and apply it using whichever mechanism matches how this pks binary was installed.
pks update [--self]$ pks updateCheck for a newer release and apply it if one exists
$ pks update --selfSame as above; --self mirrors aspire's calling convention
pks update is a single leaf command registered directly under the root pks command — it has no subcommands. It picks an update channel, checks nuget.org for the latest pks-cli package version, shows a current-to-latest diff, asks for confirmation, then applies the update through whichever mechanism matches how this pks binary was installed.
pks update compares the running binary's version against the latest version of the pks-cli package on nuget.org and, if a newer one exists, updates in place. What "updates in place" means depends entirely on the install method:
dotnet tool install — it shells out to dotnet tool update -g pks-cli for you.Run pks update periodically to pick up new pks-cli releases, or when you're told a newer version is available. Before relying on it, check pks actions to see whether the pks.update action is set to require a two-factor code, and use pks authenticator status (or pks authenticator init) to check or enroll the TOTP factor that can gate it.
AssemblyInformationalVersion on the running binary — this is baked in at build time and is not something you configure.pks update needs no credentials of its own.pks update [options]
| Flag | Type | Default | Description |
|---|---|---|---|
--self | bool | false | Accepted by the parser but not branched on anywhere in the command body — pks update always performs a self-update whether or not --self is passed. It exists to mirror aspire update --self's calling convention. |
cli.update.channel. If none is set, prompts interactively for stable (released nuget.org versions) or daily (the latest X.Y.Z-preview.N published on every push to main) and persists the choice.pks-cli version for the chosen channel (includePrerelease is only set for daily). A feed failure prints a red error and exits 1 — there is no cached or offline fallback.AssemblyInformationalVersion (build metadata after + stripped) using NuGet semver comparison. If the candidate is not strictly newer, prints "Already up to date" and exits 0.Update to {latest}? (default: yes). Answering no exits 0 with nothing changed.pks.update two-factor action (see Auth model below). A denial prints a red message and exits 1.Environment.ProcessPath to classify how this pks was installed, then runs the matching update path — see Install-method dispatch.Answering no to the confirm prompt, a feed failure, and an already-up-to-date result all return before the two-factor gate is even reached — the gate only fires when a newer version genuinely exists and you've confirmed applying it.
Detection (IInstallMethodDetector.Detect()) is purely path-based against Environment.ProcessPath, checked in this order:
| Detected path pattern | Install method | What pks update then does |
|---|---|---|
Under /.dotnet/tools/ or /.store/pks-cli/ | DotnetTool | Runs dotnet tool update -g pks-cli (adds --prerelease on the daily channel) via Process.Start, streams the exit code, and prints success or failure. This is the only path that actually performs the update for you. |
Under /node_modules/@pks-cli/ | Npm | Prints guidance to run npm install -g @pks-cli/cli@latest yourself. Does not run it. |
Under /usr/local/, /usr/bin/, or /opt/, not writable by the current process owner | Baked | Prints a yellow panel telling the operator to run ./scripts/host/pks-devswap.sh release <container> or ./scripts/host/pks-devswap.sh workspace <container> from the Docker host, then returns 0. Nothing is updated by the command itself. |
Under /usr/local/, /usr/bin/, or /opt/, writable by the current process owner; or any other writable path | StandaloneBinary | Prints guidance to download the new version and replace the binary yourself. Does not download or replace anything. |
Process filename is literally dotnet (i.e. invoked via dotnet run / dotnet pks.dll), or an unrecognized layout | Unknown | Prints "This pks was run from source... rebuild from the repo to pick up changes." |
Because detection is filesystem-path-based, running pks from an unusual location can misclassify the install method and print the wrong guidance panel.
pks update reads nuget.org, which needs no credentials. The sensitive step — actually replacing the binary — is gated by pks-cli's own local two-factor action guard, under action id pks.update ("Update pks" / "Replace or self-update the pks binary", category "Control plane", default-required in the catalog).
That gate is opt-in and silent until you turn it on:
RequireAsync auto-satisfies and the update proceeds ungated — this is trust-on-first-use, so existing users see no behavior change.pks.update is set to require it: pks update renders an approval panel and requires a TOTP code before the binary write proceeds.pks authenticator init is deliberately kept off any agent- or sudo-automatable path, so an autonomous agent cannot both enable and then satisfy this gate.
pks update
Checks the current channel, shows the diff panel if a newer version exists, and asks to confirm before applying.
pks update --self
Identical in practice to pks update — --self does not change behavior, but this is the invocation shown in the CLI's own registered example.
The dotnet tool update -g pks-cli step runs synchronously and blocks on proc.WaitForExit() with no timeout. If dotnet itself stalls — commonly a NuGet network stall — pks update hangs too, and the spinner is only shown during the earlier version-check step, not during this one. Wait it out or interrupt and retry once connectivity is confirmed.
Two independent causes produce this message:
stable never sees daily preview builds. Check cli.update.channel.NuGetVersion. A parse failure is treated as "not newer," silently — there is no separate error for it.Only InstallMethod.DotnetTool performs a real automatic update. Every other install method — Npm, Baked, StandaloneBinary, Unknown — only prints instructions and leaves the running binary untouched. Re-read the panel it printed; it names the exact command or script to run next.
This is expected for InstallMethod.Baked. A pks baked into a devcontainer image runs as a non-root pks user that cannot write /usr/local/bin/pks, so the update has to happen from outside the container. Run ./scripts/host/pks-devswap.sh release <container> (or workspace <container>) from the Docker host, not from inside the container.
No TOTP authenticator is enrolled, or pks.update isn't marked required in your action policy. Run pks authenticator init to enroll one, then check its requirement with pks actions.
pks update.pks.update requires a code.