Skip to content

fix(install): surface npm link failures and fall back to user-local shim#2520

Merged
cv merged 2 commits into
mainfrom
fix/2515-npm-link-fallback-shim
Apr 29, 2026
Merged

fix(install): surface npm link failures and fall back to user-local shim#2520
cv merged 2 commits into
mainfrom
fix/2515-npm-link-fallback-shim

Conversation

@laitingsheng

@laitingsheng laitingsheng commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Summary

A fresh git clone + npm install on a Linux host without a writable global npm prefix reported success but left no nemoclaw command on PATH — the prepare script's npm link 2>/dev/null || true swallowed both stderr and the exit code. This surfaces the real npm error and falls back to a user-local wrapper at ~/.local/bin/nemoclaw. uninstall.sh recognises the new shim shape so it cleans up later.

Related Issue

Closes #2515

Changes

  • Add scripts/npm-link-or-shim.sh: hardened set -eu helper that runs npm link and on failure writes a wrapper at ~/.local/bin/nemoclaw. Atomic write via tempfile + rename, marker-based refusal to overwrite foreign files, idempotent refresh of NemoClaw-managed shims.
  • package.json: prepare now invokes the helper instead of swallowing errors inline.
  • uninstall.sh: is_installer_managed_nemoclaw_shim recognises the dev-shim shape so remove_nemoclaw_cli cleans it up.
  • test/npm-link-or-shim.test.ts (new) + test/uninstall.test.ts: regression coverage for six failure/success paths plus the uninstaller cleanup.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

AI Disclosure

  • AI-assisted — tool: Claude Code, Codex

Signed-off-by: Tinson Lai tinsonl@nvidia.com

Summary by CodeRabbit

  • New Features

    • Enhanced CLI installation flow with a new helper that attempts linking and falls back to creating a managed user-local shim for more reliable setup.
  • Bug Fixes

    • Updated uninstall logic to recognize and remove the new managed shim variant.
  • Tests

    • Added comprehensive tests covering install fallback, shim creation/idempotence, overwrite protection, and uninstall behavior.

## Summary

A fresh `git clone` + `npm install` on a Linux host without a writable
global npm prefix (and without sudo) reported success, but the
`nemoclaw` command never landed on PATH. Root cause: the package.json
`prepare` script invoked `NEMOCLAW_INSTALLING=1 npm link 2>/dev/null ||
true`, which suppressed both stderr and the exit code, so any link
failure was invisible to the user. They only discovered it when
`nemoclaw onboard` returned "No such file or directory".

Replace the silent npm-link step with a small helper that surfaces the
real npm error and falls back to a user-local wrapper at
`~/.local/bin/nemoclaw`. Wrapper preserves the Node directory that was
on PATH at install time so it works in shells where Node is provisioned
via nvm. uninstall.sh recognises the new shim shape so a later
uninstall cleans it up alongside the installer wrapper.

## Related Issue

Closes #2515

## Changes

- scripts/npm-link-or-shim.sh: new helper invoked by `npm install` via
  the package.json `prepare` script. `set -eu` so any unchecked failure
  halts. Runs `npm link` from the repo root; on failure, prints the
  captured npm error then writes a wrapper at `~/.local/bin/nemoclaw`
  that exports the captured Node directory and execs `bin/nemoclaw.js`.
  Refuses to overwrite a foreign file (only refreshes a NemoClaw-managed
  shim, identified by a marker line). Atomic write via tempfile + rename
  so a mid-write failure cannot leave a partial unrecognisable file.
  Honours an already-set `NEMOCLAW_INSTALLING` to short-circuit
  prepare-script recursion.
- package.json: replace the inline
  `NEMOCLAW_INSTALLING=1 npm link 2>/dev/null || true` with
  `bash scripts/npm-link-or-shim.sh`. Lenient chaining preserved (the
  helper warns loudly on stderr but does not fail `npm install`).
- uninstall.sh: extend `is_installer_managed_nemoclaw_shim` to also
  recognise the dev-shim shape (marker line + same wrapper structure)
  so a later `uninstall.sh` removes it cleanly instead of leaving a
  stale `nemoclaw` command behind after the source checkout is gone.
- test/npm-link-or-shim.test.ts: regression tests covering six cases —
  shim is created on link failure (wrapper structure, marker line,
  Node-directory PATH export), no shim on success, no-op when
  `NEMOCLAW_INSTALLING` is preset, refusal to overwrite a foreign file,
  idempotent refresh of an existing dev-shim, and the original
  high-severity reproduction (`~/.local` exists as a regular file).
- test/uninstall.test.ts: regression test that a dev-shim file in
  `~/.local/bin/nemoclaw` is removed by `remove_nemoclaw_cli`.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@laitingsheng laitingsheng self-assigned this Apr 27, 2026
@coderabbitai

coderabbitai Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a88912a6-7b1d-461a-9912-51cdd9fdabc6

📥 Commits

Reviewing files that changed from the base of the PR and between 76aa927 and 2ebe5e3.

📒 Files selected for processing (1)
  • uninstall.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • uninstall.sh

📝 Walkthrough

Walkthrough

Attempts npm link during prepare; on failure it falls back to creating a managed user-local shim at ~/.local/bin/nemoclaw. Adds tests for both paths and updates uninstall logic to detect and remove the managed shim. (50 words)

Changes

Cohort / File(s) Summary
Package Configuration
package.json
Prepare script now invokes scripts/npm-link-or-shim.sh instead of running inline npm link logic.
Fallback Shim Implementation
scripts/npm-link-or-shim.sh
New executable Bash script: guards re-entrancy, verifies bin/nemoclaw.js, attempts npm link from repo root (logs to temp file), on failure creates an atomic, managed shim at ~/.local/bin/nemoclaw, refuses to overwrite foreign files, and prints PATH guidance.
Tests
test/npm-link-or-shim.test.ts, test/uninstall.test.ts
Adds tests that simulate npm link success/failure; assert shim creation, management-marker presence, idempotency, refusal to overwrite foreign files, behavior when NEMOCLAW_INSTALLING=1, and uninstall removes the managed shim.
Uninstall Logic
uninstall.sh
Extends is_installer_managed_nemoclaw_shim to recognize the new shim format (management marker + exec wrapper) and treat it as installer-managed for removal.

Sequence Diagram(s)

sequenceDiagram
  participant npm as npm (client)
  participant prepare as prepare script
  participant repo as Repo (bin/nemoclaw.js)
  participant fs as User FS (~/.local/bin)
  npm->>prepare: run prepare during install
  prepare->>repo: verify bin/nemoclaw.js executable
  prepare->>npm: attempt `npm link` (capture logs)
  alt npm link succeeds
    npm-->>prepare: success
    prepare->>fs: no shim needed (linked globally)
  else npm link fails
    npm-->>prepare: failure + logs
    prepare->>fs: create managed shim at ~/.local/bin/nemoclaw (atomic write, make executable)
    prepare->>npm: print shim creation and PATH instruction
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I hopped through scripts and linked with care,
When link-ups failed, I left a hop of flair.
A shim was written, tidy and bright,
Now nemoclaw springs into sight! 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(install): surface npm link failures and fall back to user-local shim' accurately and clearly describes the main changes: addressing a bug where npm link errors were suppressed and implementing a fallback shim mechanism.
Linked Issues check ✅ Passed All code changes directly address the requirements from issue #2515: the new shell script surfaces npm link failures and implements a user-local shim fallback; package.json integrates this helper; uninstall.sh recognizes the managed shim; tests verify both success/failure paths and cleanup.
Out of Scope Changes check ✅ Passed All changes are scoped to addressing issue #2515: new helper script, updated prepare flow, uninstaller enhancement, and comprehensive test coverage. No unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/2515-npm-link-fallback-shim

Review rate limit: 8/10 reviews remaining, refill in 11 minutes and 57 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@laitingsheng laitingsheng removed their assignment Apr 27, 2026
@wscurran wscurran added bug Something fails against expected or documented behavior CI/CD dependencies Pull requests that update a dependency file labels Apr 27, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this pull request that proposes a way to fix a bug where npm link failures were not surfaced and fell back to a user-local shim. This identifies a bug and proposes a change to surface the real npm error and fall back to a user-local wrapper at ~/.local/bin/nemoclaw, with matching recognition in uninstall.sh to clean up the shim later. The addition of a hardened set -eu helper script and updates to package.json and uninstall.sh will help ensure the issue does not recur.


Related open issues:

@cv cv merged commit 01a177c into main Apr 29, 2026
18 checks passed
@miyoungc miyoungc mentioned this pull request Apr 30, 2026
13 tasks
miyoungc added a commit that referenced this pull request Apr 30, 2026
## Summary
Refreshes the daily docs from NemoClaw commits merged in the past 24
hours and advances the docs metadata from 0.0.29 to 0.0.31, the next
version after tag v0.0.30.
The updates cover documented behavior gaps found in the merged PRs
listed below.

## Related Issue
None.

## Changes
- `docs/versions1.json` and `docs/project.json`: bump the preferred docs
version to `0.0.31` for daily release preparation after latest tag
`v0.0.30`.
- `docs/reference/commands.md`: document non-interactive Brave Search
validation fallback from #2511 / 9bfe30b, missing `--from <Dockerfile>`
path validation from #2597 / 7186834, and `logs` reading OpenShell
audit events from #2590 / e225dfb.
- `docs/inference/use-local-inference.md`: document local inference
reachability retry and host-side fallback from #2453 / 9dbe855, plus
compatible-endpoint timeout coverage from #2583 / b4ef3db.
- `docs/reference/troubleshooting.md`: document source-install shim
fallback from #2520 / 01a177c, TLS gateway trust recovery from #1936 /
24725d2, compatible-endpoint timeout coverage from #2583 / b4ef3db,
local reachability diagnostics from #2453 / 9dbe855, and host proxy
`NO_PROXY` injection from #2662 / b4df07e.

## Type of Change
- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [x] Doc only (includes code sample changes)

## Verification
- [ ] `npx prek run --all-files` passes
- [ ] `npm test` passes
- [ ] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [x] Docs updated for user-facing behavior changes
- [x] `make docs` builds without warnings (doc changes only)
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Additional verification:
- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user --dry-run` passed.
- `git diff --check` passed.
- Pre-push hooks passed through markdownlint, docs-to-skills, JSON
checks, gitleaks, and version sync before `Test (skills YAML)` failed
because this fresh worktree lacked `vitest/config`.
- `npx prek run --all-files` could not run from the fresh worktree
because `npx prek` resolved to a missing `prek@*` package; downloading
`@j178/prek` was not approved.
- `npm test` could not complete from the fresh worktree because
dependencies and compiled `dist/lib/*` artifacts were absent.

## AI Disclosure
- [x] AI-assisted — tool: OpenAI Codex

---
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
  * Version updated to 0.0.31
* Local inference onboarding now includes retry logic for container
reachability checks
  * Web search setup failure handling clarified with fallback guidance
  * Dockerfile path validation timing documented
  * Logging behavior clarified for concurrent stream reading
  * New TLS/certificate troubleshooting section added
  * Install path and proxy configuration troubleshooting updated

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
…him (NVIDIA#2520)

## Summary

A fresh `git clone` + `npm install` on a Linux host without a writable
global npm prefix reported success but left no `nemoclaw` command on
PATH — the `prepare` script's `npm link 2>/dev/null || true` swallowed
both stderr and the exit code. This surfaces the real npm error and
falls back to a user-local wrapper at `~/.local/bin/nemoclaw`.
`uninstall.sh` recognises the new shim shape so it cleans up later.

## Related Issue

Closes NVIDIA#2515

## Changes

- Add `scripts/npm-link-or-shim.sh`: hardened `set -eu` helper that runs
`npm link` and on failure writes a wrapper at `~/.local/bin/nemoclaw`.
Atomic write via tempfile + rename, marker-based refusal to overwrite
foreign files, idempotent refresh of NemoClaw-managed shims.
- `package.json`: `prepare` now invokes the helper instead of swallowing
errors inline.
- `uninstall.sh`: `is_installer_managed_nemoclaw_shim` recognises the
dev-shim shape so `remove_nemoclaw_cli` cleans it up.
- `test/npm-link-or-shim.test.ts` (new) + `test/uninstall.test.ts`:
regression coverage for six failure/success paths plus the uninstaller
cleanup.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Verification

- [x] `npx prek run --all-files` passes
- [x] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [ ] Docs updated for user-facing behavior changes
- [ ] `make docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

## AI Disclosure

- [x] AI-assisted — tool: Claude Code, Codex

---
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Enhanced CLI installation flow with a new helper that attempts linking
and falls back to creating a managed user-local shim for more reliable
setup.

* **Bug Fixes**
* Updated uninstall logic to recognize and remove the new managed shim
variant.

* **Tests**
* Added comprehensive tests covering install fallback, shim
creation/idempotence, overwrite protection, and uninstall behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
## Summary
Refreshes the daily docs from NemoClaw commits merged in the past 24
hours and advances the docs metadata from 0.0.29 to 0.0.31, the next
version after tag v0.0.30.
The updates cover documented behavior gaps found in the merged PRs
listed below.

## Related Issue
None.

## Changes
- `docs/versions1.json` and `docs/project.json`: bump the preferred docs
version to `0.0.31` for daily release preparation after latest tag
`v0.0.30`.
- `docs/reference/commands.md`: document non-interactive Brave Search
validation fallback from NVIDIA#2511 / 9bfe30b, missing `--from <Dockerfile>`
path validation from NVIDIA#2597 / 7186834, and `logs` reading OpenShell
audit events from NVIDIA#2590 / e225dfb.
- `docs/inference/use-local-inference.md`: document local inference
reachability retry and host-side fallback from NVIDIA#2453 / 9dbe855, plus
compatible-endpoint timeout coverage from NVIDIA#2583 / b4ef3db.
- `docs/reference/troubleshooting.md`: document source-install shim
fallback from NVIDIA#2520 / 01a177c, TLS gateway trust recovery from NVIDIA#1936 /
24725d2, compatible-endpoint timeout coverage from NVIDIA#2583 / b4ef3db,
local reachability diagnostics from NVIDIA#2453 / 9dbe855, and host proxy
`NO_PROXY` injection from NVIDIA#2662 / b4df07e.

## Type of Change
- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [x] Doc only (includes code sample changes)

## Verification
- [ ] `npx prek run --all-files` passes
- [ ] `npm test` passes
- [ ] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [x] Docs updated for user-facing behavior changes
- [x] `make docs` builds without warnings (doc changes only)
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Additional verification:
- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user --dry-run` passed.
- `git diff --check` passed.
- Pre-push hooks passed through markdownlint, docs-to-skills, JSON
checks, gitleaks, and version sync before `Test (skills YAML)` failed
because this fresh worktree lacked `vitest/config`.
- `npx prek run --all-files` could not run from the fresh worktree
because `npx prek` resolved to a missing `prek@*` package; downloading
`@j178/prek` was not approved.
- `npm test` could not complete from the fresh worktree because
dependencies and compiled `dist/lib/*` artifacts were absent.

## AI Disclosure
- [x] AI-assisted — tool: OpenAI Codex

---
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
  * Version updated to 0.0.31
* Local inference onboarding now includes retry logic for container
reachability checks
  * Web search setup failure handling clarified with fallback guidance
  * Dockerfile path validation timing documented
  * Logging behavior clarified for concurrent stream reading
  * New TLS/certificate troubleshooting section added
  * Install path and proxy configuration troubleshooting updated

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression chore Build, CI, dependency, or tooling maintenance and removed CI/CD bug Something fails against expected or documented behavior chore Build, CI, dependency, or tooling maintenance labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI workflows, checks, release automation, or GitHub Actions area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Linux][Install] Dev install: npm install silently succeeds when npm link fails — nemoclaw command not available afterwards

3 participants