v2026.9.10
CloakHQ/CloakBrowserv2026.9.10Sep 16, 2026by mise-en-dev
Upgrading?
AI Summary
Adds shims exclusion, npm exotic dependency approval, bulk dotfiles conflict resolution, and fixes Windows Ctrl-C handling.
Key Highlights
- Control over PATH shims with `shims.exclude`
- Approval for non-registry npm dependencies with `allow_exotic_deps`
- Bulk conflict resolution for dotfiles with `--take-remote-all`
- Clean Windows Ctrl-C handling for tasks
New Features
- `settings.shims.exclude` to prevent shims for specific names
- `allow_exotic_deps` for npm dependencies from git/tarball URLs
- Bulk dotfiles conflict flags: `--take-remote-all` and `--keep-local-all`
- Template rendering for systemd and launchd units
- vfox plugin hooks: `cmd.stream` and `cmd.exec` timeout
Full Release Notes
New settings let mise manage a tool without claiming its command names (`shims.exclude`) and approve non-registry npm dependencies (`allow_exotic_deps`), `mise dot pull` can decide every sharing conflict at once, and vfox plugin hooks gain `cmd.stream` plus a working `cmd.exec` timeout. On the fix side, `mise run` now survives Ctrl-C on Windows instead of orphaning `cmd.exe`, fish shells launched through shims start much faster with correct PATH order, and several task-resolution, lockfile, and Homebrew cask bugs are corrected.
## Highlights
- **Control over what mise puts on PATH and what it installs:** `settings.shims.exclude` keeps names like `python` resolving to the OS while mise still manages the tool; `allow_exotic_deps` approves specific npm packages fetched from git or tarball URLs; exact `packslip:` pins install during a `minimum_release_age` cooling window; and `mise upgrade --bump` keeps SemVer build metadata such as `+k3s1`.
- **Dotfiles sharing on a second machine:** `mise dot pull --take-remote-all` / `--keep-local-all` resolve all conflicts in one command, paths that cannot be decided are held rather than aborting the pass, and a directory sitting where a tracked file belongs is now reported as exactly that.
- **Task and shell reliability:** Windows Ctrl-C shuts tasks down cleanly, a task's own name always beats another task's alias, glob expansions no longer drop file tasks, Bash completion of `ns:task` names no longer duplicates the prefix, and fish startup through `mise exec`/shims is no longer quadratic in the number of tools.
## Added
- **shims:** `settings.shims.exclude` (env `MISE_SHIMS_EXCLUDE`) lists command names mise never creates shims for. The tool stays installed and version-qualified names like `python3.12` still resolve through mise, but the excluded name resolves to whatever else is on `PATH`; existing shims for those names are removed on the next `mise reshim`. Note that under `mise activate` without `--shims` the tool's `bin` directory still joins `PATH`, and excluding `python3` means `python3 -m venv` silently uses the system interpreter. ([#13266](https://github.com/jdx/mise/pull/13266))
```toml
[settings.shims]
exclude = ["python", "python3", "pip", "pip3"]
```
- **npm:** `allow_exotic_deps` approves dependencies that aube's `blockExoticSubdeps` gate would otherwise block because they come from a git, `file:`, or direct tarball URL. List package names to exempt only those (the gate stays on for the rest of the graph), or set `true` to exempt the whole graph. Applies to the `aube` and `aube_cli` installers. Embedded-aube installs now also warn when `install_env` is set, since it never reached the in-process installer. ([#13231](https://github.com/jdx/mise/pull/13231))
```toml
[tools]
"npm:@gmickel/gno" = { version = "2.3.0", allow_exotic_deps = ["xlsx"] }
```
- **dotfiles:** `mise dot pull --take-remote-all` and `--keep-local-all` decide every pending conflict at once, with per-path `--take-remote`/`--keep-local` naming exceptions. The two blanket flags are mutually exclusive, and paused-sync and adoption messages now point at them. ([#13233](https://github.com/jdx/mise/pull/13233))
```sh
mise dot pull --take-remote-all --keep-local ~/.bashrc
```
- **bootstrap:** Every string value in `[bootstrap.linux.systemd.units]` and `[bootstrap.macos.launchd.agents]` is rendered as a template before the unit file or plist is written, so `{{ config_root }}/.env` in `environment_file` resolves to the declaring config's directory. Values without template syntax (including `%h` and `$HOME`) pass through untouched, `exec()` is rejected, and a unit whose template fails is skipped by name without blocking the others. `[bootstrap.services]` is not yet templated. ([#13227](https://github.com/jdx/mise/pull/13227))
- **hooks:** Each `MISE_INSTALLED_TOOLS` entry passed to `postinstall` hooks now carries `requested_version` (for example `latest`, `22`, or an alias) alongside the resolved `version`, so a hook can tell a floating request from a pin. The field is always present; existing hooks reading `name`/`version` are unaffected. ([#13274](https://github.com/jdx/mise/pull/13274))
- **vfox plugins:** `cmd.stream` runs a command with stdin connected and stdout/stderr streamed to the terminal, for hooks that genuinely need input such as a login or license prompt; it pauses the progress renderer and holds the terminal exclusively while it runs. `cmd.exec` and `os.execute` now detach stdin unless `--raw` is set, matching every other subprocess mise spawns, so a plugin that read stdin through `os.execute` should switch to `cmd.stream`. ([#13261](https://github.com/jdx/mise/pull/13261))
- **vfox plugins:** The `timeout` option on `cmd.exec` (and `cmd.stream`) now works instead of being silently ignored. It takes seconds (fractions allowed); on expiry the spawned shell is killed and the call raises a catchable error. Only the shell mise spawned is killed, so background processes it started may keep running. ([#13263](https://github.com/jdx/mise/pull/13263))
```lua
local ok, err = pcall(cmd.exec, "some-tool sync", { timeout = 30 })
```
## Fixed
- **task:** On Windows, pressing Ctrl-C during `mise run` no longer kills mise immediately and leaves a `cmd.exe` behind stuck on `Terminate batch job (Y/N)?`. The first Ctrl-C lets running commands exit and stops scheduling new tasks; a second one takes the remaining process tree down. Tasks ended by the console are reported as interrupted instead of failing with exit code -1073741510. ([#13226](https://github.com/jdx/mise/pull/13226))
- **task:** A task's own name now always wins over another task's alias. Previously a parent config's `tests` task with `alias = "test"` could shadow a `test` task in the current directory, depending on alphabetical order. Aliases still resolve wherever no task claims that name. ([#13230](https://github.com/jdx/mise/pull/13230))
- **task:** Glob expansions such as `mise run '//...:lint'` or `'*:lint'` no longer silently drop file tasks (`mise-tasks/lint.sh`) when a sibling package has an exact match. The same-package dedup that stops `hello` and `hello.sh` running twice is preserved. ([#13277](https://github.com/jdx/mise/pull/13277))
- **completions:** Bash completion of namespaced tasks like `update:deps:no<TAB>` no longer produces `update:deps:update:deps:no-cooldown`. Reinstall the script with `mise completion bash --install` if yours predates the prefix-aware wrapper. ([#13276](https://github.com/jdx/mise/pull/13276))
- **exec:** Launching fish through `mise exec` or a shim emitted one `fish_add_path` per directory, which made startup quadratic (over 1s with ~80 tools) and reversed mise's PATH order relative to bash. A single batched call restores both. ([#13235](https://github.com/jdx/mise/pull/13235))
- **dotfiles:** A blanket `--take-remote-all`/`--keep-local-all` no longer aborts the whole pass when one path cannot be decided (a directory on the live side, or unsaved local changes under `--keep-local-all`). Decisions for the other conflicts are recorded, and the error names the held paths so fixing just those finishes the setup. ([#13239](https://github.com/jdx/mise/pull/13239), [#13242](https://github.com/jdx/mise/pull/13242))
- **dotfiles:** A directory or unreadable path where the repository has a file is now reported by `mise dot conflicts`, `mise dot status`, and `mise doctor` as exactly that, with advice to move it aside, instead of as a "changed type" conflict that `--take-remote`/`--keep-local` cannot resolve. Git or process failures while reading a live file now stop the sync with their own error instead of posing as a conflict. ([#13249](https://github.com/jdx/mise/pull/13249))
- **upgrade:** `mise upgrade --bump` preserves SemVer build metadata when rewriting a pin, so k3s bumps to `1.37.0+k3s1` rather than a nonexistent `1.37.0`, and Temurin keeps its `+7` build number. Coarser pins like `1.36` still bump to `1.37`. ([#13258](https://github.com/jdx/mise/pull/13258))
- **packslip:** An exactly pinned version (for example `"packslip:github.com/jdx/hk" = "2.0.1"`) now installs and locks while still inside its `minimum_release_age` window, as the setting documents. Fuzzy requests such as `"2"` or `latest` still wait out the cutoff. ([#13251](https://github.com/jdx/mise/pull/13251))
- **install:** `MISE_LOCKED=1 mise install <tool>` no longer warns about unrelated (often global) tools missing from the lockfile; installing the requested tool or a bare `mise install` still fails if that tool is not locked. ([#13259](https://github.com/jdx/mise/pull/13259) by @jamescassell)
- **pypi:** `mise lock` no longer fails when a `with`/`expose` requirement is pinned to a release needing a newer Python than the tool itself (e.g. `mkdocs` 1.6.1 with `mkdocstrings==1.0.6`). The sidecar's `requires-python` is now intersected across every pinned requirement; unpinned requirements and pins behind an interpreter marker leave the range alone. Existing lockfiles remain valid. ([#13252](https://github.com/jdx/mise/pull/13252))
- **aqua:** With `minimum_release_age` set, the latest release no longer falls back to an older version when the hosted version list lags GitHub. The release date from the `/releases/latest` response mise already fetched is used directly, with no extra requests. ([#13228](https://github.com/jdx/mise/pull/13228))
- **backend:** Tools whose registry entry splits across backends at a version boundary (like `hk`) now list versions from the backend that actually resolves, so `mise ls-remote hk@1.57` and `mise latest hk@1.57` return `1.57.0` instead of nothing. Also covers backends promoted by `MISE_DISABLE_BACKENDS`, platform-scoped entries, and lockfile pins. ([#13238](https://github.com/jdx/mise/pull/13238))
- **http:** GitHub answers an exhausted rate limit with 403 rather than 429, so mise never retried it. A 403 carrying `x-ratelimit-remaining: 0` or `retry-after` is now retried like a 429 under `http_retries`; a 403 with quota remaining is still treated as a refusal. Default backoff (~5s total) will not outlast a long reset, but brief contention no longer fails an install outright. ([#13256](https://github.com/jdx/mise/pull/13256))
- **skills:** `mise skills ls` and `mise skills sync` now warn when a packslip declares a skill the install does not hold, with the reason (`skills.fetch` off, `packslip.exec` off, or a failed download), instead of looking identical to "no skills declared". After an install with `skills.auto_sync` off, a one-time hint points at `mise skills sync`. `--json` output is unchanged. ([#13275](https://github.com/jdx/mise/pull/13275))
- **brew:** `adopt` is now honored for casks named on the command line (`mise bootstrap packages apply brew-cask:menuwhere`) and for tap-qualified names and aliases like `brew-cask:homebrew/cask/firefox`, so existing app bundles are adopted rather than replaced and macOS keeps their Privacy & Security grants. ([#13262](https://github.com/jdx/mise/pull/13262))
- **brew:** Tap formulae declaring requirement symbols such as `depends_on :macos` no longer make `bootstrap packages` try to fetch a formula named `macos` and abort the whole run with a 404. ([#13240](https://github.com/jdx/mise/pull/13240) by @waynehoover)
- **brew:** Tap cask metadata evaluation now understands `appdir` and `HOMEBREW_PREFIX` interpolation, and casks whose app bundle sits in a nested archive directory (`app "nested/Example.app"`) install as `Example.app` instead of being rejected as a relative target; duplicate app targets are rejected before anything is downloaded. ([#13138](https://github.com/jdx/mise/pull/13138) by @Guria, [#13199](https://github.com/jdx/mise/pull/13199) and [#13200](https://github.com/jdx/mise/pull/13200) by @soodoh)
- **bootstrap:** Selecting a Ruby to evaluate third-party Homebrew taps skips mise shims, which the metadata sandbox could not load, so package bootstrap no longer fails when Ruby is installed through mise. ([#13198](https://github.com/jdx/mise/pull/13198) by @jacobbednarz)
## Documentation
- The dotfiles history guide now explains encryption recipients (SSH keys, `age-keygen`, recovery keys) and warns that passphrase-protected SSH keys and plugin-only recipients cannot decrypt in the background; the setup guide covers adopting onto a machine that already has the files and using non-GitHub Git hosts. ([#13232](https://github.com/jdx/mise/pull/13232))
- The PyPI backend's locking limitations now point at the lockable `with`, `expose`, and `dependency_prereleases` options. ([#13222](https://github.com/jdx/mise/pull/13222))
## New Contributors
* @waynehoover made their first contribution in [#13240](https://github.com/jdx/mise/pull/13240)
**Full Changelog**: https://github.com/jdx/mise/compare/v2026.9.9...v2026.9.10
## 💚 Sponsor mise
mise is built and maintained by [@jdx](https://github.com/jdx), an open source developer at [**entire.io**](https://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](https://jdx.dev/sponsors.html). Your support funds ongoing development and helps keep mise fast, free, and independent.
Related Repositories
public-apis/public-apis★ 491,220
A collective list of free APIs
NousResearch/hermes-agent★ 256,091
The agent that grows with you
yt-dlp/yt-dlp★ 200,268
A feature-rich command-line audio/video downloader
microsoft/markitdown★ 191,564
Python tool for converting files and office documents to Markdown.
Significant-Gravitas/AutoGPT★ 187,699
AutoGPT is the vision of accessible AI for everyone, to use and to build on. Our mission is to provide the tools, so that you can focus on what matters.