Skip to content

fix(uninstall): remove agent-alias CLI shims (nemohermes, nemo-deepagents) (#6098)#6101

Open
jason-ma-nv wants to merge 1 commit into
mainfrom
fix/6098-uninstall-remove-agent-alias-shims
Open

fix(uninstall): remove agent-alias CLI shims (nemohermes, nemo-deepagents) (#6098)#6101
jason-ma-nv wants to merge 1 commit into
mainfrom
fix/6098-uninstall-remove-agent-alias-shims

Conversation

@jason-ma-nv

@jason-ma-nv jason-ma-nv commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

nemoclaw uninstall removed the nemoclaw CLI shim, the openshell* binaries, and ~/.nemoclaw/, but left the sibling agent-alias shims (nemohermes, nemo-deepagents) in ~/.local/bin. After a "clean" uninstall those commands still resolved and reported a version. This removes them too, using the same installer-managed-shim safety classification.

Related Issue

Fixes #6098

Changes

  • src/lib/domain/uninstall/shims.ts: classifyNemoclawShim / isInstallerManagedWrapperContents accept an optional binName (default nemoclaw) so a wrapper that execs …/nemohermes is recognized as installer-managed.
  • src/lib/domain/uninstall/paths.ts: add agentAliasShimPaths (nemohermes, nemo-deepagents) under the same bin dir.
  • src/lib/actions/uninstall/plan.ts: classifyShimPath threads binName through both the fd-read and metadata paths.
  • src/lib/actions/uninstall/run-plan.ts: removeNemoclawCli now also classifies and removes each alias shim — reusing the existing guard, so a non-managed file of that name (foreign file) is preserved with a warning, exactly like the nemoclaw shim.
  • Tests: per-bin-name classification (managed wrapper matched by its own name, and a nemoclaw wrapper is not treated as a managed nemohermes shim); an end-to-end run-plan test that creates managed alias symlinks and asserts both are removed.

Safe by construction: symlinks and installer-managed wrappers are removed; any other regular file at those paths (e.g. an unrelated user script) is preserved. npm-installed alias bins remain handled by the existing npm uninstall -g nemoclaw step.

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)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: completes existing uninstall cleanup; no command/flag surface change.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: uninstall/file-deletion path. Removal reuses the pre-existing classifyNemoclawShim guard (only symlinks + installer-managed wrappers removed; foreign files preserved), scoped to two fixed bin names in the resolved bin dir. 53 uninstall tests pass (51 pre-existing + 2 new), including a foreign-file-preserved assertion.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Git hooks passed during commit and push, or npx prek run --from-ref main --to-ref HEAD passes
  • Targeted tests pass for changed behavior
  • Full npm test passes (broad runtime changes only)
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run 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: Jason Ma jama@nvidia.com

Summary by CodeRabbit

  • New Features

    • Uninstall now removes supported CLI alias shims alongside the main binary.
    • Shim detection now recognizes alias wrappers for different command names.
  • Bug Fixes

    • Improved shim classification for missing files, symlinks, and permission-related cases.
    • Preserved foreign shims are now detected more accurately when aliases are involved.
  • Tests

    • Added coverage for removing alias shims and classifying alias wrapper contents correctly.

…ents) (#6098)

nemoclaw uninstall removed the nemoclaw shim but left the sibling nemohermes / nemo-deepagents shims in ~/.local/bin, so those commands still resolved after a clean uninstall.

Generalize the shim classifier to match a managed wrapper by bin name (classifyNemoclawShim/isInstallerManagedWrapperContents/classifyShimPath accept binName, default nemoclaw), enumerate the alias shim paths, and remove them in removeNemoclawCli using the same classification guard so non-managed files of that name are preserved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Jason Ma <jama@nvidia.com>
@jason-ma-nv jason-ma-nv self-assigned this Jul 1, 2026
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds support for classifying and removing sibling agent-alias CLI shims (nemohermes, nemo-deepagents) during nemoclaw uninstall. Introduces a binName parameter threaded through shim classification functions, defines AGENT_ALIAS_CLI_BINARIES and agentAliasShimPaths in uninstall paths, and wires removal logic into the run-plan flow with accompanying tests.

Changes

Agent-alias shim removal

Layer / File(s) Summary
binName-aware shim classification
src/lib/domain/uninstall/shims.ts, src/lib/domain/uninstall/shims.test.ts
isInstallerManagedWrapperContents and classifyNemoclawShim accept an optional binName (default "nemoclaw") used to match the wrapper's exec line, with tests validating hermes-alias wrapper classification.
Shim path classification with binName
src/lib/actions/uninstall/plan.ts
classifyShimPathByMetadata and classifyShimPath now accept and propagate binName through metadata fallback, fd-based classification, ENOENT handling, and error-code fallback paths.
Agent-alias path definitions
src/lib/domain/uninstall/paths.ts
Adds AGENT_ALIAS_CLI_BINARIES (nemohermes, nemo-deepagents) and agentAliasShimPaths on UninstallPaths, populated in defaultUninstallPaths().
Uninstall run-plan wiring and test
src/lib/actions/uninstall/run-plan.ts, src/lib/actions/uninstall/run-plan.test.ts
removeNemoclawCli iterates agentAliasShimPaths, classifying and removing installer-managed alias shims or warning when preserving foreign files; new test verifies both alias shims are removed during uninstall.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RunUninstallPlan as run-plan.ts
    participant Paths as paths.ts
    participant Shims as shims.ts/plan.ts

    User->>RunUninstallPlan: runUninstallPlan()
    RunUninstallPlan->>Paths: get agentAliasShimPaths
    Paths-->>RunUninstallPlan: [{binName, path}, ...]
    loop for each alias shim
        RunUninstallPlan->>Shims: classifyShimPath(path, deps, binName)
        Shims-->>RunUninstallPlan: classification (managed-wrapper / preserve-foreign-file)
        alt managed-wrapper
            RunUninstallPlan->>RunUninstallPlan: remove shim
        else preserve-foreign-file
            RunUninstallPlan->>User: warn, leave shim in place
        end
    end
    RunUninstallPlan-->>User: uninstall result
Loading

Suggested labels: bug-fix

Suggested reviewers: jyaunches, cv

🚥 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 clearly describes the main uninstall fix for removing agent-alias CLI shims.
Linked Issues check ✅ Passed The changes add bin-name-aware shim removal and uninstall alias shims, which addresses #6098.
Out of Scope Changes check ✅ Passed No clearly unrelated changes are apparent; the nemo-deepagents support is a closely related extension of the uninstall cleanup.
✨ 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/6098-uninstall-remove-agent-alias-shims

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

@github-code-quality

github-code-quality Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the branch is 96%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File f2870f0 +/-
nemoclaw/src/se...cret-scanner.ts 100%
nemoclaw/src/commands/slash.ts 100%
nemoclaw/src/li...bprocess-env.ts 100%
nemoclaw/src/bl...eprint/state.ts 98%
nemoclaw/src/onboard/config.ts 98%
nemoclaw/src/bl...int/snapshot.ts 97%
nemoclaw/src/bl...print/runner.ts 95%
nemoclaw/src/co...ration-state.ts 94%
nemoclaw/src/bl...ate-networks.ts 94%
nemoclaw/src/index.ts 94%

TypeScript / code-coverage/cli

The overall coverage in the branch is 68%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File f2870f0 +/-
src/lib/shields...nsition-lock.ts 86%
src/lib/actions...all/run-plan.ts 81%
src/lib/actions...dbox/rebuild.ts 80%
src/lib/state/o...oard-session.ts 80%
src/lib/state/sandbox.ts 72%
src/lib/onboard/preflight.ts 69%
src/lib/shields/index.ts 67%
src/lib/onboard...er-gpu-patch.ts 59%
src/lib/actions...licy-channel.ts 58%
src/lib/onboard.ts 20%

Updated July 01, 2026 06:13 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-3: Monolith test file grew by 39 lines (1389 total) — consider extraction; then add or justify PRA-T1.
Open items: 1 required · 3 warnings · 0 suggestions · 6 test follow-ups
Since last review: 0 prior items resolved · 0 still apply · 0 new items found

Action checklist

  • PRA-3 Fix: Monolith test file grew by 39 lines (1389 total) — consider extraction in src/lib/actions/uninstall/run-plan.test.ts:1
  • PRA-1 Resolve or justify: Missing integration test for wrapper-file agent-alias shims in src/lib/actions/uninstall/run-plan.test.ts:108
  • PRA-2 Resolve or justify: Missing integration test for foreign-file preservation on alias shims in src/lib/actions/uninstall/run-plan.test.ts:108
  • PRA-4 Resolve or justify: Monolith source file grew by 10 lines (963 total) — review extraction feasibility in src/lib/actions/uninstall/run-plan.ts:1
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Missing integration test for wrapper-file agent-alias shims
  • PRA-T6 Add or justify test follow-up: Missing integration test for foreign-file preservation on alias shims

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify tests src/lib/actions/uninstall/run-plan.test.ts:108 Add integration test case creating wrapper-file shims for both `nemohermes` and `nemo-deepagents` and asserting removal.
PRA-2 Resolve/justify tests src/lib/actions/uninstall/run-plan.test.ts:108 Add integration test creating a non-installer-managed regular file at alias shim path and asserting it is preserved with warning log.
PRA-3 Required architecture src/lib/actions/uninstall/run-plan.test.ts:1 Extract uninstall scenario helpers (e.g., `createTempHome`, `runUninstallPlan`, common mocks) to a shared test utility file. Do not remove the new test; extract surrounding scaffolding.
PRA-4 Resolve/justify architecture src/lib/actions/uninstall/run-plan.ts:1 Extract `removeAgentAliasShims(paths, runtime)` pure function from the loop in `removeNemoclawCli`. Keeps removal logic testable in isolation.

🚨 Required before merge

Address these before merging unless a maintainer explicitly overrides the advisor with rationale.

PRA-3 Required — Monolith test file grew by 39 lines (1389 total) — consider extraction

  • Location: src/lib/actions/uninstall/run-plan.test.ts:1
  • Category: architecture
  • Problem: run-plan.test.ts is a large-file hotspot (1389 lines). The 39-line addition for alias shim test is justified new behavior, but file size indicates extraction opportunity.
  • Impact: Large test files slow CI, reduce readability, and increase merge conflict risk. Extraction would improve maintainability.
  • Required action: Extract uninstall scenario helpers (e.g., `createTempHome`, `runUninstallPlan`, common mocks) to a shared test utility file. Do not remove the new test; extract surrounding scaffolding.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: wc -l src/lib/actions/uninstall/run-plan.test.ts shows 1389 lines; look for repeated setup patterns across tests.
  • Missing regression test: No regression test needed; this is a structural improvement. Extraction should not change test behavior.
  • Done when: The required change is committed and verification passes: wc -l src/lib/actions/uninstall/run-plan.test.ts shows 1389 lines; look for repeated setup patterns across tests.
  • Evidence: Drift context shows baseLines=1350, headLines=1389, delta=39, severity=blocker. File has 20 named test blocks.
Review findings by urgency: 1 required fix, 3 items to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Missing integration test for wrapper-file agent-alias shims

  • Location: src/lib/actions/uninstall/run-plan.test.ts:108
  • Category: tests
  • Problem: The new integration test only covers symlink-based alias shims. Issue [Linux][Install] nemoclaw uninstall leaves the nemohermes shim at ~/.local/bin/nemohermes (command still resolves) #6098 logs show installer creates 3-line wrapper files (e.g., `exec "$HOME/.hermes/node/bin/nemohermes"`). Wrapper-file variant should be tested end-to-end.
  • Impact: If wrapper-file alias shims are not removed, `nemohermes`/`nemo-deepagents` commands remain resolvable after uninstall on platforms where installer uses wrapper files.
  • Recommended action: Add integration test case creating wrapper-file shims for both `nemohermes` and `nemo-deepagents` and asserting removal.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check run-plan.test.ts for a test named like 'removes agent-alias wrapper-file shims' that creates wrapper contents via fs.writeFileSync and asserts removal.
  • Missing regression test: it('removes agent-alias wrapper-file shims (nemohermes, nemo-deepagents)') with wrapper contents matching isInstallerManagedWrapperContents pattern for each binName
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check run-plan.test.ts for a test named like 'removes agent-alias wrapper-file shims' that creates wrapper contents via fs.writeFileSync and asserts removal.
  • Evidence: run-plan.test.ts:108-145 only tests symlink variant; shims.test.ts unit test covers wrapper recognition but not end-to-end removal path

PRA-2 Resolve/justify — Missing integration test for foreign-file preservation on alias shims

  • Location: src/lib/actions/uninstall/run-plan.test.ts:108
  • Category: tests
  • Problem: Main shim has `preserve-foreign-file` guard tested implicitly; alias shims lack integration test verifying a user-managed file at `~/.local/bin/nemohermes` is preserved with warning.
  • Impact: Regression could silently delete user scripts named `nemohermes` or `nemo-deepagents` in the bin directory.
  • Recommended action: Add integration test creating a non-installer-managed regular file at alias shim path and asserting it is preserved with warning log.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check run-plan.test.ts for test creating `fs.writeFileSync(hermesShim, '#!/bin/bash echo user')` and asserting `removed` does not contain the path and logs contain warning.
  • Missing regression test: it('preserves foreign file at nemohermes path with warning') and same for nemo-deepagents
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check run-plan.test.ts for test creating `fs.writeFileSync(hermesShim, '#!/bin/bash echo user')` and asserting `removed` does not contain the path and logs contain warning.
  • Evidence: run-plan.test.ts has no foreign-file test for alias shims; main shim foreign-file behavior tested in shims.test.ts unit test only

PRA-4 Resolve/justify — Monolith source file grew by 10 lines (963 total) — review extraction feasibility

  • Location: src/lib/actions/uninstall/run-plan.ts:1
  • Category: architecture
  • Problem: run-plan.ts is a large-file hotspot (963 lines). The 10-line alias shim removal loop is justified, but file size suggests domain boundaries could be cleaner.
  • Impact: Large files increase cognitive load and coupling. The alias shim removal logic could be a separate pure function.
  • Recommended action: Extract `removeAgentAliasShims(paths, runtime)` pure function from the loop in `removeNemoclawCli`. Keeps removal logic testable in isolation.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read run-plan.ts:628-638; the for-loop over `paths.agentAliasShimPaths` is self-contained and could be a named export.
  • Missing regression test: Unit test for extracted function with various ShimClassification outcomes (remove, preserve-foreign-file, missing).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read run-plan.ts:628-638; the for-loop over `paths.agentAliasShimPaths` is self-contained and could be a named export.
  • Evidence: Drift context shows baseLines=953, headLines=963, delta=10, severity=warning.

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

  • None.
Simplification opportunities: 2 possible cuts, net -200 lines possible

These are safe simplification checks only. Do not remove validation, security controls, data-loss prevention, or required tests.

  • PRA-3 shrink (src/lib/actions/uninstall/run-plan.test.ts:1): Repeated test setup: tmpHome creation, mock runtime factory, log/removed array patterns
    • Replacement: Shared test utility module (e.g., src/lib/actions/uninstall/test-utils.ts) with createUninstallTestRuntime(), createTempHome()
    • Net: -200 lines
    • Safety boundary: Must preserve real fs/shell boundaries in integration tests; do not over-mock the uninstall execution path
  • PRA-4 shrink (src/lib/actions/uninstall/run-plan.ts:1): Inline for-loop in removeNemoclawCls (lines 628-638)
    • Replacement: export function removeAgentAliasShims(paths: UninstallPaths, runtime: UninstallRuntime): void { ... }
    • Net: 0 lines
    • Safety boundary: Must preserve same classification guard and warning behavior; no change to removal semantics
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — it('removes agent-alias wrapper-file shims (nemohermes, nemo-deepagents)'). Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/actions/uninstall/plan.ts, src/lib/actions/uninstall/run-plan.ts, src/lib/domain/uninstall/paths.ts, src/lib/domain/uninstall/shims.ts. Unit tests cover classification logic; integration tests cover symlink variant. Wrapper-file and foreign-file variants for alias shims lack integration coverage.
  • PRA-T2 Runtime validation — it('preserves foreign file at nemohermes path with warning'). Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/actions/uninstall/plan.ts, src/lib/actions/uninstall/run-plan.ts, src/lib/domain/uninstall/paths.ts, src/lib/domain/uninstall/shims.ts. Unit tests cover classification logic; integration tests cover symlink variant. Wrapper-file and foreign-file variants for alias shims lack integration coverage.
  • PRA-T3 Runtime validation — it('preserves foreign file at nemo-deepagents path with warning'). Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/actions/uninstall/plan.ts, src/lib/actions/uninstall/run-plan.ts, src/lib/domain/uninstall/paths.ts, src/lib/domain/uninstall/shims.ts. Unit tests cover classification logic; integration tests cover symlink variant. Wrapper-file and foreign-file variants for alias shims lack integration coverage.
  • PRA-T4 Runtime validation — Unit test for extracted removeAgentAliasShims function (if extracted per architecture finding). Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/actions/uninstall/plan.ts, src/lib/actions/uninstall/run-plan.ts, src/lib/domain/uninstall/paths.ts, src/lib/domain/uninstall/shims.ts. Unit tests cover classification logic; integration tests cover symlink variant. Wrapper-file and foreign-file variants for alias shims lack integration coverage.
  • PRA-T5 Missing integration test for wrapper-file agent-alias shims — Add integration test case creating wrapper-file shims for both `nemohermes` and `nemo-deepagents` and asserting removal.
  • PRA-T6 Missing integration test for foreign-file preservation on alias shims — Add integration test creating a non-installer-managed regular file at alias shim path and asserting it is preserved with warning log.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Missing integration test for wrapper-file agent-alias shims

  • Location: src/lib/actions/uninstall/run-plan.test.ts:108
  • Category: tests
  • Problem: The new integration test only covers symlink-based alias shims. Issue [Linux][Install] nemoclaw uninstall leaves the nemohermes shim at ~/.local/bin/nemohermes (command still resolves) #6098 logs show installer creates 3-line wrapper files (e.g., `exec "$HOME/.hermes/node/bin/nemohermes"`). Wrapper-file variant should be tested end-to-end.
  • Impact: If wrapper-file alias shims are not removed, `nemohermes`/`nemo-deepagents` commands remain resolvable after uninstall on platforms where installer uses wrapper files.
  • Recommended action: Add integration test case creating wrapper-file shims for both `nemohermes` and `nemo-deepagents` and asserting removal.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check run-plan.test.ts for a test named like 'removes agent-alias wrapper-file shims' that creates wrapper contents via fs.writeFileSync and asserts removal.
  • Missing regression test: it('removes agent-alias wrapper-file shims (nemohermes, nemo-deepagents)') with wrapper contents matching isInstallerManagedWrapperContents pattern for each binName
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check run-plan.test.ts for a test named like 'removes agent-alias wrapper-file shims' that creates wrapper contents via fs.writeFileSync and asserts removal.
  • Evidence: run-plan.test.ts:108-145 only tests symlink variant; shims.test.ts unit test covers wrapper recognition but not end-to-end removal path

PRA-2 Resolve/justify — Missing integration test for foreign-file preservation on alias shims

  • Location: src/lib/actions/uninstall/run-plan.test.ts:108
  • Category: tests
  • Problem: Main shim has `preserve-foreign-file` guard tested implicitly; alias shims lack integration test verifying a user-managed file at `~/.local/bin/nemohermes` is preserved with warning.
  • Impact: Regression could silently delete user scripts named `nemohermes` or `nemo-deepagents` in the bin directory.
  • Recommended action: Add integration test creating a non-installer-managed regular file at alias shim path and asserting it is preserved with warning log.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check run-plan.test.ts for test creating `fs.writeFileSync(hermesShim, '#!/bin/bash echo user')` and asserting `removed` does not contain the path and logs contain warning.
  • Missing regression test: it('preserves foreign file at nemohermes path with warning') and same for nemo-deepagents
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check run-plan.test.ts for test creating `fs.writeFileSync(hermesShim, '#!/bin/bash echo user')` and asserting `removed` does not contain the path and logs contain warning.
  • Evidence: run-plan.test.ts has no foreign-file test for alias shims; main shim foreign-file behavior tested in shims.test.ts unit test only

PRA-3 Required — Monolith test file grew by 39 lines (1389 total) — consider extraction

  • Location: src/lib/actions/uninstall/run-plan.test.ts:1
  • Category: architecture
  • Problem: run-plan.test.ts is a large-file hotspot (1389 lines). The 39-line addition for alias shim test is justified new behavior, but file size indicates extraction opportunity.
  • Impact: Large test files slow CI, reduce readability, and increase merge conflict risk. Extraction would improve maintainability.
  • Required action: Extract uninstall scenario helpers (e.g., `createTempHome`, `runUninstallPlan`, common mocks) to a shared test utility file. Do not remove the new test; extract surrounding scaffolding.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: wc -l src/lib/actions/uninstall/run-plan.test.ts shows 1389 lines; look for repeated setup patterns across tests.
  • Missing regression test: No regression test needed; this is a structural improvement. Extraction should not change test behavior.
  • Done when: The required change is committed and verification passes: wc -l src/lib/actions/uninstall/run-plan.test.ts shows 1389 lines; look for repeated setup patterns across tests.
  • Evidence: Drift context shows baseLines=1350, headLines=1389, delta=39, severity=blocker. File has 20 named test blocks.

PRA-4 Resolve/justify — Monolith source file grew by 10 lines (963 total) — review extraction feasibility

  • Location: src/lib/actions/uninstall/run-plan.ts:1
  • Category: architecture
  • Problem: run-plan.ts is a large-file hotspot (963 lines). The 10-line alias shim removal loop is justified, but file size suggests domain boundaries could be cleaner.
  • Impact: Large files increase cognitive load and coupling. The alias shim removal logic could be a separate pure function.
  • Recommended action: Extract `removeAgentAliasShims(paths, runtime)` pure function from the loop in `removeNemoclawCli`. Keeps removal logic testable in isolation.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read run-plan.ts:628-638; the for-loop over `paths.agentAliasShimPaths` is self-contained and could be a named export.
  • Missing regression test: Unit test for extracted function with various ShimClassification outcomes (remove, preserve-foreign-file, missing).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read run-plan.ts:628-638; the for-loop over `paths.agentAliasShimPaths` is self-contained and could be a named export.
  • Evidence: Drift context shows baseLines=953, headLines=963, delta=10, severity=warning.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: None
Optional E2E: None

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • None.

Optional E2E

  • None.

New E2E recommendations

  • uninstall-lifecycle (high): No existing live E2E appears to exercise nemoclaw uninstall or verify removal of the sibling agent-alias shims. Unit tests cover classification and run-plan behavior, but the real installer/uninstaller PATH interaction is not covered end-to-end.
    • Suggested test: Add a live uninstall E2E job that installs the CLI, verifies nemoclaw, nemohermes, and nemo-deepagents resolve on PATH, runs nemoclaw uninstall --yes in an isolated HOME, then verifies installer-managed alias shims are removed while a foreign same-name file is preserved.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: None
Optional E2E targets: None

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E targets

  • None. Changes are limited to uninstall implementation and unit tests. The live E2E target workflow does not have a typed target or wired free-standing job that directly exercises uninstall shim removal for agent-alias CLIs, so no E2E target dispatch is required.

Optional E2E targets

  • None.

Relevant changed files

  • None.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Changes requested

Merge posture: Do not merge yet
Primary next action: Resolve or justify PRA-1: Constrain the exported shim bin-name classifier input.
Open items: 0 required · 2 warnings · 0 suggestions · 5 test follow-ups
Top item: Constrain exported shim bin names before using them as deletion classifiers

Action checklist

  • PRA-1 Resolve or justify: Constrain the exported shim bin-name classifier input in src/lib/domain/uninstall/shims.ts:29
  • PRA-2 Resolve or justify: Add run-plan coverage for foreign alias preservation and wrapper-file deletion in src/lib/actions/uninstall/run-plan.test.ts:165
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Add run-plan coverage for foreign alias preservation and wrapper-file deletion
  • PRA-T5 Add or justify test follow-up: Acceptance clause

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify security src/lib/domain/uninstall/shims.ts:29 Make the accepted bin names explicit, either with a literal union sourced from the managed CLI constants or a runtime allowlist check that returns `preserve-foreign-file`/false for unsupported names before matching wrapper contents.
PRA-2 Resolve/justify tests src/lib/actions/uninstall/run-plan.test.ts:165 Add focused run-plan tests using a temp home with real files: one where `~/.local/bin/nemohermes` contains non-managed contents and is not removed but warns, and one where both alias paths contain installer-managed three-line wrappers and are removed.
Review findings by urgency: 0 required fixes, 2 items to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Constrain the exported shim bin-name classifier input

  • Location: src/lib/domain/uninstall/shims.ts:29
  • Category: security
  • Problem: `isInstallerManagedWrapperContents` and `classifyNemoclawShim` now accept an exported `binName: string` and use it to decide whether a regular file is an installer-managed wrapper eligible for deletion. Current production callers pass fixed values, but the exported API no longer encodes that only `nemoclaw`, `nemohermes`, and `nemo-deepagents` are valid managed CLI names.
  • Impact: A future caller could pass an unsupported or malformed name and unintentionally widen the uninstall deletion classifier for regular files. This is a low-immediacy risk in this diff because the new run-plan caller uses constants, but the changed API sits on a file-deletion trust boundary.
  • Recommended action: Make the accepted bin names explicit, either with a literal union sourced from the managed CLI constants or a runtime allowlist check that returns `preserve-foreign-file`/false for unsupported names before matching wrapper contents.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read `src/lib/domain/uninstall/shims.ts` and confirm the new `binName` parameter is no longer an unconstrained `string`, then check `src/lib/actions/uninstall/run-plan.ts` still passes only the fixed alias names.
  • Missing regression test: Add a classifier test such as `does not classify wrappers for unsupported shim bin names as managed`, covering an unsupported name and verifying the result is not removable.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read `src/lib/domain/uninstall/shims.ts` and confirm the new `binName` parameter is no longer an unconstrained `string`, then check `src/lib/actions/uninstall/run-plan.ts` still passes only the fixed alias names.
  • Evidence: `execLine.endsWith(`/${binName}" "$@"`)` is driven by an exported string parameter, while the deletion path in `run-plan.ts` removes paths when that classification returns `remove: true`.

PRA-2 Resolve/justify — Add run-plan coverage for foreign alias preservation and wrapper-file deletion

  • Location: src/lib/actions/uninstall/run-plan.test.ts:165
  • Category: tests
  • Problem: The new run-plan test covers managed alias symlinks, and the domain tests cover wrapper classification. The full uninstall run path still lacks a negative test proving a user-managed regular file named `nemohermes` or `nemo-deepagents` is preserved, and lacks an integration-style run-plan test proving installer-managed three-line alias wrapper files are removed.
  • Impact: This PR expands uninstall's deletion surface. Without run-plan-level negative coverage, a later refactor could delete user scripts with these names or fail to remove the exact wrapper artifact described in the issue while the current positive symlink test still passes.
  • Recommended action: Add focused run-plan tests using a temp home with real files: one where `~/.local/bin/nemohermes` contains non-managed contents and is not removed but warns, and one where both alias paths contain installer-managed three-line wrappers and are removed.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect `src/lib/actions/uninstall/run-plan.test.ts` around the new alias test and confirm it creates symlinks only; inspect `src/lib/domain/uninstall/shims.test.ts` to see wrapper matching is covered only at the classifier layer.
  • Missing regression test: Add `preserves user-managed agent-alias executables during uninstall` and `removes installer-managed agent-alias wrapper files during uninstall` to `src/lib/actions/uninstall/run-plan.test.ts`.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect `src/lib/actions/uninstall/run-plan.test.ts` around the new alias test and confirm it creates symlinks only; inspect `src/lib/domain/uninstall/shims.test.ts` to see wrapper matching is covered only at the classifier layer.
  • Evidence: The new run-plan test creates `fs.symlinkSync("/tmp/prefix/bin/nemohermes", hermesShim)` and `fs.symlinkSync("/tmp/prefix/bin/nemo-deepagents", deepagentsShim)`, but no run-plan test creates a regular foreign alias file or a regular installer-wrapper alias file.

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

  • None.
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Add `preserves user-managed agent-alias executables during uninstall`: create a regular executable at `~/.local/bin/nemohermes` with non-managed contents, run uninstall, assert `rmSync` is not called for that path and a preservation warning is emitted.. This PR changes uninstall/file-deletion behavior. Existing tests cover the positive symlink path and classifier behavior, but deletion-boundary changes need run-plan-level negative and wrapper-file coverage.
  • PRA-T2 Runtime validation — Add `removes installer-managed agent-alias wrapper files during uninstall`: create three-line wrapper files for `nemohermes` and `nemo-deepagents`, run uninstall, and assert both paths are removed.. This PR changes uninstall/file-deletion behavior. Existing tests cover the positive symlink path and classifier behavior, but deletion-boundary changes need run-plan-level negative and wrapper-file coverage.
  • PRA-T3 Runtime validation — Add `rejects unsupported shim bin names in classifier`: verify an unsupported bin name cannot classify wrapper contents as installer-managed/removable.. This PR changes uninstall/file-deletion behavior. Existing tests cover the positive symlink path and classifier behavior, but deletion-boundary changes need run-plan-level negative and wrapper-file coverage.
  • PRA-T4 Add run-plan coverage for foreign alias preservation and wrapper-file deletion — Add focused run-plan tests using a temp home with real files: one where `~/.local/bin/nemohermes` contains non-managed contents and is not removed but warns, and one where both alias paths contain installer-managed three-line wrappers and are removed.
  • PRA-T5 Acceptance clause — The nemohermes shim is the standard 3-line wrapper: #!/usr/bin/env bash export PATH="$HOME/.hermes/node/bin:$PATH" exec "$HOME/.hermes/node/bin/nemohermes" "$@" — add test evidence or identify existing coverage. `src/lib/domain/uninstall/shims.test.ts` verifies `nemohermes` three-line wrapper classification by bin name, and `run-plan.ts` uses that classifier. A run-plan-level wrapper-file deletion regression test is still missing.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@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 (1)
src/lib/actions/uninstall/run-plan.test.ts (1)

165-203: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Test only exercises the symlink path, not the new binName-aware wrapper classification.

Both alias shims here are plain symlinks, which classifyShimPath resolves via the isSymlink branch — a path that doesn't depend on binName at all. This test doesn't actually prove that removeNemoclawCli's new classifyShimPath(alias.path, {}, alias.binName) call correctly wires binName through to isInstallerManagedWrapperContents for a wrapper-style shim; only the pure-function unit tests in shims.test.ts cover that. Consider adding a wrapper-script variant (installer-managed wrapper content, per-bin) alongside the symlink case to close this gap end-to-end.

As per path instructions, tests should provide "behavioral confidence rather than implementation lock-in" and flag "conditionals that make a test pass without exercising its claim."

🤖 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/lib/actions/uninstall/run-plan.test.ts` around lines 165 - 203, The
uninstall test only covers plain symlink cleanup and does not exercise the new
binName-aware wrapper classification path. Update the test around
runUninstallPlan/removeNemoclawCli to include a wrapper-script fixture with
installer-managed contents and a specific binName so
classifyShimPath(alias.path, {}, alias.binName) is actually validated
end-to-end, while keeping the existing symlink case as a separate behavioral
check. Use the existing symbols removeNemoclawCli, runUninstallPlan, and
classifyShimPath to locate the right test area.

Source: Path instructions

🤖 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/lib/actions/uninstall/run-plan.test.ts`:
- Around line 165-203: The uninstall test only covers plain symlink cleanup and
does not exercise the new binName-aware wrapper classification path. Update the
test around runUninstallPlan/removeNemoclawCli to include a wrapper-script
fixture with installer-managed contents and a specific binName so
classifyShimPath(alias.path, {}, alias.binName) is actually validated
end-to-end, while keeping the existing symlink case as a separate behavioral
check. Use the existing symbols removeNemoclawCli, runUninstallPlan, and
classifyShimPath to locate the right test area.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e1d32049-1624-44c5-a215-f255824b862f

📥 Commits

Reviewing files that changed from the base of the PR and between e4b9111 and f2870f0.

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

@wscurran wscurran added area: install Install, setup, prerequisites, or uninstall flow bug-fix PR fixes a bug or regression labels Jul 1, 2026
@wscurran

wscurran commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@wscurran wscurran added integration: hermes Hermes integration behavior integration: dcode LangChain Deep Code integration behavior labels Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: install Install, setup, prerequisites, or uninstall flow bug-fix PR fixes a bug or regression integration: dcode LangChain Deep Code integration behavior integration: hermes Hermes integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Linux][Install] nemoclaw uninstall leaves the nemohermes shim at ~/.local/bin/nemohermes (command still resolves)

2 participants