github jdx/mise v2026.11.8
v2026.11.8: Bootstrap settings plugins, block edits in bootstrap files, and argv in command wrappers

51 minutes ago

This release extends mise bootstrap with experimental settings plugins, system-wide plugin directories, block edits for system files, and repositories and hooks in mise bootstrap plan. macOS preferences move to [bootstrap.settings.macos]. Command wrappers can now read the user's arguments, and a new setting keeps private GitHub repos off mise-versions. It also fixes problems in lockfiles, hook-env performance, tasks and backends.

Added

Bootstrap

  • Bootstrap settings plugins (experimental). A plugin can now apply one program's or desktop's settings from a [bootstrap.settings.<plugin>] section. The plugin reads and writes values, and mise compares them and writes only the keys that differ. A new settings bootstrap part runs after tools and package plugins. It works with --only settings and --skip settings, and the new mise bootstrap settings status and mise bootstrap settings apply [--dry-run] commands manage it directly. If a section's plugin is missing or can't run on this OS, mise skips the section and lists it as a follow-up. Settings plugins need experimental = true and are not yet included in mise bootstrap status or plan. #15621 (@jdx)

    [bootstrap.settings.omarchy.appearance]
    blur = true
    blur_strength = 4
  • System plugin directories. A distro or admin can install bootstrap package manager plugins once for every user on the machine. After the user's own plugins directory, mise searches /usr/share/mise/plugins and then $MISE_SYSTEM_DATA_DIR/plugins (default /usr/local/share/mise/plugins). MISE_SYSTEM_PLUGINS_DIRS replaces this list. These plugins need no [bootstrap.plugins] entry. A user plugin with the same name overrides a system plugin. mise uses a system plugin only if root or the current user owns it and its group and other users can't write to it. System plugin directories are ignored on Windows. mise plugins ls labels these plugins (system), and mise plugins update and uninstall skip them. #15620 (@jdx)

  • Block edits in [bootstrap.files]. An entry can now manage a marked block inside a file mise doesn't own, such as /etc/hosts, without replacing the rest of the file. mise uses sudo only when the current user can't make the change. If the file is missing, mise creates it with just the block. block can't be combined with source, content, replace, remove_empty or state = "absent", and you have to remove a block by hand for now. #15650 (@jdx, @aacebedo)

    [bootstrap.files."/etc/hosts"]
    id = "dev"
    block = """
    127.0.0.1 dev.local
    127.0.0.1 api.local
    """
  • Repositories and hooks in mise bootstrap plan. Repositories show as create, update or unchanged. A repository with local changes or conflicts shows as unknown, and --detailed-exitcode fails on it. Hooks appear with a new run action and a hook_phase field. They don't count as changes for --detailed-exitcode. The JSON summary gains a run count. Repository credentials are left out of the output. #15653 (@jdx, @azohra)

Tools, tasks and dotfiles

  • argv in command wrapper templates. A wrapper's args and env templates can now use argv, the list of arguments the user passed after the command name. The user's arguments are still forwarded unchanged after the wrapper's own args. command can't use argv. #15655 (@jdx, @andersonkrs)

    [wrappers.rails]
    command = "fnox"
    args = ["--profile={{ 'test' if argv[0] == 'test' else 'development' }}", "exec", "--", "rails"]
  • versions_host_exclude setting. This setting takes case-insensitive owner/repo glob patterns. mise looks up matching github: repos directly on GitHub instead of sending their names to mise-versions, and every other tool keeps using mise-versions. You can also set it with MISE_VERSIONS_HOST_EXCLUDE as a comma-separated list. #15666 (@jdx)

    [settings]
    versions_host_exclude = ["my-org/*", "other-org/internal-cli"]
  • Root package.json scripts in npm and Bun workspaces. A root package.json with a name is now a project in the experimental workspace task graph for every package manager, not only pnpm and Yarn. Its scripts run as <manager> run <script> --. With --affected, a change to a root lockfile now marks every Node workspace project as affected. #15616 (@jdx)

  • Warning before overwriting edited dotfile copies. If you edited a copy target after mise last wrote it, mise dot apply now warns before overwriting it. --dry-run and the confirmation list mark the file (edited since mise last wrote it). mise doesn't check targets it has no record of writing, or directory copies outside a dotfile group. #15600 (@jdx, @nahoj)

Changed

  • Clean environment for brew source builds. When mise bootstrap packages apply builds a brew formula from source, it now starts from a clean environment, as brew does. Only a short list of variables is kept, including HOME, locale, proxy and CA certificate variables, SSH_AUTH_SOCK and HOMEBREW_*. Variables such as GOROOT, CC, CFLAGS and PYTHONPATH no longer leak into the build and break it. A CC or CFLAGS exported in your shell no longer affects these builds. #15613 (@jdx)
  • Checks before mise bootstrap remote archives the source. It now refuses to send $HOME or /, which would include ~/.ssh and other credentials. It stops when the source is larger than 512 MiB or 100,000 files after excludes and lists the largest entries. It also prints archiving <dir> while it works. Pass --yes to skip these checks. #15607 (@jdx)
  • mise lock <tool> errors on unknown tools. It now fails when a tool argument doesn't match any tool configured in the project. Before, it exited 0 and wrote nothing, and with a partial match it ignored the unknown names. #15649 (@jdx)
  • gem: tools reuse Ruby's bundled gems. mise now installs gem: tools by setting GEM_HOME instead of passing --install-dir. This lets the gems bundled with Ruby satisfy dependencies, so, for example, gem:ceedling installs on Windows without MSYS2. Gems you installed globally can now also satisfy dependencies. #15644 (@jdx)
  • Archived asdf: backends removed from the registry. 90 asdf: backends whose plugin repositories are archived or gone were removed from the registry. This fixes oc@latest, among others. Each affected tool still has at least one other backend, so shorthands such as mise use oc resolve as before. #15642 (@jdx)

Deprecated

  • macOS preferences under [bootstrap.macos]. The dock, finder, keyboard, trackpad, defaults, defaults_entries and login_items tables now belong under [bootstrap.settings.macos]. mise reads both spellings, and the new one wins when a key is set in both places. Older mise versions ignore the new spelling, so keep the old one until every machine runs this version. mise won't warn about the old spelling until 2027.5.0. [bootstrap.macos.launchd.agents] stays where it is. #15622 (@jdx)

    # before
    [bootstrap.macos.dock]
    autohide = true
    
    # after
    [bootstrap.settings.macos.dock]
    autohide = true

Fixed

Lockfiles and installs

  • On private GitLab, GitHub and Forgejo releases, mise lock now sends the forge token when it fetches the release's checksum file, such as SHA256SUMS. Before, it fell back to downloading and hashing every archive. On private releases, mise install now also checks downloads against the published checksum. #15637 (@jdx, @rickeyski)
  • mise install --locked now rejects a vfox download whose checksum differs from the one in mise.lock. Only sha256 and sha512 are supported. #15648 (@jdx)
  • mise lock now records artifact bundle URLs and checksums for spm: tools on every requested platform. Before, regenerating mise.lock on one machine dropped the entries for other platforms. #15646 (@jdx, @zunda-pixel)
  • If the project's python is a plain release such as 3.12 and isn't installed, mise lock now resolves pypi: dependency graphs with that version instead of the first Python on PATH. If resolution fails, mise keeps the existing lock entry instead of removing it. #15657 (@jdx)
  • mise uninstall now removes the dangling alias links and the empty tool folder after uninstalling the last version. #15605 (@jdx)
  • On Windows, http: tools that use shared_extraction and download a raw file now hard link it instead of keeping a second copy. #15647 (@jdx)
  • With MISE_OFFLINE=1, mise now runs an installed pipx: tool from a GitHub git URL whose repo has no releases. #15602 (@jdx)
  • mise hook-env no longer reports an npm tool installed from a tarball URL at latest as missing. #15643 (@jdx)
  • Node's npm wrapper now works when called through a symlink in another directory. #15664 (@jdx)
  • mise bootstrap no longer leaves a lock file in each formula's Homebrew Cellar rack, which kept uninstalled formulae in brew list. Leftover lock files are removed on the next install. #15597 (@jdx, @SimenB)

Config and environment

  • A project's [tool_alias] now overrides a global alias with the same name, for both backends and version aliases. #15615 (@jdx)
  • minimum_release_age_excludes now accepts [tool_alias] names and exempts the backend the alias points to, whichever name the tool is requested by. #15638 (@jdx)
  • In the interactive config editor, "Load .env" now writes _.file instead of the deprecated [env.mise] table. #15640 (@jdx)
  • The hook-env fast path no longer runs fully when unrelated files appear or disappear in ancestor directories. For example, zsh's share_history lock file caused a full run at every prompt. New config files and lockfiles are still picked up. #15667 (@jdx)
  • On WSL, mise activate and mise hook-env no longer resolve /mnt/<drive> PATH entries. This removes hundreds of milliseconds per prompt when the Windows PATH is appended. #15665 (@jdx)
  • mise doctor no longer warns about the backend that a packageManager checksum in package.json forces for yarn, npm, pnpm or bun. #15604 (@jdx)
  • On macOS, task sandbox paths that start with ./, such as allow_read = ["./"], now allow access as intended. #15599 (@jdx)

Tasks and completions

  • Lua file tasks now recognize --MISE and --USAGE header comments. #15659 (@jdx, @rikonor)
  • In a monorepo, shell completion now offers bare root task names, such as test, in addition to :test and //:test. #15598 (@jdx)
  • After :::, completion now offers task names and then the flags of the next task, not more arguments for the previous one. #15614 (@jdx)
  • mise cache task '<pattern>' now reads the task cache once instead of once per matching task. With large caches this cuts the time from minutes to seconds. #15671 (@jdx)

Documentation

  • The docs now explain that global_config_file doesn't hide ~/.config/mise from projects under your home directory. #15639 (@jdx)

Full Changelog: v2026.11.7...v2026.11.8

💚 Sponsor mise

mise is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.

If mise saves you or your team time, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep mise fast, free, and independent.

Don't miss a new mise release

NewReleases is sending notifications on new releases.