Skip to content

fix(status): point SSH operators to dashboard-url for remote access - #8516

Closed
jason-ma-nv wants to merge 1 commit into
mainfrom
fix/8465-status-ssh-remote-access-hint-v2
Closed

fix(status): point SSH operators to dashboard-url for remote access#8516
jason-ma-nv wants to merge 1 commit into
mainfrom
fix/8465-status-ssh-remote-access-hint-v2

Conversation

@jason-ma-nv

@jason-ma-nv jason-ma-nv commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

nemoclaw <sandbox> status gave no remote-access guidance when run over SSH, so an operator on a remote host was left without a pointer to reach the loopback-only dashboard — unlike dashboard-url and the post-onboard block, which print an ssh -L port-forward example (#5925). When the gateway is running and the CLI is in an SSH session, status now prints a pointer to nemoclaw <sandbox> dashboard-url, which renders the copy-pastable port-forward block.

Related Issue

Closes #8465

Changes

  • src/lib/actions/sandbox/status-text.ts: add printDashboardRemoteAccessHint, called in the running-gateway branch of printGatewayProcessStatus. It reuses the existing isSshSession helper from ssh-forward-hint.ts ([All Platforms][CLI&UX] dashboard-url and post-onboard output print only the loopback URL — no copy-pastable SSH port-forward example for remote-SSH'd users #5925) and, only inside an SSH session, prints one line pointing to nemoclaw <sandbox> dashboard-url. Scoped to the gateway-runtime running path, so terminal-runtime sandboxes (which have no browser dashboard) are unaffected. This is a display-only status-output addition; it introduces no new abstraction, flag, or lifecycle behavior.
  • test/support/status-flow-test-harness.ts: add an optional gatewayRunning option (default false, preserving every existing test) and expose the isSandboxGatewayRunningForStatus spy, so a test can drive the real running-gateway rendering path end-to-end.
  • src/lib/actions/sandbox/status-flow.test.ts: add two tests — the pointer appears for a running gateway inside an SSH session, and is omitted when the session is not over SSH (SSH env controlled via vi.stubEnv so the result is deterministic even when the verifying host itself runs over SSH).

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: adds a one-line SSH-gated pointer to the existing dashboard-url command; no new command, flag, or documented contract, and the remote-access/port-forward guidance it points to is already 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: Display-only change under actions/sandbox/ (status output rendering); it adds an SSH-gated guidance line and alters no sandbox lifecycle, credential, policy, or security behavior. Deferred to normal CODEOWNERS review.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: No documentation paths changed. The change adds a single SSH-gated status-output line pointing operators to the already-documented nemoclaw <sandbox> dashboard-url command; it introduces no new command, flag, configuration, or documented contract.
  • Agent: Claude Code

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • 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
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: npx vitest run --project cli src/lib/actions/sandbox/status-flow.test.ts on a fresh clone of this branch on an Ubuntu host (Node v22.23.1, npm ci + plugin build) → 35 passed. Two-way check: reverting only status-text.ts to origin/main (keeping the tests) fails exactly the new positive test (pointer absent = bug reproduced); the negative test still passes.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • 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)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Jason Ma jama@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added SSH-aware guidance to sandbox status output.
    • When connected over SSH and the gateway is running, status now provides instructions for obtaining a dashboard URL and setting up port forwarding.
  • Tests

    • Added coverage for showing the guidance during SSH sessions and omitting it when SSH environment details are unavailable.

`nemoclaw <sandbox> status` gave no remote-access guidance when run over
SSH, unlike `dashboard-url` and the post-onboard block that print an
`ssh -L` port-forward example (#5925). A remote operator checking status
was left without a pointer to reach the loopback-only dashboard.

Extend the #5925 guidance to the status surface: when the gateway is
running and the CLI is in an SSH session, print a pointer to
`nemoclaw <sandbox> dashboard-url`, which renders the copy-pastable
port-forward block. Scoped to the running gateway-runtime path, so
terminal-runtime sandboxes (no dashboard) are unaffected.

Closes #8465

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Jason Ma <jama@nvidia.com>
@jason-ma-nv jason-ma-nv self-assigned this Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

status now prints dashboard-url remote-access guidance when the sandbox gateway is running during an SSH session. Tests cover both SSH and non-SSH environments.

Changes

SSH status guidance

Layer / File(s) Summary
Status remote-access hint
src/lib/actions/sandbox/status-text.ts
Status output checks the SSH session and gateway state before printing dashboard-url port-forward instructions.
Status flow validation
test/support/status-flow-test-harness.ts, src/lib/actions/sandbox/status-flow.test.ts
The test harness controls gateway state. Tests verify guidance for SSH sessions and omission for non-SSH sessions.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#8514: Modifies the same status output, tests, and harness behavior for SSH dashboard guidance.

Suggested reviewers: brandonpelfrey, cv, dnandakumar-nv

Sequence Diagram(s)

sequenceDiagram
  participant Status
  participant GatewayCheck
  participant SSHSession
  participant RemoteAccessHint
  Status->>GatewayCheck: Check whether the gateway is running
  Status->>SSHSession: Check SSH environment variables
  Status->>RemoteAccessHint: Print dashboard-url guidance when both checks pass
Loading
🚥 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 SSH guidance added to the status command.
Linked Issues check ✅ Passed The changes satisfy issue #8465 by guiding SSH users to dashboard-url when the gateway is running.
Out of Scope Changes check ✅ Passed All code and test changes directly support the SSH remote-access guidance objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 fix/8465-status-ssh-remote-access-hint-v2

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

@github-code-quality

github-code-quality Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 12bfa00 in the fix/8465-status-ssh-... branch remains at 96%, unchanged from commit 312f8d1 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 12bfa00 in the fix/8465-status-ssh-... branch remains at 81%, unchanged from commit 312f8d1 in the main branch.

Show a code coverage summary of the most impacted files.
File main 312f8d1 fix/8465-status-ssh-... 12bfa00 +/-
src/lib/onboard...flight-ports.ts 67% 33% -34%
src/lib/actions.../status-text.ts 41% 37% -4%
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/tunnel/services.ts 80% 80% 0%

Updated August 07, 2026 03:53 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/lib/actions/sandbox/status-flow.test.ts (1)

678-690: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add negative coverage for the gateway-state gate.

The tests cover gatewayRunning: true with SSH and without SSH. They do not prove that an SSH session with gatewayRunning: false omits the hint. Add this case through showSandboxStatus. Also cover an SSH terminal-runtime sandbox if no existing test proves that terminal-runtime output remains unchanged.

As per path instructions, review tests for behavioral confidence rather than implementation lock-in.

Also applies to: 692-703

🤖 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/status-flow.test.ts` around lines 678 - 690, Extend
the status-flow tests around showSandboxStatus with an SSH case where
gatewayRunning is false, and assert the remote-access dashboard-url hint is
omitted while normal status output remains valid. Also add coverage for an SSH
terminal-runtime sandbox if existing tests do not already verify its output
remains unchanged; assert user-visible behavior rather than internal
implementation details.

Source: Path instructions

🤖 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/actions/sandbox/status-text.ts`:
- Around line 382-400: Update the CLI documentation for the user-visible
`nemoclaw <sandbox> status` output introduced by
`printDashboardRemoteAccessHint`, including the SSH remote-access guidance and
`dashboard-url` command. Validate the documentation using the project’s
established process and obtain the required independent documentation-writer
review before handoff.
- Around line 382-400: Update printDashboardRemoteAccessHint to shell-quote
sandboxName when constructing the dashboard-url command, reusing the existing
shell-quoting helper used by the status flow tests. Preserve the current
SSH-only hint and message while ensuring names containing spaces or apostrophes
remain valid copy-pastable commands.

---

Nitpick comments:
In `@src/lib/actions/sandbox/status-flow.test.ts`:
- Around line 678-690: Extend the status-flow tests around showSandboxStatus
with an SSH case where gatewayRunning is false, and assert the remote-access
dashboard-url hint is omitted while normal status output remains valid. Also add
coverage for an SSH terminal-runtime sandbox if existing tests do not already
verify its output remains unchanged; assert user-visible behavior rather than
internal implementation details.
🪄 Autofix

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: 78742a5d-3f28-4df4-b3c8-931196479229

📥 Commits

Reviewing files that changed from the base of the PR and between 312f8d1 and 12bfa00.

📒 Files selected for processing (3)
  • src/lib/actions/sandbox/status-flow.test.ts
  • src/lib/actions/sandbox/status-text.ts
  • test/support/status-flow-test-harness.ts

Comment on lines +382 to +400
// On an SSH session the loopback-only dashboard needs a port forward to reach
// from the operator's workstation. `status` does not print the dashboard URL,
// so point to `dashboard-url`, which renders the copy-pastable `ssh -L` block.
// This extends the #5925 remote-access guidance to the status surface (#8465).
function printDashboardRemoteAccessHint(sandboxName: string): void {
if (!isSshSession()) return;
console.log(
` Remote access: run \`${CLI_NAME} ${sandboxName} dashboard-url\` for SSH port-forward instructions.`,
);
}

async function printGatewayProcessStatus(context: SandboxStatusTextContext): Promise<void> {
const { sandboxName, statusAgent } = context;
const running = await isSandboxGatewayRunningForStatus(sandboxName);
if (running === null) return;
const agentName = statusAgent.agentDisplayName;
if (running) {
console.log(` ${agentName}: ${G}running${R}`);
printDashboardRemoteAccessHint(sandboxName);

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add the required documentation update before handoff.

This PR changes the user-visible output of nemoclaw <sandbox> status. Update the affected CLI documentation, validate it, and obtain the required independent documentation-writer review.

As per coding guidelines, user-visible behavior changes require updated, validated documentation and independent documentation-writer review before final handoff.

🤖 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/status-text.ts` around lines 382 - 400, Update the
CLI documentation for the user-visible `nemoclaw <sandbox> status` output
introduced by `printDashboardRemoteAccessHint`, including the SSH remote-access
guidance and `dashboard-url` command. Validate the documentation using the
project’s established process and obtain the required independent
documentation-writer review before handoff.

Source: Coding guidelines


🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Quote sandboxName in the copy-pastable command.

Line [389] inserts sandboxName without shell quoting. A name such as alpha's box or a name with spaces produces an invalid command or multiple arguments. The existing src/lib/actions/sandbox/status-flow.test.ts exercises such names and expects shell-quoted commands at Line [70] through Line [72]. Reuse the existing shell-quoting helper here.

Proposed fix
-    `      Remote access: run \`${CLI_NAME} ${sandboxName} dashboard-url\` for SSH port-forward instructions.`,
+    `      Remote access: run \`${CLI_NAME} ${shellQuote(sandboxName)} dashboard-url\` for SSH port-forward instructions.`,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// On an SSH session the loopback-only dashboard needs a port forward to reach
// from the operator's workstation. `status` does not print the dashboard URL,
// so point to `dashboard-url`, which renders the copy-pastable `ssh -L` block.
// This extends the #5925 remote-access guidance to the status surface (#8465).
function printDashboardRemoteAccessHint(sandboxName: string): void {
if (!isSshSession()) return;
console.log(
` Remote access: run \`${CLI_NAME} ${sandboxName} dashboard-url\` for SSH port-forward instructions.`,
);
}
async function printGatewayProcessStatus(context: SandboxStatusTextContext): Promise<void> {
const { sandboxName, statusAgent } = context;
const running = await isSandboxGatewayRunningForStatus(sandboxName);
if (running === null) return;
const agentName = statusAgent.agentDisplayName;
if (running) {
console.log(` ${agentName}: ${G}running${R}`);
printDashboardRemoteAccessHint(sandboxName);
// On an SSH session the loopback-only dashboard needs a port forward to reach
// from the operator's workstation. `status` does not print the dashboard URL,
// so point to `dashboard-url`, which renders the copy-pastable `ssh -L` block.
// This extends the `#5925` remote-access guidance to the status surface (`#8465`).
function printDashboardRemoteAccessHint(sandboxName: string): void {
if (!isSshSession()) return;
console.log(
` Remote access: run \`${CLI_NAME} ${shellQuote(sandboxName)} dashboard-url\` for SSH port-forward instructions.`,
);
}
async function printGatewayProcessStatus(context: SandboxStatusTextContext): Promise<void> {
const { sandboxName, statusAgent } = context;
const running = await isSandboxGatewayRunningForStatus(sandboxName);
if (running === null) return;
const agentName = statusAgent.agentDisplayName;
if (running) {
console.log(` ${agentName}: ${G}running${R}`);
printDashboardRemoteAccessHint(sandboxName);
🤖 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/status-text.ts` around lines 382 - 400, Update
printDashboardRemoteAccessHint to shell-quote sandboxName when constructing the
dashboard-url command, reusing the existing shell-quoting helper used by the
status flow tests. Preserve the current SSH-only hint and message while ensuring
names containing spaces or apostrophes remain valid copy-pastable commands.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Failed

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

2 semantic terminology decisions

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

  • established — Remote access at src/lib/actions/sandbox/status-text.ts:389: Keep `Remote access`; existing dashboard and documentation text uses this concept consistently.
  • established — SSH port-forward at src/lib/actions/sandbox/status-text.ts:389: Keep `SSH port-forward`; it specifies the existing `port forward` term for the SSH transport.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

Recommended E2E: onboard-repair, onboard-resume

1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Do not promise port-forward instructions for routable dashboards

  • Location: src/lib/actions/sandbox/status-text.ts:389
  • Category: correctness
  • Problem: The SSH-only status hint always says that `dashboard-url` provides SSH port-forward instructions. The command suppresses its forwarding block when the resolved dashboard URL is non-loopback, so the hint is false for the supported remote dashboard bind.
  • Impact: Operators of a supported routable dashboard can be directed to instructions that are absent, leaving status output misleading at the remote-access decision point.
  • Recommendation: Either pass the dashboard access URL through the status rendering path and show this hint only when a forward is required, or change the status text to point to `dashboard-url` without claiming it renders port-forward instructions.
  • Verification: Read `buildSshForwardHintLines` and invoke the existing dashboard-url unit path with an SSH environment and a non-loopback access URL; it emits the URL without a forwarding block.
  • Test coverage: Add a status-flow test for an SSH session with a routable dashboard access URL. Assert that status omits the forwarding-specific hint, or assert the revised generic `dashboard-url` text.
  • Evidence: src/lib/actions/sandbox/status-text.ts:387-390 prints the port-forward-instructions claim whenever an SSH session and running gateway are detected. src/lib/dashboard-url-command.ts:137-143 delegates hint applicability to `buildSshForwardHintLines`. src/lib/onboard/ssh-forward-hint.ts:90-94 returns no hint when the access URL does not need a forward. src/lib/dashboard-url-command.ts:173-181 and :200-209 pass the resolved access URL to that helper.

Workflow run details

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

@jason-ma-nv

Copy link
Copy Markdown
Collaborator Author

Superseded by #8528. This PR's branch fell behind main and I needed to add the CodeRabbit-requested documentation update (docs/deployment/deploy-to-headless-server.mdx); rebasing to keep the growth guardrail's file set clean rewrote history, and repo rules block force-push, so #8528 carries the same status fix plus the doc update on a branch freshly based on current main.

@jason-ma-nv jason-ma-nv closed this Aug 7, 2026
@jason-ma-nv
jason-ma-nv deleted the fix/8465-status-ssh-remote-access-hint-v2 branch August 7, 2026 04:50
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.

[Ubuntu 24.04][CLI&UX] nemoclaw status omits SSH remote-access guidance

1 participant