feat(cli): add gateway-token command to retrieve sandbox auth token#2496
feat(cli): add gateway-token command to retrieve sandbox auth token#2496
Conversation
Add `nemoclaw <name> gateway-token` so automation can capture the OpenClaw gateway auth token after onboarding without scraping `/sandbox/.openclaw/openclaw.json` by hand. Output contract is pipe-friendly: - stdout: token only, no surrounding text - stderr: one-line security warning, suppressed by `--quiet` / `-q` - exit 0: token printed; exit 1: token unavailable, with diagnostics The command reuses the existing host-side helper `fetchGatewayAuthTokenFromSandbox` from `src/lib/onboard.ts` instead of duplicating token retrieval logic. Closes #938
📝 WalkthroughWalkthroughAdds a new CLI command Changes
Sequence DiagramsequenceDiagram
participant User as CLI User
participant CLI as nemoclaw.ts
participant Parser as gateway-token-command.ts (parse)
participant Runner as gateway-token-command.ts (run)
participant Registry as command-registry
participant Fetcher as onboard.ts (fetchGatewayAuthTokenFromSandbox)
participant Stdout as stdout
participant Stderr as stderr
User->>CLI: nemoclaw <name> gateway-token [--quiet]
CLI->>Parser: parseGatewayTokenArgs(args)
Parser-->>CLI: { options, unknown }
alt unknown flags
CLI->>Stderr: Print "Unknown flag" + Usage
CLI-->>User: Exit 1
else valid
CLI->>Runner: runGatewayTokenCommand(name, options, deps)
Runner->>Registry: lookup sandbox
alt sandbox missing
Runner->>Stderr: Diagnostic lines (sandbox not registered)
Runner-->>CLI: Exit 1
else sandbox found
Runner->>Fetcher: fetchGatewayAuthTokenFromSandbox(sandbox)
Fetcher-->>Runner: token or null/empty/error
alt token present
Runner->>Stdout: Print token (only)
alt not options.quiet
Runner->>Stderr: Print one-line security warning
end
Runner-->>CLI: Exit 0
else token absent/error
Runner->>Stderr: Two diagnostic lines (could not retrieve + status hint)
Runner-->>CLI: Exit 1
end
end
end
CLI-->>User: exit code
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
docs/reference/commands.md (1)
301-303: Use active voice and inline code for stream names.Please rewrite these lines in active voice and format
stdout/stderras inline code.As per coding guidelines, "Active voice required. Flag passive constructions." and "CLI commands, file paths, flags, parameter names, and values must use inline
codeformatting."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/reference/commands.md` around lines 301 - 303, Rewrite the three sentences using active voice and format the stream names and flags as inline code: change "The token is written to stdout with no surrounding text." to something like "Write the token to `stdout` with no surrounding text."; change "A one-line security warning is written to stderr; pass `--quiet` (or `-q`) to suppress it." to an active form like "Write a one-line security warning to `stderr`; pass `--quiet` (or `-q`) to suppress it."; and change "The command exits non-zero with a diagnostic on stderr when the sandbox is not registered or when the token cannot be retrieved (for example, if the sandbox is not running)." to an active form that formats the stream inline, e.g. "Exit with a non-zero status and write a diagnostic to `stderr` when the sandbox is not registered or when the token cannot be retrieved (for example, if the sandbox is not running)." Ensure `stdout` and `stderr` and the flags remain inline code.src/nemoclaw.ts (1)
3705-3708: Surface all unknown arguments in one diagnostic.You currently report only the first unknown token. Printing all unknown inputs makes scripted failures easier to debug.
♻️ Proposed tweak
- if (gatewayTokenUnknown.length > 0) { - console.error(` Unknown flag: ${gatewayTokenUnknown[0]}`); + if (gatewayTokenUnknown.length > 0) { + console.error(` Unknown argument(s): ${gatewayTokenUnknown.join(", ")}`); console.error(" Usage: nemoclaw <name> gateway-token [--quiet|-q]"); process.exit(1); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/nemoclaw.ts` around lines 3705 - 3708, The current handler prints only the first unknown token (gatewayTokenUnknown[0]); update the block that checks gatewayTokenUnknown in src/nemoclaw.ts to surface all unknown arguments by joining or iterating gatewayTokenUnknown (e.g., gatewayTokenUnknown.join(', ') or loop and print each) when logging the error, keep the same usage message and exit call (process.exit(1)), and ensure you reference the gatewayTokenUnknown variable and the surrounding conditional that currently prints the single token so the diagnostics show every unknown input.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@docs/reference/commands.md`:
- Around line 301-303: Rewrite the three sentences using active voice and format
the stream names and flags as inline code: change "The token is written to
stdout with no surrounding text." to something like "Write the token to `stdout`
with no surrounding text."; change "A one-line security warning is written to
stderr; pass `--quiet` (or `-q`) to suppress it." to an active form like "Write
a one-line security warning to `stderr`; pass `--quiet` (or `-q`) to suppress
it."; and change "The command exits non-zero with a diagnostic on stderr when
the sandbox is not registered or when the token cannot be retrieved (for
example, if the sandbox is not running)." to an active form that formats the
stream inline, e.g. "Exit with a non-zero status and write a diagnostic to
`stderr` when the sandbox is not registered or when the token cannot be
retrieved (for example, if the sandbox is not running)." Ensure `stdout` and
`stderr` and the flags remain inline code.
In `@src/nemoclaw.ts`:
- Around line 3705-3708: The current handler prints only the first unknown token
(gatewayTokenUnknown[0]); update the block that checks gatewayTokenUnknown in
src/nemoclaw.ts to surface all unknown arguments by joining or iterating
gatewayTokenUnknown (e.g., gatewayTokenUnknown.join(', ') or loop and print
each) when logging the error, keep the same usage message and exit call
(process.exit(1)), and ensure you reference the gatewayTokenUnknown variable and
the surrounding conditional that currently prints the single token so the
diagnostics show every unknown input.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: f01a78f1-d7b4-4ad8-a490-539c13e0590d
📒 Files selected for processing (8)
.agents/skills/nemoclaw-user-reference/references/commands.mddocs/reference/commands.mdsrc/lib/command-registry.test.tssrc/lib/command-registry.tssrc/lib/gateway-token-command.test.tssrc/lib/gateway-token-command.tssrc/lib/onboard.tssrc/nemoclaw.ts
- Drop the now-redundant `getSandbox` dependency. The upstream sandbox dispatch (`recoverRegistryEntries` + "does not exist" guard) already rejects unknown sandbox names before the action switch is reached, so the in-command check was dead code and only added a latent unbound-`this` risk by passing `registry.getSandbox` as a callback. - Silence EPIPE on stdout so consumers like `... | head -c 0` don't see a Node stack trace after the token has already been written. - Use ASCII `--` instead of an em-dash in the stderr security warning so it renders cleanly on legacy Windows consoles. No functional change for the documented happy path; the unknown-sandbox path now relies entirely on the upstream guard, which prints the same "Sandbox 'X' does not exist" message used by every other sandbox subcommand.
## Summary Refreshes user-facing docs for the last 24 hours of merged NemoClaw history and bumps the docs metadata to 0.0.29, the next version after v0.0.28. The updates are limited to behavior supported by merged PR descriptions and diffs. ## Changes - `docs/reference/commands.md`: documented `nemoclaw <name> policy-add --from-file` and `--from-dir`, including custom preset review guidance, from #2077 / commit `7720b175`. - `docs/deployment/deploy-to-remote-gpu.md`: clarified that non-loopback `CHAT_UI_URL` disables OpenClaw device pairing for remote browser-only deployments, from #2449 / commit `f5ee8a4d`. - `docs/inference/inference-options.md`: documented provider-aware credential retry validation and the NVIDIA-only `nvapi-` prefix check, from #2389 / commit `6f7f0c6d`. - `docs/inference/switch-inference-providers.md`: documented `NEMOCLAW_INFERENCE_INPUTS` for text/image-capable model metadata baked into `openclaw.json`, from #2441 / commit `f4391892`. - `docs/reference/troubleshooting.md`: added the Git certificate verification entry for proxy CA propagation through `GIT_SSL_CAINFO`, `GIT_SSL_CAPATH`, `CURL_CA_BUNDLE`, and `REQUESTS_CA_BUNDLE`, from #2345 / commit `fa0dc1ab`. - `docs/versions1.json` and `docs/project.json`: promoted docs version `0.0.29`; `docs/versions1.json` omits unpublished `0.0.26`, `0.0.27`, and `0.0.28` entries. - `.agents/skills/nemoclaw-user-*`: regenerated derived user skill references from the updated docs. - Reviewed with no extra doc changes: #2575 / `d392ec07`, #2565 / `a3231049`, #1965 / `db1ef3ca`, #1990 / `db665834`, #2495 / `7da86fa3`, #2496 / `3192f4f4`, #2490 / `8c209058`, #2487 / `1f615e2f`, #2483 / `5653d33a`, #2482 / `31c782c0`, #2464 / `23bb5703`, #2472 / `a54f9a34`, and #2437 / `6bc860d7`. - Skipped per docs policy: #2420 / `7b76df6b` touched the experimental sandbox config path listed in `docs/.docs-skip`; #2466 / `cc15689c` touched a skipped term and CI-only sandbox image files. ## 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) ## Verification <!-- Check each item you ran and confirmed. Leave unchecked items you skipped. --> - [x] `npx prek run --all-files` passes - [ ] `npm test` passes — failed locally in installer-integration tests and one onboard helper timeout; the doc-scoped hook test projects passed under `prek`. - [ ] 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 - [ ] `make docs` builds without warnings (doc changes only) — build succeeded, but local Sphinx emitted the existing version-switcher file read message. - [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) ## AI Disclosure <!-- If an AI agent authored or co-authored this PR, check the box and name the tool. Remove this section for fully human-authored PRs. --> - [x] AI-assisted — tool: Codex --- <!-- DCO sign-off required by CI. Run: git config user.name && git config user.email --> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Support for custom YAML presets in policy configuration via --from-file and --from-dir. * New build-time inference input option to declare accepted modalities (text or text,image). * **Improvements** * Credential validation now offers interactive recovery: re-enter key, retry, choose another provider, or exit. * Clarified provider-specific API key prefix handling (nvapi- only applies to NVIDIA keys). * **Documentation** * TLS certificate troubleshooting for inspected networks. * Clarified remote dashboard security/device-pairing behavior; command docs updated; docs version bumped. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
Summary
Add
nemoclaw <name> gateway-tokenso automation can capture the OpenClaw gateway auth token after onboarding without scraping/sandbox/.openclaw/openclaw.jsonby hand.Related Issue
Closes #938
Changes
src/lib/gateway-token-command.tswith a host-side handler that takes afetchTokendependency plus log/error sinks, keeping it unit-testable in isolation.fetchGatewayAuthTokenFromSandboxfromsrc/lib/onboard.ts(now exported) instead of duplicating token retrieval.src/nemoclaw.tsdispatch, parse--quiet/-q, reject unknown flags, and silence EPIPE on stdout so consumers like... | head -c 0don't see a Node stack trace after the token has been written.src/lib/command-registry.tsso it appears innemoclaw --helpautomatically.docs/reference/commands.md(skill page regenerated by the doc-to-skills hook).src/lib/gateway-token-command.test.tscovering the success path,--quiet, fetch returning null, fetch throwing, and empty-string token.Output contract:
--quiet/-q.Example:
Review Follow-ups
After the initial commit, an adversarial code review surfaced several issues. Addressed in commit
925673ec:getSandboxcheck + latent unbound-thisrisk — the upstreamrecoverRegistryEntriesguard atsrc/nemoclaw.ts:3651already rejects unknown sandbox names before the action switch is reached, so the in-command "not registered" branch was unreachable from the CLI. Dropped the dependency entirely; the unknown-sandbox path now relies on the same guard every other sandbox subcommand uses.nemoclaw foo gateway-token | head -c 0no longer emits a Node stack trace after the token has been written.--— the stderr security warning now uses ASCII so it renders cleanly on legacy Windows consoles.Considered and explicitly skipped, with reasoning:
--printflag — issue Add CLI command to retrieve gateway auth token #938 carves out two commands:opento minimize TTY exposure, andgateway-tokenfor the scripting use case. Adding TTY refusal here would depart from the issue's design.--helpflag for the subcommand — no other sandbox subcommand accepts--help; matching convention.fetchGatewayAuthTokenFromSandboxswallows every failure tonulltoday, so there is nothing to surface without a deeper refactor of the helper. Out of scope.Type of Change
Verification
npm run typecheck:clipassesnpx vitest run --project clipasses for all tests except the four pre-existing slow-timeout flakes intest/onboard.test.ts(5 s timeout vs 7–12 s actual on slow hardware) that also fail on clean main and are unrelated to this changenpx prek run --all-filespasses apart from the same pre-existingtest/onboard.test.tsflakesSummary by CodeRabbit
New Features
nemoclaw <name> gateway-tokenCLI command to output a sandbox's OpenClaw gateway auth token to stdout; emits a one-line security warning to stderr unless suppressed with--quiet/-q; exits non-zero with diagnostics on failure.Documentation
Tests