github jdx/mise v2026.9.15
v2026.9.15: vfox tools in OCI images, faster shell prompts, and safer dotfiles pattern matching

3 hours ago

mise oci build can now package tools installed by vfox plugins, and vfox plugins can repair an existing install when its tool options change. Shell prompts, cd, and settings loading are faster. Dotfiles include/exclude patterns now follow .gitignore rules for * and a leading /, which fixes a case where rollback could delete a live file.

Added

  • vfox tools in OCI images (experimental). mise oci build used to reject every tool installed by a vfox plugin. It now builds those tools into the image, with one layer per tool plus one layer per plugin at /mise/plugins/<name>/, so mise inside the image can resolve the tool without cloning the plugin. The plugin's env hook runs on the build host. Install-dir paths are rewritten to their in-image location, and mise warns when a value points into the host's home directory. Changing a plugin invalidates the reused layers of its tools on mise oci push. asdf plugins are still rejected. #13670

  • vfox plugins can repair installs that no longer match tool options. Plugins can add an optional hooks/mise_install_satisfied.lua hook that tells mise an installed version no longer matches its options, for example after a component is added to a gcloud config. mise install and auto-install (such as mise x) then rerun the plugin's PostInstall and the tool's postinstall script on the existing install without downloading it again. If the hook itself errors, mise warns and keeps the install. Plugins without the hook work as before. See docs/tool-plugin-development.md. #13668

    [tools]
    gcloud = { version = "latest", components = ["gke-gcloud-auth-plugin"] }
  • Git subdirectory installs for pypi:. Git sources now accept a #subdirectory= fragment (other fragment keys are passed through as written), and git+<scheme>:// URLs work without a trailing .git. Each subdirectory is its own tool with its own install directory. latest still means the repository's newest GitHub release, so pin a branch or commit if those releases predate the subdirectory. #13607 (@jakedgy)

    [tools]
    "pypi:git+https://github.com/runpantheon/ltui#subdirectory=ltui" = "main"
    "pypi:runpantheon/ltui#subdirectory=jtui" = "main"
  • max_version for registry backends. Registry entries can now set an exclusive max_version, alone or together with min_version, so older releases can come from a legacy backend and newer ones from another. It requires version_order = "semver". A locked backend is used only for versions it serves. #13676

  • Mac App Store names in mise bootstrap packages status. Installed mas: packages now show the app name next to the numeric ID (for example 1056643111 (Clocker)), and --json adds a name field. Apps that aren't installed still show only their ID. #13622

  • Registry: added sofka (#13612, @jylenhof), imessage-exporter (#13640, @i-api), and spotify-downloader (#13641, @i-api). nub 0.9.5 and later now installs from github:nubjs/nub, and the entry lists the nubr bin (#13643, @colinhacks). cocogitto now lists cog as its bin (#13657).

Changed

  • mise exec warns when a missing pinned tool falls back to PATH. When auto-install is off (exec_auto_install = false, auto_install = false, or auto_install_disable_tools) and the command belongs to a pinned tool that isn't installed, mise used to run a same-named binary from PATH without saying anything. It still runs it, but now prints a warning such as jq@1.7.1 is not installed and auto-install is disabled, so mise looks for jq on PATH instead. There's no warning when another configured version of the tool, a command wrapper, or a project env._.path entry provides the command. #13650, #13658
  • mise tasks validate fails on unparseable usage specs. A file task's #USAGE spec (or a TOML task's usage) that doesn't parse is now a usage-parse-error error, so validation exits 1, including with --errors-only. Before, it was only a warning and validation passed. mise run and mise tasks ls behave as before. CI that runs mise tasks validate will now fail on these specs. #13672
  • Linux GNU release binaries are linked non-PIE. Every mise command on Linux x64, arm64, and armv7 (GNU) now starts about 3 ms faster. The tradeoff is that ASLR no longer applies to mise's own code and data, though the heap, stack, and shared libraries are still randomized. musl, macOS, source builds, and cargo install are unchanged. #13687

Fixed

Dotfiles

  • * no longer crosses / in tracked include patterns. Capture and rollback used to disagree about what rules/*.md selected. After you widened the list, mise dot rollback to an older checkpoint could delete a nested file such as rules/deep/two.md. include now follows .gitignore rules: * stops at /, and you need ** to match nested files. exclude lists keep matching what they matched before, but mise now prints a deprecation warning when an exclusion depends on * crossing /. Use ** in those patterns instead. #13618
  • A leading / anchors include/exclude patterns to the entry root. Before, these patterns matched nothing at all. Now exclude = ["/cache"] skips only the top-level cache directory, and include = ["/rules/*.md"] works. In the global [history] exclude list, a leading / still means an absolute path. #13621

Tasks and config

  • Tasks in a conf.d folder fragment now run in that folder, with {{config_root}} and MISE_CONFIG_ROOT pointing there. Each folder's [task_config] applies only to its own tasks, so a fragment's includes no longer hides the default task directories like ~/.config/mise/tasks. #13662
  • A settings load that was already running could cache a stale snapshot after another thread changed settings, which dropped a just-applied override. This is fixed. #13646

Plugins and shims

  • mise now warns when an installed git plugin's origin URL or checked-out commit doesn't match its [plugins] entry. The warning appears in mise install, mise plugins install, and mise doctor. Related fixes #13663:
    • mise plugins install --force <name> now reinstalls from the [plugins] pin.
    • A failed ref checkout no longer leaves an unpinned clone behind.
    • Short SHAs fail with a clear error, since a full SHA is required.
    • Shorthand pins like owner/repo#v1.2.0 keep their ref.
  • On Windows, [wrappers.*] command wrappers (including the cargo wrapper that mr_boxington generates) now run through exe- and file-mode shims and mise x. Before, the real tool ran instead. #13673

Bootstrap

  • On apt systems, mise now simulates the install first and runs apt-get update once if the simulation fails. This fixes has no installation candidate failures on machines whose package lists cover only the install media. #13659
  • On macOS, mise bootstrap macos defaults now reads and writes the container plist for sandboxed apps such as Safari, which the app actually uses. Launch the app once first so its container exists. Writing another app's container may require Full Disk Access for your terminal. #13660
  • When mise bootstrap packages prune fails on a brew: formula it can't resolve, the error now names the config file that declares it. When the name is actually a cask, mise suggests brew-cask:<name>. #13661

Performance

  • Faster shell prompts. When nothing has changed, mise hook-env no longer loads all settings or starts the async runtime (6.6 ms to 4.9 ms on Linux in the PR's measurements), as long as hook_env.chpwd_only and hook_env.cache_ttl are unset. #13686
  • Faster cd with npm tools installed. The npm install health check now reads the virtual store's directory listing instead of calling stat on every package. #13685
  • Faster settings loading. Config discovery skips conf.d globs for directories that don't exist, which halves settings load time in deep checkouts. #13688
  • Faster brew-cask: lookups. Official casks are resolved from Homebrew's bulk cask.json index, cached locally and re-checked with a conditional request after 7.5 minutes, instead of one request per cask. In the PR's test, bootstrap packages status with 143 casks dropped from about 26s to about 2s. #13349 (@waynehoover)
  • Fixed slowdowns from deferred prunes. When a deferred-prune receipt from mise upgrade comes due but the version is still in use, mise now re-checks it once a day instead of on every command. This could make trivial commands about 9x slower. Pruning can now happen up to a day after the last reference is removed. #13674
  • mise ls, mise prune, and shim rebuilds scan install directories in a single pass. #13675

Full Changelog: vfox-v2026.9.16...v2026.9.15

💚 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.