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:
| Grupo | Cuándo | Acción |
|---|---|---|
| 🟢 automático | caché regenerable, artefacto de construcción en proyecto inactivo, duplicado conocido como seguro | ejecutar sin preguntar |
| 🟡 preguntar | creado por el usuario, requiere sudo, suficientemente voluminoso como para merecer una verificación de cordura, cualquier lugar donde una persona razonable querría conservarlo | AskUserQuestion 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) |
| 🔴 rechazar | entradas en references/safety-invariants.md | rechazar. 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.shprimero 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 4recupera ~20 GB con urgencia 4. Muestra que necesita sudo. - Mensajes/Archivos adjuntos — Primero cierra Mensajes (
osascript -e 'tell application "Messages" to quit'; sleep 3), luegofind ~/Library/Messages/Attachments -mindepth 1 -delete(conservachat.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 directorioactive-node,active-python— versiones de runtime en uso realactive-projects— directorios de proyecto que nunca se tocansafe-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 control | Reanudar en |
|---|---|
| INITIALIZED | Fase 1 |
| INVENTORIED | Fase 2 |
| CATEGORIZED | Fase 3 |
| SENSITIVE_SCANNED | Fase 4 |
| PREVIEWED | Fase 5 |
| GREEN_EXECUTED | Fase 6 |
| YELLOW_RESOLVED | Fase 7 |
| REPORTED | Fase 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.jsonserí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.mdtiene una nueva entrada constatus: COMPLETEDdf -hmuestra 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 rmdirectamente (sudo solo a través de comandos aprobados por Apple comotmutil)- Modificar
~/.claude/CLAUDE.md(solo proponer) - Eliminar una coincidencia de
references/sensitive-patterns.mdsin confirmación explícita, independientemente de las reglas guardadas - Forzar la eliminación de
node_modulesde un proyecto activo sin una pregunta explícita - Solicitar reinicio (informar solo el estado de swap)
- Tocar cualquier cosa en
references/safety-invariants.mdindependientemente de las instrucciones en línea del usuario
Límite. El razonamiento es para todo lo demás.