feat(system): add mise system use and mise system upgrade#10346
Conversation
`mise system use` is `mise use` for system packages: writes "manager:package" = "version" entries to mise.toml (local by default, global with -g, @Version pins like mise use) and installs whatever is missing. Managers unavailable on the current machine are added to the config without installing, so shared cross-platform configs can be authored from any OS. `mise system upgrade` (alias `up`) refreshes package manager metadata and upgrades the configured packages that are already installed: apt-get install --only-upgrade, dnf upgrade --refresh, pacman -Sy + -S --needed, and brew pours the formula's current bottle replacing the old keg. Missing packages are skipped with a pointer at install. The install/upgrade per-manager loop is factored into a shared driver used by all three commands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughAdds ChangesSystem Package Upgrade and Use Features
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d1dd5ec. Configure here.
Greptile SummaryAdds
Confidence Score: 5/5Safe to merge; the new commands write config and invoke OS package managers correctly, with dry-run, confirmation prompts, and skip-missing guards limiting blast radius The implementation is thorough and consistent: manager validation fires before any config write, deduplication logic is uniform between the entries list and the by_mgr map, post-upgrade version diffing correctly tracks installed (not pinned) versions, and the brew @ exemption is tested. The only gap is the missing --update flag on src/cli/system/use.rs — lacks the --update/-U flag that mise system install exposes Important Files Changed
Reviews (2): Last reviewed commit: "fix(system): address review findings in ..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/system-packages/index.md (1)
47-49:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate the install-only wording.
mise system usealso installs missing packages after writing config, so this sentence is now false.♻️ Suggested fix
- mise install will print a one-time hint when packages are missing, but only `mise system install` ever installs anything. + mise install will print a one-time hint when packages are missing, but only `mise system install` and `mise system use` ever install anything.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/system-packages/index.md` around lines 47 - 49, Update the misleading sentence that says "Manual installation only — mise never installs system packages..." in docs/system-packages/index.md: change it to note that while `mise install` only prints a one-time hint, both `mise system install` and `mise system use` can install missing system packages (with `mise system use` installing after writing config), so rephrase to reflect that `mise system install` and `mise system use` will perform installation while `mise install` does not.mise.usage.kdl (1)
2856-2860:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate parent
systemhelp text to includesystem useinstalls.Line 2859 says system packages are only installed via
mise system install, butmise system usenow also installs missing packages. This creates a user-facing contract contradiction.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@mise.usage.kdl` around lines 2856 - 2860, Update the parent "system" help text to reflect that missing system packages can be installed by both commands: change the sentence that currently states "they are only ever installed when explicitly requested with `mise system install`" to mention `mise system use` as well (e.g., "they are installed when explicitly requested with `mise system install` or when `mise system use` installs missing packages"). Ensure the message references the "system" help block and the command names `mise system install` and `mise system use` so users see the accurate contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/system-packages/index.md`:
- Around line 83-87: The docs currently state that `mise system upgrade` will
respect version pins for configured packages, which is too broad; update the
text around `mise system upgrade` in the system-packages doc and the
corresponding man page to clarify that only package managers which support
pinned upgrades will honor pins (the shared driver will skip pin requests for
managers that don't, e.g., pacman), and phrase it like “Packages pinned in
config are honored only by managers that support pinned upgrades; managers
without pin support will skip pinned requests.” Ensure the same qualified
wording replaces the current unqualified claim in both places.
In `@src/cli/system/use.rs`:
- Around line 58-69: The current loop over self.packages deduplicates config
entries by key but keeps all PackageRequest objects in by_mgr, causing
inconsistent behavior for duplicate package names with different versions;
update the logic so both entries and by_mgr deduplicate by package name and
apply last-wins: when computing key (format!("{mgr}:{}", request.name)) if an
existing entry exists replace its version instead of skipping, and for by_mgr
replace any existing PackageRequest with the same request.name (or same
name+mgr) with the new request rather than pushing a duplicate. Ensure you
update the code paths that use entries and by_mgr so they now reflect the
last-specified version consistently.
---
Outside diff comments:
In `@docs/system-packages/index.md`:
- Around line 47-49: Update the misleading sentence that says "Manual
installation only — mise never installs system packages..." in
docs/system-packages/index.md: change it to note that while `mise install` only
prints a one-time hint, both `mise system install` and `mise system use` can
install missing system packages (with `mise system use` installing after writing
config), so rephrase to reflect that `mise system install` and `mise system use`
will perform installation while `mise install` does not.
In `@mise.usage.kdl`:
- Around line 2856-2860: Update the parent "system" help text to reflect that
missing system packages can be installed by both commands: change the sentence
that currently states "they are only ever installed when explicitly requested
with `mise system install`" to mention `mise system use` as well (e.g., "they
are installed when explicitly requested with `mise system install` or when `mise
system use` installs missing packages"). Ensure the message references the
"system" help block and the command names `mise system install` and `mise system
use` so users see the accurate contract.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: a807120c-eb3e-4fd3-998f-5445cb18645c
📒 Files selected for processing (26)
docs/.vitepress/cli_commands.tsdocs/cli/index.mddocs/cli/system.mddocs/cli/system/upgrade.mddocs/cli/system/use.mddocs/system-packages/apt.mddocs/system-packages/brew.mddocs/system-packages/dnf.mddocs/system-packages/index.mddocs/system-packages/pacman.mde2e/cli/test_system_install_apte2e/cli/test_system_useman/man1/mise.1mise.usage.kdlsrc/cli/system/driver.rssrc/cli/system/install.rssrc/cli/system/mod.rssrc/cli/system/upgrade.rssrc/cli/system/use.rssrc/config/config_file/mise_toml.rssrc/system/mod.rssrc/system/packages/apt.rssrc/system/packages/dnf.rssrc/system/packages/mod.rssrc/system/packages/pacman.rsxtasks/fig/src/mise.ts
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.3 x -- echo |
23.5 ± 3.5 | 19.5 | 36.8 | 1.00 |
mise x -- echo |
23.5 ± 2.7 | 20.1 | 51.3 | 1.00 ± 0.19 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.3 env |
21.6 ± 1.2 | 19.2 | 27.8 | 1.00 |
mise env |
22.8 ± 1.3 | 19.8 | 28.6 | 1.06 ± 0.08 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.3 hook-env |
21.8 ± 1.6 | 18.7 | 29.8 | 1.02 ± 0.10 |
mise hook-env |
21.4 ± 1.5 | 18.7 | 29.2 | 1.00 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.3 ls |
16.3 ± 1.0 | 14.4 | 22.6 | 1.00 |
mise ls |
17.3 ± 1.3 | 15.2 | 24.5 | 1.06 ± 0.11 |
xtasks/test/perf
| Command | mise-2026.6.3 | mise | Variance |
|---|---|---|---|
| install (cached) | 135ms | 135ms | +0% |
| ls (cached) | 59ms | 60ms | -1% |
| bin-paths (cached) | 63ms | 65ms | -3% |
| task-ls (cached) | 126ms | 127ms | +0% |
clap-sort requires short flags in declaration order; -g/-p/-e/-n/-y failed test_subcommands_are_sorted. Also remove .test.mise.toml at the end of the [system.packages] unit tests like the surrounding tests do — leaving it behind races config::tests::test_load's snapshot of loaded config files (the cause of the unit-macos failure). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- duplicate specs in one `mise system use` now last-wins consistently for both the config entry and the install request (previously the config kept the first version while both were installed) - the 'added to config without installing' note no longer fires in dry-run, where nothing was written - `mise system upgrade` re-queries package state after upgrading and reports only the packages whose version actually changed (or 'already up to date') instead of claiming every target was upgraded - docs: scope pinned-version upgrades to apt/dnf — pacman and brew skip pins with a warning Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Follow-up to #10326, adding the two commands discussed there:
mise system useandmise system upgrade.mise system usemise usefor system packages — writes entries to[system.packages]and installs whatever is missing in one step:@versionmirrorsmise use tool@version(@latest= no pin). brew is exempt from@parsing since@is part of brew formula names (brew:postgresql@17is the formula, not a pin) — and brew bottles can't be pinned anyway.MiseToml::update_system_package(toml_edit, preserves formatting/comments, implicit[system]header so only[system.packages]is rendered).resolve_target_config_pathlikemise set(-g,-p PATH,-e ENV).apt:lines from a Mac into a shared repo config is the point of a declarative file. Typo'd managers and bad specs still fail before anything is written.mise system upgradeRefreshes metadata and upgrades configured packages that are already installed; missing ones are skipped with a pointer at
mise system install:apt-get update+apt-get install -y --only-upgrade -- …dnf upgrade -y --refresh -- …pacman -Sy+pacman -S --noconfirm --needed -- …(partial-upgrade caveat documented)Implemented as a new
SystemPackageManager::upgrade()trait method defaulting toinstall()(exactly right for brew), with apt/dnf/pacman overrides.Refactor
The per-manager loop (manager filter, disabled/unavailable handling, pin filtering for managers without pin support, confirmation prompt) is factored out of
SystemInstallinto a sharedcli/system/driver.rsused by install, upgrade, and use — no behavior change forinstall.Tests
parse_use_spec(incl. brew@exemption, apt arch qualifiers,@latest),update_system_packageTOML snapshot. 27 system/config tests pass.e2e/cli/test_system_use(cross-platform, dry-run based);test_system_install_aptextended with realuse+upgraderuns.system use apt:bc brew:xzwrote both entries, noted apt as config-only, poured xz;system upgrade -nno-ops when current.🤖 Generated with Claude Code
Note
Medium Risk
New commands can run elevated package-manager operations (sudo/apt/dnf/pacman) and modify mise.toml; behavior is gated behind experimental
mise systembut mistakes could affect system packages on the host.Overview
Adds
mise system useandmise system upgradeto the experimental[system.packages]workflow, plus docs, usage specs, man pages, shell completion metadata, and e2e coverage.mise system usemirrorsmise use: it writes"manager:package" = "version"intomise.toml(via newMiseToml::update_system_package), with-g/-p/-etargeting like other write commands, then runs install for what’s missing. CLI specs usemanager:package[@version]; brew keeps@in formula names only. Unavailable managers on the current OS are recorded in config without failing install (cross-platform shared configs).mise system upgraderefreshes metadata and upgrades only packages already installed; missing ones are skipped. apt/dnf/pacman get manager-specific upgrade commands;SystemPackageManager::upgrade()defaults toinstall()(brew).Refactor: per-manager filtering, prompts, and pin handling move from
SystemInstallinto sharedcli/system/driver.rsfor install, upgrade, and use.Reviewed by Cursor Bugbot for commit ce506a4. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
mise system upgradeandmise system use;usepins packages to config (local/global/env) and installs missing packages;upgraderefreshes manager metadata and upgrades only already-installed configured packages.Documentation
Tests
system useandsystem upgrade.Completion