repoke

Command reference

Every command takes --help. Lists of managers or packages are comma separated: --only brew,npm. Manager ids are the ones repoke list prints; packages are written name or manager:name (eslint, npm:eslint).

repoke list

The package managers repoke supports on this system, whether each is installed and its version. Plugins appear after the built-in managers.

Option
--jsonPrint JSON instead of text

repoke check

What is outdated, per manager, with the installed and the latest version. It changes nothing. Managers are checked side by side.

Option
--only <ids>Only these managers
--exclude <ids>Skip these managers
--hold <packages>Leave these packages out
--refreshRefresh package indexes first (brew update, or a plugin's refresh)
--jsonPrint JSON instead of text

Exits 0 when everything is up to date, 100 when there are updates, 1 when a manager could not be checked.

repoke upgrade

Upgrades what is outdated. In a terminal it shows a list with everything selected: space toggles a package, the right arrow selects all, the left arrow none, Escape cancels. Outside a terminal it needs --yes.

Option
--only <ids>Only these managers
--exclude <ids>Skip these managers
--package <packages>Only these packages
--hold <packages>Leave these packages alone
--refreshRefresh package indexes first
-y, --yesUpgrade everything selected without asking
--dry-runPrint the commands that would run, change nothing
--no-sudoSkip managers that need root instead of calling sudo
--jsonPrint one JSON event per line

Managers run one after another, each with its own spinner showing the last line of its output. If a batch fails, its packages are retried one at a time, so one bad package doesn't hold back the rest. A manager that needs root runs through sudo -n; in a terminal repoke asks for the password once, up front.

Exits 0 when everything selected was upgraded, 1 when something failed, 130 when the list was cancelled.

repoke export

Saves what each manager has installed on purpose (not dependencies) to a folder another machine can restore. In a terminal it asks, manager by manager, whether to include its config files.

Option
--only <ids>Only these managers
--exclude <ids>Skip these managers
-o, --output <folder>Where to write it (default: repoke-<host>-<date>)
--configInclude every manager's config files without asking
--no-configLeave all config files out
-y, --yesAsk nothing: config only with --config, and secret-looking values are removed
--forceReplace a snapshot already in the folder
--jsonPrint JSON instead of text

The folder holds repoke.toml, one line per package (cask:firefox, eslint==10.13.0), and files/ with the config files at their path under your home. Lines that look like secrets (_authToken=…, password: …, private keys) are found before saving: interactively you choose to remove their values, leave the file out or keep it; unattended, the values are always removed. A config file that is a link into a git repository is recorded as coming from your dotfiles instead of being copied.

repoke init

Sets up a machine, from a snapshot or from a catalog of common tools.

Option
--from <folder>A snapshot written by repoke export
--tools <ids>Catalog tools to install without the picker
--only <ids>Only these managers
--exclude <ids>Skip these managers
-y, --yesInstall everything without asking
--dry-runShow what would be installed and restored, change nothing
--no-sudoSkip managers that need root
--no-configDon't restore config files
--overwriteReplace config files that differ without asking; yours are backed up first
--jsonPrint JSON instead of text

With --from, managers that don't exist on this system are skipped, only what is missing is installed, and Homebrew goes first, since it often installs the other managers. A manager that is still missing is offered through Homebrew. Config files that are missing are restored, equal ones are left alone, and different ones are kept unless you choose the snapshot's copy; yours is saved as <file>.repoke-<date>.bak. Values removed from secrets are filled back from the file already on the machine.

Without --from, repoke offers a catalog of tools (git, gh, ripgrep, fd, bat, fzf, neovim, VS Code…) and installs each with the first manager on the machine that has it.

repoke schedule

Runs repoke on its own through the system scheduler: a launchd agent on macOS, a systemd user timer on Linux, Task Scheduler on Windows. A run missed while the machine was asleep or off happens at the next wake or boot.

repoke schedule install

Registers the periodic run, replacing an earlier one.

Option
--every <daily|weekly>How often (default: daily; weekly runs are on Mondays)
--at <HH:MM>Local time, 24-hour clock (default: 03:00)
--check-onlyOnly check and notify; don't upgrade
--only <ids>Only these managers
--exclude <ids>Skip these managers
--dry-runPrint the scheduler files and commands, register nothing

By default the job runs repoke upgrade --yes --no-sudo. Schedulers start jobs with a bare PATH, so install saves yours (with fnm's per-shell folder swapped for its default alias); run it again after changing your PATH. Upgrading repoke doesn't touch the schedule: the job runs the repoke on your PATH, which Homebrew, cargo and self-update keep current. Without systemd it prints the crontab line to add instead.

repoke schedule status

Whether a run is scheduled, when, and how the last one went. --json prints it as JSON.

repoke schedule run

What the scheduler runs, and a way to try the job now. It keeps the output of the last run and a history.jsonl in ~/Library/Logs/repoke (~/.local/state/repoke on Linux, %LOCALAPPDATA%\repoke on Windows), and sends a system notification when something was upgraded, failed or is pending.

repoke schedule remove

Unregisters the run. --dry-run prints what would be removed.

repoke self-update

Updates repoke. If Homebrew or cargo installed it, it runs brew upgrade repoke or cargo install repoke --locked; otherwise it downloads the release for your system, checks its SHA-256 and swaps the binary in place.

Option
--checkOnly say whether a newer version exists; exits 100 when it does
-y, --yesUpdate without asking
--jsonPrint JSON instead of text

In a terminal, repoke also mentions a new version at most once a day. REPOKE_NO_UPDATE_CHECK=1 turns that off.

repoke mcp

An MCP server over stdio, so AI agents can use repoke as a tool. It has four tools:

ToolWhat it does
list_managersThe managers on the machine and their versions
check_updatesWhat is outdated; takes only, exclude, hold, refresh
upgradeUpgrades; takes only, exclude, hold, packages and dry_run. It only previews unless dry_run is false, and never uses sudo
schedule_statusThe schedule and the last run

In Claude Code, /plugin install repoke --marketplace paveldelpozo/repoke adds the server and a skill on when to use it. In Codex, add to ~/.codex/config.toml:

[mcp_servers.repoke]
command = "repoke"
args = ["mcp"]

repoke plugin

Managers added without changing repoke: a TOML file in ~/.config/repoke/managers/, or a repoke-<id> executable on your PATH. How to write one: the plugin guide.

Command
repoke plugin list [--json]The plugins found, and any problem with them
repoke plugin new <id> [--exec] [-o <path>]A template to start from: TOML by default, a script with --exec
repoke plugin search [--json]The official plugins
repoke plugin install <id> [-y] [--force]Downloads an official plugin, shows its code and asks before installing it
repoke plugin remove <id>Removes a plugin that plugin install installed

Configuration

~/.config/repoke/config.toml (%APPDATA%\repoke\config.toml on Windows, or the file in REPOKE_CONFIG):

exclude = ["mas"]                # managers left out unless named in --only
hold = ["eslint", "pnpm:pnpm"]   # never upgraded nor reported, as name or manager:name
plugin_timeout = "10m"           # longest a plugin command may run (600, 90s, 10m, 1h; 0 = no limit)

[brew]
greedy = true                    # also casks that update themselves
Variable
REPOKE_CONFIGUse another config file
REPOKE_PLUGIN_TIMEOUTOverrides plugin_timeout for one run
REPOKE_NO_PLUGINSIgnore every plugin for one run
REPOKE_PLUGIN_INDEXAnother plugin index, a URL or a local file
REPOKE_NO_UPDATE_CHECKNever mention a new repoke version
NO_COLOROutput without colors

JSON output

check --json prints one object per manager: id, name, version, packages (each with name, current, latest) and error.

upgrade --json and init --json print one event per line, as they happen:

EventWhen
check_failedA manager could not be checked
runningA command starts
plannedWith --dry-run, the commands that would run
donePackages upgraded or installed, with seconds
failedPackages that failed, with the error and sometimes a hint
skippedPackages left out, with the reason
retryingA batch failed and is retried one package at a time
configinit only: what happened to a config file
summaryTotals, the whole run's elapsed_seconds and a per-manager breakdown

Exit codes

CodeMeaning
0Done, or everything is up to date
100check and self-update --check: there is something to update
1A manager failed to check, upgrade or install
2Invalid arguments or config, or --yes needed outside a terminal
130The interactive list was cancelled

This page is built from docs/commands.md.