Conversation
| = manifest.dependencies.into_iter().map(|(n, r)| (n, r, false)) | ||
| .chain(manifest.optional_dependencies.into_iter().map(|(n, r)| (n, r, true))); | ||
|
|
||
| for (name, range, is_optional) in all_dependencies { |
There was a problem hiding this comment.
Optional deps missing from pnpm output parsing
Medium Severity
The new code reads optionalDependencies from each package's package.json manifest and then looks them up via entry.dependencies.get(&name). However, PnpmListDependency only deserializes the dependencies key from pnpm's JSON output. Since pnpm's list --json outputs optionalDependencies as a separate top-level key (evidenced by its --no-optional and --prod filter flags), optional dependencies of workspace packages will never be found in entry.dependencies, and the new handling code will silently skip all of them.
Reviewed by Cursor Bugbot for commit 1d9b669. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ed5ae36. Configure here.
| # Capture the versions pnpm resolved (normalized to name@version) | ||
| pnpm ls -r --json --depth=Infinity \ | ||
| | jq -r '.. | objects | select(.version? and .from?) | "\(.from)@\(.version)"' \ | ||
| | sort -u > "${TEMP_DIR}/pnpm-versions.txt" |
There was a problem hiding this comment.
Test version extraction likely broken for transitive dependencies
Medium Severity
The jq filter builds version strings using \(.from)@\(.version), but the from field in pnpm's JSON output includes the version range for transitive dependencies (e.g., "from": "graceful-fs@^4.2.0"). This produces garbled entries like graceful-fs@^4.2.0@4.2.6 instead of graceful-fs@4.2.6, causing false mismatches with the yarn side. With jest having 100+ transitive dependencies, this likely exceeds the 5-mismatch threshold, making the test always fail — or if from was removed in recent pnpm, the file would be empty and the test would pass vacuously without verifying anything.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ed5ae36. Configure here.
⏱️ Benchmark Resultsgatsby install-full-cold
📊 Raw benchmark data (gatsby install-full-cold)Base times: 2.651s, 2.489s, 2.431s, 2.456s, 2.465s, 2.429s, 2.444s, 2.439s, 2.446s, 2.437s, 2.458s, 2.463s, 2.447s, 2.442s, 2.437s, 2.442s, 2.459s, 2.402s, 2.473s, 2.486s, 2.443s, 2.458s, 2.431s, 2.448s, 2.438s, 2.469s, 2.438s, 2.463s, 2.454s, 2.448s Head times: 2.620s, 2.410s, 2.490s, 2.428s, 2.419s, 2.436s, 2.457s, 2.443s, 2.435s, 2.457s, 2.467s, 2.438s, 2.487s, 2.453s, 2.469s, 2.425s, 2.443s, 2.444s, 2.454s, 2.466s, 2.487s, 2.460s, 2.416s, 2.466s, 2.471s, 2.466s, 2.484s, 2.511s, 2.441s, 2.447s gatsby install-cache-and-lock (warm, with lockfile)
📊 Raw benchmark data (gatsby install-cache-and-lock (warm, with lockfile))Base times: 0.362s, 0.355s, 0.365s, 0.360s, 0.365s, 0.365s, 0.362s, 0.363s, 0.358s, 0.365s, 0.360s, 0.360s, 0.363s, 0.360s, 0.367s, 0.357s, 0.367s, 0.355s, 0.365s, 0.359s, 0.358s, 0.368s, 0.363s, 0.370s, 0.388s, 0.359s, 0.348s, 0.352s, 0.358s, 0.356s Head times: 0.363s, 0.361s, 0.361s, 0.361s, 0.381s, 0.359s, 0.372s, 0.369s, 0.405s, 0.362s, 0.362s, 0.370s, 0.361s, 0.372s, 0.360s, 0.363s, 0.362s, 0.367s, 0.374s, 0.366s, 0.375s, 0.362s, 0.368s, 0.362s, 0.370s, 0.364s, 0.367s, 0.371s, 0.365s, 0.374s |


This PR adds a way to migrate a repository from pnpm to Yarn. I have an older repository I need to migrate so this will be handy.
Note
Medium Risk
Changes how lockfiles are synthesized from
pnpm listoutput (depth handling, path resolution, optional dependency filtering), which can affect dependency resolution during migrations. Adds new e2e coverage and updates CI sandbox tooling, so failures may surface in build/test pipelines.Overview
Improves pnpm migration lockfile generation by dynamically choosing
pnpm listdepth based on pnpm version, normalizing relative package paths tonode_modules, and incorporatingoptionalDependenciesonly when actually installed.Updates the e2e sandbox image to install
pnpm, adds an e2epnpm-migration.shtest that compares resolved versions between pnpm and yarn with a mismatch threshold, and expands.gitignoreto exclude local.claude/.supersetdirectories.Reviewed by Cursor Bugbot for commit ed5ae36. Bugbot is set up for automated code reviews on this repo. Configure here.