Skip to content

chore(deps): update dependency jdx/mise to v2026.11.0 - #80

Open
opencode-circadian-renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jdx-mise-2026.x
Open

opencode-circadian-renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jdx-mise-2026.x

Conversation

@opencode-circadian-renovate

@opencode-circadian-renovate opencode-circadian-renovate Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Type Update Change Pending
jdx/mise uses-with minor 2026.10.7 → 2026.11.0 v2026.11.4 (+3)

Release Notes

jdx/mise

v2026.11.0: : Task locks for shared resources, safer lockfiles, and .agents/skills as the default skills directory

Compare Source

Tasks can now declare a lock, so runs that share a resource take turns, even across worktrees and terminals. This release also adds opt-in npm provenance verification, dotfile dependencies, and mise bootstrap --update for global config checkouts. Lockfiles get stricter: --locked now requires checksums, and safe mode no longer trusts project lockfiles. The planned removal of minimum-version reading from go.mod and CMakeLists.txt also lands here. See Breaking Changes before you upgrade.

Added

  • Task lock. When several agents or terminals run tasks at the same time, they can collide on resources that exist only once on the machine, such as a shared test database, a simulator or a GPU. A task can now name the locks it needs, and a run that needs a lock someone else holds waits for it. #​15242 (@​jdx)

    • A string name is shared by every task on the machine that uses it. lock = true locks the task within its repository, and all worktrees of that repository share the lock.
    • mise takes the lock just before the first command, after dependencies, skip_if, sources and cache checks, so a skipped task never waits. A task waiting for a lock gives up its --jobs slot, so other tasks keep running. Nested mise run calls inherit their parent's locks and don't deadlock on them.
    • mise run --lock-timeout 5m, or the task.lock_timeout setting, makes a task fail after waiting that long. The error names the run holding the lock. mise tasks info and --dry-run show the locks a task takes.
    • Locks are OS file locks (flock, or LockFileEx on Windows), so they are released when the holder exits, even if it is killed. This feature is not experimental.
    [tasks.test]
    run = "pytest"
    lock = "test-db"
    
    [tasks."e2e:ios"]
    run = "./scripts/e2e-ios.sh"
    lock = ["ios-simulator", "test-db"]
    [test] waiting for lock test-db, held by test in ~/src/shop-pr-42 (pid 4121, for 3.0s)
    
  • npm provenance verification (opt-in). With npm.provenance = true, or the provenance category of paranoid, mise install verifies the Sigstore provenance an npm: tool's package publishes, against the sha512 integrity that the install locks. Packages that publish no provenance install as before. This only works with the embedded aube package manager, and only the tool's own package is checked, not its dependencies. #​15240 (@​jdx, @​kndoshn)

    [settings.npm]
    provenance = true
  • Dotfile depends. A [dotfiles] entry or a [dotfile_groups] group can list the groups or entry targets it depends on. mise dot apply writes those first, in rounds. This lets an entry such as a mode = "fnox" file or a template that reads a file use files created in the same apply, so a new machine needs only one apply. mise reports an error for a cycle or an unknown name. If a round fails, mise stops and lists the entries it didn't apply. #​15277 (@​jdx, @​owpac)

    [dotfiles]
    "~/.workrc" = { mode = "fnox", depends = ["secrets"] }
    "~/.npmrc" = { mode = "fnox", depends = ["~/.ssh/encryption_ed25519"] }
  • mise bootstrap --update pulls the global config checkout. Without --from or --adopt, --update fast-forwards the Git checkout that holds ~/.config/mise. This works whether the directory is linked into a checkout by --config-dir or is a checkout itself from --adopt. Bootstrap then runs again from the new commit. mise accepts only fast-forwards, so a diverged checkout stops the run. --dry-run prints the git pull --ff-only instead of running it. #​15286 (@​jdx, @​owpac)

  • Skills default to .agents/skills. When skills.dir is unset, mise skills sync and skills.auto_sync use .agents/skills if it exists, or else an existing .claude/skills. If neither exists, mise creates .agents/skills and makes .claude/skills a symlink to it, so Claude Code finds the skills too. Projects that already sync into .claude/skills keep doing so. #​15278 (@​jdx, @​canac)

  • mise use -g syncs skills into your home directory. With skills.auto_sync on, mise use -g links the skills of global tools into the skills directory under your home directory. mise install and mise upgrade keep those links current from any directory. mise skills sync --global now links only tools from the global and system config, not every tool active in the current directory. #​15276 (@​jdx, @​canac)

  • Registry: kotlin-toolchain (JetBrains' Kotlin Toolchain, formerly Amper) #​15234 (@​ggoggam), headscale #​15282 (@​i-api), and tailscale #​15298 (@​i-api).

Fixed

Tasks
  • On Windows, a multi-line run or run_windows script under cmd.exe ran only its first line and exited 0. It now runs every line, and a later exit /b fails the task. Each line still runs whatever the previous line's exit code was, and %VAR% is expanded once for the whole script. #​15238 (@​jdx)
  • With jobs > 1, mise run could hang forever after a task failed while other tasks were still queued. #​15268 (@​jdx)
  • Monorepo tasks run from the root, such as mise run //subproject:task, now get the variables the subproject's daemons export, such as API_PORT. An explicit [env] value for the same key still wins. #​15217 (@​jdx, @​dotellie)
  • mise tasks validate no longer reports a run_windows-only task as having no command when you run it on macOS or Linux. #​15258 (@​jdx, @​ryan-pip)
  • A mistyped command such as mise lsit now suggests mise list. Hidden internal commands are never suggested. #​15260 (@​jdx)
Tools and backends
  • A tool requested as latest with prerelease = true now runs the newest installed version, prereleases included. Before, it kept running the stable release behind the latest symlink. This affects mise x, PATH, which, where and bin-paths. #​15259 (@​jdx, @​ywenhao)
  • pypi: tools now install when mise has no Python interpreter. mise warns and installs from the version alone. --locked installs and tools that select a specific python still fail. #​15287 (@​jdx)
  • pypi: tools from an SSH GitHub source with only Git tags and no releases now list versions when a GitHub token is configured. #​15291 (@​jdx)
  • mise daemons status, stop, logs, prune and tui no longer fail with "No version is set for shim: pitchfork" when the project doesn't pin pitchfork in [tools]. #​15237 (@​jdx, @​brodienguyen)
Lockfiles
  • mise lock no longer fails when a Java vendor publishes no build for one of the lockfile's platforms, such as Oracle GraalVM on linux-arm64-musl. It skips that platform. #​15269 (@​jdx)
  • mise lock now prints "Pruned …" only after it writes the lockfile, so a run that fails partway no longer claims a prune that didn't happen. #​15267 (@​jdx)
Config
  • A .config/, mise/ or .mise/ directory that is its own Git repository, such as a dotfiles checkout, loads again as config for the directory around it. Before, its config was dropped without any message. #​15224 (@​jdx, @​mdt3r)
Dotfiles and bootstrap
  • Several Windows dotfiles fixes: #​15248, #​15249, #​15252, #​15254 (@​jdx)
    • mise dot unapply now removes junctions and directory symlinks instead of failing with "Access is denied".
    • symlink-each entries now prune dangling links even after their state file is lost.
    • A symlink entry that fell back to a copy is reported as copied, both in apply output and in mise dot status.
    • Changing the letter case of a target path no longer creates a second state file.
  • After mise dot apply fails partway, the next apply now continues without needing mise dot recover. Links made before the failure are recorded, and empty directories the apply created are removed. #​15253 (@​jdx)
  • mise bootstrap no longer records history checkpoints for runs that change nothing. This also makes no-op runs faster. #​15246 (@​jdx)
  • With homebrew_metadata = true, the Homebrew cask handoff now also writes INSTALL_RECEIPT.json, so brew info shows the install date and that you requested the cask. The handoff now requires Homebrew 6.0.22 or newer. With an older Homebrew, mise keeps ownership of the cask. #​15274 (@​jdx)
  • brew-cask upgrades no longer skip auto-updating apps whose installed version still matches the install record but has a different number of version components than the cask version, such as Firefox 158.0.1 vs 159.0. #​15226 (@​waynehoover)
  • mise bootstrap packages apply no longer reinstalls every mas: app while Spotlight is rebuilding its index, for example after a macOS update. If mas list comes back empty but App Store apps are installed, mise stops with an error instead. #​15228 (@​waynehoover)
  • mise's background services on Windows, such as the tool updater, now keep running after you close the Windows Terminal window. This needs Windows 11 24H2 or Windows Server 2025 or later, and a window can still appear briefly at startup. #​15265 (@​CCJK123)
Performance
  • Embedded vfox plugins such as gcloud no longer re-run their env hook on every prompt. The cached result is dropped when an environment variable the hook read changes. Plugins can also use the new mise.cache Lua module to name files their result depends on, or to turn caching off. #​15227 (@​jdx, @​leipert)
  • mise hook-env no longer re-parses uv.lock sidecars for pypi:/pipx: tools on every run. In one report this took about 320 ms of a 395 ms prompt. #​15230 (@​jdx)
  • "latest" tools no longer check their install directory several extra times per prompt. #​15295 (@​jdx, @​disrupted)
Packaging
  • apt update against the mise Debian repository should no longer fail with "File has unexpected size … Mirror sync in progress?". Repository metadata is now cached for 5 minutes instead of a day, and the index files are uploaded before the files that describe them. #​15219 (@​jdx)

Security

  • Locked mode requires checksums. mise install --locked now fails before downloading if a lockfile entry for the current platform has a URL but no checksum. #​15285 (@​jdx, @​deniskern)
  • Safe mode never trusts a project lockfile. With MISE_SAFE=1, a project's mise.lock can no longer choose download URLs, even in a trusted project or in CI. mise downloads from the backend's own release and still checks the lockfile's checksum. --locked now accepts entries that have a checksum but no URL. #​15235 (@​jdx)
  • A project .miserc.toml can no longer drop global environments. A project file could set env = [] without being trusted and turn off environments chosen in the global or system miserc.toml, such as one that sets paranoid = true. A project's env_conf_d could do the same to global conf.d fragments. Project files can still add environments. #​15281 (@​jdx, @​adam-moss)

Breaking Changes

  • go.mod and CMakeLists.txt minimum versions are no longer read. This removal was announced in 2026.8.10. A bare go 1.21 line in go.mod no longer selects a Go version. mise reads only a toolchain goX.Y.Z line, or an exact go X.Y.Z line when there is no toolchain line. cmake_minimum_required in CMakeLists.txt is ignored, and the hidden idiomatic_version_file_ignore_minimum_versions setting is removed. To migrate, add toolchain go1.21.4 to go.mod, or set the version in .go-version or mise.toml. For cmake, set the version in mise.toml. #​15266 (@​jdx)
  • --locked fails on lockfile entries without checksums. This affects lockfiles written by hand or by an older mise. Run mise lock once to fill in the checksums. Lockfiles in lockfile_mode = "merge" are exempt. To keep the old behavior, set locked_require_checksum = false, or set it to true to require checksums in merge mode too. The setting will start warning in 2027.10.0. #​15285
  • Global environments now also load where a project .miserc.toml used to replace them. To leave one out for a single run, use -E or MISE_ENV. #​15281

New Contributors

Full Changelog: jdx/mise@v2026.10.25...v2026.11.0

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

v2026.10.25: : Edit and remove tasks from the CLI, and mise watch --once

Compare Source

mise tasks can now add, change and remove tasks in a chosen config file without an editor, and mise watch --once waits for one change, runs the tasks and exits. Both suit scripts and coding agents. The release also adds opt-in env caching for configs with redacted values, and fixes concurrent installs, lockfiles in symlinked config dirs, slow reshims and signed macOS app bundles.

Added

  • mise tasks set and mise tasks rm, plus more options for mise tasks add. #​15213 (@​jdx)

    • add, set and rm take the same --env, --global and --path flags as mise use, so you can pick the file they write to.
    • add and set take new task fields: --env-var, --tools, --usage and --confirm.
    • set changes only the fields you pass and keeps the rest of the file, comments included. --unset FIELD removes a field. It fails if the task doesn't exist.
    • rm (alias remove) deletes a TOML task's table or a file task's script. It asks for confirmation unless you pass --yes, and it refuses tasks inferred from package.json or defined in included files.
    • All three commands accept --json and --dry-run. If more than one loaded file defines a task, set and rm stop and list the files so you can choose one.
    • When add or set trusts the config root it writes to, it now says so on stderr.
    mise tasks add --env local deploy --env-var STAGE=prod --tools node@24 \
      --confirm "Deploy now?" -- ./deploy.sh
    mise tasks set build --description "Build for release" -- cargo build --release
    mise tasks rm --env local --yes scratch
  • mise watch --once. mise waits for a change in the watched sources, runs the tasks once with mise run, and exits with their status. It uses the same filters as a normal watch and runs nothing at start, so --postpone is implied. Flags that only control how watchexec reruns the command, such as --restart and --clear, are refused with --once. Ctrl-C exits with 130. SIGTERM while waiting exits without running anything. A signal during the run stops the whole task process tree. mise watch also now passes --exit-on-error to watchexec, which stops at the first failed run and exits with its status. --exit-on-error requires watchexec 2.5.0 or later. #​15212 (@​jdx)

    mise watch test --once && echo "tests pass after the change"
  • env_cache_redacted setting. With env_cache = true, mise never caches an environment that contains a redact = true directive, so a slow _.source script ran again on every prompt. The new opt-in env_cache_redacted setting (MISE_ENV_CACHE_REDACTED=1, default false) lets these environments be cached. Values stay masked in output when they are read from the cache. The tradeoff: the secret values are stored on disk, encrypted with a key that every process started from the activated shell inherits. age and sops values, plugin results with cacheable = false, redacted [vars], and redacted default/required directives are still never cached. With MISE_DEBUG=1, mise now logs when an environment wasn't cached and which directive prevented it. #​15200 (@​jdx, @​Achder)

    [settings]
    env_cache = true
    env_cache_redacted = true
  • managed_by in bootstrap package status JSON. Installed brew-cask packages now report managed_by ("mise", "homebrew" or "unknown") in mise bootstrap packages status --json and mise bootstrap status --json. Scripts can use it to tell which casks mise will upgrade and which it leaves to Homebrew. #​15198 (@​jdx, @​drewbitt)

  • Registry: added jouet, which installs from its signed packslip #​15201 (@​jdx)

Changed

  • mise tasks add now accepts --force. Re-adding an identical task does nothing. Replacing a task that has a different definition without --force still works for now. mise will warn about it starting in 2027.5.0 and refuse it starting in 2028.5.0. Scripts that only run on current mise versions can add --force now. #​15213 (@​jdx)

Fixed

  • Running several mise install processes at once could fail with errors like "Python graph installs require an installed interpreter", because one process saw a tool another process was still installing and treated it as complete. Installs and forced reinstalls now mark a version as incomplete before touching its directory. #​15196 (@​jdx, @​theredspoon)
  • When ~/.config/mise is a symlink into a dotfiles checkout that has a config.override.toml, running mise install inside the checkout no longer makes mise.lock alternate between full and empty. #​15197 (@​jdx, @​ponko2)
  • mise reshim, including the reshim at the end of mise install, no longer slows down quadratically with the number of tracked configs. On machines with thousands of tracked projects it could take minutes. #​15203 (@​jdx, @​Birzool)
  • On macOS, signed .app bundles extracted from tarballs made with bsdtar are no longer killed on launch. mise now applies the ._* AppleDouble files to the files they belong to and then deletes them, as macOS tar does. #​15211 (@​jdx, @​jpeeler)
  • A [bootstrap.repos] entry whose ref is an annotated tag now reports current once that tag is checked out. Before, it always reported differs, and every apply checked the tag out again. #​15199 (@​jdx)
  • Dotfiles: replacing several tracked paths with the directory that contains them no longer leaves the directory stuck as "not applied here" with autosave stopped. #​15187 (@​jdx, @​drewbitt)
  • Dotfiles: mise dot untrack with several paths now checks all of them before changing anything. Before, if a later path wasn't tracked, the command failed but had already stopped tracking the earlier paths. #​15208 (@​jdx, @​drewbitt)

Full Changelog: jdx/mise@v2026.10.24...v2026.10.25

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

v2026.10.24: : Container daemons, append-position PATH entries, and extra CA certificates

Compare Source

Experimental daemons can now run container images with Docker or Podman, and named preset ports can get their own port per worktree. This release also adds position = "append" for env._.path, an extra_ca_certs setting for TLS-inspecting proxies, and a registry_index option for locking pypi: tools. It fixes several lockfile, PyPI, Homebrew and task issues.

Added

  • Container images as daemons (experimental). A custom daemon with an image key runs through docker run or podman run. It supports ports, readiness checks, depends, the proxy and mise daemons logs, just like other daemons. Every port is published on 127.0.0.1 only. Containers are named per project and worktree, so two checkouts never clash, and a stale container left behind by a killed run is removed before the next start. runtime = "auto" (the default) uses docker if it is on PATH, otherwise podman. You can set MISE_CONTAINER_RUNTIME to use any Docker-compatible CLI. data_mount bind-mounts a per-checkout data directory, and ready_cmd can use {{ runtime }}, {{ container }} and port placeholders. Limitations: mise does not pull or build images or start the Docker/Podman service, only TCP ports are supported, and starting a container daemon on Windows fails. #​15182 (@​jdx)

    [daemons.cockroach]
    image = "cockroachdb/cockroach:v25.1.0"
    command = ["start-single-node", "--insecure"]
    port = { auto = true, base = 26257 }
    ports.http = { container = 8080, auto = true, base = 27000 }
    data_mount = "/cockroach/cockroach-data"
    ready_cmd = "{{ runtime }} exec {{ container }} cockroach sql --insecure -e 'select 1'"
  • Per-worktree named ports for daemon presets. Named preset ports such as http_port on cockroachdb or monitor_port on nats now accept { auto = true, base, stride }, just like the primary port. Each linked worktree adds its slot to the port's own base. Before, these ports were either fixed or offset from the preset default. When base is omitted, it defaults to the preset's port. Integer overrides still work as before. mise now reports a load error if an auto named port collides with another daemon's port in the same project. #​15181 (@​jdx)

    [daemons.cockroach]
    preset = "cockroachdb"
    version = "26"
    port = { auto = true, base = 26258 }
    ports.http_port = { auto = true, base = 27000 }
  • position = "append" for env._.path. Appended entries go after tool paths and before the inherited PATH. This lets directories like ~/bin or ~/.cargo/bin stop shadowing tools that mise installs. The default is still "prepend". #​15158 (@​jdx, @​Mossop)

    [env]
    _.path = [
      "bin",
      { path = ["~/bin", "~/.cargo/bin"], position = "append" },
    ]
  • extra_ca_certs setting. extra_ca_certs (MISE_EXTRA_CA_CERTS) points to a PEM bundle that mise trusts in addition to its usual roots, on every platform. Use it when you're behind a traffic-inspecting proxy such as Socket Firewall. It covers mise's own HTTP requests: downloads, version lookups, GitHub API calls, attestation checks and vfox plugins. Programs that mise runs, such as git and uv, keep using their own certificate settings. You can set it only in the environment or in global config. The path must be absolute or start with ~/. If the bundle is unusable, mise warns and keeps its usual roots. #​15171 (@​jdx, @​abjectnotfound)

    MISE_EXTRA_CA_CERTS=/etc/ssl/proxy-ca.pem mise install
  • registry_index for pypi: tools. Set registry_index = "priority" to search a per-tool registry_url before PyPI when locking. This works for registries that host only your own packages, such as Gitea/Forgejo, pypiserver or a static index. The tool always comes from the registry, and only packages the registry doesn't have fall back to PyPI. The default, "default", keeps the current behavior: the registry replaces PyPI. #​15157 (@​jdx)

    [tools]
    "pypi:black" = { version = "25.9.0", registry_url = "<your-registry>/api/packages/org/pypi/simple/{}/", registry_index = "priority" }
  • secret() in merge = "missing" dotfile entries. Tera templates in these entries can now call secret(). mise asks only for the secrets of keys missing from the target, so you can add a key to a private config later without entering the existing ones again. mise dot status and mise dot diff never read or prompt for a secret. Enforced merge = true entries still can't use secret(). #​15168 (@​jdx, @​thernstig)

  • Danger Swift libraries. The danger-swift registry entry now uses Danger's official installer, so libDanger and the Swift modules are installed with the executable. You still need to install Node and Danger JS separately. #​15120 (@​Mostafa-Ashraf97)

Fixed

  • Lockfiles
    • mise upgrade now updates every lock entry of a tool that is declared in more than one config file, such as config.toml and a conf.d fragment. Before, the old entry stayed in the lockfile and mise outdated kept offering the same upgrade. #​15164 (@​jdx, @​eliebleton-manomano)
    • http: tools with a file:// URL and no checksum install and lock again under the default lockfile_mode = "generate". mise now hashes the local file directly. #​15180 (@​jdx, @​hcrosse)
    • mise install no longer exits 1 when a git task include can't be loaded, for example a private repository in CI. It warns and leaves the lockfile unchanged. An explicit mise lock still fails. #​15166 (@​jdx)
  • PyPI / pipx
    • mise lock now locks a pypi: tool's dependency graph with the selected Python, even when that Python isn't on PATH. If a per-tool python isn't installed yet, uv may download it for resolution only, unless offline is set. #​15153 (@​jdx)
    • Tools from registries that publish no upload times can now have their dependency graph locked when minimum_release_age is set. Dependencies still respect the cutoff. #​15159 (@​jdx)
    • Repos that lock the same tool and dependencies on different days now share one install instead of each creating its own copy. Each affected tool gets one new install the first time you install it after upgrading. #​15179 (@​jdx, @​tecnobrat)
  • Homebrew
    • Source builds of tap formulae whose post_install uses Homebrew's MachO no longer fail. These steps are skipped with a warning. #​15152 (@​jdx)
    • install_symlink with a relative source, such as bin.install_symlink "foo" => "bar", now resolves against the target directory, as Homebrew does, instead of failing with different prefix. #​15173 (@​waynehoover)
    • Cask postflight hooks that use staged_path can now access the binary payload. This fixes installs such as brew-cask:dynatrace-oss/tap/dtctl. #​14837 (@​azohra)
  • Tasks
    • A remote file task (one whose file is an HTTP URL) with its own env no longer fails with exit 127 when it runs as a sub-task or dependency. #​15178 (@​jdx)
    • mise now accepts comments in turbo.json, which is parsed as JSONC, and in global.json, which still rejects trailing commas. Before, a commented turbo.json printed a warning on every run and its task suggestions were dropped, and a commented global.json broke dotnet version detection. #​15141 (@​jdx)
  • mise prune no longer removes tool versions that tasks still need when those tasks come from task_config.includes files, default task directories, or executable scripts with #MISE tools=.... #​15156 (@​jdx)
  • latest for gem: tools no longer resolves to a RubyGems prerelease such as 4.1.0.beta3. To get prereleases, request one explicitly or set MISE_PRERELEASES=1. #​15143 (@​dennmart)
  • When the active version doesn't provide a shim's executable, the error now names that version and the config that set it, and lists the installed versions that do provide it. Before, mise said "No version is set" and suggested switching versions with mise use -g. #​15165 (@​jdx, @​mzagaja)
  • mise upgrade and mise outdated no longer say "All tools are up to date" when a version lookup fails. They now list the tools they could not check. #​15171 (@​jdx, @​abjectnotfound)

Changed

  • Homebrew formulae are now resolved from the bulk formula.json index, with caching for tap metadata and cask evaluations. In one large setup, warm mise bootstrap packages upgrade --dry-run dropped from about 7.7s to 3.7s, and status from about 4.0s to 1.5s. The first run on a machine downloads the index once. #​15183 (@​waynehoover)

Deprecated

  • lockfile_mode = "merge" is deprecated in favor of the default generate mode. Nothing changes yet. mise will start warning in 2027.4.0, and the mode will be removed in 2027.10.0. To migrate, delete the lockfile_mode = "merge" line (or unset MISE_LOCKFILE_MODE=merge). #​15184 (@​jdx)

Documentation

New Contributors

Full Changelog: jdx/mise@v2026.10.23...v2026.10.24

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

v2026.10.23: : Dotfile groups can apply edits, INI merges, and fnox-stored dotfiles

Compare Source

Dotfile groups can now carry block, line and merge edits, merge entries work on INI files, and mode = "fnox" deploys files kept encrypted in fnox. mise secrets also no longer lets a project grant itself keys from your personal fnox config. The rest of the release adds compact-index version listing for gem sources such as GitHub Packages, plus fixes for uninstall, lockfiles, command wrappers, Windows and MSYS2.

Added

  • Edits inside dotfile groups. A [dotfile_groups.<name>.entries] table can now hold block, line and merge edits alongside whole-file entries. These edits apply only on machines that select the group in [bootstrap] dotfile_groups. Before, edits had to live under [dotfiles], which applies on every machine. Edit entries use the <path>/<id> key form, and a relative source starts at the group root. The edited file must be inside the group's target. Deselecting a group leaves the content its edits already wrote. #​15131 (@​jdx, @​thernstig)

    [dotfile_groups.common]
    root = "common"
    mode = "copy"
    
    [dotfile_groups.common.entries]
    "~/.config/mise/conf.d/private.local.toml/defaults" = { source = "../templates/private.toml", merge = "missing", permissions = "0600" }
  • Dotfile merges into INI files. A merge entry can now set keys in INI files such as pip.conf, tox.ini and setup.cfg. Changed keys are replaced in place, new keys go into their section, and missing sections are added at the end of the file. Comments, other keys, indentation, CRLF line endings and a BOM are all kept. Targets ending in .ini are detected automatically. For any other file name, set format = "ini". Parsing follows Python's configparser, and a target that doesn't parse is reported and left unchanged. This change also fixes merges in any format whose target is a symlink to its own source: if the source fails to parse, mise now keeps the link instead of replacing it with a copy. #​15135 (@​jdx, @​Mossop)

    [dotfiles]
    "~/.config/pip/pip.conf/shared" = { source = "pip/shared.conf", merge = true, format = "ini" }
  • mode = "fnox" for dotfiles containing secrets. This entry writes the file that fnox stores for the target path, so files like ~/.npmrc or ~/.kube/config stay out of your dotfiles repository. It requires fnox 1.44.0 or newer on PATH. Files are written with mode 0600 unless permissions says otherwise. mise dot edit runs fnox edit --file. mise dot diff never prints the content, and dry runs never call fnox. mise dot unapply removes the target only while it still matches what fnox stores, unless you pass --force. mise oci build skips these entries. One limitation: mise dot rollback journals the previous plaintext in the local state directory. Only UTF-8 text files are supported. #​15134 (@​jdx, @​owpac)

    fnox set --file ~/.npmrc
    [dotfiles]
    "~/.npmrc" = { mode = "fnox" }
  • Gem sources without the JSON versions API. If a gem source returns 404 for api/v1/versions/<gem>.json, mise now lists versions from the source's compact index (info/<gem>), the same file Bundler uses. As a result, latest, version prefixes, mise outdated and mise upgrade work for gems from GitHub Packages (rubygems.pkg.github.com/<org>) and similar registries. GitHub Packages doesn't publish release dates, so minimum_release_age can't filter its versions. A 401 from GitHub Packages now comes with a hint about the read:packages token scope. #​15122 (@​waynehoover)

Fixed

  • mise uninstall ruby 3.4.1 no longer removes ruby@3.4.12 when 3.4.1 isn't installed. A version now matches only when it equals the query or continues it after ., - or +, the same way mise matches versions elsewhere. #​15116 (@​jdx, @​Aqualon)
  • mise ls now shows lazy tools that haven't been installed as a dimmed (lazy) instead of a red (missing). A bare mise upgrade no longer lists them among the tools it resolves. mise ls --json still reports "installed": false, and mise ls --missing still includes them. #​15114 (@​jdx)
  • Installing a packageManager entry with a checksum (for example pnpm@11.7.0+sha512...) no longer forces every later install of that tool onto the npm backend. Installs that an earlier version already pinned recover on their next install. #​15124 (@​jdx, @​foobear)
  • A command run through a [wrappers] entry now still goes through other wrappers. For example, node run from a wrapped pnpm now gets the node wrapper's args and env. A wrapper is skipped only for its own nested calls, and that skip is tracked in __MISE_ACTIVE_WRAPPERS. #​15126 (@​jdx)
  • Locked installs inside a dotfiles checkout that is linked into your global config, such as ~/.config/mise/conf.d/dotfiles -> ~/dotfiles, no longer fail with "No lockfile URL found". The checkout's mise.lock is now trusted as global config. A project mise.toml that symlinks to your global config still can't vouch for the project's lockfile. #​15130 (@​jdx, @​soodoh)
  • When ~/.config/mise is a symlink into a dotfiles repository, mise lock --global writes npm and Python sidecars to locks/ again instead of .mise/locks/. Existing pointers are rewritten on the next lock. You can delete the old .mise/locks/ directory by hand. #​15125 (@​jdx)
  • When a backend (cargo, go, gem, pipx, ...) runs a program that isn't on PATH, the error now names it, for example `cargo` not found. Before, it only said "No such file or directory". #​15119 (@​jdx, @​Mossop)
  • Under MSYS2, Git Bash and Cygwin, mise activate for bash, zsh and fish now exports MANPATH in POSIX form, so man can use it. Empty entries are kept so man still uses its default paths. #​15117 (@​jdx, @​PTechoueyres-mic)
  • On Windows, mise self-update retries for about 6 seconds when antivirus briefly locks mise.exe. If replacing the binary fails after the old one has been moved aside, mise copies the new binary into place, so the install directory is never left without mise.exe. #​15138 (@​jdx)

Changed

  • mise dot status and mise dot sync no longer start one git process per tracked file. In one test with about 860 tracked files, a warm mise dot status dropped from about 7s to 1.4s. Output is unchanged. #​15127 (@​waynehoover)
  • The README has been rewritten. It now shows a full mise.toml example up front, an updated quickstart, a table of everyday commands, and a section on mise bootstrap. #​15136 (@​jdx)

Security

  • Projects can no longer grant themselves your personal fnox keys. A key defined in fnox's global config, or in a fnox.toml in or above $HOME, now counts as yours rather than the project's. If a task's secrets list or a {{ secrets.NAME }} reference names such a key, the task fails before any secret is resolved. The error names the file that defines the key. --secrets-all leaves these keys out, while mise run --secrets NAME and mise x --secrets NAME still pass them because you named them yourself. mise secrets ls and mise tasks validate report these grants as problems of kind personal. To give a key to the project, define it in the project's fnox.toml. This needs a fnox release that reports where each key is defined. With older fnox, behavior is unchanged. mise secrets is still experimental. #​15133 (@​jdx)

Full Changelog: jdx/mise@v2026.10.22...v2026.10.23

💚 Sponsor mise

mise is built and maintained by @​jdx, an open source developer at entire.io, the titl

[!IMPORTANT]
✂ PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate CLI.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants