Skip to content

feat: rename mise prepare to mise deps and add package management#9056

Merged
jdx merged 5 commits intomainfrom
feat/deps-command
Apr 19, 2026
Merged

feat: rename mise prepare to mise deps and add package management#9056
jdx merged 5 commits intomainfrom
feat/deps-command

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 11, 2026

Summary

  • Renames the experimental mise prepare command to mise deps, positioning it as a proper dependency management command
  • Adds mise deps add npm:react and mise deps remove npm:lodash subcommands for managing individual packages
  • Implements add/remove for all 4 JS package managers (npm, yarn, pnpm, bun)
  • mise deps (bare) defaults to mise deps install which is the previous mise prepare behavior
  • Renames all config ([prepare] -> [deps]), settings (show_prepare_stale -> show_deps_stale), flags (--no-prepare -> --no-deps), and state files (prepare-state.toml -> deps-state.toml)
  • No backwards compatibility needed since prepare was experimental

Test plan

  • cargo build compiles cleanly
  • mise run lint passes
  • mise deps --help shows subcommands (add, install, remove)
  • mise dep --help alias works
  • mise deps add npm:react installs react via npm
  • mise deps add -D npm:vitest installs as devDependency
  • mise deps remove npm:lodash uninstalls via npm
  • mise deps (bare) runs all configured providers
  • mise deps install --dry-run shows what would run
  • mise run --no-deps skips auto deps
  • e2e tests: mise run test:e2e test_deps test_deps_depends test_deps_tool_install

🤖 Generated with Claude Code


Note

Medium Risk
Medium risk because this renames an end-to-end command/config surface (preparedeps) and threads the new flag/state/schema through exec/run flows, which can break existing experimental users and monorepo provider discovery. Behavior is largely a rename plus new JS package add/remove execution, but touches multiple CLI entrypoints and config parsing.

Overview
Renames the experimental dependency workflow from mise prepare to mise deps. This updates CLI wiring, help/manpages, usage spec, interactive config editor UI, and all documentation references, including the skip flag rename from --no-prepare to --no-deps in mise exec/mise run.

Promotes deps into a first-class config surface. Config/schema/settings are renamed from [prepare] to [deps], status.show_prepare_stale to status.show_deps_stale, and the persisted freshness state file from .mise/prepare-state.toml to .mise/deps-state.toml, with corresponding engine/provider renames.

Adds package management subcommands. Introduces mise deps add and mise deps remove, parsing ecosystem:package specs, installing required tools first, and executing provider-specific commands (implemented for npm, yarn, pnpm, bun), while bare mise deps defaults to deps install. E2E tests are updated/added to cover listing/dry-run/explain, dependency ordering, tool-install-before-deps, and aliasing (dep and hidden prepare).

Reviewed by Cursor Bugbot for commit 9cb375e. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request renames the experimental "prepare" feature to "deps" across the codebase and documentation, while introducing new subcommands for adding and removing dependencies. Feedback indicates that the current implementation of these subcommands ignores user-defined configurations and monorepo settings by using default provider instances. Furthermore, it is recommended to batch package operations for improved performance and to respect configured timeouts instead of hardcoding them.

Comment thread src/deps/mod.rs Outdated
Comment on lines +303 to +321
pub fn create_provider(ecosystem: &str, project_root: &Path) -> Result<Box<dyn DepsProvider>> {
use providers::*;
use rule::DepsProviderConfig;

let config = DepsProviderConfig::default();
match ecosystem {
"npm" => Ok(Box::new(NpmDepsProvider::new(project_root, config))),
"yarn" => Ok(Box::new(YarnDepsProvider::new(project_root, config))),
"pnpm" => Ok(Box::new(PnpmDepsProvider::new(project_root, config))),
"bun" => Ok(Box::new(BunDepsProvider::new(project_root, config))),
"go" => Ok(Box::new(GoDepsProvider::new(project_root, config))),
"pip" => Ok(Box::new(PipDepsProvider::new(project_root, config))),
"poetry" => Ok(Box::new(PoetryDepsProvider::new(project_root, config))),
"uv" => Ok(Box::new(UvDepsProvider::new(project_root, config))),
"bundler" => Ok(Box::new(BundlerDepsProvider::new(project_root, config))),
"composer" => Ok(Box::new(ComposerDepsProvider::new(project_root, config))),
_ => bail!("unknown deps provider '{ecosystem}'"),
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

create_provider initializes a provider with a default configuration (DepsProviderConfig::default()), which ignores any user-defined settings in mise.toml (such as custom env, dir, or timeout).

Additionally, in monorepos, this may cause add and remove operations to run in the project root instead of the specific subdirectory where the provider is configured. These commands should ideally use the DepsEngine to find and use the existing configured provider instance.

Comment thread src/cli/deps/add.rs
Comment on lines +51 to +57
for spec in &self.packages {
let (ecosystem, package) = parse_package_spec(spec)?;
let provider = crate::deps::create_provider(ecosystem, &project_root)?;

let cmd = provider.add_command(package, self.dev)?;
DepsEngine::execute_command(&cmd, &env, None)?;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The current implementation executes a separate command for each package in the list. For performance and to allow the package manager to perform better dependency resolution, it is recommended to batch packages of the same ecosystem into a single command (e.g., npm install pkg1 pkg2).

Comment thread src/cli/deps/add.rs Outdated
let provider = crate::deps::create_provider(ecosystem, &project_root)?;

let cmd = provider.add_command(package, self.dev)?;
DepsEngine::execute_command(&cmd, &env, None)?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The timeout for the command is hardcoded to None. It should respect the provider's configured timeout if one is specified in mise.toml.

Suggested change
DepsEngine::execute_command(&cmd, &env, None)?;
DepsEngine::execute_command(&cmd, &env, provider.timeout())?;

Comment thread src/cli/deps/remove.rs Outdated
let provider = crate::deps::create_provider(ecosystem, &project_root)?;

let cmd = provider.remove_command(package)?;
DepsEngine::execute_command(&cmd, &env, None)?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The timeout for the command is hardcoded to None. It should respect the provider's configured timeout if one is specified in mise.toml.

Suggested change
DepsEngine::execute_command(&cmd, &env, None)?;
DepsEngine::execute_command(&cmd, &env, provider.timeout())?;

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 11, 2026

Greptile Summary

This PR renames the experimental prepare subsystem to deps across the entire codebase (CLI, config, state file, settings, docs, e2e tests) and adds mise deps add / mise deps remove subcommands backed by provider-specific implementations for npm, yarn, pnpm, and bun. Bare mise deps now defaults to mise deps install (the former mise prepare), and --no-prepare becomes --no-deps in mise exec / mise run.

Confidence Score: 5/5

Safe to merge; all remaining findings are P2 style/clarity concerns with no correctness or data-integrity impact.

No P0 or P1 issues were found. The rename is thorough (CLI, config, state file, settings, docs, tests). The new add/remove commands use correct package manager flags. The two P2 findings (misleading error for unknown ecosystems in create_provider, and the redundant validation in DepsOrdering::new) do not affect correctness at runtime.

src/deps/mod.rs (create_provider error message) and src/deps/deps_ordering.rs (dead validation path)

Important Files Changed

Filename Overview
src/cli/deps/mod.rs New entry point for mise deps; flattens DepsInstall args and defaults to install subcommand. parse_package_spec correctly handles scoped packages like @types/react.
src/cli/deps/add.rs Implements mise deps add ecosystem:package; groups by ecosystem for batching and delegates execution to provider-specific commands. Toolset bootstrap pattern is consistent with install.rs.
src/cli/deps/remove.rs Mirrors add.rs; delegates to provider remove_command. Structure is correct and consistent.
src/cli/deps/install.rs Renamed from prepare.rs; adds --list and --explain modes alongside existing dry-run/force/only/skip flags. Logic is sound.
src/deps/mod.rs Core types and create_provider helper. build_provider always returns Some for non-built-in names (creating a CustomDepsProvider), making the ok_or_else guard unreachable and producing a misleading error when an unrecognized ecosystem is passed to add/remove.
src/deps/engine.rs Full engine with parallel execution, dependency ordering, and state persistence. Pre-filters unknown deps before DepsOrdering::new, which renders that module's validation redundant (but harmless).
src/deps/deps_ordering.rs Thin wrapper around DepsGraph for Kahn's-algorithm scheduling. The unknown-dep bail is dead code in production since the engine always pre-filters, creating a confusing dual contract.
src/deps/providers/bun.rs Handles both bun.lockb and bun.lock lockfile formats. Correct bun add (bun add [--dev]) and remove (bun remove) commands.
src/deps/state.rs Renamed from prepare-state.toml to deps-state.toml. Blake3 hashing logic is unchanged and correct. hash_dir_files depth-3 cap is reasonable.
src/deps/rule.rs Renamed config structs (PrepareConfigDepsConfig). serde(deny_unknown_fields) on DepsProviderConfig will reject any future undocumented fields, which is good for schema hygiene.
src/cli/exec.rs Renames --no-prepare to --no-deps and switches PrepareEngine/PrepareOptions to their deps equivalents. Clean rename, no logic changes.
src/cli/run.rs Same rename pattern as exec.rs. Monorepo subdir config collection logic is preserved correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["mise deps [subcommand]"] --> B{Subcommand?}
    B -->|"add ecosystem:pkg"| C["DepsAdd::run"]
    B -->|"remove ecosystem:pkg"| D["DepsRemove::run"]
    B -->|"install (default)"| E["DepsInstall::run"]

    C --> F["parse_package_spec()"]
    D --> F
    F --> G["create_provider(ecosystem)"]
    G --> H{Built-in?}
    H -->|"npm/yarn/pnpm/bun"| I["Typed Provider\n(add/remove_command)"]
    H -->|"unknown name"| J["CustomDepsProvider\n(bails on add/remove)"]
    I --> K["DepsEngine::execute_command()"]

    E --> L["DepsEngine::new()"]
    L --> M["discover_providers()"]
    M --> N{Has deps?}
    N -->|"yes"| O["ensure_experimental()"]
    N -->|"no"| P["(no-op)"]
    O --> Q["check_freshness()"]
    Q -->|"stale"| R{Has deps ordering?}
    R -->|"yes"| S["run_with_deps()\nKahn's algorithm"]
    R -->|"no"| T["run_parallel()"]
    S --> U["DepsState::save()\n.mise/deps-state.toml"]
    T --> U

    V["mise exec / mise run"] -->|"unless --no-deps"| L
Loading

Fix All in Claude Code

Reviews (4): Last reviewed commit: "[autofix.ci] apply automated fixes" | Re-trigger Greptile

Comment thread src/cli/deps/add.rs
Comment thread src/deps/mod.rs Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 11, 2026

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.17 x -- echo 23.3 ± 0.3 22.4 26.5 1.00
mise x -- echo 23.8 ± 0.4 23.0 29.8 1.02 ± 0.02

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.17 env 23.1 ± 0.5 22.4 29.5 1.00
mise env 23.4 ± 0.3 22.7 25.6 1.02 ± 0.02

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.17 hook-env 23.8 ± 0.3 22.2 25.9 1.00
mise hook-env 24.4 ± 0.5 23.6 29.5 1.02 ± 0.03

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.17 ls 21.2 ± 0.3 19.8 23.2 1.00
mise ls 21.7 ± 0.2 21.0 23.1 1.02 ± 0.02

xtasks/test/perf

Command mise-2026.4.17 mise Variance
install (cached) 148ms 153ms -3%
ls (cached) 79ms 80ms -1%
bin-paths (cached) 84ms 85ms -1%
task-ls (cached) 827ms 829ms +0%

jdx and others added 4 commits April 19, 2026 05:21
Renames the experimental `prepare` command to `deps` and adds subcommands
for managing individual packages. This is the first step toward making mise
an actual package manager.

Changes:
- Rename `src/prepare/` module to `src/deps/` with all types renamed
  (PrepareProvider -> DepsProvider, PrepareEngine -> DepsEngine, etc.)
- Rename `[prepare]` config section to `[deps]` in mise.toml
- Rename `--no-prepare` flag to `--no-deps` on run/exec
- Rename `status.show_prepare_stale` setting to `status.show_deps_stale`
- Add `mise deps` subcommand structure (install, add, remove)
- `mise deps` (bare) defaults to install (previous prepare behavior)
- `mise deps add npm:react` / `mise deps add -D npm:vitest` adds packages
- `mise deps remove npm:lodash` removes packages
- Implement add/remove for npm, yarn, pnpm, and bun providers
- Add `create_provider()` for on-the-fly provider creation
- Rename state file from `prepare-state.toml` to `deps-state.toml`
- Update all docs, schema, e2e tests, and interactive config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Batch packages by ecosystem into single commands (e.g., `npm install
  react lodash` instead of two separate calls)
- Use configured provider settings (env, dir, timeout) from mise.toml
  instead of always using defaults
- Pass provider timeout to execute_command instead of hardcoded None
- Change add_command/remove_command trait to accept &[&str] for batching

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jdx jdx force-pushed the feat/deps-command branch from 0101ed4 to 9cb375e Compare April 19, 2026 05:29
Copy link
Copy Markdown

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

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9cb375e. Configure here.

Comment thread e2e-win/deps.Tests.ps1

try {
mise prepare --list | Should -Match 'No prepare providers found'
mise prepare --list | Should -Match 'No deps providers found'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Windows e2e test still uses old command name

Low Severity

The Windows e2e test at line 23 still calls mise prepare --list instead of mise deps --list. While the rest of the test file was properly renamed from "prepare" to "deps", this command invocation was missed. It works today because prepare is a hidden alias, but the test is supposed to exercise the primary deps command path, not the backward-compatibility alias.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9cb375e. Configure here.

@jdx jdx merged commit 105274d into main Apr 19, 2026
35 checks passed
@jdx jdx deleted the feat/deps-command branch April 19, 2026 07:11
jdx pushed a commit that referenced this pull request Apr 19, 2026
### 🚀 Features

- **(latest)** add --before flag to mise latest by @risu729 in
[#9168](#9168)
- **(npm)** add aube package manager support by @jdx in
[#9256](#9256)
- **(spm)** add filter_bins option to restrict built executables by @jdx
in [#9253](#9253)
- **(vfox)** support plugin-declared dependencies via metadata.lua by
@ahemon in [#9051](#9051)
- rename `mise prepare` to `mise deps` and add package management by
@jdx in [#9056](#9056)

### 🐛 Bug Fixes

- **(backend)** skip versions host for direct-source backends by @jdx in
[#9245](#9245)
- **(github)** route artifact attestation verification to custom api_url
by @jdx in [#9254](#9254)
- **(lockfile)** use unique temp file for atomic save to avoid
concurrent rename race by @jdx in
[#9250](#9250)
- **(log)** drop noisy third-party debug/trace logs by @jdx in
[#9248](#9248)
- **(progress)** disable animated clx output in ci by @jdx in
[#9249](#9249)
- **(use)** honor --quiet and --silent flags by @jdx in
[#9251](#9251)
- **(vfox)** opt backend plugins out of --locked URL check by @jdx in
[#9252](#9252)

### 📦 Registry

- add aqua backend for bitwarden-secrets-manager by @msuzoagu in
[#9255](#9255)

### New Contributors

- @ahemon made their first contribution in
[#9051](#9051)
- @msuzoagu made their first contribution in
[#9255](#9255)
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