Skip to content

Add voicemode uninstall command and clear uninstall docs - #500

Open
ai-cora wants to merge 6 commits into
masterfrom
feat/VM-1874-uninstall
Open

Add voicemode uninstall command and clear uninstall docs#500
ai-cora wants to merge 6 commits into
masterfrom
feat/VM-1874-uninstall

Conversation

@ai-cora

@ai-cora ai-cora commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a clear, scriptable uninstall path for VoiceMode, as requested in #497:

  • voicemode uninstall — top-level CLI command that removes services, config, and the ~/.voicemode footprint (with dry-run/confirmation handling for both-scopes MCP removal edge cases)
  • README uninstall section + a full footprint reference doc listing everything VoiceMode installs and where
  • Skill + slash-command coverage (/voicemode:uninstall) so Claude Code users can drive it conversationally
  • ~1,000 lines of tests covering the CLI paths

Closes #497

Status

This is up for review rather than merged: it hasn't had end-to-end testing across platforms yet. Testing and feedback from anyone who wants a clean uninstall path is very welcome — see the comment on #497.

🤖 Generated with Claude Code

mbailey and others added 6 commits July 9, 2026 02:22
Add a no-think uninstall command that reverses install.sh: stops +
removes the Whisper, Kokoro, and mlx-audio services (via the existing
*_uninstall tool fns), removes the Claude MCP registration, deletes
~/.voicemode/voicemode.env (+ legacy .voicemode.env), and finally
uninstalls the voice-mode uv tool (last, since it deletes the running
binary). Safe by default via -y/--yes confirmation; --remove-models
and --remove-all-data mirror the existing service-uninstall flags.
Errors are collected rather than aborting, and a residual-footprint
report is printed at the end. Voice profiles are always preserved
unless --remove-all-data.

Satisfies R1-R5 and R9 (CliRunner tests covering ordering, flag
forwarding, -y bypass, voices-preserved, and error collection).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Peer review (Fable-5 @ effort=max, reviews/2026-07-09T0224-impl-001/
fable-design-review.md) found impl-001 sound-with-fixes: 3 HIGH + several
MED issues. Applies the full rework required before this slice can pass.

- R10 (D1 data policy): --remove-all-data no longer overpromises -- voice
  clones (voices/ + voices.json) are NEVER auto-deleted, even with that
  flag. The flag now sweeps every other BASE_DIR entry (logs, audio,
  transcriptions, cache, models, services) truthfully, matching corrected
  help/report text. Default behavior now backs up voicemode.env (renamed
  to voicemode.env.uninstalled) instead of hard-deleting it.
- R11: tear down the 4th service, "voicemode" ("serve", the HTTP MCP
  server) -- stop + disable the launchd/systemd unit and remove the
  services/voicemode start-script dir, BEFORE package removal, via a new
  shared `_teardown_serve_service` helper.
- R12: detect a Claude Code PLUGIN install (`claude plugin list`) and
  report the manual `claude plugin uninstall voicemode` step -- `claude
  mcp remove` cannot reach plugin-registered servers.
  R13: MCP removal now tries BOTH user scope and the default/local scope.
- R14: exit non-zero when any errors were collected; skip package
  self-removal (step 6) when earlier steps errored, so the re-run path
  (`voicemode uninstall`) isn't amputated.
- R15 (D2): add `voicemode service uninstall <name>` wrapper subcommands
  (whisper/kokoro/mlx-audio via the existing `.fn` idiom, voicemode via
  the new shared teardown helper) -- resolves the deprecation strings at
  cli.py:1161 etc. that already pointed at this (until now nonexistent)
  command. Renamed the top-level command function to `voicemode_uninstall`
  (explicit `@command('uninstall')` name) so it no longer shadows kokoro's
  module-level `def uninstall`.
- R16: hardened tests against the BASE_DIR-patch invariant (added a
  `base_dir` fixture + canary assertion, isolated from conftest's
  `isolate_home_directory` fake-home scaffolding so it can't leak into
  --remove-all-data sweep tests as a false "leftover"), commented the
  load-bearing function-level BASE_DIR import, fixed the --remove-models
  help-text nit (Kokoro models too), and renamed the mislabeled ordering
  test.

35 new/updated tests (25 in test_uninstall_cli.py, 10 in the new
test_service_uninstall_cli.py). Full pytest suite green: 1898 passed, 59
skipped (pre-existing).
…ow-up)

Closes the one coverage gap noted in the review report card
(reviews/2026-07-09T0300-impl-001/testing.md): a real (non "not found")
claude mcp remove failure at BOTH the user and local scope must collect
into errors (surfacing via R14's non-zero exit + skip-package-removal)
rather than being silently dropped or crashing.
…nce (R6, R7, R17, R18)

- README ## Uninstall section after ## Installation Details, before
  ## Troubleshooting -- covers both install paths (Claude Code plugin
  and Python installer package), points at `voicemode uninstall` and
  its final flag semantics (D1: back up config, never auto-remove
  voice clones), and links the footprint doc.
- docs/reference/uninstall.md: comprehensive install-footprint
  reference -- the voice-mode uv tool, full ~/.voicemode/ layout,
  launchd/systemd unit names for all 4 services, MCP registration
  (both scopes) + the Claude Code plugin path, Linux sudo system
  packages per distro (install.sh:501-515), and shared tools left
  behind (uv, Homebrew+portaudio/ffmpeg, brew shellenv profile line,
  rustup, uv cache, HF hub cache).
- Wired into mkdocs.yml nav (Reference section) and the README
  Documentation list.
- CHANGELOG.md ## [Unreleased] entry (R18).

Full pytest suite green: 1899 passed, 59 skipped (docs-only change,
no runtime surface).
docs/reference/uninstall.md's "See also" link to the README used
../../README.md -- correct for raw GitHub browsing (docs/reference/ ->
project root is two hops) but wrong inside the mkdocs-built site, where
docs/gen_pages.py copies the root README.md into the virtual docs tree
at docs/README.md (one level above docs/reference/). Confirmed against
the existing docs/.archive/uv.md convention (../README.md from one
level under docs/). `mkdocs build --strict` warnings: 22 with the bug
(21 pre-existing + this one), 21 without (matches pre-impl-002
baseline at 3762891) -- no new warnings from this feature now.
Add uninstall guidance to .claude/skills/voicemode/SKILL.md (new
"Uninstalling" section + Documentation Index entry), create
.claude/commands/uninstall.md mirroring install.md's structure, and
add a pointer to uninstall from .claude/commands/install.md.

Covers the Claude Code plugin uninstall path (`claude plugin uninstall`)
as a first-class route alongside `voicemode uninstall`, per R19 --
plugin-managed MCP registrations aren't visible to `claude mcp remove`.
Reflects the final impl-001 flag semantics (D1): config backed up not
deleted, voice clones never auto-removed, dual-scope MCP removal.

Full pytest suite green: 1899 passed, 59 skipped (docs/skill-only diff,
no runtime surface).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants