Skip to content

feat: install/uninstall DX sugar#470

Merged
ericksoa merged 8 commits intomainfrom
feat/nemoclaw-sugar
Mar 22, 2026
Merged

feat: install/uninstall DX sugar#470
ericksoa merged 8 commits intomainfrom
feat/nemoclaw-sugar

Conversation

@kjw3
Copy link
Contributor

@kjw3 kjw3 commented Mar 20, 2026

Summary

  • ANSI Shadow banner refresh: all-green NVIDIA-styled banner for install.sh and uninstall.sh with truecolor and 256-color fallbacks; NO_COLOR respected
  • Pure-bash braille spinner wrapping slow npm install, nvm install, and dependency steps with clean non-TTY fallback
  • Numbered step headers with dim dividers for clearer install/uninstall progress
  • Installer flags: --help, --version, and -v; expanded help now documents the useful non-interactive onboarding environment variables
  • Completion copy refresh: installer footer now derives the sandbox name and prints the next commands directly ($ nemoclaw <sandbox> connect, sandbox@<sandbox>$ openclaw tui)
  • Uninstaller UX: matching all-green banner/signoff and simplified resource wording (NemoClaw resources, NemoClaw providers)
  • Terminal contrast cleanup: removed hardcoded bright-white command text in favor of green prompts plus default terminal foreground for command text
  • withSpinner<T>() helper in onboard.ts for slow async validation steps
  • promptSelect updated with NVIDIA green default marker () and dimmed hints
  • Regression tests for --help, --version, -v, non-TTY spinner failure output, and interactive/non-interactive install paths

Install Header
image

Install Footer
image

Uninstall Header
image

Uninstall Footer
image

NO_COLOR=1
image

Test plan

  • node --test test/install-preflight.test.js — installer tests pass
  • node --test test/uninstall.test.js — uninstaller tests pass
  • node --test test/cli.test.js — help sections and dispatch tests pass
  • Manual: bash install.sh --help shows usage and environment variables and exits 0
  • Manual: bash uninstall.sh --help shows usage and exits 0
  • Manual: run installer in a TTY — banner/footer render cleanly on dark and light terminals
  • Manual: NO_COLOR=1 bash install.sh — no color codes in output

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added version information display capability
    • Interactive confirmation prompts for sandbox deletion with option to skip
  • Improvements

    • Enhanced terminal output with color styling and visual status indicators
    • Improved operation feedback with progress spinners and step indicators
    • Better SSH readiness messaging with incremental progress updates
    • Respects NO_COLOR environment variable for terminal styling preferences

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 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

Enhanced CLI and installer user experience across multiple scripts with ANSI color support gated by NO_COLOR and TTY detection, added progress indicators (spinners and step headers), implemented version flag handling, introduced async confirmation for destructive operations, and improved command output streaming with selective filtering and error handling.

Changes

Cohort / File(s) Summary
CLI Color & Version Enhancements
bin/nemoclaw.js
Added terminal color/style helpers (truecolor/256-color), colored status output with green checkmarks, updated SSH readiness messaging with incremental dot progress, introduced --version / -v flag with package version display, and extended help text with CLI version and revised guidance.
Async Destroy with Confirmation
bin/nemoclaw.js
Converted sandboxDestroy() to async function accepting optional args, implemented asynchronous user confirmation prompts when --yes or --force not provided, and updated dispatch to await the async operation with colored success output.
Installer Script UI Overhaul
install.sh
Added conditional ANSI color/style handling (NO_COLOR + TTY aware), implemented new UI helpers (step, print_banner, spin, ok), introduced version/help flag handling with --version/-v and --help/-h, wrapped Node.js and NemoClaw installation steps in spinners with output capture, and updated main() execution flow with numbered step framing and conditional onboarding.
Uninstaller Script UI Overhaul
uninstall.sh
Added conditional ANSI color/style variables for NVIDIA-themed coloring, replaced echo-based helpers with printf-based implementations, introduced spin, step, print_banner, and print_bye UI helpers, enhanced confirmation prompts with explicit removal categories, and reworked main() flow with banner and labeled step headers.
Onboarding Stream & Spawn Improvements
bin/lib/onboard.js
Added ANSI-colored console helpers (note() for dim output), introduced streamSandboxCreate() using child_process.spawn with incremental output filtering, updated installOpenshell() to use spawnSync with explicit error handling and output printing, and adjusted policy preset UI for interactive vs. non-interactive contexts.
Installation & Uninstallation CLI Tests
test/install-preflight.test.js, test/uninstall.test.js
Added shared test utilities for generating controlled fake node/npm binaries on temporary PATH, implemented comprehensive CLI flag validation (help, version), source-checkout scenario testing, non-TTY spinner failure modes, and uninstaller CLI integration tests with stub executables and environment mocking.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 Hopping through the CLI with colors so bright,
Spinners that twirl and progress that's right,
Async confirmations before the great purge,
Streamed sandbox creation—no more lurking dirge,
This bunny approves, the UX takes its flight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.63% 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 PR title 'feat: install/uninstall DX sugar' directly and clearly reflects the main focus of the changeset: improving the developer experience (DX) of the install and uninstall scripts with enhanced UI, banners, spinners, and flags.
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 feat/nemoclaw-sugar

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

@kjw3 kjw3 marked this pull request as ready for review March 20, 2026 04:42
Copy link

@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: 2

🧹 Nitpick comments (1)
uninstall.sh (1)

293-296: Minor: Silent success in spin() branch obscures intent.

The : # spin already printed ✓ comment explains the empty then-block, but a more explicit approach would improve readability.

🔧 Optional: Use `||` pattern instead of if-then-else
-    if spin "Removing nemoclaw npm package..." \
-        npm uninstall -g --loglevel=error nemoclaw; then
-      : # spin already printed ✓
-    else
+    spin "Removing nemoclaw npm package..." \
+        npm uninstall -g --loglevel=error nemoclaw || \
       warn "Global nemoclaw npm package not found or already removed"
-    fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uninstall.sh` around lines 293 - 296, The then-branch after the call to
spin(...) with npm uninstall -g --loglevel=error nemoclaw is currently empty
with a comment; update the branch to be explicit: either replace the
if-then-else with the recommended short-circuit pattern (spin "Removing..." npm
uninstall -g --loglevel=error nemoclaw || { handle failure; }) or keep the if
and add an explicit no-op/log statement (e.g., an explicit echo or a commentless
noop) inside the then branch so the intent around spin()’s success is clear;
refer to the spin(...) invocation and the npm uninstall -g --loglevel=error
nemoclaw command to locate and change the code.
🤖 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 32: Remove the unused color variable C_WHITE from the install.sh color
definitions: locate the assignment line that declares C_GREEN, C_CLAW, C_BOLD,
C_DIM, C_RED, C_YELLOW, C_CYAN, C_WHITE, C_RESET and remove C_WHITE from the
comma-separated/space-separated list so only used color variables remain (e.g.,
leave C_GREEN, C_CLAW, C_BOLD, C_DIM, C_RED, C_YELLOW, C_CYAN, C_RESET).

In `@nemoclaw/src/commands/onboard.ts`:
- Around line 154-161: The spinner color constant _spinGreen currently ignores
NO_COLOR; update its expression to also check process.env.NO_COLOR (treating any
set value as disabling color) so that when NO_COLOR is present the value is the
empty string instead of an escape code, and also apply the same NO_COLOR check
to the spinner reset code (the reset constant used after the checkmark, e.g.,
_spinReset) so no ANSI reset is emitted when colors are disabled; ensure both
symbols (_spinGreen and the reset constant) mirror the NO_COLOR handling used in
prompt.ts.

---

Nitpick comments:
In `@uninstall.sh`:
- Around line 293-296: The then-branch after the call to spin(...) with npm
uninstall -g --loglevel=error nemoclaw is currently empty with a comment; update
the branch to be explicit: either replace the if-then-else with the recommended
short-circuit pattern (spin "Removing..." npm uninstall -g --loglevel=error
nemoclaw || { handle failure; }) or keep the if and add an explicit no-op/log
statement (e.g., an explicit echo or a commentless noop) inside the then branch
so the intent around spin()’s success is clear; refer to the spin(...)
invocation and the npm uninstall -g --loglevel=error nemoclaw command to locate
and change the code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5b38311f-3079-4f0a-8a0d-cbc9fd332862

📥 Commits

Reviewing files that changed from the base of the PR and between dbfd78c and 4689ed0.

📒 Files selected for processing (7)
  • bin/nemoclaw.js
  • install.sh
  • nemoclaw/src/commands/onboard.ts
  • nemoclaw/src/onboard/prompt.ts
  • test/install-preflight.test.js
  • test/uninstall.test.js
  • uninstall.sh

Copy link

@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: 4

🤖 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`:
- Around line 53-58: The final banner printf in install.sh is missing the
trailing "╚══╝" block for the CLAW wordmark, causing the right edge to be
trimmed; update the last printf (the one using ${C_GREEN}${C_BOLD} ╚═╝ 
╚═══╝╚══════╝╚═╝     ╚═╝ ╚═════╝  ${C_RESET}${C_CLAW}${C_BOLD}╚═════╝╚══════╝╚═╝
╚═╝ ╚══╝╚══╝${C_RESET}) to include the additional "╚══╝" at the end (matching
uninstall.sh) so the CLAW segment prints fully, keeping the same color variables
(${C_CLAW}, ${C_GREEN}, ${C_BOLD}, ${C_RESET}) and formatting.
- Around line 117-125: The spin() function currently calls wait "$pid" directly
which, under set -e, can abort the script before the status is captured; change
both wait calls inside spin() so they are executed inside an if/else wrapper
that captures the exit code into the local variable status (e.g., run wait
"$pid" inside an if; in the then branch set status=0, in the else branch set
status=$?); then retain the existing success/failure printf, cat "$log" and rm
-f "$log" behavior so error logging and cleanup always run even when the
background job fails.
- Around line 252-256: The Node install runs in a child shell so the selected
Node version isn't active in the parent shell; after the existing spin call that
invokes nvm install 22 (the line that sources $NVM_DIR/nvm.sh and runs nvm
install 22), source nvm in the current shell (ensure_nvm_loaded or by sourcing
"$NVM_DIR/nvm.sh") and run nvm use 22 so the parent shell's PATH is updated;
update the script around the spin "Installing Node.js 22..." invocation to
source nvm and call nvm use 22 in the parent shell before running
ensure_supported_runtime or command_exists node.

In `@nemoclaw/src/commands/onboard.ts`:
- Around line 178-181: The error path in the onboard spinner handler is
hardcoding ANSI red escape sequences instead of using the same color constants
that respect NO_COLOR; define a new constant (e.g., _spinRed) alongside
_spinGreen/_spinReset and replace the hardcoded red sequence in the error
handler ((err: unknown) => { ... }) so the handler uses _spinRed and _spinReset
when writing the failure message and before throwing the error.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b1e22fbb-91f5-4bc2-acfc-23e1fd5337d3

📥 Commits

Reviewing files that changed from the base of the PR and between 4689ed0 and 60b5d40.

📒 Files selected for processing (2)
  • install.sh
  • nemoclaw/src/commands/onboard.ts

Copy link

@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: 2

🧹 Nitpick comments (1)
install.sh (1)

259-261: Reuse RECOMMENDED_NODE_MAJOR here.

A constant for the recommended major already exists, so hard-coding 22 again gives the installer two sources of truth for the Node target.

Suggested refactor
-  spin "Installing Node.js 22..." bash -c ". \"$NVM_DIR/nvm.sh\" && nvm install 22 --no-progress"
+  spin "Installing Node.js ${RECOMMENDED_NODE_MAJOR}..." \
+    bash -c ". \"$NVM_DIR/nvm.sh\" && nvm install ${RECOMMENDED_NODE_MAJOR} --no-progress"
   ensure_nvm_loaded
-  nvm use 22 --silent
+  nvm use "${RECOMMENDED_NODE_MAJOR}" --silent
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.sh` around lines 259 - 261, The installer hard-codes Node major
version "22" in the spin and nvm commands; change those to use the existing
RECOMMENDED_NODE_MAJOR constant instead. Update the calls around spin
"Installing Node.js 22..." and the subsequent nvm install and nvm use
invocations to interpolate or reference RECOMMENDED_NODE_MAJOR (and adjust the
human-facing message string to include it) so the script has a single source of
truth (refer to the spin invocation, ensure_nvm_loaded usage, and the nvm
install/use lines).
🤖 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`:
- Around line 452-457: The CLI flag parsing loop (for arg in "$@"; do ... case
"$arg" in) currently ignores unknown options; update the case in that loop to
add a default *) branch that prints an error including the invalid flag, calls
usage (or prints short help), and exits with a non-zero status so mistyped flags
like --noninteractive fail fast; ensure the branch references the same
variables/functions (e.g., NON_INTERACTIVE, usage) and does not allow unknown
flags to fall through.
- Around line 473-477: verify_nemoclaw may return success while warning that
PATH still needs updating, but the script then immediately calls run_onboard
which fails if the nemoclaw binary isn't actually runnable; modify the installer
flow so that after verify_nemoclaw (and before run_onboard) you explicitly check
that the nemoclaw executable is available and runnable (e.g., via command -v or
a small test invocation) and only call run_onboard when that check passes,
otherwise skip onboarding and surface the PATH/instruction warning (retain
post_install_message behavior).

---

Nitpick comments:
In `@install.sh`:
- Around line 259-261: The installer hard-codes Node major version "22" in the
spin and nvm commands; change those to use the existing RECOMMENDED_NODE_MAJOR
constant instead. Update the calls around spin "Installing Node.js 22..." and
the subsequent nvm install and nvm use invocations to interpolate or reference
RECOMMENDED_NODE_MAJOR (and adjust the human-facing message string to include
it) so the script has a single source of truth (refer to the spin invocation,
ensure_nvm_loaded usage, and the nvm install/use lines).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bf1da863-d310-4ca8-9c41-7792b34e5b89

📥 Commits

Reviewing files that changed from the base of the PR and between 60b5d40 and 0660a0f.

📒 Files selected for processing (2)
  • install.sh
  • nemoclaw/src/commands/onboard.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • nemoclaw/src/commands/onboard.ts

Copy link

@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.

♻️ Duplicate comments (1)
install.sh (1)

53-58: ⚠️ Potential issue | 🟡 Minor

The install banner is still missing the last block of CLAW.

Line 58's "W" character ends with ╚══╝╚══╝ (two legs), but the matching banner in uninstall.sh ends with ╚══╝╚══╝╚══╝ (three legs). This trims the right edge of the wordmark and creates visual inconsistency between the two scripts.

🖼️ Proposed fix
-  printf "  ${C_GREEN}${C_BOLD} ╚═╝  ╚═══╝╚══════╝╚═╝     ╚═╝ ╚═════╝  ${C_RESET}${C_CLAW}${C_BOLD}╚═════╝╚══════╝╚═╝  ╚═╝ ╚══╝╚══╝${C_RESET}\n"
+  printf "  ${C_GREEN}${C_BOLD} ╚═╝  ╚═══╝╚══════╝╚═╝     ╚═╝ ╚═════╝  ${C_RESET}${C_CLAW}${C_BOLD}╚═════╝╚══════╝╚═╝  ╚═╝ ╚══╝╚══╝╚══╝${C_RESET}\n"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.sh` around lines 53 - 58, The install script's ASCII banner is
missing the final "╚══╝" segment for the rightmost "CLAW" block; update the
final printf line in install.sh (the printf that currently ends with "╚══╝╚══╝")
to match the uninstall.sh banner by appending the missing "╚══╝" so the string
becomes "╚══╝╚══╝╚══╝", keeping all existing color variables (C_GREEN, C_BOLD,
C_RESET, C_CLAW) and escape sequences intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@install.sh`:
- Around line 53-58: The install script's ASCII banner is missing the final
"╚══╝" segment for the rightmost "CLAW" block; update the final printf line in
install.sh (the printf that currently ends with "╚══╝╚══╝") to match the
uninstall.sh banner by appending the missing "╚══╝" so the string becomes
"╚══╝╚══╝╚══╝", keeping all existing color variables (C_GREEN, C_BOLD, C_RESET,
C_CLAW) and escape sequences intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 182d6ac9-7d6f-41f2-b96f-05f67dbe91f3

📥 Commits

Reviewing files that changed from the base of the PR and between 0660a0f and 24a69b9.

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

@kjw3 kjw3 requested review from ericksoa and jacobtomlinson March 20, 2026 05:55
@wscurran wscurran added priority: high Important issue that should be resolved in the next release NemoClaw CLI Use this label to identify issues with the NemoClaw command-line interface (CLI). labels Mar 20, 2026
@kjw3 kjw3 marked this pull request as draft March 20, 2026 21:48
@kjw3
Copy link
Contributor Author

kjw3 commented Mar 20, 2026

Opinions so far. Single color green will update later

@kjw3 kjw3 force-pushed the feat/nemoclaw-sugar branch from 24a69b9 to c4c9076 Compare March 22, 2026 00:38
@kjw3 kjw3 marked this pull request as ready for review March 22, 2026 00:59
Copy link

@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 (2)
bin/lib/onboard.js (1)

89-144: Consider handling the error event on the spawned process.

If bash is missing or the spawn fails (e.g., ENOENT), the error event fires but the promise may never resolve or may resolve with an undefined status. Adding an error handler would make this more resilient.

💡 Proposed fix to handle spawn errors
   child.stdout.on("data", onChunk);
   child.stderr.on("data", onChunk);

   return new Promise((resolve) => {
+    child.on("error", (err) => {
+      lines.push(`spawn error: ${err.message}`);
+      resolve({ status: 1, output: lines.join("\n"), sawProgress });
+    });
     child.on("close", (code) => {
       if (pending) flushLine(pending);
       resolve({ status: code ?? 1, output: lines.join("\n"), sawProgress });
     });
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 89 - 144, streamSandboxCreate currently
never listens for the spawned process's "error" event so if spawn fails the
returned Promise can hang or return undefined status; add a child.on("error",
...) handler (near where child.stdout/onChunk and child.stderr are wired) that
flushes any pending via flushLine, pushes the error.message (and/or error.code)
into lines or sets a descriptive output, and resolves the Promise with a
non‑zero status and sawProgress=false (or otherwise rejects consistently) so
callers always get a deterministic result when spawn fails; reference
streamSandboxCreate, child, flushLine, onChunk and the Promise resolution in
your change.
test/uninstall.test.js (1)

28-55: LGTM! Well-structured isolation test.

The stub executable approach effectively isolates the uninstall script from real system state. The test validates both the --yes flag behavior and the expected output markers.

Consider cleaning up the temp directory after the test for tidiness, though this is not critical since Node's test runner and the OS will eventually clean /tmp:

💡 Optional cleanup
     const output = `${result.stdout}${result.stderr}`;
     assert.match(output, /NemoClaw/);
     assert.match(output, /Claws retracted/);
+
+    // Cleanup
+    fs.rmSync(tmp, { recursive: true, force: true });
   });
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/uninstall.test.js` around lines 28 - 55, Test creates a temp directory
in the "--yes skips the confirmation prompt and completes successfully" test
(variable tmp) but never removes it; add cleanup to remove tmp (and its fakeBin
contents) after the test completes — e.g., wrap the spawnSync/assertions in
try/finally or add a finally-like cleanup that calls fs.rmSync(tmp, { recursive:
true, force: true }) so the temporary directory is deleted; locate the test
block in test/uninstall.test.js referencing tmp, fakeBin, spawnSync and
UNINSTALL_SCRIPT and insert the cleanup there.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@bin/lib/onboard.js`:
- Around line 89-144: streamSandboxCreate currently never listens for the
spawned process's "error" event so if spawn fails the returned Promise can hang
or return undefined status; add a child.on("error", ...) handler (near where
child.stdout/onChunk and child.stderr are wired) that flushes any pending via
flushLine, pushes the error.message (and/or error.code) into lines or sets a
descriptive output, and resolves the Promise with a non‑zero status and
sawProgress=false (or otherwise rejects consistently) so callers always get a
deterministic result when spawn fails; reference streamSandboxCreate, child,
flushLine, onChunk and the Promise resolution in your change.

In `@test/uninstall.test.js`:
- Around line 28-55: Test creates a temp directory in the "--yes skips the
confirmation prompt and completes successfully" test (variable tmp) but never
removes it; add cleanup to remove tmp (and its fakeBin contents) after the test
completes — e.g., wrap the spawnSync/assertions in try/finally or add a
finally-like cleanup that calls fs.rmSync(tmp, { recursive: true, force: true })
so the temporary directory is deleted; locate the test block in
test/uninstall.test.js referencing tmp, fakeBin, spawnSync and UNINSTALL_SCRIPT
and insert the cleanup there.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ff49e0b1-08e9-4cc2-b86b-496b60c3b119

📥 Commits

Reviewing files that changed from the base of the PR and between 24a69b9 and 3598449.

📒 Files selected for processing (6)
  • bin/lib/onboard.js
  • bin/nemoclaw.js
  • install.sh
  • test/install-preflight.test.js
  • test/uninstall.test.js
  • uninstall.sh
✅ Files skipped from review due to trivial changes (1)
  • test/install-preflight.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • uninstall.sh
  • install.sh

@kjw3
Copy link
Contributor Author

kjw3 commented Mar 22, 2026

Rebased and polished on top of current main.

What changed in this pass:

  • kept the branch focused on installer / uninstaller / onboarding UX, without carrying old drift from main
  • updated installer and uninstaller branding to the final all-green treatment
  • made installer version output derive from package.json
  • added -v as a shortcut for install.sh --version
  • expanded install.sh --help with the useful non-interactive environment variables
  • cleaned up installer completion copy and footer commands
  • reduced npm/build noise behind spinner-based progress
  • switched sandbox image creation to filtered progress output instead of dumping the full raw build log
  • cleaned up non-interactive onboarding output so it is quieter but still explicit
  • added Next: labels to the final command blocks
  • made uninstall step 3/4 progress more consistent
  • fixed small robustness/test issues raised in review, including sandbox-create spawn failure handling and temp-dir cleanup in uninstall tests

Validation:

  • automated:
    • node --test test/install-preflight.test.js test/uninstall.test.js test/cli.test.js
    • node --test test/onboard.test.js
  • manual:
    • interactive ./install.sh
    • non-interactive ./install.sh --non-interactive
    • NO_COLOR=1 ./install.sh
    • ./uninstall.sh --yes
    • NO_COLOR=1 ./uninstall.sh --yes

Current state:

  • the branch is rebased on current main
  • the PR is intended to carry the visual / DX improvements only
  • install, uninstall, interactive, non-interactive, and NO_COLOR flows have all been rechecked after the rebasing/polish work

kjw3 and others added 8 commits March 21, 2026 21:55
- ANSI Shadow NEMOCLAW ASCII art banner (install + uninstall)
- Exact NVIDIA green #76B900 with truecolor detection; 256-color fallback
- Pure-bash braille spinner wrapping npm/nvm slow operations
- Numbered step headers [1/3], [2/3], [3/3] with dim dividers
- --help and --version flags for install.sh and uninstall.sh
- Bold green NemoClaw wordmark + elapsed timer at install completion
- GitHub and Docs links in completion message
- Motivational completion copy for new devs
- Same treatment on uninstall.sh: matching banner, "Claws retracted" signoff
- withSpinner<T>() helper in onboard.ts for slow validation steps
- Colorized promptSelect with NVIDIA green default marker and dimmed hints
- Regression tests for --help, --yes, non-TTY spinner, and interactive paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Split the ANSI Shadow NEMOCLAW header art so the NEMO half renders in
NVIDIA green (#76B900) and the CLAW half in OpenClaw red (#ff4d4d),
with proper 256-color fallbacks. Applies to both install.sh and
uninstall.sh banners, and to the NemoClaw wordmark in print_done() /
print_bye().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- onboard.ts: _spinGreen now emits "" when NO_COLOR is set (previously
  always emitted a 256-color code on TTYs); add _spinReset to replace
  the hardcoded \x1b[0m reset so no ANSI codes escape under NO_COLOR.
  Pattern mirrors prompt.ts.
- install.sh: remove unused C_WHITE variable (definition and no-color
  fallback assignment).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- install.sh spin(): replace `wait "$pid"; local status=$?` with an
  if/else block so set -e cannot abort the script before the exit code
  is captured when the background job fails.
- install.sh install_nodejs(): source nvm and run `nvm use 22 --silent`
  in the parent shell after the Node.js 22 spin so PATH is updated
  before `node --version` is called.
- onboard.ts: add _spinRed constant (NO_COLOR-aware, mirrors _spinGreen/
  _spinReset) and replace the hardcoded \x1b[1;31m/\x1b[0m in the
  spinner error path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Flag parsing: add *) catch-all that prints usage and errors on unknown
  options so mistyped flags like --noninteractive fail fast instead of
  silently falling through.
- main(): guard run_onboard behind command_exists nemoclaw so the
  onboarding step is skipped (with a clear warning) when nemoclaw is
  installed but not yet on PATH, rather than failing with a cryptic
  command-not-found error.
- install_nodejs(): replace hardcoded "22" in the spin message, nvm
  install, and nvm use calls with RECOMMENDED_NODE_MAJOR so there is a
  single source of truth for the target Node version.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kjw3 kjw3 force-pushed the feat/nemoclaw-sugar branch from b9afab7 to f5b3d23 Compare March 22, 2026 02:01
@ericksoa ericksoa merged commit 6f81a85 into main Mar 22, 2026
5 checks passed
@ericksoa
Copy link
Contributor

Super cool and needed, thanks @kjw3 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

NemoClaw CLI Use this label to identify issues with the NemoClaw command-line interface (CLI). priority: high Important issue that should be resolved in the next release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants