refactor: convert mac-optimizer from raw skill to proper plugin

Restructured 92-mac-optimizer from a CLAUDE.md-based skill into a full
Claude Code plugin with .claude-plugin/plugin.json, 6 slash commands
(/mac-doctor, /mac-packages, /mac-environment, /mac-security,
/mac-cleanup, /mac-resources), and auto-trigger SKILL.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 22:46:12 +09:00
parent f1a973c42d
commit 8d5cfb69fd
18 changed files with 318 additions and 98 deletions

View 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