From 9cd47133d116f5eac49da8a5db388fd46d8ac259 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:19:54 +0000 Subject: [PATCH 1/7] chore: update contributors [skip ci] --- CONTRIBUTORS.svg | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTORS.svg b/CONTRIBUTORS.svg index f74fcb4..e4df547 100644 --- a/CONTRIBUTORS.svg +++ b/CONTRIBUTORS.svg @@ -1,4 +1,4 @@ - + @@ -35,6 +35,17 @@ + + + + + + + + dwjoss + + + @@ -45,7 +56,7 @@ alexandear - + @@ -56,7 +67,7 @@ iamxorum - + @@ -67,17 +78,6 @@ amanthanvi - - - - - - - - - dwjoss - - From 37e6994c3452de0f56985eec2df9467aceb9ceeb Mon Sep 17 00:00:00 2001 From: tw93 Date: Tue, 27 Jan 2026 11:34:21 +0800 Subject: [PATCH 2/7] feat(clean): add Yandex Browser cache cleanup support --- lib/clean/user.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/clean/user.sh b/lib/clean/user.sh index 591bf19..50d8f31 100644 --- a/lib/clean/user.sh +++ b/lib/clean/user.sh @@ -473,6 +473,12 @@ clean_browsers() { safe_clean ~/Library/Caches/company.thebrowser.Browser/* "Arc cache" safe_clean ~/Library/Caches/company.thebrowser.dia/* "Dia cache" safe_clean ~/Library/Caches/BraveSoftware/Brave-Browser/* "Brave cache" + # Yandex Browser. + safe_clean ~/Library/Caches/Yandex/YandexBrowser/* "Yandex cache" + safe_clean ~/Library/Application\ Support/Yandex/YandexBrowser/ShaderCache/* "Yandex shader cache" + safe_clean ~/Library/Application\ Support/Yandex/YandexBrowser/GrShaderCache/* "Yandex GR shader cache" + safe_clean ~/Library/Application\ Support/Yandex/YandexBrowser/GraphiteDawnCache/* "Yandex Dawn cache" + safe_clean ~/Library/Application\ Support/Yandex/YandexBrowser/*/GPUCache/* "Yandex GPU cache" local firefox_running=false if pgrep -x "Firefox" > /dev/null 2>&1; then firefox_running=true From 736bca14b5122199f975df87f5897d16664988b0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:34:41 +0000 Subject: [PATCH 3/7] chore: update contributors [skip ci] --- CONTRIBUTORS.svg | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTORS.svg b/CONTRIBUTORS.svg index e4df547..dbfb58f 100644 --- a/CONTRIBUTORS.svg +++ b/CONTRIBUTORS.svg @@ -1,4 +1,4 @@ - + @@ -35,17 +35,6 @@ - - - - - - - - dwjoss - - - @@ -56,7 +45,7 @@ alexandear - + @@ -67,6 +56,17 @@ iamxorum + + + + + + + + + dwjoss + + From 9a109b2b39d01594ec4e3172b228265ef9ba558e Mon Sep 17 00:00:00 2001 From: Gokul <43350089+gokulp01@users.noreply.github.com> Date: Tue, 27 Jan 2026 05:42:54 -0600 Subject: [PATCH 4/7] fix(clean): handle singular 4K movie summary (#376) --- bin/clean.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/clean.sh b/bin/clean.sh index 8f700c1..0c789b0 100755 --- a/bin/clean.sh +++ b/bin/clean.sh @@ -1046,7 +1046,11 @@ perform_cleanup() { local movies movies=$(echo "$freed_gb" | awk '{printf "%.0f", $1/4.5}') if [[ $movies -gt 0 ]]; then - summary_details+=("Equivalent to ~$movies 4K movies of storage.") + if [[ $movies -eq 1 ]]; then + summary_details+=("Equivalent to ~$movies 4K movie of storage.") + else + summary_details+=("Equivalent to ~$movies 4K movies of storage.") + fi fi fi From 54259d6df1c1aa240697848da6a21eec92023149 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 11:43:12 +0000 Subject: [PATCH 5/7] chore: update contributors [skip ci] --- CONTRIBUTORS.svg | 137 +++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/CONTRIBUTORS.svg b/CONTRIBUTORS.svg index dbfb58f..9daf3c1 100644 --- a/CONTRIBUTORS.svg +++ b/CONTRIBUTORS.svg @@ -1,4 +1,4 @@ - + @@ -35,6 +35,17 @@ + + + + + + + + dwjoss + + + @@ -45,7 +56,7 @@ alexandear - + @@ -56,17 +67,6 @@ iamxorum - - - - - - - - - dwjoss - - @@ -157,68 +157,68 @@ - + - - - NanmiCoder + + + ndbroadbent - + - - - purofle + + + shakeelmohamed - + - - - huyixi + + + Sizk - + - - - frozturk + + + thijsvanhal - + - - - bunizao + + + TomP0 - + - - - bikraj2 + + + yuzeguitarist @@ -234,68 +234,68 @@ - + - - - yuzeguitarist + + + bikraj2 - + - - - TomP0 + + + bunizao - + - - - thijsvanhal + + + frozturk - + - - - Sizk + + + huyixi - + - - - shakeelmohamed + + + purofle - + - - - ndbroadbent + + + NanmiCoder @@ -398,6 +398,17 @@ + + + + + + + + gokulp01 + + + @@ -408,7 +419,7 @@ Copper-Eye - + @@ -419,7 +430,7 @@ ClathW - + From 8b9436e244cb744d149d5c4a43fb4e9358b1c32f Mon Sep 17 00:00:00 2001 From: tw93 Date: Tue, 27 Jan 2026 20:04:29 +0800 Subject: [PATCH 6/7] feat(check): detect third-party firewalls before built-in check (#374) Support Little Snitch, LuLu, Radio Silence, Hands Off!, Murus, Vallum. --- lib/check/all.sh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/check/all.sh b/lib/check/all.sh index e2324e3..ee100cd 100644 --- a/lib/check/all.sh +++ b/lib/check/all.sh @@ -112,8 +112,31 @@ check_filevault() { check_firewall() { # Check whitelist if command -v is_whitelisted > /dev/null && is_whitelisted "firewall"; then return; fi - # Check firewall status using socketfilterfw (more reliable than defaults on modern macOS) + unset FIREWALL_DISABLED + + # Check third-party firewalls first (lightweight path-based detection, no sudo required) + local third_party_firewall="" + if [[ -d "/Applications/Little Snitch.app" ]] || [[ -d "/Library/Little Snitch" ]]; then + third_party_firewall="Little Snitch" + elif [[ -d "/Applications/LuLu.app" ]]; then + third_party_firewall="LuLu" + elif [[ -d "/Applications/Radio Silence.app" ]]; then + third_party_firewall="Radio Silence" + elif [[ -d "/Applications/Hands Off!.app" ]]; then + third_party_firewall="Hands Off!" + elif [[ -d "/Applications/Murus.app" ]]; then + third_party_firewall="Murus" + elif [[ -d "/Applications/Vallum.app" ]]; then + third_party_firewall="Vallum" + fi + + if [[ -n "$third_party_firewall" ]]; then + echo -e " ${GREEN}✓${NC} Firewall ${third_party_firewall} active" + return + fi + + # Fall back to macOS built-in firewall check local firewall_output=$(sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate 2> /dev/null || echo "") if [[ "$firewall_output" == *"State = 1"* ]] || [[ "$firewall_output" == *"State = 2"* ]]; then echo -e " ${GREEN}✓${NC} Firewall Network protection enabled" From 7760b36c742d159ea40dc9f6e80db6fb6dcb9768 Mon Sep 17 00:00:00 2001 From: tw93 Date: Tue, 27 Jan 2026 20:22:30 +0800 Subject: [PATCH 7/7] Update Security Review --- SECURITY_AUDIT.md | 70 ++++++++++++----------------------------------- 1 file changed, 17 insertions(+), 53 deletions(-) diff --git a/SECURITY_AUDIT.md b/SECURITY_AUDIT.md index af3069d..3604c19 100644 --- a/SECURITY_AUDIT.md +++ b/SECURITY_AUDIT.md @@ -64,13 +64,15 @@ See `lib/core/app_protection.sh:find_app_files()`. ## Protected Categories -| Category | What's protected | -| -------- | ---------------- | -| System | Control Center, System Settings, TCC, `/Library/Updates`, Spotlight | -| VPN/Proxy | Shadowsocks, V2Ray, Tailscale, Clash | -| AI | Cursor, Claude, ChatGPT, Ollama, LM Studio | -| Time Machine | Checks if backup is running. If status unclear, skips cleanup. | -| Startup | `com.apple.*` LaunchAgents/Daemons always skipped | +System stuff stays untouched: Control Center, System Settings, TCC, Spotlight, `/Library/Updates`. + +VPN and proxy tools are skipped: Shadowsocks, V2Ray, Tailscale, Clash. + +AI tools are protected: Cursor, Claude, ChatGPT, Ollama, LM Studio. + +Time Machine backups running? Won't clean. Status unclear? Also won't clean. + +`com.apple.*` LaunchAgents/Daemons are never touched. See `lib/core/app_protection.sh:is_critical_system_component()`. @@ -87,12 +89,7 @@ Code at `cmd/analyze/*.go`. ## Timeouts -| Operation | Timeout | Why | -| --------- | ------- | --- | -| Network volume check | 5s | NFS/SMB/AFP can hang forever | -| App bundle search | 10s | mdfind sometimes stalls | -| SQLite vacuum | 20s | Skip if Mail/Safari/Messages is open | -| dyld cache rebuild | 180s | Skip if done in last 24h | +Network volume checks timeout after 5s (NFS/SMB/AFP can hang forever). mdfind searches get 10s. SQLite vacuum gets 20s, skipped if Mail/Safari/Messages is open. dyld cache rebuild gets 180s, skipped if done in the last 24h. See `lib/core/base.sh:run_with_timeout()`. @@ -112,18 +109,12 @@ Run `mo clean --dry-run` or `mo optimize --dry-run` to preview what would happen ## Testing -| Area | Coverage | -| ---- | -------- | -| File ops | 95% | -| Cleaning | 87% | -| Optimize | 82% | -| System | 90% | -| Security | 100% | +180+ test cases, roughly 88% coverage overall. Security stuff is 100% covered, file ops 95%, cleaning 87%, optimize 82%, system 90%. -180+ test cases total, about 88% coverage. +Run tests: ```bash -bats tests/ # run all +bats tests/ # all bats tests/security.bats # security only ``` @@ -131,39 +122,12 @@ CI runs shellcheck and go vet on every push. ## Dependencies -System binaries used, all SIP protected: +System binaries we use are all SIP protected: `plutil` (plist validation), `tmutil` (Time Machine), `dscacheutil` (cache rebuild), `diskutil` (volume info). -| Binary | For | -| ------ | --- | -| `plutil` | plist validation | -| `tmutil` | Time Machine | -| `dscacheutil` | cache rebuild | -| `diskutil` | volume info | - -Go libs in analyze-go: - -| Lib | Version | License | -| --- | ------- | ------- | -| `bubbletea` | v0.23+ | MIT | -| `lipgloss` | v0.6+ | MIT | -| `gopsutil` | v3.22+ | BSD-3 | -| `xxhash` | v2.2+ | BSD-2 | - -Versions are pinned. No CVEs. Binaries built via GitHub Actions. +Go deps: bubbletea v0.23+, lipgloss v0.6+, gopsutil v3.22+, xxhash v2.2+. All MIT/BSD licensed. Versions are pinned, no CVEs. Binaries built via GitHub Actions. ## Limitations -| What | Impact | Workaround | -| ---- | ------ | ---------- | -| Needs sudo for system caches | Annoying first time | Docs explain why | -| 60-day wait for orphans | Some junk stays longer | Use `mo uninstall` manually | -| No undo | Gone is gone | Use dry-run first | -| English names only | Might miss localized apps | Falls back to bundle ID | +System cache cleanup needs sudo, first time you'll get a password prompt. Orphan files wait 60 days before cleanup, use `mo uninstall` to delete manually if you're in a hurry. No undo, gone is gone, use dry-run first. Only recognizes English names, localized app names might be missed, but falls back to bundle ID. -**Won't touch:** - -- Your documents or media -- Password managers or keychains -- Files under `/etc` -- Browser history/cookies -- Git repos +Won't touch: documents, media files, password managers, keychains, configs under `/etc`, browser history/cookies, git repos.