Skip to content

fix(cli): guard OpenShell ssh-config calls#3859

Merged
ericksoa merged 2 commits into
NVIDIA:mainfrom
yimoj:fix/3701-openshell-command-docs-ux
May 22, 2026
Merged

fix(cli): guard OpenShell ssh-config calls#3859
ericksoa merged 2 commits into
NVIDIA:mainfrom
yimoj:fix/3701-openshell-command-docs-ux

Conversation

@yimoj

@yimoj yimoj commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR guards NemoClaw's internal OpenShell SSH-config probes by verifying the sandbox with openshell sandbox get first, avoiding the upstream ssh-config false-positive path for unknown sandbox names. It also updates the OpenShell command docs to use the working logs -n and doctor check forms.

Related Issue

Fixes #3701

Changes

  • Add a guarded captureSandboxSshConfigCommand/runtime wrapper and use it from backup, restore, version probing, skill install, process recovery, and share-command paths.
  • Preserve stderr for guarded sandbox probes when needed so timeout/transient failures are not mislabeled as missing sandboxes.
  • Add probe timeouts to lifecycle and skill-install SSH-config capture paths.
  • Update diagnostics collection to verify a named sandbox with openshell sandbox get before collecting SSH-based internals.
  • Add focused tests for the guarded SSH-config flow and update version-probe mocks.
  • Update the CLI selection guide examples from openshell logs --tail/openshell doctor to openshell logs <name> -n 20/openshell doctor check.

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)

Focused checks run:

  • npx vitest run src/lib/adapters/openshell/client.test.ts src/lib/sandbox/version.test.ts
  • npx vitest run src/lib/adapters/openshell/client.test.ts src/lib/sandbox/version.test.ts test/snapshot.test.ts
  • npx vitest run test/gateway-state-reconcile-2276.test.ts -t "skill install"
  • NEMOCLAW_TEST_TIMEOUT=20000 npx vitest run src/lib/domain/sandbox/logs.test.ts test/cli.test.ts -t logs
  • NEMOCLAW_TEST_TIMEOUT=20000 npx vitest run src/lib/share-command.test.ts test/share-command-remote-path.test.ts test/snapshot.test.ts test/repro-2201.test.ts test/rebuild-credential-preflight.test.ts test/cli.test.ts -t "connect --probe-only|recovers non-OpenClaw|share|snapshot|rebuild|2201"
  • npx vitest run test/snapshot.test.ts test/repro-2201.test.ts test/rebuild-credential-preflight.test.ts
  • npx biome check src/lib/adapters/openshell/client.ts src/lib/adapters/openshell/client.test.ts src/lib/sandbox/version.test.ts src/lib/state/sandbox.ts src/lib/actions/sandbox/skill-install.ts
  • npm run build:cli
  • npm run typecheck:cli
  • npm run checks
  • git diff --check
  • codex review -c sandbox_mode="danger-full-access" --uncommitted

Lifecycle E2E status:

  • Nightly workflow dispatch for state-backup-restore-e2e, snapshot-commands-e2e, and rebuild-openclaw-e2e was rejected by GitHub with HTTP 403: Must have admin rights to Repository.
  • Local isolated attempts were run with unique HOME, NEMOCLAW_HOME, and NEMOCLAW_SANDBOX_NAME values. Docker and OpenShell were available (docker_rc:0, openshell 0.0.39), but this shell has no NVIDIA_API_KEY; each script failed at preflight before sandbox creation:
    • test/e2e/test-state-backup-restore.sh: ERROR: NVIDIA_API_KEY not set, state_backup_restore_rc:1
    • test/e2e/test-snapshot-commands.sh: [FAIL] NVIDIA_API_KEY is required, snapshot_commands_rc:1
    • test/e2e/test-rebuild-openclaw.sh: [FAIL] NVIDIA_API_KEY is required, rebuild_openclaw_rc:1

Signed-off-by: Yimo Jiang yimoj@nvidia.com

Summary by CodeRabbit

  • Documentation

    • CLI selection guide now recommends openshell logs <sandbox-name> -n 20, adds openshell doctor check, clarifies -n vs --tail, and updates lower-level debugging guidance.
  • Bug Fixes

    • SSH config retrieval now verifies sandbox existence and returns clearer not-found responses, improving reliability of SSH probing.
  • Tests

    • Expanded tests to validate SSH probing order, error handling, and combined stdout/stderr behavior.

Review Change Stack

@yimoj yimoj self-assigned this May 20, 2026
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Extracts sandbox-aware SSH-config capture into new client/runtime helpers, centralizes stdout+stderr handling, refactors callers/tests/state/diagnostics to use the helper, and updates CLI docs to prefer openshell logs <name> -n 20 and recommend openshell doctor check.

Changes

SSH Config Capture Extraction and Refactoring

Layer / File(s) Summary
New client helpers and stderr handling
src/lib/adapters/openshell/client.ts, src/lib/adapters/openshell/client.test.ts, src/lib/adapters/openshell/runtime.ts
Adds includeStderr?: boolean, shared output builders, captureSandboxSshConfigCommand (two-step: sandbox get then sandbox ssh-config with not-found rewrite), runtime wrapper captureSandboxSshConfig, and tests for existence/not-found/error and stderr aggregation.
Update process recovery and skill install callers
src/lib/actions/sandbox/process-recovery.ts, src/lib/actions/sandbox/skill-install.ts
Call-sites switched to captureSandboxSshConfig/captureSandboxSshConfigCommand instead of constructing openshell arg arrays; temp-file creation, ssh spawn, and cleanup remain unchanged.
Update sandbox version probing with SSH config capture
src/lib/sandbox/version.ts, src/lib/sandbox/version.test.ts
probeAgentVersion now uses captureSandboxSshConfigCommand(openshellBinary, sandboxName, { ignoreError, timeout }). Tests and mocks updated to assert the new helper across probe scenarios.
Update command dependencies and sandbox state callers
src/lib/share-command-deps.ts, src/lib/state/sandbox.ts
getSshConfig in shared deps and state/sandbox now use the sandbox-specific capture helper with ignoreError: true and configured timeout; JSDoc updated to note existence verification.
Diagnostics gating, redact export, and CLI docs
src/lib/diagnostics/debug.ts, docs/reference/cli-selection-guide.mdx
Diagnostics now checks sandbox existence using openshell sandbox get <name> before collecting internals; re-exports redact; CLI docs favor openshell logs <name> -n 20 over --tail and add openshell doctor check to lower-level debugging guidance.

Sequence Diagram (high level):

sequenceDiagram
  participant Caller as Caller (process-recovery / skill-install / version / state)
  participant Runtime as src/lib/adapters/openshell/runtime.ts
  participant Client as src/lib/adapters/openshell/client.ts
  participant Openshell as openshell CLI
  Caller->>Runtime: captureSandboxSshConfig(sandboxName, opts)
  Runtime->>Client: captureSandboxSshConfigCommand(binary, sandboxName, opts)
  Client->>Openshell: "sandbox get <name>" (ignoreError, includeStderr)
  alt sandbox exists
    Client->>Openshell: "sandbox ssh-config <name>"
    Openshell-->>Client: ssh-config stdout
    Client-->>Runtime: ssh-config output
    Runtime-->>Caller: ssh-config output
  else sandbox missing or get failed
    Openshell-->>Client: get error output
    Client-->>Runtime: "sandbox '<name>' not found" (or get error)
    Runtime-->>Caller: error output
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #3739: Addresses the OpenShell UX issues (E3–E5) by adding a sandbox existence check before ssh-config, preferring -n for logs, and recommending openshell doctor check.

Suggested labels

NemoClaw CLI, fix

Suggested reviewers

  • ericksoa

Poem

🐰 I hop through sandboxes bright and small,
I check each name before sharing the call,
If found, keys and proxies appear,
If missing, I say so clear—
Happy hops and tidy logs to all!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.53% 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 'fix(cli): guard OpenShell ssh-config calls' accurately summarizes the main change: adding guards (sandbox existence checks) before OpenShell ssh-config invocations.
Linked Issues check ✅ Passed The PR directly addresses E3 from issue #3701 by adding sandbox existence checks via 'openshell sandbox get' before 'openshell sandbox ssh-config' calls across multiple code paths (process-recovery, skill-install, version probe, share-command, state backup/restore). CLI docs were updated reflecting recommended commands (E4, E5). All primary coding objectives are met.
Out of Scope Changes check ✅ Passed All changes are scoped to issue #3701: ssh-config guarding logic, supporting helper functions in client/runtime adapters, test updates, and CLI documentation updates. No unrelated modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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

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

Actionable comments posted: 1

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

Inline comments:
In `@src/lib/adapters/openshell/client.ts`:
- Around line 183-187: The current code always replaces an empty output for any
non-zero sandboxGet.status with "sandbox '<sandboxName>' not found", which hides
other failure modes; change the logic in the sandbox retrieval branch so you
only synthesize the "not found" message for a proven not-found condition (e.g.,
a specific exit code or when stderr/output explicitly contains "not found"), and
for any other non-zero status preserve sandboxGet.output (or include
sandboxGet.error/exit code in the returned object) instead of overwriting it;
update the handling around sandboxGet, sandboxName and sandboxGet.status to
return the original result for transient or timeout errors and only emit the
not-found string when you can definitively detect that condition.
🪄 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: Enterprise

Run ID: 56954f5f-d7fc-4262-8804-8413bb15e52b

📥 Commits

Reviewing files that changed from the base of the PR and between 11b1937 and 28e1c46.

📒 Files selected for processing (11)
  • docs/reference/cli-selection-guide.mdx
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/skill-install.ts
  • src/lib/adapters/openshell/client.test.ts
  • src/lib/adapters/openshell/client.ts
  • src/lib/adapters/openshell/runtime.ts
  • src/lib/diagnostics/debug.ts
  • src/lib/sandbox/version.test.ts
  • src/lib/sandbox/version.ts
  • src/lib/share-command-deps.ts
  • src/lib/state/sandbox.ts

Comment thread src/lib/adapters/openshell/client.ts
@yimoj yimoj force-pushed the fix/3701-openshell-command-docs-ux branch from 28e1c46 to d2da090 Compare May 20, 2026 05:35

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

Actionable comments posted: 1

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

Inline comments:
In `@src/lib/adapters/openshell/client.ts`:
- Around line 35-37: The async capture path currently ignores includeStderr when
ignoreError is true, so update the async output-building logic (the code
handling CaptureOpenshellAsyncOptions / the function that assembles async
results) to respect the includeStderr flag even if ignoreError === true: when
includeStderr is true, append or merge stderr into the returned output/error
payload the same way the sync path does. Locate the code that checks ignoreError
and constructs the async response (references: CaptureOpenshellAsyncOptions,
includeStderr, ignoreError) and change the conditional so stderr is
preserved/attached when includeStderr is set.
🪄 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: Enterprise

Run ID: 38ab85a1-548c-41a5-bdfa-df2508563f4c

📥 Commits

Reviewing files that changed from the base of the PR and between 28e1c46 and d2da090.

📒 Files selected for processing (11)
  • docs/reference/cli-selection-guide.mdx
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/skill-install.ts
  • src/lib/adapters/openshell/client.test.ts
  • src/lib/adapters/openshell/client.ts
  • src/lib/adapters/openshell/runtime.ts
  • src/lib/diagnostics/debug.ts
  • src/lib/sandbox/version.test.ts
  • src/lib/sandbox/version.ts
  • src/lib/share-command-deps.ts
  • src/lib/state/sandbox.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/cli-selection-guide.mdx

Comment thread src/lib/adapters/openshell/client.ts
@yimoj yimoj force-pushed the fix/3701-openshell-command-docs-ux branch from d2da090 to 96d0f41 Compare May 20, 2026 05:44

@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 (2)
src/lib/state/sandbox.ts (1)

472-476: Run the state lifecycle E2E set for this change path.

Since this touches sandbox backup/restore SSH-config retrieval, please run state-backup-restore-e2e, snapshot-commands-e2e, and rebuild-openclaw-e2e on this branch before merge.

As per coding guidelines: "src/lib/state/sandbox.ts: This file manages sandbox state (backup, restore, rebuild, snapshot). Changes affect data persistence across sandbox lifecycle operations." and the listed E2E test recommendation.

🤖 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 `@src/lib/state/sandbox.ts` around lines 472 - 476, This change touches sandbox
SSH-config retrieval in src/lib/state/sandbox.ts (specifically the call to
captureSandboxSshConfigCommand and the result handling) and requires running the
full state lifecycle E2E suites before merging: execute
state-backup-restore-e2e, snapshot-commands-e2e, and rebuild-openclaw-e2e on
this branch to validate backup/restore/snapshot/rebuild behavior; if any
failures appear, reproduce them locally while inspecting
captureSandboxSshConfigCommand and related backup/restore logic in sandbox.ts to
determine whether the SSH-config fallback (ignoreError: true) or result.status
handling should be adjusted and then re-run the E2Es until all pass.
src/lib/sandbox/version.test.ts (1)

31-31: ⚡ Quick win

Remove unused mock for captureOpenshellCommand.

The mock for captureOpenshellCommand is no longer used after the refactor to captureSandboxSshConfigCommand. All tests now reference the new helper. Removing this line will prevent confusion for future maintainers.

🧹 Proposed cleanup
   versionGte: (left = "0.0.0", right = "0.0.0") => {
     const lhs = String(left).split(".").map((p) => parseInt(p, 10) || 0);
     const rhs = String(right).split(".").map((p) => parseInt(p, 10) || 0);
     const length = Math.max(lhs.length, rhs.length);
     for (let i = 0; i < length; i++) {
       const a = lhs[i] || 0;
       const b = rhs[i] || 0;
       if (a > b) return true;
       if (a < b) return false;
     }
     return true;
   },
-  captureOpenshellCommand: vi.fn(),
   captureSandboxSshConfigCommand: vi.fn(),
 }));
🤖 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 `@src/lib/sandbox/version.test.ts` at line 31, Remove the unused mock property
captureOpenshellCommand from the test mocks in version.test.ts: locate the mock
object that currently defines captureOpenshellCommand: vi.fn() and delete that
entry so only the active helper (captureSandboxSshConfigCommand) remains; ensure
no other tests reference captureOpenshellCommand and run the test suite to
confirm no breakage.
🤖 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 `@src/lib/sandbox/version.test.ts`:
- Line 31: Remove the unused mock property captureOpenshellCommand from the test
mocks in version.test.ts: locate the mock object that currently defines
captureOpenshellCommand: vi.fn() and delete that entry so only the active helper
(captureSandboxSshConfigCommand) remains; ensure no other tests reference
captureOpenshellCommand and run the test suite to confirm no breakage.

In `@src/lib/state/sandbox.ts`:
- Around line 472-476: This change touches sandbox SSH-config retrieval in
src/lib/state/sandbox.ts (specifically the call to
captureSandboxSshConfigCommand and the result handling) and requires running the
full state lifecycle E2E suites before merging: execute
state-backup-restore-e2e, snapshot-commands-e2e, and rebuild-openclaw-e2e on
this branch to validate backup/restore/snapshot/rebuild behavior; if any
failures appear, reproduce them locally while inspecting
captureSandboxSshConfigCommand and related backup/restore logic in sandbox.ts to
determine whether the SSH-config fallback (ignoreError: true) or result.status
handling should be adjusted and then re-run the E2Es until all pass.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1e258949-de29-47f2-ad5e-eaba572ef30b

📥 Commits

Reviewing files that changed from the base of the PR and between d2da090 and 96d0f41.

📒 Files selected for processing (11)
  • docs/reference/cli-selection-guide.mdx
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/skill-install.ts
  • src/lib/adapters/openshell/client.test.ts
  • src/lib/adapters/openshell/client.ts
  • src/lib/adapters/openshell/runtime.ts
  • src/lib/diagnostics/debug.ts
  • src/lib/sandbox/version.test.ts
  • src/lib/sandbox/version.ts
  • src/lib/share-command-deps.ts
  • src/lib/state/sandbox.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/cli-selection-guide.mdx

@yimoj yimoj force-pushed the fix/3701-openshell-command-docs-ux branch from 96d0f41 to 66a54f1 Compare May 20, 2026 05:51
@yimoj

yimoj commented May 20, 2026

Copy link
Copy Markdown
Contributor Author

CodeRabbit follow-up:

  • Removed the unused captureOpenshellCommand mock from src/lib/sandbox/version.test.ts in 66a54f1fd.
  • Attempted to dispatch the requested nightly lifecycle E2E jobs against this PR head:
    gh workflow run nightly-e2e.yaml --repo NVIDIA/NemoClaw --ref main -f jobs=state-backup-restore-e2e,snapshot-commands-e2e,rebuild-openclaw-e2e -f target_ref=refs/pull/3859/head -f pr_number=3859
  • GitHub rejected the dispatch with HTTP 403: Must have admin rights to Repository. I did not run those full lifecycle E2Es locally because they exercise real OpenShell/Docker gateway state; the scoped local lifecycle coverage already run is documented in the PR body.

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/lib/actions/sandbox/skill-install.ts (1)

171-173: ⚡ Quick win

Add an explicit timeout to SSH-config capture in skill install.

Line 171 performs a blocking OpenShell probe without an explicit timeout; a hung CLI call can stall the command.

♻️ Proposed patch
 import { captureSandboxSshConfig } from "../../adapters/openshell/runtime";
+import { OPENSHELL_PROBE_TIMEOUT_MS } from "../../adapters/openshell/timeouts";
@@
   const sshConfigResult = captureSandboxSshConfig(sandboxName, {
     ignoreError: true,
+    timeout: OPENSHELL_PROBE_TIMEOUT_MS,
   });
🤖 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 `@src/lib/actions/sandbox/skill-install.ts` around lines 171 - 173, The call to
captureSandboxSshConfig(sandboxName, { ignoreError: true }) can block
indefinitely; add an explicit timeout (e.g., 5–15s) so the skill install cannot
hang: either extend the call to pass a timeout option if captureSandboxSshConfig
supports it (e.g., { ignoreError: true, timeoutMs: 10000 } or an AbortSignal),
or wrap the call in a Promise.race that rejects after the timeout and then
handle the timeout error the same way ignoreError is handled; update the
invocation in skill-install.ts (the captureSandboxSshConfig usage) to use the
timeout and ensure any thrown timeout is caught/logged consistent with existing
error handling.
🤖 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.

Inline comments:
In `@src/lib/state/sandbox.ts`:
- Around line 472-474: captureSandboxSshConfigCommand is called without any
timeout which allows a hung OpenShell process to stall lifecycle operations;
update the call site that constructs result (calling
captureSandboxSshConfigCommand(openshellBinary, sandboxName, { ignoreError: true
})) to pass a probe timeout option (e.g., { ignoreError: true, timeoutMs:
<reasonable-ms> }) or use the existing timeout parameter shape accepted by
captureSandboxSshConfigCommand so the OpenShell invocation is cancelled after a
bounded time, and ensure the surrounding logic handles the timeout as an
ignorable error similar to other transient failures.

---

Nitpick comments:
In `@src/lib/actions/sandbox/skill-install.ts`:
- Around line 171-173: The call to captureSandboxSshConfig(sandboxName, {
ignoreError: true }) can block indefinitely; add an explicit timeout (e.g.,
5–15s) so the skill install cannot hang: either extend the call to pass a
timeout option if captureSandboxSshConfig supports it (e.g., { ignoreError:
true, timeoutMs: 10000 } or an AbortSignal), or wrap the call in a Promise.race
that rejects after the timeout and then handle the timeout error the same way
ignoreError is handled; update the invocation in skill-install.ts (the
captureSandboxSshConfig usage) to use the timeout and ensure any thrown timeout
is caught/logged consistent with existing error handling.
🪄 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: Enterprise

Run ID: 78d5c329-ccd6-4763-a09c-2476c43310a4

📥 Commits

Reviewing files that changed from the base of the PR and between 96d0f41 and 66a54f1.

📒 Files selected for processing (11)
  • docs/reference/cli-selection-guide.mdx
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/skill-install.ts
  • src/lib/adapters/openshell/client.test.ts
  • src/lib/adapters/openshell/client.ts
  • src/lib/adapters/openshell/runtime.ts
  • src/lib/diagnostics/debug.ts
  • src/lib/sandbox/version.test.ts
  • src/lib/sandbox/version.ts
  • src/lib/share-command-deps.ts
  • src/lib/state/sandbox.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/cli-selection-guide.mdx

Comment thread src/lib/state/sandbox.ts
Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
@yimoj yimoj force-pushed the fix/3701-openshell-command-docs-ux branch from 66a54f1 to 4b42805 Compare May 20, 2026 05:58
@yimoj

yimoj commented May 20, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume
@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

@yimoj Thanks for the follow-up! Acknowledged on:

  • The removal of the unused captureOpenshellCommand mock from src/lib/sandbox/version.test.ts (commit 66a54f1fd).
  • The HTTP 403 on the nightly lifecycle E2E dispatch — that's a repository-level permissions constraint, not a code issue. The scoped local lifecycle coverage documented in the PR body is a reasonable substitute given the constraint.

Resuming reviews and kicking off a fresh review now.

✅ Actions performed

Reviews resumed.


Full review triggered.

@yimoj

yimoj commented May 20, 2026

Copy link
Copy Markdown
Contributor Author

Correction/update on lifecycle E2E verification:

I did attempt the CodeRabbit-requested lifecycle scripts locally with isolated state and unique sandbox names after the workflow dispatch was rejected:

  • HOME=/tmp/nemoclaw-fix-3701-home-fix3701-state-... NEMOCLAW_HOME=$HOME/.nemoclaw NEMOCLAW_SANDBOX_NAME=fix3701-state-... timeout 2m bash test/e2e/test-state-backup-restore.sh
    • Result: ERROR: NVIDIA_API_KEY not set, state_backup_restore_rc:1
  • HOME=/tmp/nemoclaw-fix-3701-home-fix3701-snapshot-... NEMOCLAW_HOME=$HOME/.nemoclaw NEMOCLAW_SANDBOX_NAME=fix3701-snapshot-... timeout 2m bash test/e2e/test-snapshot-commands.sh
    • Result: [FAIL] NVIDIA_API_KEY is required, snapshot_commands_rc:1
  • HOME=/tmp/nemoclaw-fix-3701-home-fix3701-rebuild-... NEMOCLAW_HOME=$HOME/.nemoclaw NEMOCLAW_SANDBOX_NAME=fix3701-rebuild-... timeout 2m bash test/e2e/test-rebuild-openclaw.sh
    • Result: [FAIL] NVIDIA_API_KEY is required, rebuild_openclaw_rc:1

Local preflight evidence: Docker is available (docker_rc:0), OpenShell is available (openshell 0.0.39), but this shell has no NVIDIA_API_KEY (nvidia_api_key:missing). The scripts fail before sandbox creation, so no shared OpenShell/gateway state was contaminated by these attempts.

@yimoj yimoj added the v0.0.48 Release target label May 20, 2026
@cv cv added v0.0.49 Release target v0.0.50 Release target and removed v0.0.48 Release target v0.0.49 Release target labels May 21, 2026
…mmand-docs-ux

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

# Conflicts:
#	docs/reference/cli-selection-guide.mdx

@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)
src/lib/state/sandbox.ts (1)

1376-1389: Run the targeted lifecycle E2E suites before merge.

This restore-path update changes backup/restore persistence behavior; please run state-backup-restore-e2e, snapshot-commands-e2e, and rebuild-openclaw-e2e for confidence on state integrity.

As per coding guidelines: src/lib/state/sandbox.ts changes should validate state-backup-restore-e2e, snapshot-commands-e2e, and rebuild-openclaw-e2e.

Also applies to: 1401-1406

🤖 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 `@src/lib/state/sandbox.ts` around lines 1376 - 1389, This change around
restore behavior (calling shouldPreserveOpenClawManagedExtensions,
buildRestoreTarArgs and using spawnSync to run tar producing tarResult) requires
running the targeted lifecycle E2E suites to validate state integrity; run
state-backup-restore-e2e, snapshot-commands-e2e, and rebuild-openclaw-e2e
against the branch and confirm backups/restores and snapshots behave as before
(including the alternate code paths at the nearby block referenced around lines
where buildRestoreTarArgs/spawnSync/tarResult are used), fix any failing
assertions or state drift observed, and update tests or code
(preserveManagedExtensions handling in shouldPreserveOpenClawManagedExtensions
or argument construction in buildRestoreTarArgs) until all three suites pass.
🤖 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 `@src/lib/state/sandbox.ts`:
- Around line 1376-1389: This change around restore behavior (calling
shouldPreserveOpenClawManagedExtensions, buildRestoreTarArgs and using spawnSync
to run tar producing tarResult) requires running the targeted lifecycle E2E
suites to validate state integrity; run state-backup-restore-e2e,
snapshot-commands-e2e, and rebuild-openclaw-e2e against the branch and confirm
backups/restores and snapshots behave as before (including the alternate code
paths at the nearby block referenced around lines where
buildRestoreTarArgs/spawnSync/tarResult are used), fix any failing assertions or
state drift observed, and update tests or code (preserveManagedExtensions
handling in shouldPreserveOpenClawManagedExtensions or argument construction in
buildRestoreTarArgs) until all three suites pass.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7a640608-99ff-4f98-873e-4f2950559c51

📥 Commits

Reviewing files that changed from the base of the PR and between 4b42805 and ad2c219.

📒 Files selected for processing (6)
  • docs/reference/cli-selection-guide.mdx
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/diagnostics/debug.ts
  • src/lib/sandbox/version.test.ts
  • src/lib/share-command-deps.ts
  • src/lib/state/sandbox.ts

@ericksoa

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 22, 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.

@ericksoa ericksoa merged commit 7ba9bdc into NVIDIA:main May 22, 2026
22 checks passed
@wscurran wscurran added area: docs Documentation, examples, guides, or docs build bug-fix PR fixes a bug or regression and removed documentation labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: docs Documentation, examples, guides, or docs build bug-fix PR fixes a bug or regression v0.0.50 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[All Platforms][CLI] openshell ssh-config / logs / doctor — 3 UX issues

4 participants