Skip to content

Comments

feat(install): auto-install plugins from [plugins] config section#7856

Merged
jdx merged 4 commits intomainfrom
feat/auto-install-plugins-section
Jan 28, 2026
Merged

feat(install): auto-install plugins from [plugins] config section#7856
jdx merged 4 commits intomainfrom
feat/auto-install-plugins-section

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Jan 27, 2026

Summary

  • Auto-install all plugins defined in [plugins] config section during tool installation
  • Previously, plugins were only auto-installed when a tool using that plugin was being installed
  • Plugins without a corresponding tool in [tools] (like env plugins) never got auto-installed

Changes

Added ensure_config_plugins_installed() to Toolset::install_all_versions() which:

  • Iterates over config.repo_urls (the [plugins] section)
  • Parses plugin keys to determine type (asdf, vfox, vfox-backend)
  • Installs any plugins that aren't already installed

This works across all tool install paths: mise install, mise upgrade, mise use, and internal auto-install.

Test plan

  • Unit tests pass (mise run test:unit)
  • E2E plugin tests pass (e2e/plugins/test_plugin_install, e2e/plugins/test_tiny)
  • E2E install tests pass (e2e/cli/test_install_before)

🤖 Generated with Claude Code


Note

Ensures plugins listed in mise.toml [plugins] are installed even without corresponding tools, enabling env-only plugins to be set up during installs.

  • Adds Toolset::ensure_config_plugins_installed to install all plugins from config.repo_urls before resolving tools; integrates into install_missing_runtimes and install_all_versions
  • Parses plugin keys to determine PluginType (asdf, vfox, vfox-backend) with sane fallbacks via parse_plugin_key
  • Respects dry_run and skips empty/malformed plugin names
  • Adds E2E test e2e/plugins/test_plugins_section_auto_install verifying auto-install with plugin-only and plugin+tool scenarios

Written by Cursor Bugbot for commit 4d1a3ea. This will update automatically on new commits. Configure here.

Copilot AI review requested due to automatic review settings January 27, 2026 20:31
@jdx jdx force-pushed the feat/auto-install-plugins-section branch from 845b72c to 918bd03 Compare January 27, 2026 20:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds automatic installation of plugins defined in the [plugins] configuration section during tool installation. Previously, plugins were only installed when a tool using them was being installed, leaving standalone plugins (like env plugins) uninstalled.

Changes:

  • Added ensure_config_plugins_installed() method to install all plugins from config before tool installation
  • Added parse_plugin_key() helper to determine plugin type from configuration keys
  • Integrated plugin installation into all tool install code paths

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +493 to +506
fn parse_plugin_key<'a>(key: &'a str, url: &str) -> (PluginType, &'a str) {
if let Some(name) = key.strip_prefix("vfox:") {
(PluginType::Vfox, name)
} else if let Some(name) = key.strip_prefix("vfox-backend:") {
(PluginType::VfoxBackend, name)
} else if let Some(name) = key.strip_prefix("asdf:") {
(PluginType::Asdf, name)
} else if url.contains("vfox-") {
// Match existing behavior from config/mod.rs:226-228
(PluginType::Vfox, key)
} else {
(PluginType::Asdf, key)
}
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plugin type parsing logic is duplicated from config/mod.rs (lines 226-228). Consider extracting this logic into a shared helper function in a common module to avoid code duplication and ensure consistent behavior across the codebase.

Copilot uses AI. Check for mistakes.
@jdx jdx force-pushed the feat/auto-install-plugins-section branch from 918bd03 to 4095e71 Compare January 27, 2026 20:46
@github-actions
Copy link

github-actions bot commented Jan 27, 2026

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.1.8 x -- echo 19.8 ± 0.6 18.8 24.3 1.00
mise x -- echo 20.2 ± 0.8 19.1 22.4 1.02 ± 0.05

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.1.8 env 19.2 ± 0.7 18.2 23.3 1.00
mise env 19.9 ± 0.8 18.7 24.9 1.04 ± 0.06

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.1.8 hook-env 19.1 ± 0.3 18.4 20.5 1.00
mise hook-env 19.2 ± 0.3 18.5 21.3 1.01 ± 0.02

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.1.8 ls 16.9 ± 0.5 16.2 19.0 1.00
mise ls 17.4 ± 0.7 16.6 19.9 1.03 ± 0.05

xtasks/test/perf

Command mise-2026.1.8 mise Variance
install (cached) 109ms 109ms +0%
ls (cached) 65ms 66ms -1%
bin-paths (cached) 69ms 69ms +0%
task-ls (cached) 281ms 287ms -2%

@jdx jdx force-pushed the feat/auto-install-plugins-section branch from 4095e71 to d764385 Compare January 27, 2026 20:48
Previously, plugins defined in [plugins] were only auto-installed when
a tool using that plugin was being installed. Plugins without a
corresponding tool in [tools] (like env plugins) never got auto-installed.

This adds plugin auto-installation to Toolset::install_all_versions() so
it works across all tool install paths (mise install, mise upgrade,
mise use, etc.).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@jdx jdx force-pushed the feat/auto-install-plugins-section branch from d764385 to feb19c1 Compare January 27, 2026 20:49
jdx and others added 2 commits January 27, 2026 19:06
…_runtimes

The previous implementation placed ensure_config_plugins_installed inside
install_all_versions, but install_missing_runtimes has an early return when
no tools need installing. This meant plugins from [plugins] config section
were never installed when running `mise install` with only plugins defined.

Also fixes the e2e test to verify plugins are actually installed (cloned)
by checking for URLs in --refs output, rather than just checking if the
plugin name appears in the list (which happens via config registration).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

} else {
(PluginType::Asdf, key)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty plugin name causes panic in debug builds

Medium Severity

The parse_plugin_key function can return an empty string for the plugin name when the config key is empty ("") or contains only a prefix like "vfox:". This empty name is then passed to plugin_type.plugin(), which calls AsdfPlugin::new or VfoxPlugin::new - both have #[requires(!name.is_empty())] contracts that panic in debug builds. In release builds, the plugin path becomes the plugins directory itself (dirs::PLUGINS), causing silent incorrect behavior.

Additional Locations (1)

Fix in Cursor Fix in Web

Adds validation to skip empty plugin names that could result from
malformed config keys like "" or "vfox:". This prevents panics in
debug builds from the #[requires(!name.is_empty())] contract in
AsdfPlugin::new and VfoxPlugin::new.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@jdx jdx merged commit e0f2ebc into main Jan 28, 2026
35 checks passed
@jdx jdx deleted the feat/auto-install-plugins-section branch January 28, 2026 01:56
mise-en-dev added a commit that referenced this pull request Jan 28, 2026
### 🚀 Features

- **(doctor)** add backend mismatch warnings by @jdx in
[#7847](#7847)
- **(http)** add rename_exe support for archive extraction by @jdx in
[#7874](#7874)
- **(http)** send x-mise-ci header for CI environment tracking by @jdx
in [#7875](#7875)
- **(install)** auto-install plugins from [plugins] config section by
@jdx in [#7856](#7856)
- **(registry)** add vercel by @mikecurtis in
[#7844](#7844)
- **(task)** support glob patterns in task_config.includes by @jdx in
[#7870](#7870)
- **(task)** add task templates for reusable task definitions by @jdx in
[#7873](#7873)

### 🐛 Bug Fixes

- **(backend)** change registry mismatch log from info to debug by @jdx
in [#7858](#7858)
- **(ci)** use squash merge for auto-merge-release workflow by @jdx in
[7e5e71e](7e5e71e)
- **(ci)** remove --auto flag to merge immediately when CI passes by
@jdx in
[23ed2ed](23ed2ed)
- **(github)** select platform-matching provenance file for SLSA
verification by @jdx in [#7853](#7853)
- **(go)** filter out version "1" from available versions by @jdx in
[#7871](#7871)
- **(install)** skip CurDir components when detecting archive structure
by @jdx in [#7868](#7868)
- **(pipx)** ensure Python minor version symlink exists for postinstall
hooks by @jdx in [#7869](#7869)
- **(registry)** prevent duplicate -stable suffix in Flutter download
URLs by @jdx in [#7872](#7872)
- **(task)** pass env to usage parser for env-backed arguments by @jdx
in [#7848](#7848)
- **(task)** propagate MISE_ENV to child tasks when using -E flag by
@jdx in
[06ee776](06ee776)
- **(vfox-dotnet)** use os.execute() to fix Windows installation by
@prodrigues1912 in [#7843](#7843)

### 📚 Documentation

- update cache-behavior with env_cache information by @jdx in
[#7849](#7849)

### ◀️ Revert

- remove task inheritance from parent configs in monorepos by @jdx in
[#7851](#7851)
- Revert "fix(ci): remove --auto flag to merge immediately when CI
passes" by @jdx in
[0606187](0606187)

### 📦 Registry

- add mago
([aqua:carthage-software/mago](https://github.com/carthage-software/mago))
by @scop in [#7845](#7845)

### Chore

- **(ci)** auto-merge release branch into main daily at 4am CST by @jdx
in [#7852](#7852)

### New Contributors

- @mikecurtis made their first contribution in
[#7844](#7844)
- @prodrigues1912 made their first contribution in
[#7843](#7843)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant