Skip to content

fix(detector): resolve symlinks when classifying the system node#113

Merged
dipto0321 merged 2 commits into
mainfrom
fix/detector/system-node-resolve-symlinks
Jul 3, 2026
Merged

fix(detector): resolve symlinks when classifying the system node#113
dipto0321 merged 2 commits into
mainfrom
fix/detector/system-node-resolve-symlinks

Conversation

@dipto0321

Copy link
Copy Markdown
Owner

Summary

Resolve symlinks when classifying the node found on PATH, and teach the classifier fnm's multishell farm dirs — so an fnm shim (~/.local/state/fnm_multishells/<id>/bin/node) classifies as managed by fnm instead of unrecognized layout, a kind the cleanup logic treats as safe to overwrite. Closes #111

Linked issues

Closes #111

Type of change

  • feat — new feature (MINOR bump)
  • fix — bug fix (PATCH bump)
  • refactor — no behavior change
  • perf — performance improvement
  • docs — documentation only
  • test — tests only
  • chore — maintenance / dependency bump
  • ci — CI/CD only
  • build — build system only
  • Breaking change (MAJOR bump) — explain below

Checklist

  • Title follows Conventional Commits (feat(scope): subject)
  • I ran make ci locally and it passes
  • I added or updated tests for the change
  • I updated relevant docs (README, docs/, inline godoc)
  • No new linter warnings
  • If breaking: I documented the migration path in the PR body and updated CHANGELOG.md

Scope notes

  • Resolution can upgrade a classification, never downgrade one. Path patterns still classify the unresolved path first; the resolved target is consulted only when the original is unknown. This keeps Debian's /usr/bin/node → /etc/alternatives/node correctly os-package (pinned by a new test).
  • evalSymlinks is a package seam (like whichNode/getenv) so tests use canned resolutions instead of real symlinks, which need elevated rights on Windows runners.
  • SystemNodeInfo.Path keeps the original PATH entry for display; only classification consults the resolved location.
  • Multishell farm roots cover $FNM_MULTISHELL_PATH (plus its farm parent, catching sibling instances from other shells), $XDG_STATE_HOME/fnm_multishells, ~/.local/state/fnm_multishells, and the legacy $TMPDIR/fnm_multishells.

Screenshots / output

Before: System node: /Users/dipto/.local/state/fnm_multishells/79731_.../bin/node (unrecognized layout)
After: System node: /Users/dipto/.local/state/fnm_multishells/79731_.../bin/node (managed by fnm) — verified live on the reporting machine.

🤖 Generated with Claude Code

dipto0321 and others added 2 commits July 4, 2026 01:13
The system-node classifier matched exec.LookPath's result against
manager roots and path patterns without ever resolving symlinks. fnm
is the canonical casualty: its shell integration puts a per-shell
multishell shim dir on PATH ($FNM_MULTISHELL_PATH/bin), so the node
nodeup finds symlink-resolves into $FNM_DIR but shares no path
prefix with it — and the user's own manager-owned node reported as
"unrecognized layout", a kind the cleanup logic treats as safe to
overwrite.

ResolveSystemNode now resolves the PATH entry once (new evalSymlinks
seam) and consults both locations: manager roots match either path,
while path-pattern classification still prefers the unresolved path
and only consults the resolved one when the original is unrecognized
— resolution can upgrade a classification, never downgrade one
(Debian's /usr/bin/node -> /etc/alternatives symlink stays
os-package). managerManagedRoots additionally recognizes the fnm
multishell farm dirs ($FNM_MULTISHELL_PATH and its parent,
$XDG_STATE_HOME / ~/.local/state / legacy $TMPDIR fnm_multishells)
so the farm classifies as fnm-owned even when resolution fails.

Verified live: nodeup check now reports the fnm multishell node as
"managed by fnm".

Refs #111

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
filepath.Dir rewrites separators, so the Windows runner got
\state\fnm_multishells where the table expected the forward-slash
literal. Mirror production by computing the expectation with
filepath.Dir.

Refs #111

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cocogitto-bot

cocogitto-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

✔️ 95ace76...6ce416b - Conventional commits check succeeded.

@dipto0321 dipto0321 merged commit a4050d8 into main Jul 3, 2026
10 checks passed
@dipto0321 dipto0321 deleted the fix/detector/system-node-resolve-symlinks branch July 3, 2026 19:18
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.

fix(detector): system-node classifier doesn't resolve symlinks — fnm multishell node reported as "unrecognized layout"

1 participant