#!/usr/bin/env bash # chrome_load_extensions — lanza Chrome (WSL2→Windows chrome.exe) con extensiones unpacked cargadas en un perfil CDP. # Chrome 148+: requiere --load-extension= Y --disable-extensions-except= juntos. # NUNCA pasar --disable-extensions (desactiva todo, incluyendo las que quieres cargar). chrome_load_extensions() { local port=9222 local profile="" local proxy="" local url="" local -a ext_paths=() # --- Parse args --- while [[ $# -gt 0 ]]; do case "$1" in --port) port="$2"; shift 2 ;; --profile) profile="$2"; shift 2 ;; --ext) ext_paths+=("$2"); shift 2 ;; --proxy) proxy="$2"; shift 2 ;; --url) url="$2"; shift 2 ;; --*) echo "chrome_load_extensions: flag desconocido: $1" >&2; return 1 ;; *) # Positional = extra ext path ext_paths+=("$1"); shift ;; esac done if [[ ${#ext_paths[@]} -eq 0 ]]; then echo "chrome_load_extensions: se requiere al menos un --ext PATH de extension unpacked" >&2 return 1 fi # --- Detectar chrome.exe --- local chrome_bin="" if command -v chrome.exe &>/dev/null; then chrome_bin="chrome.exe" elif [[ -f "/mnt/c/Program Files/Google/Chrome/Application/chrome.exe" ]]; then chrome_bin="/mnt/c/Program Files/Google/Chrome/Application/chrome.exe" elif [[ -f "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" ]]; then chrome_bin="/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" else echo "chrome_load_extensions: chrome.exe no encontrado en PATH ni en rutas conocidas" >&2 return 1 fi # --- Detectar WSL2 --- local wsl2=0 if grep -qi 'microsoft\|wsl' /proc/version 2>/dev/null; then wsl2=1 fi # --- Traducir paths de extensiones a Windows si hace falta --- local -a win_ext_paths=() for p in "${ext_paths[@]}"; do if [[ $wsl2 -eq 1 ]] && [[ "$p" != [A-Za-z]:\\* ]]; then # Path Linux → traducir a Windows local win_p win_p=$(wslpath -w "$p" 2>/dev/null) || { echo "chrome_load_extensions: wslpath -w '$p' falló" >&2 return 1 } win_ext_paths+=("$win_p") else win_ext_paths+=("$p") fi done # --- Resolver perfil --- if [[ -z "$profile" ]]; then # Default: perfil canónico fn-chrome-cdp-profile en Windows local win_user="${USERNAME:-${USER:-lucas}}" if [[ $wsl2 -eq 1 ]]; then profile="C:\\Users\\${win_user}\\AppData\\Local\\fn-chrome-cdp-profile" else profile="/tmp/fn-chrome-cdp-profile" fi elif [[ $wsl2 -eq 1 ]] && [[ "$profile" != [A-Za-z]:\\* ]]; then # Path Linux del perfil → traducir a Windows profile=$(wslpath -w "$profile" 2>/dev/null) || { echo "chrome_load_extensions: wslpath -w '$profile' falló" >&2 return 1 } fi # --- Construir lista de paths separada por coma (para Chrome) --- # Chrome usa coma como separador en --load-extension y --disable-extensions-except. # NO usar `echo` para el join: rutas Windows como C:\Users tienen \U, y el echo de # zsh (o sh con xpg_echo) interpreta \U como escape unicode y trunca la ruta a "C:". # Acumulador con += y printf-safe, sin interpretacion de backslashes. local ext_list="" local p for p in "${win_ext_paths[@]}"; do ext_list+="${ext_list:+,}${p}" done # --- Construir args de Chrome --- local -a args=( "--remote-debugging-port=${port}" "--user-data-dir=${profile}" "--no-first-run" "--no-default-browser-check" "--remote-allow-origins=*" "--load-extension=${ext_list}" "--disable-extensions-except=${ext_list}" # Chrome 137+ activa por defecto el feature DisableLoadExtensionCommandLineSwitch, # que IGNORA silenciosamente --load-extension. Hay que desactivarlo o las # extensiones unpacked no cargan (chrome://extensions sale vacio). "--disable-features=DisableLoadExtensionCommandLineSwitch" ) # WSL2: bind en 0.0.0.0 para que sea accesible desde la red WSL if [[ $wsl2 -eq 1 ]]; then args+=("--remote-debugging-address=0.0.0.0") fi if [[ -n "$proxy" ]]; then args+=("--proxy-server=${proxy}") fi if [[ -n "$url" ]]; then args+=("--new-window" "$url") fi # --- Revisar si CDP ya responde en el puerto --- if curl -sf --max-time 1 "http://127.0.0.1:${port}/json/version" &>/dev/null; then echo "chrome_load_extensions: CDP ya activo en puerto ${port}; lanzando ventana extra" >&2 fi # --- Lanzar Chrome desacoplado del proceso padre --- # setsid + redirección evita el exit 144 en el Bash tool (el pipe no queda retenido). setsid "$chrome_bin" "${args[@]}" "/tmp/chrome_ext_${port}.log" 2>&1 & local chrome_pid=$! disown "$chrome_pid" echo "chrome_load_extensions: Chrome lanzado PID=${chrome_pid} puerto=${port}" >&2 # --- Esperar a que CDP esté listo (hasta 15 segundos) --- local deadline=$(( $(date +%s) + 15 )) local ready=0 while [[ $(date +%s) -lt $deadline ]]; do if curl -sf --max-time 1 "http://127.0.0.1:${port}/json/version" &>/dev/null; then ready=1 break fi sleep 0.5 done if [[ $ready -eq 1 ]]; then echo "chrome_load_extensions: CDP listo en 127.0.0.1:${port}" else echo "chrome_load_extensions: advertencia — CDP no respondió en 15s en puerto ${port}; Chrome puede estar iniciando lentamente" >&2 fi echo "$chrome_pid" }