moshcode: uninstall an engine or tool - #150
Merged
Merged
Conversation
`moshcode install` had no inverse. Removing opencode meant knowing which
installer had put it where, which is the thing the wrapper exists to spare you.
moshcode uninstall <engine|tool> [--dry-run] [--yes]
Installers come in two shapes and only one has an inverse anyone wrote down.
`npm install -g <pkg>` is undone by npm, which knows what it put where — the
package name is read out of the install spec rather than duplicated. A
`curl … | sh` installer drops a binary and leaves no record, so removing it
means finding that binary and deleting it, which is a different kind of
operation and is treated like one:
- it is only offered when the binary sits somewhere a per-user installer
would plausibly have put it. An allow-list, not a deny-list: the question
is not "is this dangerous" but "did something we ran create this", and
/usr/bin/opencode came from a package manager and is not ours to remove
- it needs --yes. Deleting a file because a flag was left off is not a thing
this should do
- it says out loud that config, caches and credentials in your home
directory stay, because "uninstalled" reads as "gone" and it is not
npm removals do not ask, since one command puts it back.
Plans are data, so every branch is tested without deleting anything, and
--dry-run shows exactly what would go. 7 tests, most of them about when it
refuses.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
ralyodio
pushed a commit
that referenced
this pull request
Jul 31, 2026
`moshcode uninstall <engine|tool>` shipped in #150 and is documented in `moshcode help`, but it was never added to CORE_CLI_COMMANDS. Shell completion is generated from that roster, so tab completion did not know the command existed: `moshcode un<TAB>` offered nothing, and `moshcode uninstall <TAB>` offered no targets. The `remove` alias was missing for the same reason. completion.test.mjs already guards this ("completion schema covers every explicitly dispatched CLI command") and has been failing on main since #150 landed. Add uninstall and remove to the roster, and give uninstall a target bucket wired into the bash, zsh and fish generators. The bucket is the same ENGINES + TOOLS roster the dispatch resolves against, so every offered target is one uninstall can actually accept. Flags --yes, -y and --dry-run complete after a target. Co-authored-by: clawedassistant26 <307253840+clawedassistant26@users.noreply.github.com>
ralyodio
added a commit
that referenced
this pull request
Jul 31, 2026
* chore(release): v0.13.3 install.sh resolves releases/latest, so everything merged since v0.13.2 has been sitting on main unreachable — `moshcode dns enable` exists in the source and not in anyone's binary. The headline is the DNS bridge (#141). Moshpit names now resolve for every program on the machine, not just inside TronBrowser: each OS gets the mechanism that routes ONE SUFFIX rather than the one that replaces the resolver — /etc/resolver on macOS, systemd-resolved routing-only domains or dnsmasq on Linux, an NRPT rule per namespace on Windows. moshcode dns enable / disable / status moshcode uninstall <engine|tool> (#150, completion in #151) The pit gained most of a namespace registry in between: key pins per name (#137), pasted bulk claiming with per-line price and target (#138, #142, #143, #146), all-numeric endings (#147), /n/<name> serving a name or a directory (#145, #149), and Buy Now on an unclaimed name (#148). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: restore the em-dash the version bump escaped The bump rewrote package.json through a JSON serialiser that defaults to ASCII, turning the em-dash in `description` into —. Valid JSON and the same string once parsed, but a gratuitous diff in a commit that should touch one line. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
moshcode installhad no inverse. Removing opencode meant knowing which installer put it where — the thing the wrapper exists to spare you.Two installer shapes, one inverse
npm install -g <pkg>is undone by npm, which knows what it put where. The package name is read out of the install spec rather than duplicated, so it can't drift.A
curl … | shinstaller drops a binary and leaves no record. Removing it means finding and deleting that binary — a different kind of operation, treated like one:~/.local/bin,~/.bun/bin,/usr/local/bin, …). The question isn't "is this dangerous" but "did something we ran create this" — and only an allow-list answers that./usr/bin/opencodecame from a package manager and isn't ours to remove.--yes. Deleting a file because a flag was left off isn't a thing this should do. npm removals don't ask, since one command puts it back.Verified live
Tests
Plans are data, so every branch is tested without deleting anything. 7 tests, most about when it refuses — including that an npm entry ignores a
/usr/binpath that the binary branch would reject.Also exports
resolveExecutablefromengines.mjs, which was module-private.🤖 Generated with Claude Code