Skip to content

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Nov 25, 2025

Summary

Fixes an issue where mise x npm:@anthropic-ai/claude-code@latest would return an older version when both v-prefixed and non-v-prefixed versions were installed.

  • Fixed version sorting to normalize v-prefix before comparing (so v2.0.51 sorts correctly with 2.0.35 and 2.0.52)
  • Fixed fuzzy_match_filter to also match without the v-prefix (so v1.0.0 can match 1.0.0 in npm registries)

Root Cause

When users install npm packages with explicit v-prefixed versions like npm:[email protected], the install directory would be named v1.0.0 even though npm registries don't use v-prefixes. This caused:

  1. Version sorting bug: The Versioning library parses v2.0.51 as a General type (treating "v2" as alphanumeric) rather than Ideal semver, causing incorrect sort order when mixed with non-v-prefixed versions
  2. Version matching bug: Requesting npm:[email protected] wouldn't match 1.0.0 in the npm registry

Test plan

  • Added unit tests for normalize_version_for_sort
  • Added unit test demonstrating the version sorting fix
  • All existing tests pass
  • Clippy passes

🤖 Generated with Claude Code


Note

Normalizes v-prefixed versions for correct sort order and updates fuzzy matching to match with/without the v-prefix, with unit tests added.

  • Version handling:
    • src/toolset/install_state.rs: Add normalize_version_for_sort and use it when sorting installed versions to correctly order mixed v-prefixed and non-prefixed versions.
    • src/backend/mod.rs: Update fuzzy_match_filter to support matching queries both with and without a leading v (e.g., v1.0.0 matches 1.0.0), and refine the latest pattern.
  • Tests:
    • Add unit tests for normalization and mixed v-prefix sorting behavior in install_state.rs.

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

When users install npm packages with explicit v-prefixed versions like
`npm:[email protected]`, the install directory would be named `v1.0.0` even
though npm registries don't use v-prefixes. This caused two issues:

1. Version sorting: The `Versioning` library parses `v2.0.51` differently
   than `2.0.51`, causing incorrect sort order when mixed versions exist.
   For example, `["v2.0.51", "2.0.35", "2.0.52"]` would sort incorrectly,
   making the `latest` symlink point to `2.0.35` instead of `2.0.52`.

2. Version matching: Requesting `npm:[email protected]` wouldn't match `1.0.0`
   in the npm registry, falling back to using the raw `v1.0.0` string.

This commit fixes both issues:
- Normalize versions by stripping v-prefix before sorting
- Allow fuzzy_match_filter to match versions without the v-prefix

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copilot AI review requested due to automatic review settings November 25, 2025 23:50
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 fixes version handling issues with npm packages that have v-prefixed versions, ensuring that mise x npm:@anthropic-ai/claude-code@latest correctly returns the latest version regardless of v-prefix usage.

Key Changes:

  • Normalized version sorting to handle mixed v-prefixed and non-v-prefixed versions correctly
  • Enhanced version matching to support queries with v-prefix against registries without v-prefix

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/toolset/install_state.rs Added normalize_version_for_sort function and updated version sorting logic to strip v-prefix before comparison; includes comprehensive unit tests
src/backend/mod.rs Enhanced fuzzy_match_filter to match v-prefixed queries against non-v-prefixed registry versions

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

Comment on lines +794 to +799
let query_without_v_regex = if query.starts_with('v') || query.starts_with('V') {
let without_v = regex::escape(&query[1..]);
Some(Regex::new(&format!("^{without_v}([-.].+)?$")).unwrap())
} else {
None
};
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

String slicing with &query[1..] will panic if query is a single character 'v' or 'V'. Add a length check before slicing to ensure the string has more than one character.

Copilot uses AI. Check for mistakes.
.iter()
.sorted_by_cached_key(|v| (Versioning::new(v), v.to_string()))
.collect();
println!("Without normalization: {:?}", sorted_without_norm);
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

Test code should not contain println! statements as they clutter test output. Consider removing these debug statements or using proper test assertions instead.

Copilot uses AI. Check for mistakes.
Comment on lines +339 to +340
println!("With normalization: {:?}", sorted_with_norm);

Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

Test code should not contain println! statements as they clutter test output. Consider removing these debug statements or using proper test assertions instead.

Suggested change
println!("With normalization: {:?}", sorted_with_norm);

Copilot uses AI. Check for mistakes.
@jdx jdx enabled auto-merge (squash) November 26, 2025 00:01
@jdx jdx merged commit 863755e into main Nov 26, 2025
28 checks passed
@jdx jdx deleted the fix/npm-v-prefix-versions branch November 26, 2025 00:09
@github-actions
Copy link

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.11.7 x -- echo 19.1 ± 0.4 18.2 21.0 1.00
mise x -- echo 19.7 ± 0.5 18.5 21.5 1.03 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.11.7 env 18.6 ± 0.6 17.7 24.2 1.00
mise env 19.1 ± 0.8 18.0 29.6 1.03 ± 0.05

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.11.7 hook-env 18.7 ± 0.7 17.6 27.5 1.00
mise hook-env 18.9 ± 0.4 17.9 20.2 1.01 ± 0.05

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.11.7 ls 16.0 ± 0.3 15.3 17.3 1.00
mise ls 16.6 ± 0.5 15.6 19.1 1.03 ± 0.04

xtasks/test/perf

Command mise-2025.11.7 mise Variance
install (cached) 106ms 106ms +0%
ls (cached) 64ms 66ms -3%
bin-paths (cached) 71ms 72ms -1%
task-ls (cached) 424ms 427ms +0%

jdx pushed a commit that referenced this pull request Nov 26, 2025
### 📦 Registry

- add blender by @lucasew in
[#7014](#7014)
- add vespa-cli by @buinauskas in
[#7037](#7037)
- fix vespa-cli order by @buinauskas in
[#7038](#7038)
- add scooter by @TyceHerrman in
[#7039](#7039)
- Prefer github backend for allure by @TobiX in
[#7049](#7049)

### 🚀 Features

- **(plugins)** Install a plugin from a zip file over HTTPS by @KaanYT
in [#6992](#6992)
- **(registry)** add tool options support for http backend by @jdx in
[#7061](#7061)

### 🐛 Bug Fixes

- **(core)** trim `core:` prefix in unalias_backend by @kou029w in
[#7040](#7040)
- **(go)** use -mod=readonly for go install by @joonas in
[#7052](#7052)
- **(npm)** handle v-prefixed versions correctly by @jdx in
[#7062](#7062)
- **(tasks)** add missing task fields to JSON output by @roele in
[#7044](#7044)
- semver in aqua by @lucasew in
[#7018](#7018)
- use the musl version if installing in Android (Termux) by @lucasew in
[#7027](#7027)
- empty enable_tools crash by @moshen in
[#7035](#7035)

### 📚 Documentation

- add MISE and USAGE syntax hl queries to neovim cookbook by @okuuva in
[#7047](#7047)
- use local assets for screenshots by @okuuva in
[#7056](#7056)
- remove GitHub issues link from roadmap by @jdx in
[6897286](6897286)

### 📦️ Dependency Updates

- update docker/metadata-action digest to 318604b by @renovate[bot] in
[#7033](#7033)
- update actions/checkout digest to 34e1148 by @renovate[bot] in
[#7032](#7032)
- lock file maintenance by @renovate[bot] in
[#7048](#7048)

### Chore

- upgrade actionlint to 1.7.9 and fix lint issues by @jdx in
[#7065](#7065)

### New Contributors

- @joonas made their first contribution in
[#7052](#7052)
- @KaanYT made their first contribution in
[#6992](#6992)
- @kou029w made their first contribution in
[#7040](#7040)
- @moshen made their first contribution in
[#7035](#7035)
- @buinauskas made their first contribution in
[#7038](#7038)
- @lucasew made their first contribution in
[#7014](#7014)

## 📦 Aqua Registry Updates

#### New Packages (3)

- [`m7medVision/lazycommit`](https://github.com/m7medVision/lazycommit)
-
[`microsoft/component-detection`](https://github.com/microsoft/component-detection)
- [`owenlamont/ryl`](https://github.com/owenlamont/ryl)

#### Updated Packages (1)

- [`sst/opencode`](https://github.com/sst/opencode)
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.

2 participants