v2026.8.15: Dotfiles diff and capture, scoped config updates, and per-tool postinstall hooks
- Add `mise bootstrap dotfiles diff` to preview exactly what apply would change without writing anything
- Add `mise bootstrap dotfiles add --changed` to capture every drifted copy-mode target back into its source in one command
- Add `manifest = "git"` option for directory `copy` and `symlink-each` entries to manage only paths returned by `git ls-files`
- Add automatic reconciliation of stale symlinks when a profile change points a target at a different source
- Add `mise bootstrap --from <git-url>` to clone a setup/dotfiles repo and run bootstrap from that checkout
- Add `mise use --postinstall <COMMAND>` to attach a per-tool post-install hook that runs when that tool is installed or reinstalled
- Add `--append` and `--remove` options to `mise config set` for list-like keys
- Add explicit `--global` and `--system` targeting for `mise config get` and `mise config set`
- Add `config_source` template variable that references the absolute path of the config file the template lives in
- Add `task_source_files(only_changed=true)` to return only sources written since the task last succeeded
- Add `release_url` field to `mise outdated --json` output pointing at the release page for the offered version
- Change `mise upgrade` to no longer delete replaced installs immediately, instead scheduling them for removal after `upgrade.prune_after` (default 24h) when `upgrade.auto_prune` is on
- Add `MISE_CONFIG_FILE`, `MISE_GLOBAL_CONFIG_FILE`, `MISE_CONFIG_ROOT`, and `MISE_PROJECT_ROOT` environment variables to tool postinstall hooks
- Fix `.env` files written as UTF-16 to be decoded and loaded instead of being silently dropped
- Fix UTF-16 task files to receive a clear hint to save as UTF-8
- Fix `mise install --dry-run` to not claim it would install a tool that cannot actually be installed on the current platform
- Fix `mise exec` to report clearly when a requested tool is not available on the current platform
From mise
This release expands the dotfiles/bootstrap workflow with previews, bulk capture, git-tracked manifests, and profile reconciliation, adds scoped config collection updates and per-tool postinstall hooks, and rounds it out with a large batch of fixes across tasks, schema validation, Windows, lockfiles, and shims.
Highlights
- Dotfiles management grows a full preview-and-capture workflow:
mise bootstrap dotfiles diff, bulkadd --changed, git-tracked directory manifests, and automatic reconciliation when a profile switches a target's source. mise config setlearns idempotent list updates (--append/--remove) and explicit--global/--systemtargeting, andmise usegains per-tool--postinstallhooks.- Safer upgrades: replaced tool versions now linger for a grace period instead of being deleted immediately, so a bad upgrade is easier to recover from.
Added
-
dotfiles: New
mise bootstrap dotfiles diffpreviews exactly whatapplywould change without writing anything, printing unified content patches for copy, template, and inline entries and structural summaries for symlinks and directories. Optional target filters use the same selection semantics asapply. (#12511 by @jdx) -
dotfiles:
mise bootstrap dotfiles add --changedcaptures every drifted copy-mode target back into its source in one command, without naming each path. Directory copies, symlinks, templates, and inline content are skipped, and untrusted configs are blocked. (#12512 by @jdx) -
dotfiles: Directory
copyandsymlink-eachentries can now setmanifest = "git"to manage only paths returned bygit ls-files, so a dotfiles repo thatgitignores everything and force-adds selected paths no longer traverses (or links) ignored home-directory content. Links are removed when a file drops out of the index. (#12523 by @jdx) -
dotfiles:
symlink-eachapply now reconciles stale links when a profile change (for example togglingMISE_ENVbetween home and work) points a target at a different source. Only links still pointing at the previously recorded source are removed; unmanaged paths and paths desired by another active source are left alone, and dry-run previews the removals. (#12524 by @jdx) -
bootstrap:
mise bootstrap --from <git-url>clones a setup/dotfiles repo (into$MISE_DATA_DIR/bootstrap-repoby default, or--from-dir), then runs bootstrap from that checkout. Existing checkouts are reused when the origin matches,--updatefast-forwards them, and--dry-runonly prints the plannedgit clone/git pull. (#12525 by @jdx) -
use:
mise use --postinstall <COMMAND>attaches a per-tool post-install hook that runs only when that tool is installed or reinstalled. Repeat the flag before each tool to give each its own hook. (#12609 by @jdx)mise use --postinstall "mbx setup --defaults" mr-boxington -
config:
mise config setgains--appendand--removefor list-like keys (append without duplicates, remove matching entries, promote scalars to arrays as needed) while preserving TOML comments and formatting, plus explicit--global/--systemtargeting forconfig get/set. Tool postinstall hooks now also receiveMISE_CONFIG_FILE,MISE_GLOBAL_CONFIG_FILE,MISE_CONFIG_ROOT, andMISE_PROJECT_ROOT. (#12603 by @jdx) -
config: Templates can now reference
config_source, the absolute path of the config file the template lives in (not resolved through symlinks). This lets a shared config symlinked intoconf.dadd its own real directory toPATH, for example{{ config_source | canonicalize | dirname }}/bin. Available inmise.toml,.tool-versions,[env]directives, and[settings.age]. (#12454 by @Marukome0743) -
task:
task_source_files(only_changed=true)returns only the sources written since the task last succeeded, so linters and formatters can run against just what changed. A failed run keeps its files outstanding until the task passes. (#12470 by @Marukome0743) -
outdated:
mise outdated --jsonnow includes arelease_urlfield pointing at the release page for the offered version (from the versions host, aqua, GitHub/GitLab, or the rust core plugin). The key is omitted rather than null when no page is available. (#12494 by @Marukome0743)
Changed
- upgrade:
mise upgradeno longer deletes the replaced install immediately. Whenupgrade.auto_pruneis on, the old version stays on disk and is scheduled for removal afterupgrade.prune_after(default 24h), cleaned up opportunistically on later runs.--prunestill removes immediately and--no-prunekeeps the old tree with no scheduled cleanup.mise lssurfaces deferred removals. (#12593 by @jdx)
Fixed
- env,tasks:
.envfiles written as UTF-16 (the default from Windows PowerShell 5.1's>andOut-File) are now decoded and loaded instead of being silently dropped, and a UTF-16 task file now gets a clear hint to save it as UTF-8. (#12507 by @JamBalaya56562) - install:
mise install --dry-runno longer claims it would install a tool that cannot actually be installed on this platform. (#12568 by @JamBalaya56562) - exec:
mise execnow reports clearly when a requested tool is not available on the current platform. (#12547 by @JamBalaya56562) - config: Request-specific tool options are preserved rather than dropped during config merges. (#12060 by @risu729)
- config: A bare
tool_aliasvalue is now resolved through the registry. (#12506 by @Marukome0743) - config: Minimum-release-age exclusions from multiple configs are merged instead of overwritten. (#12460 by @jdx)
- lockfile: Version ties are broken correctly when a legacy lockfile answers
latest, and links belonging to other backends are ignored. (#12583, #12605 by @Marukome0743, @jdx) - monorepo: Idiomatic version files are resolved from the task's own config root. (#12565 by @kaii-zen)
- task: Several ordering fixes so injected and dependency tasks keep their intended slots, tasks that link back into themselves are skipped, and
taskkilloutput is suppressed on Windows. (#12450, #12466, #12482, #12510, #12563 by @Marukome0743, @jrandolf, @JamBalaya56562, @sortA0329) - shims/generate: Arguments are now delivered intact for
file-mode shims and Windows launchers, andmise generateexplains when a--mise-binpath has no Windows launcher. Non-executable system fallbacks are skipped. (#12502, #12463, #12496, #12545 by @JamBalaya56562, @jdx) - http: Raw binaries are copied on Windows where a junction cannot name a file, and a download that fails because the path is too long now explains itself. (#12465, #12550 by @Marukome0743, @JamBalaya56562)
- link/file: Links whose target no longer exists can now be shown and removed. (#12468, #12469 by @JamBalaya56562)
- trust: The ignore list is now read by what its entries point at, matching how trust links are stored. (#12428 by @JamBalaya56562)
- watch: The terminal is restored when the watched process is signalled. (#12451 by @Marukome0743)
- activate: The pwsh deactivation preamble no longer pollutes
$Error. (#12483 by @JamBalaya56562) - backend: Rolling updates behind a versions host are now detected. (#12440 by @jdx)
- github: Stale cached attestations are retried. (#12495 by @jdx)
- ls-remote: Recorded listing errors now cause a failure instead of returning stale/empty results. (#12551 by @jdx)
- npm: Dangling aube-backed tool installs are repaired. (#12570 by @jdx)
- bootstrap: Brew cask dependencies are preserved during prune. (#12461 by @jdx)
- azure: The CLI now includes pip for extension support. (#12555 by @esteve)
- registry: Windows/arm64 can fall back to x64 backends, as aqua already does. (#12560 by @JamBalaya56562)
- doctor: The self-update leftover check is gated so it does not fire for installs that manage updates elsewhere. (#12438 by @salim-b)
- schema: Several JSON schema corrections so registry, plugin, tool-option, and settings definitions match what the build consumers actually accept. (#12514, #12515, #12520, #12522, #12527 by @risu729)
Performance
- brew: Homebrew bootstrap bottles are now downloaded concurrently (bounded by
MISE_JOBS), while pouring, source builds, and prefix linking stay in dependency order. (#12604 by @jdx)
Registry
New tools: pkgx, onefetch, syncthing, ols, spin-framework, cursor-agent, 7zip, mosh, pastel, broot, exiftool, spotify-player, yt-dlp-nightly, and cliamp. magika and sbt now install from their GitHub releases, and pre-commit uses the pipx backend on Windows. Various dependency and OS-limit cleanups were also applied. (#12272, #12437, #12448, #12484, #12485, #12478, #12486, #12532, #12535, #12533, #12538, #12539, #12542, #12581, #12553, #12567, #12549)
New Contributors
- @sortA0329 made their first contribution in #12563
- @seuros made their first contribution in #12519
- @pb3975 made their first contribution in #12478
- @ThorstenHans made their first contribution in #12485
Full Changelog: https://github.com/jdx/mise/compare/v2026.8.14...v2026.8.15
💚 Sponsor mise
mise is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools. Development is funded by sponsors.
If mise saves you or your team time, please consider sponsoring at jdx.dev. Individual and company sponsorships keep mise fast, free, and independent.