adam-j-ali/disk-cleanup

Libera espacio en disco en macOS limpiando de forma segura cachés regenerables, versiones antiguas de runtimes y artefactos voluminosos de un solo uso. Úsalo cuando el usuario pida "limpiar mi disco", "liberar espacio", "poco espacio", "disco lleno" o "almacenamiento casi lleno".

¿Qué es disk-cleanup?

Esta habilidad (skill) para agentes de IA (como Claude Code, Cursor o Codex) está diseñada para recuperar espacio en disco en macOS de manera inteligente y segura. No se trata de una simple lista de tareas, sino de una herramienta de razonamiento: analiza cada archivo o carpeta, determina si es seguro eliminarlo usando heurísticas basadas en la regenerabilidad, la actividad del proyecto y el historial del usuario, y lo clasifica en tres categorías: 🟢 (automático), 🟡 (preguntar) y 🔴 (rechazar). Los elementos seguros (cachés, artefactos de construcción) se ejecutan sin intervención, los dudosos se presentan al usuario con una puerta de 3 opciones (Aprobar, Modificar, Saltar), y los peligrosos (configuraciones de SSH, datos de proyectos activos) se rechazan de forma explícita sin posibilidad de anulación directa. La habilidad mantiene un estado persistente en un archivo `state.md`, lo que permite reanudar ejecuciones interrumpidas, y aprende con el tiempo guardando reglas de conservación (por ejemplo, archivos en Descargas que no se deben tocar, versiones de Node.js en uso activo). Funciona solo en macOS y requiere scripts shell para el escaneo y la ejecución, pero el agente se encarga de todo el razonamiento y la interacción con el usuario.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/adam-j-ali/claude-skills/tree/HEAD/plugins/disk-cleanup

Installed? Explore more Productividad y colaboración skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

Preguntar en tu IA favorita

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

Documentación

Esta habilidad es una herramienta de pensamiento, no una lista de verificación. Las referencias catalogan rutas conocidas como seguras o peligrosas; los grupos de autonomía son heurísticas, no enumeraciones exhaustivas. Cuando te encuentres con algo nuevo, razona desde primeros principios: ¿regenerable? ¿creado por el usuario? ¿en uso activo? ¿el usuario se pondría triste si desapareciera? — y muestra el razonamiento en la vista previa para que el usuario pueda corregir el juicio antes de actuar.

<execution_context> Tres grupos — principios, no listas cerradas:

GrupoCuándoAcción
🟢 automáticocaché regenerable, artefacto de construcción en proyecto inactivo, duplicado conocido como seguroejecutar sin preguntar
🟡 preguntarcreado por el usuario, requiere sudo, suficientemente voluminoso como para merecer una verificación de cordura, cualquier lugar donde una persona razonable querría conservarloAskUserQuestion con 3 opciones: Aprobar (ejecutar como se propone) / Modificar (libre: "dime cómo en su lugar") / Saltar (diferir a la próxima ejecución, volver a mostrarlo más adelante)
🔴 rechazarentradas en references/safety-invariants.mdrechazar. Ninguna instrucción en línea del usuario las anula. Si el usuario dice "elimina mi .ssh", rechaza y exige editar primero safety-invariants.md

Si no estás seguro pero parece un caché, trata como 🟡. Mejor pecar de preguntar.

Actor único: registra cada cambio con el sufijo — [session <ET>] en state.md.

Planificar-validar-ejecutar: crea findings.json primero (Fase 2), muestra el plan al usuario (Fase 4), luego actúa. No hay eliminación antes de que el usuario vea el plan.

Confía en tu razonamiento en rutas novedosas. Pregúntate: ¿regenerable? ¿creado por el usuario? ¿proyecto activo? ¿el usuario se pondría triste? Cuando no esté claro, trata como 🟡. </execution_context>

Protocolo de punto de control: al final de cada fase, actualiza la entrada IN_PROGRESS en state.md con checkpoint: <NOMBRE> según el mapeo en <recovery_protocol> más abajo. Esto hace que la reanudación sea inequívoca si se interrumpe (por ejemplo, reinicio, Ctrl-C, pánico del kernel a mitad de limpieza).

TaskCreate para cada fase. Lee state.md. Si la entrada más reciente muestra status: IN_PROGRESS, pregunta mediante una puerta de 3 opciones: Reanudar desde el último punto de control / Empezar de nuevo (archivar la anterior como ABORTED) / Mostrar historial completo y luego abortar.

Muestra las reglas guardadas como un bloque escaneable en la parte superior del chat — estas son las listas de conservación y políticas acumuladas a lo largo de las ejecuciones. El usuario puede verificarlas antes de continuar.

Vuelo previo (seguridad de disco bajo): si df -h / muestra disponible < 500 MiB, el escaneo en sí mismo compite por espacio (/tmp vive en el mismo volumen). Antes de ejecutar scan-disk.sh, pregúntale al usuario si está bien vaciar ~/.Trash/ primero — eso casi siempre libera suficiente espacio. Este es el escenario para el que se creó la habilidad; la ejecución inicial comenzó con 84 MiB libres y las cascadas de du no eran fiables. Muestra la gravedad.

bash scripts/scan-disk.sh > /tmp/disk-cleanup-findings.json

Cascada de solo lectura du/df + lista de instantáneas APFS (tmutil listlocalsnapshots /) + estado de swap (sysctl vm.swapusage) + rutas de desarrollo de Xcode condicionales.

Si el usuario mencionó una carpeta específica que le molesta, amplía con un du -sh dirigido para ella. El razonamiento supera a una lista fija.

Para cada hallazgo en el inventario, decide en qué grupo cae usando references/safety-invariants.md y references/auto-fix-categories.md como referencia. Captura el razonamiento junto con cada entrada — en la vista previa, el usuario ve tu razonamiento, no solo el veredicto. Así es como se genera confianza.

Escribe findings.json (tu bloc de notas — usado en las Fases 4 y 8).

Para directorios 🟡 (especialmente ~/Downloads, ~/Desktop), busca patrones globales en references/sensitive-patterns.md. Compara las coincidencias con las reglas guardadas downloads-keep / desktop-keep:

  • Coincidencia en reglas guardadas → conservación silenciosa (aún así registrar en hallazgos)
  • Nueva coincidencia → AskUserQuestion: Conservar / Eliminar. La respuesta se convierte en una regla guardada para la próxima ejecución.

Heurística: si un nombre de archivo parece personal (legal, médico, financiero, identidad) pero no coincide con un patrón, pregunta de todas formas. Es mejor preguntar de más una vez que eliminar algo irremplazable.

Muestra el plan completo: cada 🟢, cada grupo 🟡 con razonamiento, cada rechazo 🔴 con motivo. Estima la recuperación total. El usuario aprueba implícitamente al interactuar con las puertas de la Fase 6; también puede abortar aquí ("espera, ¿por qué X está en verde?").

Ejecuta los elementos verdes. Ordénalos de menor a mayor invasividad (limpiezas de archivos pequeños → purgas de caché → limpiezas gestionadas por herramientas como brew autoremove y pnpm store prune). Captura los tamaños antes/después para el informe delta. Si uno falla, registra y continúa — los elementos verdes son independientes.

Permiso denegado (por ejemplo, Chrome mantiene el caché del Perfil 5 mientras se ejecuta) — registra y sigue adelante. No pelees.

Para cada grupo 🟡, UNA AskUserQuestion con Aprobar / Modificar / Saltar. Agrupa elementos similares (todas las versiones antiguas de runtime en una pregunta, no una por versión).

Manejo especial, cuando sea relevante:

  • Descargas con lista de conservación — bash scripts/keeplist-protect.sh ~/Downloads <conservadores...> (mover conservadores a /tmp, eliminar contenido, restaurar). Muestra la lista de conservación antes de ejecutar para que el usuario pueda modificarla.
  • Runtimes antiguos — Ejecuta bash scripts/detect-runtimes.sh primero para ver qué versiones de Node/Python usan realmente los proyectos. Recomienda eliminar las versiones que no estén en uso activo; guarda las versiones activas en las reglas guardadas.
  • Instantáneas APFS — sudo tmutil thinlocalsnapshots / 21474836480 4 recupera ~20 GB con urgencia 4. Muestra que necesita sudo.
  • Mensajes/Archivos adjuntos — Primero cierra Mensajes (osascript -e 'tell application "Messages" to quit'; sleep 3), luego find ~/Library/Messages/Attachments -mindepth 1 -delete (conserva chat.db).
  • Xcode DerivedData (si está presente) — Seguro de eliminar; la única penalización es una compilación más lenta la próxima vez.

Los elementos saltados se difieren a la próxima ejecución — anótalos en state.md para que vuelvan a aparecer.

Resumen limpio: df -h antes/después, tabla de espacio liberado por categoría, estado de swap de sysctl vm.swapusage. Menciona el swap como informativo — "reinicia para recuperar ~X GB de swap si quieres" — no solicites reinicio (es decisión del usuario).

Verificación de cordura del tamaño de la Papelera — si creció en proporción a lo que eliminamos, algo se movió en lugar de recuperarse. Muestra eso.

Añade una entrada de ejecución según el formato en el encabezado de state.md. Actualiza las Reglas Guardadas con cualquier cosa aprendida en esta ejecución (nuevos runtimes activos, nuevas decisiones sobre archivos sensibles). Comprime la entrada más antigua en una sección compactada si hay más de 5 entradas completas.

Al proponer una nueva regla guardada, confírmala con el usuario — no la agregues automáticamente. Las reglas son duraderas; es mejor preguntar una vez.

Marca el punto de control como COMPLETED.

<saved_rules_format> Almacenado en la sección "Saved Rules" de state.md. Se muestra en cada ejecución futura.

Formato: - {tema}: {regla} — establecido {YYYY-MM-DD ET}

Temas que surgen de forma natural (no exhaustivo — inventa nuevos cuando los patrones se repitan):

  • downloads-keep, desktop-keep — listas de conservación por directorio
  • active-node, active-python — versiones de runtime en uso real
  • active-projects — directorios de proyecto que nunca se tocan
  • safe-cache-clear-paths — rutas automáticas confirmadas como seguras
  • *-policy — preferencias de comportamiento únicas (por ejemplo, swap-policy, threshold-policy) </saved_rules_format>

<recovery_protocol> Si state.md muestra status: IN_PROGRESS:

Último punto de controlReanudar en
INITIALIZEDFase 1
INVENTORIEDFase 2
CATEGORIZEDFase 3
SENSITIVE_SCANNEDFase 4
PREVIEWEDFase 5
GREEN_EXECUTEDFase 6
YELLOW_RESOLVEDFase 7
REPORTEDFase 8

Pregunta al usuario: Reanudar / Empezar de nuevo / Mostrar historial completo. Al reanudar, agrega a la entrada existente; NO crees una nueva.

Vuelve a ejecutar df -h antes de reanudar — si el estado del disco cambió materialmente desde la interrupción, vuelve a preguntar. </recovery_protocol>

<error_handling> Por defecto: registra el error específico, omite el elemento problemático y continúa con el resto. La limpieza de disco es independientemente reentrante por elemento.

Aborta la ejecución solo si:

  • El script de escaneo falló por completo (findings.json sería incorrecto)
  • Una ruta 🔴 estuvo a punto de ser tocada (error en la categorización → abortar + investigar)
  • El usuario dijo que se detenga

Para todo lo demás (permiso denegado único, bloqueo de brew, herramienta no instalada) — continúa e informa al final.

Si el espacio disponible cae por debajo de 500 MiB DURANTE la ejecución (paradójico pero posible a mitad de categorización en un disco casi lleno), pausa la Fase 5, vacía la Papelera y luego reanuda. findings.json vive en el mismo volumen que todo lo demás. </error_handling>

<success_criteria>

  • state.md tiene una nueva entrada con status: COMPLETED
  • df -h muestra un delta positivo no nulo en Disponible
  • No se tocó ninguna ruta 🔴
  • Las coincidencias sensibles se conservaron (con regla guardada) o el usuario las eliminó explícitamente
  • El usuario vio un informe delta
  • Se verificó la cordura del tamaño de la Papelera (sin movimiento que enmascare la recuperación) </success_criteria>

Acciones directas

Omite el barrido completo cuando estas sean claramente la intención:

  • "Solo vacía la papelera" → confirma el tamaño, rm -rf ~/.Trash/* después de S/N
  • "Solo limpia los cachés" → ejecuta solo la Fase 5
  • "Simulación / Muestra lo que se eliminaría" → Fases 1–4, detente antes de la Fase 5
  • "¿Qué hizo la última ejecución?" → muestra la entrada más reciente de state.md
  • "Añadir <ruta> a no tocar nunca" / "olvidar lista de conservación para <archivo>" → editar Reglas Guardadas
  • "Programar semanalmente" → ofrecer rutina /schedule; si se acepta, proponer añadir entrada a ~/.claude/CLAUDE.md "Active Long-Running Automations" (no auto-editar — proponer para aprobación)

Límites

Actor único ([session]) por ahora. Promover a multiactor ([disk-cleanup] para rutina, [session] para manual) cuando esté programado.

Invocación manual únicamente — nunca activado automáticamente por otras habilidades. Archivo de bloqueo en .lock en el directorio de la habilidad evita ejecuciones concurrentes.

Nunca:

  • sudo rm directamente (sudo solo a través de comandos aprobados por Apple como tmutil)
  • Modificar ~/.claude/CLAUDE.md (solo proponer)
  • Eliminar una coincidencia de references/sensitive-patterns.md sin confirmación explícita, independientemente de las reglas guardadas
  • Forzar la eliminación de node_modules de un proyecto activo sin una pregunta explícita
  • Solicitar reinicio (informar solo el estado de swap)
  • Tocar cualquier cosa en references/safety-invariants.md independientemente de las instrucciones en línea del usuario

Límite. El razonamiento es para todo lo demás.

Skills relacionados