sysup is a cross-platform system update utility that manages all package managers and tools from a single entry point. It works on macOS, Linux, and WSL.
Source: ~/.local/bin/sysup (dot_local/bin/executable_sysup in chezmoi)
sysup # Show what's outdated (same as sysup status)
sysup status # Read-only: check each package manager for updates
sysup upgrade # Apply all updates (uses full-upgrade for apt)
sysup repair # Fix broken packages and resolve dependency issues
sysup clean # Clear package manager and tool caches
sysup doctor # Check which tools are installed + versions
sysup version # Show sysup version
sysup help # Show built-in help| Command | Description |
|---|---|
sysup / sysup status |
Check each package manager for available updates (read-only) |
sysup upgrade |
Apply all updates across every installed package manager |
sysup repair |
Fix broken packages, resolve dependencies, clean caches (with confirmation) |
sysup clean |
Clear package manager and tool caches to free disk space |
sysup doctor |
Report installed tools, versions, and key filesystem paths |
sysup version |
Print the sysup version |
sysup help |
Show the built-in help text |
Modules are checked in the order listed below. Each module is skipped if its tool isn't installed.
| Module | What it does | Platform |
|---|---|---|
brew |
Updates Homebrew formulae. On macOS, also upgrades casks. Runs brew cleanup --prune=30 after upgrading. |
All |
apt |
Updates and full-upgrades system packages via apt-get dist-upgrade. Handles dependency changes for kernels, drivers, and distros like Pop!_OS. Requires sudo. Runs autoremove and autoclean after upgrading. |
Linux/WSL |
fnm |
Checks the current Node.js version against the latest LTS. Installs and sets LTS as default on upgrade. | All |
uv |
Runs uv self update (skipped if uv is brew-managed) and uv tool upgrade --all. |
All |
pipx |
Runs pipx upgrade-all to update all pipx-managed Python packages. |
All |
tpm |
Checks if TPM is installed. On upgrade, runs the TPM updater (~/.tmux/plugins/tpm/bin/update_plugins all). |
All |
vscode |
Counts installed VS Code extensions. On upgrade, re-installs each extension with --force to trigger updates. |
All |
chezmoi |
Checks for pending dotfile changes. On upgrade, runs chezmoi update --force to pull and apply from the repo. |
All |
- status: Each module checks for available updates and reports them. No changes are made.
- upgrade: Each module applies its updates. A summary at the end shows which modules succeeded, failed, or were skipped.
- repair: Runs recovery steps for brew and apt. Prompts for confirmation before proceeding.
sysup repair fixes broken package states without reinstalling the OS. It prompts for confirmation before running.
| Manager | Steps | What it fixes |
|---|---|---|
apt |
dpkg --configure -a → apt --fix-broken install → apt clean → apt autoremove |
Interrupted installs, unmet dependencies, corrupted package database, orphaned packages |
brew |
brew doctor → brew cleanup --prune=0 → brew autoremove |
Stale caches, orphaned dependencies, configuration issues |
- Software installs failing with dependency errors
- Updates stopping halfway through
- Package manager reporting broken packages
- Applications failing after a system update
sysup clean clears package manager and tool caches to free disk space. It shows the size of each cache before cleaning and reports how much space was freed.
| Tool | Command | What it clears |
|---|---|---|
uv |
uv cache clean |
Downloaded Python packages and wheels |
brew |
brew cleanup --prune=0 |
Old formula versions and stale downloads |
pip |
pip cache purge |
Cached pip downloads |
npm |
npm cache clean --force |
Cached npm packages |
docker |
docker builder prune -a -f |
Build cache only (images/containers untouched) |
go |
go clean -modcache |
Downloaded Go modules |
Each tool is skipped if not installed. A total freed summary is shown at the end.
sysup doctor reports system information, installed tools with versions, and key filesystem paths.
| Group | Tools checked |
|---|---|
| Package Managers | brew, apt-get, chezmoi, fnm, node, npm, uv, pipx |
| Development Tools | git, zsh, tmux, fzf, docker, python3, poetry, just, gh, curl, sysbak, rsnapshot |
| Modern CLI Replacements | eza, bat, fd, rg, delta, btop, zoxide, jq, sensors, sar |
| Path | Description |
|---|---|
~/.tmux/plugins/tpm |
Tmux Plugin Manager |
~/.oh-my-zsh |
Oh My Zsh framework |
~/.config/dev/config |
Dev session manager config |
~/.config/sysbak/config |
Backup manager config |
~/Projects |
Project discovery directory |
Each tool and path is shown with a green check (✓), yellow warning (⚠ installed but version unavailable), or red cross (✗ not installed).
On Linux, if pop-upgrade is installed (Pop!_OS), sysup doctor adds a Linux Daemon Health section showing whether the daemon is running and its current CPU usage. A daemon using >5% CPU is flagged as potentially stuck.
sysup # What needs updating?
sysup upgrade # Update everything
sysup clean # Free disk space from caches
sysup repair # Fix broken packages
sysup doctor # Verify all tools are presentEach module follows the same pattern:
- Create functions:
<name>_status(),<name>_upgrade(), and optionally<name>_repair() - Gate both functions with
if ! has <tool>; then summary_skip "<name>"; return; fi - Use
summary_ok,summary_skip, orsummary_failto report results - Add calls to both functions in
cmd_status()andcmd_upgrade() - Add the tool to the appropriate
tools_*array incmd_doctor()so it appears in doctor output - If the tool has a non-standard version flag, add a case to
get_version()
The get_version() function handles tools with non-standard --version output. For most tools, it extracts just the version number. Add a new case entry if your tool's output format differs from <tool> --version printing a parseable version string.