fix(uninstall): preserve independent CLI tool dotdirs (#993) (#994)
* fix(uninstall): preserve independent CLI tool dotdirs (#993) find_app_files() built XDG-style deletion candidates (~/.config/<name>, ~/.local/share/<name>, ~/.<name>) from a GUI app's display name. When the display name collides with an independently-shipped CLI tool, uninstalling the GUI app silently deleted the CLI's entire state directory. Observed: - Uninstalling Claude.app wiped ~/.claude (Claude Code CLI: projects, skills, plugins, accumulated cross-project memory). - Uninstalling OpenCode.app wiped ~/.local/share/opencode, ~/.config/opencode and the opencode binary. Case-insensitive APFS amplified the Claude case: $HOME/.Claude built from app_name="Claude" aliases to $HOME/.claude. Fix: introduce INDEPENDENT_CLI_DOTDIR_NAMES (claude, opencode, codex, gemini) and a _path_belongs_to_independent_cli helper that find_app_files consults after the existing empty-name safety check. Match is lowercase + leading-dot-stripped and scoped to $HOME, $HOME/.config, $HOME/.local/share, $HOME/.cache so case-insensitive collisions are caught without affecting unrelated paths. The deny-list is intentionally tight; Maestro Studio / Zed / Firefox style XDG cleanup (#377) is unaffected and is covered by a regression test. Tests: tests/uninstall_naming_variants.bats — 4 new cases (Claude preservation, opencode preservation across all three XDG roots, codex preservation, Zed XDG cleanup still works). bats reports 16/16 passing. Closes #993. * fix(uninstall): inline deny-list so bats subshells keep the safeguard The helper iterated INDEPENDENT_CLI_DOTDIR_NAMES, which is a readonly array declared in app_protection_data.sh. Bats 1.x carries readonly scalar reentry guards from setup() into the @test body but not readonly arrays, so once find_app_files reached the helper the array was undeclared and set -u tripped "unbound variable" on every protected case. The deny-list staying live in fresh bats subshells is also more robust than relying on the data file being re-sourced. Inline the four names in the helper and keep the array in the data file as a discoverability anchor (with a sync note in the helper). Restores maestro-studio / Firefox Developer Edition / Claude / OpenCode / Codex / Zed Nightly tests. --------- Co-authored-by: Tw93 <hitw93@gmail.com>
J
Jiawee committed
3fa3eb5cecbf1ba7367f1bf14a853cda3c2a3834
Parent: d822064
Committed by GitHub <noreply@github.com>
on 5/28/2026, 8:06:02 AM