mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 16:49:41 +00:00
feat: enhance system protection by adding critical path safeguards and removing problematic Spotlight and Finder/Dock cleanups.
This commit is contained in:
21
bin/clean.sh
21
bin/clean.sh
@@ -221,23 +221,10 @@ safe_clean() {
|
||||
for path in "${targets[@]}"; do
|
||||
local skip=false
|
||||
|
||||
# Hard-coded protection for critical apps (cannot be disabled by user)
|
||||
case "$path" in
|
||||
*clash* | *Clash* | *surge* | *Surge* | *mihomo* | *openvpn* | *OpenVPN* | *verge* | *Verge* | *shadowsocks* | *Shadowsocks* | *v2ray* | *V2Ray* | *sing-box* | *tailscale* | *nordvpn* | *NordVPN* | *expressvpn* | *ExpressVPN* | *protonvpn* | *ProtonVPN* | *mullvad* | *Mullvad* | *hiddify* | *Hiddify* | *loon* | *Loon* | *Cursor* | *cursor* | *Claude* | *claude* | *ChatGPT* | *chatgpt* | *Ollama* | *ollama* | *lmstudio* | *Chatbox* | *Gemini* | *gemini* | *Perplexity* | *perplexity* | *Windsurf* | *windsurf* | *Poe* | *poe* | *DiffusionBee* | *diffusionbee* | *DrawThings* | *drawthings* | *Aerial* | *aerial* | *Fliqlo* | *fliqlo* | *com.apple.finder* | *com.apple.Settings* | *com.apple.SystemSettings* | *com.apple.controlcenter*)
|
||||
skip=true
|
||||
((skipped_count++))
|
||||
;;
|
||||
esac
|
||||
|
||||
# Protect system app containers from accidental cleanup
|
||||
# Extract bundle ID from ~/Library/Containers/<bundle_id>/... paths
|
||||
if [[ "$path" == */Library/Containers/* ]] && [[ "$path" =~ /Library/Containers/([^/]+)/ ]]; then
|
||||
local container_bundle_id="${BASH_REMATCH[1]}"
|
||||
if should_protect_data "$container_bundle_id"; then
|
||||
debug_log "Protecting system container: $container_bundle_id"
|
||||
skip=true
|
||||
((skipped_count++))
|
||||
fi
|
||||
# Centralized protection for critical apps and system components
|
||||
if should_protect_path "$path"; then
|
||||
skip=true
|
||||
((skipped_count++))
|
||||
fi
|
||||
|
||||
[[ "$skip" == "true" ]] && continue
|
||||
|
||||
@@ -184,6 +184,12 @@ cleanup_path() {
|
||||
return
|
||||
fi
|
||||
|
||||
# Centralized protection check
|
||||
if should_protect_path "$expanded_path"; then
|
||||
echo -e "${YELLOW}${ICON_WARNING}${NC} Protected $label"
|
||||
return
|
||||
fi
|
||||
|
||||
local size_kb
|
||||
size_kb=$(get_path_size_kb "$expanded_path")
|
||||
local size_display=""
|
||||
|
||||
@@ -129,7 +129,6 @@ EOF
|
||||
items+=('log_cleanup|Diagnostics Cleanup|Purge old diagnostic & crash logs|true')
|
||||
items+=('mail_downloads|Mail Downloads|Clear old mail attachments (> 30 days)|true')
|
||||
items+=('swap_cleanup|Swap Refresh|Reset swap files and dynamic pager|true')
|
||||
items+=('spotlight_cache_cleanup|Spotlight Cache|Clear user-level Spotlight indexes|true')
|
||||
items+=('developer_cleanup|Developer Cleanup|Clear Xcode DerivedData & DeviceSupport|true')
|
||||
items+=('network_optimization|Network Optimization|Flush DNS, ARP & reset mDNS|true')
|
||||
|
||||
|
||||
@@ -81,9 +81,10 @@ clean_finder_metadata() {
|
||||
# Clean macOS system caches
|
||||
clean_macos_system_caches() {
|
||||
safe_clean ~/Library/Saved\ Application\ State/* "Saved application states"
|
||||
safe_clean ~/Library/Caches/com.apple.spotlight "Spotlight cache"
|
||||
|
||||
# MOVED: Spotlight cache cleanup moved to optimize command
|
||||
# REMOVED: Spotlight cache cleanup can cause system UI issues
|
||||
# Spotlight indexes should be managed by macOS automatically
|
||||
# safe_clean ~/Library/Caches/com.apple.spotlight "Spotlight cache"
|
||||
|
||||
safe_clean ~/Library/Caches/com.apple.photoanalysisd "Photo analysis cache"
|
||||
safe_clean ~/Library/Caches/com.apple.akd "Apple ID cache"
|
||||
|
||||
@@ -164,16 +164,19 @@ readonly DATA_PROTECTED_BUNDLES=(
|
||||
"com.telerik.Fiddler" # Fiddler
|
||||
"com.usebruno.app" # Bruno (API client)
|
||||
|
||||
# Network Proxy & VPN Tools (protect all variants)
|
||||
# ============================================================================
|
||||
# Network Proxy & VPN Tools (Broad Glob Protection)
|
||||
# ============================================================================
|
||||
# Clash variants
|
||||
"*clash*" # All Clash variants (ClashX, ClashX Pro, Clash Verge, etc)
|
||||
"*Clash*" # Capitalized variants
|
||||
"*clash-verge*" # Explicit Clash Verge protection
|
||||
"*verge*" # Verge variants (lowercase)
|
||||
"*Verge*" # Verge variants (capitalized)
|
||||
"com.nssurge.surge-mac" # Surge
|
||||
"*surge*" # Surge variants
|
||||
"*Surge*" # Surge variants
|
||||
"mihomo*" # Mihomo Party and variants
|
||||
"*openvpn*" # OpenVPN Connect and variants
|
||||
"*OpenVPN*" # OpenVPN capitalized variants
|
||||
"net.openvpn.*" # OpenVPN bundle IDs
|
||||
|
||||
# Proxy Clients (Shadowsocks, V2Ray, etc)
|
||||
"*ShadowsocksX-NG*" # ShadowsocksX-NG
|
||||
@@ -207,7 +210,12 @@ readonly DATA_PROTECTED_BUNDLES=(
|
||||
"*windscribe*" # Windscribe
|
||||
"*mullvad*" # Mullvad
|
||||
"*privateinternetaccess*" # PIA
|
||||
"net.openvpn.*" # OpenVPN bundle IDs
|
||||
|
||||
# Screensaver & Dynamic Wallpaper
|
||||
"*Aerial*" # Aerial screensaver (all case variants)
|
||||
"*aerial*" # Aerial lowercase
|
||||
"*Fliqlo*" # Fliqlo screensaver (all case variants)
|
||||
"*fliqlo*" # Fliqlo lowercase
|
||||
|
||||
# ============================================================================
|
||||
# Development Tools - Git & Version Control
|
||||
@@ -469,6 +477,79 @@ should_protect_data() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if a specific path should be protected from deletion
|
||||
# Centralized logic to protect system settings, control center, and critical apps
|
||||
#
|
||||
# Args: $1 - path to check
|
||||
# Returns: 0 if protected, 1 if safe to delete
|
||||
should_protect_path() {
|
||||
local path="$1"
|
||||
[[ -z "$path" ]] && return 1
|
||||
|
||||
local path_lower
|
||||
path_lower=$(echo "$path" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# 1. Check for explicit critical system keywords in path (case-insensitive)
|
||||
# Protect System Settings, Preferences, Control Center, and related XPC services
|
||||
if [[ "$path_lower" =~ systemsettings || "$path_lower" =~ systempreferences || "$path_lower" =~ controlcenter ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 2. Protect system-critical cache directories that cause UI corruption
|
||||
# These caches are essential for modern macOS (Sonoma/Sequoia) system UI rendering
|
||||
case "$path" in
|
||||
# System Settings and Control Center caches (CRITICAL - prevents blank panel bug)
|
||||
*com.apple.systempreferences.cache* | *com.apple.Settings.cache* | *com.apple.controlcenter.cache*)
|
||||
return 0
|
||||
;;
|
||||
# Finder and Dock (system essential)
|
||||
*com.apple.finder.cache* | *com.apple.dock.cache*)
|
||||
return 0
|
||||
;;
|
||||
# System XPC services and sandboxed containers
|
||||
*/Library/Containers/com.apple.Settings* | */Library/Containers/com.apple.SystemSettings* | */Library/Containers/com.apple.controlcenter*)
|
||||
return 0
|
||||
;;
|
||||
*/Library/Group\ Containers/com.apple.systempreferences* | */Library/Group\ Containers/com.apple.Settings*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# 3. Extract bundle ID from app container/group container paths
|
||||
# Matches: .../Library/Containers/bundle.id/...
|
||||
# Matches: .../Library/Group Containers/group.id/...
|
||||
if [[ "$path" =~ /Library/Containers/([^/]+) ]] || [[ "$path" =~ /Library/Group\ Containers/([^/]+) ]]; then
|
||||
local bundle_id="${BASH_REMATCH[1]}"
|
||||
if should_protect_data "$bundle_id"; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 4. Check for specific hardcoded critical patterns
|
||||
case "$path" in
|
||||
*com.apple.Settings* | *com.apple.SystemSettings* | *com.apple.controlcenter* | *com.apple.finder*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# 5. Check the full path against protected patterns (Broad Glob Match)
|
||||
# This catches things like /Users/tw93/Library/Caches/Claude when pattern is *Claude*
|
||||
for pattern in "${SYSTEM_CRITICAL_BUNDLES[@]}" "${DATA_PROTECTED_BUNDLES[@]}"; do
|
||||
if bundle_matches_pattern "$path" "$pattern"; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
# 6. Check if the filename itself matches any protected patterns
|
||||
local filename
|
||||
filename=$(basename "$path")
|
||||
if should_protect_data "$filename"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Find and list app-related files (consolidated from duplicates)
|
||||
find_app_files() {
|
||||
local bundle_id="$1"
|
||||
|
||||
@@ -163,7 +163,6 @@ TouchID sudo check|check_touchid|config_check
|
||||
Rosetta 2 check|check_rosetta|config_check
|
||||
Git configuration check|check_git_config|config_check
|
||||
Login items check|check_login_items|config_check
|
||||
Spotlight cache cleanup|spotlight_cache|system_optimization
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
@@ -176,6 +176,10 @@ opt_saved_state_cleanup() {
|
||||
# Only delete old saved states (safety window)
|
||||
local deleted=0
|
||||
while IFS= read -r -d '' state_path; do
|
||||
# Protect system critical components
|
||||
if should_protect_path "$state_path"; then
|
||||
continue
|
||||
fi
|
||||
if safe_remove "$state_path" true; then
|
||||
((deleted++))
|
||||
fi
|
||||
@@ -188,31 +192,6 @@ opt_saved_state_cleanup() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Finder and Dock: refresh interface caches
|
||||
# REMOVED: Deleting Finder cache causes user configuration loss
|
||||
# Including window positions, sidebar settings, view preferences, icon sizes
|
||||
# Users reported losing Finder settings even with .DS_Store whitelist protection
|
||||
# Keep this function for reference but do not use in default optimizations
|
||||
opt_finder_dock_refresh() {
|
||||
echo -e "${BLUE}${ICON_ARROW}${NC} Resetting Finder & Dock caches..."
|
||||
local -a interface_targets=(
|
||||
"$HOME/Library/Caches/com.apple.finder|Finder cache"
|
||||
"$HOME/Library/Caches/com.apple.dock.iconcache|Dock icon cache"
|
||||
)
|
||||
for target in "${interface_targets[@]}"; do
|
||||
IFS='|' read -r target_path label <<< "$target"
|
||||
cleanup_path "$target_path" "$label"
|
||||
done
|
||||
|
||||
# Warn user before restarting Finder (may lose unsaved work)
|
||||
echo -e "${YELLOW}${ICON_WARNING}${NC} About to restart Finder & Dock (save any work in Finder windows)"
|
||||
sleep 2
|
||||
|
||||
killall Finder > /dev/null 2>&1 || true
|
||||
killall Dock > /dev/null 2>&1 || true
|
||||
echo -e "${GREEN}${ICON_SUCCESS}${NC} Finder & Dock relaunched"
|
||||
}
|
||||
|
||||
# Swap cleanup: reset swap files
|
||||
opt_swap_cleanup() {
|
||||
echo -e "${BLUE}${ICON_ARROW}${NC} Removing swapfiles and resetting dynamic pager..."
|
||||
@@ -352,54 +331,6 @@ opt_network_optimization() {
|
||||
}
|
||||
|
||||
# Clean Spotlight user caches
|
||||
opt_spotlight_cache_cleanup() {
|
||||
# Check whitelist
|
||||
if is_whitelisted "spotlight_cache"; then
|
||||
echo -e "${GRAY}${ICON_SUCCESS}${NC} Spotlight cache cleanup (whitelisted)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}${ICON_ARROW}${NC} Cleaning Spotlight user caches..."
|
||||
|
||||
local cleaned_count=0
|
||||
local total_size_kb=0
|
||||
|
||||
# CoreSpotlight user cache (can grow very large)
|
||||
local spotlight_cache="$HOME/Library/Metadata/CoreSpotlight"
|
||||
if [[ -d "$spotlight_cache" ]]; then
|
||||
local size_kb=$(get_path_size_kb "$spotlight_cache")
|
||||
if [[ "$size_kb" -gt 0 ]]; then
|
||||
local size_human=$(bytes_to_human "$((size_kb * 1024))")
|
||||
if safe_remove "$spotlight_cache" true; then
|
||||
echo -e " ${GREEN}${ICON_SUCCESS}${NC} CoreSpotlight cache ${GREEN}($size_human)${NC}"
|
||||
((cleaned_count++))
|
||||
((total_size_kb += size_kb))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Spotlight saved application state
|
||||
local spotlight_state="$HOME/Library/Saved Application State/com.apple.spotlight.Spotlight.savedState"
|
||||
if [[ -d "$spotlight_state" ]]; then
|
||||
local size_kb=$(get_path_size_kb "$spotlight_state")
|
||||
if [[ "$size_kb" -gt 0 ]]; then
|
||||
local size_human=$(bytes_to_human "$((size_kb * 1024))")
|
||||
if safe_remove "$spotlight_state" true; then
|
||||
echo -e " ${GREEN}${ICON_SUCCESS}${NC} Spotlight state ${GREEN}($size_human)${NC}"
|
||||
((cleaned_count++))
|
||||
((total_size_kb += size_kb))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $cleaned_count -gt 0 ]]; then
|
||||
local total_human=$(bytes_to_human "$((total_size_kb * 1024))")
|
||||
echo -e "${GREEN}${ICON_SUCCESS}${NC} Cleaned $cleaned_count items ${GREEN}($total_human)${NC}"
|
||||
echo -e "${YELLOW}${ICON_WARNING}${NC} System settings may require logout/restart to display correctly"
|
||||
else
|
||||
echo -e "${GREEN}${ICON_SUCCESS}${NC} No Spotlight caches to clean"
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute optimization by action name
|
||||
execute_optimization() {
|
||||
@@ -415,13 +346,11 @@ execute_optimization() {
|
||||
radio_refresh) opt_radio_refresh ;;
|
||||
mail_downloads) opt_mail_downloads ;;
|
||||
saved_state_cleanup) opt_saved_state_cleanup ;;
|
||||
finder_dock_refresh) opt_finder_dock_refresh ;;
|
||||
swap_cleanup) opt_swap_cleanup ;;
|
||||
startup_cache) opt_startup_cache ;;
|
||||
local_snapshots) opt_local_snapshots ;;
|
||||
developer_cleanup) opt_developer_cleanup ;;
|
||||
fix_broken_configs) opt_fix_broken_configs ;;
|
||||
spotlight_cache_cleanup) opt_spotlight_cache_cleanup ;;
|
||||
network_optimization) opt_network_optimization ;;
|
||||
*)
|
||||
echo -e "${RED}${ICON_ERROR}${NC} Unknown action: $action"
|
||||
|
||||
Reference in New Issue
Block a user