diff --git a/.claude/settings.json b/.claude/settings.json index a17cc32..b2a73a4 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -7,5 +7,19 @@ "enabledPlugins": { "gopls-lsp@claude-plugins-official": true }, - "skipDangerousModePermissionPrompt": true + "skipDangerousModePermissionPrompt": true, + "permissions": { + "allow": [ + "Edit(~/.claude/**)", + "Write(~/.claude/**)", + "Edit(.claude/**)", + "Write(.claude/**)" + ], + "deny": [ + "Edit(~/.claude/.git/**)", + "Write(~/.claude/.git/**)", + "Edit(.git/**)", + "Write(.git/**)" + ] + } } diff --git a/install.sh b/install.sh index fede774..d8c52ce 100755 --- a/install.sh +++ b/install.sh @@ -96,6 +96,93 @@ else echo "WARN: settings.json no encontrado en el repo" fi +# === Limpieza de configuración que no debe cambiar === +echo "" +echo "=== Limpiando configuración inmutable ===" + +# 1. Eliminar backups viejos de settings.json (más de 7 días) +DELETED_BACKUPS=0 +for backup in "$CLAUDE_DIR"/settings.json.backup.*; do + [ -f "$backup" ] || continue + if [ "$(find "$backup" -mtime +7 2>/dev/null)" ]; then + rm -f "$backup" + DELETED_BACKUPS=$((DELETED_BACKUPS + 1)) + fi +done +[ "$DELETED_BACKUPS" -gt 0 ] && echo "Eliminados $DELETED_BACKUPS backups viejos de settings.json" + +# 2. Eliminar backups viejos de statusline.sh (más de 7 días) +DELETED_SL=0 +for backup in "$CLAUDE_DIR"/statusline.sh.backup.*; do + [ -f "$backup" ] || continue + if [ "$(find "$backup" -mtime +7 2>/dev/null)" ]; then + rm -f "$backup" + DELETED_SL=$((DELETED_SL + 1)) + fi +done +[ "$DELETED_SL" -gt 0 ] && echo "Eliminados $DELETED_SL backups viejos de statusline.sh" + +# 3. Si settings.json es un symlink correcto, eliminar cualquier settings.json suelto +# que pueda haber quedado (no el symlink en sí) +if [ -L "$CLAUDE_DIR/settings.json" ] && [ "$(readlink "$CLAUDE_DIR/settings.json")" = "$REPO_DIR/.claude/settings.json" ]; then + # Eliminar archivos sueltos que puedan sobreescribir el symlink + for stale in "$CLAUDE_DIR"/settings.json.tmp "$CLAUDE_DIR"/settings.json.new; do + if [ -f "$stale" ]; then + rm -f "$stale" + echo "Eliminado archivo temporal: $(basename "$stale")" + fi + done +fi + +# 4. Resetear settings.local.json a vacío si existe con contenido +# (este archivo es para overrides locales temporales, no debe acumular config) +LOCAL_SETTINGS="$CLAUDE_DIR/settings.local.json" +if [ -f "$LOCAL_SETTINGS" ] && [ -s "$LOCAL_SETTINGS" ]; then + CONTENT=$(cat "$LOCAL_SETTINGS" 2>/dev/null) + # Solo limpiar si tiene contenido real (no solo {} o vacío) + if [ "$CONTENT" != "{}" ] && [ "$CONTENT" != "" ]; then + echo "WARN: settings.local.json tenía contenido, reseteando a vacío" + echo -n "" > "$LOCAL_SETTINGS" + fi +fi + +# 5. Asegurar que settings.json tiene los permisos de allow/deny correctos +# Allow: editar .claude/ sin preguntar | Deny: nunca tocar .git/ +REQUIRED_PERMISSIONS='{ + "allow": [ + "Edit(~/.claude/**)", + "Write(~/.claude/**)", + "Edit(.claude/**)", + "Write(.claude/**)" + ], + "deny": [ + "Edit(~/.claude/.git/**)", + "Write(~/.claude/.git/**)", + "Edit(.git/**)", + "Write(.git/**)" + ] + }' + +SETTINGS_FILE="$REPO_DIR/.claude/settings.json" +if [ -f "$SETTINGS_FILE" ] && command -v jq &>/dev/null; then + CURRENT_PERMS=$(jq -c '.permissions // empty' "$SETTINGS_FILE" 2>/dev/null) + EXPECTED_PERMS=$(echo "$REQUIRED_PERMISSIONS" | jq -c '.') + + if [ "$CURRENT_PERMS" != "$EXPECTED_PERMS" ]; then + jq --argjson perms "$REQUIRED_PERMISSIONS" '.permissions = $perms' "$SETTINGS_FILE" > "$SETTINGS_FILE.tmp" \ + && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE" + echo "Actualizado: permissions en settings.json (allow .claude/*, deny .git/*)" + else + echo "OK: permissions ya están correctos" + fi +else + echo "WARN: jq no disponible, no se pudo verificar permissions" +fi + +# 6. Asegurar que el settings.json del repo no tiene permisos de escritura para group/others +chmod 644 "$REPO_DIR/.claude/settings.json" +echo "Permisos de settings.json del repo: 644 (rw-r--r--)" + echo "" echo "=== Instalación completada ===" echo "Tus comandos y configuración ahora están sincronizados con el repositorio." @@ -104,5 +191,7 @@ echo "Configuración instalada:" echo " • Skills y Agents enlazados simbólicamente" echo " • Status Line configurada con vibecoding setup" echo " • Settings.json enlazado (compartido entre repos)" +echo " • Backups viejos limpiados (>7 días)" +echo " • Archivos temporales de configuración eliminados" echo "" echo "Reinicia Claude Code para ver la nueva status line."