Communitygithub.com

Offwhite-Del/mac-declutter

Habilidad para limpieza profunda de máquinas macOS de desarrollo: proliferación de agentes de IA, servicios zombis, restos de aplicaciones, trampas de proxy, purga de cachés y auditorías de rendimiento.

¿Qué es mac-declutter?

mac-declutter es un manual de limpieza profunda para máquinas macOS de desarrolladores, diseñado para eliminar la proliferación de agentes de IA (como archivos de configuración de Claude, Codex, etc.), servicios zombis en segundo plano, restos de aplicaciones eliminadas, trampas de proxy y realizar auditorías de rendimiento. Funciona en fases: primero realiza un inventario de solo lectura de directorios de agentes, servicios, aplicaciones y cachés; luego guía al usuario en la desinstalación segura, priorizando la detención de servicios, eliminación de archivos plist, la aplicación/binario y restos en Librería, respetando siempre la protección de integridad del sistema (SIP) sin forzarla. Incluye una fase de purga de cachés con riesgo cero, una auditoría de rendimiento que mide presión de memoria y uso de swap, y una verificación final. Es útil porque automatiza decisiones informadas (basadas en tamaño, última fecha de uso, estado de ejecución) y evita errores comunes como eliminar sesiones de usuario o ignorar proxies muertos. Soporta macOS y se ejecuta via scripts de shell y comandos nativos.

Compatible con✓Claude Code✓Codex CLI~Cursor✓OpenCode
npx skills add Offwhite-Del/mac-declutter

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace mac-declutter?

Un manual probado en batalla para limpiar el Mac de un desarrollador: proliferación de agentes de IA, servicios zombis en segundo plano, restos de aplicaciones, trampas de proxy y auditorías de rendimiento.

Principios fundamentales:

  • Inventario antes de eliminar. Nunca desinstales a ciegas: mide tamaño, fecha de último uso y estado de ejecución primero, luego deja que el usuario elija.
  • Nunca toques registros de sesión ni datos de usuario a menos que se te pida explícitamente. Las cachés se regeneran; las sesiones no.
  • Verifica después de cada mutación — proceso eliminado, puerto cerrado, elemento de inicio de sesión eliminado.
  • La Protección de Integridad del Sistema (SIP) es un muro duro. Las aplicaciones propiedad de root, los contenedores sandbox y las extensiones DriverKit tienen cada una una ruta de eliminación autorizada; no luches contra el sistema operativo.

Fase 0 — Triaje de red (haz esto primero)

El síntoma "todo está desconectado" casi siempre es un proxy local muerto, no aplicaciones rotas:

scutil --proxy                       # a qué apunta el proxy del sistema
nc -z -w 2 127.0.0.1 <puerto>        # ¿está escuchando algo realmente?
lsof -nP -iTCP:<puerto> -sTCP:LISTEN # quién es el dueño

La trampa clásica: las herramientas estilo Clash/V2Ray configuran el proxy del sistema macOS a 127.0.0.1:PUERTO, luego el núcleo muere — el modo de reglas no importa, todo el tráfico muere en la puerta. Las aplicaciones que respetan el proxy del sistema (la mayoría de apps GUI, algunas CLI) fallan todas; curl sigue funcionando porque omite el proxy del sistema, lo que engaña el diagnóstico. Soluciones: reinicia el núcleo del proxy, o desactiva el proxy (networksetup -setwebproxystate Wi-Fi off + -setsecurewebproxystate + -setsocksfirewallproxystate + WPAD off), o apunta la configuración de proxy de la aplicación a nada. Recuerda: curl ignora el proxy del sistema — prueba la conectividad estilo aplicación con curl -x http://127.0.0.1:PUERTO.

Fase 1 — Inventario (solo lectura)

Ejecuta scripts/inventory.sh, o cubre manualmente estas dimensiones:

  • Directorios de configuración de agentes: ~/.claude, ~/.codex, ~/.pi, ~/.jcode, ~/.config/opencode, etc. Para cada uno: tamaño (du -sh), última actividad (mtime del archivo más nuevo), si el binario CLI aún existe (which).
  • Estado de inicio de sesión/autenticación: auth.json, openai-auth.json, archivos de credenciales — lista las claves, nunca imprimas secretos.
  • Servicios en segundo plano: launchctl list | grep -v com.apple y ~/Library/LaunchAgents/*.plist — lee el ProgramArguments de cada plist para saber qué ejecuta realmente.
  • Aplicaciones: para cada .app no de Apple en /Applications y ~/Applications, recoge tamaño, kMDItemLastUsedDate mediante mdls, y presencia de _MASReceipt (apps de la App Store). "Nunca abierta" + grande = candidato principal.
  • Cachés: ~/Library/Caches, ~/.npm, cachés de pip/bun — grandes y siempre seguras de purgar.

Presenta los hallazgos como una tabla de conservar/eliminar y deja que el usuario elija. Marca las aplicaciones de pago/suscripción (p. ej., _MASReceipt, productos de suscripción conocidos) para que el usuario cancele la facturación antes de eliminar.

Fase 2 — Manual de desinstalación

Por objetivo, en orden:

  1. Detén servicios: launchctl remove <etiqueta> para cada LaunchAgent/Daemon relacionado.
  2. Elimina plists: ~/Library/LaunchAgents/<etiqueta>.plist.
  3. Elimina la app/CLI: rm -rf el .app / npm uninstall -g <paquete> / elimina el binario.
    • Permission denied → propiedad de root (instalado con paquete). Usa osascript -e 'do shell script "rm -rf ..." with administrator privileges' (una ventana de contraseña GUI). Nunca uses sudo a ciegas.
  4. Restos en Librería: comprueba y elimina ~/Library/{Application Support,Caches,Containers,HTTPStorages,Preferences}/<app-o-bundle-id>.
    • Los Containers/* sandbox pueden resistir incluso a root (protección del administrador de contenedores). Si son pequeños, déjalos — el SO elimina los contenedores huérfanos; nunca vale la pena desactivar SIP.
  5. Extensiones del sistema: systemextensionsctl list. SIP bloquea la desinstalación directa — la única ruta limpia es reinstalar la aplicación del proveedor y ejecutar su desinstalador oficial (busca uninstall.sh en /Library/Application Support/<proveedor>/). Los controladores DriverKit .dext se descargan solo en el próximo reinicio — dile al usuario que desaparecerá tras reiniciar.
  6. Elementos de inicio de sesión obsoletos: tras eliminar una aplicación, su entrada "Abrir al iniciar sesión" a menudo permanece como un zombi. Elimínala con osascript -e 'tell application "System Events" to delete login item "<nombre>"'.
  7. Procesos residuales: las aplicaciones eliminadas pueden dejar procesos ejecutándose desde directorios temporales del actualizador (p. ej., la preparación de Squirrel ShipIt). ps aux | grep -i <nombre>, mátalos, y comprueba si hay un directorio de datos en $HOME (~.<nombreapp>) — los demonios generados por el actualizador suelen ocultar cientos de MB allí.

Fase 3 — Purga de cachés (riesgo cero)

npm cache clean --force
rm -rf ~/Library/Caches/pip ~/.bun/install/cache
rm -rf ~/Library/Caches/<app-eliminada>/*

Las cachés se regeneran. Los historiales de sesión (sessions/, projects/, registros de conversación *.jsonl) no — déjalos a menos que el usuario diga explícitamente lo contrario.

Fase 4 — Auditoría de rendimiento

memory_pressure | tail -2    # % libre y presión
sysctl -n vm.swapusage       # swap usado debería ser ~0 en una máquina sana
sysctl -n vm.loadavg
ps -axm -o rss,comm | awk 'NR>1 {rss=$1; $1=""; sub(/^ /,""); a[$0]+=rss} END {for (k in a) printf "%d\t%s\n", a[k]/1024, k}' | sort -rn | head -15
  • "Memoria usada" en el Monitor de Actividad incluye caché de archivos — juzga por el color de presión de memoria y el swap, no por el número de GB.
  • Tras una eliminación masiva, Spotlight (mds_stores, corespotlightd) reindexa durante unas horas — temporal, no lo "arregles".
  • Agrupa RSS por familia de aplicaciones (los navegadores y las apps de chat generan muchos ayudantes); reporta totales por familia, no ruido por proceso.
  • No optimices lo que no es un problema: en una máquina con cero swap y presión verde, intercambiar la UX del día a día (p. ej., un IME inteligente) por unos pocos cientos de MB es un mal trato — dilo.

Fase 5 — Verificación final

  • Las etiquetas eliminadas no aparecen en launchctl list; los plists han desaparecido; no hay procesos que coincidan con nombres eliminados (excepto controladores pendientes de reinicio).
  • La escucha del puerto del proxy coincide con scutil --proxy; los puntos finales clave de la API son accesibles (401 = accesible pero requiere autenticación, es un aprobado).
  • Cada agente CLI superviviente pasa una prueba real de extremo a extremo (envía un prompt de una línea, espera una respuesta).
  • df -h / antes/después para la puntuación.

Skills relacionados