- Add confirm_purge_cleanup() to show item count + size and require
explicit Enter/y confirmation before any deletion
- Two-pass layout in clean_project_artifacts: pass 1 collects data,
pre-scan finds max path and artifact widths, pass 2 formats with
consistent column alignment across all rows
- Adaptive footer hints in select_purge_categories degrade gracefully
on narrow terminals (full → reduced → minimal)
- Use printf '\033[J' to clear stale content when list height shrinks
- Guard empty-array expansions with ${arr[*]-} for set -u safety
- Add BATS tests for confirm_purge_cleanup (Enter confirm, ESC cancel)
- Capture terminal width in parent before forking; avoids unreliable
tput calls inside the background subshell
- Write spinner output directly to /dev/tty to prevent stdout state
contention between parent and background processes
- Use \033[2K (erase entire line) instead of \033[K (erase to EOL)
- Add handle_interrupt() so Ctrl-C cleanly stops spinner, restores
cursor, and exits 130
- cleanup_monitor now writes \r\033[2K\n so subsequent output starts
on a clean line rather than on the cleared spinner line
- Fix Messages running check to not skip CrashReporter/idleassetsd cleanup
- Add proper spacing between function definitions
- Add app_support_item_size_bytes() for accurate size calculation
- Improve progress reporting during Application Support scan
Replace du traversal + double find with single find -print0 + stat -f%z
to eliminate 8+ minute hang on directories with 392K files. Add progress
feedback via update_progress_if_needed in the outer loop.
The dry-run mode hardcoded SYSTEM_CLEAN=false, which meant
the entire system section was silently skipped during preview.
Users had no way to see what /Library/Caches, /private/var/log,
diagnostics, or other sudo-required paths would be cleaned.
Now dry-run checks for a cached sudo session (sudo -n) and
includes the system preview when available. When sudo isn't
cached, a hint tells the user how to get the full preview
without running the whole script as root.
- reduce noisy scan output outside debug mode
- consolidate final result messaging
- run xcode/code editor stages explicitly in developer flow
- update dev cache tests for new stage calls