Skip to content

feat(cli): typed command registry as single source of truth (#2388)#2446

Merged
jyaunches merged 7 commits into
mainfrom
issue-2388-typed-command-registry
Apr 24, 2026
Merged

feat(cli): typed command registry as single source of truth (#2388)#2446
jyaunches merged 7 commits into
mainfrom
issue-2388-typed-command-registry

Conversation

@jyaunches

@jyaunches jyaunches commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Create a typed command registry (src/lib/command-registry.ts) as the single source of truth for all 46 NemoClaw CLI commands. Derive help output, dispatch arrays, and docs-parity checking from it, replacing three independent hand-maintained sources. Re-enable the cloud-experimental-e2e nightly job now that the check-docs parity check passes reliably.

Related Issue

Fixes #2388

Changes

  • New src/lib/command-registry.ts: Defines CommandDef interface, CommandGroup union type, and COMMANDS array with all 46 CLI commands (23 global + 23 sandbox). Exports helper functions: globalCommands, sandboxCommands, visibleCommands, commandsByGroup, canonicalUsageList, globalCommandTokens, sandboxActionTokens.
  • New src/lib/command-registry.test.ts: 21 unit tests covering all registry invariants — counts, deduplication, ordering, token extraction, group membership.
  • Rewritten help() in src/nemoclaw.ts: Now iterates commandsByGroup() from registry instead of hand-written console.log lines. Reconfiguration section rewritten with bullet points to prevent phantom nemoclaw-prefixed parser matches.
  • Derived dispatch arrays: GLOBAL_COMMANDS now calls globalCommandTokens() and sandboxActions now calls sandboxActionTokens() — no more hand-maintained sets/arrays.
  • Added --dump-commands internal flag: Prints canonical command list for check-docs.sh parity checks, replacing the fragile perl help-parsing pipeline.
  • Simplified check-docs.sh: Phase 1 now uses --dump-commands instead of perl regex extraction. Phase 2 strips <arg> and [optional] placeholders from doc headings for clean comparison.
  • Added missing doc headings: nemoclaw onboard --from, nemoclaw setup, nemoclaw start, nemoclaw stop in docs/reference/commands.md.
  • Re-enabled cloud-experimental-e2e: Removed DISABLED comment, CLOUD_EXPERIMENTAL_E2E_ENABLED variable gate, and SKIP_CHECK_DOCS flag.
  • Updated test/image-cleanup.test.ts: Adapted to verify gc via registry source instead of regex-matching the old GLOBAL_COMMANDS Set literal.

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)

AI Disclosure

  • AI-assisted — tool: Claude Code (pi agent)

Signed-off-by: Julie Yaunches jyaunches@nvidia.com

Summary by CodeRabbit

  • Documentation

    • Added nemoclaw onboard --from <Dockerfile> usage guide and documented deprecated aliases (nemoclaw start, nemoclaw stop, nemoclaw setup) with warnings.
  • New Features

    • Added a developer-facing --dump-commands option to emit the canonical command list.
  • Improvements

    • Overhauled help/command organization for clearer grouping and more accurate, stable command listings.

…2388)

Create src/lib/command-registry.ts with:
- CommandDef interface and CommandGroup union type
- COMMANDS array with all 46 CLI commands (23 global + 23 sandbox)
- Helper functions: globalCommands, sandboxCommands, visibleCommands,
  commandsByGroup, canonicalUsageList, globalCommandTokens, sandboxActionTokens
- GROUP_ORDER for consistent help display ordering

11 hidden commands (5 help/version aliases + 6 shields/config) are excluded
from help output and canonical list but included in dispatch derivation.

Unit tests cover all invariants: counts, deduplication, ordering, token extraction.
Replace hand-written help() with registry-driven output:
- Import commandsByGroup from command-registry
- Iterate groups in GROUP_ORDER for consistent section ordering
- Apply bold/dim styling for first-in-group and deprecated commands
- Rewrite Reconfiguration section with bullet points to prevent
  phantom nemoclaw-prefixed lines from confusing check-docs.sh

The help output visually matches the previous layout while being
derived entirely from the single source of truth.
…gistry (#2388)

Replace hand-maintained dispatch arrays with registry-derived values:
- GLOBAL_COMMANDS = globalCommandTokens() (was new Set([...]))
- sandboxActions = sandboxActionTokens() (was inline array)
- Update image-cleanup.test.ts to verify gc via registry source
  instead of regex-matching the old Set literal
…ump (#2388)

Phase 4 of the typed command registry:
- Add --dump-commands flag to CLI dispatch (internal developer flag)
- Replace fragile perl help-parsing pipeline in check-docs.sh with
  direct --dump-commands invocation
- Strip <arg> and [optional] placeholders from docs headings in
  check-docs.sh Phase 2 for clean comparison
- Add missing docs headings: onboard --from, setup, start, stop
- check-docs.sh --only-cli now passes with 35 matched commands
- Remove DISABLED comment and CLOUD_EXPERIMENTAL_E2E_ENABLED variable gate
- Remove SKIP_CHECK_DOCS=1 flag since parity check now passes
- Job runs unconditionally for the NVIDIA/NemoClaw repository
@jyaunches jyaunches self-assigned this Apr 24, 2026
@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

Pull request was closed or merged during review

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: 9fb523c4-aba7-4fac-a681-273490820495

📥 Commits

Reviewing files that changed from the base of the PR and between f4bffeb and 7b593df.

📒 Files selected for processing (6)
  • .github/workflows/nightly-e2e.yaml
  • docs/reference/commands.md
  • src/lib/command-registry.ts
  • src/nemoclaw.ts
  • test/e2e/e2e-cloud-experimental/check-docs.sh
  • test/image-cleanup.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/nemoclaw.ts

📝 Walkthrough

Walkthrough

A new typed CLI command registry centralizes command metadata and powers runtime help, token extraction, and a --dump-commands output; help generation, tests, docs validation script, and CI E2E job were updated to consume the registry output for consistency validation.

Changes

Cohort / File(s) Summary
Command Registry
src/lib/command-registry.ts, src/lib/command-registry.test.ts
Adds a typed command catalog and exported helpers (grouping, canonical usage list, global/sandbox token extraction) plus comprehensive tests asserting registry structure and stable outputs.
CLI Integration
src/nemoclaw.ts
Rewires help generation and dispatch token sources to use registry helpers (commandsByGroup(), globalCommandTokens(), sandboxActionTokens()); adds --dump-commands developer flag that emits canonical usage list.
Documentation
docs/reference/commands.md
Adds entries for nemoclaw onboard --from <Dockerfile> and deprecated compatibility aliases (nemoclaw start/stop, nemoclaw setup) to match registry-driven command set.
Tests
test/image-cleanup.test.ts, test/e2e/e2e-cloud-experimental/check-docs.sh
Tests updated to source expected commands from the registry; check-docs.sh now uses bin/nemoclaw.js --dump-commands and normalizes doc headings to compare against canonical registry output.
CI / Workflow
.github/workflows/nightly-e2e.yaml
cloud-experimental-e2e job unconditional run enabled (removed prior vars gating); minor env var order adjustment within job steps.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer
  participant CLI as nem oclaw CLI
  participant Reg as command-registry
  participant Docs as docs/reference/commands.md
  participant Check as check-docs.sh
  participant CI as GitHub Actions (nightly-e2e)

  Dev->>Reg: add/modify CommandDef entry
  CLI->>Reg: call commandsByGroup(), globalCommandTokens(), sandboxActionTokens()
  CLI->>Dev: on --dump-commands emit canonicalUsageList()
  Check->>CLI: run --dump-commands
  Check->>Docs: parse headings and normalize
  Check->>Reg: compare normalized docs vs canonicalUsageList()
  CI->>Check: execute check-docs.sh during cloud-experimental-e2e
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through code to tuck commands in one nest,
No more scattered crumbs — a registry at rest.
Help now grows straight from a single seed,
Docs and tests check in — tidy and freed. 🥕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(cli): typed command registry as single source of truth' directly and clearly summarizes the main objective: introducing a typed command registry to centralize CLI command metadata.
Linked Issues check ✅ Passed The PR successfully implements all Phase 1 objectives and key Phase 2-4 components: creates typed command-registry.ts with CommandDef and COMMANDS array, rewrites help() from registry, derives dispatch arrays from registry, adds --dump-commands flag for parity checks, and re-enables cloud-experimental-e2e.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue's objectives: command registry implementation, help/dispatch refactoring, docs validation tooling, and nightly job re-enablement. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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 issue-2388-typed-command-registry

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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/nightly-e2e.yaml (1)

90-102: ⚠️ Potential issue | 🟠 Major

Restore the docs-skip env or remove the dedicated docs step.

This job still runs check-docs.sh in its own step below, but the main E2E step no longer sets RUN_E2E_CLOUD_EXPERIMENTAL_SKIP_CHECK_DOCS=1. That makes docs parity run twice, adds avoidable runtime, and can fail the main E2E step before the dedicated docs step gets a chance to isolate the problem.

Suggested fix
       - name: Run cloud-experimental E2E test
         env:
           NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}
           GITHUB_TOKEN: ${{ github.token }}
           # Non-interactive install (expect-driven Phase 3 optional). Runner has no expect; Phase 5e TUI skips if expect is absent.
           RUN_E2E_CLOUD_EXPERIMENTAL_INTERACTIVE_INSTALL: "0"
+          RUN_E2E_CLOUD_EXPERIMENTAL_SKIP_CHECK_DOCS: "1"
           NEMOCLAW_NON_INTERACTIVE: "1"
           NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
           NEMOCLAW_RECREATE_SANDBOX: "1"
           NEMOCLAW_POLICY_MODE: "custom"
           NEMOCLAW_POLICY_PRESETS: "npm,pypi"

Also applies to: 104-123

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/nightly-e2e.yaml around lines 90 - 102, The main E2E step
is missing the RUN_E2E_CLOUD_EXPERIMENTAL_SKIP_CHECK_DOCS=1 environment variable
so docs checking runs twice; either add
RUN_E2E_CLOUD_EXPERIMENTAL_SKIP_CHECK_DOCS: "1" to the Run cloud-experimental
E2E test step (so check-docs.sh only runs in the dedicated docs step) or remove
the dedicated check-docs.sh step entirely; update the workflow where the Run
cloud-experimental E2E test env is defined and/or remove the separate
check-docs.sh step to ensure docs parity runs exactly once.
🧹 Nitpick comments (1)
docs/reference/commands.md (1)

617-628: Avoid maintaining two setup sections.

This adds a second nemoclaw setup entry while the page still has ### Legacy \nemoclaw setup`` later on. Keeping both descriptions in sync will reintroduce the same drift this PR is trying to remove; it would be safer to fold the legacy content into this new heading and keep a single source of truth.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/reference/commands.md` around lines 617 - 628, There are two separate
"nemoclaw setup" sections causing duplication; remove the later "Legacy
`nemoclaw setup`" section and merge any unique legacy details into the current
"### `nemoclaw setup`" block so there is a single canonical entry; ensure the
merged block preserves the deprecation notice, the compatibility alias sentence,
and any legacy usage examples or caveats previously under "Legacy `nemoclaw
setup`" and delete the duplicate heading.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/command-registry.ts`:
- Around line 353-358: The registry entry for the "nemoclaw uninstall" command
is wrong: either remove the code that passes a remoteScriptUrl into
runUninstallCommand or update the registry description to match the actual
behavior; specifically, because src/nemoclaw.ts still passes remoteScriptUrl
into runUninstallCommand, change the command registry object's description (the
entry with usage "nemoclaw uninstall") to note that it will attempt a remote
fallback (or otherwise accurately describe remoteScriptUrl behavior) so
user-facing help matches the implementation.
- Around line 26-40: The CommandDef.usage field is being used both as the
canonical command ID and as the help-facing syntax, which causes help() to show
non-runnable placeholders; add an optional helpUsage (or help?) property to
CommandDef and update help() to render cmd.helpUsage ?? cmd.usage while leaving
canonicalUsageList() and any logic that expects the canonical ID using the
original usage value; locate CommandDef, canonicalUsageList(), and help() in
command-registry.ts and change types and rendering accordingly so docs/ID
generation still use usage but help output prefers helpUsage when present.

In `@test/e2e/e2e-cloud-experimental/check-docs.sh`:
- Around line 145-146: The test is capturing stderr into the canonical command
list because the invocation of "$NODE" "$CLI_JS" --dump-commands uses 2>&1;
change it to capture stdout only by removing 2>&1 and redirecting stdout into
"$_tmp/help.txt" (retain the existing LC_ALL=C sort -u pipeline), and capture
stderr separately (e.g., to a temporary stderr file or variable) so you can
print or fail with the stderr contents if the command exits non-zero; update the
invocation in check-docs.sh where "$NODE" "$CLI_JS" --dump-commands is called to
implement this separation.

---

Outside diff comments:
In @.github/workflows/nightly-e2e.yaml:
- Around line 90-102: The main E2E step is missing the
RUN_E2E_CLOUD_EXPERIMENTAL_SKIP_CHECK_DOCS=1 environment variable so docs
checking runs twice; either add RUN_E2E_CLOUD_EXPERIMENTAL_SKIP_CHECK_DOCS: "1"
to the Run cloud-experimental E2E test step (so check-docs.sh only runs in the
dedicated docs step) or remove the dedicated check-docs.sh step entirely; update
the workflow where the Run cloud-experimental E2E test env is defined and/or
remove the separate check-docs.sh step to ensure docs parity runs exactly once.

---

Nitpick comments:
In `@docs/reference/commands.md`:
- Around line 617-628: There are two separate "nemoclaw setup" sections causing
duplication; remove the later "Legacy `nemoclaw setup`" section and merge any
unique legacy details into the current "### `nemoclaw setup`" block so there is
a single canonical entry; ensure the merged block preserves the deprecation
notice, the compatibility alias sentence, and any legacy usage examples or
caveats previously under "Legacy `nemoclaw setup`" and delete the duplicate
heading.
🪄 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: a57f21ec-8109-4a53-8ba9-60f7dd994cc7

📥 Commits

Reviewing files that changed from the base of the PR and between b804db0 and f4bffeb.

📒 Files selected for processing (7)
  • .github/workflows/nightly-e2e.yaml
  • docs/reference/commands.md
  • src/lib/command-registry.test.ts
  • src/lib/command-registry.ts
  • src/nemoclaw.ts
  • test/e2e/e2e-cloud-experimental/check-docs.sh
  • test/image-cleanup.test.ts

Comment on lines +26 to +40
export interface CommandDef {
/** Canonical command signature, e.g. "nemoclaw <name> snapshot create" */
usage: string;
/** One-line description for help output */
description: string;
/** Optional flag syntax, e.g. "[--name <label>]" */
flags?: string;
/** Section header in help output */
group: CommandGroup;
/** Deprecated commands show dimmed in help */
deprecated?: boolean;
/** Hidden commands are excluded from help and canonical list but included in dispatch */
hidden?: boolean;
/** Whether this command is global or sandbox-scoped */
scope: "global" | "sandbox";

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.

⚠️ Potential issue | 🟠 Major

Split canonical command IDs from help syntax.

usage is now doing double duty for docs parity and nemoclaw help, so the help output drops required arguments for several runnable commands: nemoclaw onboard --from <Dockerfile>, nemoclaw <name> skill install <path>, nemoclaw <name> channels add <channel>, nemoclaw credentials reset <KEY>, and similar entries. The docs checker compensates by stripping placeholders from headings, but help() renders these strings verbatim, so users no longer see runnable syntax.

Suggested direction
 export interface CommandDef {
-  /** Canonical command signature, e.g. "nemoclaw <name> snapshot create" */
+  /** Canonical command signature used for docs parity/token derivation. */
   usage: string;
+  /** User-facing syntax shown by `nemoclaw help`. Defaults to `usage`. */
+  helpUsage?: string;
   /** One-line description for help output */
   description: string;

Then keep canonicalUsageList() on usage, but have help() render cmd.helpUsage ?? cmd.usage:

   {
     usage: "nemoclaw onboard --from",
+    helpUsage: "nemoclaw onboard --from <Dockerfile>",
     description: "Use a custom Dockerfile for the sandbox image",
   },
   {
     usage: "nemoclaw <name> skill install",
+    helpUsage: "nemoclaw <name> skill install <path>",
     description: "Deploy a skill directory to the sandbox",
   },
   {
     usage: "nemoclaw credentials reset",
+    helpUsage: "nemoclaw credentials reset <KEY>",
     description: "Remove a stored credential so onboard re-prompts",
   },

Also applies to: 72-77, 141-146, 177-200, 321-326

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/command-registry.ts` around lines 26 - 40, The CommandDef.usage field
is being used both as the canonical command ID and as the help-facing syntax,
which causes help() to show non-runnable placeholders; add an optional helpUsage
(or help?) property to CommandDef and update help() to render cmd.helpUsage ??
cmd.usage while leaving canonicalUsageList() and any logic that expects the
canonical ID using the original usage value; locate CommandDef,
canonicalUsageList(), and help() in command-registry.ts and change types and
rendering accordingly so docs/ID generation still use usage but help output
prefers helpUsage when present.

Comment on lines +353 to +358
{
usage: "nemoclaw uninstall",
description: "Run uninstall.sh (local only; no remote fallback)",
group: "Cleanup",
scope: "global",
},

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.

⚠️ Potential issue | 🟡 Minor

Fix the uninstall description before it becomes user-facing help.

The registry says nemoclaw uninstall is “local only; no remote fallback”, but src/nemoclaw.ts still passes a remoteScriptUrl into runUninstallCommand(). With help now driven from this registry, the CLI will advertise the opposite of its actual behavior.

Suggested fix
   {
     usage: "nemoclaw uninstall",
-    description: "Run uninstall.sh (local only; no remote fallback)",
+    description: "Run uninstall.sh (local first; remote fallback if missing)",
     group: "Cleanup",
     scope: "global",
   },
📝 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
{
usage: "nemoclaw uninstall",
description: "Run uninstall.sh (local only; no remote fallback)",
group: "Cleanup",
scope: "global",
},
{
usage: "nemoclaw uninstall",
description: "Run uninstall.sh (local first; remote fallback if missing)",
group: "Cleanup",
scope: "global",
},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/command-registry.ts` around lines 353 - 358, The registry entry for
the "nemoclaw uninstall" command is wrong: either remove the code that passes a
remoteScriptUrl into runUninstallCommand or update the registry description to
match the actual behavior; specifically, because src/nemoclaw.ts still passes
remoteScriptUrl into runUninstallCommand, change the command registry object's
description (the entry with usage "nemoclaw uninstall") to note that it will
attempt a remote fallback (or otherwise accurately describe remoteScriptUrl
behavior) so user-facing help matches the implementation.

Comment thread test/e2e/e2e-cloud-experimental/check-docs.sh Outdated
Signed-off-by: Carlos Villela <cvillela@nvidia.com>

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

Pulled this locally and merged current main in e3309437 to clear the conflicts in src/nemoclaw.ts, test/image-cleanup.test.ts, and the docs-parity normalizer used by check-docs.sh.

A few review notes after reading the diff end-to-end and reconciling it with current main:

  • The strongest part of this change is the elimination of three independent command inventories. Deriving dispatch/help/docs parity from one registry is exactly the right direction, and --dump-commands is much less fragile than scraping ANSI help output.
  • The main thing I’d still watch is that CommandDef.usage is currently serving two jobs at once: the canonical docs key and the rendered help syntax. Because of that, the generated help now drops some operand/detail text that used to be visible to users (onboard --from <Dockerfile>, skill install <path>, channels add <channel>, credentials reset <KEY>, debug --output FILE, etc.). The docs parity check still passes because headings are normalized, but the interactive help UX regresses a bit. I think this probably wants either a separate canonical identifier vs. display string, or a more structured representation for args/options.
  • While merging main, I preserved the newer snapshot restore ... --to <dst> guidance and the long-form openshell inference set --model/--provider guidance. Those landed after this branch forked and are easy to lose if the registry data stops carrying the same level of detail as help text.
  • I also had to harden the docs normalizer to peel multiple trailing bracket groups. Current docs now have forms like snapshot restore [selector] [--to <dst>], which exposed that the previous normalization logic still assumed a single optional tail. A small regression test around canonicalization would make this path a lot less brittle.
  • Coverage-wise, the registry invariants are well tested, but there’s still a gap at the final rendered-help layer. A normalized snapshot/golden test for nemoclaw --help would catch exactly the class of regressions above.

Local verification on the merged branch:

  • npm run build:cli
  • npx vitest run src/lib/command-registry.test.ts test/image-cleanup.test.ts
  • CHECK_DOC_LINKS_REMOTE=0 bash test/e2e/e2e-cloud-experimental/check-docs.sh

(Full remote link checking still trips on the existing https://platform.openai.com/api-keys docs URL, which looks unrelated to this PR.)

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv added the v0.0.25 label Apr 24, 2026
@jyaunches jyaunches merged commit f7dff7b into main Apr 24, 2026
20 checks passed
jyaunches added a commit to jyaunches/NemoClaw that referenced this pull request Apr 28, 2026
…DIA#2644)

Replace the 931-line cloud-experimental-e2e monolith with 4 independent,
focused E2E tests:

- cloud-onboard-e2e: public installer + Landlock + security checks
- cloud-inference-e2e: live chat via inference.local + skill filesystem
- skill-agent-e2e: skill injection + agent verification (with retry + fuzzy match)
- docs-validation-e2e: CLI/docs parity via check-docs.sh

Key improvements:
- Flaky Phase 5d (skill agent) no longer blocks Landlock/security signal
- Phase 5e (TUI smoke) dropped from nightly — timing-dependent expect
- Phase 5f (docs validation) re-enabled as own job (root cause fixed by NVIDIA#2446)
- Each test installs independently — no cascade failures
- skill-agent-e2e adds retry logic + fuzzy token matching for LLM non-determinism

Also removes dead scripts from e2e-cloud-experimental/skip/ (01-onboard-completion,
04-nemoclaw-openshell-status-parity, 05-network-policy — all covered by dedicated jobs).

Fixes NVIDIA#2644
Signed-off-by: Jessica Yaunches <jyaunches@nvidia.com>
jyaunches added a commit that referenced this pull request Apr 29, 2026
…) (#2647)

## Summary

Replace the 931-line `cloud-experimental-e2e` monolith with 4
independent, focused E2E tests. Flaky phases no longer block signal from
stable phases.

Fixes #2644

## New Jobs

| Job | What it tests | Timeout | Former phases |
|-----|--------------|---------|---------------|
| `cloud-onboard-e2e` | Public installer, Landlock enforcement, API key
leak detection, inference.local HTTPS | 45 min | 0, 1, 3, 5 checks, 6 |
| `cloud-inference-e2e` | Live chat via inference.local, skill
filesystem validation | 30 min | 5b, 5c |
| `skill-agent-e2e` | Skill injection + agent verification (with retry +
fuzzy match) | 30 min | 5d |
| `docs-validation-e2e` | CLI/docs parity (nemoclaw --help vs
commands.md) | 15 min | 5f |

## Key Improvements

- **Flaky Phase 5d** (skill agent) no longer blocks Landlock/security
signal
- **Phase 5e** (TUI smoke) dropped from nightly — timing-dependent
expect with 7+ tunable sleeps is fundamentally unsuited for CI
- **Phase 5f** (docs validation) re-enabled as its own job — root cause
fixed by #2446 (typed command registry)
- Each test installs independently — no cascade failures
- `skill-agent-e2e` adds **retry logic** (3 attempts, 15s between) and
**fuzzy token matching** (case-insensitive, strips quotes/backticks) to
handle LLM non-determinism
- Remote link probing disabled for docs validation
(`CHECK_DOC_LINKS_REMOTE=0`) to avoid 429 rate-limit flakes

## Deleted

- `test/e2e/test-e2e-cloud-experimental.sh` (931-line monolith)
- `test/e2e/e2e-cloud-experimental/skip/` (3 dead scripts — coverage
already exists in dedicated jobs: `network-policy-e2e`,
`sandbox-operations-e2e`)

## Kept

- All helpers under `test/e2e/e2e-cloud-experimental/` (checks/,
features/, cleanup.sh, check-docs.sh) — referenced by the new scripts

## Type of Change

- Code change (refactor)

## Verification

- YAML validated locally
- All 29 nightly jobs have selective dispatch guards (validated with
script)
- All 4 new jobs in `notify-on-failure` and `report-to-pr` needs lists
- `workflow_dispatch.inputs.jobs` description updated with new job names

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

* **Chores**
* Replaced one monolithic nightly E2E job with four targeted nightly
jobs (onboard, inference, skill-agent, docs validation); updated
notification/reporting workflow dependencies and workflow inputs.
* Shortened job timeouts and adjusted failure-artifact uploads for
clearer, faster diagnostics.
  * Updated review tooling guidance to map paths to the new E2E jobs.

* **Tests**
* Added standalone E2E runners for cloud onboarding, cloud inference,
skill-agent verification, and docs validation.
* Removed legacy experimental E2E orchestration and several obsolete
test scripts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Jessica Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
) (NVIDIA#2446)

## Summary

Create a typed command registry (`src/lib/command-registry.ts`) as the
single source of truth for all 46 NemoClaw CLI commands. Derive help
output, dispatch arrays, and docs-parity checking from it, replacing
three independent hand-maintained sources. Re-enable the
`cloud-experimental-e2e` nightly job now that the check-docs parity
check passes reliably.

## Related Issue

Fixes NVIDIA#2388

## Changes

- **New `src/lib/command-registry.ts`**: Defines `CommandDef` interface,
`CommandGroup` union type, and `COMMANDS` array with all 46 CLI commands
(23 global + 23 sandbox). Exports helper functions: `globalCommands`,
`sandboxCommands`, `visibleCommands`, `commandsByGroup`,
`canonicalUsageList`, `globalCommandTokens`, `sandboxActionTokens`.
- **New `src/lib/command-registry.test.ts`**: 21 unit tests covering all
registry invariants — counts, deduplication, ordering, token extraction,
group membership.
- **Rewritten `help()` in `src/nemoclaw.ts`**: Now iterates
`commandsByGroup()` from registry instead of hand-written console.log
lines. Reconfiguration section rewritten with bullet points to prevent
phantom `nemoclaw`-prefixed parser matches.
- **Derived dispatch arrays**: `GLOBAL_COMMANDS` now calls
`globalCommandTokens()` and `sandboxActions` now calls
`sandboxActionTokens()` — no more hand-maintained sets/arrays.
- **Added `--dump-commands` internal flag**: Prints canonical command
list for check-docs.sh parity checks, replacing the fragile perl
help-parsing pipeline.
- **Simplified `check-docs.sh`**: Phase 1 now uses `--dump-commands`
instead of perl regex extraction. Phase 2 strips `<arg>` and
`[optional]` placeholders from doc headings for clean comparison.
- **Added missing doc headings**: `nemoclaw onboard --from`, `nemoclaw
setup`, `nemoclaw start`, `nemoclaw stop` in
`docs/reference/commands.md`.
- **Re-enabled `cloud-experimental-e2e`**: Removed DISABLED comment,
`CLOUD_EXPERIMENTAL_E2E_ENABLED` variable gate, and `SKIP_CHECK_DOCS`
flag.
- **Updated `test/image-cleanup.test.ts`**: Adapted to verify `gc` via
registry source instead of regex-matching the old `GLOBAL_COMMANDS` Set
literal.

## 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
- [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
- [x] 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)

## AI Disclosure
- [x] AI-assisted — tool: Claude Code (pi agent)

---
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>

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

* **Documentation**
* Added `nemoclaw onboard --from <Dockerfile>` usage guide and
documented deprecated aliases (`nemoclaw start`, `nemoclaw stop`,
`nemoclaw setup`) with warnings.

* **New Features**
* Added a developer-facing `--dump-commands` option to emit the
canonical command list.

* **Improvements**
* Overhauled help/command organization for clearer grouping and more
accurate, stable command listings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
…DIA#2644) (NVIDIA#2647)

## Summary

Replace the 931-line `cloud-experimental-e2e` monolith with 4
independent, focused E2E tests. Flaky phases no longer block signal from
stable phases.

Fixes NVIDIA#2644

## New Jobs

| Job | What it tests | Timeout | Former phases |
|-----|--------------|---------|---------------|
| `cloud-onboard-e2e` | Public installer, Landlock enforcement, API key
leak detection, inference.local HTTPS | 45 min | 0, 1, 3, 5 checks, 6 |
| `cloud-inference-e2e` | Live chat via inference.local, skill
filesystem validation | 30 min | 5b, 5c |
| `skill-agent-e2e` | Skill injection + agent verification (with retry +
fuzzy match) | 30 min | 5d |
| `docs-validation-e2e` | CLI/docs parity (nemoclaw --help vs
commands.md) | 15 min | 5f |

## Key Improvements

- **Flaky Phase 5d** (skill agent) no longer blocks Landlock/security
signal
- **Phase 5e** (TUI smoke) dropped from nightly — timing-dependent
expect with 7+ tunable sleeps is fundamentally unsuited for CI
- **Phase 5f** (docs validation) re-enabled as its own job — root cause
fixed by NVIDIA#2446 (typed command registry)
- Each test installs independently — no cascade failures
- `skill-agent-e2e` adds **retry logic** (3 attempts, 15s between) and
**fuzzy token matching** (case-insensitive, strips quotes/backticks) to
handle LLM non-determinism
- Remote link probing disabled for docs validation
(`CHECK_DOC_LINKS_REMOTE=0`) to avoid 429 rate-limit flakes

## Deleted

- `test/e2e/test-e2e-cloud-experimental.sh` (931-line monolith)
- `test/e2e/e2e-cloud-experimental/skip/` (3 dead scripts — coverage
already exists in dedicated jobs: `network-policy-e2e`,
`sandbox-operations-e2e`)

## Kept

- All helpers under `test/e2e/e2e-cloud-experimental/` (checks/,
features/, cleanup.sh, check-docs.sh) — referenced by the new scripts

## Type of Change

- Code change (refactor)

## Verification

- YAML validated locally
- All 29 nightly jobs have selective dispatch guards (validated with
script)
- All 4 new jobs in `notify-on-failure` and `report-to-pr` needs lists
- `workflow_dispatch.inputs.jobs` description updated with new job names

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

* **Chores**
* Replaced one monolithic nightly E2E job with four targeted nightly
jobs (onboard, inference, skill-agent, docs validation); updated
notification/reporting workflow dependencies and workflow inputs.
* Shortened job timeouts and adjusted failure-artifact uploads for
clearer, faster diagnostics.
  * Updated review tooling guidance to map paths to the new E2E jobs.

* **Tests**
* Added standalone E2E runners for cloud onboarding, cloud inference,
skill-agent verification, and docs validation.
* Removed legacy experimental E2E orchestration and several obsolete
test scripts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Jessica Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
ksapru pushed a commit to ksapru/NemoClaw that referenced this pull request May 12, 2026
) (NVIDIA#2446)

## Summary

Create a typed command registry (`src/lib/command-registry.ts`) as the
single source of truth for all 46 NemoClaw CLI commands. Derive help
output, dispatch arrays, and docs-parity checking from it, replacing
three independent hand-maintained sources. Re-enable the
`cloud-experimental-e2e` nightly job now that the check-docs parity
check passes reliably.

## Related Issue

Fixes NVIDIA#2388

## Changes

- **New `src/lib/command-registry.ts`**: Defines `CommandDef` interface,
`CommandGroup` union type, and `COMMANDS` array with all 46 CLI commands
(23 global + 23 sandbox). Exports helper functions: `globalCommands`,
`sandboxCommands`, `visibleCommands`, `commandsByGroup`,
`canonicalUsageList`, `globalCommandTokens`, `sandboxActionTokens`.
- **New `src/lib/command-registry.test.ts`**: 21 unit tests covering all
registry invariants — counts, deduplication, ordering, token extraction,
group membership.
- **Rewritten `help()` in `src/nemoclaw.ts`**: Now iterates
`commandsByGroup()` from registry instead of hand-written console.log
lines. Reconfiguration section rewritten with bullet points to prevent
phantom `nemoclaw`-prefixed parser matches.
- **Derived dispatch arrays**: `GLOBAL_COMMANDS` now calls
`globalCommandTokens()` and `sandboxActions` now calls
`sandboxActionTokens()` — no more hand-maintained sets/arrays.
- **Added `--dump-commands` internal flag**: Prints canonical command
list for check-docs.sh parity checks, replacing the fragile perl
help-parsing pipeline.
- **Simplified `check-docs.sh`**: Phase 1 now uses `--dump-commands`
instead of perl regex extraction. Phase 2 strips `<arg>` and
`[optional]` placeholders from doc headings for clean comparison.
- **Added missing doc headings**: `nemoclaw onboard --from`, `nemoclaw
setup`, `nemoclaw start`, `nemoclaw stop` in
`docs/reference/commands.md`.
- **Re-enabled `cloud-experimental-e2e`**: Removed DISABLED comment,
`CLOUD_EXPERIMENTAL_E2E_ENABLED` variable gate, and `SKIP_CHECK_DOCS`
flag.
- **Updated `test/image-cleanup.test.ts`**: Adapted to verify `gc` via
registry source instead of regex-matching the old `GLOBAL_COMMANDS` Set
literal.

## 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
- [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
- [x] 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)

## AI Disclosure
- [x] AI-assisted — tool: Claude Code (pi agent)

---
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>

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

* **Documentation**
* Added `nemoclaw onboard --from <Dockerfile>` usage guide and
documented deprecated aliases (`nemoclaw start`, `nemoclaw stop`,
`nemoclaw setup`) with warnings.

* **New Features**
* Added a developer-facing `--dump-commands` option to emit the
canonical command list.

* **Improvements**
* Overhauled help/command organization for clearer grouping and more
accurate, stable command listings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
@wscurran wscurran added the feature PR adds or expands user-visible functionality label Jun 8, 2026
@jyaunches jyaunches deleted the issue-2388-typed-command-registry branch June 12, 2026 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature PR adds or expands user-visible functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(cli): typed command registry to fix docs-drift and re-enable cloud-experimental-e2e

3 participants