Skip to content

fix(installer): resolve the CLI through the user-local shim - #8452

Merged
prekshivyas merged 3 commits into
mainfrom
codex/salvage-8440-user-shim-ready
Aug 6, 2026
Merged

fix(installer): resolve the CLI through the user-local shim#8452
prekshivyas merged 3 commits into
mainfrom
codex/salvage-8440-user-shim-ready

Conversation

@cv

@cv cv commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes installer verification when npm prefix changes leave NemoClaw available only through the user-local shim. The installer now probes the shim after the npm-prefix checks and records whether the calling shell needs a PATH refresh.

This replacement preserves Dongni Yang's original commit from #8440 and adds the missing regression coverage.

Related Issue

Closes #8311

Changes

  • Probe the user-local shim when the active npm prefix does not expose the CLI.
  • Re-check command resolution before recording readiness so a rejected binary that shadows the shim keeps the PATH-refresh guidance.
  • Cover stale-prefix, shadowing, shim-on-PATH, npm-uninstall, and missing-shim 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)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: docs/reference/troubleshooting.mdx already explains how to source the shell profile and add ~/.local/bin to PATH. The removed installer failure was not documented.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: An independent review passed all nine security categories for PR commit d2b1ea5139076b45bf366dcec04a3a75dd8cf49e against base SHA 2f297843b8fddad80b046eaf34f2987bdd922711. The existing shim trust boundary does not change.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: No waiver is recorded.

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: Reviewed scripts/install.sh, test/install-npm-resolution.test.ts, and the existing user-local shim recovery in docs/reference/troubleshooting.mdx for PR commit d2b1ea5139076b45bf366dcec04a3a75dd8cf49e against base SHA 2f297843b8fddad80b046eaf34f2987bdd922711. The change removes an undocumented failure and retains the documented recovery action. The review covered repository terminology, test titles, comments, security wording, and documentation ownership; no documentation or code sample changed.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit: Not applicable; scripts/prepare-dgx-station-host.sh does not change.
  • Station profile/scenario: Not applicable.
  • Result: Not applicable.
  • Supporting evidence: Not applicable.

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub — both contributor commits and the current-main refresh commit are GitHub Verified.
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable — normal hooks passed for the contributor fix, remediation, and current-main refresh.
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — GitHub Actions is authoritative; no standalone local test suite ran for the reviewed replacement commit.
  • Applicable broad gate passed — GitHub Actions has not completed for the replacement PR.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only) — not applicable; no documentation changes.
  • Doc pages follow the style guide (doc changes only) — not applicable; no documentation changes.
  • New doc pages include SPDX header and frontmatter (new pages only) — not applicable; no new page.

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

Summary by CodeRabbit

  • Bug Fixes

    • Improved CLI detection when the active npm installation path does not contain the command.
    • Added support for valid user-local CLI shims.
    • Provides clearer onboarding guidance when PATH needs refreshing.
    • Correctly resolves valid shims and removes conflicting invalid command entries.
    • Reports a clear failure when no usable CLI installation is found.
  • Tests

    • Added coverage for local shim discovery, PATH handling, conflicting binaries, and missing installations.

Dongni-Yang and others added 3 commits August 6, 2026 11:10
verify_nemoclaw only reached the user-local shim check from inside the
npm-prefix branch, so a host whose active npm prefix differs from the one
the CLI was installed under -- a Homebrew npm shadowing the installer's
nvm npm -- fell through to "binary not found" and exited 1 while the shim
the installer had just created was working. The diagnostic even printed
the shim path, implying it had been searched when it never was.

Probe the shim directly after the npm-prefix branch. Resolution state
comes from record_cli_resolution_state so the recovery export directory
stays consistent with the sibling stale-PATH branch, then the branch
re-checks what the name actually resolves to: the shim itself means the
shell is ready, while a rejected binary still shadowing it keeps the
PATH-refresh hint that record_cli_resolution_state would otherwise clear
once the shim directory is on PATH. Without that re-check print_done()
reports a clean install for a shell where the CLI name still runs the
binary this function just refused.

This clears the spurious exit 1 whenever a working shim exists. It does
not explain why the PATH lookup failed on the reporter's host given that
ensure_cli_shim calls refresh_path immediately after writing the shim;
that remains open and is not reproducible without the macOS host.

Refs #8311

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv added the v0.0.104 label Aug 6, 2026
@cv cv self-assigned this Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The installer now checks the user-local nemoclaw shim when the active npm prefix lacks the CLI. It validates the shim, handles PATH readiness and refresh messaging, and continues onboarding through its absolute path. Tests cover fallback, shadowing binaries, recovery, and failure.

Changes

CLI shim verification

Layer / File(s) Summary
User-local shim fallback
scripts/install.sh
verify_nemoclaw validates the user-local shim, records its path, determines readiness from PATH, and supports onboarding through the shim.
Shim resolution test coverage
test/install-npm-resolution.test.ts
Tests simulate stale npm-prefix environments and cover shim fallback, PATH refresh hints, shadowing-binary removal, successful resolution, and missing-CLI failure.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#8440: Implements the same user-local shim fallback and overlapping installer-resolution tests.

Suggested labels: area: install, bug-fix

Suggested reviewers: brandonpelfrey, dnandakumar-nv

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: resolving the CLI through the user-local shim during installation.
Linked Issues check ✅ Passed The installer independently checks the user-local shim and handles PATH refresh and shadowing cases required by issue #8311.
Out of Scope Changes check ✅ Passed The changes are limited to shim resolution in the installer and regression tests for the linked issue.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/salvage-8440-user-shim-ready

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

@github-code-quality

github-code-quality Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit d2b1ea5 in the codex/salvage-8440-u... branch remains at 96%, unchanged from commit 2f29784 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit d2b1ea5 in the codex/salvage-8440-u... branch remains at 82%, unchanged from commit 2f29784 in the main branch.

Show a code coverage summary of the most impacted files.
File main 2f29784 codex/salvage-8440-u... d2b1ea5 +/-
src/lib/onboard...shboard-port.ts 96% 90% -6%
src/lib/inferen...y-production.ts 48% 48% 0%
src/lib/core/immutable.ts 97% 97% 0%
src/lib/messagi...flow-planner.ts 93% 93% 0%
src/lib/sandbox...rce-identity.ts 87% 87% 0%
src/lib/actions...air-approval.ts 89% 90% +1%
src/lib/inferen...er-discovery.ts 87% 88% +1%

Updated August 06, 2026 07:19 UTC

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/install-npm-resolution.test.ts (1)

429-429: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use the repository POSIX PATH separator.

Replace path.delimiter with ":" in these test PATH values. These tests run on POSIX environments in CI. This keeps the new cases consistent with the established test convention.

Based on learnings: “prefer the established POSIX PATH separator : when constructing process.env.PATH in tests” and “Do not replace it with path.delimiter.”

Also applies to: 444-444, 467-467

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/install-npm-resolution.test.ts` at line 429, Update the PATH
constructions in the affected test cases to use the POSIX separator ":" instead
of path.delimiter, including the entries around tree.fakeBin, tree.shimPath, and
TEST_SYSTEM_PATH. Keep the existing PATH component order and test behavior
unchanged.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/install-npm-resolution.test.ts`:
- Line 429: Update the PATH constructions in the affected test cases to use the
POSIX separator ":" instead of path.delimiter, including the entries around
tree.fakeBin, tree.shimPath, and TEST_SYSTEM_PATH. Keep the existing PATH
component order and test behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ae68882d-a3e8-4868-ab15-200550484679

📥 Commits

Reviewing files that changed from the base of the PR and between 2f29784 and d2b1ea5.

📒 Files selected for processing (2)
  • scripts/install.sh
  • test/install-npm-resolution.test.ts

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · medium confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized terminology decisions differ; normalized E2E selections differ; severity counts match.
3 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • bootstrap-install-smoke: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • spark-install: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • double-onboard: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

3 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — user-local shim at scripts/install.sh:2245: Keep `user-local shim`; existing installer, contributor, and test text uses the same meaning.
  • justified — active npm prefix at scripts/install.sh:2244: Keep `active npm prefix`; the modifier identifies the stale-prefix case that controls fallback behavior.
  • established — PATH-refresh at test/install-npm-resolution.test.ts:419: Keep `PATH-refresh`; it uses the established PATH-refresh concept for the emitted guidance.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-onboard, managed-image-multiarch-startup

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@prekshivyas
prekshivyas merged commit 130f4de into main Aug 6, 2026
88 of 89 checks passed
@prekshivyas
prekshivyas deleted the codex/salvage-8440-user-shim-ready branch August 6, 2026 18:20
@cjagwani cjagwani mentioned this pull request Aug 7, 2026
23 tasks
cjagwani added a commit that referenced this pull request Aug 7, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Adds the canonical dated changelog entry required before cutting
`v0.0.104`.
The entry reconciles user-facing changes merged from `v0.0.103` through
`8d2b86aaf44968b4f7bc3b714222a73bd28e0403` while excluding hidden and
experimental product surfaces.

## Changes

- Added `docs/changelog/2026-08-06.mdx` with the exact `## v0.0.104`
heading and release themes for local inference, private endpoints,
network policy, state authority, lifecycle recovery, uninstall, Hermes,
MCP diagnostics, credential safety, and installation guidance.
- Source summary links:
- [#8399](#8399) ->
`docs/changelog/2026-08-06.mdx`: fixed DGX Spark local serving profiles.
- [#8418](#8418) ->
`docs/changelog/2026-08-06.mdx`: durable llama.cpp lifecycle management.
- [#8422](#8422) ->
`docs/changelog/2026-08-06.mdx`: recoverable llama.cpp receipt
publication.
- [#8402](#8402) ->
`docs/changelog/2026-08-06.mdx`: remediable DGX Spark storage admission.
- [#8391](#8391) ->
`docs/changelog/2026-08-06.mdx`: host-local serving recipe contracts.
- [#8401](#8401) ->
`docs/changelog/2026-08-06.mdx`: serving profile lifecycle provenance.
- [#8322](#8322) ->
`docs/changelog/2026-08-06.mdx`: guarded llama.cpp route compatibility.
- [#8272](#8272) ->
`docs/changelog/2026-08-06.mdx`: explicitly trusted private endpoints
with stable policy pins and CA trust.
- [#8431](#8431) ->
`docs/changelog/2026-08-06.mdx`: Personal onboarding policy tier and its
trust boundary.
- [#8143](#8143) ->
`docs/changelog/2026-08-06.mdx`: manifest-derived state authority.
- [#7859](#7859) ->
`docs/changelog/2026-08-06.mdx`: side-effect-free lifecycle lock
timeouts.
- [#8262](#8262) ->
`docs/changelog/2026-08-06.mdx`: managed gateway lease waiting.
- [#8339](#8339) ->
`docs/changelog/2026-08-06.mdx`: continued journaled rebuild recreation.
- [#8373](#8373) ->
`docs/changelog/2026-08-06.mdx`: restore readiness after compatibility
decisions.
- [#8443](#8443) ->
`docs/changelog/2026-08-06.mdx`: fail-closed malformed registry
handling.
- [#8419](#8419) ->
`docs/changelog/2026-08-06.mdx`: bounded recovery for a gateway that
never served.
- [#8486](#8486) ->
`docs/changelog/2026-08-06.mdx`: target-scoped registry recovery.
- [#8259](#8259) ->
`docs/changelog/2026-08-06.mdx`: scoped uninstall ordering and retry
safety.
- [#8457](#8457) ->
`docs/changelog/2026-08-06.mdx`: desktop metadata exclusion during
uninstall.
- [#8026](#8026) ->
`docs/changelog/2026-08-06.mdx`: typed Hermes configuration policy.
- [#8242](#8242) ->
`docs/changelog/2026-08-06.mdx`: Hermes WhatsApp session diagnostics.
- [#8344](#8344) ->
`docs/changelog/2026-08-06.mdx`: patched Hermes image and dependency
checks.
- [#8491](#8491) ->
`docs/changelog/2026-08-06.mdx`: bounded MCP discovery timeout.
- [#8490](#8490) ->
`docs/changelog/2026-08-06.mdx`: MCP shadow diagnostics.
- [#7619](#7619) ->
`docs/changelog/2026-08-06.mdx`: web-search credential isolation.
- [#8476](#8476) ->
`docs/changelog/2026-08-06.mdx`: stable preflight advisory identifiers.
- [#8452](#8452) ->
`docs/changelog/2026-08-06.mdx`: user-local CLI resolution.
- [#8481](#8481) ->
`docs/changelog/2026-08-06.mdx`: remote network-policy terminal
guidance.
- Product-scope exclusions:
[#8429](#8429) remains
experimental; [#8261](#8261)
remains feature-gated; and portable-profile changes
[#8408](#8408),
[#8415](#8415),
[#8446](#8446),
[#8458](#8458),
[#8462](#8462), and
[#8506](#8506) are not promoted
as supported product surfaces.

## Type of Change

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

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [x] Existing tests cover changed behavior — justification: `npx vitest
run test/changelog-docs.test.ts` passed 6/6 and validates dated
changelog structure and published links.
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: `docs/changelog/2026-08-06.mdx`; release-range scope,
writing rules, documentation style, skip terms, exact names,
threat-boundary wording, and published routes reviewed; changelog tests
and docs build passed.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 02b51ae -->
<!-- docs-review-agents-blob-sha: c69aad4 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable; no DGX Station host preparation script
changed.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: `npx
vitest run test/changelog-docs.test.ts` passed 6/6.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Not applicable to a single
changelog entry.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [x] `npm run 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)

The new dated changelog file includes the required parser-safe SPDX
header and intentionally has no frontmatter, matching the changelog
contract and existing entries.

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
  * Added release notes for v0.0.104.
* Documented fixes for local model runtimes, private endpoints, network
policies, state recovery, uninstall behavior, safety updates, MCP
diagnostics, credential isolation, and installation guidance.

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

[macOS][Install] fresh install exits 1 "nemoclaw binary not found" although the CLI shim is installed and works

3 participants