Skip to content

refactor(cli): migrate commands to shared oclif base#3611

Merged
cv merged 7 commits into
mainfrom
refactor/oclif-shared-command-base
May 15, 2026
Merged

refactor(cli): migrate commands to shared oclif base#3611
cv merged 7 commits into
mainfrom
refactor/oclif-shared-command-base

Conversation

@cv
Copy link
Copy Markdown
Collaborator

@cv cv commented May 15, 2026

Summary

Migrates the remaining oclif command classes onto NemoClawCommand so CLI-wide parser and output conventions have a single base class. Adds a metadata guard that loads every discovered oclif command and fails if any command bypasses the shared NemoClaw base.

Changes

  • Migrated global, compatibility, credentials, tunnel, onboarding, and debug commands to NemoClawCommand.
  • Migrated sandbox inspection, recovery, mutation, nested feature, and internal commands to NemoClawCommand.
  • Added an oclif metadata test that verifies every discovered command extends the shared NemoClaw oclif base.

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: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

Release Notes

  • Refactor
    • Updated internal command infrastructure to improve code organization and maintainability. All command functionality remains unchanged.

Review Change Stack

@cv cv self-assigned this May 15, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

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: b2bca65a-a586-46a5-b3dc-b14c3f2af696

📥 Commits

Reviewing files that changed from the base of the PR and between da1ad74 and d17c6c7.

📒 Files selected for processing (52)
  • src/commands/internal/dns/fix-coredns.ts
  • src/commands/internal/dns/setup-proxy.ts
  • src/commands/internal/installer/normalize-env.ts
  • src/commands/internal/installer/plan.ts
  • src/commands/internal/installer/resolve-release-tag.ts
  • src/commands/internal/uninstall/classify-shim.ts
  • src/commands/internal/uninstall/plan.ts
  • src/commands/internal/uninstall/run-plan.ts
  • src/lib/cli/oclif-command-metadata.test.ts
  • src/lib/commands/credentials.ts
  • src/lib/commands/credentials/list.ts
  • src/lib/commands/credentials/reset.ts
  • src/lib/commands/debug.ts
  • src/lib/commands/deploy.ts
  • src/lib/commands/deprecated/start.ts
  • src/lib/commands/deprecated/stop.ts
  • src/lib/commands/gateway-token.ts
  • src/lib/commands/onboard.ts
  • src/lib/commands/sandbox/channels/add.ts
  • src/lib/commands/sandbox/channels/list.ts
  • src/lib/commands/sandbox/channels/remove.ts
  • src/lib/commands/sandbox/channels/start.ts
  • src/lib/commands/sandbox/channels/stop.ts
  • src/lib/commands/sandbox/config/get.ts
  • src/lib/commands/sandbox/config/set.ts
  • src/lib/commands/sandbox/connect.ts
  • src/lib/commands/sandbox/doctor.ts
  • src/lib/commands/sandbox/hosts/add.ts
  • src/lib/commands/sandbox/hosts/list.ts
  • src/lib/commands/sandbox/hosts/remove.ts
  • src/lib/commands/sandbox/logs.ts
  • src/lib/commands/sandbox/policy/add.ts
  • src/lib/commands/sandbox/policy/list.ts
  • src/lib/commands/sandbox/policy/remove.ts
  • src/lib/commands/sandbox/share.ts
  • src/lib/commands/sandbox/share/mount.ts
  • src/lib/commands/sandbox/share/status.ts
  • src/lib/commands/sandbox/share/unmount.ts
  • src/lib/commands/sandbox/shields/down.ts
  • src/lib/commands/sandbox/shields/status.ts
  • src/lib/commands/sandbox/shields/up.ts
  • src/lib/commands/sandbox/skill/install.ts
  • src/lib/commands/sandbox/snapshot/create.ts
  • src/lib/commands/sandbox/snapshot/list.ts
  • src/lib/commands/sandbox/snapshot/restore.ts
  • src/lib/commands/sandbox/status.ts
  • src/lib/commands/setup-spark.ts
  • src/lib/commands/setup.ts
  • src/lib/commands/tunnel/start.ts
  • src/lib/commands/tunnel/stop.ts
  • src/lib/commands/uninstall.ts
  • src/lib/recover-cli-command.ts

📝 Walkthrough

Walkthrough

All CLI command classes are migrated from Oclif's Command base to a shared NemoClawCommand base class. Import statements are updated consistently, and test validation is added to enforce the new inheritance pattern across discovered commands.

Changes

NemoClaw CLI Command Base Class Migration

Layer / File(s) Summary
Test validation for NemoClawCommand inheritance
src/lib/cli/oclif-command-metadata.test.ts
Added helper function extendsNemoClawCommand() to walk prototype chain. Replaced prior metadata statics test with assertion that all discovered commands extend NemoClawCommand.
Internal DNS, installer, uninstall, and deprecated commands
src/commands/internal/dns/fix-coredns.ts, src/commands/internal/dns/setup-proxy.ts, src/commands/internal/installer/normalize-env.ts, src/commands/internal/installer/plan.ts, src/commands/internal/installer/resolve-release-tag.ts, src/commands/internal/uninstall/classify-shim.ts, src/commands/internal/uninstall/plan.ts, src/commands/internal/uninstall/run-plan.ts, src/lib/commands/deprecated/start.ts, src/lib/commands/deprecated/stop.ts
Updated imports to remove Command from @oclif/core and add NemoClawCommand. All command classes updated to extend NemoClawCommand. Runtime behavior and command metadata unchanged.
Core and utility CLI commands
src/lib/commands/credentials.ts, src/lib/commands/credentials/list.ts, src/lib/commands/credentials/reset.ts, src/lib/commands/debug.ts, src/lib/commands/deploy.ts, src/lib/commands/gateway-token.ts, src/lib/commands/onboard.ts, src/lib/commands/setup-spark.ts, src/lib/commands/setup.ts, src/lib/commands/tunnel/start.ts, src/lib/commands/tunnel/stop.ts, src/lib/commands/uninstall.ts, src/lib/recover-cli-command.ts
Credentials, debug, deploy, gateway-token, onboard, setup, tunnel, uninstall, and recovery commands migrated to NemoClawCommand base class with matching import updates. No changes to command registration, flags, or run() behavior.
Sandbox feature commands
src/lib/commands/sandbox/channels/add.ts, src/lib/commands/sandbox/channels/list.ts, src/lib/commands/sandbox/channels/remove.ts, src/lib/commands/sandbox/channels/start.ts, src/lib/commands/sandbox/channels/stop.ts, src/lib/commands/sandbox/config/get.ts, src/lib/commands/sandbox/config/set.ts, src/lib/commands/sandbox/connect.ts, src/lib/commands/sandbox/doctor.ts, src/lib/commands/sandbox/hosts/add.ts, src/lib/commands/sandbox/hosts/list.ts, src/lib/commands/sandbox/hosts/remove.ts, src/lib/commands/sandbox/logs.ts, src/lib/commands/sandbox/policy/add.ts, src/lib/commands/sandbox/policy/list.ts, src/lib/commands/sandbox/policy/remove.ts, src/lib/commands/sandbox/share.ts, src/lib/commands/sandbox/share/mount.ts, src/lib/commands/sandbox/share/status.ts, src/lib/commands/sandbox/share/unmount.ts, src/lib/commands/sandbox/shields/down.ts, src/lib/commands/sandbox/shields/status.ts, src/lib/commands/sandbox/shields/up.ts, src/lib/commands/sandbox/skill/install.ts, src/lib/commands/sandbox/snapshot/create.ts, src/lib/commands/sandbox/snapshot/list.ts, src/lib/commands/sandbox/snapshot/restore.ts, src/lib/commands/sandbox/status.ts
All sandbox subcommands across channels, config, connect, doctor, hosts, logs, policy, share, shields, skill, and snapshot utilities switched to NemoClawCommand inheritance. Imports updated; all command metadata and run() implementations preserved.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#3599: Both PRs are related at the code level by migrating Oclif CLI command classes to the shared NemoClawCommand base, which is a key prerequisite for the tightened legacy/Oclif help routing and alias branding changes in src/nemoclaw.ts/oclif-runner.

Suggested labels

NemoClaw CLI, status: rfr

Suggested reviewers

  • jyaunches
  • ericksoa

🐰 Hoppy migrations hop along with glee,
Forty commands now share one family tree,
From Command to NemoClaw, the refactor's complete,
Your CLI commands are fresh and so neat!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 'refactor(cli): migrate commands to shared oclif base' directly and clearly summarizes the primary change: migrating CLI commands to use a shared base class.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ 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 refactor/oclif-shared-command-base

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.

@github-actions
Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: cloud-onboard-e2e, sandbox-operations-e2e, diagnostics-e2e, network-policy-e2e, shields-config-e2e, snapshot-commands-e2e, channels-stop-start-e2e, tunnel-lifecycle-e2e
Optional E2E: cloud-e2e, credential-sanitization-e2e, runtime-overrides-e2e, macos-e2e

Dispatch hint: cloud-onboard-e2e,sandbox-operations-e2e,diagnostics-e2e,network-policy-e2e,shields-config-e2e,snapshot-commands-e2e,channels-stop-start-e2e,tunnel-lifecycle-e2e

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • cloud-onboard-e2e (high): Validates installer/onboard command paths, policy setup, credential handling, DNS/inference.local readiness, and live sandbox bootstrap after the command base migration.
  • sandbox-operations-e2e (high): Required because many sandbox lifecycle commands now inherit NemoClawCommand, including connect, status, logs, recover, and related operational flows covered by this job.
  • diagnostics-e2e (medium): Covers debug, credentials list/reset, version, and sandbox config diagnostics; these command classes were touched and include credential-safety behavior.
  • network-policy-e2e (medium): Policy add/list/remove commands affect sandbox network security boundaries and were changed to the shared base class.
  • shields-config-e2e (medium): Shields up/down/status and config get/set commands are security-boundary controls; this verifies they still parse and enforce lifecycle behavior on a live sandbox.
  • snapshot-commands-e2e (medium): Snapshot create/list/restore command classes changed and snapshot restore is a real sandbox state lifecycle path.
  • channels-stop-start-e2e (high): Messaging channel start/stop/add/remove/list command classes changed; this is the cheapest existing channel lifecycle regression gate.
  • tunnel-lifecycle-e2e (medium): Tunnel start/stop and deprecated start/stop aliases changed to the shared command base; tunnel lifecycle is a deployment/user-access flow.

Optional E2E

  • cloud-e2e (high): Broad install → onboard → live assistant smoke coverage provides additional confidence that the shared command base did not regress the default OpenClaw user journey.
  • credential-sanitization-e2e (high): Useful adjacent coverage for credential-safe command output and sandbox config/diagnostic flows, but diagnostics-e2e already exercises the directly touched credentials commands.
  • runtime-overrides-e2e (medium): Onboard/setup command parsing changed through the shared base; runtime override coverage is useful if the PR changes global parser/base flag behavior, but it is adjacent rather than primary.
  • macos-e2e (medium): The shared oclif command base is platform-independent, so macOS smoke/build coverage is useful for cross-platform CLI command loading, but Ubuntu live flows are the merge-blocking signal here.

New E2E recommendations

  • uninstall lifecycle (high): The PR touches public uninstall and internal uninstall planning/run-plan commands, but the inspected E2E workflows do not expose an uninstall E2E job; only unit-style uninstall coverage was found. A live host uninstall test would catch parser/base-command regressions and unsafe cleanup behavior.
    • Suggested test: Add an uninstall-lifecycle-e2e job that installs NemoClaw, creates or mocks a sandbox/gateway state, runs nemoclaw uninstall --yes, verifies shims/state cleanup behavior, and confirms protected OpenShell/resources are preserved or removed according to flags.

Dispatch hint

  • Workflow: .github/workflows/nightly-e2e.yaml
  • jobs input: cloud-onboard-e2e,sandbox-operations-e2e,diagnostics-e2e,network-policy-e2e,shields-config-e2e,snapshot-commands-e2e,channels-stop-start-e2e,tunnel-lifecycle-e2e

@cv cv added the v0.0.44 Release target label May 15, 2026
@cv cv enabled auto-merge (squash) May 15, 2026 17:23
@cv cv disabled auto-merge May 15, 2026 17:26
Copy link
Copy Markdown
Contributor

@cjagwani cjagwani left a comment

Choose a reason for hiding this comment

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

Approving. Clean mechanical pass to land the second half of the NemoClawCommand migration started in #3599, plus a self-enforcing guard so this can't silently regress.

What I checked:

  • All 50 command-class edits are the same 3-line pattern (drop Command import, add NemoClawCommand import, swap extends). No file declared a local help flag, so the new baseFlags = { help: Flags.help(...) } on the base is collision-free.
  • src/lib/cli/oclif-command-metadata.test.ts:18-28 loads the oclif config and walks every discovered command's prototype chain — exactly the verifiable goal of the PR.
  • credentials.ts and onboard.ts are risky-area paths but only as thin oclif shells forwarding to existing actions; the run() bodies are unchanged.
  • One drive-by: a stray blank line removed at src/lib/recover-cli-command.ts:4. Under-the-bar.

Nit (non-blocking): the prototype walker matches on current.name === "NemoClawCommand". instanceof NemoClawCommand would be slightly more robust to renames, but the stringly-typed match avoids a circular import at test-discovery time and is fine.

CI is fully green including test-e2e-sandbox, test-e2e-gateway-isolation, test-e2e-ollama-proxy, and macos-e2e. Ready to merge.

@cv cv merged commit 456a8c8 into main May 15, 2026
29 checks passed
cv added a commit that referenced this pull request May 15, 2026
## Summary
Uses the shared `NemoClawCommand` base for common oclif conventions now
that #3611 has landed. It removes duplicated command-local help flags,
routes internal JSON output through the base helper, and adds a guard so
help stays centralized.

## Changes
- Removed repeated `help: Flags.help({ char: "h" })` declarations now
inherited from `NemoClawCommand.baseFlags`.
- Replaced internal command `console.log(JSON.stringify(..., null, 2))`
calls with `this.logJson(...)`.
- Added an oclif metadata guard that fails when discovered command
classes redeclare a local `help` flag.

## Type of Change
- [x] 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
- [x] `npx prek run --all-files` passes
- [x] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] 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](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

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

Labels

v0.0.44 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants