1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-05 02:44:44 +00:00

Optimize the installation experience of raycast

This commit is contained in:
Tw93
2025-11-09 10:48:12 +08:00
parent 0db4d565cb
commit bab0cb4958
8 changed files with 247 additions and 283 deletions

View File

@@ -64,14 +64,14 @@ mo --version # Show installed version
## Quick Launchers
Generate Spotlight / Shortcuts launchers with one command:
One command sets up Raycast + Alfred shortcuts for `mo clean` and `mo uninstall`:
```bash
curl -fsSL https://raw.githubusercontent.com/tw93/mole/main/integrations/setup-shortcut-apps.sh | bash
curl -fsSL https://raw.githubusercontent.com/tw93/mole/main/integrations/setup-quick-launchers.sh | bash
```
This drops tiny apps such as “Mole Clean” into `~/Applications` so you can trigger them from Spotlight, Dock, or the Shortcuts app.
For Alfred, Shortcuts details, and more, see [integrations/README.md](integrations/README.md).
Done! Raycast gets “Clean Mac / Uninstall Apps”, Alfred gets `mclean / muninstall`.
Details and manual options live in [integrations/README.md](integrations/README.md).
## Features in Detail

View File

@@ -2,22 +2,17 @@
Quick launcher integrations for Mole.
## Shortcut Apps (Spotlight & Shortcuts)
Generate ready-to-use launcher apps (Clean / Dry Run / Uninstall):
## Raycast + Alfred (clean & uninstall)
```bash
curl -fsSL https://raw.githubusercontent.com/tw93/Mole/main/integrations/setup-shortcut-apps.sh | bash
curl -fsSL https://raw.githubusercontent.com/tw93/Mole/main/integrations/setup-quick-launchers.sh | bash
```
This drops them into `~/Applications`, so you can trigger Mole via Spotlight, Dock, or Shortcuts (“Open App” action).
Prefer to craft your own shortcut? Add “Run Shell Script”:
This command:
```bash
mo clean
```
Dry run: `mo clean --dry-run` • Uninstall: `mo uninstall`
- Adds two Raycast Script Commands (`Clean Mac`, `Uninstall Apps`) to the usual Raycast directories and opens the Script Commands panel so you can reload immediately.
- Creates two Alfred workflows with keywords `mclean` and `muninstall` so you can type and run Mole in Alfred.
Both launchers call your locally installed `mo`/`mole` binary directly—no extra prompts or AppleScript permissions needed.
## Alfred
@@ -34,9 +29,8 @@ For uninstall: `mo uninstall`
## Uninstall
```bash
rm -rf ~/Applications/Mole\ Clean*.app
rm -rf ~/Applications/Mole\ Uninstall\ Apps.app
# Legacy Raycast script commands (if you installed them before switching)
rm -rf ~/Documents/Raycast/Scripts/mole-*.sh
rm -rf ~/Library/Application\ Support/Raycast/script-commands/mole-*.sh
# Alfred workflows live in:
# ~/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.*
```

View File

@@ -1,32 +0,0 @@
#!/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

View File

@@ -1,32 +0,0 @@
#!/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

View File

@@ -1,32 +0,0 @@
#!/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

View File

@@ -0,0 +1,235 @@
#!/bin/bash
# Create Raycast script commands and Alfred keywords for Mole (clean + uninstall).
set -euo pipefail
BLUE='\033[0;34m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
ICON_STEP="➜"
ICON_SUCCESS="✓"
ICON_WARN="!"
ICON_ERR="✗"
log_step() { echo -e "${BLUE}${ICON_STEP}${NC} $1"; }
log_success() { echo -e "${GREEN}${ICON_SUCCESS}${NC} $1"; }
log_warn() { echo -e "${YELLOW}${ICON_WARN}${NC} $1"; }
log_error() { echo -e "${RED}${ICON_ERR}${NC} $1"; }
detect_mo() {
if command -v mo >/dev/null 2>&1; then
command -v mo
elif command -v mole >/dev/null 2>&1; then
command -v mole
else
log_error "Mole not found. Install it first via Homebrew or ./install.sh."
exit 1
fi
}
write_raycast_script() {
local target="$1"
local title="$2"
local command="$3"
cat > "$target" <<EOF
#!/bin/bash
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title ${title}
# @raycast.mode fullOutput
# @raycast.packageName Mole
# Optional parameters:
# @raycast.icon 🐹
set -euo pipefail
MO_CMD="${command}"
echo "🐹 Running ${title}..."
echo ""
eval "\$MO_CMD"
EOF
chmod +x "$target"
}
create_raycast_commands() {
local mo_bin="$1"
local clean_cmd="\"${mo_bin}\" clean"
local uninstall_cmd="\"${mo_bin}\" uninstall"
local default_dir="$HOME/Library/Application Support/Raycast/script-commands"
local alt_dir="$HOME/Documents/Raycast/Scripts"
local dirs=()
if [[ -d "$default_dir" ]]; then
dirs+=("$default_dir")
fi
if [[ -d "$alt_dir" ]]; then
dirs+=("$alt_dir")
fi
if [[ ${#dirs[@]} -eq 0 ]]; then
dirs+=("$default_dir")
fi
log_step "Installing Raycast commands..."
for dir in "${dirs[@]}"; do
mkdir -p "$dir"
write_raycast_script "$dir/mole-clean.sh" "Clean Mac" "$clean_cmd"
write_raycast_script "$dir/mole-uninstall.sh" "Uninstall Apps" "$uninstall_cmd"
log_success "Scripts ready in: $dir"
done
if open "raycast://extensions/script-commands" > /dev/null 2>&1; then
log_step "Raycast settings opened. Run “Reload Script Directories”."
else
log_warn "Could not auto-open Raycast. Open it manually to reload scripts."
fi
}
uuid() {
if command -v uuidgen >/dev/null 2>&1; then
uuidgen
else
# Fallback pseudo UUID
openssl rand -hex 16 | sed 's/\(..\)/\1/g' | cut -c1-32
fi
}
create_alfred_workflow() {
local mo_bin="$1"
local prefs_dir="${ALFRED_PREFS_DIR:-$HOME/Library/Application Support/Alfred/Alfred.alfredpreferences}"
local workflows_dir="$prefs_dir/workflows"
if [[ ! -d "$workflows_dir" ]]; then
log_warn "Alfred preferences not found at $workflows_dir. Skipping Alfred workflow."
return
fi
log_step "Installing Alfred workflows..."
local workflows=(
"fun.tw93.mole.clean|Mole Clean|mclean|Run Mole clean|\"${mo_bin}\" clean"
"fun.tw93.mole.uninstall|Mole Uninstall|muninstall|Uninstall apps via Mole|\"${mo_bin}\" uninstall"
)
for entry in "${workflows[@]}"; do
IFS="|" read -r bundle name keyword subtitle command <<< "$entry"
local workflow_uid="user.workflow.$(uuid | tr '[:upper:]' '[:lower:]')"
local input_uid
local action_uid
input_uid="$(uuid)"
action_uid="$(uuid)"
local dir="$workflows_dir/$workflow_uid"
mkdir -p "$dir"
cat > "$dir/info.plist" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>bundleid</key>
<string>${bundle}</string>
<key>createdby</key>
<string>Mole</string>
<key>name</key>
<string>${name}</string>
<key>objects</key>
<array>
<dict>
<key>config</key>
<dict>
<key>argumenttype</key>
<integer>2</integer>
<key>keyword</key>
<string>${keyword}</string>
<key>subtext</key>
<string>${subtitle}</string>
<key>text</key>
<string>${name}</string>
<key>withspace</key>
<true/>
</dict>
<key>type</key>
<string>alfred.workflow.input.keyword</string>
<key>uid</key>
<string>${input_uid}</string>
<key>version</key>
<integer>1</integer>
</dict>
<dict>
<key>config</key>
<dict>
<key>concurrently</key>
<true/>
<key>escaping</key>
<integer>102</integer>
<key>script</key>
<string>#!/bin/bash
PATH="/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin"
${command}
</string>
<key>scriptargtype</key>
<integer>1</integer>
<key>scriptfile</key>
<string></string>
<key>type</key>
<integer>0</integer>
</dict>
<key>type</key>
<string>alfred.workflow.action.script</string>
<key>uid</key>
<string>${action_uid}</string>
<key>version</key>
<integer>2</integer>
</dict>
</array>
<key>connections</key>
<dict>
<key>${input_uid}</key>
<array>
<dict>
<key>destinationuid</key>
<string>${action_uid}</string>
<key>modifiers</key>
<integer>0</integer>
<key>modifiersubtext</key>
<string></string>
</dict>
</array>
</dict>
<key>uid</key>
<string>${workflow_uid}</string>
<key>version</key>
<integer>1</integer>
</dict>
</plist>
EOF
log_success "Workflow ready: ${name} (keyword: ${keyword})"
done
log_step "Open Alfred preferences → Workflows if you need to adjust keywords."
}
main() {
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Mole Quick Launchers"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
local mo_bin
mo_bin="$(detect_mo)"
log_step "Detected Mole binary at: ${mo_bin}"
create_raycast_commands "$mo_bin"
create_alfred_workflow "$mo_bin"
echo ""
log_success "Done! Raycast (search “Clean Mac”) and Alfred (keywords: mclean / muninstall) are ready."
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
}
main "$@"

View File

@@ -1,76 +0,0 @@
#!/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
BLUE='\033[0;34m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
ICON_STEP="➜"
ICON_SUCCESS="✓"
ICON_WARN="!"
ICON_ERR="✗"
log_step() { echo -e "${BLUE}${ICON_STEP}${NC} $1"; }
log_success() { echo -e "${GREEN}${ICON_SUCCESS}${NC} $1"; }
log_warn() { echo -e "${YELLOW}${ICON_WARN}${NC} $1"; }
log_error() { echo -e "${RED}${ICON_ERR}${NC} $1"; }
DEFAULT_DIR="$HOME/Library/Application Support/Raycast/script-commands"
ALT_DIR="$HOME/Documents/Raycast/Scripts"
RAYCAST_DIRS=()
if [[ -d "$DEFAULT_DIR" ]]; then
RAYCAST_DIRS+=("$DEFAULT_DIR")
fi
if [[ -d "$ALT_DIR" ]]; then
RAYCAST_DIRS+=("$ALT_DIR")
fi
if [[ ${#RAYCAST_DIRS[@]} -eq 0 ]]; then
RAYCAST_DIRS+=("$DEFAULT_DIR")
fi
BASE_URL="https://raw.githubusercontent.com/tw93/Mole/main/integrations/raycast"
SCRIPTS=(mole-clean.sh mole-clean-dry-run.sh mole-uninstall.sh)
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Mole × Raycast Script Commands"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_step "Checking Raycast installation..."
if [[ ! -d "/Applications/Raycast.app" ]]; then
log_warn "Raycast not found. Install it from https://raycast.com"
exit 1
fi
log_step "Syncing scripts (${#SCRIPTS[@]}) to Raycast directories..."
for dir in "${RAYCAST_DIRS[@]}"; do
mkdir -p "$dir"
for script in "${SCRIPTS[@]}"; do
curl -fsSL "$BASE_URL/$script" -o "$dir/$script"
chmod +x "$dir/$script"
done
log_success "Scripts ready in: $dir"
done
echo ""
log_success "All set! Next steps:"
cat <<INSTRUCTIONS
1. Open Raycast and run "Reload Script Directories".
2. Search for "Clean Mac" / "Dry Run" / "Uninstall Apps".
3. Missing? Open Raycast Settings → Extensions → Script Commands
and add $(printf '"%s" ' "${RAYCAST_DIRS[@]}").
INSTRUCTIONS
if open "raycast://extensions/script-commands" > /dev/null 2>&1; then
log_step "Raycast settings opened so you can confirm the directory."
else
log_warn "Could not auto-open Raycast. Launch it manually if needed."
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""

View File

@@ -1,93 +0,0 @@
#!/bin/bash
# Create double-clickable Mole launchers (works great with Spotlight & Shortcuts).
set -euo pipefail
BLUE='\033[0;34m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
ICON_STEP="➜"
ICON_SUCCESS="✓"
ICON_WARN="!"
ICON_ERR="✗"
log_step() { echo -e "${BLUE}${ICON_STEP}${NC} $1"; }
log_success() { echo -e "${GREEN}${ICON_SUCCESS}${NC} $1"; }
log_warn() { echo -e "${YELLOW}${ICON_WARN}${NC} $1"; }
log_error() { echo -e "${RED}${ICON_ERR}${NC} $1"; }
if ! command -v osascript >/dev/null 2>&1 || ! command -v osacompile >/dev/null 2>&1; then
log_error "This installer needs AppleScript tools (osascript / osacompile). They ship with macOS."
exit 1
fi
# Resolve Mole executable
if command -v mo >/dev/null 2>&1; then
MO_BIN="$(command -v mo)"
elif command -v mole >/dev/null 2>&1; then
MO_BIN="$(command -v mole)"
else
log_error "Couldn't find Mole. Install via Homebrew or the install.sh script first."
exit 1
fi
APP_DIR_BASE="${APP_DIR_BASE:-$HOME/Applications}"
mkdir -p "$APP_DIR_BASE"
declare -a ACTIONS=(
"Mole Clean|$MO_BIN clean|Run full clean with Mole"
"Mole Clean (Dry Run)|$MO_BIN clean --dry-run|Preview cleanup targets"
"Mole Uninstall Apps|$MO_BIN uninstall|Interactive app uninstaller"
)
create_launcher() {
local name="$1"
local command="$2"
local description="$3"
local app_path="$APP_DIR_BASE/$name.app"
local tmp_scpt
tmp_scpt="$(mktemp)"
# Escape backslashes and quotes for AppleScript literal
local escaped_cmd="${command//\\/\\\\}"
escaped_cmd="${escaped_cmd//\"/\\\"}"
cat > "$tmp_scpt" <<EOF
on run
set targetCommand to "${escaped_cmd}"
tell application "Terminal"
activate
do script targetCommand
end tell
end run
EOF
osacompile -o "$app_path" "$tmp_scpt"
rm -f "$tmp_scpt"
/usr/bin/plutil -replace CFBundleIdentifier -string "fun.tw93.mole.$(echo "$name" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]' )" "$app_path/Contents/Info.plist" 2>/dev/null || true
/usr/bin/plutil -replace CFBundleDisplayName -string "$name" "$app_path/Contents/Info.plist" 2>/dev/null || true
log_success "Created ${name}${app_path}"
log_step "You can now launch it from Spotlight or add to macOS Shortcuts."
echo " ${description}"
}
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Mole macOS Launcher Creator"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_step "Installing launchers into: $APP_DIR_BASE"
for entry in "${ACTIONS[@]}"; do
IFS="|" read -r name cmd desc <<< "$entry"
create_launcher "$name" "$cmd" "$desc"
done
echo ""
log_step "Tip: open Shortcuts.app → New Shortcut → Add Action → 'Open App', then pick the launcher."
log_success "Done! Search Spotlight for “Mole Clean” to try it."
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""