GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Fix npm crawler missing relocated dependency stores (#359, #362) by mikolalysenko · Pull Request #365 · SocketDev/socket-patch Conversation
|
| Issue | Case | Regression test | Red without fix | Green |
|---|---|---|---|---|
| #359 | transitive + scoped + two-hash copies in .store: scan, resolver, peer fan-out |
crawlers::npm_crawler::tests::test_npm_linked_store_transitive_packages_are_found |
✅ fails | ✅ |
| #359 | store-key decoding (hash with -/_, prerelease, scoped, shrinkwrap dir) |
test_decode_npm_store_entry_name |
new helper | ✅ |
| #359 | real npm, install-strategy=linked, is-odd → is-number: apply patches the copy Node loads, rollback restores it, vendor rewires the lock, vendor --revert is byte-exact |
e2e_vendor_npm_build::npm_linked_strategy_transitive_package_is_patched_rolled_back_and_vendored |
✅ fails (apply failed) |
✅ |
| #362 | virtualStoreDir as JSON ../.vstore, YAML absolute path, YAML '.custom': scan, resolver, peer fan-out |
test_pnpm_relocated_virtual_store_dir_is_walked |
✅ fails | ✅ |
| #362 | store outside the project, or reached through a link (relative or absolute record), is not walked | test_pnpm_virtual_store_dir_outside_project_is_ignored |
guard | ✅ |
| #362 | default --cwd .: an absolute outside store is not crawled; in-project stores, relative and absolute, are |
scan_pnpm_relocated_store_cwd_e2e (3 tests) |
✅ absolute in-project case fails on 1eb28a7 | ✅ |
| #362 | absolute in-project store reached through a linked ancestor: scan and resolver | test_absolute_in_project_store_is_walked_through_any_spelling |
✅ fails on 1eb28a7 | ✅ |
| #362 | absolute recording of the default .pnpm / node_modules is not a relocated store (no double walk) |
test_absolute_default_store_is_not_a_relocated_store |
✅ fails on 6c155c6 | ✅ |
| #362 | containment rule: only plain child names below the importer | test_path_below_accepts_only_plain_children |
✅ | ✅ |
| #362 | an enclosing project's relocated store is not used for peer fan-out | test_enclosing_projects_relocated_store_is_not_a_peer_variant_source |
guard | ✅ |
| #362 | real pnpm 10, virtualStoreDir: .vstore and node_modules/.custom: apply patches the copy Node loads, rollback restores it |
e2e_vendor_pnpm_build::pnpm_agent_apply_patches_a_transitive_dep_in_a_relocated_virtual_store |
✅ fails | ✅ |
Local results on 80f4a71, merged with main 2463257:
cargo test -p socket-patch-core --lib -- npm_crawler: 62 passed.scan_pnpm_relocated_store_cwd_e2e: 3 passed.cargo clippy --workspace --all-features -- -D warnings: clean.cargo fmt --all -- --check: the only diffs in touched files (visit_resolver_dir's signature, oracle.rs imports) are byte-identical on main. CI runs no fmt gate.cargo test --workspace --all-features --no-fail-fast on 1eb28a7: 9,337 passed and 12 failed. All 12 are write-failure or permission tests that fail only because the sandbox runs as root, the same set reported on the other agent PRs. None are in crawler, npm or pnpm code.CI on 80f4a71: all workflows are green (CI, npm, pnpm, Bun, vlt, Audit), and Bugbot reports no new issues. Earlier, on 6c155c6, the vlt legs failed between about 03:05 and 03:20 UTC. The cause was vlt ci itself getting 401 from api.socket.dev/v0/purl, which is outside this diff, and the vlt legs passed again after that window.
🤖 Generated with Claude Code
Note
Medium Risk
Changes filesystem discovery for agent scan/apply/rollback/vendor; incorrect containment logic could skip in-project deps or touch shared stores, but extensive tests guard the boundary cases.
Overview
Agent-mode npm crawling no longer treats transitive-only install layouts as missing packages (package_not_installed). The crawler walks npm’s linked store (node_modules/.store for install-strategy=linked) and pnpm’s relocated virtual store (from node_modules/.modules.yaml / virtualStoreDir), including scan, resolve, apply/rollback/vendor, and peer-variant duplicate discovery.
Safety: stores outside the project (e.g. pnpm’s global virtual store) are excluded so default --cwd . does not patch shared trees across projects (#361). In-project stores still work for relative, absolute, and symlinked path spellings.
Tests & docs: e2e for linked npm and relocated pnpm; scan cwd regression tests; docs/ecosystems.md and CHANGELOG updated.
Reviewed by Cursor Bugbot for commit 444da8c. Configure here.
Generated by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
With npm's install-strategy=linked, or a pnpm virtualStoreDir moved away from node_modules/.pnpm, transitive dependencies live only in a store the crawler never walked: it matched stores by fixed name and skipped every other hidden dir. apply, scan and vendor then reported those packages as not installed and left them unpatched. The crawler now walks npm's node_modules/.store (including scoped entries one level down) and the pnpm store that .modules.yaml records, in scan, apply's resolver and the peer-copy fan-out. A recorded store outside the project, such as pnpm's global virtual store shared by other projects, is still left alone. Assisted-by: Claude Code:claude-opus-5-5
Covers #359 (npm install-strategy=linked, transitive dep only in node_modules/.store: apply, rollback and vendor) and #362 (pnpm virtualStoreDir at .vstore and node_modules/.custom: apply and rollback), each checking that Node loads the patched copy. Both fail on main with package_not_installed. Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Claude Code:claude-opus-5-5
The fan-out that patches every peer-variant copy looked up a relocated pnpm store from any ancestor directory. For a project nested inside another pnpm project, that could pick the outer project's store and patch copies this project never loads. A relocated store now counts only when the copy being patched sits inside it. Assisted-by: Claude Code:claude-opus-5-5
npm 9.0-9.3 ignore install-strategy=linked and install the hoisted tree, so the npm 9.0.0 compatibility cell has no .store to test. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
Or push these changes by commenting:
@cursor push af6d4cb22e
diff --git a/crates/socket-patch-core/src/crawlers/npm_crawler.rs b/crates/socket-patch-core/src/crawlers/npm_crawler.rs --- a/crates/socket-patch-core/src/crawlers/npm_crawler.rs +++ b/crates/socket-patch-core/src/crawlers/npm_crawler.rs @@ -310,6 +310,9 @@ let text = crate::utils::fs::read_regular_to_string_sync(&nm.join(PNPM_MODULES_YAML)).ok()?; let recorded = parse_modules_yaml_virtual_store_dir(&text)?; let importer = normalize_lexically(nm.parent()?); + if importer.as_os_str().is_empty() { + return None; + } let store = normalize_lexically(&nm.join(recorded)); if store == normalize_lexically(&nm.join(".pnpm")) || store == normalize_lexically(nm) { return None; @@ -1088,7 +1091,11 @@ /// Inside a store entry (`store_entry`) a link is a dependency edge into /// a sibling entry, whose own visit records that copy, so only a real /// directory there matches. - fn visit_resolver_dir(nm_path: PathBuf, store_entry: bool, pending: &[Target]) -> ResolverVisit { + fn visit_resolver_dir( + nm_path: PathBuf, + store_entry: bool, + pending: &[Target], + ) -> ResolverVisit { let listing = list_dir_sync(&nm_path); let probe_filter = ProbeFilter::new(&listing); let matched = pending
You can send follow-ups to the cloud agent here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
[agent] Two new issues share this PR's root cause (a dependency store dir that isn't on the hard-coded list gets dropped by the hidden-entry skip): #366 (Bun isolated linker, Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
On macOS the temp dir sits under the /var -> /private/var link, so the peer-variant fan-out from a direct dep's importer link only matched the relocated store on the canonical chain and reported the copy as /private/var/..., unlike the other store layouts. Containment is now also checked canonically, so the store is kept as the caller spelled it. The regression test reaches its project through a linked ancestor so this is covered on every platform. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HcXxpY7X3MC84EEfA8jws6
With the CLI's default `--cwd .` the importer is the empty relative
path, and `strip_prefix("")` accepts every path, so an absolute
`virtualStoreDir` such as pnpm's global virtual store passed the
in-project check and was crawled (and would be patched in place).
The store must now sit strictly below the importer by plain child
names: no root, prefix or `..` component.
Reported by Cursor Bugbot on #365.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HcXxpY7X3MC84EEfA8jws6
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
The Windows test helper shells out to `cmd /C mklink /J`, which reads a `/` inside a path (`[email protected]/node_modules/is-number`) as a switch, so the linked-store and relocated-store tests failed on Windows with "Invalid switch". Rebuild both paths from their components first so every separator is `\`. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HcXxpY7X3MC84EEfA8jws6
|
[agent] Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Brings in the v5 consolidation (#277). Keeps main's rewritten CHANGELOG and re-adds this branch's Fixed entry, and points the virtualStoreDir reader at strip_bom's new home in utils::serde. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Old pnpm records virtualStoreDir as an absolute path. With the default --cwd . the importer is the empty path, which is never a prefix of an absolute store, so a store inside the project was skipped and its transitive packages stayed package_not_installed. An absolute store is now also compared with both sides canonicalized, which also covers a project reached through a linked ancestor. A store that resolves outside the project, such as pnpm's global virtual store, is still refused. Reported by Cursor Bugbot on #365. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
pnpm's default store, node_modules/.pnpm, is walked by name. An old or Windows pnpm can record it in .modules.yaml as an absolute path, and from --cwd . (or through a linked ancestor) that spelling missed the lexical default-location check. The relocated-store reader then accepted it too, so every store copy was reported twice. The check now compares the importer-relative tail, so any spelling of the default store, or of node_modules itself, is skipped. Reported by Cursor Bugbot on #365. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[burn-down agent] Ready for review on Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
# Conflicts: # CHANGELOG.md
|
bugbot run Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 444da8c. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
npm install-strategy=linked: transitive packages under node_modules/.store are "not installed", and scan --apply exits 0 leaving them unpatched
There was an error while loading. Please reload this page.