Skip to content

fix(cli): show SSH port-forward hint for remote dashboard access (#5925)#5929

Merged
cv merged 5 commits into
NVIDIA:mainfrom
atulya-singh:fix/5925-ssh-port-forward-hint
Jul 8, 2026
Merged

fix(cli): show SSH port-forward hint for remote dashboard access (#5925)#5929
cv merged 5 commits into
NVIDIA:mainfrom
atulya-singh:fix/5925-ssh-port-forward-hint

Conversation

@atulya-singh

@atulya-singh atulya-singh commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Summary

When NemoClaw runs inside an SSH session, the dashboard URL binds to 127.0.0.1 on the remote host and is unreachable from the operator's workstation browser without a port forward. The post-onboard summary and dashboard-url output now print a copy-pastable ssh -L <port>:127.0.0.1:<port> <user>@<host> example, and the Quickstart and remote-GPU deploy docs cross-reference the same command.

Related Issue

Fixes #5925

Changes

  • Add pure helper src/lib/onboard/ssh-forward-hint.ts:
    • isSshSession() detects SSH_CONNECTION / SSH_CLIENT / SSH_TTY.
    • buildSshForwardHintLines() derives the host from the SSH_CONNECTION server-IP field and the user from USER/LOGNAME, returning a copy-pastable ssh -L block. Returns null outside an SSH session or when the dashboard already binds a routable address (WSL fallback, NEMOCLAW_DASHBOARD_BIND=0.0.0.0). Unsafe usernames fall back to <user>; an unknown host falls back to <host>.
  • src/lib/dashboard-url-command.ts: append the hint to non-quiet output (both token and session-auth paths); suppressed under --quiet so scripted consumers still get exactly one line.
  • src/lib/onboard/dashboard.ts: printDashboard shows the hint in the post-onboard "is ready" summary (covers OpenClaw and agent dashboards).
  • Docs: new "Open the Dashboard When You SSH'd into a Remote Host" subsection in docs/get-started/quickstart.mdx, and a copy-pastable ssh -L command in docs/deployment/deploy-to-remote-gpu.mdx (Remote Dashboard Access).
  • Tests: ssh-forward-hint.test.ts (8 cases) plus 3 new dashboard-url-command.test.ts cases (hint over SSH, absent without SSH, suppressed under --quiet).

The hint only ever references loopback forwarding; it does not suggest binding to 0.0.0.0, and it points to the already-printed dashboard URL rather than reprinting the tokenized URL, so it does not duplicate the secret token.

Type of Change

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

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Atulya Singh atulyarajsingh@gmail.com

Summary by CodeRabbit

  • New Features
    • Added SSH port-forwarding guidance for accessing the dashboard when connected via SSH.
    • Dashboard onboarding and dashboard URL output can now show copy-pastable ssh -L instructions when forwarding is needed.
  • Bug Fixes
    • Dashboard URL output now conditionally includes (or omits) the SSH forwarding hint based on SSH/session context and whether the dashboard URL is loopback-bound; quiet mode remains unchanged.
    • Improved, safer SSH-session detection and sanitization of rendered hint content.
  • Documentation
    • Updated the remote GPU guide and quickstart with local workstation browser and ssh -L examples.
  • Tests
    • Added coverage for SSH hint generation, session detection, and dashboard URL command behavior.

…DIA#5925)

Signed-off-by: Atulya Singh <atulyarajsingh@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3da22a89-1743-4751-897a-ff8cc9737a6a

📥 Commits

Reviewing files that changed from the base of the PR and between f593b57 and ce1f066.

📒 Files selected for processing (2)
  • docs/deployment/deploy-to-remote-gpu.mdx
  • docs/get-started/quickstart.mdx
💤 Files with no reviewable changes (2)
  • docs/get-started/quickstart.mdx
  • docs/deployment/deploy-to-remote-gpu.mdx

📝 Walkthrough

Walkthrough

Adds SSH-session detection and copy-pastable ssh -L hint generation for dashboard access, wires it into dashboard-url and onboarding output, and updates quickstart and deployment docs with matching remote-SSH instructions.

Changes

SSH Port-Forward Hint

Layer / File(s) Summary
SSH hint helper and tests
src/lib/onboard/ssh-forward-hint.ts, src/lib/onboard/ssh-forward-hint.test.ts
New module exports isSshSession and buildSshForwardHintLines, sanitizes user and destination values, checks whether the access URL still needs forwarding, and returns formatted hint lines or null. Tests cover SSH detection, placeholder rendering, sanitization, custom formatting, and non-forwarding cases.
Dashboard URL command output
src/lib/dashboard-url-command.ts, src/lib/dashboard-url-command.test.ts
DashboardUrlCommandDeps gains optional env, a local helper prints SSH hint lines when available, and both the plain URL and token-based paths call it before returning or logging the dashboard URL. Tests cover SSH-session output, session-auth behavior, no-hint output without SSH env, and quiet-mode suppression.
Onboarding dashboard output
src/lib/onboard/dashboard.ts
OnboardDashboardDeps gains optional env, and printDashboard computes SSH hint lines from chain.port and chain.accessUrl before the existing “Manage later” output.
Quickstart and deployment docs
docs/get-started/quickstart.mdx, docs/deployment/deploy-to-remote-gpu.mdx
Quickstart adds a remote-SSH dashboard subsection with loopback binding explanation and an ssh -L example. The deployment guide adds matching remote dashboard port-forwarding instructions and references the CLI output flow.

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

Sequence Diagram(s)

sequenceDiagram
  participant User as SSH user
  participant DashboardUrl as dashboard-url command
  participant Onboard as onboarding output
  participant Hint as buildSshForwardHintLines
  participant Env as process.env
  User->>DashboardUrl: run dashboard-url
  DashboardUrl->>Hint: port, accessUrl, env
  Hint->>Env: read SSH_* and USER
  Hint-->>DashboardUrl: hint lines or null
  DashboardUrl-->>User: dashboard URL + SSH hint

  User->>Onboard: complete onboarding
  Onboard->>Hint: port, accessUrl, env
  Hint-->>Onboard: hint lines or null
  Onboard-->>User: ready block + SSH hint
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% 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 clearly matches the main change: adding SSH port-forward hints for remote dashboard access.
Linked Issues check ✅ Passed The CLI, onboarding output, Quickstart, and remote GPU docs now provide SSH port-forward guidance for remote-SSH users.
Out of Scope Changes check ✅ Passed The added helper, tests, and documentation all support the remote dashboard access fix and stay within scope.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 3

🧹 Nitpick comments (1)
src/lib/dashboard-url-command.test.ts (1)

88-138: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a non-quiet assertion for the session/none branch.

These cases only exercise the tokenized URL path. runDashboardUrlCommand now prints the SSH hint in the plain-URL branch too, but the visible session coverage is still quiet-only, so a regression there would slip through.

🤖 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/dashboard-url-command.test.ts` around lines 88 - 138, The test
coverage for runDashboardUrlCommand is missing a non-quiet assertion for the
plain-URL path when no tokenized session is used, so add a case that exercises
the session/none branch with quiet false and verifies the SSH hint is printed
there too. Update the dashboard URL command tests around runDashboardUrlCommand
and makeSinks to assert the Remote access SSH hint appears in the non-quiet
plain-URL output, while keeping the quiet-mode behavior unchanged.
🤖 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 `@docs/deployment/deploy-to-remote-gpu.mdx`:
- Line 154: Split the combined sentence in the deployment guide into two
separate source lines to follow the one-sentence-per-line MDX rule. Update the
surrounding prose in the deployment section so the first sentence about running
nemoclaw over SSH and the command output stands alone, and the second sentence
about opening the dashboard URL on your workstation is on its own line.

In `@src/lib/onboard/dashboard.ts`:
- Around line 496-499: Pass env explicitly into buildSshForwardHintLines from
this OnboardDashboard flow instead of letting it read process.env implicitly.
Thread env through OnboardDashboardDeps here the same way dashboard-url already
does, and update the call site in the dashboard summary rendering so the SSH
hint stays deterministic and testable. Also make sure any related SSH hint or
detection helpers use the passed env argument rather than ambient shell state.

In `@src/lib/onboard/ssh-forward-hint.ts`:
- Around line 27-37: The helper serverAddressFromSshConnection should not derive
the SSH destination from SSH_CONNECTION, since it only exposes the remote socket
address and loses the original host, port, aliases, and ProxyJump details.
Update the ssh-forward-hint flow to return a placeholder unless the caller can
pass the original destination string explicitly, and keep
serverAddressFromSshConnection limited to fallback behavior rather than
constructing the ssh -L example target.

---

Nitpick comments:
In `@src/lib/dashboard-url-command.test.ts`:
- Around line 88-138: The test coverage for runDashboardUrlCommand is missing a
non-quiet assertion for the plain-URL path when no tokenized session is used, so
add a case that exercises the session/none branch with quiet false and verifies
the SSH hint is printed there too. Update the dashboard URL command tests around
runDashboardUrlCommand and makeSinks to assert the Remote access SSH hint
appears in the non-quiet plain-URL output, while keeping the quiet-mode behavior
unchanged.
🪄 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: e1935265-b6a6-458e-8355-ff9cab336012

📥 Commits

Reviewing files that changed from the base of the PR and between 4db5d5d and 9191002.

📒 Files selected for processing (7)
  • docs/deployment/deploy-to-remote-gpu.mdx
  • docs/get-started/quickstart.mdx
  • src/lib/dashboard-url-command.test.ts
  • src/lib/dashboard-url-command.ts
  • src/lib/onboard/dashboard.ts
  • src/lib/onboard/ssh-forward-hint.test.ts
  • src/lib/onboard/ssh-forward-hint.ts

Comment thread docs/deployment/deploy-to-remote-gpu.mdx Outdated
Comment thread src/lib/onboard/dashboard.ts
Comment thread src/lib/onboard/ssh-forward-hint.ts Outdated
Signed-off-by: Atulya Singh <atulyarajsingh@gmail.com>
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression labels Jun 29, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for adding the SSH port-forward hint for remote dashboard access. This fixes the missing copy-pastable ssh -L example for users running NemoClaw over SSH.


Related open issues:

@cv cv added the v0.0.76 Release target label Jul 7, 2026
cv
cv previously requested changes Jul 7, 2026

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Unresolved correctness issue: SSH_CONNECTION cannot recover the original user-facing destination across aliases, NAT, or ProxyJump, but the current hint presents the inferred socket IP as copy-pastable. Use unless an explicit original destination is supplied, and cover aliased and jump-host scenarios. Required CI and advisor also have not run.

@wscurran wscurran added v0.0.77 Release target and removed v0.0.76 Release target labels Jul 7, 2026
@ericksoa ericksoa added v0.0.78 Release target and removed v0.0.77 Release target labels Jul 8, 2026
Signed-off-by: Atulya Singh <atulyarajsingh@gmail.com>
@atulya-singh

Copy link
Copy Markdown
Contributor Author

@cv thanks — addressed the correctness issue.

What changed

The hint no longer turns SSH_CONNECTION into the SSH destination. As you noted, its server-IP field is just the remote socket address and can't recover the destination the operator actually typed across an ~/.ssh/config alias, NAT, or ProxyJump, so presenting it as copy-pastable was wrong for exactly the sessions this feature targets.

  • Host → <host> placeholder by default. A concrete host is only rendered when an explicit destination is supplied to buildSshForwardHintLines({ destination }); nothing is inferred from SSH_CONNECTION. sshDestinationFromConnection() and the DEFAULT_SSH_PORT constant are removed.
  • Dropped the -p <port> flag — it came from the same untrusted SSH_CONNECTION field and would look authoritative next to a placeholder host.
  • Username is kept (falling back to <user> when missing/unsafe): unlike the host, it's the effective remote login user and stays correct through NAT/ProxyJump. Net render: ssh -L 18790:127.0.0.1:18790 spark@<host>.

Test coverage for aliased / jump-host

Added cases asserting the socket IP never leaks — a NAT'd/aliased direct host and a private bastion-side (ProxyJump) target on a custom port both render spark@<host> with no IP and no -p. Also added explicit-destination-verbatim and unsafe-destination-fallback cases. Removed the now-invalid -p test.

Docs

deploy-to-remote-gpu.mdx no longer claims the CLI prints the "detected host" — it now states the host stays a <host> placeholder you substitute, and why.

Verified locally: ssh-forward-hint + dashboard-url-command suites, the full src/lib/onboard/ CLI suite (1643 passing), npm run typecheck:cli, Biome, and npm run docs (0 errors).

On the CI/advisor note — those required jobs are gated behind copy-pr-bot maintainer vetting and haven't been able to run on this fork PR yet; they should execute once vetted.

@cv cv dismissed their stale review July 8, 2026 16:32

Addressed on current head ce1f066: the hint always uses unless an explicit destination is available, and alias/NAT/ProxyJump regression cases cover the original correctness concern. All 32 checks are green after updating onto current main.

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed exact head ce1f066 after its current-main refresh. The SSH hint no longer infers a copy-pastable destination from SSH_CONNECTION; it uses , preserves explicit destinations, and covers aliases, NAT, ProxyJump, quiet/non-quiet output, and deterministic env injection. All 32 checks are green, DCO and all 4 commits are Verified, CodeRabbit is clear, and no current advisor blocker exists.

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Renewing approval on exact head 4f00992 after the docs-only current-main refresh. The reviewed SSH-destination fix is unchanged; all 30 checks are green, merge state is clean, all 5 commits are Verified, and the exact-head gate passes.

@cv cv merged commit 40a7a84 into NVIDIA:main Jul 8, 2026
30 checks passed
@cjagwani cjagwani mentioned this pull request Jul 9, 2026
21 tasks
cv pushed a commit that referenced this pull request Jul 9, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prepares the user documentation for NemoClaw v0.0.78 by replacing the
unreleased section with release highlights and synchronizing the
affected inference, lifecycle, messaging, and CLI reference pages with
merged behavior.

## Changes

- Publish the v0.0.78 release-notes section with links to the most
specific user guides for each shipped behavior.
- Document authoritative Deep Agents route health, Nemotron Ultra
profile behavior, and Hermes compatible-endpoint context metadata.
- Document forced rebuild recovery after total backup failure and the
ownership-safe tunnel/full-stop behavior.
- Keep command examples and shared agent variants aligned with the
current OpenClaw, Hermes, and Deep Agents interfaces.

Source mapping:

- [#3787](#3787) ->
`docs/about/release-notes.mdx`: Record reliable workspace template
seeding during sandbox startup.
- [#4960](#4960) ->
`docs/about/release-notes.mdx`: Record safer detection of rewritten
OpenClaw gateway processes.
- [#5676](#5676) ->
`docs/about/release-notes.mdx`: Record warning-tolerant agent-list JSON
handling.
- [#5857](#5857) ->
`docs/about/release-notes.mdx`: Record synchronization of explicit
OpenClaw main-agent model state.
- [#5929](#5929) ->
`docs/about/release-notes.mdx`: Record copyable SSH port-forward
guidance for remote dashboards.
- [#6068](#6068) ->
`docs/about/release-notes.mdx`: Record custom-image plugin provenance
reconciliation.
- [#6116](#6116) ->
`docs/about/release-notes.mdx`: Record live-loopback dashboard-forward
recovery.
- [#6122](#6122) ->
`docs/about/release-notes.mdx`: Announce validated, round-trippable
policy YAML output.
- [#6211](#6211) ->
`docs/manage-sandboxes/lifecycle.mdx`, `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Explain the explicit no-backup `rebuild
--force` recovery boundary.
- [#6283](#6283) ->
`docs/about/release-notes.mdx`: Record Hermes WebUI port alignment.
- [#6293](#6293) ->
`docs/inference/switch-inference-providers.mdx`,
`docs/about/release-notes.mdx`: Document compatible-endpoint
context-length probing for Hermes.
- [#6320](#6320) ->
`docs/about/release-notes.mdx`: Record bounded gateway-recovery waits.
- [#6377](#6377) ->
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain
rebuild diagnostics and prepared MCP-destroy recovery.
- [#6412](#6412) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document authoritative agent-visible
inference route health.
- [#6421](#6421) ->
`docs/about/release-notes.mdx`: Record the longer quiet-pull window for
managed vLLM images.
- [#6431](#6431) ->
`docs/inference/model-capability-audit.mdx`,
`docs/about/release-notes.mdx`: Document the version-pinned Nemotron
Ultra profile plugin.
- [#6439](#6439) ->
`docs/about/release-notes.mdx`: Summarize the authenticated, pinned
credential-capture helper boundary.
- [#6450](#6450) ->
`docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document
host-forward cleanup and ownership-safe gateway-port release.
- [#6474](#6474) ->
`docs/manage-sandboxes/messaging-channels.mdx`,
`docs/about/release-notes.mdx`: Record composable OpenClaw messaging
runtime loaders.
- [#6475](#6475) ->
`docs/about/release-notes.mdx`: Record removal of the unavailable Kimi
K2.6 production endpoint option.
- [#6480](#6480) ->
`docs/about/release-notes.mdx`: Record stderr routing for the plugin
registration banner.
- [#6481](#6481) ->
`docs/about/release-notes.mdx`: Record post-pull Ollama model discovery
checks.
- [#6482](#6482) ->
`docs/about/release-notes.mdx`: Record Ollama model warm-up after daemon
restart.
- [#6486](#6486) ->
`docs/about/release-notes.mdx`: Publish the opt-in, thread-scoped Deep
Agents auto-approval boundary.
- [#6490](#6490) ->
`docs/about/release-notes.mdx`: Record diagnostics for custom images
missing the managed runtime.
- [#6494](#6494) ->
`docs/inference/model-capability-audit.mdx`,
`docs/about/release-notes.mdx`: Document nonempty tool-call content
preservation and placeholder rejection.
- [#6497](#6497) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document isolated Deep Agents
route-probe output.
- [#6506](#6506) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document observability-preserving
managed route probes.
- [#6508](#6508) ->
`docs/about/release-notes.mdx`: Link the new extension taxonomy and
SDK-readiness reference from the release summary.

Release-source verification: GitHub reports all 29 cited source PRs as
merged with base `main`, and every merge commit is an ancestor of
`origin/main` at `17bf9a6a9688b3b1d69cf4b37d3f23110acb055e`. No
source-mapping mismatches were found.

## Type of Change

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

## Quality Gates

<!-- Check exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: Documentation-only
release-prep changes; `npm run docs` validates variants, routes, and
Fern content.
- [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:

## Verification

<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed 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: Tests
are not applicable to this documentation-only change set.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — exited
0 with zero errors; Fern reported the existing unauthenticated
redirect-check and light-mode contrast warnings.
- [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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

---------

Signed-off-by: cjagwani <cjagwani@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…DIA#5925) (NVIDIA#5929)

## Summary

When NemoClaw runs inside an SSH session, the dashboard URL binds to
`127.0.0.1` on the remote host and is unreachable from the operator's
workstation browser without a port forward. The post-onboard summary and
`dashboard-url` output now print a copy-pastable `ssh -L
<port>:127.0.0.1:<port> <user>@<host>` example, and the Quickstart and
remote-GPU deploy docs cross-reference the same command.

## Related Issue

Fixes NVIDIA#5925

## Changes

- Add pure helper `src/lib/onboard/ssh-forward-hint.ts`:
- `isSshSession()` detects `SSH_CONNECTION` / `SSH_CLIENT` / `SSH_TTY`.
- `buildSshForwardHintLines()` derives the host from the
`SSH_CONNECTION` server-IP field and the user from `USER`/`LOGNAME`,
returning a copy-pastable `ssh -L` block. Returns `null` outside an SSH
session or when the dashboard already binds a routable address (WSL
fallback, `NEMOCLAW_DASHBOARD_BIND=0.0.0.0`). Unsafe usernames fall back
to `<user>`; an unknown host falls back to `<host>`.
- `src/lib/dashboard-url-command.ts`: append the hint to non-quiet
output (both token and session-auth paths); suppressed under `--quiet`
so scripted consumers still get exactly one line.
- `src/lib/onboard/dashboard.ts`: `printDashboard` shows the hint in the
post-onboard "is ready" summary (covers OpenClaw and agent dashboards).
- Docs: new "Open the Dashboard When You SSH'd into a Remote Host"
subsection in `docs/get-started/quickstart.mdx`, and a copy-pastable
`ssh -L` command in `docs/deployment/deploy-to-remote-gpu.mdx` (Remote
Dashboard Access).
- Tests: `ssh-forward-hint.test.ts` (8 cases) plus 3 new
`dashboard-url-command.test.ts` cases (hint over SSH, absent without
SSH, suppressed under `--quiet`).

The hint only ever references loopback forwarding; it does not suggest
binding to `0.0.0.0`, and it points to the already-printed dashboard URL
rather than reprinting the tokenized URL, so it does not duplicate the
secret token.

## Type of Change

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

## Verification
<!-- Check each item you ran and confirmed. Leave unchecked items you
skipped. Doc-only changes do not require npm test unless you ran it. -->
- [ ] `npx prek run --all-files` passes
- [ ] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [x] Docs updated for user-facing behavior changes
- [x] `make 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)

<!-- Verification notes: targeted checks were run for the changed
surface — `npx vitest run --project cli` for the new helper and
dashboard-url tests, the full `src/lib/onboard/` cli suite (1640
passing), `npm run typecheck:cli`, Biome check, and `npm run docs` (0
errors). The full `npm test`/`prek --all-files` gate was not run green
locally because unrelated subprocess-spawning tests time out under this
sandbox's resource limits (they pass in isolation and are untouched by
this diff); CI provides the authoritative full run. No new doc pages
were added, only existing pages updated. -->

---
Signed-off-by: Atulya Singh <atulyarajsingh@gmail.com>


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

* **New Features**
* Added SSH port-forwarding guidance for accessing the dashboard when
connected via SSH.
* Dashboard onboarding and dashboard URL output can now show
copy-pastable `ssh -L` instructions when forwarding is needed.
* **Bug Fixes**
* Dashboard URL output now conditionally includes (or omits) the SSH
forwarding hint based on SSH/session context and whether the dashboard
URL is loopback-bound; quiet mode remains unchanged.
* Improved, safer SSH-session detection and sanitization of rendered
hint content.
* **Documentation**
* Updated the remote GPU guide and quickstart with local workstation
browser and `ssh -L` examples.
* **Tests**
* Added coverage for SSH hint generation, session detection, and
dashboard URL command behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Atulya Singh <atulyarajsingh@gmail.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prepares the user documentation for NemoClaw v0.0.78 by replacing the
unreleased section with release highlights and synchronizing the
affected inference, lifecycle, messaging, and CLI reference pages with
merged behavior.

## Changes

- Publish the v0.0.78 release-notes section with links to the most
specific user guides for each shipped behavior.
- Document authoritative Deep Agents route health, Nemotron Ultra
profile behavior, and Hermes compatible-endpoint context metadata.
- Document forced rebuild recovery after total backup failure and the
ownership-safe tunnel/full-stop behavior.
- Keep command examples and shared agent variants aligned with the
current OpenClaw, Hermes, and Deep Agents interfaces.

Source mapping:

- [NVIDIA#3787](NVIDIA#3787) ->
`docs/about/release-notes.mdx`: Record reliable workspace template
seeding during sandbox startup.
- [NVIDIA#4960](NVIDIA#4960) ->
`docs/about/release-notes.mdx`: Record safer detection of rewritten
OpenClaw gateway processes.
- [NVIDIA#5676](NVIDIA#5676) ->
`docs/about/release-notes.mdx`: Record warning-tolerant agent-list JSON
handling.
- [NVIDIA#5857](NVIDIA#5857) ->
`docs/about/release-notes.mdx`: Record synchronization of explicit
OpenClaw main-agent model state.
- [NVIDIA#5929](NVIDIA#5929) ->
`docs/about/release-notes.mdx`: Record copyable SSH port-forward
guidance for remote dashboards.
- [NVIDIA#6068](NVIDIA#6068) ->
`docs/about/release-notes.mdx`: Record custom-image plugin provenance
reconciliation.
- [NVIDIA#6116](NVIDIA#6116) ->
`docs/about/release-notes.mdx`: Record live-loopback dashboard-forward
recovery.
- [NVIDIA#6122](NVIDIA#6122) ->
`docs/about/release-notes.mdx`: Announce validated, round-trippable
policy YAML output.
- [NVIDIA#6211](NVIDIA#6211) ->
`docs/manage-sandboxes/lifecycle.mdx`, `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Explain the explicit no-backup `rebuild
--force` recovery boundary.
- [NVIDIA#6283](NVIDIA#6283) ->
`docs/about/release-notes.mdx`: Record Hermes WebUI port alignment.
- [NVIDIA#6293](NVIDIA#6293) ->
`docs/inference/switch-inference-providers.mdx`,
`docs/about/release-notes.mdx`: Document compatible-endpoint
context-length probing for Hermes.
- [NVIDIA#6320](NVIDIA#6320) ->
`docs/about/release-notes.mdx`: Record bounded gateway-recovery waits.
- [NVIDIA#6377](NVIDIA#6377) ->
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain
rebuild diagnostics and prepared MCP-destroy recovery.
- [NVIDIA#6412](NVIDIA#6412) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document authoritative agent-visible
inference route health.
- [NVIDIA#6421](NVIDIA#6421) ->
`docs/about/release-notes.mdx`: Record the longer quiet-pull window for
managed vLLM images.
- [NVIDIA#6431](NVIDIA#6431) ->
`docs/inference/model-capability-audit.mdx`,
`docs/about/release-notes.mdx`: Document the version-pinned Nemotron
Ultra profile plugin.
- [NVIDIA#6439](NVIDIA#6439) ->
`docs/about/release-notes.mdx`: Summarize the authenticated, pinned
credential-capture helper boundary.
- [NVIDIA#6450](NVIDIA#6450) ->
`docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document
host-forward cleanup and ownership-safe gateway-port release.
- [NVIDIA#6474](NVIDIA#6474) ->
`docs/manage-sandboxes/messaging-channels.mdx`,
`docs/about/release-notes.mdx`: Record composable OpenClaw messaging
runtime loaders.
- [NVIDIA#6475](NVIDIA#6475) ->
`docs/about/release-notes.mdx`: Record removal of the unavailable Kimi
K2.6 production endpoint option.
- [NVIDIA#6480](NVIDIA#6480) ->
`docs/about/release-notes.mdx`: Record stderr routing for the plugin
registration banner.
- [NVIDIA#6481](NVIDIA#6481) ->
`docs/about/release-notes.mdx`: Record post-pull Ollama model discovery
checks.
- [NVIDIA#6482](NVIDIA#6482) ->
`docs/about/release-notes.mdx`: Record Ollama model warm-up after daemon
restart.
- [NVIDIA#6486](NVIDIA#6486) ->
`docs/about/release-notes.mdx`: Publish the opt-in, thread-scoped Deep
Agents auto-approval boundary.
- [NVIDIA#6490](NVIDIA#6490) ->
`docs/about/release-notes.mdx`: Record diagnostics for custom images
missing the managed runtime.
- [NVIDIA#6494](NVIDIA#6494) ->
`docs/inference/model-capability-audit.mdx`,
`docs/about/release-notes.mdx`: Document nonempty tool-call content
preservation and placeholder rejection.
- [NVIDIA#6497](NVIDIA#6497) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document isolated Deep Agents
route-probe output.
- [NVIDIA#6506](NVIDIA#6506) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document observability-preserving
managed route probes.
- [NVIDIA#6508](NVIDIA#6508) ->
`docs/about/release-notes.mdx`: Link the new extension taxonomy and
SDK-readiness reference from the release summary.

Release-source verification: GitHub reports all 29 cited source PRs as
merged with base `main`, and every merge commit is an ancestor of
`origin/main` at `17bf9a6a9688b3b1d69cf4b37d3f23110acb055e`. No
source-mapping mismatches were found.

## Type of Change

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

## Quality Gates

<!-- Check exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: Documentation-only
release-prep changes; `npm run docs` validates variants, routes, and
Fern content.
- [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:

## Verification

<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed 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: Tests
are not applicable to this documentation-only change set.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — exited
0 with zero errors; Fern reported the existing unauthenticated
redirect-check and light-mode contrast warnings.
- [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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

---------

Signed-off-by: cjagwani <cjagwani@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression v0.0.78 Release target

Projects

None yet

5 participants