Skip to content

fix(cli): tighten oclif compatibility routing#3599

Merged
cv merged 5 commits into
mainfrom
fix/oclif-router-boundaries
May 15, 2026
Merged

fix(cli): tighten oclif compatibility routing#3599
cv merged 5 commits into
mainfrom
fix/oclif-router-boundaries

Conversation

@cv

@cv cv commented May 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Tightens the oclif compatibility layer so legacy sandbox help stays side-effect free and native oclif help respects alias branding. This also documents the front-controller boundary, starts migrating parent commands to the shared NemoClaw oclif base, and adds regression coverage for the routing behavior.

Changes

  • Documented src/nemoclaw.ts as the compatibility front controller between public legacy sandbox syntax and oclif-native command IDs.
  • Rendered legacy sandbox-scoped help before registry recovery to avoid starting or repairing services for help-only invocations.
  • Updated native oclif argv dispatch to pass branded package metadata through execute() so nemohermes sandbox ... --help uses the alias binary name.
  • Migrated root and sandbox parent commands to NemoClawCommand.
  • Added regression tests for side-effect-free legacy sandbox help and alias branding in native oclif help.

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

  • New Features

    • Added help flag detection for sandbox action arguments, enabling action-scoped help to render before registry recovery.
  • Refactor

    • Updated core CLI command classes to use the project's custom command base class for improved command handling.
  • Tests

    • Added comprehensive CLI help and dispatch compatibility test suite.

Review Change Stack

@cv cv self-assigned this May 15, 2026
@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Refactored multiple Oclif-based command classes to extend a shared NemoClawCommand base, enhanced runOclifArgv to load and apply branded Oclif configuration before execution, added early help-flag routing in main() to dispatch legacy sandbox help before registry recovery, and added test coverage for CLI compatibility and binary naming.

Changes

CLI Command Inheritance and Oclif Config Branding

Layer / File(s) Summary
Oclif runner config loading and branding
src/lib/cli/oclif-runner.ts, src/lib/cli/oclif-runner.test.ts
runOclifArgv refactored to load OclifConfig from rootDir, apply branded binary metadata via applyBrandedBin(), and invoke executeOclif with loadOptions including the patched pjson. Tests verify Config.load is called with rootDir, execute is called with branded loadOptions, and metadata is consistently applied across config instances.
Command classes inherit from NemoClawCommand
src/lib/commands/root/help.ts, src/lib/commands/root/version.ts, src/lib/commands/sandbox/skill.ts, src/lib/commands/sandbox/snapshot.ts
Four command classes (RootHelpCommand, VersionCommand, SkillCliCommand, SnapshotCommand) changed from extending @oclif/core Command to extending NemoClawCommand, with imports updated and runtime behavior preserved.
Main entry point help-flag routing
src/nemoclaw.ts
Added module documentation describing the file as a compatibility front controller. Introduced hasHelpFlag() helper to detect --help/-h in action arguments. Reworked main() to compute sandboxActions earlier and route action help requests via resolveLegacySandboxDispatch() before registry recovery logic, ensuring legacy help renders before side effects.
CLI compatibility test coverage
test/cli-oclif-compatibility.test.ts
New test file validates that legacy sandbox help renders correctly when auto registry recovery is disabled, asserts validateName is called and recovery is skipped, and verifies the binary alias (nemohermes) appears in help output while the nemoclaw name does not.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

NemoClaw CLI, fix, enhancement: testing, refactor

Suggested reviewers

  • ericksoa
  • prekshivyas
  • cjagwani

Poem

🐰 Commands now share a common base so true,
With Oclif branded when the CLI shines through,
Help flags routed early, no registry dance,
Legacy dispatch gets its proper chance!
NemoClaw hops forward, refactored with care. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: tightening oclif compatibility routing by ensuring legacy sandbox help is side-effect free and preserving alias branding in native oclif help.
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 fix/oclif-router-boundaries

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: sandbox-operations-e2e, snapshot-commands-e2e, skill-agent-e2e
Optional E2E: cloud-e2e, channels-stop-start-e2e

Dispatch hint: sandbox-operations-e2e,snapshot-commands-e2e,skill-agent-e2e

Auto-dispatched E2E: sandbox-operations-e2e, snapshot-commands-e2e, skill-agent-e2e via nightly-e2e.yaml at e5f2efdac5e1ff9772676be1876b3fb6043422acnightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • sandbox-operations-e2e (high): Validates broad legacy sandbox command routing and lifecycle behavior after changes to the public CLI front controller and registry-recovery/help dispatch ordering.
  • snapshot-commands-e2e (medium): Directly covers the touched sandbox:snapshot command by exercising snapshot create/list/restore against a live sandbox.
  • skill-agent-e2e (medium): Directly covers the touched sandbox:skill command and verifies the installed skill is visible to the assistant in a real sandbox/user flow.

Optional E2E

  • cloud-e2e (high): Useful broad smoke for install/onboard, public CLI availability, nemoclaw --help, logs, policy setup, and live inference after CLI entrypoint and oclif runner changes.
  • channels-stop-start-e2e (high): Adjacent confidence because the new compatibility tests focus on sandbox channels start --help and native oclif help branding; this validates the real channels lifecycle, though the PR does not change channel runtime behavior directly.

New E2E recommendations

  • CLI dispatch and help compatibility (medium): Existing E2E coverage appears to validate broad CLI flows but not the specific regression that nemoclaw <missing-sandbox> <sandbox-action> --help must render help without registry recovery or sandbox repair side effects.
    • Suggested test: Add a lightweight cli-dispatch-help-compat-e2e that installs from source, invokes legacy sandbox-scoped help for a missing sandbox, asserts exit/output, and asserts no registry recovery/sandbox creation side effects.
  • Alias launcher branding (low): The PR changes native oclif argv execution to pass branded package metadata, but current coverage for alias binary help appears to be unit/integration only rather than E2E-installed binaries.
    • Suggested test: Add alias-help-branding-e2e covering installed alias launchers such as nemohermes sandbox channels start --help and asserting examples use the alias name, not nemoclaw.

Dispatch hint

  • Workflow: .github/workflows/nightly-e2e.yaml
  • jobs input: sandbox-operations-e2e,snapshot-commands-e2e,skill-agent-e2e

@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.

🧹 Nitpick comments (2)
src/nemoclaw.ts (1)

161-163: ⚡ Quick win

Honor -- when detecting help flags.

This helper now runs before oclif parsing, so treating any later --help/-h as metadata changes normal CLI semantics. A token after -- should stay positional/pass-through instead of short-circuiting into front-controller help.

Suggested change
 function hasHelpFlag(args: readonly string[]): boolean {
-  return args.includes("--help") || args.includes("-h");
+  for (const arg of args) {
+    if (arg === "--") {
+      return false;
+    }
+    if (arg === "--help" || arg === "-h") {
+      return true;
+    }
+  }
+  return false;
 }
🤖 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/nemoclaw.ts` around lines 161 - 163, The hasHelpFlag helper treats any
occurrence of "--help" or "-h" as a help request even if it appears after a "--"
token; update hasHelpFlag to scan args only up to the first "--" (i.e., stop
when you encounter "--") and return true only if "--help" or "-h" appears before
that token so positional/pass-through args after "--" are ignored by the
front-controller help detection.
test/cli-oclif-compatibility.test.ts (1)

111-121: ⚡ Quick win

Make the spawned alias-help check hermetic.

This child inherits NEMOCLAW_DISABLE_AUTO_DISPATCH from the parent environment, which can silently skip the CLI path the test is supposed to cover. Adding a timeout here also prevents a routing regression from hanging the suite indefinitely.

Suggested change
   it("uses the alias binary name in native oclif help", () => {
+    const env = { ...process.env, NO_COLOR: "1" };
+    delete env.NEMOCLAW_DISABLE_AUTO_DISPATCH;
+
     const result = spawnSync(
       process.execPath,
       ["bin/nemohermes.js", "sandbox", "channels", "start", "--help"],
       {
         cwd: process.cwd(),
         encoding: "utf8",
-        env: {
-          ...process.env,
-          NO_COLOR: "1",
-        },
+        env,
+        timeout: 10_000,
       },
     );
🤖 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 `@test/cli-oclif-compatibility.test.ts` around lines 111 - 121, The spawned CLI
test is non-hermetic because the child inherits NEMOCLAW_DISABLE_AUTO_DISPATCH
from the parent and can skip the path under test; update the spawnSync
invocation that assigns result (the call to spawnSync with process.execPath and
["bin/nemohermes.js", "sandbox", "channels", "start", "--help"]) to explicitly
set NEMOCLAW_DISABLE_AUTO_DISPATCH in the env (e.g. "0" or remove it) and add a
timeout (e.g. timeout: 10000) to the spawnSync options so the test cannot hang
indefinitely.
🤖 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.

Nitpick comments:
In `@src/nemoclaw.ts`:
- Around line 161-163: The hasHelpFlag helper treats any occurrence of "--help"
or "-h" as a help request even if it appears after a "--" token; update
hasHelpFlag to scan args only up to the first "--" (i.e., stop when you
encounter "--") and return true only if "--help" or "-h" appears before that
token so positional/pass-through args after "--" are ignored by the
front-controller help detection.

In `@test/cli-oclif-compatibility.test.ts`:
- Around line 111-121: The spawned CLI test is non-hermetic because the child
inherits NEMOCLAW_DISABLE_AUTO_DISPATCH from the parent and can skip the path
under test; update the spawnSync invocation that assigns result (the call to
spawnSync with process.execPath and ["bin/nemohermes.js", "sandbox", "channels",
"start", "--help"]) to explicitly set NEMOCLAW_DISABLE_AUTO_DISPATCH in the env
(e.g. "0" or remove it) and add a timeout (e.g. timeout: 10000) to the spawnSync
options so the test cannot hang indefinitely.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d524d732-04b6-4dbd-acff-3d765ef16c8f

📥 Commits

Reviewing files that changed from the base of the PR and between 40a99e8 and e5f2efd.

📒 Files selected for processing (8)
  • src/lib/cli/oclif-runner.test.ts
  • src/lib/cli/oclif-runner.ts
  • src/lib/commands/root/help.ts
  • src/lib/commands/root/version.ts
  • src/lib/commands/sandbox/skill.ts
  • src/lib/commands/sandbox/snapshot.ts
  • src/nemoclaw.ts
  • test/cli-oclif-compatibility.test.ts

@cv cv enabled auto-merge (squash) May 15, 2026 16:17
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 25927765067
Target ref: e5f2efdac5e1ff9772676be1876b3fb6043422ac
Workflow ref: main
Requested jobs: sandbox-operations-e2e,snapshot-commands-e2e,skill-agent-e2e
Summary: 2 passed, 1 failed, 0 skipped

Job Result
sandbox-operations-e2e ✅ success
skill-agent-e2e ✅ success
snapshot-commands-e2e ❌ failure

Failed jobs: snapshot-commands-e2e. Check run artifacts for logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants