mise-en-place

jdx/mise last check 661 releases today
Notes

The front-end to your dev env Pronounced "MEEZ ahn plahs"

Release notes
view on github
2026.10.18 · v2026.10.18: mise lsp: a language server for mise.toml · today

mise now includes a language server, mise lsp, which gives editors diagnostics, completion, hover, navigation and quick fixes for mise.toml. Doctor checks can depend on other checks, and mise dot history purge erases a tracked file from dotfiles history. This release also fixes many lockfile, prune, Windows and dotfiles issues.

Added

  • mise lsp, a language server for mise config files. It runs over stdin/stdout, so any editor with an LSP client can use it (Neovim, Helix, Emacs, Zed, VS Code, ...). It uses the schema and formatter of the installed mise, so its answers match your version. #14744, #14808, #14811, #14812 (@jdx)

    • Diagnostics: TOML syntax errors, unknown keys with a "did you mean" suggestion, values of the wrong type, and deprecated keys. It warns about task references that point to no task and reports depends cycles as errors.
    • Completion and hover: config keys and enum or boolean values, task names in depends, depends_post, wait_for, run = [{ task = ... }] and extends, and tool names from the registry under [tools]. Hover shows the description and backends of a tool, or the description and command of a task.
    • Navigation and editing: go to a task's definition (also in included files), find its references, and rename a task together with every reference in the file. Quick fixes replace an unknown key or task name, and rewrite a deprecated key such as env_path to the key that replaces it. Formatting gives the same output as mise fmt.
    • It only handles files that mise loads as configs (mise.toml, mise.<env>.toml, conf.d/*.toml, ...) and ignores Cargo.toml, pyproject.toml and other TOML files, so you can attach it to the TOML filetype. Configs are parsed but never rendered, and it makes no network requests, so opening an untrusted file runs nothing. Clients can turn off formatting, hover, completion, definition, references or rename with initializationOptions.
    vim.lsp.config("mise", { cmd = { "mise", "lsp" }, filetypes = { "toml" }, root_markers = { "mise.toml" } })
    vim.lsp.enable("mise")
    
  • Doctor checks can depend on other checks. Add depends (a single name or a list) to a check in [doctor.checks.*]. If a dependency fails, errors, is skipped or is blocked, the dependent check is reported as blocked, and its command and hint are skipped. A blocked result does not change the exit code on its own. An unknown dependency name or a cycle is reported as a config error, and then no checks run. #14773 (@jdx)

    [doctor.checks."examplectl:project"]
    depends = ["examplectl:auth"]
    run = 'test -n "$(examplectl config get project)"'
    
  • mise dot history purge <path> removes a tracked path from local dotfiles history. Use it after tracking a secret by mistake. Checkpoints that changed only that path are removed. All other checkpoints keep their numeric IDs, messages and dates, so history, rollback and undo keep working. Use --dry-run to preview and --yes to skip the prompt. --backup keeps the old history under refs/mise/purge-backup/, and --keep-objects skips pruning. The command refuses if any version of the path is already reachable from the origin, because mise never force-pushes. #14831 (@jdx)

  • A dotfiles variant's target can be a template, so one shared config can link into locations that differ between machines. Only the variant target is rendered. Templates get the standard config context (env, xdg_config_home, config_root, ...), but exec() and vars are not available. The rendered path must be absolute or start with ~/. #14856 (@jdx, @ponko2)

    [dotfiles.examplectl]
    source = "dotfiles/examplectl"
    mode = "symlink"
    variants = [{ default = true, target = "{{ xdg_config_home }}/examplectl" }]
    
  • mise upgrade --bump --pin writes resolved versions to config. Requests such as latest or 20 become the exact version, for example 24.14.0, even if the tool was already up to date. With the pin setting (MISE_PIN=1), a plain mise upgrade --bump now does the same. --dry-run shows what would change. #14791 (@jdx)

  • [bootstrap.hooks] tables accept run_windows, as tasks and [hooks] already do. On Windows it is used instead of run. A table with only run_windows does nothing on other platforms. #14851 (@jdx)

  • Registry: goose-agent (aqua:aaif-goose/goose), the Goose AI agent CLI. The installed binary is still named goose. #14822 (@kwsantiago)

Changed

  • pin now also affects a plain mise upgrade --bump. If you have pin enabled, your next mise upgrade --bump rewrites non-exact requests such as "22" to exact versions such as "22.1.0". Without pin, requests keep their precision as before. #14791 (@jdx)
  • mise unuse tool@version only prunes the version you named. It used to prune every unused version of the tool. If the named version is kept, mise now explains why, for example node@24.20.0 is kept: required by ~/proj/mise.toml. mise unuse node without a version still prunes all unused versions of node. #14863 (@jdx, @Strepto)

Fixed

Lockfiles

  • If a pipx tool selects its own Python (python = "3.12"), mise use, mise up -l, mise lock pipx:... and mise lock python now keep both that Python and the project's Python in mise.lock. Before, one entry was dropped and mise install --locked failed. #14794 (@jdx, @AllDmeat)
  • mise install tool@latest no longer fails with "lockfile contains multiple resolutions" when nested configs pin different versions. The nearest lockfile now decides. #14818 (@jdx)
  • When a monorepo root config is in .config/mise.toml, the shared lockfile is now written to .config/mise.lock instead of <root>/mise.lock. #14860 (@jdx, @fxsalazar)
  • mise lock for pipx: and pypi: tools now accepts PyPI simple indexes that respond with a PEP 691 +html content type, such as Azure Artifacts. #14852 (@jdx, @alexanderlinne)
  • Locked conda installs reuse cached downloads whose checksum is known, instead of downloading the package again. #14866 (@zeitlinger)

Install, upgrade and prune

  • A project-level [hooks].postinstall now runs with the version that was just installed. Before, during mise upgrade of a fuzzy request such as latest, its PATH pointed at the old version. #14853 (@jdx, @sam9191)
  • mise prune no longer aborts with "points to an unknown mise Python installation" when a pypi/pipx tool's receipt reaches mise's Python through a minor-version link such as python/3.14. #14857, #14874 (@jdx, @chancez)
  • With MISE_OVERRIDE_TOOL_VERSIONS_FILENAMES set, tracked .tool-versions files are still loaded. Before, mise prune could remove versions that those projects still used. #14779 (@jdx)
  • java = "latest" now selects the newest installed build when two installed versions differ only after + (for example +7 and +101). #14876 (@jdx, @javabrett)
  • gem: installs and bundle install no longer fail when mise is not on PATH. This applies to Rubies installed with this release or later. #14850 (@jdx, @fxsalazar)
  • packslip tools no longer warn on every mise outdated or mise up about skipping a version that is past the minimum_release_age cutoff when that version is already installed. #14835 (@jdx, @alx-xo)
  • Homebrew tap formulae that define their own Requirement classes no longer break mise bootstrap packages apply. mise does not enforce these requirements and logs a warning about them. #14807 (@jdx)
  • mise oci build images that include rust now contain a working cargo and rustc, with CARGO_HOME and RUSTUP_HOME set, so containers no longer download the toolchain again on first use. The build now fails if rust comes from a rustup that mise does not manage. #14854 (@jdx, @eiswind)

Network and backends

  • In official rustls Linux builds, mise falls back to its bundled Mozilla root certificates, with a warning, when no system CA certificates can be loaded (for example in minimal containers, or when SSL_CERT_FILE points to a missing file). Roots that do load are not changed. #14817 (@jdx)
  • GitHub assets now download correctly when .netrc has credentials for github.com. The reachability check no longer sends those credentials, which had caused a fallback to the rate-limited API. #14786 (@jdx)
  • github: tools for which mise-versions returned an empty release list (such as github:caarlos0/svu) now fall back to paged listing, so their versions are found. #14877 (@jdx)
  • Expired glab OAuth2 tokens are now ignored instead of sent. This fixes 401 Unauthorized errors when installing gitlab: tools from public projects. #14873 (@jdx, @chung1905)

Windows

  • Zip archives that contain read-only files, such as the Flutter SDK, now extract without "Access is denied". #14869 (@jdx, @akiWagashi)
  • uv-locked pipx: tools whose console script names end in .py (for example pipx:clang-format) now install. #14825 (@jdx)
  • In tasks, run_windows = [] now skips the task on Windows instead of running run. #14859 (@jdx)

Tasks, bootstrap and generate

  • mise tasks list now works as an alias for mise tasks ls. If you have a task named list, that task still runs. #14878 (@jdx, @mcstafford-git)
  • mise bootstrap no longer fails when a namespaced task such as system:bootstrap exists but no task is named exactly bootstrap. #14858 (@jdx)
  • mise generate install-script --write and mise generate task-stubs now write files that end with a newline. Existing stubs regenerate as before. #14819 (@itochan)
  • curl https://mise.run | sh no longer fails when ~/.config/curlrc sets write-out. #14830 (@jdx)

Dotfiles

  • A mode = "track" entry declared in a config.<env>.toml stays tracked on machines that don't select that env. Before, those machines published a removal of the entry. #14815 (@jdx)
  • One saved enrollment under a parent directory that is now a symlink no longer stops automatic capture for all other tracked paths. It is reported as invalid instead. #14871 (@jdx)
  • The JSON schema now declares the keys of [dotfile_groups.<name>.entries], so strict validators such as Tombi accept valid entries and report unknown keys. #14810 (@jdx)

Other

  • The aqua registry built into mise is now encoded the same way on every build, so builds of the same source are reproducible. #14809 (@jdx)

Performance

  • mise now checks trusted_config_paths after the cheaper trust rules and resolves each entry at most once per process. This speeds up hook-env when entries are on slow mounts such as autofs /home on macOS. #14875 (@jdx)

Documentation

  • The dotfiles docs now explain repo-only files, how existing repos fit in, undoing an accidental track, and what add --no-apply, dot diff and exclude do. #14829, #14862 (@jdx)

New Contributors

  • @kwsantiago made their first contribution in #14822

Full Changelog: https://github.com/jdx/mise/compare/v2026.10.17...v2026.10.18

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