SIGN IN SIGN UP
tw93 / Mole UNCLAIMED

🐹 Deep clean and optimize your Mac.

0 0 83 Shell

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