diff --git a/README.md b/README.md index c7a6ae3..55e4a92 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ - **Deep System Cleanup** - Cleans way more junk than CleanMyMac/Lemon - caches, logs, temp files - **Thorough Uninstall** - Scans 22+ locations to remove app leftovers, not just the .app file +- **System Optimization** - Rebuilds caches, resets services, and trims swap/network cruft with one run - **Interactive Disk Analyzer** - Navigate folders with arrow keys, find and delete large files quickly - **Fast & Lightweight** - Terminal-based with arrow-key navigation, pagination, and Touch ID support -- **System Optimization** - Rebuilds caches, resets services, and trims swap/network cruft with one run ## Quick Start @@ -47,8 +47,8 @@ mo clean # System cleanup mo clean --dry-run # Preview mode mo clean --whitelist # Manage protected caches mo uninstall # Uninstall apps -mo analyze # Disk analyzer mo optimize # System optimization +mo analyze # Disk analyzer mo touchid # Configure Touch ID for sudo mo update # Update Mole @@ -120,22 +120,6 @@ Space freed: 12.8GB ==================================================================== ``` -### Disk Space Analyzer - -```bash -$ mo analyze - -Analyze Disk ~/Documents | Total: 156.8GB - - ▶ 1. ███████████████████ 48.2% | 📁 Library 75.4GB >6mo - 2. ██████████░░░░░░░░░ 22.1% | 📁 Downloads 34.6GB - 3. ████░░░░░░░░░░░░░░░ 14.3% | 📁 Movies 22.4GB - 4. ███░░░░░░░░░░░░░░░░ 10.8% | 📁 Documents 16.9GB - 5. ██░░░░░░░░░░░░░░░░░ 5.2% | 📄 backup_2023.zip 8.2GB - - ↑↓←→ Navigate | O Open | F Reveal | ⌫ Delete | L Large(24) | Q Quit -``` - ### System Optimization ```bash @@ -155,6 +139,22 @@ System optimization completed ==================================================================== ``` +### Disk Space Analyzer + +```bash +$ mo analyze + +Analyze Disk ~/Documents | Total: 156.8GB + + ▶ 1. ███████████████████ 48.2% | 📁 Library 75.4GB >6mo + 2. ██████████░░░░░░░░░ 22.1% | 📁 Downloads 34.6GB + 3. ████░░░░░░░░░░░░░░░ 14.3% | 📁 Movies 22.4GB + 4. ███░░░░░░░░░░░░░░░░ 10.8% | 📁 Documents 16.9GB + 5. ██░░░░░░░░░░░░░░░░░ 5.2% | 📄 backup_2023.zip 8.2GB + + ↑↓←→ Navigate | O Open | F Reveal | ⌫ Delete | L Large(24) | Q Quit +``` + ## Support - If Mole reclaimed storage for you, consider starring the repo or sharing it with friends needing a cleaner Mac. diff --git a/bin/optimize.sh b/bin/optimize.sh index 63744d1..28bcebf 100755 --- a/bin/optimize.sh +++ b/bin/optimize.sh @@ -109,6 +109,45 @@ ensure_directory() { mkdir -p "$expanded_path" > /dev/null 2>&1 || true } +list_login_items() { + local raw_items + raw_items=$(osascript -e 'tell application "System Events" to get the name of every login item' 2> /dev/null || echo "") + [[ -z "$raw_items" || "$raw_items" == "missing value" ]] && return + + IFS=',' read -ra login_items_array <<< "$raw_items" + for entry in "${login_items_array[@]}"; do + local trimmed + trimmed=$(echo "$entry" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') + [[ -n "$trimmed" ]] && printf "%s\n" "$trimmed" + done +} + +SUDO_KEEPALIVE_PID="" + +start_sudo_keepalive() { + [[ -n "$SUDO_KEEPALIVE_PID" ]] && return + + ( + while true; do + if ! sudo -n true 2> /dev/null; then + exit 0 + fi + sleep 30 + done + ) & + SUDO_KEEPALIVE_PID=$! +} + +stop_sudo_keepalive() { + if [[ -n "$SUDO_KEEPALIVE_PID" ]]; then + kill "$SUDO_KEEPALIVE_PID" 2> /dev/null || true + wait "$SUDO_KEEPALIVE_PID" 2> /dev/null || true + SUDO_KEEPALIVE_PID="" + fi +} + +trap stop_sudo_keepalive EXIT + count_local_snapshots() { if ! command -v tmutil > /dev/null 2>&1; then echo 0 @@ -340,12 +379,6 @@ execute_optimization() { fi ;; - login_items) - echo -e "${BLUE}${ICON_ARROW}${NC} Listing login items..." - osascript -e 'tell application "System Events" to get the name of every login item' 2> /dev/null | sed 's/, /\n • /g; s/^/ • /' - echo -e "${GRAY}Use System Settings → General → Login Items to disable entries you don't need.${NC}" - ;; - startup_cache) echo -e "${BLUE}${ICON_ARROW}${NC} Rebuilding kext caches..." if sudo kextcache -i / > /dev/null 2>&1; then @@ -418,6 +451,9 @@ execute_optimization() { } main() { + if [[ -t 1 ]]; then + clear + fi print_header # Check dependencies @@ -463,8 +499,8 @@ main() { fi done < <(parse_optimizations "$health_json") - # Simple confirmation - echo -ne "${PURPLE}${ICON_ARROW}${NC} Press ${GREEN}Enter${NC} to optimize, ${GRAY}ESC${NC} to cancel: " + # Simple confirmation with sudo context + echo -ne "${PURPLE}${ICON_ARROW}${NC} System optimizations need admin access — ${GREEN}Enter${NC} Touch ID/password, ${GRAY}ESC${NC} cancel: " IFS= read -r -s -n1 key || key="" case "$key" in @@ -477,6 +513,12 @@ main() { ;; "" | $'\n' | $'\r') printf "\r\033[K" + if ! request_sudo_access "System optimizations require admin access"; then + echo "" + echo -e "${YELLOW}Authentication failed${NC}" + exit 1 + fi + start_sudo_keepalive ;; *) echo "" @@ -508,6 +550,28 @@ main() { done fi + # Show login item reminder at the end of optimization log + local -a login_items_list=() + while IFS= read -r login_item; do + [[ -n "$login_item" ]] && login_items_list+=("$login_item") + done < <(list_login_items || true) + + if (( ${#login_items_list[@]} > 0 )); then + local display_count=${#login_items_list[@]} + echo "" + echo -e "${BLUE}${ICON_ARROW}${NC} Login items (${display_count}) auto-start at login:" + local preview_limit=5 + (( preview_limit > display_count )) && preview_limit=$display_count + for ((i = 0; i < preview_limit; i++)); do + printf " • %s\n" "${login_items_list[$i]}" + done + if (( display_count > preview_limit )); then + local remaining=$((display_count - preview_limit)) + echo " • …and $remaining more" + fi + echo -e "${GRAY}Review System Settings → General → Login Items to trim extras.${NC}" + fi + echo "" local summary_title="System optimization completed" local -a summary_details=() diff --git a/lib/optimize_health.sh b/lib/optimize_health.sh index bf26548..a183a05 100755 --- a/lib/optimize_health.sh +++ b/lib/optimize_health.sh @@ -169,17 +169,6 @@ check_swap_cleanup() { fi } -# Check login items -check_login_items() { - local items - items=$(osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null || echo "") - - [[ -z "$items" || "$items" == "missing value" ]] && return - - local count=$(echo "$items" | tr ',' '\n' | grep -v '^[[:space:]]*$' | wc -l | tr -d ' ') - [[ $count -gt 0 ]] && echo "login_items|Login Items|Review ${count} login items|true" -} - # Check local snapshots check_local_snapshots() { command -v tmutil >/dev/null 2>&1 || return @@ -253,7 +242,6 @@ EOF item=$(check_mail_downloads || true); [[ -n "$item" ]] && items+=("$item") item=$(check_saved_state || true); [[ -n "$item" ]] && items+=("$item") item=$(check_swap_cleanup || true); [[ -n "$item" ]] && items+=("$item") - item=$(check_login_items || true); [[ -n "$item" ]] && items+=("$item") item=$(check_local_snapshots || true); [[ -n "$item" ]] && items+=("$item") item=$(check_developer_cleanup || true); [[ -n "$item" ]] && items+=("$item") diff --git a/mole b/mole index bdc1c06..4f8d2e7 100755 --- a/mole +++ b/mole @@ -132,11 +132,11 @@ show_help() { echo printf "%s%s%s\n" "$BLUE" "COMMANDS" "$NC" printf " %s%-28s%s %s\n" "$GREEN" "mo" "$NC" "Interactive main menu" - printf " %s%-28s%s %s\n" "$GREEN" "mo optimize" "$NC" "System health check & optimization" printf " %s%-28s%s %s\n" "$GREEN" "mo clean" "$NC" "Deeper system cleanup" printf " %s%-28s%s %s\n" "$GREEN" "mo clean --dry-run" "$NC" "Preview cleanup (no deletions)" printf " %s%-28s%s %s\n" "$GREEN" "mo clean --whitelist" "$NC" "Manage protected caches" printf " %s%-28s%s %s\n" "$GREEN" "mo uninstall" "$NC" "Remove applications completely" + printf " %s%-28s%s %s\n" "$GREEN" "mo optimize" "$NC" "System health check & optimization" printf " %s%-28s%s %s\n" "$GREEN" "mo analyze" "$NC" "Interactive disk space explorer" printf " %s%-28s%s %s\n" "$GREEN" "mo touchid" "$NC" "Configure Touch ID for sudo" printf " %s%-28s%s %s\n" "$GREEN" "mo update" "$NC" "Update Mole to the latest version" @@ -455,8 +455,8 @@ show_main_menu() { printf '\r\033[2K%s\n' "$(show_menu_option 1 "Clean Mac - Remove junk files and optimize" "$([[ $selected -eq 1 ]] && echo true || echo false)")" printf '\r\033[2K%s\n' "$(show_menu_option 2 "Uninstall Apps - Remove applications completely" "$([[ $selected -eq 2 ]] && echo true || echo false)")" - printf '\r\033[2K%s\n' "$(show_menu_option 3 "Analyze Disk - Interactive space explorer" "$([[ $selected -eq 3 ]] && echo true || echo false)")" - printf '\r\033[2K%s\n' "$(show_menu_option 4 "Optimize Mac - System health & tuning" "$([[ $selected -eq 4 ]] && echo true || echo false)")" + printf '\r\033[2K%s\n' "$(show_menu_option 3 "Optimize Mac - System health & tuning" "$([[ $selected -eq 3 ]] && echo true || echo false)")" + printf '\r\033[2K%s\n' "$(show_menu_option 4 "Analyze Disk - Interactive space explorer" "$([[ $selected -eq 4 ]] && echo true || echo false)")" if [[ -t 0 ]]; then printf '\r\033[2K\n' @@ -527,8 +527,8 @@ interactive_main_menu() { case $current_option in 1) exec "$SCRIPT_DIR/bin/clean.sh" ;; 2) exec "$SCRIPT_DIR/bin/uninstall.sh" ;; - 3) exec "$SCRIPT_DIR/bin/analyze.sh" ;; - 4) exec "$SCRIPT_DIR/bin/optimize.sh" ;; + 3) exec "$SCRIPT_DIR/bin/optimize.sh" ;; + 4) exec "$SCRIPT_DIR/bin/analyze.sh" ;; esac ;; "h" | "H") @@ -543,8 +543,8 @@ interactive_main_menu() { case $key in 1) exec "$SCRIPT_DIR/bin/clean.sh" ;; 2) exec "$SCRIPT_DIR/bin/uninstall.sh" ;; - 3) exec "$SCRIPT_DIR/bin/analyze.sh" ;; - 4) exec "$SCRIPT_DIR/bin/optimize.sh" ;; + 3) exec "$SCRIPT_DIR/bin/optimize.sh" ;; + 4) exec "$SCRIPT_DIR/bin/analyze.sh" ;; esac ;; esac