v2026.4.12

jdx/misev2026.4.12Apr 15, 2026by mise-en-dev

AI Summary

Adds OS/architecture filtering for tool configuration, defaults task confirmation prompts to 'no', and improves npm supply chain security.

Key Highlights

  • Tool `os` field now supports `os/arch` compound entries like `macos/arm64`.
  • Task `confirm` can now default to `no` for destructive actions.
  • npm supply chain protection now uses the purpose-built `--min-release-age` flag.

New Features

  • OS/architecture compound syntax in tool filtering
  • Task confirmation default
  • npm `--min-release-age` for supply chain protection
  • New registry entries (openfga, copilot, trzsz-go)

Full Release Notes

This release adds OS/architecture compound filtering for tool configuration, lets task confirmation prompts default to "no" for destructive actions, and upgrades npm supply chain protection to use the recommended `--min-release-age` flag. It also fixes several bugs including a panic on empty config filename overrides and circular shim symlinks.

## Highlights

- Tool `os` field now supports `os/arch` compound entries like `"macos/arm64"` or `"linux/x64"`, letting you restrict tools to specific platform and architecture combinations.
- Task `confirm` can now default to "no", so destructive tasks require the user to explicitly opt in rather than just pressing Enter.
- npm supply chain protection now uses the purpose-built `--min-release-age` flag on npm 11.10.0+, aligning with npm's recommended approach.

## Added

- **OS/architecture compound syntax in tool filtering** -- The `os` field on tool entries now accepts `os/arch` entries (e.g. `os = ["linux", "macos/arm64"]`). When an entry contains `/`, both the OS and architecture must match. Plain OS entries continue to match any architecture. OS aliases (`darwin` to `macos`) and arch aliases (`aarch64` to `arm64`, `x86_64`/`amd64` to `x64`) are normalized automatically. [#9088](https://github.com/jdx/mise/pull/9088) by @RobertDeRose

  ```toml
  [tools]
  # Install on all Linux machines and Apple Silicon Macs, but skip Intel Macs
  hk = { version = "latest", os = ["linux", "macos/arm64"] }
  ```

- **Task confirmation default** -- The `confirm` field on tasks now accepts a map with `message` and `default` keys, allowing you to set whether the prompt defaults to "yes" or "no". This is useful for destructive tasks where you want the user to explicitly confirm. The existing string syntax continues to work and defaults to "yes" for backwards compatibility. [#9089](https://github.com/jdx/mise/pull/9089) by @roele

  ```toml
  [tasks.release]
  confirm = { message = "Are you sure you want to cut a release?", default = "no" }
  run = "scripts/release.sh"
  ```

- **npm `--min-release-age` for supply chain protection** -- When `install_before` is configured, mise now uses npm's `--min-release-age=<days>` flag for npm 11.10.0+, which is the flag npm recommends for supply chain protection. Older npm versions continue to use `--before`. Sub-day windows also fall back to `--before` since `--min-release-age` is day-granular. [#9072](https://github.com/jdx/mise/pull/9072) by @webkaz

- **New registry entries** -- Added `openfga` ([#9084](https://github.com/jdx/mise/pull/9084) by @mnm364), `copilot` ([#9082](https://github.com/jdx/mise/pull/9082) by @risu729), and `trzsz-go` ([#9083](https://github.com/jdx/mise/pull/9083) by @ZeroAurora).

## Fixed

- **Panic on empty `MISE_OVERRIDE_CONFIG_FILENAMES`** -- Setting `MISE_OVERRIDE_CONFIG_FILENAMES=""` (e.g. to clear it for a child process) caused a panic because the empty string was injected as a config path, which resolved to the filesystem root and had no parent directory. Empty segments from empty strings, leading/trailing colons, and consecutive colons are now filtered out. [#9076](https://github.com/jdx/mise/pull/9076) by @baby-joel

- **Circular shim symlinks when shims are on PATH** -- When `mise activate --shims` put the shims directory on PATH and a `mise` shim existed (e.g. from having `core:rust` in the toolset after a cargo install), `reshim` would create shims pointing to the mise shim instead of the real binary, including a circular `mise` to `mise` symlink that broke all shims. `doctor` would also falsely report all shims as "missing". Both now use `which_no_shims` to resolve the real mise binary. [#9071](https://github.com/jdx/mise/pull/9071) by @kevinswiber

- **`__MISE_EXE` not exported in bash activate** -- The `__MISE_EXE` variable was not exported in the bash activation script, so child shells couldn't access it and the `mise` function failed. Additionally, when ARGV0 was a bare name (e.g. `mise`) instead of an absolute path, PATH changes could break execution. The variable is now properly exported and bare names are resolved via `which`. [#9081](https://github.com/jdx/mise/pull/9081) by @fru1tworld

- **Aliased installs sharing a backend were deduplicated** -- When multiple tool aliases (e.g. `iii` and `iii-console`) resolved to the same backend and version (e.g. `github:iii-hq/iii@latest`), the install scheduler collapsed them into a single job and skipped the second install. The dependency graph now keys on the configured tool name plus version, so alias-specific options like `asset_pattern` and `bin_path` are preserved. [#9093](https://github.com/jdx/mise/pull/9093) by @jdx

## New Contributors

- @kevinswiber made their first contribution in [#9071](https://github.com/jdx/mise/pull/9071)
- @webkaz made their first contribution in [#9072](https://github.com/jdx/mise/pull/9072)
- @RobertDeRose made their first contribution in [#9088](https://github.com/jdx/mise/pull/9088)

**Full Changelog**: https://github.com/jdx/mise/compare/v2026.4.11...v2026.4.12