Skip to content

refactor(cli): move dev shim install behind internal command - #3090

Merged
cv merged 100 commits into
mainfrom
refactor/npm-link-shim-internal
May 6, 2026
Merged

refactor(cli): move dev shim install behind internal command#3090
cv merged 100 commits into
mainfrom
refactor/npm-link-shim-internal

Conversation

@cv

@cv cv commented May 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Moves the npm link / user-local dev shim fallback out of scripts/npm-link-or-shim.sh and into a hidden oclif internal command. The shell script is now a small source-checkout wrapper while shim classification and writing are covered by TypeScript unit tests.

Changes

  • Add nemoclaw internal dev npm-link-or-shim for dev checkout CLI exposure.
  • Add typed dev shim domain helpers and an action-layer runner for npm link fallback behavior.
  • Reduce scripts/npm-link-or-shim.sh to node/compiled-CLI resolution and delegation.
  • Update npm-link shim tests to cover the wrapper path plus direct TypeScript behavior.

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)

Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added automatic fallback installation mechanism: if standard npm linking fails, the CLI installer now creates a local executable shim at ~/.local/bin/nemoclaw to ensure accessibility in restricted environments.
  • Tests

    • Added comprehensive test coverage for installation and dev-shim functionality.

cv added 30 commits May 2, 2026 13:36
@cv cv self-assigned this May 6, 2026
@coderabbitai

coderabbitai Bot commented May 6, 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: d24e9084-5dc1-4b39-bf28-c82f790c832b

📥 Commits

Reviewing files that changed from the base of the PR and between f729544 and ab60b4c.

📒 Files selected for processing (8)
  • scripts/npm-link-or-shim.sh
  • src/commands/internal/dev/npm-link-or-shim.ts
  • src/lib/actions/dev-shim.test.ts
  • src/lib/actions/dev-shim.ts
  • src/lib/domain/dev-shim.test.ts
  • src/lib/domain/dev-shim.ts
  • test/internal-cli.test.ts
  • test/npm-link-or-shim.test.ts

📝 Walkthrough

Walkthrough

This PR refactors npm-link-or-shim functionality by simplifying a shell script wrapper to delegate to a new internal oclif command, which in turn calls a TypeScript module that attempts npm link with a fallback to creating a user-local bash shim. Domain utilities support shim classification and content generation, with comprehensive test coverage across all layers.

Changes

npm-link-or-shim Refactoring

Layer / File(s) Summary
Domain Utilities
src/lib/domain/dev-shim.ts, src/lib/domain/dev-shim.test.ts
Introduces DEV_SHIM_MARKER, classifyDevShim() (categorizes shim content as absent/managed/foreign), buildDevShimContents() (generates bash shim with marker and exec invocation), and pathContainsDirectory() (checks directory presence in PATH).
Core Action
src/lib/actions/dev-shim.ts, src/lib/actions/dev-shim.test.ts
Implements runNpmLinkOrShim() function with dependency injection. Attempts npm link first; if it fails, creates a user-local shim at ~/.local/bin/nemoclaw. Handles environment guards (NEMOCLAW_INSTALLING), error logging, path validation, and node resolution. Tests cover recursion guards, success cases, shim creation, foreign shim protection, and error handling.
CLI Command
src/commands/internal/dev/npm-link-or-shim.ts
Adds oclif command InternalDevNpmLinkOrShimCommand that parses repo-root flag and delegates to runNpmLinkOrShim(), exiting with the result status. Includes metadata (summary, description, usage, examples).
Script Wrapper
scripts/npm-link-or-shim.sh
Simplifies shell wrapper from 69 to 16 lines. Removes complex shim creation and fallback logic; now validates Node availability, resolves paths, sets installation guard, and delegates directly to the internal dev command via Node.
Integration Tests
test/internal-cli.test.ts, test/npm-link-or-shim.test.ts
Adds oclif routing test for help text. Refactors npm-link-or-shim integration test to run the shell script from repo root with full environment context (NEMOCLAW_CLI_JS, NEMOCLAW_INSTALLING). Tests cover npm link success, fallback shim creation with marker and PATH export, no-op behavior during prepare recursion, and shim permission/creation errors.

Sequence Diagram

sequenceDiagram
    actor User
    participant Shell as scripts/npm-link-or-shim.sh
    participant Node as Node.js
    participant CLI as oclif CLI
    participant Action as runNpmLinkOrShim()
    participant npm as npm process
    participant Shim as ~/.local/bin/nemoclaw
    
    User->>Shell: Execute npm-link-or-shim.sh
    Shell->>Shell: Validate Node & paths
    Shell->>Shell: Set NEMOCLAW_INSTALLING guard
    Shell->>Node: Exec Node with CLI JS
    Node->>CLI: Load & route to internal dev command
    CLI->>Action: Call runNpmLinkOrShim(repoRoot)
    
    Action->>npm: Attempt npm link
    npm-->>Action: Success (status 0)
    Action-->>CLI: Return status 0
    
    alt npm link fails
        Action->>Action: Build shim contents (with marker & exec)
        Action->>Shim: Write shim to ~/.local/bin/nemoclaw
        Action->>Action: Validate PATH & permissions
        Action-->>CLI: Return status 0 or error
    end
    
    CLI->>Node: Exit with status
    Node->>User: Return exit code
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 The shell script now dances with the CLI,
npm link first, then a shim in ~/.local/bin,
No recursion—a guard keeps the prepare script grin,
Domain, action, and tests in perfect harmony,
Refactored with care, complexity pared down—hooray! 🎉

🚥 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 accurately and concisely describes the main change: refactoring the dev shim install logic by moving it from a shell script into a hidden internal oclif command.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 refactor/npm-link-shim-internal

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

@cv
cv marked this pull request as draft May 6, 2026 06:15
@copy-pr-bot

copy-pr-bot Bot commented May 6, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@cv cv added NemoClaw CLI refactor PR restructures code without intended behavior change labels May 6, 2026
@cv

cv commented May 6, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cv

cv commented May 6, 2026

Copy link
Copy Markdown
Collaborator Author

Automated PR review summary

Reviewed PR #3090: refactor(cli): move dev shim install behind internal command

Recommendation

  • Recommendation: PASS
  • Highest observed severity: low
  • Block merge: no
  • Why: The highest-risk downside of this refactor would be breaking developer checkout CLI exposure or overwriting user shims. In the reviewed environment, the wrapper successfully delegated into the new internal implementation, fallback shim creation remained functional under forced failure, and non-managed user shims were not clobbered.
  • Reviewer summary: Reviewed PR refactor(cli): move dev shim install behind internal command #3090 with PR-specific adversarial probes against the installed CLI and source-checkout wrapper. Forced npm-link failure still produced a working managed shim, existing foreign shims were preserved, and the new internal command was routable without becoming top-level public help surface.

Installation and setup findings

  • The repo installer path worked with local-source overrides: NemoClaw CLI installed, OpenShell was installed on demand, the gateway started, sandbox my-assistant was created, ssh into that NemoClaw-managed sandbox succeeded, and an in-sandbox OpenClaw query returned 4. The only issue was the original 600s installer command timing out near the end of policy preset application, so onboarding metadata remains marked in-progress even though the sandbox is functional.

What was validated

  • The PR revision was checked out in an isolated review environment.
  • The local checkout was installed using the repository installer flow as closely as the environment allowed.
  • Adversarial, PR-specific probes were then run against the installed environment and relevant repository context.
  • Diff summary:
 .../skills/nemoclaw-contributor-create-pr/SKILL.md |   20 +-
 .../nemoclaw-maintainer-pr-comparator/SKILL.md     |  121 --
 .../checks/tier-0-gates.md                         |   61 -
 .../checks/tier-1-correctness.md                   |   86 --
 .../checks/tier-2-quality.md                       |   64 -
 .../repo-policy.md                                 |   86 --
 .../scripts/check-coderabbit-threads.sh            |  105 --
 .../scripts/collect-gates.sh                       |   84 --
 .../scripts/find-candidates.sh                     |   86 --
 .../scripts/parse-supersession.sh                  |   68 --
 .../scripts/render-verdict.py                      |  232 ----
 .../templates/verdict.md                           |   88 --
 .../tiebreakers.md                                 |   61 -
 .../validation/backtest.md                         |   69 --
 .agents/skills/nemoclaw-skills-guide/SKILL.md      |    2 +-
 .../references/agent-skills.md                     |    4 +-
 .../nemoclaw-user-configure-inference/SKILL.md     |  329 ++---
 .../references/inference-options.md                |    4 +-
 .../references/set-up-sub-agent.md                 |  120 --
 .../references/swit
...[truncated]

Failing tests and unresolved impact

  • No failing adversarial tests were captured.

Passing tests and why they mattered

Passing test 1: Wrapper fallback still creates a working dev shim

  • What was tested: The refactored shell wrapper still delegates to the internal command and, when npm link fails, creates a working managed shim that preserves Node access.
  • Why it mattered: If false, source-checkout installs can lose CLI exposure for developers and the refactor would break the prepare/manual wrapper path.
  • Observed result: Forced npm failure produced ~/.local/bin/nemoclaw with managed marker, preserved /usr/bin in PATH, exec target /workspace/nemoclaw/bin/nemoclaw.js, and running the shim with --help returned 0.
  • Command: bash /tmp/pr3090-test1.sh
  • Recommended follow-up coverage: Yes—keep an integration/regression test covering the shell wrapper delegating to the compiled internal command under forced npm-link failure.

Passing test 2: Foreign user shim is not overwritten on fallback

  • What was tested: The new TypeScript fallback path preserves an existing non-managed ~/.local/bin/nemoclaw instead of overwriting it.
  • Why it mattered: If false, the refactor could clobber user-installed binaries or custom wrappers in a developer environment.
  • Observed result: Precreated foreign shim kept identical sha256 before/after execution; stderr reported the file was not managed by NemoClaw and was not overwritten.
  • Command: bash /tmp/pr3090-test2.sh
  • Recommended follow-up coverage: Yes—keep as a regression test because protecting foreign user shims is a high-value safety behavior.

Passing test 3: Internal command is routable but not exposed in top-level help

  • What was tested: nemoclaw internal dev npm-link-or-shim remains callable for wrapper delegation while staying hidden from ordinary top-level help output.
  • Why it mattered: If false, the wrapper could fail at runtime or the PR could unintentionally broaden the public CLI surface.
  • Observed result: Top-level help did not list npm-link-or-shim; direct internal help exited 0 and displayed the expected usage for the hidden command.
  • Command: bash /tmp/pr3090-test3.sh
  • Recommended follow-up coverage: Yes—retain a focused integration test to prevent broken internal routing or accidental exposure in the public help surface.

Bottom line

  • Based on the install evidence and adversarial probes, this PR looks reasonable to approve.

@cv
cv marked this pull request as ready for review May 6, 2026 19:52
@cv
cv changed the base branch from refactor/debug-shell-wrapper to main May 6, 2026 19:52
@cv
cv enabled auto-merge (squash) May 6, 2026 19:52
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv
cv requested a review from prekshivyas May 6, 2026 19:52

@prekshivyas prekshivyas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Clean shell→TS migration matching the pattern in #3083 (uninstall) and #3088 (debug). scripts/npm-link-or-shim.sh reduced from 87→33 lines; the bash shim builder, foreign-file classifier, mktemp atomic-rename, PATH lookup, and NEMOCLAW_INSTALLING recursion guard are all reproduced in runNpmLinkOrShim at src/lib/actions/dev-shim.ts:362. The shim format (DEV_SHIM_MARKER + bash header + export PATH=\"$NODE_DIR:$PATH\" + exec \"$BIN_PATH\" \"$@\") is byte-identical to the old script.

Verified the package.json prepare chain still satisfies the new dist/ dependency: npm run build:cli runs before bash scripts/npm-link-or-shim.sh, so dist/nemoclaw.js exists by the time the wrapper exec's the internal command.

Net test coverage grew, not shrunk:

  • test/npm-link-or-shim.test.ts: 6→3 cases at the wrapper integration level (kept fallback-on-fail, no-shim-on-success, NEMOCLAW_INSTALLING-recursion-guard)
  • src/lib/actions/dev-shim.test.ts adds back the foreign-overwrite-refusal, refresh-managed-shim, and broken-.local-dir cases at the unit level with injectable deps (6 cases)
  • src/lib/domain/dev-shim.test.ts adds pure-function tests for classifyDevShim / buildDevShimContents / pathContainsDirectory (3 cases)
  • test/internal-cli.test.ts adds the oclif routing assertion for internal dev npm-link-or-shim --help

Total: 9 new TS unit tests + 1 routing test in exchange for 3 removed bash-driven integration tests. Cleaner isolation, no regressions.

Tiny nit (non-blocking, deliberate): Old bash script could run npm link directly with only bin/nemoclaw.js present — useful if a dev manually invoked the script outside npm install. New wrapper requires dist/nemoclaw.js to exist first; if missing, logs Run npm run build:cli and retry. and exits 0. The npm prepare flow guarantees this, but standalone invocation now needs the build step. Acceptable contract change since the script header explicitly documents "invoked by npm install via package.json prepare".

CI: pr.yaml rollup checks pass (commit-lint, dco, layer-boundary, check-hash, CodeRabbit, changes). Self-hosted: 1 prior success on pull-request/3090. build-sandbox-images / macos-e2e / wsl-e2e / current self-hosted run still in progress at approval time.

@cv
cv merged commit f2d7b4c into main May 6, 2026
13 checks passed
@cv
cv deleted the refactor/npm-link-shim-internal branch May 27, 2026 21:17
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output and removed NemoClaw CLI labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output refactor PR restructures code without intended behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants