🚦 upgate
The gate between available and ready updates
A new version can be available before it is ready for your system. upgate
waits for the configured release age, applies the version policy, and checks
OSV when it can identify the exact package. You see the
result and choose what gets updated.
Package managers still find and install updates in their own way. upgate
checks the possible updates before it runs their commands. This makes supply
chain attacks harder, but still it cannot prove that a release is safe.

Install
Download the prebuilt binary for your system from the
latest release. Unpack
it and place upgate in a directory from your PATH. Rust is not required.
Build with Cargo
To build upgate from source, you need Rust 1.88 or newer.
Build the current source
macOS is the main platform today. Linux is supported too, but it has not had the same amount of real-world testing yet.
Start here
This command scans installed tools, builds an update plan, and opens the interactive picker. The picker shows current tools, available updates, and anything delayed, blocked, or failed. Choose the updates you want, then run them from the picker.
For read-only checks and other workflows:
# List installed tools
# Build a plan without updating anything
# Run only selected package managers
# Preview the commands without running them
# Apply the default selection without opening the picker
Add --verbose when you need release-age, version-policy, or security details.
Supported package managers
Defaults and supported features differ by manager.
| Package manager | Default mode | Minimum release age | Version policies | OSV check |
|---|---|---|---|---|
| Homebrew | apply |
12 hours | none, stable, same-track |
When the Git source is known |
| Bun | apply |
7 days | none, stable, same-track |
npm |
| Cargo | apply |
7 days | none, stable, same-track |
crates.io |
| npm | apply |
7 days | none, stable, same-track |
npm |
| mise | apply |
7 days | none |
Known backend or Git source |
| pipx | apply |
7 days | none, stable, same-track |
PyPI |
| pnpm | apply |
7 days | none, stable, same-track |
npm |
| uv | apply |
7 days | none |
PyPI |
| Go | apply |
7 days | none, stable, same-track |
Go |
| RubyGems | off |
7 days | stable |
RubyGems |
| .NET tools | off |
7 days | none, stable, same-track |
NuGet |
The OSV column shows where package identity comes from. A check runs only when
upgate can make an exact mapping. Missing package-manager executables are
skipped.
Configuration
The config file is $XDG_CONFIG_HOME/upgate/config.toml, or
~/.config/upgate/config.toml when XDG_CONFIG_HOME is not set. Without a
config file, upgate uses the defaults above.
[]
= "14d"
= "same-track"
[]
= "skip"
= ["typescript"]
[]
= "plan"
Manager mode can be:
apply: include the manager in every commandplan: scan and plan, but do not updateoff: skip the manager
A selection rule controls the default package selection. except always means
the opposite of mode. The example skips npm packages by default, except for
typescript.
Release age accepts seconds, minutes, hours, and days, such as 30m, 12h, or
7d. npm accepts whole days only.
Version policy can be:
none: do not filter prereleasesstable: use final releases onlysame-track: stay at least as stable as the installed version
Not every policy fits every manager. Unsupported combinations are rejected. See the full config example for every setting.
Use --set or -S for one run:
Release age and security
A version younger than min_release_age is not selected by the normal plan.
When a manager provides version history, an older eligible version can be used
instead. Waiting gives problems time to become visible. It is not proof that a
release is safe.
OSV checks run only for packages with an exact ecosystem and package identity. For those packages, a vulnerable target or a failed OSV request is blocked by default. Packages without an OSV mapping are shown without an audit result and are not blocked.
The interactive picker can offer a forced target for some blocked updates. When that option is present, you can choose it explicitly.
upgate scan --verbose audits installed versions. Normal scan does not
contact OSV.
Logs
Each run gets a timestamped directory:
- macOS:
~/Library/Logs/upgate/ - Linux:
$XDG_STATE_HOME/upgate/logs/, or~/.local/state/upgate/logs/
Files:
core.log: always logs failed commands and commands that change the systemsnapshot.json: plan and selected actions for apply runs
Use --log-commands to save all output and timing for every external command:
--log-commandsprints the exact session directory after the run.--trace-commandsshows commands live. Interactive mode shows them inside the picker.
Run upgate --help to see all command options.