feat: add mac-optimizer skill (92) — Claude Code only
macOS system health toolkit with 5 audit modules (packages, environment, security, cleanup, resources) and cleanup executor. Fixed bugs from review: - Replace GNU timeout with perl alarm (macOS compatible) - Remove Linux-only ps --sort flag, use portable sort - Add JSON escaping to all audit scripts - Remove redundant classify_size branch Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
118
custom-skills/92-mac-optimizer/scripts/audit_packages.sh
Executable file
118
custom-skills/92-mac-optimizer/scripts/audit_packages.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bash
|
||||
# audit_packages.sh — Audit package managers on macOS
|
||||
# Output: JSON lines to stdout, one per finding
|
||||
set -euo pipefail
|
||||
|
||||
json_escape() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g' | tr '\n' ' '; }
|
||||
|
||||
json_finding() {
|
||||
local severity="$1" finding action details
|
||||
finding=$(json_escape "$2")
|
||||
action=$(json_escape "$3")
|
||||
details=$(json_escape "$4")
|
||||
printf '{"module":"packages","severity":"%s","finding":"%s","action":"%s","details":"%s"}\n' \
|
||||
"$severity" "$finding" "$action" "$details"
|
||||
}
|
||||
|
||||
# --- Homebrew ---
|
||||
if command -v brew &>/dev/null; then
|
||||
echo '{"module":"packages","severity":"info","finding":"Homebrew detected","action":"none","details":"'$(brew --version | head -1)'"}'
|
||||
|
||||
# brew update
|
||||
brew update --quiet 2>/dev/null || true
|
||||
|
||||
# outdated formulae
|
||||
outdated=$(brew outdated --json=v2 2>/dev/null || echo '{}')
|
||||
formula_count=$(echo "$outdated" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('formulae',[])))" 2>/dev/null || echo 0)
|
||||
cask_count=$(echo "$outdated" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('casks',[])))" 2>/dev/null || echo 0)
|
||||
|
||||
if [ "$formula_count" -gt 0 ] 2>/dev/null; then
|
||||
formula_list=$(echo "$outdated" | python3 -c "
|
||||
import sys,json
|
||||
d=json.load(sys.stdin)
|
||||
names=[f['name'] for f in d.get('formulae',[])]
|
||||
print(', '.join(names[:10]))
|
||||
if len(names)>10: print(f'... and {len(names)-10} more')
|
||||
" 2>/dev/null || echo "")
|
||||
json_finding "warning" "${formula_count} Homebrew formulae outdated" "brew upgrade" "$formula_list"
|
||||
fi
|
||||
|
||||
if [ "$cask_count" -gt 0 ] 2>/dev/null; then
|
||||
json_finding "warning" "${cask_count} Homebrew casks outdated" "brew upgrade --cask" ""
|
||||
fi
|
||||
|
||||
if [ "$formula_count" -eq 0 ] && [ "$cask_count" -eq 0 ] 2>/dev/null; then
|
||||
json_finding "info" "All Homebrew packages up to date" "none" ""
|
||||
fi
|
||||
|
||||
# brew doctor
|
||||
doctor_output=$(brew doctor 2>&1 || true)
|
||||
doctor_warnings=$(echo "$doctor_output" | grep -c "Warning:" 2>/dev/null || echo 0)
|
||||
if [ "$doctor_warnings" -gt 0 ] 2>/dev/null; then
|
||||
json_finding "warning" "brew doctor found ${doctor_warnings} warning(s)" "brew doctor" "Run brew doctor for details"
|
||||
fi
|
||||
|
||||
# autoremove candidates
|
||||
autoremove_output=$(brew autoremove --dry-run 2>/dev/null || echo "")
|
||||
orphan_count=$(echo "$autoremove_output" | grep -c "^=" 2>/dev/null || echo 0)
|
||||
if echo "$autoremove_output" | grep -q "would remove" 2>/dev/null; then
|
||||
json_finding "info" "Orphaned Homebrew dependencies found" "brew autoremove" "$autoremove_output"
|
||||
fi
|
||||
else
|
||||
json_finding "info" "Homebrew not installed" "none" "Consider installing from https://brew.sh"
|
||||
fi
|
||||
|
||||
# --- npm / nvm ---
|
||||
if command -v nvm &>/dev/null || [ -d "$HOME/.nvm" ]; then
|
||||
# Source nvm if available
|
||||
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh" 2>/dev/null
|
||||
|
||||
if command -v nvm &>/dev/null; then
|
||||
node_versions=$(nvm ls --no-colors 2>/dev/null | grep -c "v[0-9]" || echo 0)
|
||||
current_node=$(nvm current 2>/dev/null || echo "none")
|
||||
json_finding "info" "nvm detected: ${node_versions} version(s), current: ${current_node}" "none" ""
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v npm &>/dev/null; then
|
||||
json_finding "info" "npm detected" "none" "$(npm --version 2>/dev/null)"
|
||||
|
||||
npm_outdated=$(npm outdated -g --json 2>/dev/null || echo '{}')
|
||||
npm_outdated_count=$(echo "$npm_outdated" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo 0)
|
||||
|
||||
if [ "$npm_outdated_count" -gt 0 ] 2>/dev/null; then
|
||||
json_finding "warning" "${npm_outdated_count} global npm packages outdated" "npm update -g" ""
|
||||
fi
|
||||
else
|
||||
json_finding "info" "npm not installed" "none" ""
|
||||
fi
|
||||
|
||||
# --- Python / pyenv ---
|
||||
if command -v pyenv &>/dev/null; then
|
||||
pyenv_versions=$(pyenv versions --bare 2>/dev/null | wc -l | tr -d ' ')
|
||||
current_python=$(pyenv version-name 2>/dev/null || echo "system")
|
||||
json_finding "info" "pyenv detected: ${pyenv_versions} version(s), current: ${current_python}" "none" ""
|
||||
|
||||
# Check pip outdated for current environment
|
||||
if command -v pip &>/dev/null || command -v pip3 &>/dev/null; then
|
||||
pip_cmd=$(command -v pip3 || command -v pip)
|
||||
pip_outdated=$($pip_cmd list --outdated --format=json 2>/dev/null || echo '[]')
|
||||
pip_count=$(echo "$pip_outdated" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo 0)
|
||||
|
||||
if [ "$pip_count" -gt 0 ] 2>/dev/null; then
|
||||
json_finding "warning" "${pip_count} pip packages outdated in current env" "pip install --upgrade" ""
|
||||
fi
|
||||
fi
|
||||
elif command -v python3 &>/dev/null; then
|
||||
py_version=$(python3 --version 2>/dev/null || echo "unknown")
|
||||
json_finding "info" "System Python: ${py_version} (no pyenv)" "none" ""
|
||||
fi
|
||||
|
||||
# --- Other package managers (presence detection only) ---
|
||||
for mgr in yarn pnpm cargo go gem composer; do
|
||||
if command -v "$mgr" &>/dev/null; then
|
||||
version=$($mgr --version 2>/dev/null | head -1 || echo "unknown")
|
||||
json_finding "info" "${mgr} detected: ${version}" "none" "Presence check only"
|
||||
fi
|
||||
done
|
||||
Reference in New Issue
Block a user