Skip to content

feat: self-update, reconnect, model catalogue, build toolchain, docs fixes (#642, #716, #733, #724, #747) - #788

Closed
cluster2600 wants to merge 31 commits into
NVIDIA:mainfrom
cluster2600:feat/10-features-and-fixes
Closed

feat: self-update, reconnect, model catalogue, build toolchain, docs fixes (#642, #716, #733, #724, #747)#788
cluster2600 wants to merge 31 commits into
NVIDIA:mainfrom
cluster2600:feat/10-features-and-fixes

Conversation

@cluster2600

Copy link
Copy Markdown
Contributor

Summary

graph TD
    subgraph "nemoclaw update"
        A[detectInstallType] -->|source| B[git fetch+reset+link]
        A -->|global| C[npm install -g]
    end
    subgraph "nemoclaw reconnect"
        D[checkGateway] -->|unhealthy| E[restart]
        E --> F[checkSandbox]
        F -->|unhealthy| G[repairCoreDns + ports]
    end
    subgraph "Model catalogue"
        H[activeModelEntries] --> I[6 models incl. kimi-k2.5, qwen3.5]
    end
Loading
  • Self-update: nemoclaw update [--check] via git or npm
  • Reconnect: nemoclaw reconnect [sandbox] [--diagnose]
  • Model catalogue: full 6-model list, custom model prepended
  • Build toolchain: build-essential + python3-dev for aarch64 native addons
  • Build-arg injection: input validation for Dockerfile parameters
  • Docs: fixed broken links, setup-spark messaging
  • 82 new tests

Closes #642, #716, #733, #724, #747, #738.

Test plan

  • All tests passing
  • Verify self-update and reconnect commands

- uninstall.sh: check parent directory writability instead of file
  writability when deciding whether sudo is needed for removal. The
  previous check followed symlinks, so a symlink to a user-writable
  target in a root-owned directory would attempt unprivileged rm and
  fail with EACCES.

- scripts/install.sh: replace NODE_MGR-based sudo heuristic with a
  direct writability check on the npm global prefix. The old approach
  always used sudo for nodesource installs, which changes PATH and
  breaks environments where the prefix is already user-writable.
…in process args (NVIDIA#579, NVIDIA#664)

Add redactSecrets() to runner.js with patterns matching env assignments,
nvapi- prefixes, GitHub PATs, and Bearer tokens. Apply to error messages
in run() and runInteractive() so failed commands never leak credentials.

Fix setupSpark() to pass NVIDIA_API_KEY via env option instead of
interpolating into the command string (visible in ps aux).

Fix walkthrough.sh to use tmux -e for env propagation instead of
embedding the key in the shell command. Fix telegram-bridge.js to use
SSH SendEnv instead of command-line export.

9 new tests covering redaction patterns and regression guards.
…VIDIA#693)

RFC1918 addresses were blocked by the egress proxy because no policy
entry existed for host.openshell.internal. Add a local-inference preset
that whitelists ports 11434 (Ollama) and 8000 (vLLM) with binary
restrictions, and auto-suggest it during onboard when a local inference
provider is selected.
Policy presets without a binaries section cause 403 errors because
the egress proxy has no approved binary list and denies all traffic.

- Add binaries (openclaw, claude) to all 9 affected presets
- Package manager presets additionally allow their tool binaries
  (pip for pypi, npm/node/yarn for npm, docker for docker)
- Add validatePreset() that warns on missing binaries at apply time
- Add 3 regression tests ensuring all presets have binaries
- Fix installer HTTPS remediation test (shadow real nemoclaw binary)
- Fix installer to print GitHub URL when binary not found
…IA#606, NVIDIA#719)

Add config-io.js module providing atomic JSON config file writes
(write-to-temp + rename) with proper EACCES error detection and
user-facing remediation hints. Refactor credentials.js and registry.js
to use the shared module instead of raw fs calls.

When ~/.nemoclaw/ is owned by root or has wrong permissions, users now
get a clear error message with fix commands instead of a cryptic
EACCES stack trace.
)

Replace all curl|bash and curl|sudo bash patterns with download-to-file
and SHA-256 verification before execution. Adds download_and_verify()
helper to install.sh, scripts/install.sh, and scripts/brev-setup.sh.

- Ollama installer: download to temp file, verify SHA-256, then execute
- NodeSource setup: download to temp file, verify SHA-256, then execute
- nvm installer: refactored to use shared download_and_verify() helper
- NEMOCLAW_SKIP_INTEGRITY=1 env var available for CI/air-gapped bypass
- 7 new tests covering hash match, mismatch, skip, cleanup, and
  static analysis of all three installer scripts
…NVIDIA#684)

Ports 8080 (gateway) and 18789 (dashboard) now configurable via
NEMOCLAW_GATEWAY_PORT and NEMOCLAW_DASHBOARD_PORT env vars. When the
default port is occupied, resolvePort() auto-selects an alternative
(port+1 through port+9) and notifies the user. Error messages now
suggest the env var override. Adds parsePortEnv() with range validation
(1024–65535). 15 new tests for port parsing, resolution, and conflict
handling.
Add buildCredentialEnv() helper and KNOWN_CREDENTIAL_KEYS to
credentials.js as the single source of truth for credential retrieval.
All integrations now use getCredential() consistently instead of
raw process.env access.

- nemoclaw.js deploy: uses buildCredentialEnv() instead of per-key
  manual reads (fixes GITHUB_TOKEN bypassing credentials.json)
- onboard.js sandbox create: uses buildCredentialEnv() for env injection
- onboard.js setupInference: passes NVIDIA_API_KEY via env indirection
  (_NEMOCLAW_CRED) instead of CLI args (no longer visible in ps/proc)
- onboard.js policy detect: removes redundant || process.env fallbacks
- telegram-bridge.js: uses getCredential() for both tokens
- 13 new tests covering buildCredentialEnv, getCredential priority,
  and source-level checks for consistent credential patterns
…DIA#626)

k3s-inside-Docker has broken DNS on all platforms — CoreDNS forwards to
127.0.0.11 (Docker embedded DNS) which is unreachable from k3s pods.
Previously the fix only applied to Colima, leaving Docker Desktop and
plain Docker users with DNS failures (getaddrinfo EAI_AGAIN).

- shouldPatchCoredns() now returns true for colima, docker-desktop, docker
- fix-coredns.sh accepts a runtime argument and resolves the Docker socket
  per-runtime (Colima socket, Docker Desktop socket, or default)
- onboard.js passes detected runtime to fix-coredns.sh
- 4 new regression tests for DNS upstream resolution on non-Colima runtimes
…nt (NVIDIA#731, NVIDIA#726)

install.sh: add --ignore-scripts to npm link on both source-checkout and
GitHub-clone paths to prevent husky prepare hook from invoking missing
binaries (npm error 127).

onboard.js: lsof suggestions in port-conflict messages now include sudo
prefix so users on Linux can actually see root-owned listeners.

preflight.js: lsof port detection falls back to sudo -n when non-root
user gets empty output, improving port conflict diagnosis.

Also adds .shellcheckrc to suppress pre-existing info-level shellcheck
warnings (SC2059 for printf color codes, SC1091 for dynamic nvm source).
…tallation (NVIDIA#737)

Both installers now run detect_placeholder_package() before npm link,
checking npm root -g for a placeholder nemoclaw package (no bin.nemoclaw
field) and removing it. Post-install verification confirms the binary
responds to --version. Docs updated to use git+https URL instead of bare
npm install -g nemoclaw. 3 new regression tests.
…IA#578)

Pin every third-party and official action across all 6 CI workflow files
to full 40-character commit SHAs with version comments for auditability.

Pinned actions:
- actions/checkout v4 (34e11487)
- actions/setup-node v4 (49933ea5)
- actions/setup-python v5 (a26af69b)
- actions/upload-artifact v4 (ea165f8d)
- astral-sh/setup-uv v4 (38f3f104)
- rossjrw/pr-preview-action v1 (ffa7509e)

Added 7 regression tests that scan all workflow files and fail if any
action uses a tag ref instead of a SHA.
The Dockerfile generated openclaw.json at build time with the default
model (nemotron-3-super-120b-a12b), but model selection happened AFTER
sandbox creation.  Users who chose Ollama or vLLM saw the wrong model
in the OpenClaw TUI.

Fix: extract selectInferenceProvider() from setupNim() and call it
BEFORE createSandbox().  New patchDockerfileModel() helper replaces
ARG NEMOCLAW_MODEL in the build context so the image is built with
the correct model baked into openclaw.json.

Onboard step reorder: select provider (step 3) → create sandbox (step 4).
…int (NVIDIA#710, NVIDIA#709)

Move Ollama validation into Step 3 (provider selection) so users get
immediate feedback instead of failing in Step 5 after a multi-minute
sandbox build.

- hasInstalledOllamaModels(): checks `ollama list` before proceeding;
  exits with remediation hint (`ollama pull`) if no models are installed
- getOllamaBindAddressHint(): on Linux, shows OLLAMA_HOST=0.0.0.0
  fix with both one-shot and systemd-persistent instructions
- validateLocalProvider() now runs early on Linux in selectInferenceProvider()
  to catch container-unreachable Ollama before sandbox creation
- 8 new regression tests
New logger module writes timestamped DEBUG messages to stderr when
enabled via --verbose, --debug, LOG_LEVEL=debug, or NEMOCLAW_VERBOSE=1.
All runner commands are logged with secrets redacted. Flags are stripped
before dispatch so they don't interfere with subcommands.
…lowedOrigins (NVIDIA#739)

- Add OPENCLAW_VERSION build arg so users can upgrade OpenClaw without
  editing the Dockerfile (override via NEMOCLAW_OPENCLAW_VERSION env var)
- Expand trustedProxies to include RFC1918 private CIDRs (10.0.0.0/8,
  172.16.0.0/12, 192.168.0.0/16) so X-Forwarded-For headers are trusted
  from SSH tunnels and reverse proxies on headless deployments
- Add NEMOCLAW_EXTRA_ORIGINS build arg for additional CORS origins
  (comma-separated, override via NEMOCLAW_EXTRA_ORIGINS env var)
- Add patchDockerfileVersion() and patchDockerfileExtraOrigins() helpers
  in onboard.js, called during sandbox creation
- 9 new regression tests
…esolved.conf (NVIDIA#744)

On DGX Spark (Ubuntu with systemd-resolved), /etc/resolv.conf points to
127.0.0.53 (stub resolver) which is loopback and gets filtered out.
resolve_coredns_upstream() now falls back to /run/systemd/resolve/resolv.conf
which contains the actual upstream nameservers.
…in nimStatus (NVIDIA#684, NVIDIA#713)

NIM inference port (default 8000) now configurable via NEMOCLAW_NIM_PORT
env var, matching the pattern established for gateway and dashboard ports.
nimStatus() health check uses stored port instead of hardcoded 8000,
fixing incorrect health reports when NIM runs on a non-default port.
nimPort is stored in the sandbox registry for later status queries.
OpenShell may set the sandbox home directory to 0711 (drwx--x--x),
which prevents agents from listing or reading files. Add explicit
chmod 755 /sandbox in the Dockerfile and a runtime fix_home_permissions()
function in nemoclaw-start.sh that detects and repairs restrictive modes
(700, 710, 711) at startup.
…hot, and policies

Blueprint Python code previously had 0% test coverage. Adds 134 pytest
tests across 3 modules: runner (plan/apply/status/rollback/CLI), snapshot
(create/restore/cutover/rollback/list), and policy presets (structural
validation of all 10 YAML presets with parametrized checks for required
fields, binaries, port ranges, and SPDX headers).
Add 25 new tests covering previously untested branches:
- validatePreset: warning branch when binaries section missing
- extractPresetEntries: null return for missing network_policies
- parseCurrentPolicy: all 3 code paths (null, no separator, with separator)
- applyPreset: sandbox name validation (6 rejection cases + missing preset)
- getAppliedPresets: unknown sandbox returns empty array
- getProviderSelectionConfig: vllm-local provider, unknown provider returns null
- getOpenClawPrimaryModel: default model selection for ollama/nim/unknown providers
…ests

Export parsePolicyPresetEnv, isSafeModelId, getNonInteractiveProvider,
getNonInteractiveModel, and printDashboard from onboard.js for testing.

Add two new test files:
- onboard-helpers.test.js: 34 tests covering policy preset parsing,
  model ID validation, non-interactive env var handling, and dashboard
  output rendering
- branch-coverage.test.js: 40 tests targeting uncovered branches across
  platform.js (WSL procVersion, plain docker), preflight.js
  (getConfiguredPorts error paths), local-inference.js (default switch
  cases, validateOllamaModel JSON error), inference-config.js (model
  defaults), config-io.js (ENOENT/ENOTDIR), runner.js (shellQuote)
…-openshell, logger

26 new tests targeting uncovered branches:
- CLI: --version, -v, --verbose/--debug flag stripping (6 tests)
- config-io: non-EACCES error rethrow paths, no-cause constructor (3 tests)
- platform: findColimaDockerSocket null, isUnsupportedMacosRuntime (6 tests)
- resolve-openshell: empty/relative/absolute commandV, home edge cases (7 tests)
- logger: format specifier overflow, plain message without args (2 tests)

Coverage improvements: logger.js → 100% branches, config-io → 85%,
resolve-openshell → 85.71%, platform → 84.31%, bin/lib → 81.92%
…models (NVIDIA#733)

activeModelEntries() previously returned only the onboarded model,
preventing users from switching to other models via `openshell inference
set`. Now returns the full 6-model catalog (added kimi-k2.5 and
qwen3.5-397b) with the onboarded model prepended if it's custom.

Also fixes printDashboard() calling nimStatus() without the configured
NIM port — now reads nimPort from registry for correct health checks
on non-default ports.
NVIDIA#738)

README.md: CLI reference link used .md extension instead of .html,
causing 404 on docs.nvidia.com. PR template: relative links to
CONTRIBUTING.md resolved from .github/ instead of repo root.
setup-spark.sh: exit message now explains what was configured
(cgroup v2) and why re-onboarding may be needed; removed unused
SCRIPT_DIR variable (shellcheck SC2034).

6 new regression tests validate link integrity and messaging.
New `nemoclaw update` command detects installation type (source checkout
or global npm) and updates accordingly. `nemoclaw update --check` shows
whether an update is available without installing.
…#724)

WhatsApp channel (via @whiskeysockets/baileys/libsignal-node) and other
native addons (@matrix-org/matrix-sdk-crypto-nodejs, protobufjs, koffi)
fail to install on DGX Spark because node:22-slim lacks build tools.

Add build-essential + python3-dev to both Dockerfiles, then purge after
all npm installs complete to keep the image lean (~200MB savings).

7 new regression tests validate toolchain presence, install ordering,
and post-install cleanup in both production and test Dockerfiles.
The Dockerfile's Python config generator used shell interpolation
('${VAR}') inside Python string literals to read build args. A crafted
NEMOCLAW_OPENCLAW_VERSION or NEMOCLAW_EXTRA_ORIGINS containing single
quotes could inject arbitrary Python code during docker build.

Defense in depth:
- Dockerfile: promote ARGs to ENV, read via os.environ.get() instead
  of shell interpolation — eliminates the injection vector at its root
- onboard.js: isSafeVersion() and isSafeOriginsList() validate inputs
  before patching the Dockerfile, rejecting quotes/backticks/semicolons
- 15 new regression tests verify injection attempts are blocked and
  the Dockerfile uses the safe os.environ pattern
…jection

detectGpu() now accepts optional {runCapture, platform} deps parameter
for testability without changing its public API (no args = real system).

20 new tests cover all GPU detection branches: NVIDIA discrete (single/
multi GPU VRAM), DGX Spark GB10 (free -m valid/empty/throws/NaN), Apple
Silicon (VRAM GB/MB, sysctl fallback valid/throws/empty), and all
error/fallthrough paths (nvidia-smi empty/non-numeric/throws, no
chipset match, system_profiler empty/throws, non-darwin skip).
… repair (NVIDIA#716)

On WSL2 and other Docker runtimes, restarting openshell-cluster breaks
gateway/sandbox connectivity, previously forcing a full re-onboard.
The new `nemoclaw reconnect` command repairs connectivity in seconds:

- Detects unhealthy gateway and restarts with version-pinned image
- Re-applies CoreDNS fix for Docker-based runtimes
- Waits for sandbox pod to reach Ready state
- Restarts dashboard port forwards
- `--diagnose` flag shows connectivity state without repair

New reconnect.js module with full DI for testability. 32 new tests.
…DIA#736)

The Dockerfile's Python config generator hardcoded reasoning=False and
maxTokens=4096 for all models. Nemotron 3 Super 120B supports reasoning
(thinking tokens) and 8192 max output tokens — when misconfigured,
OpenClaw fails to decode streamed responses containing reasoning tokens,
causing "error decoding response body" in the TUI.

- Dockerfile: add reasoning_models set and model_max_tokens dict; use
  model_entry() helper instead of hardcoded model config objects
- TypeScript plugin: add reasoning flag to ModelProviderEntry interface
  and MODEL_CATALOG entries (Super/Ultra=true, others=false)
- 6 new regression tests (3 Dockerfile + 3 TypeScript)
@coderabbitai

coderabbitai Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@cluster2600 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 27 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7c83e0d3-cda6-4d0b-8dd1-e1157b5cd5ad

📥 Commits

Reviewing files that changed from the base of the PR and between 6e1208c and 806e73b.

⛔ Files ignored due to path filters (1)
  • research/results.tsv is excluded by !**/*.tsv
📒 Files selected for processing (77)
  • .agents/skills/docs/nemoclaw-reference/references/commands.md
  • .github/PULL_REQUEST_TEMPLATE.md
  • .github/workflows/commit-lint.yaml
  • .github/workflows/docs-preview-pr.yaml
  • .github/workflows/docs.yaml
  • .github/workflows/nightly-e2e.yaml
  • .github/workflows/pr.yaml
  • .shellcheckrc
  • Dockerfile
  • README.md
  • bin/lib/config-io.js
  • bin/lib/credentials.js
  • bin/lib/local-inference.js
  • bin/lib/logger.js
  • bin/lib/nim.js
  • bin/lib/onboard.js
  • bin/lib/platform.js
  • bin/lib/policies.js
  • bin/lib/preflight.js
  • bin/lib/reconnect.js
  • bin/lib/registry.js
  • bin/lib/runner.js
  • bin/lib/update.js
  • bin/nemoclaw.js
  • docs/reference/commands.md
  • install.sh
  • nemoclaw-blueprint/policies/presets/discord.yaml
  • nemoclaw-blueprint/policies/presets/docker.yaml
  • nemoclaw-blueprint/policies/presets/huggingface.yaml
  • nemoclaw-blueprint/policies/presets/jira.yaml
  • nemoclaw-blueprint/policies/presets/local-inference.yaml
  • nemoclaw-blueprint/policies/presets/npm.yaml
  • nemoclaw-blueprint/policies/presets/outlook.yaml
  • nemoclaw-blueprint/policies/presets/pypi.yaml
  • nemoclaw-blueprint/policies/presets/slack.yaml
  • nemoclaw-blueprint/policies/presets/telegram.yaml
  • nemoclaw-blueprint/pyproject.toml
  • nemoclaw-blueprint/tests/__init__.py
  • nemoclaw-blueprint/tests/test_policies.py
  • nemoclaw-blueprint/tests/test_runner.py
  • nemoclaw-blueprint/tests/test_snapshot.py
  • nemoclaw/src/index.ts
  • nemoclaw/src/register.test.ts
  • scripts/brev-setup.sh
  • scripts/fix-coredns.sh
  • scripts/install.sh
  • scripts/lib/runtime.sh
  • scripts/nemoclaw-start.sh
  • scripts/setup-spark.sh
  • scripts/telegram-bridge.js
  • scripts/walkthrough.sh
  • test/Dockerfile.sandbox
  • test/branch-coverage.test.js
  • test/cli.test.js
  • test/config-io.test.js
  • test/credential-unified.test.js
  • test/dockerfile-config.test.js
  • test/docs-links.test.js
  • test/inference-config.test.js
  • test/install-preflight.test.js
  • test/installer-integrity.test.js
  • test/local-inference.test.js
  • test/nim.test.js
  • test/onboard-helpers.test.js
  • test/onboard-model-sync.test.js
  • test/onboard-selection.test.js
  • test/platform.test.js
  • test/policies.test.js
  • test/port-config.test.js
  • test/reconnect.test.js
  • test/runner.test.js
  • test/runtime-shell.test.js
  • test/startup-permissions.test.js
  • test/update.test.js
  • test/verbose.test.js
  • test/workflow-pinned.test.js
  • uninstall.sh
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions

Copy link
Copy Markdown
Contributor

This repository limits contributors to 10 open pull requests. Please close or merge existing PRs before opening new ones.

@github-actions github-actions Bot closed this Mar 24, 2026
@wscurran wscurran added the feature PR adds or expands user-visible functionality label Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature PR adds or expands user-visible functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(cli): add self-update command for automatic CLI updates

2 participants