diff --git a/lib/check/health_json.sh b/lib/check/health_json.sh index 559a817..fa6bcf5 100644 --- a/lib/check/health_json.sh +++ b/lib/check/health_json.sh @@ -124,10 +124,13 @@ EOF # Always-on items (no size checks - instant) items+=('system_maintenance|System Maintenance|Rebuild system databases & flush caches|true') - items+=('maintenance_scripts|Maintenance Scripts|Run daily/weekly/monthly scripts & rotate logs|true') + items+=('maintenance_scripts|Maintenance Scripts|Rotate system logs|true') items+=('recent_items|Recent Items|Clear recent apps/documents/servers lists|true') items+=('log_cleanup|Diagnostics Cleanup|Purge old diagnostic & crash logs|true') - items+=('startup_cache|Startup Cache Rebuild|Rebuild kext caches & prelinked kernel|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|false') # Output items as JSON local first=true diff --git a/lib/manage/update.sh b/lib/manage/update.sh index 396d9a5..0838bb6 100644 --- a/lib/manage/update.sh +++ b/lib/manage/update.sh @@ -152,7 +152,7 @@ perform_updates() { local brew_output="" local brew_status=0 - if ! brew_output=$(brew upgrade 2>&1); then + if ! brew_output=$(brew upgrade --formula 2>&1); then brew_status=$? fi @@ -248,13 +248,21 @@ perform_updates() { # Update Mole if [[ -n "${MOLE_UPDATE_AVAILABLE:-}" && "${MOLE_UPDATE_AVAILABLE}" == "true" ]]; then echo -e "${BLUE}Updating Mole...${NC}" - if "${SCRIPT_DIR}/mole" update 2>&1 | grep -qE "(Updated|latest version)"; then + # Try to find mole executable + local mole_bin="${SCRIPT_DIR}/../../mole" + [[ ! -f "$mole_bin" ]] && mole_bin=$(command -v mole 2> /dev/null || echo "") + + if [[ -x "$mole_bin" ]]; then + if "$mole_bin" update 2>&1 | grep -qE "(Updated|latest version)"; then echo -e "${GREEN}✓${NC} Mole updated" reset_mole_cache ((updated_count++)) else echo -e "${RED}✗${NC} Mole update failed" fi + else + echo -e "${RED}✗${NC} Mole executable not found" + fi echo "" fi diff --git a/lib/optimize/tasks.sh b/lib/optimize/tasks.sh index 08a0d48..920abe2 100644 --- a/lib/optimize/tasks.sh +++ b/lib/optimize/tasks.sh @@ -16,45 +16,22 @@ opt_system_maintenance() { echo -e "${RED}${ICON_ERROR}${NC} Failed to clear DNS cache" fi - echo -e "${BLUE}${ICON_ARROW}${NC} Clearing memory cache..." - if sudo purge 2> /dev/null; then - echo -e "${GREEN}${ICON_SUCCESS}${NC} Memory cache cleared" - else - echo -e "${RED}${ICON_ERROR}${NC} Failed to clear memory" - fi - # Skip: Font cache rebuild breaks ScreenSaverEngine and other system components - # echo -e "${BLUE}${ICON_ARROW}${NC} Rebuilding font cache..." - # sudo atsutil databases -remove > /dev/null 2>&1 - # echo -e "${GREEN}${ICON_SUCCESS}${NC} Font cache rebuilt" - echo -e "${BLUE}${ICON_ARROW}${NC} Rebuilding Spotlight index (runs in background)..." + echo -e "${BLUE}${ICON_ARROW}${NC} Checking Spotlight index..." local md_status md_status=$(mdutil -s / 2> /dev/null || echo "") if echo "$md_status" | grep -qi "Indexing disabled"; then - echo -e "${GRAY}-${NC} Spotlight indexing disabled, skipping rebuild" + echo -e "${GRAY}-${NC} Spotlight indexing disabled" else - # mdutil triggers background indexing - don't wait - run_with_timeout 10 sudo mdutil -E / > /dev/null 2>&1 || true - echo -e "${GREEN}${ICON_SUCCESS}${NC} Spotlight rebuild initiated" + echo -e "${GREEN}${ICON_SUCCESS}${NC} Spotlight index functioning" fi echo -e "${BLUE}${ICON_ARROW}${NC} Refreshing Bluetooth services..." sudo pkill -f blued 2> /dev/null || true echo -e "${GREEN}${ICON_SUCCESS}${NC} Bluetooth controller refreshed" - # Skip: log erase --all --force deletes ALL system logs, making debugging impossible - # Users should manually manage logs if needed using: sudo log erase --all --force - # if command -v log > /dev/null 2>&1 && [[ "${MO_ENABLE_LOG_CLEANUP:-0}" == "1" ]]; then - # echo -e "${BLUE}${ICON_ARROW}${NC} Compressing system logs..." - # if command -v has_sudo_session > /dev/null 2>&1 && ! has_sudo_session; then - # echo -e "${YELLOW}!${NC} Skipped log compression ${GRAY}(admin session inactive)${NC}" - # elif run_with_timeout 15 sudo -n log erase --all --force > /dev/null 2>&1; then - # echo -e "${GREEN}${ICON_SUCCESS}${NC} logarchive trimmed" - # else - # echo -e "${YELLOW}!${NC} Skipped log compression ${GRAY}(requires Full Disk Access)${NC}" - # fi - # fi + } # Cache refresh: update Finder/Safari caches @@ -81,41 +58,12 @@ opt_cache_refresh() { # Maintenance scripts: run periodic tasks opt_maintenance_scripts() { - local success=true - local periodic_cmd="/usr/sbin/periodic" - - # Show spinner while running all tasks - if [[ -t 1 ]]; then - start_inline_spinner "" - fi - - # Run periodic scripts silently with timeout - if [[ -x "$periodic_cmd" ]]; then - if ! run_with_timeout 180 sudo "$periodic_cmd" daily weekly monthly > /dev/null 2>&1; then - success=false - fi - fi - - # Run newsyslog silently with timeout - if ! run_with_timeout 120 sudo newsyslog > /dev/null 2>&1; then - success=false - fi - - # Run repair_packages silently with timeout - if [[ -x "/usr/libexec/repair_packages" ]]; then - if ! run_with_timeout 180 sudo /usr/libexec/repair_packages --repair --standard-pkgs --volume / > /dev/null 2>&1; then - success=false - fi - fi - - if [[ -t 1 ]]; then - stop_inline_spinner - fi - - if [[ "$success" == "true" ]]; then - echo -e "${GREEN}${ICON_SUCCESS}${NC} Complete" + # Run newsyslog to rotate system logs + echo -e "${BLUE}${ICON_ARROW}${NC} Rotating system logs..." + if run_with_timeout 120 sudo newsyslog > /dev/null 2>&1; then + echo -e "${GREEN}${ICON_SUCCESS}${NC} Logs rotated" else - echo -e "${YELLOW}!${NC} Some tasks timed out or failed" + echo -e "${YELLOW}!${NC} Failed to rotate logs" fi } @@ -163,8 +111,7 @@ opt_radio_refresh() { echo -e "${BLUE}${ICON_ARROW}${NC} Refreshing Wi-Fi service..." # Only restart Wi-Fi service, do NOT delete saved networks - # Skip: Deleting airport.preferences.plist causes all saved Wi-Fi passwords to be lost - # sudo rm -f "$sysconfig"/com.apple.airport.preferences.plist + # Safe alternative: just restart the Wi-Fi interface local wifi_interface @@ -274,9 +221,7 @@ opt_finder_dock_refresh() { opt_swap_cleanup() { echo -e "${BLUE}${ICON_ARROW}${NC} Removing swapfiles and resetting dynamic pager..." if sudo launchctl unload /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist > /dev/null 2>&1; then - sudo rm -f /private/var/vm/swapfile* > /dev/null 2>&1 || true - sudo touch /private/var/vm/swapfile0 > /dev/null 2>&1 || true - sudo chmod 600 /private/var/vm/swapfile0 > /dev/null 2>&1 || true + # Safe swap reset: just restart the pager, don't manually rm files sudo launchctl load /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist > /dev/null 2>&1 || true echo -e "${GREEN}${ICON_SUCCESS}${NC} Swap cache rebuilt" else @@ -286,37 +231,9 @@ opt_swap_cleanup() { # Startup cache: rebuild kernel caches opt_startup_cache() { - local macos_version - macos_version=$(sw_vers -productVersion | cut -d '.' -f 1) - local success=true - - if [[ -t 1 ]]; then - start_inline_spinner "" - fi - - if [[ "$macos_version" -ge 11 ]] || [[ "$(uname -m)" == "arm64" ]]; then - if ! run_with_timeout 120 sudo kextcache -i / > /dev/null 2>&1; then - success=false - fi - else - if ! run_with_timeout 180 sudo kextcache -i / > /dev/null 2>&1; then - success=false - fi - - # Skip: Deleting PrelinkedKernels breaks ScreenSaverEngine and other system components - # sudo rm -rf /System/Library/PrelinkedKernels/* > /dev/null 2>&1 || true - run_with_timeout 120 sudo kextcache -system-prelinked-kernel > /dev/null 2>&1 || true - fi - - if [[ -t 1 ]]; then - stop_inline_spinner - fi - - if [[ "$success" == "true" ]]; then - echo -e "${GREEN}${ICON_SUCCESS}${NC} Complete" - else - echo -e "${YELLOW}!${NC} Timed out or failed" - fi + # kextcache/PrelinkedKernel rebuilds are legacy and heavy. + # Modern macOS (Big Sur+) handles this automatically and securely (SSV). + echo -e "${GRAY}-${NC} Startup cache rebuild skipped (handled by macOS)" } # Local snapshots: thin Time Machine snapshots