Skip to content

feat(onboard): print Control UI chat URLs with embedded gateway token#906

Merged
cv merged 1 commit intoNVIDIA:mainfrom
HagegeR:feat/control-ui-urls
Mar 25, 2026
Merged

feat(onboard): print Control UI chat URLs with embedded gateway token#906
cv merged 1 commit intoNVIDIA:mainfrom
HagegeR:feat/control-ui-urls

Conversation

@HagegeR
Copy link
Copy Markdown
Contributor

@HagegeR HagegeR commented Mar 25, 2026

Summary

After onboard completes, print clickable Control UI URLs that include the gateway auth token so users can copy-paste them directly into a browser (port-forwarded). When the token download fails, fall back to manual instructions.

Related Issue

Related to #20 — this PR complements the remote dashboard access fix by providing token-embedded URLs that work over SSH port-forwarding. See also #114 which addresses the gateway binding side.

Changes

  • bin/lib/onboard.js:
    • Add CONTROL_UI_PORT / CONTROL_UI_CHAT_PATH constants
    • Add findOpenclawJsonPath() — recursive search for openclaw.json in download dir
    • Add fetchGatewayAuthTokenFromSandbox() — downloads openclaw.json from the sandbox to extract gateway.auth.token
    • Add buildControlUiChatUrls() — generates http://127.0.0.1 and http://localhost URLs with #token= hash
    • Update printDashboard() — show Control UI URLs with embedded token, or fallback instructions

Type of Change

  • New feature (non-breaking change that adds functionality)

Testing

  • npx prek run --all-files passes
  • npm test passes
  • Manual testing: onboard prints Control UI URLs when sandbox has a gateway token

Checklist

General

  • I have read the CONTRIBUTING doc.
  • I have signed my commits (git log --show-signature).

Code Changes

  • Formatters applied — npx prek run --all-files auto-fixes formatting.
  • No secrets, API keys, or credentials committed.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

Added logic to the onboarding process that retrieves a gateway authentication token from the sandbox by downloading and parsing openclaw.json, then embeds this token into Control UI chat URLs displayed in the dashboard. Includes fallback instructions when token retrieval fails.

Changes

Cohort / File(s) Summary
Onboarding Token Integration
bin/lib/onboard.js
Added token-fetching helper to download openclaw.json from sandbox, recursively locate the file, and extract cfg.gateway.auth.token. Updated printDashboard() to embed token in Control UI URLs with #token=<token> format; added fallback messaging with manual retrieval instructions when token unavailable.

Sequence Diagram

sequenceDiagram
    participant Onboard as Onboarding Process
    participant OpenShell as openshell CLI
    participant Sandbox as Sandbox
    participant Parser as JSON Parser
    participant Dashboard as Dashboard

    Onboard->>OpenShell: sandbox download
    OpenShell->>Sandbox: Request openclaw.json
    Sandbox-->>OpenShell: Download files
    OpenShell-->>Onboard: Return download output
    
    Onboard->>Parser: Recursively locate openclaw.json
    Parser-->>Onboard: File path found
    
    Onboard->>Parser: Extract cfg.gateway.auth.token
    Parser-->>Onboard: Token value (or null on failure)
    
    alt Token Retrieved
        Onboard->>Dashboard: Pass token to printDashboard()
        Dashboard->>Dashboard: Generate URLs with `#token`=<token>
        Dashboard-->>Onboard: Display Control UI URLs
    else Token Unavailable
        Onboard->>Dashboard: Pass null token
        Dashboard->>Dashboard: Generate fallback URL
        Dashboard-->>Onboard: Display fallback URL + manual retrieval instructions
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A token hops from sandbox deep,
Tucked in JSON, secrets to keep,
The dashboard links now glow so bright,
With auth embedded—pure delight!
When tokens hide, we leave a map,
For humans to close the gap. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding Control UI chat URLs with embedded gateway tokens to the onboarding output.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

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

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@bin/lib/onboard.js`:
- Around line 2187-2200: The function buildControlUiChatUrls embeds the raw
token into the URL fragment, which can produce malformed URLs when the token
contains special characters; update the logic in buildControlUiChatUrls to
URL-encode the token (use encodeURIComponent on token before constructing
hash/pathChat) so the fragment becomes `#token=<encoded>` and all constructed
URLs use this encoded token (keep references to CONTROL_UI_CHAT_PATH,
CONTROL_UI_PORT and the chatUi handling intact).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c88cdc80-206d-463d-a93f-9741fa09da0e

📥 Commits

Reviewing files that changed from the base of the PR and between 0ef5dd2 and c9e5324.

📒 Files selected for processing (1)
  • bin/lib/onboard.js

Comment thread bin/lib/onboard.js
Comment on lines +2187 to +2200
function buildControlUiChatUrls(token) {
const hash = token ? `#token=${token}` : "";
const pathChat = `${CONTROL_UI_CHAT_PATH}${hash}`;
const bases = [
`http://127.0.0.1:${CONTROL_UI_PORT}`,
`http://localhost:${CONTROL_UI_PORT}`,
];
const chatUi = (process.env.CHAT_UI_URL || "").trim().replace(/\/$/, "");
const urls = bases.map((b) => `${b}${pathChat}`);
if (chatUi && /^https?:\/\//i.test(chatUi) && !bases.includes(chatUi)) {
urls.push(`${chatUi}${pathChat}`);
}
return [...new Set(urls)];
}
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 25, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

URL-encode the token before embedding in the URL fragment.

If the gateway token contains URL-special characters (#, ?, &, =, spaces, etc.), the resulting URL will be malformed. Use encodeURIComponent() to ensure the token is safely embedded.

🔧 Proposed fix
 function buildControlUiChatUrls(token) {
-  const hash = token ? `#token=${token}` : "";
+  const hash = token ? `#token=${encodeURIComponent(token)}` : "";
   const pathChat = `${CONTROL_UI_CHAT_PATH}${hash}`;
📝 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
function buildControlUiChatUrls(token) {
const hash = token ? `#token=${token}` : "";
const pathChat = `${CONTROL_UI_CHAT_PATH}${hash}`;
const bases = [
`http://127.0.0.1:${CONTROL_UI_PORT}`,
`http://localhost:${CONTROL_UI_PORT}`,
];
const chatUi = (process.env.CHAT_UI_URL || "").trim().replace(/\/$/, "");
const urls = bases.map((b) => `${b}${pathChat}`);
if (chatUi && /^https?:\/\//i.test(chatUi) && !bases.includes(chatUi)) {
urls.push(`${chatUi}${pathChat}`);
}
return [...new Set(urls)];
}
function buildControlUiChatUrls(token) {
const hash = token ? `#token=${encodeURIComponent(token)}` : "";
const pathChat = `${CONTROL_UI_CHAT_PATH}${hash}`;
const bases = [
`http://127.0.0.1:${CONTROL_UI_PORT}`,
`http://localhost:${CONTROL_UI_PORT}`,
];
const chatUi = (process.env.CHAT_UI_URL || "").trim().replace(/\/$/, "");
const urls = bases.map((b) => `${b}${pathChat}`);
if (chatUi && /^https?:\/\//i.test(chatUi) && !bases.includes(chatUi)) {
urls.push(`${chatUi}${pathChat}`);
}
return [...new Set(urls)];
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 2187 - 2200, The function
buildControlUiChatUrls embeds the raw token into the URL fragment, which can
produce malformed URLs when the token contains special characters; update the
logic in buildControlUiChatUrls to URL-encode the token (use encodeURIComponent
on token before constructing hash/pathChat) so the fragment becomes
`#token=<encoded>` and all constructed URLs use this encoded token (keep
references to CONTROL_UI_CHAT_PATH, CONTROL_UI_PORT and the chatUi handling
intact).

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.

@HagegeR confirm this either cannot be an issue or let's encodeURIComponent

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.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't know how the token is generated, but it worked for my use case, we can try, but it might be overkill

@cv
Copy link
Copy Markdown
Contributor

cv commented Mar 25, 2026

Pretty neat UX!

@cv cv merged commit ce7f1ea into NVIDIA:main Mar 25, 2026
9 of 10 checks passed
lakamsani pushed a commit to lakamsani/NemoClaw that referenced this pull request Apr 4, 2026
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.

3 participants