docs/package-plugin-development.md
A package plugin is a Lua-based vfox plugin that implements a machine-global
manager for [bootstrap.packages]. It wraps state owned
by a host tool rather than installing versioned tools under mise's data
directory.
mise-vscode-extensions/
├── metadata.lua
├── mise.plugin.toml
└── hooks/
├── package_installed.lua
├── package_install.lua
└── package_upgrade.lua
The required hooks/package_installed.lua and hooks/package_install.lua pair
identifies the repository as a package plugin. A repository with only one of
these hooks remains a regular vfox plugin. If hooks/backend_install.lua is
also present, mise treats the repository as a tool backend instead; package
and tool-backend plugins must be separate repositories.
[package-manager]
requires = ["code"]
supports_version_pins = true
os = ["macos", "linux"]
requires lists host binaries the hooks invoke. mise adds its shims and
global toolset bin paths to PATH, but does not install these tools
automatically; users declare them in [tools] or install them manually.supports_version_pins defaults to false.os is optional and defaults to every platform. Values use mise platform
names such as macos, linux, and windows.All hooks receive the complete package batch. Managers must be batch-oriented.
function PLUGIN:PackageInstalled(ctx)
-- ctx.packages: {{ name = "diff", version = "1.3.4" | nil }, ...}
return {
packages = {
{ name = "diff", state = "installed", version = "1.3.4" },
{ name = "s3", state = "missing" },
},
}
end
PackageInstalled must be side-effect free, fast, non-interactive, and never
elevate. It must return one installed or missing entry for every request.
mise computes a version mismatch when a requested pin is not exactly equal to
the returned version.
function PLUGIN:PackageInstall(ctx)
-- ctx.dry_run: print intended actions and do nothing
-- ctx.update: refresh manager metadata first when applicable
for _, package in ipairs(ctx.packages) do
-- install package.name, optionally at package.version
end
return {}
end
PackageUpgrade has the same context and response. It is optional; mise calls
PackageInstall when the upgrade hook is absent. The name reserves room for a
future PackageUninstall hook, but uninstall and prune are not part of v1.
sudo in any hook. mise never elevates for
them.PackageInstalled is side-effect free, non-interactive, never elevates, and
should be fast.requires.For a VS Code implementation, PackageInstalled can parse
code --list-extensions --show-versions, PackageInstall can run
code --install-extension name[@version], and PackageUpgrade can run
code --update-extensions or reinstall the requested extensions.