URGENT FIX: uninstall preserves user data by default (was destructive)
User reported losing 6 months of accumulated work — projects, plans, custom commands/skills, file-history, history.jsonl — because uclaude_uninstall.sh did `rm -rf ~/.claude` without warning or backup. Same destruction risk in codex/gemini/qwen uninstallers (each has its own ~/.tool-name/ dir with user data). Fix: - claude/uclaude_uninstall.sh: DEFAULT preserves projects/, history.jsonl, commands/, plans/, file-history/, plugins/. Only removes settings.json + cache/ (which Claude regenerates). settings.json backed up first. - Explicit opt-in to wipe everything: UCLAUDE_PURGE_USER_DATA=1 (and even then creates a tar backup before delete) - README guidance updated NEVER again should an uninstaller silently destroy user data. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -42,21 +42,68 @@ else
|
||||
fi
|
||||
|
||||
# ---- Remove settings ----
|
||||
# DEFAULT: PRESERVE user data (projects, history, plans, commands, plugins,
|
||||
# file-history). Only delete settings.json + cache/. User data took months
|
||||
# to accumulate — never destroy without explicit opt-in.
|
||||
#
|
||||
# Set UCLAUDE_PURGE_USER_DATA=1 to wipe the entire ~/.claude/ directory
|
||||
# (the old destructive behavior).
|
||||
|
||||
PURGE_USER_DATA="${UCLAUDE_PURGE_USER_DATA:-0}"
|
||||
TIMESTAMP=$(date +%Y%m%d%H%M%S)
|
||||
|
||||
for user_home in /root /home/*; do
|
||||
CLAUDE_DIR="$user_home/.claude"
|
||||
if [ -d "$CLAUDE_DIR" ]; then
|
||||
info "Removing $CLAUDE_DIR..."
|
||||
rm -rf "$CLAUDE_DIR"
|
||||
log "Removed $CLAUDE_DIR"
|
||||
if [ "$PURGE_USER_DATA" = "1" ]; then
|
||||
# Explicit opt-in: tar backup first, then wipe
|
||||
BACKUP_TAR="$user_home/.claude.uninstall-backup.${TIMESTAMP}.tar.gz"
|
||||
info "PURGE mode — backing up to $BACKUP_TAR before delete..."
|
||||
tar -czf "$BACKUP_TAR" -C "$user_home" .claude 2>/dev/null && \
|
||||
log "Backup saved: $BACKUP_TAR" || \
|
||||
warn "Backup failed — aborting purge to preserve data"
|
||||
if [ -f "$BACKUP_TAR" ]; then
|
||||
rm -rf "$CLAUDE_DIR"
|
||||
log "Removed $CLAUDE_DIR (restore: tar -xzf $BACKUP_TAR -C $user_home)"
|
||||
fi
|
||||
else
|
||||
# Default: preserve user data, only remove patcher-managed files
|
||||
info "Cleaning $CLAUDE_DIR (preserving user data)..."
|
||||
for f in settings.json settings.local.json .patcher.config.cache.json; do
|
||||
if [ -f "$CLAUDE_DIR/$f" ]; then
|
||||
# Backup settings.json before delete (env vars are
|
||||
# easy to recreate, but user may have customized)
|
||||
cp "$CLAUDE_DIR/$f" "$CLAUDE_DIR/${f}.uninstall.bak.${TIMESTAMP}"
|
||||
rm -f "$CLAUDE_DIR/$f"
|
||||
log "Removed $CLAUDE_DIR/$f (backup: ${f}.uninstall.bak.${TIMESTAMP})"
|
||||
fi
|
||||
done
|
||||
# Optionally clean cache/ (safe — Claude regenerates on next run)
|
||||
if [ -d "$CLAUDE_DIR/cache" ]; then
|
||||
rm -rf "$CLAUDE_DIR/cache"
|
||||
log "Removed $CLAUDE_DIR/cache (will regenerate)"
|
||||
fi
|
||||
log "PRESERVED in $CLAUDE_DIR: projects/, history.jsonl, commands/, plans/, file-history/, plugins/, etc."
|
||||
fi
|
||||
fi
|
||||
CLAUDE_JSON="$user_home/.claude.json"
|
||||
if [ -f "$CLAUDE_JSON" ]; then
|
||||
# Backup before delete (.claude.json holds onboarding + recent
|
||||
# session refs — useful to keep for restore).
|
||||
cp "$CLAUDE_JSON" "${CLAUDE_JSON}.uninstall.bak.${TIMESTAMP}"
|
||||
rm -f "$CLAUDE_JSON"
|
||||
log "Removed $CLAUDE_JSON"
|
||||
log "Removed $CLAUDE_JSON (backup: ${CLAUDE_JSON}.uninstall.bak.${TIMESTAMP})"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$PURGE_USER_DATA" != "1" ]; then
|
||||
echo
|
||||
info "User data PRESERVED. To wipe everything:"
|
||||
info " UCLAUDE_PURGE_USER_DATA=1 sudo bash uclaude_uninstall.sh"
|
||||
info "(That mode creates a tar backup first, even on purge)"
|
||||
echo
|
||||
fi
|
||||
|
||||
# ---- Remove env vars from shell rc files ----
|
||||
|
||||
for user_home in /root /home/*; do
|
||||
|
||||
Reference in New Issue
Block a user