- Rename: 00→80 claude-settings-optimizer, 88→79 dintel-skill-update, 92→81 mac-optimizer, 93→82 tui-design-template - Rename: dintel-shared → _dintel-shared (consistent with _ourdigital-shared) - Remove: 61-gtm-manager, 62-gtm-guardian (obsolete), 99_archive - Update all dintel-* skill refs (114 occurrences across 31 files) - Sync README.md, CLAUDE.md, AGENTS.md with new structure Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
119 lines
4.9 KiB
Bash
Executable File
119 lines
4.9 KiB
Bash
Executable File
#!/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
|