fix(completion): complete the uninstall command and its targets - #151
Merged
ralyodio merged 1 commit intoJul 31, 2026
Merged
Conversation
`moshcode uninstall <engine|tool>` shipped in moshcoder#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 moshcoder#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.
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.
The bug
uninstallshipped in #150 (af572d5) andmoshcode helpdocuments it:But it was never added to
CORE_CLI_COMMANDSinsrc/cli-schema.mjs. Shell completion is generated from that roster, so tab completion does not know the command exists. Same for theremovealias, whichbin/moshcode.mjs:294dispatches alongside it.main is currently red because of this.
completion.test.mjs:68already guards exactly this ("completion schema covers every explicitly dispatched CLI command") and has been failing since #150 landed:Reproduced before touching anything
Sourcing the real generated script in a real bash and calling the real completion function on unmodified main:
moshcode un<TAB>moshcode uninstall <TAB>moshcode remove <TAB>moshcode completion bash,zshandfisheach contained zero occurrences ofuninstallorremove.After the fix, same harness:
moshcode un<TAB>uninstallmoshcode uninstall <TAB>aider c0mpute claude codex coinpay doctl doppler gemini gh opencode privacycode railway secrets supabase tailscale turso ugigmoshcode uninstall claude --<TAB>--yes --dry-runThe fix
src/cli-schema.mjs: adduninstalland itsremovealias toCORE_CLI_COMMANDS.src/completion.mjs: add anuninstalltarget bucket and wireuninstall|removeinto the bash, zsh and fish generators, mirroring howinstallis wired.The bucket is the same
ENGINES+TOOLSroster the dispatch resolves against (Object.hasOwn(ENGINES, target) || Object.hasOwn(TOOLS, target)), so every offered target is oneuninstallwill actually accept. Engine aliases are deliberately not offered, because that lookup does not resolve them, andinstallalready behaves the same way. There is a test asserting that, so this cannot drift into offering targets that error.--yes,-yand--dry-runcomplete after a target.--yesmatters most: without it, removing a binary refuses and exits 1.25 insertions, no deletions, no behaviour change outside completion.
Tests
New
test/completion-uninstall.test.mjs, 13 tests.8 are the bug and fail before / pass after: uninstall and remove in the top-level model;
moshcode un<TAB>completing in real bash; every removable engine and tool offered; the alias completing the same set; the flags completing; zsh and fish covered too; and a copy of the dispatch-coverage guard so a future command added without completion fails next to this regression.5 are controls that pass both ways and assert the opposite direction, so the fix cannot buy a green suite by over-offering or by disturbing what already worked:
installcompletion byte-identical, no engine aliases offered, an unrelated command still completing nothing, uninstall not re-offering the roster outside the target position, and the generated bash still passingbash -n.Fail-before was measured by reverting both source files with
git checkout --: 8 fail / 5 pass unpatched, 13/13 patched.Full suite: 560 tests / 1 fail → 573 tests / 0 fail. That one failure was the pre-existing
completion.test.mjsone above, which this fixes. Baseline was measured by moving the new test file out rather than assumed.Scoped out
uninstallis not in the moshscript vocabulary, so thecliVerbssplit inhelp()is unaffected. I checked, because the comment there warns that a command missing from the roster "gets misfiled as a moshscript-only local verb" — that consequence does not apply here. The impact was confined to shell completion.