Skip to content

fix(install): add build:cli step and harden E2E destroy check#1277

Merged
cv merged 6 commits intomainfrom
fix/install-build-cli
Apr 1, 2026
Merged

fix(install): add build:cli step and harden E2E destroy check#1277
cv merged 6 commits intomainfrom
fix/install-build-cli

Conversation

@ericksoa
Copy link
Copy Markdown
Contributor

@ericksoa ericksoa commented Apr 1, 2026

Summary

  • install.sh missing build:cli: PR refactor(cli): extract pure functions from onboard.js to typed TypeScript modules #1240 replaced bin/lib/ CJS modules with shims that re-export from dist/lib/, but install.sh never ran npm run build:cli. Every fresh install crashed on nemoclaw onboard with Cannot find module '../../dist/lib/preflight'
  • E2E destroy verification: The cleanup phase used nemoclaw list to verify a sandbox was gone, but list triggers gateway recovery which can restart a destroyed gateway and re-import the sandbox. Now checks the registry file directly instead
  • Uses --if-present so installs targeting older tags without build:cli don't break

Test plan

  • Run install.sh on a clean VM and verify nemoclaw onboard no longer crashes
  • Verify dist/lib/preflight.js exists after install completes
  • Nightly E2E cloud-e2e passes the destroy verification phase

Summary by CodeRabbit

  • New Features
    • NemoClaw CLI modules are now built and compiled during the installation process, ensuring the command-line interface is fully prepared for immediate use.

PR #1240 replaced bin/lib/ CJS modules with thin shims that re-export
from dist/lib/, but install.sh was never updated to run `npm run
build:cli`. Every fresh install now crashes on `nemoclaw onboard` with
"Cannot find module '../../dist/lib/preflight'".

Add the missing build:cli step to both install paths (local source and
GitHub clone).

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added CLI module building step to NemoClaw installation process and updated E2E test verification methods to check the registry file directly instead of parsing nemoclaw list command output.

Changes

Cohort / File(s) Summary
Installation Build Step
install.sh, test/install-preflight.test.js
Added npm run --if-present build:cli spinner step to NemoClaw installation in both local and GitHub source paths. Updated npm stub in test to accept build:cli and --if-present arguments.
E2E Test Verification
test/e2e/test-full-e2e.sh, test/e2e/test-gpu-e2e.sh
Changed sandbox cleanup/destruction verification to read ${HOME}/.nemoclaw/sandboxes.json registry file directly instead of parsing nemoclaw list output. Updated failure messages to reference "in registry" state.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hops through build steps with pride,
CLI modules now compile inside!
Registry files speak the truth so plain,
No more list commands to entertain!
Tests that whisper what they find,
Faster, cleaner, and refined! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the two main changes: adding the build:cli step to the installer and hardening the E2E destroy verification check to read the registry file directly.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/install-build-cli

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

The install-preflight test npm stubs only matched `npm run build` but
not `npm run build:cli`, causing exit code 98 when install.sh invokes
the new CLI build step.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
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 `@install.sh`:
- Line 702: The installer calls npm run build:cli unconditionally via the spin
wrapper (e.g., spin "Building NemoClaw CLI modules" npm run build:cli), which
fails for refs where package.json lacks the build:cli script; modify install.sh
to check whether the script exists before running it: detect the npm script by
inspecting package.json (e.g., using jq or npm run | grep) in the current
NemoClaw checkout (respecting NEMOCLAW_INSTALL_TAG), and only invoke spin ...
npm run build:cli when the script is present; ensure you perform the same
guarded check for both occurrences referencing build:cli so installs on
tags/refs without that script don’t error out.
🪄 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: 3491cebd-4849-4236-8e0e-c97ea86e3ab6

📥 Commits

Reviewing files that changed from the base of the PR and between 2804b74 and 1d319ab.

📒 Files selected for processing (1)
  • install.sh

Installs targeting older tags via NEMOCLAW_INSTALL_TAG would fail if
the ref's package.json lacks the build:cli script. Using npm run
--if-present makes the step a no-op on those refs.

Update test npm stubs to accept the --if-present flag.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
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 `@install.sh`:
- Line 702: The install.sh usage of "npm run --if-present build:cli" should be
changed to either remove the "--if-present" so npm fails if the script is
missing, or add an explicit detection+fallback: check for the presence of the
"build:cli" npm script (e.g., by listing available scripts) and if absent run a
fallback like "build" or fail with a clear error; update both occurrences that
call npm run --if-present build:cli (the spin "Building NemoClaw CLI modules"
invocations) to use this explicit check/fallback so missing scripts do not
silently succeed.
🪄 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: b57c6161-4327-426f-acab-e7d14d9851f4

📥 Commits

Reviewing files that changed from the base of the PR and between 4d7f57f and 62cbbc0.

📒 Files selected for processing (2)
  • install.sh
  • test/install-preflight.test.js
✅ Files skipped from review due to trivial changes (1)
  • test/install-preflight.test.js

nemoclaw list called recoverRegistryEntries() which could restart a
destroyed gateway and re-import stale sandbox entries. This caused
the E2E destroy verification to fail: destroy removes the sandbox,
then list resurrects it by restarting the gateway and polling
openshell sandbox list.

list should just read the local registry. Recovery belongs in
commands that need a live gateway (connect, status).

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa changed the title fix(install): add build:cli step to compile TypeScript CLI modules fix(install,cli): add build:cli step and make list read-only Apr 1, 2026
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.

🧹 Nitpick comments (1)
test/cli.test.js (1)

646-646: Test may fail on systems without openshell installed.

Since the registry contains gamma, listSandboxes() will call captureOpenshell(["inference", "get"], ...) to query live inference. If openshell is not in PATH, getOpenshellBinary() calls process.exit(1), causing test failure.

Other tests (e.g., "prefers live inference model/provider over stale registry values" at line 1475) stub openshell for the same scenario. Consider adding a minimal stub here for test isolation.

♻️ Suggested stub addition
+    const localBin = path.join(home, "bin");
+    fs.mkdirSync(localBin, { recursive: true });
+    fs.writeFileSync(
+      path.join(localBin, "openshell"),
+      [
+        "#!/usr/bin/env bash",
+        'if [ "$1" = "inference" ] && [ "$2" = "get" ]; then',
+        "  exit 1",
+        "fi",
+        "exit 0",
+      ].join("\n"),
+      { mode: 0o755 },
+    );
+
-    const r = runWithEnv("list", { HOME: home });
+    const r = runWithEnv("list", { HOME: home, PATH: `${localBin}:${process.env.PATH || ""}` });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/cli.test.js` at line 646, The test calls runWithEnv("list", { HOME: home
}) which triggers listSandboxes() -> captureOpenshell(["inference","get"], ...)
and getOpenshellBinary() may call process.exit(1) if openshell is missing; add a
minimal openshell stub for this test by creating a tiny executable script (or
otherwise stubbing getOpenshellBinary/captureOpenshell) and prepending its
directory to PATH before invoking runWithEnv so the lookup succeeds and the test
no longer exits; reference the helpers runWithEnv, listSandboxes,
captureOpenshell, and getOpenshellBinary when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/cli.test.js`:
- Line 646: The test calls runWithEnv("list", { HOME: home }) which triggers
listSandboxes() -> captureOpenshell(["inference","get"], ...) and
getOpenshellBinary() may call process.exit(1) if openshell is missing; add a
minimal openshell stub for this test by creating a tiny executable script (or
otherwise stubbing getOpenshellBinary/captureOpenshell) and prepending its
directory to PATH before invoking runWithEnv so the lookup succeeds and the test
no longer exits; reference the helpers runWithEnv, listSandboxes,
captureOpenshell, and getOpenshellBinary when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 03aad817-5508-4868-82a0-dded37bf02cc

📥 Commits

Reviewing files that changed from the base of the PR and between 62cbbc0 and 86d638b.

📒 Files selected for processing (2)
  • bin/nemoclaw.js
  • test/cli.test.js

Revert the list-is-read-only change — the recovery behavior from #1187
is intentional and valuable after reboots.

The E2E destroy check used `nemoclaw list` which triggers gateway
recovery, potentially restarting a destroyed gateway and re-importing
stale sandbox entries. Check the registry file directly instead.

The list-recovery-after-destroy interaction is a real bug but belongs
in a separate PR.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa changed the title fix(install,cli): add build:cli step and make list read-only fix(install): add build:cli step and harden E2E destroy check Apr 1, 2026
@cv cv enabled auto-merge (squash) April 1, 2026 22:09
@cv cv merged commit 4aded30 into main Apr 1, 2026
4 checks passed
@cv cv deleted the fix/install-build-cli branch April 1, 2026 22:22
laitingsheng pushed a commit that referenced this pull request Apr 2, 2026
## Summary
- **install.sh missing build:cli**: PR #1240 replaced `bin/lib/` CJS
modules with shims that re-export from `dist/lib/`, but `install.sh`
never ran `npm run build:cli`. Every fresh install crashed on `nemoclaw
onboard` with `Cannot find module '../../dist/lib/preflight'`
- **E2E destroy verification**: The cleanup phase used `nemoclaw list`
to verify a sandbox was gone, but `list` triggers gateway recovery which
can restart a destroyed gateway and re-import the sandbox. Now checks
the registry file directly instead
- Uses `--if-present` so installs targeting older tags without
`build:cli` don't break

## Test plan
- [ ] Run `install.sh` on a clean VM and verify `nemoclaw onboard` no
longer crashes
- [ ] Verify `dist/lib/preflight.js` exists after install completes
- [ ] Nightly E2E cloud-e2e passes the destroy verification phase

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
lakamsani pushed a commit to lakamsani/NemoClaw that referenced this pull request Apr 4, 2026
…#1277)

## Summary
- **install.sh missing build:cli**: PR NVIDIA#1240 replaced `bin/lib/` CJS
modules with shims that re-export from `dist/lib/`, but `install.sh`
never ran `npm run build:cli`. Every fresh install crashed on `nemoclaw
onboard` with `Cannot find module '../../dist/lib/preflight'`
- **E2E destroy verification**: The cleanup phase used `nemoclaw list`
to verify a sandbox was gone, but `list` triggers gateway recovery which
can restart a destroyed gateway and re-import the sandbox. Now checks
the registry file directly instead
- Uses `--if-present` so installs targeting older tags without
`build:cli` don't break

## Test plan
- [ ] Run `install.sh` on a clean VM and verify `nemoclaw onboard` no
longer crashes
- [ ] Verify `dist/lib/preflight.js` exists after install completes
- [ ] Nightly E2E cloud-e2e passes the destroy verification phase

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
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