Skip to content

refactor(uninstall): extract plan domain helpers#3080

Merged
cv merged 95 commits into
mainfrom
refactor/uninstall-plan-domain
May 6, 2026
Merged

refactor(uninstall): extract plan domain helpers#3080
cv merged 95 commits into
mainfrom
refactor/uninstall-plan-domain

Conversation

@cv

@cv cv commented May 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Extracts uninstaller decision logic into typed domain/action helpers without changing the shell uninstaller entrypoint. This creates the testable planning layer needed before replacing uninstall.sh with an internal oclif command wrapper in the next stacked PR.

Changes

  • Add uninstall domain helpers for shim classification, uninstall paths, gateway volume names, and plan construction.
  • Add action-layer helpers to classify on-disk shims and build a host uninstall plan from environment-derived paths.
  • Add direct TypeScript tests for managed shim detection, path planning, model/OpenShell preservation flags, and host plan construction.

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 uninstall functionality with multi-step cleanup workflows for managing system components
    • Added shim classification system to intelligently preserve or remove installed components
    • Added filesystem path management for uninstall operations
  • Tests

    • Added test coverage for uninstall plans, paths, and component classification

cv added 30 commits May 2, 2026 13:36
@cv cv self-assigned this May 6, 2026
@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

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: b4c2ece6-6170-4fa5-b0e0-55f2f4c3f636

📥 Commits

Reviewing files that changed from the base of the PR and between 489198d and cc93aae.

📒 Files selected for processing (8)
  • src/lib/actions/uninstall-plan.test.ts
  • src/lib/actions/uninstall-plan.ts
  • src/lib/domain/uninstall/paths.test.ts
  • src/lib/domain/uninstall/paths.ts
  • src/lib/domain/uninstall/plan.test.ts
  • src/lib/domain/uninstall/plan.ts
  • src/lib/domain/uninstall/shims.test.ts
  • src/lib/domain/uninstall/shims.ts

📝 Walkthrough

Walkthrough

This PR introduces a new uninstall system comprising domain models for shim classification and path resolution, plan construction logic that orchestrates cleanup operations, and an actions layer that builds host-side uninstall plans from environment variables. Five new modules with supporting tests are added.

Changes

Uninstall Feature System

Layer / File(s) Summary
Shim Classification
src/lib/domain/uninstall/shims.ts
src/lib/domain/uninstall/shims.test.ts
ShimKind union type and ShimClassification interface classify shim paths as missing, managed, or preserved. Helper functions detect installer-managed wrappers and dev shim markers via file contents.
Uninstall Path Resolution
src/lib/domain/uninstall/paths.ts
src/lib/domain/uninstall/paths.test.ts
Constants for gateway names and provider names. UninstallPaths interface and defaultUninstallPaths function compute filesystem paths for config, state, binaries, and temp cleanup. uninstallStatePaths returns removal order.
Uninstall Plan Construction
src/lib/domain/uninstall/plan.ts
src/lib/domain/uninstall/plan.test.ts
UninstallPlanAction union and UninstallPlan interface model multi-step cleanup operations. buildUninstallPlan composes paths and shim classification into ordered steps (services, providers, gateway, models, binaries, state). flattenUninstallPlan linearizes for execution.
Host Action Binding
src/lib/actions/uninstall-plan.ts
src/lib/actions/uninstall-plan.test.ts
FileSystemDeps and HostUninstallPlanOptions interfaces. classifyShimPath wraps classifyNemoclawShim with filesystem operations and ENOENT handling. buildHostUninstallPlan resolves environment-derived paths and delegates to domain buildUninstallPlan.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A shim or two, some paths to clear,
Plans unfold, the way is near—
Step by step, in order fine,
Cleanup flows like a bunny's design!

🚥 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 'refactor(uninstall): extract plan domain helpers' accurately describes the main change: extracting uninstall decision logic into typed domain and action helpers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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/uninstall-plan-domain

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

@cv cv marked this pull request as draft May 6, 2026 06:15
@copy-pr-bot

copy-pr-bot Bot commented May 6, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@cv cv added NemoClaw CLI refactor PR restructures code without intended behavior change labels May 6, 2026
@cv

cv commented May 6, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

@cv

cv commented May 6, 2026

Copy link
Copy Markdown
Collaborator Author

Automated PR review summary

Reviewed PR #3080: refactor(uninstall): extract plan domain helpers

Recommendation

  • Recommendation: PASS
  • Highest observed severity: low
  • Block merge: no
  • Why: The main risks in this refactor were silent semantic drift in uninstall planning and overbroad shim deletion. Targeted runtime/source-backed probes showed strict shim classification, correct env-derived uninstall path planning, correct toggle behavior, and unchanged uninstall.sh entrypoint wiring.
  • Reviewer summary: Reviewed the PR with PR-specific adversarial probes against the extracted uninstall planning helpers and the installed CLI wiring. The tested plan-layer behaviors matched the PR's stated refactor-only scope.

Installation and setup findings

  • Nemoclaw installation from the local repo worked. I used the repository installer entrypoint in non-interactive mode with the local checkout as source, confirmed the created sandbox via nemoclaw list/status, SSHed into that NemoClaw-managed sandbox and got '2+2=4', then ran an in-sandbox OpenClaw probe that returned '4'. The only incomplete piece is that the original installer process hit the 600s timeout while onboarding policy setup was still running, but the installed CLI, created sandbox, and provider reachability were all proven functional.

What was validated

  • The PR revision was checked out in an isolated review environment.
  • The local checkout was installed using the repository installer flow as closely as the environment allowed.
  • Adversarial, PR-specific probes were then run against the installed environment and relevant repository context.
  • Diff summary:
 .../skills/nemoclaw-contributor-create-pr/SKILL.md |   20 +-
 .../nemoclaw-maintainer-pr-comparator/SKILL.md     |  121 --
 .../checks/tier-0-gates.md                         |   61 -
 .../checks/tier-1-correctness.md                   |   86 --
 .../checks/tier-2-quality.md                       |   64 --
 .../repo-policy.md                                 |   86 --
 .../scripts/check-coderabbit-threads.sh            |  105 --
 .../scripts/collect-gates.sh                       |   84 --
 .../scripts/find-candidates.sh                     |   86 --
 .../scripts/parse-supersession.sh                  |   68 --
 .../scripts/render-verdict.py                      |  232 ----
 .../templates/verdict.md                           |   88 --
 .../tiebreakers.md                                 |   61 -
 .../validation/backtest.md                         |   69 --
 .agents/skills/nemoclaw-skills-guide/SKILL.md      |    2 +-
 .../references/agent-skills.md                     |    4 +-
 .../nemoclaw-user-configure-inference/SKILL.md     |  329 ++----
 .../references/inference-options.md                |    4 +-
 .../references/set-up-sub-agent.md                 |  120 --
 .../references/sw
...[truncated]

Failing tests and unresolved impact

  • No failing adversarial tests were captured.

Passing tests and why they mattered

Passing test 1: Shim classification is strict enough to avoid deleting user-managed wrapper-like files

  • What was tested: Only exact installer/dev-managed shim layouts are removable; wrapper-like files with extra content are preserved.
  • Why it mattered: If false, uninstall planning could delete user-managed executables or other foreign files.
  • Observed result: Probe classified an exact 3-line wrapper as managed-wrapper/remove=true, while the same wrapper plus an extra line became preserve-foreign-file/remove=false.
  • Command: node /tmp/pr3080_probe.mjs
  • Recommended follow-up coverage: Keep this as unit/regression coverage because matcher broadening would create destructive false positives during uninstall.

Passing test 2: Host uninstall plan derives cleanup targets from env while preserving a foreign shim

  • What was tested: buildHostUninstallPlan uses HOME/TMPDIR/XDG_BIN_HOME-derived paths and preserves a non-managed shim instead of deleting it.
  • Why it mattered: If false, the refactor could change uninstall targets, miss cleanup, or remove a user-managed binary.
  • Observed result: Flattened plan preserved the foreign shim, used TMPDIR-based cleanup globs, targeted state dirs under the supplied HOME, and included OpenShell binary paths /usr/local/bin/openshell plus <XDG_BIN_HOME>/openshell.
  • Command: node /tmp/pr3080_probe.mjs
  • Recommended follow-up coverage: Keep integration-style regression coverage around env-derived path construction and shim preservation because future wrapper migration will depend on it.

Passing test 3: Toggle handling matches claimed uninstall planning behavior

  • What was tested: keepOpenShell/deleteModels/custom gateway toggles produce preserve-openshell-binary, delete-ollama-model, and custom gateway/docker-volume actions without semantic drift.
  • Why it mattered: If false, the extracted planning layer would not faithfully model uninstall.sh behavior for future command-wrapper migration.
  • Observed result: Observed destroy-openshell-gateway customgw, delete-docker-volume openshell-cluster-customgw, deletion of both Ollama model actions, preserve-openshell-binary, and state-path deletions in expected order.
  • Command: node /tmp/pr3080_probe.mjs
  • Recommended follow-up coverage: Keep as regression/integration coverage because stacked follow-up PRs will likely reuse this plan contract directly.

Passing test 4: Runtime uninstall entrypoint remains uninstall.sh

  • What was tested: This PR is plan-layer only and does not switch the user-facing uninstall command away from the shell script.
  • Why it mattered: If false, runtime behavior changed beyond the stated refactor scope and would need end-to-end uninstall validation.
  • Observed result: Source inspection showed src/lib/commands/uninstall.ts and command registry still describe running uninstall.sh; no evidence that this PR replaced the shell entrypoint.
  • Command: grep -RIn -E 'uninstall\.sh|buildHostUninstallPlan' src/lib uninstall.sh package.json
  • Recommended follow-up coverage: No new automated test needed for this refactor-only PR; add an integration test when the next PR actually introduces the wrapper entrypoint.

Bottom line

  • Based on the install evidence and adversarial probes, this PR looks reasonable to approve.

@cv cv marked this pull request as ready for review May 6, 2026 19:31
@cv cv changed the base branch from refactor/internal-dns-setup-proxy to main May 6, 2026 19:31
@cv cv enabled auto-merge (squash) May 6, 2026 19:31
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv requested a review from prekshivyas May 6, 2026 19:35

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

Clean additive refactor — 528+/0-, 8 new files under src/lib/domain/uninstall/ and src/lib/actions/.

  • Models the six steps of uninstall.sh as typed plan actions (delete-openshell-provider, destroy-openshell-gateway, delete-shim, preserve-shim, delete-docker-volume, (delete|preserve)-ollama-models, (delete|preserve)-openshell-binary, delete-runtime-glob, delete-path, uninstall-npm-package, stop-*).
  • No call-site rewiring this PR — uninstall.sh remains the entrypoint, helpers have zero callers (deliberate prep for next stacked PR).
  • Unit coverage looks thorough: paths.test.ts (XDG/TMPDIR derivation), plan.test.ts (full structure + delete-models / keep-openshell / custom gateway / foreign-shim variants), shims.test.ts (symlink / managed wrapper / dev-shim / foreign / missing / unsupported), uninstall-plan.test.ts (real-fs classification path).
  • Public CLI surface unchanged. No drive-by edits, no new orphan imports in src/nemoclaw.ts.

Nit (non-blocking): isInstallerManagedWrapperContents and isDevShimContents rely on exact line-count plus prefix/suffix matching of the wrapper content. Slightly brittle if the installer ever changes the wrapper format, but the fallthrough goes to preserve-foreign-file (no unsafe deletes), and the marker-based dev-shim check is robust.

CI: pr.yaml rollup checks pass (commit-lint, dco, layer-boundary, check-hash, CodeRabbit). Self-hosted: prior completed run was success on pull-request/3080; build-sandbox-images / macos-e2e / current self-hosted run still in progress at approval time.

@cv cv merged commit 3902f74 into main May 6, 2026
12 checks passed
@cv cv deleted the refactor/uninstall-plan-domain branch May 27, 2026 21:18
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output and removed NemoClaw CLI labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output refactor PR restructures code without intended behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants