An open API service indexing awesome lists of open source software.

https://github.com/lu-zhengda/updater

macOS app update manager — check and update apps from Sparkle, Homebrew, Mac App Store, and GitHub Releases
https://github.com/lu-zhengda/updater

bubbletea claude-code claude-code-plugin cli go homebrew mac-app-store macos package-manager sparkle tui updater

Last synced: about 1 month ago
JSON representation

macOS app update manager — check and update apps from Sparkle, Homebrew, Mac App Store, and GitHub Releases

Awesome Lists containing this project

README

          

# updater

[![CI](https://github.com/lu-zhengda/updater/actions/workflows/ci.yml/badge.svg)](https://github.com/lu-zhengda/updater/actions/workflows/ci.yml)
[![Release](https://github.com/lu-zhengda/updater/actions/workflows/release.yml/badge.svg)](https://github.com/lu-zhengda/updater/actions/workflows/release.yml)
[![Latest Release](https://img.shields.io/github/v/release/lu-zhengda/updater?sort=semver)](https://github.com/lu-zhengda/updater/releases)
[![Go Version](https://img.shields.io/github/go-mod/go-version/lu-zhengda/updater)](https://github.com/lu-zhengda/updater/blob/main/go.mod)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/lu-zhengda/updater/blob/main/LICENSE)

`updater` is a macOS CLI/TUI that discovers installed apps, checks for updates across multiple ecosystems, and applies the right update action per app.

## Requirements

- macOS (the one truly non-negotiable requirement)
- Homebrew (recommended)
- `mas` for Mac App Store checks (installed automatically with the Homebrew cask)

## Install (Recommended)

Install from Homebrew tap:

```sh
brew install --cask lu-zhengda/tap/updater
updater --version
```

This is the easiest path and includes `mas` automatically as a cask dependency.

Upgrade later:

```sh
brew upgrade --cask lu-zhengda/tap/updater
```

## Quick Start

```sh
# 1) Validate environment and dependencies
updater doctor

# 2) Discover installed apps and detected sources
updater scan

# 3) Check available updates
updater check

# 4) Preview update actions without changing anything
updater update --all --dry-run

# 5) Apply updates
updater update --all
```

Launch the interactive TUI:

```sh
updater
```

## What It Supports

| Source | How updates are checked | Update behavior |
| --- | --- | --- |
| Sparkle | Appcast feed from app metadata | Direct DMG/ZIP/PKG install when possible, otherwise opens download URL |
| Homebrew cask | `brew outdated --cask --greedy --json` | `brew upgrade --cask ` |
| Homebrew formula | `brew outdated --formula --json` | `brew upgrade ` |
| Mac App Store | `mas outdated` | `mas upgrade ` or opens App Store updates |
| GitHub Releases | GitHub Releases API | Direct install when possible, otherwise opens release asset URL |
| Electron generic | `latest-mac.yml` from update server | Direct install when possible, otherwise opens app |
| Brew-info fallback | `brew info --cask --json=v2` | If brew-installed: `brew upgrade --cask`; otherwise opens app |
| macOS system | `softwareupdate -l` | Opens Software Update settings |

Also detected (for visibility): Setapp, JetBrains Toolbox, and Adobe apps.

## Command Guide

Core update workflow:

```sh
updater scan
updater check
updater check --share
updater update "1Password"
updater update --all
updater update --all --auto
updater update --all --dry-run
```

Scripting/JSON:

```sh
updater scan --json
updater check --json
updater outdated --json
updater history --json
updater doctor --json
updater update --all --dry-run --json
```

Agent mode:

- All commands support `--json`.
- When `updater` detects it is running inside Codex or Claude Code, JSON output is enabled automatically.
- Override behavior with `UPDATER_AGENT_MODE=0` (force off) or `UPDATER_AGENT_MODE=1` (force on).
- `updater update --json` is supported for dry-run planning (`--dry-run`).

Management:

```sh
updater pin "Google Chrome"
updater unpin "Google Chrome"
updater policy "Google Chrome" manual
updater install firefox
updater rollback "Firefox"
updater cleanup --days 90
updater cleanup --days 90 --delete
```

Automation:

```sh
updater schedule --interval 24
updater schedule --remove
```

## Configuration

Config file path:

```text
~/.config/updater/config.yaml
```

Example:

```yaml
ignored_apps:
- com.apple.Safari

pinned_apps:
- com.google.Chrome

# auto | manual | notify-only
policies:
com.microsoft.VSCode: auto
com.google.Chrome: manual

github_mappings:
com.microsoft.VSCode: "microsoft/vscode"

cask_mappings:
com.readdle.PDFExpert-Mac: "pdf-expert"

github_token: "ghp_..."
max_concurrent: 10
max_backups: 1
interactive_notifications: true
```

Notes:

- `GITHUB_TOKEN` environment variable overrides `github_token`.
- `cask_mappings` are only needed when automatic cask token detection is wrong.
- Use `updater config export` and `updater config import ` to move config between machines.

## Safety Model

- `--dry-run` prints the exact planned actions without making changes.
- Backups are created before install-based updates when app paths are available.
- Failed direct installs attempt automatic rollback from backup.
- Pinned apps are skipped in `update --all`.
- `policy` lets you force per-app behavior (`auto`, `manual`, `notify-only`).

## Build From Source

Requires Go `1.25.7+`.

```sh
git clone https://github.com/lu-zhengda/updater.git
cd updater
make install PREFIX=~/.local
```

If needed, add to `PATH`:

```sh
export PATH="$HOME/.local/bin:$PATH"
```

If building from source and you want Mac App Store checks, install `mas`:

```sh
brew install mas
```

## Developer Commands

```sh
make build
make test
make clean
```

## License

MIT