---
name: prepare_chrome_profile
kind: function
lang: bash
domain: browser
version: "1.0.0"
purity: impure
signature: "prepare_chrome_profile --src <user-data-dir> --dst <user-data-dir> [--keep <ext_id>]... [--force]"
description: "Clona un user-data-dir de Chrome/Chromium creando un perfil de scraping limpio: conserva solo las extensiones de una lista blanca (por defecto uBlock Origin Lite) y excluye caché, locks y sesiones antiguas."
tags: [chrome, browser, profile, scraping, extensions, navegator]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "bash/functions/browser/prepare_chrome_profile.sh"
params:
  - name: --src
    desc: "user-data-dir origen con un perfil Chrome/Chromium ya configurado (debe existir --src/Default)"
  - name: --dst
    desc: "Ruta de destino del nuevo perfil; no debe existir salvo que se pase --force"
  - name: --keep
    desc: "ID de extensión Chrome a conservar (repetible). Si no se pasa ninguno el default es ddkjiahejlhfcafbddmgiahcphecmpfh (uBlock Origin Lite)"
  - name: --force
    desc: "Borra --dst si existe antes de recrearlo. Sin este flag la función aborta si --dst ya existe"
output: "JSON en stdout: {dst, kept: [id...], removed: [id...]}. Exit 0 en éxito."
---

## Ejemplo

```bash
source $HOME/fn_registry/bash/functions/browser/prepare_chrome_profile.sh

prepare_chrome_profile \
  --src "$HOME/.config/chromium" \
  --dst "$HOME/.local/share/web_scraping/chrome-profile"

# Con extensión adicional conservada
prepare_chrome_profile \
  --src "$HOME/.config/chromium" \
  --dst "$HOME/.local/share/web_scraping/chrome-profile" \
  --keep "ddkjiahejlhfcafbddmgiahcphecmpfh" \
  --keep "cjpalhdlnbpafiamejdnhcphjbkeiagm" \
  --force

# Salida esperada (ejemplo):
# {"dst":"/home/enmanuel/.local/share/web_scraping/chrome-profile","kept":["ddkjiahejlhfcafbddmgiahcphecmpfh"],"removed":["abcdefghijklmnopabcdefghijklmnop","dark-reader-id"]}
```

## Cuando usarla

Úsala antes de lanzar una sesión de scraping/automatización para partir de un perfil aislado: con uBlock Origin Lite activo (menos anuncios/trackers = DOM más limpio, respuestas más rápidas) pero sin extensiones que interfieren (Dark Reader muta colores del DOM, NoScript bloquea JS, OneTab modifica tabs). También sirve para aislar sesiones de diferentes proyectos de scraping sin contaminar el perfil personal.

## Gotchas

- **Chrome debe estar CERRADO sobre `--src`** antes de ejecutar. Los archivos SQLite (`Cookies`, `History`, `Login Data`, etc.) estarán bloqueados si Chrome está abierto, y `rsync` copiará versiones inconsistentes. Verificar con `pgrep -x chromium` o `pgrep -x chrome`.
- **HMAC de Secure Preferences**: el archivo `Local State` contiene la semilla HMAC que Chrome usa para verificar `Preferences` y `Secure Preferences`. Si no se copia (o se copia entre máquinas distintas con distinto binding), Chrome puede invalidar las extensiones al arrancar y resetear configuraciones. La función copia `Local State` automáticamente, pero la copia entre máquinas puede seguir produciendo resets de extensiones — esto es comportamiento esperado de Chrome, no un bug de esta función.
- **Purga de referencias en Preferences**: tras borrar las carpetas de extensiones fuera de la whitelist, la función también elimina con `python3` las entradas `extensions.settings.<id>` de `Default/Preferences` y `Default/Secure Preferences`, los IDs de `extensions.pinned_extensions` y las claves `protection.macs.extensions.settings.<id>`. Sin esta limpieza Chrome detecta las entradas en Preferences (con `from_webstore`/install_source) y **vuelve a descargar la extensión del Web Store al arrancar**, deshaciendo el filtrado (caso real: Dark Reader reaparece y oscurece páginas rompiendo screenshots). Si `python3` falla al procesar un Preferences concreto se emite un warning a stderr pero la función no aborta — el borrado de carpetas ya es el efecto principal.
- **`--force` borra `--dst` completamente**: si `--dst` es un perfil con datos que quieres conservar, no uses `--force` sin antes hacer backup.
- **Extensiones instaladas desde Web Store vs unpacked**: esta función opera sobre la carpeta `Extensions/` física. Las extensiones instaladas desde la Web Store tienen IDs de 32 caracteres en minúsculas. Las extensiones unpacked (`--load-extension`) no viven en `Extensions/` y no se ven afectadas.

## Exit codes

| Código | Significado |
|--------|------------|
| 0 | Éxito |
| 1 | Argumento inválido o `--src/Default` no existe |
| 2 | `--dst` ya existe y no se pasó `--force` |
| 3 | `--src` y `--dst` resuelven al mismo path real |
| 4 | Error durante `rsync` |
