Search before asking
Motivation
Pake turns any URL into a desktop app, but once the app is installed there is no way to uninstall it from the Pake CLI. Users have to manually delete the .app from /Applications, the .msi from the build folder, the .deb/.rpm via dpkg/rpm, plus the data directories under ~/Library/Caches/<productName>, %APPDATA%/<productName>, ~/.config/<productName>, etc. This is error-prone, leaves residue on disk, and there is no discoverable way to know which Pake build produced which app.
Solution
Add a new pake uninstall [<name>] subcommand. Each successful pake <url> --name <name> build writes metadata to a per-user registry:
- Linux:
~/.config/pake/history.json
- macOS:
~/Library/Application Support/pake/history.json
- Windows:
%APPDATA%/pake/history.json
The subcommand then:
- With no argument: shows an interactive
prompts selector with all registered apps, lets the user pick one, then a multiselect to choose which categories to remove (binary / cache / config).
- With a name: skips the list and goes directly to category selection.
Before any destructive action, a preview of exact paths/commands is shown and an explicit confirmation is required.
Per-platform removal:
- macOS:
rm -rf of the .app in /Applications and the .dmg/.app artifact; data dirs under ~/Library/Application Support/<productName> and ~/Library/Caches/<productName>.
- Windows: tries
msiexec /x {ProductCode} if it can be resolved, otherwise falls back to rm of the .msi/.exe artifact; data dirs under %APPDATA%/<productName> and %LOCALAPPDATA%/<productName>. The Windows Registry is not modified beyond the ProductCode lookup.
- Linux (.deb):
sudo dpkg --remove pake-<normalized-name>. If it fails, abort the whole uninstall — no config/cache wipe.
- Linux (.rpm):
sudo rpm --erase pake-<normalized-name>. Same abort semantics.
- Linux (AppImage / raw binary):
rm -f <output_path>.
- Linux data dirs (all variants):
~/.config/<productName> and ~/.cache/<productName> removed after binary removal succeeds.
Multi-target entries (e.g. an app built as both .deb and .rpm) remove all targets; config/cache are removed once at the end.
Failure semantics:
- Targets already manually deleted outside Pake: warn and continue, exit 0.
- Linux package manager failure: abort, exit 3.
- User cancellation at any prompt: exit 2, no state changes.
- Name not found: exit 1, registry unchanged.
- Corrupt/unreadable registry: exit 1, no destructive action.
Alternatives considered
- Manual deletion (the current state) — error-prone, leaves residue, no discoverability. This is what the issue is trying to fix.
- Add an uninstall command inside the Rust/Tauri runtime of the packaged app — rejected, out of scope. Pake's app lifecycle is CLI-side; the packaged app is a generic WebKit/WebView2 shell, so uninstall belongs in
bin/, not src-tauri/.
- Use a TUI library like
blessed or ink — rejected; the existing prompts library covers the interactive flows we need (select, multiselect, confirm) and keeps the dependency footprint unchanged.
- Shell-script-only uninstall (a separate
scripts/uninstall.sh invoked manually) — rejected; the user's pain point is "I don't know how to uninstall", and a script they have to discover does not solve that.
Anything else?
A formal spec, design, and task breakdown for this feature are tracked via Spec-Driven Development locally. The full requirements (18) and scenarios (~75) cover registry creation/updates, the interactive flow, per-platform mechanics, multi-target entries, errors, and cleanup. The spec can be pasted in a follow-up comment if it helps reviewers. I'm willing to submit a PR with the implementation once the approach is confirmed.
Are you willing to submit a PR?
Search before asking
Motivation
Pake turns any URL into a desktop app, but once the app is installed there is no way to uninstall it from the Pake CLI. Users have to manually delete the
.appfrom/Applications, the.msifrom the build folder, the.deb/.rpmviadpkg/rpm, plus the data directories under~/Library/Caches/<productName>,%APPDATA%/<productName>,~/.config/<productName>, etc. This is error-prone, leaves residue on disk, and there is no discoverable way to know which Pake build produced which app.Solution
Add a new
pake uninstall [<name>]subcommand. Each successfulpake <url> --name <name>build writes metadata to a per-user registry:~/.config/pake/history.json~/Library/Application Support/pake/history.json%APPDATA%/pake/history.jsonThe subcommand then:
promptsselector with all registered apps, lets the user pick one, then a multiselect to choose which categories to remove (binary/cache/config).Before any destructive action, a preview of exact paths/commands is shown and an explicit confirmation is required.
Per-platform removal:
rm -rfof the.appin/Applicationsand the.dmg/.appartifact; data dirs under~/Library/Application Support/<productName>and~/Library/Caches/<productName>.msiexec /x {ProductCode}if it can be resolved, otherwise falls back tormof the.msi/.exeartifact; data dirs under%APPDATA%/<productName>and%LOCALAPPDATA%/<productName>. The Windows Registry is not modified beyond the ProductCode lookup.sudo dpkg --remove pake-<normalized-name>. If it fails, abort the whole uninstall — no config/cache wipe.sudo rpm --erase pake-<normalized-name>. Same abort semantics.rm -f <output_path>.~/.config/<productName>and~/.cache/<productName>removed after binary removal succeeds.Multi-target entries (e.g. an app built as both
.deband.rpm) remove all targets; config/cache are removed once at the end.Failure semantics:
Alternatives considered
bin/, notsrc-tauri/.blessedorink— rejected; the existingpromptslibrary covers the interactive flows we need (select, multiselect, confirm) and keeps the dependency footprint unchanged.scripts/uninstall.shinvoked manually) — rejected; the user's pain point is "I don't know how to uninstall", and a script they have to discover does not solve that.Anything else?
A formal spec, design, and task breakdown for this feature are tracked via Spec-Driven Development locally. The full requirements (18) and scenarios (~75) cover registry creation/updates, the interactive flow, per-platform mechanics, multi-target entries, errors, and cleanup. The spec can be pasted in a follow-up comment if it helps reviewers. I'm willing to submit a PR with the implementation once the approach is confirmed.
Are you willing to submit a PR?