Skip to content

fix(install): keep nemoclaw available after install#1468

Merged
kjw3 merged 4 commits intomainfrom
fix/install-nemoclaw-command-path
Apr 4, 2026
Merged

fix(install): keep nemoclaw available after install#1468
kjw3 merged 4 commits intomainfrom
fix/install-nemoclaw-command-path

Conversation

@kjw3
Copy link
Copy Markdown
Contributor

@kjw3 kjw3 commented Apr 4, 2026

Summary

Fixes a CLI install regression where nemoclaw was reported as installed but the command was broken after install completed.

This changes the installer so:

  • user shells get a stable ~/.local/bin/nemoclaw wrapper
  • the wrapper prepends the resolved Node bin to PATH before execing the installed CLI
  • bootstrap curl | bash installs no longer npm link a temporary cloned checkout
  • bootstrap payload clones are treated as ephemeral, not as persistent source checkouts

Root Cause

There were two installer-side problems:

  1. The thin bootstrap install.sh cloned the selected ref into a temporary directory and then executed scripts/install.sh from that clone. The payload installer treated that temp clone as a source checkout and ran npm link, which created a global package symlink into the temp directory. Once the bootstrap temp directory was cleaned up, nemoclaw was broken.

  2. Even when the CLI binary existed, future shells could still fail to run it because the shebang relied on node being on PATH. On hosts using nvm, sourcing nvm.sh was not sufficient to guarantee that a Node version was active in later shells.

Related Issues

Related: #569, #989, #1429

Notes:

  • #569 is the closest installer/runtime-path issue.
  • #989 and #1429 track the developer-doc path that requires npm link.
  • This PR does not update docs, so it does not close #989 or #1429.

Related Prior Work

This overlaps with earlier installer investigation/work in:

Those PRs helped surface the same general npm/prefix/PATH fragility from adjacent angles.

What Changed

  • install.sh
    • marks bootstrap payload execution as ephemeral via NEMOCLAW_BOOTSTRAP_PAYLOAD=1
  • scripts/install.sh
    • adds a stable ~/.local/bin/nemoclaw wrapper
    • wrapper exports the resolved Node bin onto PATH and execs the installed nemoclaw
    • is_source_checkout() now rejects bootstrap payload clones
  • test/install-preflight.test.js
    • adds coverage for source checkout detection and bootstrap payload handling
    • updates shim expectations to match the wrapper behavior

Supported Paths

This PR fixes the fully supported installer paths:

  • curl | bash
  • repo checkout + ./install.sh

Developer repo usage remains:

  • git clone
  • npm install
  • npm link
  • nemoclaw onboard

Plain npm install alone is not treated as a supported CLI install path.

Validation

Local:

  • npm test -- test/install-preflight.test.js

Live:

  • brev-cpu kj-nemoclaw-cpu-test
    • repo checkout + ./install.sh --non-interactive
    • raw GitHub bootstrap installer equivalent to curl | bash
    • verified fresh-shell command -v nemoclaw and nemoclaw --version
  • spark spark-d8c8
    • reproduced broken pre-fix binary state
    • repo checkout + ./install.sh --non-interactive
    • verified fresh-shell command -v nemoclaw and nemoclaw --version

Notes

I only live-tested non-interactive installs on this branch. Interactive install behavior was not live-retested here.

Summary by CodeRabbit

  • Bug Fixes / Improvements

    • Improved installer reliability and shim creation so the CLI runs correctly even when Node is outside PATH.
    • Installer better distinguishes source checkouts vs non-persistent payload installs and emits clearer informational messages.
    • Uninstaller now recognizes and removes installer-generated wrapper shims while preserving unrelated user files.
  • Tests

    • Added and updated tests covering shim behavior, uninstall handling, and installation-type detection.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 772eb77a-1108-4c67-a615-31c3b2352358

📥 Commits

Reviewing files that changed from the base of the PR and between a90dbad and b1b7465.

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

📝 Walkthrough

Walkthrough

Installer now marks versioned payload runs with NEMOCLAW_BOOTSTRAP_PAYLOAD=1. The npm-installed nemoclaw shim is now a generated wrapper script that ensures Node is on PATH. Source-checkout detection and uninstall logic were added/adjusted; tests updated to validate the new behaviors.

Changes

Cohort / File(s) Summary
Payload Environment
install.sh
Set NEMOCLAW_BOOTSTRAP_PAYLOAD=1 when invoking the versioned installer payload; removed exporting NEMOCLAW_REPO_ROOT for that invocation.
Shim Generation & Source Detection
scripts/install.sh, uninstall.sh
ensure_nemoclaw_shim now creates an executable wrapper that prepends Node's dir to PATH and execs the CLI instead of a symlink; added is_source_checkout(repo_root) detection (considers .git, NEMOCLAW_REPO_ROOT, and NEMOCLAW_BOOTSTRAP_PAYLOAD); added is_installer_managed_nemoclaw_shim() and updated uninstall removal logic to handle wrapper shims.
Tests
test/install-preflight.test.js, test/uninstall.test.js
Updated shim test to inspect wrapper contents; added three is_source_checkout unit tests; adjusted fixtures to include .git and dynamic repo_root; added uninstall tests for wrapper shim removal and preservation when user content present.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through scripts and paths so wide,
I wrapped Node's road where binaries hide.
A bootstrap flag, a shim that sings,
I nudge the PATH and pull the strings.
Now the CLI bounds — joy in my hops!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% 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 clearly and concisely describes the main change: fixing the issue where nemoclaw command was unavailable after installation.
Linked Issues check ✅ Passed The PR addresses issue #989 by implementing installer-managed wrapper shims and detecting source checkouts to preserve npm link functionality for developers.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the install regression and preserving CLI availability through wrapper shims and source-checkout detection.

✏️ 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/install-nemoclaw-command-path

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

@kjw3 kjw3 marked this pull request as ready for review April 4, 2026 03:26
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/install.sh (1)

455-486: ⚠️ Potential issue | 🟠 Major

Update uninstall.sh to handle script-based shims.

The shim is now created as an executable script (lines 479-486), but uninstall.sh only removes symlinks (line 341: [ -L ... ]). Regular files matching the shim name trigger the warning "Leaving ... in place because it is not an installer-managed shim." (line 344) instead of being removed, leaving installer-created shims behind after uninstallation.

Add logic to detect and remove script-based shims, for example by checking for the #!/usr/bin/env bash marker or another identifier that distinguishes installer-managed shims from user-created files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install.sh` around lines 455 - 486, The uninstall script currently
only removes symlink shims and leaves installer-created script shims behind;
update uninstall.sh to detect and remove regular files created by
ensure_nemoclaw_shim by checking for the installer marker (e.g. the shebang
"#!/usr/bin/env bash" or the expected exec line that the shim writes) inside
"$NEMOCLAW_SHIM_DIR/nemoclaw" (or the same path used by ensure_nemoclaw_shim) —
ensure you only remove the file when it is a regular file and its contents match
the installer-created shim pattern, otherwise keep the existing behavior of
leaving user-created files and emitting the same warning.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@scripts/install.sh`:
- Around line 455-486: The uninstall script currently only removes symlink shims
and leaves installer-created script shims behind; update uninstall.sh to detect
and remove regular files created by ensure_nemoclaw_shim by checking for the
installer marker (e.g. the shebang "#!/usr/bin/env bash" or the expected exec
line that the shim writes) inside "$NEMOCLAW_SHIM_DIR/nemoclaw" (or the same
path used by ensure_nemoclaw_shim) — ensure you only remove the file when it is
a regular file and its contents match the installer-created shim pattern,
otherwise keep the existing behavior of leaving user-created files and emitting
the same warning.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2959ebde-d097-4a5c-a8bc-c557241937e5

📥 Commits

Reviewing files that changed from the base of the PR and between 3f4d6fe and b309aa0.

📒 Files selected for processing (3)
  • install.sh
  • scripts/install.sh
  • test/install-preflight.test.js

@kjw3
Copy link
Copy Markdown
Contributor Author

kjw3 commented Apr 4, 2026

Addressing Coderabbit review

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@uninstall.sh`:
- Around line 329-345: The is_installer_managed_nemoclaw_shim function currently
allows extra content before/after the three expected lines, causing false
positives; tighten the matcher so the file must consist exactly of the
three-line structure by anchoring the pattern to the whole contents (remove the
leading/trailing wildcards and only allow the intended intraline wildcards),
e.g. change the case pattern in is_installer_managed_nemoclaw_shim to match
'^#!/usr/bin/env
bash\n'"$path_line"*"$path_suffix"'\n'"$exec_line"*"$exec_suffix"'$' (i.e. no
extra '*' before/after) so only exact three-line installer-generated shims are
detected and user wrappers are preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e83e39a7-526e-45b0-8a28-b5ac8021f832

📥 Commits

Reviewing files that changed from the base of the PR and between b309aa0 and a90dbad.

📒 Files selected for processing (2)
  • test/uninstall.test.js
  • uninstall.sh

@kjw3 kjw3 merged commit 3328359 into main Apr 4, 2026
10 checks passed
@kjw3 kjw3 deleted the fix/install-nemoclaw-command-path branch April 4, 2026 04:11
ericksoa pushed a commit that referenced this pull request Apr 4, 2026
…ty (#1470)

## Summary
- unify installer and onboarding host detection around shared TypeScript
preflight logic
- move `deploy` behavior into TypeScript, thin the Brev compatibility
wrapper, and harden Brev readiness handling
- demote or remove legacy platform-specific setup paths (`setup-spark`,
`brev-setup.sh`) in favor of the canonical installer + onboard flow
- update docs, CLI help, and Brev E2E coverage to match the new behavior

## What Changed
- added shared host assessment and remediation planning in
`src/lib/preflight.ts`
- wired installer and onboard flows to the same host preflight decisions
- changed Podman handling from hard block to unsupported-runtime warning
- migrated deploy logic into `src/lib/deploy.ts`
- updated `nemoclaw deploy` to use the authenticated Brev CLI, current
Brev create flags, explicit GCP provider default, stricter readiness
checks, and standard installer/onboard flow
- removed `scripts/setup-spark.sh` and reduced `scripts/brev-setup.sh`
to a deprecated compatibility wrapper
- updated README/docs/help text and hardened the Brev E2E cleanup path

## Validation
- `npm run build:cli`
- targeted Vitest coverage for `src/lib/preflight.test.ts`,
`src/lib/deploy.test.ts`, `test/install-preflight.test.js`,
`test/cli.test.js`, `test/runner.test.js`
- live Brev validation with `TEST_SUITE=deploy-cli` on
`cpu-e2.4vcpu-16gb`
- confirmed successful end-to-end remote deploy after waiting for Brev
`status=RUNNING`, `build_status=COMPLETED`, `shell_status=READY`

## Related Issues
- Fixes #1377
- Addresses #1330
- Addresses #1390
- Related to #1404

## Credit / Prior Work
This branch builds on ideas and prior work from:
- #1368 by @zyang-dev for simplifying Spark setup and removing the old
cgroup workaround
- #1395 and #1468 by @kjw3 for the thin installer/bootstrap direction
and installer path reliability
- #1450 by @cjagwani for switching Brev flows toward GCP for reliability
- #1383 by @13ernkastel for the current Brev create flag compatibility
work
- #1364 by @WuKongAI-CMU for deploy sync-path fixes
- #1362 and #1266 by @jyaunches for the Brev E2E/launchable
infrastructure direction
- issue ideas from #1377 and #1404 by @zNeill, #1330 by @Marcelo5444,
and #1390 by @ericksoa


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

* **New Features**
* Improved host diagnostics with actionable remediation guidance
surfaced during installer/onboard preflight.

* **Improvements**
* macOS (Intel) now recommends Docker Desktop; DGX Spark guidance now
uses the standard installer + `nemoclaw onboard`.
* Preflight output shows detected runtime and WSL notes; installer
prints remediation actions and will skip onboarding on blocking issues.

* **Deprecations**
* `nemoclaw deploy`, `nemoclaw setup-spark`, and the legacy bootstrap
wrapper are now deprecated compatibility paths.

* **Documentation**
* Quickstart, troubleshooting, and command reference updated to reflect
installer+onboard flow and deprecation guidance.

* **Tests**
* Added/updated tests covering preflight, deploy compatibility, CLI
aliases, and deploy e2e scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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