mise-en-place

jdx/mise last check 307 releases recent
Notes

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

Release notes
v2026.9.7: Lockfile revision 2 with npm and Python dependency graphs, dotfile conflict inspection · recent
view on github

This release introduces mise.lock revision 2, which records complete transitive dependency graphs for npm tools (via embedded aube) and Python tools (via uv) in native sidecar files, and adds mise bootstrap dotfiles conflicts for inspecting dotfile sync conflicts before resolving them. It also lets dotfile templates consume bootstrap secrets, stops minimum_release_age from rejecting versions already committed to a lockfile, and closes a security gap in history.describe_command.

Added

  • lock: Lockfile revision 2 records the full dependency graph of npm tools installed by embedded aube and of pypi: tools installed by uv, then replays it with a strict frozen install so two projects on the same top-level version can still receive their own reviewed transitive graph. Graphs live in native sidecar files (uv.lock / aube-lock.yaml plus a manifest) under .mise/locks/<backend-tool>/<version>/, referenced from mise.lock by relative path and SHA-256 digest, so the lockfile itself stays small. Commit the sidecar directory with mise.lock. New lockfiles use revision 2; existing revision 0 and 1 files keep their format until you run mise lock --upgrade. mise lock --bump <tool> refreshes a tool's transitive graph even when its top-level version is unchanged, ordinary mise install validates and accepts hand-edited sidecars, and mise install --locked rejects digest mismatches until you run mise lock. Python graph locking requires uv 0.12.10 or newer and published wheels for the target platform; Git sources, standalone pipx installs, and free-form uvx_args/pipx_args stay version-only. (#13131, #13146 by @jdx)

    mise lock --upgrade        # move an existing lockfile to revision 2 and resolve graphs
    mise install --locked      # replay the recorded graphs
    mise lock --bump pypi:black  # refresh Black's dependencies without changing its version
    
  • pypi: pypi: is now the preferred name for the Python CLI backend; pipx: remains fully supported as an alias with no warnings, and settings accept both pypi.* and pipx.* names. The two spellings are distinct tool identities (pypi-black vs pipx-black install directories and lock entries), so switching spelling creates a new installation. (#13146 by @jdx)

  • bootstrap: mise bootstrap dotfiles conflicts [PATH...] shows a read-only comparison of the saved local and fetched remote versions of a conflicted dotfile so you can decide between --take-remote and --keep-local with full context. The default output is a unified diff including file-mode changes; --difftool opens the configured Git diff.tool (falling back to merge.tool) and --tool <name> picks one explicitly. Encrypted contents are decrypted only into private temporary files, and inspection never modifies either side or marks the conflict resolved. Bootstrap secrets are also now resolved from the same composed config maps as dotfile discovery, so root-scoped dotfile templates can use secrets declared by their bootstrap root. (#13144 by @jdx)

    mise bootstrap dotfiles conflicts ~/.config/mise/config.toml
    mise bootstrap dotfiles conflicts --difftool ~/.config/mise/config.toml
    
  • dotfiles: Dotfile templates (mode = "template") can reference [bootstrap.secrets] values with {{ secret(name="...") }}, matching managed bootstrap file templates. Dotfiles commands that render templates (add, apply, diff, edit, status, unapply) accept --prompt-secrets; without an available value, rendering fails closed. A full mise bootstrap run preflights dotfile templates before making changes, mise bootstrap status reports secrets used only by dotfiles, and textual diffs redact resolved secret values. (#13140 by @jdx)

    [bootstrap.secrets]
    api_token = "EXAMPLE_API_TOKEN"
    
    [dotfiles."~/.config/example/credentials"]
    source = "dotfiles/credentials.tmpl"
    mode = "template"
    

Fixed

  • lock: Installing from a committed mise.lock no longer fails when the locked release is younger than minimum_release_age. The cutoff still applies when resolving unlocked fuzzy requests and when generating or bumping a lockfile, and npm:/pypi: still forward it to unpinned transitive dependencies, but a reviewed lock entry now reproduces immediately in CI instead of waiting for the release to cool. (#13128 by @jdx)
  • config: A .python-version (or other idiomatic version file) containing system selects the system interpreter without printing the mise-specific @system deprecation warning, matching the existing .tool-versions exception. Explicit python@system requests from mise configuration or command arguments still warn. (#13132 by @jdx)
  • npm: Embedded aube is updated to 2.2.16, fixing the Bun checksum install regression and ensuring local npm tarballs keep their manifest package name. (#13145 by @jdx)
  • registry: The mc shorthand uses aqua:minio/mc again now that the upstream Aqua registry entry is restored, with asdf:mise-plugins/mise-mc kept as the fallback. (#13124 by @jdx)

Security

  • history: history.describe_command is now global-only. Previously an implicitly trusted project could set it and have a later dotfiles history checkpoint execute the project-controlled command with unencrypted tracked-file diffs. The setting is honored only from system/global configuration or MISE_HISTORY_DESCRIBE_COMMAND; project values are ignored with a warning. (#13134 by @jdx)
  • oci: mise oci build now renders dotfile templates with a restricted engine: secret() is rejected and the env context, get_env(), exec(), and read_file() are unavailable, so ambient credentials cannot be baked into a publishable image layer. (#13140 by @jdx)

Breaking Changes

  • Lockfile revision 2 is not readable by older mise versions. Newly created lockfiles use revision 2, and existing files switch only when you run mise lock --upgrade. Upgrade collaborators and CI to this release before committing a revision 2 mise.lock, and commit the .mise/locks/ (or .config/mise/locks/) sidecar directory alongside it. Revision 2 --locked installs fail if a recorded graph is missing or its digest does not match. If you gitignore mise.local.lock, also ignore its matching sidecar subdirectory (for example .mise/locks/mise.local/).
  • history.describe_command in project configuration is ignored. Move it to ~/.config/mise/config.toml or set MISE_HISTORY_DESCRIBE_COMMAND.
  • mise oci build dotfile templates can no longer call secret(), get_env(), exec(), or read_file() or read the env context.

Full Changelog: https://github.com/jdx/mise/compare/v2026.9.6...v2026.9.7

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