mirror of
https://github.com/tw93/Mole.git
synced 2026-02-11 15:18:59 +00:00
Merge branch 'dev'
This commit is contained in:
10
README.md
10
README.md
@@ -62,6 +62,16 @@ mo --version # Show installed version
|
|||||||
- Protect caches with `mo clean --whitelist`; defaults cover Playwright, HuggingFace, and Maven paths.
|
- Protect caches with `mo clean --whitelist`; defaults cover Playwright, HuggingFace, and Maven paths.
|
||||||
- Use `mo touchid` to approve sudo with Touch ID instead of typing your password.
|
- Use `mo touchid` to approve sudo with Touch ID instead of typing your password.
|
||||||
|
|
||||||
|
## Quick Launchers
|
||||||
|
|
||||||
|
Install Raycast integration with one command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/tw93/mole/main/integrations/setup-raycast.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
For Alfred and macOS Shortcuts, see [integrations/README.md](integrations/README.md).
|
||||||
|
|
||||||
## Features in Detail
|
## Features in Detail
|
||||||
|
|
||||||
### Deep System Cleanup
|
### Deep System Cleanup
|
||||||
|
|||||||
77
bin/clean.sh
77
bin/clean.sh
@@ -21,6 +21,13 @@ IS_M_SERIES=$([ "$(uname -m)" = "arm64" ] && echo "true" || echo "false")
|
|||||||
readonly MAX_PARALLEL_JOBS=15 # Maximum parallel background jobs
|
readonly MAX_PARALLEL_JOBS=15 # Maximum parallel background jobs
|
||||||
readonly TEMP_FILE_AGE_DAYS=7 # Age threshold for temp file cleanup
|
readonly TEMP_FILE_AGE_DAYS=7 # Age threshold for temp file cleanup
|
||||||
readonly ORPHAN_AGE_DAYS=60 # Age threshold for orphaned data
|
readonly ORPHAN_AGE_DAYS=60 # Age threshold for orphaned data
|
||||||
|
|
||||||
|
# Protected Service Worker domains (web-based editing tools)
|
||||||
|
readonly PROTECTED_SW_DOMAINS=(
|
||||||
|
"capcut.com"
|
||||||
|
"photopea.com"
|
||||||
|
"pixlr.com"
|
||||||
|
)
|
||||||
# Default whitelist patterns (preselected, user can disable)
|
# Default whitelist patterns (preselected, user can disable)
|
||||||
declare -a DEFAULT_WHITELIST_PATTERNS=(
|
declare -a DEFAULT_WHITELIST_PATTERNS=(
|
||||||
"$HOME/Library/Caches/ms-playwright*"
|
"$HOME/Library/Caches/ms-playwright*"
|
||||||
@@ -444,6 +451,54 @@ start_cleanup() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Clean Service Worker CacheStorage with domain protection
|
||||||
|
clean_service_worker_cache() {
|
||||||
|
local browser_name="$1"
|
||||||
|
local cache_path="$2"
|
||||||
|
|
||||||
|
[[ ! -d "$cache_path" ]] && return 0
|
||||||
|
|
||||||
|
local cleaned_size=0
|
||||||
|
local protected_count=0
|
||||||
|
|
||||||
|
# Find all cache directories and calculate sizes
|
||||||
|
while IFS= read -r cache_dir; do
|
||||||
|
[[ ! -d "$cache_dir" ]] && continue
|
||||||
|
|
||||||
|
# Extract domain from path
|
||||||
|
local domain=$(basename "$cache_dir" | grep -oE '[a-zA-Z0-9][-a-zA-Z0-9]*\.[a-zA-Z]{2,}' | head -1 || echo "")
|
||||||
|
local size=$(du -sk "$cache_dir" 2>/dev/null | awk '{print $1}')
|
||||||
|
|
||||||
|
# Check if domain is protected
|
||||||
|
local is_protected=false
|
||||||
|
for protected_domain in "${PROTECTED_SW_DOMAINS[@]}"; do
|
||||||
|
if [[ "$domain" == *"$protected_domain"* ]]; then
|
||||||
|
is_protected=true
|
||||||
|
protected_count=$((protected_count + 1))
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Clean if not protected
|
||||||
|
if [[ "$is_protected" == "false" ]]; then
|
||||||
|
if [[ "$DRY_RUN" != "true" ]]; then
|
||||||
|
rm -rf "$cache_dir" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
cleaned_size=$((cleaned_size + size))
|
||||||
|
fi
|
||||||
|
done < <(find "$cache_path" -type d -depth 2 2>/dev/null)
|
||||||
|
|
||||||
|
if [[ $cleaned_size -gt 0 ]]; then
|
||||||
|
local cleaned_mb=$((cleaned_size / 1024))
|
||||||
|
if [[ "$DRY_RUN" != "true" ]]; then
|
||||||
|
echo -e " ${GREEN}${ICON_SUCCESS}${NC} $browser_name Service Worker cache (${cleaned_mb}MB cleaned, $protected_count protected)"
|
||||||
|
else
|
||||||
|
echo -e " ${YELLOW}→${NC} $browser_name Service Worker cache (would clean ${cleaned_mb}MB, $protected_count protected)"
|
||||||
|
fi
|
||||||
|
note_activity
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
perform_cleanup() {
|
perform_cleanup() {
|
||||||
echo -e "${BLUE}${ICON_ADMIN}${NC} $(detect_architecture) | Free space: $(get_free_space)"
|
echo -e "${BLUE}${ICON_ADMIN}${NC} $(detect_architecture) | Free space: $(get_free_space)"
|
||||||
|
|
||||||
@@ -576,11 +631,30 @@ perform_cleanup() {
|
|||||||
|
|
||||||
safe_clean ~/Library/Caches/com.microsoft.edgemac/* "Edge cache"
|
safe_clean ~/Library/Caches/com.microsoft.edgemac/* "Edge cache"
|
||||||
safe_clean ~/Library/Caches/company.thebrowser.Browser/* "Arc cache"
|
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"
|
safe_clean ~/Library/Caches/BraveSoftware/Brave-Browser/* "Brave cache"
|
||||||
safe_clean ~/Library/Caches/Firefox/* "Firefox cache"
|
safe_clean ~/Library/Caches/Firefox/* "Firefox cache"
|
||||||
safe_clean ~/Library/Caches/com.operasoftware.Opera/* "Opera cache"
|
safe_clean ~/Library/Caches/com.operasoftware.Opera/* "Opera cache"
|
||||||
safe_clean ~/Library/Caches/com.vivaldi.Vivaldi/* "Vivaldi cache"
|
safe_clean ~/Library/Caches/com.vivaldi.Vivaldi/* "Vivaldi cache"
|
||||||
|
safe_clean ~/Library/Caches/Comet/* "Comet cache"
|
||||||
|
safe_clean ~/Library/Caches/com.kagi.kagimacOS/* "Orion cache"
|
||||||
|
safe_clean ~/Library/Caches/zen/* "Zen cache"
|
||||||
safe_clean ~/Library/Application\ Support/Firefox/Profiles/*/cache2/* "Firefox profile cache"
|
safe_clean ~/Library/Application\ Support/Firefox/Profiles/*/cache2/* "Firefox profile cache"
|
||||||
|
|
||||||
|
# Service Worker CacheStorage (all profiles)
|
||||||
|
while IFS= read -r sw_path; do
|
||||||
|
local profile_name=$(basename "$(dirname "$(dirname "$sw_path")")")
|
||||||
|
local browser_name="Chrome"
|
||||||
|
[[ "$sw_path" == *"Microsoft Edge"* ]] && browser_name="Edge"
|
||||||
|
[[ "$sw_path" == *"Brave"* ]] && browser_name="Brave"
|
||||||
|
[[ "$sw_path" == *"Arc"* ]] && browser_name="Arc"
|
||||||
|
[[ "$profile_name" != "Default" ]] && browser_name="$browser_name ($profile_name)"
|
||||||
|
clean_service_worker_cache "$browser_name" "$sw_path"
|
||||||
|
done < <(find "$HOME/Library/Application Support/Google/Chrome" \
|
||||||
|
"$HOME/Library/Application Support/Microsoft Edge" \
|
||||||
|
"$HOME/Library/Application Support/BraveSoftware/Brave-Browser" \
|
||||||
|
"$HOME/Library/Application Support/Arc/User Data" \
|
||||||
|
-type d -name "CacheStorage" -path "*/Service Worker/*" 2>/dev/null)
|
||||||
end_section
|
end_section
|
||||||
|
|
||||||
# ===== 6. Cloud Storage =====
|
# ===== 6. Cloud Storage =====
|
||||||
@@ -865,6 +939,9 @@ perform_cleanup() {
|
|||||||
safe_clean ~/Library/Caches/com.sketchup.*/* "SketchUp cache"
|
safe_clean ~/Library/Caches/com.sketchup.*/* "SketchUp cache"
|
||||||
safe_clean ~/Library/Caches/com.raycast.macos/* "Raycast cache"
|
safe_clean ~/Library/Caches/com.raycast.macos/* "Raycast cache"
|
||||||
safe_clean ~/Library/Caches/com.tw93.MiaoYan/* "MiaoYan cache"
|
safe_clean ~/Library/Caches/com.tw93.MiaoYan/* "MiaoYan cache"
|
||||||
|
safe_clean ~/Library/Caches/com.klee.desktop/* "Klee cache"
|
||||||
|
safe_clean ~/Library/Caches/klee_desktop/* "Klee desktop cache"
|
||||||
|
safe_clean ~/Library/Caches/com.orabrowser.app/* "Ora browser cache"
|
||||||
safe_clean ~/Library/Caches/com.filo.client/* "Filo cache"
|
safe_clean ~/Library/Caches/com.filo.client/* "Filo cache"
|
||||||
safe_clean ~/Library/Caches/com.flomoapp.mac/* "Flomo cache"
|
safe_clean ~/Library/Caches/com.flomoapp.mac/* "Flomo cache"
|
||||||
safe_clean ~/Library/Caches/com.spotify.client/* "Spotify cache"
|
safe_clean ~/Library/Caches/com.spotify.client/* "Spotify cache"
|
||||||
|
|||||||
43
integrations/README.md
Normal file
43
integrations/README.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Mole Integrations
|
||||||
|
|
||||||
|
Quick launcher integrations for Mole.
|
||||||
|
|
||||||
|
## Raycast
|
||||||
|
|
||||||
|
One command install:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/tw93/Mole/main/integrations/setup-raycast.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Then open Raycast and search "Reload Script Commands".
|
||||||
|
|
||||||
|
Available commands: `clean mac`, `dry run`, `uninstall apps`
|
||||||
|
|
||||||
|
## Alfred
|
||||||
|
|
||||||
|
Add a workflow with keyword `clean` and script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mo clean
|
||||||
|
```
|
||||||
|
|
||||||
|
For dry-run: `mo clean --dry-run`
|
||||||
|
|
||||||
|
For uninstall: `mo uninstall`
|
||||||
|
|
||||||
|
## macOS Shortcuts
|
||||||
|
|
||||||
|
Create a shortcut with "Run Shell Script":
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mo clean
|
||||||
|
```
|
||||||
|
|
||||||
|
Then add to Menu Bar or assign a keyboard shortcut.
|
||||||
|
|
||||||
|
## Uninstall
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf ~/Library/Application\ Support/Raycast/script-commands/mole-*.sh
|
||||||
|
```
|
||||||
32
integrations/raycast/mole-clean-dry-run.sh
Executable file
32
integrations/raycast/mole-clean-dry-run.sh
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Required parameters:
|
||||||
|
# @raycast.schemaVersion 1
|
||||||
|
# @raycast.title Clean Mac (Dry Run)
|
||||||
|
# @raycast.mode fullOutput
|
||||||
|
# @raycast.packageName Mole
|
||||||
|
|
||||||
|
# Optional parameters:
|
||||||
|
# @raycast.icon 👀
|
||||||
|
# @raycast.needsConfirmation false
|
||||||
|
|
||||||
|
# Documentation:
|
||||||
|
# @raycast.description Preview what Mole would clean without making changes
|
||||||
|
# @raycast.author tw93
|
||||||
|
# @raycast.authorURL https://github.com/tw93/Mole
|
||||||
|
|
||||||
|
# Detect mo/mole installation
|
||||||
|
if command -v mo >/dev/null 2>&1; then
|
||||||
|
MO_BIN="mo"
|
||||||
|
elif command -v mole >/dev/null 2>&1; then
|
||||||
|
MO_BIN="mole"
|
||||||
|
else
|
||||||
|
echo "❌ Mole not found. Install from:"
|
||||||
|
echo " https://github.com/tw93/Mole"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run dry-run
|
||||||
|
echo "👀 Previewing cleanup..."
|
||||||
|
echo ""
|
||||||
|
"$MO_BIN" clean --dry-run
|
||||||
32
integrations/raycast/mole-clean.sh
Executable file
32
integrations/raycast/mole-clean.sh
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Required parameters:
|
||||||
|
# @raycast.schemaVersion 1
|
||||||
|
# @raycast.title Clean Mac
|
||||||
|
# @raycast.mode fullOutput
|
||||||
|
# @raycast.packageName Mole
|
||||||
|
|
||||||
|
# Optional parameters:
|
||||||
|
# @raycast.icon 🐹
|
||||||
|
# @raycast.needsConfirmation true
|
||||||
|
|
||||||
|
# Documentation:
|
||||||
|
# @raycast.description Deep clean your Mac using Mole
|
||||||
|
# @raycast.author tw93
|
||||||
|
# @raycast.authorURL https://github.com/tw93/Mole
|
||||||
|
|
||||||
|
# Detect mo/mole installation
|
||||||
|
if command -v mo >/dev/null 2>&1; then
|
||||||
|
MO_BIN="mo"
|
||||||
|
elif command -v mole >/dev/null 2>&1; then
|
||||||
|
MO_BIN="mole"
|
||||||
|
else
|
||||||
|
echo "❌ Mole not found. Install from:"
|
||||||
|
echo " https://github.com/tw93/Mole"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run cleanup
|
||||||
|
echo "🐹 Starting cleanup..."
|
||||||
|
echo ""
|
||||||
|
"$MO_BIN" clean
|
||||||
32
integrations/raycast/mole-uninstall.sh
Executable file
32
integrations/raycast/mole-uninstall.sh
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Required parameters:
|
||||||
|
# @raycast.schemaVersion 1
|
||||||
|
# @raycast.title Uninstall Apps
|
||||||
|
# @raycast.mode fullOutput
|
||||||
|
# @raycast.packageName Mole
|
||||||
|
|
||||||
|
# Optional parameters:
|
||||||
|
# @raycast.icon 🗑️
|
||||||
|
# @raycast.needsConfirmation true
|
||||||
|
|
||||||
|
# Documentation:
|
||||||
|
# @raycast.description Completely uninstall apps using Mole
|
||||||
|
# @raycast.author tw93
|
||||||
|
# @raycast.authorURL https://github.com/tw93/Mole
|
||||||
|
|
||||||
|
# Detect mo/mole installation
|
||||||
|
if command -v mo >/dev/null 2>&1; then
|
||||||
|
MO_BIN="mo"
|
||||||
|
elif command -v mole >/dev/null 2>&1; then
|
||||||
|
MO_BIN="mole"
|
||||||
|
else
|
||||||
|
echo "❌ Mole not found. Install from:"
|
||||||
|
echo " https://github.com/tw93/Mole"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run uninstall
|
||||||
|
echo "🗑️ Starting app uninstaller..."
|
||||||
|
echo ""
|
||||||
|
"$MO_BIN" uninstall
|
||||||
31
integrations/setup-raycast.sh
Executable file
31
integrations/setup-raycast.sh
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# One-line Raycast integration installer
|
||||||
|
# Usage: curl -fsSL https://raw.githubusercontent.com/tw93/Mole/main/integrations/setup-raycast.sh | bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
RAYCAST_DIR="$HOME/Library/Application Support/Raycast/script-commands"
|
||||||
|
BASE_URL="https://raw.githubusercontent.com/tw93/Mole/main/integrations/raycast"
|
||||||
|
|
||||||
|
# Check Raycast
|
||||||
|
if [[ ! -d "$HOME/Library/Application Support/Raycast" ]]; then
|
||||||
|
echo -e "${YELLOW}Raycast not found. Install from: https://raycast.com${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing Mole commands for Raycast..."
|
||||||
|
mkdir -p "$RAYCAST_DIR"
|
||||||
|
|
||||||
|
# Download scripts
|
||||||
|
for script in mole-clean.sh mole-clean-dry-run.sh mole-uninstall.sh; do
|
||||||
|
curl -fsSL "$BASE_URL/$script" -o "$RAYCAST_DIR/$script"
|
||||||
|
chmod +x "$RAYCAST_DIR/$script"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓${NC} Installed! Open Raycast and search: 'Reload Script Commands'"
|
||||||
|
echo ""
|
||||||
|
echo "Then search for: 'Clean Mac'"
|
||||||
Reference in New Issue
Block a user