Releases: jdx/mise
Release list
v2026.8.2: Declarative System Bootstrap
This release turns mise bootstrap into a full declarative host-provisioning system: alongside packages, mise can now converge privileged files, Linux users and groups, systemd services, Docker Compose projects, and firewall rules — all with plan/apply/status workflows, secret handling, and the ability to run over SSH against remote hosts. It also makes Ruby's ruby.compile=false a strict precompiled-only mode and lands a batch of install and lockfile fixes.
Highlights
mise bootstrapgains a Terraform-style declarative model. A newmise bootstrap planpreviews changes with table or JSON output and detailed exit codes, and each resource type has its ownapply/statuscommands that converge only when something actually differs.- Bootstrap can now provision far more than tools and packages: privileged files and directories, Linux accounts, systemd services, Compose projects, and host firewall rules, with dependency ordering, fail-closed safety checks, and secret inputs sourced from environment variables (never stored in config).
- The same bootstrap project can be applied to remote machines over SSH via
mise bootstrap remote, including automatic detection of the target's OS/arch/libc and signature-verified download of the matching mise binary.
Added
- bootstrap: declarative resource plans.
mise bootstrap planpreviews what bootstrap would change before applying, with table or--jsonoutput and optional--detailed-exitcode(0 = no changes, 2 = changes, 1 = error). Resources have stable identities, dependency graphs, and validation for duplicates, missing dependencies, and cycles. (#11669 by @jdx) - bootstrap: manage privileged files and directories via
[bootstrap.files]and[bootstrap.directories], with content (inline or from a source), ownership, mode, and explicitpresent/absentstate. Writes are atomic, removal is opt-in (and requiresrecursive = truefor non-empty directories), and privileged work runs through hidden helpers that never expose file content in argv or logs. (#11674 by @jdx) - bootstrap: secret inputs for managed files.
[bootstrap.secrets]references sensitive values through environment variables so nothing is stored in config, and managed files withtemplate = truecan render them via{{ secret(name="...") }}.mise bootstrap secrets statusreports availability without revealing values, and--prompt-secretsprompts securely for anything missing. (#11680 by @jdx) - bootstrap: manage Linux users and groups via
[bootstrap.users]and[bootstrap.groups], with create/update/remove, supplementary groups, home handling, and explicitstate = "absent". Accounts converge before the files that reference them, and UID/GID collisions fail closed. (#11681 by @jdx) - bootstrap: manage Linux systemd services via
[bootstrap.services]for running/stopped, enabled/disabled, and masked state. Managed files and directories can setnotifyto triggerreload,restart, orreload_or_restarthandlers, but only after a real file change. (#11688 by @jdx) - bootstrap: manage Docker Compose projects via
[bootstrap.compose]for running, stopped, and absent states, with pull/build/recreate/wait policies, one-shot services, orphan/volume/image removal, and explicit dependencies. Convergence compares live container runtime and health to the rendered Compose model (Compose v2 only). (#11689 by @jdx) - bootstrap: manage Linux host firewall rules via
[bootstrap.linux.firewall]with nftables, firewalld, and UFW backends (backend = "auto"). Includes SSH-lockout protection (default-deny requires a covering allow rule orallow_lockout = true), drift detection, and preservation of undeclared rules unlessexclusiveis set. (#11694 by @jdx) - bootstrap: run bootstrap over SSH with
mise bootstrap remote, targeting a named[bootstrap.remote.hosts]inventory or ad-hocuser@hosttargets. mise archives and stages your project, provisions a compatible mise binary on the host, runs bootstrap with forwarded flags, and cleans up staging afterward. (#11690 by @jdx) - bootstrap: remote provisioning now detects each target's OS, architecture, and Linux libc (glibc vs musl) and, when the local binary is not compatible, downloads the matching raw executable for the same release from GitHub with minisign-verified checksums. Custom or debug builds fail closed and require an explicit
mise_bin,remote_mise, orbootstrap_command. (#11693 by @jdx)
Changed
- ruby:
ruby.compile = falseis now a strict precompiled-only mode, matchingpython.compile. Installs error withno precompiled ruby foundinstead of silently falling back to ruby-build, and version listings (mise ls-remote ruby, fuzzy resolution) are filtered to versions that actually have a precompiled binary for your platform. Previouslyfalsewas a no-op after precompiled binaries became the default in 2026.8.0. Unset andcompile = trueare unchanged; Windows is unaffected. (#11710 by @jdx) - task: workspace task inference is now opt-in per provider via
task.auto_infer(e.g.task.auto_infer = ["node"]) instead of running whenever experimental features are enabled. Explicit mise tasks always take precedence over inferred package scripts on name and alias collisions. (#11706 by @jdx)
Fixed
- brew:
:any_skip_relocationbottles no longer leave unresolved@@HOMEBREW_*@@placeholders in scripts and config files. That tag now only skips binary linkage relocation while text placeholders are still replaced. (#11665 by @jdx) - brew-cask: detect extensionless DMG downloads (such as Raycast) by their UDIF trailer instead of treating them as raw executables and failing to find the app bundle. (#11692 by @jacobbednarz)
- lock:
mise lock --bumpnow errors instead of writing an incomplete lockfile when a version bump would drop platform coverage that the previous locked version had. Best-effort skips are retained for platforms a tool never supported. (#11664 by @jdx) - pipx: release-age gating now uses PyPI's precise RFC3339
upload_time_iso_8601timestamp instead of the timezone-naiveupload_time, which previously made freshly released packages appear up to ~24h younger and over-gated them underminimum_release_age. (#11662 by @Guria) - pacman:
pacman -Qis now parsed underLC_ALL=Cso missing-package detection works in non-English locales; previously[bootstrap.packages]could bail on a translated "was not found" message. (#11673 by @rarandeyo) - sync: clear stale
incompletemarkers when an external link (from uv, nvm, pyenv, nodenv, or Homebrew) is confirmed healthy, somise whereno longer treats a working external version as incomplete after an interrupted install. (#11172 by @risu729) - completions: an explicit
--no longer hijacks task argument completion after usage v5.mise run <task> -- <TAB>again offers the task's declared choices instead of falling back to filenames, while still forwarding extra arguments. (#11711 by @jdx) - registry: shim auto-install uses new declared
binsmetadata to pick the correct provider before falling back to incidental executables, fixing cases where invoking thenpmshim could run Node's bundled npm instead of the configured npm version. (#11666, #11671, #11676, #11677, #11678 by @jdx)
New Contributors
- @jacobbednarz made their first contribution in #11692
- @rarandeyo made their first contribution in #11673
Full Changelog: v2026.8.1...v2026.8.2
💚 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.
v2026.8.1: Task Cache Goes Remote, Affected Tasks, and Config Ergonomics
This release rounds out mise's experimental task artifact cache with size/age limits, inspection tooling, and a full local-plus-remote cache backend (including authenticated CI caching), adds experimental mise run --affected for monorepos, and lands a batch of config, upgrade, and install fixes.
Highlights
- The experimental task output cache now supports remote sharing: a composite store reads locally first, promotes remote hits, and mirrors writes, with authenticated requests backed by token files or GitHub Actions OIDC. Cache entries can be inspected, cleared per-task, and bounded by size and age.
- Experimental
mise run --affectedruns only the tasks in monorepo projects touched by your Git changes, using workspace dependency graphs, global task inputs, and provider lockfile attribution to decide what is affected. - The config-writing flags are now more forgiving:
--fileand--pathare interchangeable across the commands that write config, so you no longer have to remember which name each subcommand expects.
Added
-
task: experimental
mise run --affectedselects and runs only the tasks in projects affected by Git changes, combining the workspace dependency graph,global_inputs, and provider lockfile diffs. Base and head revisions can be overridden with--affected-base/--affected-headorMISE_AFFECTED_*. Includes JSON output and an--explainbreakdown of why each task was selected. (#11590, #11587, #11589, #11591, #11593 by @jdx)mise run --affected test mise run --affected --affected-base main test
-
task: remote task cache. A composite store layers local and remote backends, reading local first and promoting remote hits, then committing locally before mirroring writes so a remote failure never loses a local hit. Requests are hardened, verified, streamed, and support read/write access modes. (#11622, #11623, #11624, #11626, #11627 by @jdx)
-
task: authenticated remote cache. Credentials resolve in fixed precedence: an explicit bearer token, a global-only token file (
MISE_TASK_CACHE_REMOTE_TOKEN_FILE), then GitHub Actions OIDC whenMISE_TASK_CACHE_REMOTE_OIDC_AUDIENCEis set. HTTPS is enforced except for loopback development endpoints. (#11625, #11653 by @jdx) -
task:
task.cache_max_sizeandtask.cache_max_agesettings cap the task output cache independently of the global prune age, evicting least-recently-accessed entries after writes and rejecting expired entries on restore. (#11610 by @jdx) -
task: inspect and selectively clear the cache with
mise cache task <task>(table or--json, reporting stored size, restorable bytes, saved time, last access, and outputs) andmise cache clear --task <task>, which removes only that task's entries without touching your working-tree outputs. (#11604 by @jdx) -
task:
mise run --task-cache-explain <task>prints a structural breakdown of what feeds a task's cache key (input categories, counts, env/var names and presence, platform) without emitting secret-derived hashes, and works under--dry-run. Companion changes report cache miss reasons, cache statistics, resolved cache paths, and add JSON explanation output. (#11595, #11597, #11599, #11600, #11601 by @jdx) -
task: cache artifacts are now checksum-verified and cache declarations are audited on load. (#11605, #11617 by @jdx)
-
config:
--fileand--pathare now interchangeable across the commands that write config:mise use,mise set,mise unuse,mise unset,mise config get, andmise config set. (#11577, #11616, #11631, #11640 by @JamBalaya56562)mise use --file mise.local.toml node@22 mise set --path mise.local.toml FOO=bar -
upgrade:
mise upgrade --no-prunekeeps the version being replaced instead of uninstalling it, so external references such as virtualenvs built from a mise-managed Python keep working. Also works with--bump. (#11639 by @JamBalaya56562) -
env: on Windows, mise now warns when the generated PATH exceeds the ~8191-character length at which
cmd.exesilently drops the variable, which otherwise makes every command appear unrecognized. (#11643 by @JamBalaya56562) -
vfox: Lua plugins gain
strip_components = 1onarchiver.decompressplus sortedfile.list,file.glob, andfile.move, letting plugins flatten versioned archive roots and rename executables portably without shelling out. (#11652 by @jdx)
Fixed
- config: tool versions may now contain a colon, so templated versions like
{{ exec(...) | split(pat=': ') | last }}and selectors resolved from templates no longer fail config loading. (#11580 by @JamBalaya56562) - config: config writes no longer pick a target that config loading would ignore, honor ignore filters when a
--path <dir>is given, and no longer write the global config into aconf.ddrop-in. (#11571, #11609, #11633 by @JamBalaya56562) - upgrade:
mise upgrade --bumpnow applies every eligible tool bump in the same config file instead of letting the last save overwrite earlier ones, and preserves successful bumps when another tool in the file fails to install. (#11572 by @Marukome0743) - install: a failed backend install no longer leaves runtime aliases such as
latestpointing at the removed version; mise rebuilds valid symlinks (or removes dangling ones) after cleanup. (#11579 by @Marukome0743) - brew: Linux Homebrew bottles containing shebang executables with binary payloads (such as Watchman's
watchman-diagzipapp) now relocate correctly with long Linuxbrew prefixes. (#11632 by @Marukome0743) - pipx: extras are now applied to git-based installs. (#11586 by @jdx)
- prune: read-only shared installs are excluded from pruning. (#11644 by @Marukome0743)
- task: dangling task symlinks are skipped, wildcard task matching respects group boundaries, shared pre/post dependencies are supported, and task-list flags are rejected on subcommands. Task cache writes are serialized and abandoned partial writes are cleaned up. (#11574, #11581, #11578 by @Marukome0743; #11638, #11606, #11608 by @jdx)
- schema: JSON schemas are now published alongside the documentation. (#11596 by @jdx)
Documentation
- Recommend installing official release binaries, clarify Node dependency behavior for npm-backed tools, offer shims as a workaround for the Windows PATH length limit, and fix a dead tool-stub example URL and an npmmirror
node.mirror_urlexample. (#11615, #11637 by @jdx; #11642 by @JamBalaya56562; #11377, #11460 by @Bartok9) - Document the remote cache protocol and its trust requirements. (#11621, #11628 by @jdx)
Full Changelog: v2026.8.0...v2026.8.1
💚 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.
v2026.8.0: 15% faster shims, multi-language workspaces, and precompiled Ruby
This release makes mise noticeably faster on Linux x64: shims have 15% lower latency, while config-aware commands are 8–11% faster in local release-to-release benchmarks. It also significantly expands the experimental monorepo task workflow with dependency inference across Cargo, uv (Python), Go, and Node workspaces, and makes precompiled Ruby binaries the default.
⚡ Performance: up to 15% lower latency
Official checksum-verified Linux x64 GNU binaries were compared on an AMD Ryzen 9 7950X3D using an isolated offline fixture with warm filesystem caches (20 warmups and 200 measured runs per command):
| Workload | v2026.7.18 | v2026.8.0 | Lower latency |
|---|---|---|---|
| Node shim dispatch | 6.990 ms | 5.929 ms | 15.2% |
tasks ls |
7.353 ms | 6.574 ms | 10.6% |
env -s bash |
7.942 ms | 7.187 ms | 9.5% |
current |
7.667 ms | 6.961 ms | 9.2% |
settings |
5.823 ms | 5.331 ms | 8.5% |
--help |
5.036 ms | 4.731 ms | 6.1% |
version |
5.108 ms | 4.884 ms | 4.4% |
registry |
7.457 ms | 7.181 ms | 3.7% |
Release downloads are smaller as well:
| Linux x64 artifact | Size change |
|---|---|
.tar.xz |
11.1% smaller |
.tar.gz |
5.9% smaller |
.tar.zst |
5.0% smaller |
| Allocated ELF sections | 0.6% smaller |
The raw executable file is 2.5% larger because of the BOLT file layout, despite its smaller allocated sections and compressed artifacts. Shim dispatch was measured in two reversed-order 300-run rounds. These are whole-release results against v2026.7.18, so they include all changes between the releases rather than isolating BOLT alone.
Highlights
- Workspace inference now spans four ecosystems.
mise tasks graphdiscovers projects and internal dependency edges from Cargo, uv, Go, and Node workspace metadata without needing the underlying toolchain installed, and--explainattributes every project, edge, and task field to its source. - Precompiled Ruby binaries are now the default, cutting install times for most users while keeping source builds available on demand.
Added
-
task: Cargo workspaces are now inferred for the task graph. mise parses root and member
Cargo.tomlfiles (nocargobinary required) to buildcargo:<package>projects and internal edges from normal, dev, build, target-specific, renamed, and inheritedworkspace = truepath dependencies, with provenance surfaced in graph output. (#11554 by @jdx) -
task: uv (Python) workspaces are inferred from
pyproject.toml. When[tool.uv.workspace]is present, member globs and exclusions defineuv:<package>projects and edges come from[tool.uv.sources]workspace = true/ localpathentries across main, optional, dependency-group, and legacy dev dependencies — again without invokinguvor Python. (#11556 by @jdx) -
task: Go workspaces are discovered from
go.workusedirectives and each module'sgo.mod, registering stablego:<module-path>projects without running thegobinary. Dependency ordering is supplied explicitly via[monorepo.projects]overrides. (#11559 by @jdx) -
task: workspace providers can now contribute task suggestions. The Node provider imports supported
inputs,outputs,cache, anddependsOnmetadata from matchingturbo.jsonentries for inferred package scripts, trackingturbo.jsonas a task definition source. Unsupported Turbo expressions are left unset. (#11543 by @jdx) -
task:
mise tasks graph --explainshows provider and metadata-source provenance for every inferred project, dependency edge, task, and provider-suggested field, and--jsonnow serializes the same attribution. Config overrides are labeled asconfigurationrather than misattributed to inference. (#11547 by @jdx)mise tasks graph --explain
-
task:
mise watchgains a per-taskwatch.no_vcs_ignoreoption so tasks can watch sources that are excluded by.gitignore(such as generated files). VCS ignores stay enabled by default to avoid scanning broad build directories; one opted-in task enables it for the combined watch process. (#11535 by @Marukome0743)[tasks.generate] run = "process generated/output.json" sources = ["generated/output.json"] watch = { no_vcs_ignore = true }
-
task: groundwork for affected-project task selection: mise can now resolve affected Git base/head revisions (with
MISE_AFFECTED_BASE/MISE_AFFECTED_HEADoverrides and CI auto-detection for GitHub Actions and GitLab), map changed files to the workspace projects that own them, and expand that set through transitive reverse-dependency edges across providers. (#11585, #11569, #11583 by @jdx)
Changed
- ruby: precompiled Ruby binaries are now the default when
ruby.compileis unset — installs tryjdx/rubybinaries first and fall back to a source build when none are available. Setruby.compile = trueto force a source build as before. (#11584 by @jdx)
Fixed
- config:
--path <dir>now targets a config file inside that directory foruse,unuse,set,unset,dotfiles add, and thesystemsubcommands. Previously--pathwas silently discarded when the current directory already had a config in scope, somise unuse --path ../othercould remove a tool from the wrong file. (#11575 by @JamBalaya56562) - task: Ctrl-C is now treated as an interruption rather than a task failure.
mise runstops starting new work, exits with status 130, and no longer printsno exit statusortask failed, while still allowing post-dependency cleanup to run. (#11511 by @Marukome0743) - task:
sourcesandoutputsnow support brace globs (e.g.{a,b}/**), and literal single-element braces are preserved rather than being mangled. (#11555, #11565 by @Marukome0743) - python:
mise run --tool python@3.12now honors the selected interpreter when creating a_.python.venv, instead of building the venv from the first[tools] pythonentry. (#11567 by @JamBalaya56562) - unuse:
mise unuse node@20onnode = ["20", "22"]now removes only the matching version and preserves the rest, including structured options and.tool-versionsentries. The whole tool key is removed only for an unversioned request or after the last version is unused. (#11563 by @Marukome0743) - env: an explicit
redact = falseon a variable now excludes it from matchingredactionspatterns, so a short opted-out value no longer leaks into the global scrubber and partially redacts unrelated secrets. (#11564 by @jdx) - hook-env: if a shell command overwrites a mise-managed variable or removes a PATH entry added by mise,
hook-envnow detects the drift and restores it, while leaving user-owned variables, added PATH entries, and PATH reordering untouched. (#11568 by @Marukome0743) - dotfiles:
symlink-eachno longer recursively walks shared targets like~for status, apply, and unapply. mise now records exact source-to-target pairs in a manifest under$MISE_STATE_DIR/dotfiles, avoiding traversal of unrelated and unreadable home-directory trees. Existing installs are backfilled on their next apply. (#11549 by @jdx) - asdf: dependencies declared via
[tools].dependsare now on the PATH given tobin/downloadandbin/installscripts during the samemise install, fixing first-install failures where a dependency's executable was still missing.bin/installnow also fails when it installs nothing. (#11531 by @Marukome0743, #11553 by @JamBalaya56562) - vfox: plugins whose
pre_installhook returns a sha1 or md5 checksum are now verified instead of panicking withnot implemented: sha1. (#11536 by @JamBalaya56562) - aqua: checksum files that carry a byte-order mark are now read correctly, and the checksum manifest is fetched with the text-fetching path again. (#11552, #11558 by @JamBalaya56562)
- brew-cask: direct cask pours are hardened with transactional activation, content-fingerprinted receipts, validated paths, and structured
terminate_process/postflight handling, covering current cask shapes such as Cloudflare WARP, TablePlus, Zoom, OrbStack, Surge, Plex Media Server, and Zed Preview. Homebrew-owned casks are left byte-for-byte untouched. (#11215 by @donbeave) - forgejo: the new
fjmacOS key path is now supported. (#11545 by @jdx) - github, gitlab:
gh/glabconfig is now found on Windows. (#11508 by @JamBalaya56562) - http: HTTP client initialization failures are now handled gracefully instead of aborting. (#11561 by @Marukome0743)
Performance
v2026.7.18: Monorepo task ergonomics and a broad round of fixes
This release refines mise's experimental monorepo task workflow with relative dependency paths and a compact dependency tree view, and lands a wide batch of fixes across Cargo installs, plugins, PATH handling, Windows program resolution, Aqua locks, GitLab pagination, and more.
Added
-
task:
mise tasks depsgains a--compactflag that expands each shared dependency subtree only once and marks later references as(already shown), keeping every incoming edge visible while avoiding the recursive blow-up that wildcard-heavy monorepo graphs produced. Default output is unchanged unless you pass the flag. (#11502 by @jdx)mise tasks deps --compact
-
task: monorepo task dependencies now support
./-prefixed relative paths, resolved from the declaring task's own monorepo location, so one aggregate declaration works unchanged at the root, in nested apps, and in leaves without hard-coded absolute paths. Trailing...patterns now include the base project itself in addition to its descendants. (#11503 by @jdx)[tasks.test] depends = [{ task = "./...:groups:tests:*", optional = true }]
Fixed
- cargo: installs now record the effective install options (
features,default-features,bin,crate,locked) and reinstall automatically when any of them change, so changing feature flags or the selected binary no longer silently reuses the wrong artifact. Incompatible shared/system installs are shadowed in your primary install directory instead of being modified. (#11480 by @Marukome0743) - plugins:
[plugins]entries can now point at local filesystem paths (absolute,~/, or explicit.//../relative to the config root). Local asdf, vfox, vfox-backend, and package plugins are installed as symlinks so source edits take effect immediately, while Git URLs, refs, archives, andfile://sources keep their existing behavior. (#11487 by @Marukome0743) - plugins: batch
plugins install,plugins install --all, andplugins updatenow finish every plugin even when one fails, preserving successful changes and reporting all failures together (in deterministic order) with a failing exit status. (#11490 by @Marukome0743) - env: computed environments (
mise env,mise xchild PATHs,mise doctor) now collapse exact duplicate PATH entries first-wins, fixing the runaway_.pathaccumulation that appeared in nested shells and IDE terminals that inherit an activated PATH without mise's state vars. The live shell PATH is intentionally left untouched. (#11491 by @JamBalaya56562) - install: installing a tool no longer touches your loaded config files, so editors stop reporting spurious "file changed on disk" warnings. hook-env still detects installs and PATH changes via the mise data directory. (#11495 by @Marukome0743)
- prune:
mise prune --toolsno longer discards references from untrusted idiomatic version files and plain.tool-versions, preventing removal of versions still in use by other projects. (#11501 by @jdx) - monorepo:
idiomatic_version_file_enable_toolsset in a config root's own[settings]is now honored by monorepo-wide commands likemise ls --monorepoandmise install --monorepo, instead of only being applied when mise runs from inside that root. (#11463 by @kaii-zen) - asdf:
bin/list-allandbin/latest-stablescripts now receive your resolved mise[env]values, removals, and_.pathadditions, so plugins that need a credential or helper on PATH can list versions. Caches are partitioned per environment so results are never reused across differing configs. (#11492 by @Marukome0743) - aqua: locked HTTP installs (such as Cabal artifacts on
downloads.haskell.org) again retain prefix-scoped format and file metadata, so archives are extracted correctly rather than copied as the executable. (#11499 by @jdx) - gitlab: authentication headers are now sent on every page of paginated release/tag requests, fixing anonymous page-2 requests on private or rate-limited GitLab projects when
MISE_LIST_ALL_VERSIONSis set. (#11507 by @JamBalaya56562) - backend (Windows): mise now resolves a genuinely spawnable program instead of a bare name, fixing
program not founderrors when a tool is present only as a.cmdshim (for example a scoop- or pip-installedpipx.cmd). Interpreter-only files such as.ps1and.vbsare recognized correctly, with.vbsfile tasks routed throughcscript. (#11486, #11489 by @JamBalaya56562) - watch:
mise watch --wrap-process groupis now honored on macOS instead of being silently dropped for watchexec's platform default ofsession. The--helptext also documents the platform-dependent defaults. (#11512 by @JamBalaya56562) - lockfile: monorepo legacy path discovery is now cached, avoiding redundant work during lockfile operations. (#11500 by @jdx)
Registry
New Contributors
Full Changelog: v2026.7.17...v2026.7.18
💚 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.
v2026.7.17: Monorepo Task Inference and Root Defaults
This release builds out mise's experimental monorepo task story: Node workspaces now infer project dependency graphs, import package scripts as first-class tasks, and can share configuration through root task defaults and upstream (^task) dependencies. It also adds per-tool control over idiomatic version files, a smoother dotfiles workflow, and a batch of fixes across shell activation, hook-env, Homebrew casks, Aqua, and Python uv environments.
Highlights
- Node monorepo workspaces gain end-to-end task support: inferred project dependency edges, imported
package.jsonscripts asnode:<package>#<script>tasks, root task defaults shared by task name, and experimental^taskupstream dependencies for "build upstream projects first" ordering. - New
optional = truetask dependencies run when they match and are silently skipped when they don't, and idiomatic version files can now be disabled per tool so.nvmrcandpackage.jsonno longer fight over your Node version. - A round of environment and shell fixes stops hook-env from reloading every prompt after unrelated file writes, keeps the fish
cdhook working during compound commands, and fixes zsh activation underPOSIX_IDENTIFIERS.
Added
-
task: Node workspace packages now expose their
package.jsonscripts as mise tasks without needing amise.tomlin every package. Scripts get stable IDs likenode:@scope/app#buildplus monorepo path aliases such as//packages/app:build, run in their package root through the detected package manager (npm/pnpm/Yarn/Bun) with raw argument passthrough, and explicit tasks take precedence while keeping both names linked. (#11466 by @jdx) -
task: Node workspaces now infer project dependency edges by matching declared internal package names (
dependencies,devDependencies,optionalDependencies,peerDependencies) to other discovered packages, surfaced throughmise tasks graph. This is the graph that powers dependency-aware ordering. (#11435 by @jdx) -
task: experimental root task defaults via
[monorepo.task_defaults.<name>]in the rootmise.toml, applied by task name to both inferred and explicit workspace tasks. Task-local config andextendstemplates still win. (#11473 by @jdx)[monorepo.task_defaults.build] sources = ["src/**", "package.json"] outputs = ["dist/**"] cache = { enabled = true } [monorepo.task_defaults.test] env = { NODE_ENV = "test" }
-
task: experimental
^taskupstream dependency syntax so a task can require the same task in every upstream workspace project before it runs, expanding through the project graph (including transitive upstreams) and skipping projects that lack the task. Supported independsonly. (#11476 by @jdx)[monorepo.task_defaults.build] depends = ["^build"]
-
task: optional dependencies via
optional = trueon structured task dependencies. Optional deps run all matches when present and are silently omitted when nothing matches, while invalid selectors still error. Works acrossdepends,depends_post, andwait_for. (#11471 by @jdx) -
config:
idiomatic_version_file_disable_fileslets you disable individual idiomatic version files per tool usingtool:filenamepairs, so you can keep.nvmrcselecting Node while ignoringpackage.jsondevEngines, with pnpm still readingpackage.json. (#11470 by @jdx)mise settings add idiomatic_version_file_disable_files node:package.json
-
dotfiles:
mise bootstrap dotfiles addnow applies captured entries by default (use--no-applyfor capture-only workflows), moves real paths into the dotfiles source before linking, normalizes and sorts[dotfiles]entries, and reports config writes and concrete apply actions, with rollback on failure. (#11451 by @jdx)
Fixed
- hook-env: creating an unrelated file in a config-search ancestor directory no longer forces
env._.sourceand full config reloads to re-run on every prompt indefinitely. Forced fast-path runs now always refresh the session. (#11458 by @Marukome0743) - activate: the fish directory-change hook now stays active while commands run, so each
cdin a compound command applies the matching mise environment immediately, matching Bash and Zsh behavior. (#11478 by @Marukome0743) - activate: zsh activation now works with
POSIX_IDENTIFIERSenabled;MISE_*changes are captured correctly instead of hitting abad math expressionerror. (#11467 by @jdx) - brew: Homebrew casks using the new
command_wrapperartifacts and structuredrunlifecycle steps (for example Firefox and OrbStack) now install and reconcile correctly instead of failing on unknown metadata. (#11472 by @jdx) - aqua: version overrides now match their
version_prefixfamily before evaluating constraints, so packages with multiple tag families (like oxlint'soxlint_vandapps_v) resolve to the right override. Locked installs also parse the release tag from the download URL so prefix-scoped overrides apply. (#11469, #11482 by @jdx) - python: uv auto-venv now respects
UV_PROJECT_ENVIRONMENTwhen selecting, creating, and activating the virtual environment (resolving relative paths from the workspace root), and folds the resolved path into env cache keys so alternate venv locations are honored. (#11475 by @Marukome0743) - lockfile: shim resolution with explicit unified monorepo lockfiles (
[monorepo] lockfile = true) no longer rescans every configured monorepo root per tool, removing repeated filesystem traversal on the hot path. (#11468 by @jdx) - config: alias and bootstrap writers, aliased tool keys, and version arrays now preserve surrounding comments when rewriting
mise.toml. (#11453, #11474, #11454 by @JamBalaya56562) - self-update: when self-update is disabled and no packager instructions file exists (as on Homebrew and Arch installs), mise now shows a generic upgrade hint instead of reporting an out-of-date version with no follow-up advice. (#11449 by @JamBalaya56562)
- task: source metadata hashes now include mtime, improving change detection for task sources. (#11455 by @JamBalaya56562)
Documentation
Full Changelog: v2026.7.16...v2026.7.17
💚 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.
v2026.7.16: Task Workspaces, MCP Command Effects, and Dotfiles Cleanup
This release expands the experimental task output cache with per-run controls, a configurable cache directory, and command-derived cache inputs, and lays the groundwork for monorepo-aware task workspaces starting with Node discovery. It also teaches mise mcp to expose each command's read/write/destructive effect to agents, consolidates dotfiles management under mise bootstrap, and lands a broad batch of fixes across brew, npm, tasks, config rewriting, and OCI pushes.
Highlights
- The experimental task output cache gains per-run controls (
--task-cache/MISE_TASK_CACHE), a configurabletask.cache_dir, andcache.command_inputsso cache keys can fold in runtime state like compiler versions. - New experimental workspace project graph model with Node monorepo discovery (npm, pnpm, Yarn, Bun) via Aube, the foundation for monorepo-aware affected-project and task inference.
mise mcpcan now tell agents what a command does: the newlist_commandstool returns each command's read/write/destructive effect so agents can reason about safety before running anything.
Added
-
task: per-run cache controls via
--task-cache <mode>andMISE_TASK_CACHE, supportingread-write(default),read-only,write-only,off, andlocal-only. Read-only lets untrusted CI jobs consume existing results without publishing misses, write-only warms the cache without consuming entries, andoffgives a clean diagnostic path while preserving normalsourcesfreshness. Honored bymise runand bootstrap/naked task entry points. (#11396 by @jdx) -
task: experimental
task.cache_dirsetting andMISE_TASK_CACHE_DIRto place task output artifacts on dedicated volumes or project-specific locations without relocating mise's entire cache.mise cache clearandmise cache prunecover the custom location. (#11399 by @jdx) -
task: experimental
cache.command_inputsso cacheable tasks invalidate on command-derived state (likenode --versionor a generated config fingerprint) that isn't captured by source files. Each command runs in the task directory with the resolved tool environment, and its text plus stdout/stderr hashes fold into the cache key. (#11381 by @jdx)[tasks.build] run = "..." sources = ["src/**/*.rs"] outputs = ["dist/app"] cache = { enabled = true, command_inputs = ["rustc --version"] }
-
task: experimental workspace project graph model and provider interface, the ecosystem-neutral foundation for Node, Cargo, uv, and Go monorepo discovery, plus Node workspace discovery for npm, pnpm, Yarn, and Bun monorepos powered by Aube's shared manifest parsing and workspace-confined scanning. (#11400, #11418, #11420, #11422, #11424, #11427, #11430, #11445 by @jdx)
-
mcp: new
list_commandstool exposing mise's command tree with each command's declared effect (read,write,destructive, or unclassified), help text, and hidden status, so agents can see what a command does before invoking it. An optionalinclude_hiddencontrols visibility, and unclassified is explicitly treated as unknown rather than safe. (#11389 by @jdx) -
cargo:
cargo.binstall_nativegraduates from experimental and can now discover conventionally named GitHub release artifacts from a crate's linked repository whenpackage.metadata.binstallis absent, so more precompiled binaries install without crate-specific configuration. It also works under the defaultlocked = truepath. (#11433 by @jdx) -
dotfiles: new
mise bootstrap dotfiles unapply(with hiddenmise dotfiles unapplycompatibility alias) to remove managed symlinks, copies, templates, and edit blocks while preserving unmanaged content. Supports target filters,--dry-run,--yes, and requires--forcefor modified or ambiguous content. (#11437 by @jdx) -
bootstrap: dotfiles management is now consolidated under
mise bootstrap dotfiles(add,edit,apply,status), which runspre-dotfiles/post-dotfileshooks correctly. The top-levelmise dotfilescommand is hidden and deprecated (warnings in 2027.2.0, removal in 2028.2.0) but still works. (#11436 by @jdx) -
bootstrap: added
bsas a visible shorthand alias formise bootstrap. (#11439 by @jdx) -
spm: new
install_commandoption for source installs runs a custom command from the checked-out package, and fails the install when the command exits successfully but installs nothing intobin/(protecting against scripts that swallow build failures). (#11369 by @Marukome0743)
Fixed
- backend: a network failure while listing remote versions is now reported as a fetch failure instead of a misleading "no versions found matching date filter". The failure is memoized per process to avoid redundant HTTP retries, cutting duplicate warning spam and install time roughly in half in the failing case. (#11391 by @jdx)
- config:
mise use,mise up --bump, andmise setnow preserve trailing inline comments when rewritingmise.toml, matching the existing behavior for comments above a line and for.tool-versions. (#11415 by @JamBalaya56562) - oci: chunked
mise oci pushnow accepts201 Createdon the chunkPATCH, fixing large-layer pushes to AWS ECR that previously failed withblob chunk upload failed: 201. (#11376 by @fire-ant) - npm: tools resolved from a
mise.lockpin are now trusted through aube's low-download popularity gate for the requested package, so reproducing an existing lockfile no longer requiresallow_low_downloads. First-time unlocked installs and OSV malicious-package checks are unchanged. (#11384 by @jdx) - npm: aube confirmation prompts are now routed through mise's shared prompt path. (#11441 by @jdx)
- pipx: no longer suggests
uvwhenuvxis disabled for the package. (#11373 by @JamBalaya56562) - dotfiles:
symlink-eachnow prunes stale mise-managed symlinks left behind when a source file is deleted (reporting them as drift inmise dotfiles status), collapses emptied directories, and gainsexcludeglob patterns for directory-walking modes, while leaving unmanaged files and user links untouched. (#11388 by @jdx) - brew: maintain linked-keg compatibility records (#11371 by @benjaminwestern), adopt existing cask completion links (#11383 by @jdx), and use the download client for artifacts (#11428 by @jdx).
- aqua: preserve legacy root binary layouts so tools that expect binaries at the install root keep working. (#11397 by @jdx)
- shim: missing executables are now attributed to the configured tool that should provide them. (#11398 by @jdx)
- bootstrap: the generated install script honors
MISE_VERSIONandMISE_INSTALL_PATH(#11401 by @JamBalaya56562), and mise-managedmasis now detected (#11429 by @jdx). - generate: git pre-commit hooks respect quiet flags (#11310), use the current env directive syntax (#11311), and resolve hooks correctly in git worktrees (#11313) — all by @Marukome0743.
- task: support mixed file task dependencies (#11382 by @jdx), deduplicate equivalent task sources (#11204 by @risu729), support multi-line arrays in file task headers (#11412 by @Marukome0743), allow
falseto override script headers (#11112 by @risu729), and treat a missing content-hash baseline as stale (#11447 by @JamBalaya56562). - link: reject selector-style link requests. (#11218 by @risu729)
- progress output no longer repaints over interactive confirmation prompts; the shared renderer is now suspended while a prompt owns the terminal. (#11421 by @jdx)
Documentation
- Documented external cache inputs (#11395 by @jdx) and how packagers can disable self-update (#11446 by @JamBalaya56562).
- Replaced the dead Taobao Node mirror example with npmmirror (#11217 by @Bartok9) and fixed a redactions glob example using removed nested syntax (#11448 by @Marukome0743).
Registry
v2026.7.15: Experimental Task Output Caching
This release lands the first version of experimental local task output caching, letting eligible tasks restore their declared outputs and replay their logs without rerunning. It also adds structured registry idiomatic-version-file parsing, a standalone Aube installer mode, and a broad batch of task, Homebrew, shell, and Windows path fixes.
Highlights
- Experimental local task artifact caching restores task outputs (and replays their logs) across deletions, checkouts, and unchanged CI runs, with cache keys derived from source contents, task config, tools, and environment. It works for tasks that produce files, tasks with no filesystem outputs, and multi-task graphs, and stays opt-in and conservative on any failure.
- Registry-backed tools can now parse idiomatic version files (like
dagger.json,Taskfile.yml,.chezmoiversion, and 8 more) in-process, with no plugin or shell execution.
Added
-
task: experimental, opt-in local artifact caching. Tasks with
sourcesand explicitoutputscan restore their outputs from a content-addressed cache instead of rerunning, and successful stdout/stderr are replayed through whatever output mode the current run uses. Cache keys combine source contents, task configuration and arguments, declared and allowlisted ambient environment, resolved tools, OS, and architecture. Cache failures degrade to misses or warnings rather than failing a task. (#11328, #11347 by @jdx)[tasks.build] run = "..." sources = ["src/**/*.rs"] outputs = ["dist/app"] cache = { enabled = true, env = ["CI"] }
-
task: dependency artifact keys now fold into a task's cache key, so downstream tasks reuse cached outputs when their dependencies resolve to the same artifacts, and an upstream input change correctly invalidates downstream results. (#11340 by @jdx)
-
task: result-only caching via
outputs = []for checks like lint, test, and typecheck that produce no files. Their successful result and replayable logs are cached without writing an archive. (#11351 by @jdx) -
task: reusable and global cache inputs. Define named
[task_config.input_groups]referenced fromsourcesas@group:<name>, andtask_config.global_inputsto apply config-rooted patterns to every task in scope, so shared lockfiles and toolchain files no longer need repeating per task. (#11356 by @jdx) -
task:
task_config.global_envfor scoped environment inputs that participate in cache keys, pluspass_through_env/task_config.global_pass_through_envto keep selected ambient variables (like tokens) available underdeny_envwithout affecting cache keys. (#11363 by @jdx) -
task:
outputsnow support ordered!exclusions and re-inclusions (mirroringsources), with\!escaping. Excluded paths are omitted from freshness hashes and cache archives, and existing excluded files are preserved on restore. (#11367 by @jdx) -
task:
task_config.shellsets a project-scoped default shell for tasks, with task-local and templateshellstill taking precedence. This gives users a safe migration path after the 2026.7.14 change that ignored project-level default shell-arg settings. (#11354 by @jdx) -
config: registry
idiomatic_filesentries can now define structuredversion_regex,version_json_path, andversion_exprparsers, adding in-process idiomatic version-file parsing for 11 tools including Dagger, Task, chezmoi, CMake, Earthly, golangci-lint, GoReleaser, Lefthook, Pixi, pre-commit, and Ruff. Parsing runs without executing plugin or shell code, and remains opt-in per tool. (#11341 by @jdx)mise settings add idiomatic_version_file_enable_tools dagger task lefthook
-
npm: new
npm.package_manager = "aube_cli"mode installsnpm:tools through a separately installed standalone Aube executable while mise still resolves versions itself, avoiding Aube's npm compatibility shim. The default embeddedaubebehavior is unchanged. (#11357 by @jdx) -
deps: explicitly configured
mise depsproviders that are currently inapplicable now stay visible.mise deps --listshows an active/inactive status with a reason (e.g.inactive (missing package-lock.json)), andmise deps <provider> --explainor an explicit run fails with that reason instead of silently disappearing. (#11182 by @risu729)
Fixed
- task:
source_freshness_hash_contents = truenow skips mtime comparison entirely, so tasks no longer re-run on every CI job after a cache restore resets timestamps. Output integrity is tracked with a content hash that also detects missing, partially deleted, and modified outputs. (#11319 by @rabadin) - task: confirming (or auto-confirming) the executable-bit prompt for a file task now runs the task in the same
mise run, instead ofchmod-ing the file and still failing with "no task found". Respects--yes,MISE_YES, and the trustedyessetting. (#11337 by @jdx) - task: circular dependency detection now runs on the fully resolved graph, so cycles through
wait_for,{{usage.*}}dependencies, anddepends_postare reported with a concrete path before any task runs, while valid post-dependency graphs are no longer rejected. (#11329 by @jdx) - task:
$ ...task headers now display forwarded arguments accurately for inline and shebang tasks, no longer making multiline tasks appear to pass args to their first command. (#11344 by @jdx) - task:
--outputandMISE_TASK_OUTPUToverrides now honor raw and interactive tasks the same waytask.outputconfig does, fixing mixed command/timing output for tasks that need inherited stdio. (#11355 by @jdx) - brew:
mise bootstrap packages upgradeno longer fails to link kegs when formulae were already installed and linked by real Homebrew. mise now recognizes brew's directory symlinks, resolves link targets one hop like brew does, and expands directory symlinks into real directories before linking. This also fixes second-upgrade failures for formulae shipping versioned dylib aliases in pure-mise setups. (#11320 by @mjun0812) - brew:
mise bootstrap packages prunenow correctly removes a keg's unversioned dylib alias links instead of leaving them dangling. (#11330 by @mjun0812) - env:
~/paths now expand using the platform path separator, so Windows install and tool locations no longer surface mixed separators (e.g.C:\Users\me\.local/share/mise) throughmise where, shims, and related output. (#11312 by @JamBalaya56562) - shell:
mise activate pwshnow works underSet-StrictMode, guarding uninitialized globals that previously aborted activation, fixing a baremiseinvocation, restoringchpwdhook chaining, and silencing command-not-found errors when PSReadLine is unavailable. (#11314 by @JamBalaya56562) - backend: a plugin whose backend is listed in
disable_backendsno longer shadows the registry entry, so a registry shorthand falls back to an enabled backend instead of failing to install. Already-installed tools keep reporting their recorded backend. (#11362 by @JamBalaya56562) - generate:
mise generate task-docs --injectnow errors with a clear message when the<!-- mise-tasks -->markers are missing or reversed, instead of truncating or clobbering the target file. (#11359 by @JamBalaya56562) - mcp: the MCP
initializeresponse now reports the server asmiseat mise's version, instead of inheriting rmcp's default identity. (#11361 by @jdx)
Documentation
- settings: choice descriptions now render markdown. (#11335 by @jdx)
- tasks: clarified shebang argument behavior. (#11336 by @jdx)
- shims: documented how
activatetreats the shims directory with auto-install. (#11366 by @JamBalaya56562)
Registry
New Contributors
Full Changelog: v2026.7.14...v2026.7.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.
v2026.7.14: Multi-asset GitHub installs, safer defaults, and Windows pip
This release adds overlay installs for GitHub-based tools, closes a config-trust security gap around default shell arguments, and lands a wide batch of correctness fixes across tasks, lockfiles, npm, Swift, brew casks, and Windows Python.
Added
-
github: the GitHub/GitLab/Forgejo release backend now accepts
additional_asset_patterns, so a single install can overlay multiple release archives from the same tag into one installation directory. Each supplemental artifact is locked and verified (checksums and provenance) on its own, and--lockedfails if the recorded set no longer matches. This models release layouts like Ollama's optional ROCm archive without making a large payload unconditional. (#11272 by @jdx)[tools."github:ollama/ollama"] version = "latest" additional_asset_patterns = ["ollama-linux-amd64-rocm.tgz"]
-
npm: new
allow_low_downloadstool option lets an embedded aube install bypass the weekly-download popularity gate for the requested package only, so curated tools likebibtex-tidyandpurtyinstall again withoutnpm.shell_out. Transitive dependencies still hit the gate. (#11305 by @jdx) -
env: structured env files (
env._.fileloading JSON/YAML/TOML) support an explicitexpand = trueoption for shell-style variable expansion, including references to earlier values. See Fixed below for the default-behavior change. (#11269 by @jdx)
Fixed
- env: values loaded from JSON/YAML/TOML env files are literal by default again, fixing a regression where every value was shell-expanded when
env_shell_expandwas on. That corrupted literals such as bcrypt-style$6$salt$hashand could pull in matching process-environment values. Opt back into expansion withexpand = true. (#11269 by @jdx) - python:
pipis now usable on fresh Windows installs. mise synthesizespip.cmd/pip3.cmdwrappers, adds the install'sScriptsdirectory to PATH so pip-installed console scripts resolve, and fixes default-package installation on Windows. (#11278 by @JamBalaya56562) - github:
.exerelease assets are now preferred on Windows, so tools that ship both an extensionless and.exebinary no longer install the non-runnable one and fail with "cannot find binary path". (#11257 by @gologames) - github: a rejected GitHub token (401) now produces an actionable error that names the token source (gh CLI,
github_tokens.toml, OAuth, env var, etc.) and includes GitHub's response and a remediation hint, instead of a bare401 Unauthorized. (#11236 by @Marukome0743) - backend: an archive containing a single binary with an OS/arch suffix (e.g.
gdscript-formatter-macos-aarch64) is now renamed to its clean name on PATH, matching the existing behavior for single-file downloads. (#11232 by @Marukome0743) - brew: brew-cask installs handle more real-world casks — completion stanzas and
system_commandin lifecycle blocks are supported, and artifact links into root-owned directories like/usr/local/binnow elevate through mise's sudo policy instead of failing with permission errors. Fixes installingdocker-desktop. (#11273 by @jdx) - lockfile:
prefix:tool requests now honor the locked version onmise installinstead of silently re-resolving to the newest match. Constrained upgrades viamise upgrade/mise lock --bumpstill work. (#11255 by @JamBalaya56562) - aqua: cross-platform lockfiles for aqua HTTP packages preserve a reachable
v-prefixed URL, fixing 404s where an entry locked to another platform's unprefixed URL. (#11267 by @jdx) - swift: Swift lockfile entries now record the target Linux distro (
ubuntu24.04,fedora39,ubi9, ...) so checksums are no longer verified across mismatched distro tarballs, andmise lockwrites meaningful entries and re-locks correctly after changingswift.platform. (#11299 by @jdx) - task: with a git worktree checked out inside the main checkout, mise no longer loads the enclosing monorepo root's tasks into the nested root's namespace. Env, tools, and vars still inherit as before. (#11283 by @jdx)
- task: changing a task's
runcommand,sources, oroutputsnow invalidates its cached state, so tasks are no longer incorrectly skipped after such edits. (#11288 by @rabadin) - task: a task's source hash is now persisted only after a successful run, so a failed run no longer marks stale sources as up to date. (#11296 by @rabadin)
- completions: shell completion no longer offers mise's own global flags after a task name (where they aren't valid), and a task flag that shares a name with a mise flag now completes its own values correctly. (#11284 by @jdx)
- npm: npm package versions with very large numeric components (up to
Number.MAX_SAFE_INTEGER) now sort correctly, fixing cases where a0.0.*build could be picked over a newer stable release. (#11280 by @jdx) - npm: aube trust-downgrade failures now surface a clearer explanation, and aube's own progress display no longer competes with mise's output (bumped to 1.33.1). (#11292, #11308 by @jdx)
- npm: aube
allow_buildsis now serialized as a map. (#11262 by @jdx) - version: the update-check cache now negative-caches, so machines that can't reach the network (or run a build newer than the latest release) stop re-running the full check — including building an HTTP client and parsing the CA trust store — on every invocation. This is a significant speedup for commands like
mise --versionin those cases. (#11285 by @jdx) - env: remaining
std::env::vars()call sites now usevars_safe(). (#11309 by @JamBalaya56562)
Changed
- usage: every mise command now declares its effect on the system — read-only, modifies state, or destructive — surfaced in the command reference. This requires usage 4.0 (
min_usage_versionbumped), so shell completions and doc rendering now depend on it. (#11306 by @jdx)
Security
- config: the Unix/Windows default file and inline shell-argument settings are now global-only. Because local config is loaded before trust evaluation, an untrusted repository could previously influence how commands from trusted sources were executed. Global config and
MISE_*environment variables still apply. Reported by @arpitjain099. (#11293 by @jdx)
Warning
Breaking change: project-local values for unix_default_file_shell_args, unix_default_inline_shell_args, windows_default_file_shell_args, and windows_default_inline_shell_args are ignored in this release. Projects that used these settings to standardize task shells should set shell on each task for now. A config-scoped task_config.shell replacement is proposed in #11354.
Performance
Documentation
- npm: documented Socket integrations. (#11268 by @jdx)
- backend: corrected the
bin_path/asset_patterntemplate variable docs. (#11298 by @jdx) - Retargeted a dead clap.rs link to docs.rs/clap. (#11194 by @Bartok9)
- Added a generated
llms.txtindex for AI agents. (#11300 by @jdx)
Registry
- Added
checkstyle(#11287 by @zeitlinger),grok(#11291), andtak(#11307) by @jdx.
New Contributors
- @gologames made their first contribution in #11257
Full Changelog: v2026.7.13...v2026.7.14
💚 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.
v2026.7.13: Multi-binary renaming, cask completions, and go.mod support
This release expands archive backends to rename multiple binaries from a single release, adds Homebrew cask shell completions and go.mod version-file support, and fixes a broad batch of task, install, lockfile, and language-plugin correctness issues.
Added
-
backend:
rename_exenow accepts a table mapping source patterns to target names, so an archive that ships several executables can expose all of them cleanly on PATH instead of only one. The existing string form is unchanged. (#11231 by @jdx)[tools."github:DanielGavin/ols"] version = "latest" rename_exe = { "ols-*" = "ols", "odinfmt-*" = "odinfmt" }
-
brew: brew-cask now installs shell completions (declared
bash_completion/fish_completion/zsh_completionfiles andgenerate_completions_from_executablefor bash, zsh, fish, and pwsh) instead of skipping them, tracking them in cask receipts and installed-state checks. (#11198 by @jdx) -
go:
go.modcan now be used as an idiomatic version file. Atoolchain goX.Y.Zdirective resolves as an exact pin, while ago X.Yminimum resolves to the latest matching patch. It is opt-in and unchanged unless enabled per-tool. (#11213 by @JamBalaya56562)mise settings add idiomatic_version_file_enable_tools go
-
task: PowerShell task shells (
pwsh/powershell) now run with-NoProfileby default, matching how mise spawns POSIX shells, so a profile that mutatesPATH(such as a mise activation snippet) can no longer shadow a task's own tools and cause confusing "cannot find binary path" errors. Opt out with the newwindows_powershell_no_profilesetting (MISE_WINDOWS_POWERSHELL_NO_PROFILE=false). (#11199 by @jdx)
Fixed
- env:
_.path/_.file/_.sourcedirectives within a single[env]._block are now resolved in written order, so a_.pathcan reference a variable exported by a_.sourcewritten before it. (#11163 by @JamBalaya56562) - install: failed installs no longer print a contradictory "installed but not activated" hint before the real error. (#11227 by @jdx)
- install: logical state mutations during install are now serialized to avoid races. (#11207 by @risu729)
- lockfile: upgrading a locked
github:tool to a newer version that is already installed on disk no longer triggers a false supply-chain "provenance regression" error. (#11230 by @jdx) - npm: aube install failures now surface the full cause chain instead of an opaque "failed to resolve dependencies" message, with mise-native remediation guidance (
trust_policy_excludesornpm.shell_out) for trust-downgrade errors. (#11226 by @jdx) - task: inline task definitions now follow a consistent first-wins precedence model across local,
conf.d, and monorepo configs, so lower-precedence metadata no longer leaks into script tasks and the winning config's context is preserved. (#11103 by @risu729) - task: source freshness now tracks files correctly for workspace-rooted
sourcespatterns used in nested subproject tasks, so edits inside a subproject trigger a rerun. (#11202 by @rabadin) - brew: cask upgrades handle structured
preflight_steps/postflight_stepsfor move/remove operations, and cleanup-onlyzappkgutilIDs are no longer treated as install receipts (which could leave pkg cask status permanently missing). (#11197 by @jdx) - brew: cask upgrades no longer fail when removing a protected app backup (e.g. docker-desktop) hits "Permission denied", recovering permissions the way Homebrew does before retrying. (#11219 by @jdx)
- python: a
python3executable is now provided on Windows. (#11212 by @jdx) - ruby: custom
ruby.precompiled_url = "owner/repo"sources now fetch release metadata directly from GitHub instead of the restricted versions host, avoiding 403 warnings. (#11154 by @risu729) - ruby: Gemfile version pins with multi-digit segments (e.g.
ruby "3.4.10") are now parsed correctly. (#11229 by @capnregex) - bootstrap:
./-prefixed relative[bootstrap.repos]paths no longer display with a leading./component. (#11214 by @lilienblum) - http: invalid URLs now return an error instead of panicking. (#11160 by @Marukome0743)
- settings: avoid a panic when a parent settings key is an inline table. (#11184 by @Marukome0743)
- self-update: the updater's TLS backend now matches the feature it was built with, fixing failures when compiled with
native-tls. (#10834 by @bltavares)
Deprecated
- python: the legacy
virtualenvtool option is deprecated in favor of the_.python.venvenv directive. It now emits a warning and is scheduled for removal around2027.7.0. (#11234 by @JamBalaya56562)
Documentation
- python: clarify that
uv_venv_autorequires auv.lockfile. (#11223 by @jdx) - Fix dead links in the contributing guide and the aqua-registry/pipx installation docs. (#11123, #11167 by @Bartok9)
New Contributors
- @capnregex made their first contribution in #11229
- @rabadin made their first contribution in #11202
Full Changelog: v2026.7.12...v2026.7.13
💚 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.
v2026.7.12: Safe mode, node-free npm, and a built-in OCI push client
This release centers on running mise safely against untrusted config, shipping node-free npm: version resolution and installs, and replacing external tools (skopeo/crane, gpg) with built-in, dependency-free implementations. Along the way it fixes a prefer_offline timeout regression, several config/env correctness issues, and platform-specific problems on Windows and macOS.
Highlights
- New
MISE_SAFE=1mode turns mise into an inert config reader so automation (CI, Renovate) can runmise lock --bumpagainst untrusted branches without trust prompts or arbitrary code execution. - The
npm:backend no longer needs node or npm installed to resolve or install packages — version metadata is fetched over HTTP and installs run in-process via the embedded aube package manager. mise oci pushgained a full built-in registry client: no more skopeo/crane, with blob dedup, chunked uploads, retries, cross-repo mounts, layer reuse from prior images, and multi-arch image indexes.
Added
-
Safe mode: a new global-only
safesetting (MISE_SAFE=1) makes mise refuse or ignore anything that would let project config execute code or inject environment. Blocked (with errors): templateexec()/read_file(),_.source, hooks, tasks, asdf plugin scripts, and plugin installs. Ignored: project[env],_.path,_.file,[shell_alias], and[settings]. HTTP-based version resolution, lockfile refresh/bump, and already-installed/embedded plugins keep working. Because a config loaded this way is inert, safe mode also skips the trust requirement. (#11146, #11151 by @jdx)MISE_SAFE=1 mise lock --bump --dry-run --json # detect updates with zero code execution, no trust needed -
mise lock --bump: advance fuzzy lockfile selectors (latest,lts, prefixes like"20") to the newest matching remote versions without installing anything and without touchingmise.toml. Exact pins stay put. Pairs with--jsonand--dry-runfor a CI job that opens lockfile-only PRs. (#11145 by @jdx)$ mise lock --bump --dry-run --json [{ "name": "node", "backend": "core:node", "old_versions": ["22.14.0"], "new_versions": ["22.15.0"] }]
-
Node-free
npm:backend:mise ls-remote npm:*andlatestresolution now query the npm registry directly over HTTP, and installs run in-process through the embedded aube package manager. node is only needed to run installed tools (and their lifecycle scripts), not to install them. User~/.npmrc, scoped registries, auth, andminimum_release_ageare honored. A newnpm.shell_outsetting (MISE_NPM_SHELL_OUT) routes both metadata and installs through the npm CLI for setups relying on npm-only config likecafileor client certs. (#11147, #11149 by @jdx) -
Built-in OCI registry client:
mise oci pushno longer requires skopeo or crane. It uses an in-tree OCI Distribution client that uploads only blobs the registry is missing, resolves credentials the way docker/podman do (docker login/podman loginis all the setup needed), and answers registry auth challenges so private base-image pulls via--fromalso work.mise oci run --engine dockernow streams the image intodocker loadinstead of needing skopeo. The--toolflag was removed. (#11132 by @jdx) -
OCI push robustness: large layers upload in 64 MiB chunks, transient failures retry with mise's standard backoff, base layers are mounted cross-repo (
?mount=) when they already live on the destination registry (zero bytes transferred), and pushes/pulls now show byte progress. A newoci.insecure_registriessetting opts non-loopback registries into plain HTTP. (#11141 by @jdx) -
OCI layer reuse:
mise oci pushreuses unchanged tool layers from the previously pushed image (or--cache-from REF), skipping the tar/gzip build entirely — reused tools don't even need to be installed locally.--no-cacheforces a full rebuild. (#11142 by @jdx) -
Multi-arch OCI images:
mise oci push --update-indexpoints a tag at an OCI image index and upserts the current platform while preserving entries pushed by other architectures, so one runner per arch can assemble a multi-arch tag. (#11144 by @jdx) -
Built-in signature verification: Node.js and Swift download signatures are now verified in-process with the pure-Rust rPGP crate against the bundled keyrings, dropping the external
gpgbinary dependency. Note: previously, ifgpgwas missing and the setting was unset, verification was silently skipped; now verification always runs when enabled — opt out withgpg_verify = false. (#11148 by @jdx) -
Relative bootstrap repo paths:
[bootstrap.repos]destination keys can now be relative paths, resolved against the declaring project's root (with guards preventing escape outside the project tree), making a project'smise.tomlportable across machines. (#11155 by @lilienblum)
Fixed
- http:
mise lock,ls-remote,outdated, andupgradeno longer get capped to a single 3s no-retry attempt whenprefer_offlineis set — they honor the configuredfetch_remote_versions_timeoutand retry budget again, fixing spurious timeouts. Interactive fast paths keep their bounded behavior. (#11190 by @jdx) - lock: unfiltered
mise lockno longer prunes OS-restricted tool entries (e.g.os = ["macos"]) when run on a platform that doesn't target them, keeping shared lockfiles stable across platforms. (#11175 by @jdx) - env: values loaded from
_.fileenv files now resolve references to variables defined in earlier files or[env]blocks instead of collapsing to empty, fixing flaky dotenv behavior. (#11158 by @Marukome0743) - env:
[env] _.sourcenow works on Windows by resolving a real POSIX bash (Git Bash / MSYS2, honoringMISE_BASH_PATH) instead of the WSL launcher or a missingbash.exe, and correctly filters MSYS runtime noise and converts prepended PATH entries back to Windows form. (#11097 by @JamBalaya56562) - config:
trusted_config_paths(MISE_TRUSTED_CONFIG_PATHS) now overrides configs previously added to the ignore list, so a settings-trusted config is actually discovered and loaded. (#11152 by @JamBalaya56562) - config:
env/varsarray parsing is now consistent — accidental array forms forvarsand taskenv/varsare rejected with clear errors, while the intentional[[env]]and directive-level arrays (_.source,_.file,_.path) remain supported. (#11060 by @risu729) - config:
mise config setno longer panics when descending into a non-table value. (#11153 by @Marukome0743) - config: clearer warnings for unsupported semver ranges. (#11176 by @risu729)
- hook-env: entering a directory with an untrusted config now prints a single concise warning (
... is not trusted, run 'mise trust' to enable it) instead of the full error chain. Explicit commands still show the full trust error and prompt. (#11159 by @lilienblum) - activate:
mise activate zshno longer hangs non-interactive login shells under Rosetta — a v2026.7.11 regression where env-state snapshotting autoloaded thezsh/parametermodule viadlopen. (#11188 by @jdx) - brew-cask: case-insensitive app bundle lookup (fixing casks like
yaak) and correct resolution of preflight-generated wrapper scripts on the extract stage (fixingvlc). (#11164 by @donbeave) - brew: cask binaries can symlink into
/usr/localon arm64. (#11174 by @jdx) - backend: qualified prerelease suffixes are now detected correctly. (#11179 by @risu729)
- completions: avoid a network lookup during usage completion. (#11169 by @jdx)
- link: clear a stale incomplete marker when linking a tool. (#11150 by @Marukome0743)
- shim: unresolved Windows exe-shim dispatch (e.g. a project-scoped tool run outside the project) now shows the actionable "no version is set" guidance instead of an opaque "cannot find binary path". (#11189 by @jdx)
- vfox: preserve inner quotes when a vfox Lua command dispatches through
cmd.exeon Windows, fixing commands such as the Yarn 2+ install flow. (#11166 by @finalchild) - github/gitlab/forgejo: statically-linked
linux-muslassets are now considered a fallback for Android/Termux when a package publishes no Android-specific asset, so tools like starship, bat, and hk can install there. (#10730 by @bltavares) - deps: avoid installing tools during dry runs, and enforce the experimental gate for task providers. (#11016, #11177 by @risu729)
Documentation
- Document environment-variable backing for file-task arguments and flags, including CLI/env/default precedence. (#11165 by @zeitlinger)