Config GC — Recolección de basura para configuraciones de Claude Code
Inspirado en la recolección de basura en tiempo de ejecución: escanea periódicamente objetos que ya no son referenciados, redundantes, caducados o de bajo valor, y recupera espacio. La diferencia crucial: aquí la recolección requiere un humano en el bucle. Nunca elimines de forma autónoma.
Cuándo activarla
- El usuario pide limpiar, auditar o reducir su configuración de Claude Code
- El usuario se queja de demasiados skills, hooks ruidosos o inicio lento de sesión
- Se debe realizar una revisión periódica (mensual) de la configuración
- Después de instalar un paquete grande de skills (por ejemplo, este repositorio), para conciliar superposiciones con la configuración existente
NO activar para: limpiar código fuente del proyecto (eso es refactorización), borrar el historial de chat o desinstalar Claude Code.
Filosofía de diseño
- Las configuraciones solo de añadido filtran. Los skills, archivos de memoria, hooks y entradas de permisos siempre se agregan. Sin revisión periódica se pudren en silencio.
- Las auditorías regulares superan a las purgas únicas. Escanea cada ~30 días y propone un lote pequeño de candidatos cada vez.
- Estrategias por canal. Cada tipo de acumulación (skills, hooks, permisos, ...) tiene sus propias señales de caducidad; no apliques una regla para todos.
- Primero, eliminación suave. Renombra a
.disabled> mueve a~/.claude/_gc_trash/> eliminación real. Siempre mantén un camino para deshacer. - Humano en el bucle forzoso. Cada candidato recibe su propia confirmación
[y/n/skip]. No hay atajo de «sí a todo». - Mantén un registro. Cada ejecución de GC añade a
~/.claude/gc_log.md: qué se tocó, por qué y cómo deshacerlo.
Canales de escaneo
| # | Canal | Ruta | Señales de caducidad / redundancia |
|---|---|---|---|
| 1 | Skills | ~/.claude/skills/*/ | Nombres muy superpuestos; nunca activados en transcripciones recientes; desajuste de dominio con el trabajo real del usuario; SKILL.md roto o vacío |
| 2 | Memoria | ~/.claude/**/memory/*.md + su índice | Múltiples entradas de índice para un mismo tema; contenido que contradice entradas más recientes; fechas ya pasadas; archivos huérfanos que faltan en el índice; fragmentos de menos de 100 palabras que deberían fusionarse |
| 3 | Hooks | ~/.claude/hooks/ + configuraciones | Scripts en disco pero no referenciados por ninguna configuración de hook; versiones antiguas reemplazadas por reescrituras |
| 4 | Permisos | permissions.allow en settings.json / settings.local.json | Entradas duplicadas; entradas específicas ya cubiertas por un comodín (ej. Bash(git push) cuando Bash(*) está permitido); concesiones únicas de experimentos pasados |
| 5 | Servidores MCP | ~/.claude.json o .mcp.json del proyecto | Servidores que fallan al conectar; duplicados funcionales; no usados durante mucho tiempo |
| 6 | Recordatorios / tareas programadas | donde el usuario los guarde | Disparadores únicos de más de 30 días; tareas cuyos scripts de destino ya no existen |
| 7 | Historial de proyectos | ~/.claude/projects/*/ | Instantáneas de transferencia obsoletas; registros de sesión reemplazados por estado más reciente |
| 8 | Cachés de runtime | cache/, file-history/, logs/, shell-snapshots/ | Ordena por tamaño y mtime; propón elementos de más de 30 días y grandes |
Flujo de trabajo
- Escanea todos los canales (o el subconjunto que nombre el usuario). Recolecta candidatos con: ruta, canal, señal que lo marcó, tamaño, última modificación.
- Clasifica por confianza (roto/huérfano = alta; solo antiguo = baja) y preséntalos como una tabla numerada. Limita cada ejecución a ~20 candidatos — GC es periódico, no exhaustivo.
- Confirma uno por uno. Para cada candidato muestra la evidencia y luego pregunta
[y/n/skip]. El usuario puede detenerse en cualquier momento. - Eliminación suave de los confirmados: prefiere renombrar con
.disabledpara skills y hooks, y mover a_gc_trash/<fecha>/para archivos. Las entradas de permisos viven en JSON (sin comentarios posibles): haz una copia de seguridad del archivo de configuración, registra cada entrada eliminada textualmente engc_log.mdy luego elimínala del arregloallowconjq. Solo elimina de forma permanente cuando el usuario lo pida explícitamente. - Registra la ejecución en
~/.claude/gc_log.md: marca de tiempo, elementos procesados, instrucciones para deshacer. - Informa: tamaño recuperado, canales aún saludables, fecha sugerida para la próxima revisión.
Comandos de escaneo de ejemplo
Scripts de hook huérfanos (canal 3) — scripts en disco que ninguna configuración de hook referencia:
for f in ~/.claude/hooks/*; do
name=$(basename "$f")
grep -rq "$name" ~/.claude/settings.json ~/.claude/settings.local.json 2>/dev/null \
|| echo "HUÉRFANO: $f"
done
Entradas de permisos redundantes (canal 4) — duplicados y concesiones específicas eclipsadas por un comodín:
jq -r '.permissions.allow[]' ~/.claude/settings.local.json | sort | uniq -d
if jq -e '.permissions.allow | index("Bash(*)")' ~/.claude/settings.local.json >/dev/null; then
jq -r '.permissions.allow[]' ~/.claude/settings.local.json \
| grep '^Bash(' | grep -vF 'Bash(*)'
fi
Cachés obsoletas más grandes (canal 8) — du -k en lugar de find -printf (solo GNU), para que funcione en macOS/BSD:
find ~/.claude/file-history ~/.claude/shell-snapshots -type f -mtime +30 \
-exec du -k {} + 2>/dev/null | sort -rn | head -20
Eliminación suave con ruta para deshacer (captura la fecha una vez para que el registro no pueda contradecir al directorio):
gc_date=$(date +%Y-%m-%d)
mkdir -p ~/.claude/_gc_trash/$gc_date
mv ~/.claude/skills/dead-skill ~/.claude/_gc_trash/$gc_date/
echo "$(date -Iseconds) movido skills/dead-skill -> _gc_trash/$gc_date/ (deshacer: mv de vuelta)" >> ~/.claude/gc_log.md
Eliminar una entrada de permiso confirmada como redundante (JSON no tiene comentarios — copia de seguridad, registra y luego edita):
cp ~/.claude/settings.local.json ~/.claude/settings.local.json.bak
echo "$(date -Iseconds) eliminada entrada de permiso: Bash(git push) (deshacer: restaurar desde .bak o volver a añadir)" >> ~/.claude/gc_log.md
jq '.permissions.allow -= ["Bash(git push)"]' ~/.claude/settings.local.json.bak \
> ~/.claude/settings.local.json
Anti-patrones
- Aprobación masiva. Preguntar «¿eliminar todos los 15? [s/n]» va contra el diseño. Un elemento, una decisión.
- Eliminación definitiva en la primera pasada. Si no hay una copia en
_gc_trash/o un renombrado.disabled, lo hiciste mal. - Tratar «antiguo» como «muerto». Un skill no tocado durante 60 días puede ser estacional (temporada de impuestos, revisiones trimestrales). La antigüedad es una señal, no un veredicto — por eso un humano confirma.
- Limpiar la memoria truncando. Fusionar dos archivos de memoria contradictorios requiere leer ambos y conservar la verdad más reciente, no eliminar el más largo.
- Tocar cualquier cosa fuera de
~/.claude(o del.claude/del proyecto). Config GC nunca se adentra en árboles de código fuente.
Mejores prácticas
- Ejecútala después de grandes adiciones, no solo en el calendario: instalar un paquete de 50 skills es justo cuando aparecen superposiciones con los skills existentes.
- Cuando dos skills se superponen, prefiere deshabilitar el que tiene la descripción de activación más débil — es el que probablemente nunca se disparaba.
- La limpieza de permisos es el canal de mayor valor por minuto invertido: las entradas allow redundantes dificultan las revisiones de seguridad.
- Conserva
gc_log.mdpara siempre. Es pequeño, y «¿cuándo deshabilité ese hook y por qué?» aparece más a menudo de lo que piensas.
Skills relacionadas
skill-stocktake— audita la calidad de los skills; config-gc audita la existencia de los skills. Ejecuta stocktake sobre lo que sobrevive a GC.workspace-surface-audit— la contraparte aditiva: recomienda qué instalar. config-gc es la mitad sustractiva del mismo ciclo de vida.configure-ecc— después de instalar skills con ella, ejecuta config-gc para conciliar superposiciones con tu configuración preexistente.continuous-learning— produce los archivos de memoria que esta skill audita posteriormente.security-review— se complementa bien con el canal de permisos.