From 550150758816c0850df2f1dbafc281a76db53c1a Mon Sep 17 00:00:00 2001 From: egutierrez Date: Mon, 29 Jun 2026 12:42:55 +0200 Subject: [PATCH] =?UTF-8?q?feat(infra):=20launch=5Ffleetclaude=20auto-dete?= =?UTF-8?q?cta=20terminal=20(kitty=20=E2=86=94=20Windows=20Terminal)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La ruta ventana-nueva ya no asume kitty. Elige terminal según el host, sin config por PC: kitty si está instalado y hay display ($DISPLAY/$WAYLAND_DISPLAY); si no, en WSL abre Windows Terminal (wt.exe) ejecutando `wsl.exe [-d $WSL_DISTRO_NAME] -- bash -lic 'tmux ... attach'`. Arregla el síntoma "se lanza la flota pero no se ve": en WSL sin kitty la sesión tmux se creaba pero ninguna ventana la mostraba. Mismo `fleetclaude` funciona en un PC con kitty y en otro WSL sin kitty. wt.exe se lanza desde un subshell con cwd /mnt/c para evitar el warning por cwd UNC (\\wsl.localhost\...). El path de attach interactivo (terminal real fuera de tmux) queda intacto. Bump 1.5.0 -> 1.6.0. Co-Authored-By: Claude Opus 4.8 (1M context) --- bash/functions/infra/launch_fleetclaude.md | 49 ++++++++++++------ bash/functions/infra/launch_fleetclaude.sh | 58 ++++++++++++++++------ 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/bash/functions/infra/launch_fleetclaude.md b/bash/functions/infra/launch_fleetclaude.md index 5e0ba0cd..bc733ac8 100644 --- a/bash/functions/infra/launch_fleetclaude.md +++ b/bash/functions/infra/launch_fleetclaude.md @@ -3,11 +3,11 @@ name: launch_fleetclaude kind: function lang: bash domain: infra -version: "1.5.0" +version: "1.6.0" purity: impure signature: "launch_fleetclaude [--cwd ] [--bin ] [--session ] [--reuse] [--cols ]" -description: "Entrypoint de FleetView: abre una ventana kitty con una sesion tmux (socket aislado por perfil) de dos panes (TUI fleetview a la izquierda, claude --dangerously-skip-permissions a la derecha) para centralizar la flota de Claudes. El pane de la TUI corre dentro del bucle supervisor supervise_fleetview_tui, que la relanza si muere (crash/panic/kill), asi el panel de control NUNCA se pierde. Soporta PERFILES multiples: sin --session/--reuse cada invocacion abre un perfil nuevo (fleet, fleet2, fleet3, ...) con su propia flota; inyecta FLEET_SOCKET/FLEET_SESSION a la TUI para que cada panel vea solo sus Claudes. Instala atajos alt+flechas/alt+enter/alt+n que controlan la TUI desde cualquier pane, y fija el ancho del sidebar con hooks." -tags: [claude-fleet, infra, kitty, tmux, claude, fleetview, launcher] +description: "Entrypoint de FleetView: abre una ventana de terminal con una sesion tmux (socket aislado por perfil) de dos panes (TUI fleetview a la izquierda, claude --dangerously-skip-permissions a la derecha) para centralizar la flota de Claudes. La terminal se AUTO-DETECTA sin config por PC: kitty si esta instalado y hay display ($DISPLAY/$WAYLAND_DISPLAY), si no Windows Terminal (wt.exe) en WSL adjuntando via wsl.exe. El pane de la TUI corre dentro del bucle supervisor supervise_fleetview_tui, que la relanza si muere (crash/panic/kill), asi el panel de control NUNCA se pierde. Soporta PERFILES multiples: sin --session/--reuse cada invocacion abre un perfil nuevo (fleet, fleet2, fleet3, ...) con su propia flota; inyecta FLEET_SOCKET/FLEET_SESSION a la TUI para que cada panel vea solo sus Claudes. Instala atajos alt+flechas/alt+enter/alt+n que controlan la TUI desde cualquier pane, y fija el ancho del sidebar con hooks." +tags: [claude-fleet, infra, kitty, tmux, claude, fleetview, launcher, wsl, windows-terminal] params: - name: --cwd desc: "Directorio de trabajo de ambos panes tmux. Opcional. Default: raiz del repo fn_registry, derivada dinamicamente via git rev-parse desde la ubicacion del script (sin hardcodear paths de usuario)." @@ -19,7 +19,7 @@ params: desc: "Reattach al perfil principal 'fleet' en vez de abrir uno nuevo. Opcional. Recupera el comportamiento idempotente clasico (volver a invocar NO duplica la flota, reusa la existente)." - name: --cols desc: "Ancho en columnas del pane izquierdo (la TUI). Opcional. Default: 40." -output: "Crea/reutiliza una sesion tmux detached con dos panes y lanza una ventana kitty 'FleetView' adjunta a ella, desacoplada del shell padre (setsid). Imprime el estado por stdout. Sin valor de retorno; exit 0 en exito." +output: "Crea/reutiliza una sesion tmux detached con dos panes y lanza una ventana de terminal 'FleetView' adjunta a ella (kitty o Windows Terminal segun auto-deteccion), desacoplada del shell padre. Imprime el estado por stdout. Sin valor de retorno; exit 0 en exito." uses_functions: - supervise_fleetview_tui_bash_infra uses_types: [] @@ -49,7 +49,7 @@ launch_fleetclaude --reuse launch_fleetclaude --session trabajo --cols 50 ``` -Tras invocarlo aparece una ventana kitty titulada `FleetView ()` con dos +Tras invocarlo aparece una ventana de terminal titulada `FleetView ()` con dos panes lado a lado: a la izquierda la TUI `fleetview`, a la derecha una sesion de `claude --dangerously-skip-permissions`. Cada perfil es un socket+sesion tmux aislados con su propia flota: puedes tener varias FleetView abiertas a la vez. @@ -78,12 +78,24 @@ al retomar el trabajo en el repo `fn_registry`. `respawn-pane` de alt+R y los Claude nuevos hereden el socket). `main.go` los lee con fallback a `fleet`. Por eso cada panel ve SOLO los Claude de su perfil (cruza la lista del sistema con los panes de su socket). +- **Auto-deteccion de terminal (sin config por PC)**: en la ruta ventana-nueva el + launcher elige terminal solo. (1) `kitty` instalado **y** display usable + (`$DISPLAY`/`$WAYLAND_DISPLAY`) → kitty (escritorio Linux nativo o WSLg con + kitty). (2) Si no, WSL con `wt.exe` en el PATH → Windows Terminal ejecutando + `wsl.exe [-d $WSL_DISTRO_NAME] -- bash -lic 'tmux -L attach ...'`. + (3) Ninguna → error con las salidas posibles. Asi el MISMO `fleetclaude` + funciona en un PC con kitty y en otro WSL sin kitty, cada uno elige su + terminal. Causa raiz del sintoma "se lanza la flota pero no se ve": kitty no + instalado en WSL hacia que la sesion tmux se creara sin ventana que la mostrara. - **Dentro de tmux abre ventana nueva**: si invocas `fleetclaude` desde dentro de una sesion tmux (`$TMUX` definido), NO hace `attach` anidado (rompe / avisa de - nesting); cae a la ruta kitty y abre una ventana nueva. Fuera de tmux y con - TTY, reutiliza la terminal actual con `exec tmux attach`. -- **kitty detached (setsid)**: la ventana se lanza con `setsid ... &` para - sobrevivir al cierre de la terminal que la invoco. No bloquea al shell padre. + nesting); cae a la ruta ventana-nueva (auto-deteccion de terminal). Fuera de + tmux y con TTY, reutiliza la terminal actual con `exec tmux attach`. +- **kitty detached (setsid)**: la ventana kitty se lanza con `setsid ... &` para + sobrevivir al cierre de la terminal que la invoco. La ventana de Windows + Terminal (wt.exe) ya es un proceso Windows independiente del arbol Linux, asi + que sobrevive sola (se lanza con `&`+`disown` desde un subshell con cwd `/mnt/c` + para evitar el warning de wt.exe por cwd UNC `\\wsl.localhost\...`). - **TUI bajo supervisor (auto-respawn)**: el pane izquierdo NO corre un `exec fleetview` de una sola vida, sino `supervise_fleetview_tui` (bucle que relanza la TUI si muere por crash/panic/kill). Asi el panel de control nunca se @@ -116,14 +128,23 @@ al retomar el trabajo en el repo `fn_registry`. - **Ancho del sidebar via hooks**: `client-resized` y `window-layout-changed` re-fijan el pane 0 (TUI) a `--cols` columnas, porque el `attach` de kitty y el conmutar de Claude redistribuyen el espacio. -- **tmux siempre, kitty solo sin TTY**: `tmux` es obligatorio (aborta != 0 si - falta). `kitty` solo se necesita en la ruta sin-TTY (atajo de escritorio, cron, - script), donde abre una ventana nueva. Invocado desde una terminal interactiva - (el caso normal del alias `fleetclaude`), reutiliza la terminal actual con - `exec tmux attach` y NO necesita kitty — util en WSL u hosts sin kitty. +- **tmux siempre; terminal (kitty/wt.exe) solo sin TTY**: `tmux` es obligatorio + (aborta != 0 si falta). Una terminal nueva (kitty o Windows Terminal) solo se + necesita en la ruta sin-TTY (dentro de tmux, atajo de escritorio, cron, script), + donde abre una ventana nueva. Invocado desde una terminal interactiva fuera de + tmux (el caso normal del alias `fleetclaude`), reutiliza la terminal actual con + `exec tmux attach` y no necesita ni kitty ni wt.exe. ## Capability growth log +- v1.6.0 (2026-06-29) — **auto-deteccion de terminal (kitty ↔ Windows Terminal)**. + La ruta ventana-nueva ya no asume kitty: elige terminal segun el host. kitty si + esta instalado y hay display (`$DISPLAY`/`$WAYLAND_DISPLAY`); si no, en WSL abre + Windows Terminal (`wt.exe`) ejecutando `wsl.exe [-d $WSL_DISTRO_NAME] -- bash + -lic 'tmux ... attach'`. Mismo `fleetclaude` en un PC con kitty y en otro WSL + sin kitty. Arregla el sintoma "se lanza la flota pero no se ve": en WSL sin + kitty la sesion tmux se creaba pero ninguna ventana la mostraba. wt.exe se + lanza desde un subshell con cwd `/mnt/c` para evitar el warning por cwd UNC. - v1.5.0 (2026-06-24) — **auto-respawn de la TUI**. El pane izquierdo ya no corre `exec fleetview` (una sola vida), sino el bucle supervisor `supervise_fleetview_tui`, que relanza la TUI si muere (crash/panic/kill de su diff --git a/bash/functions/infra/launch_fleetclaude.sh b/bash/functions/infra/launch_fleetclaude.sh index 67b25916..853171e1 100644 --- a/bash/functions/infra/launch_fleetclaude.sh +++ b/bash/functions/infra/launch_fleetclaude.sh @@ -294,31 +294,61 @@ USAGE $T set-hook -g window-layout-changed "resize-pane -t $left_pane -x $cols" # ----------------------------------------------------------------------- - # Lanzar kitty adjuntando la sesion, DESACOPLADA del shell padre con - # setsid, para que no muera al cerrar la terminal invocadora. - # (Mismo patron que reboot_all_claudes para relanzar terminales.) + # Adjuntar la sesion en una terminal, DESACOPLADA del shell padre para que + # no muera al cerrar la terminal invocadora. # ----------------------------------------------------------------------- # Adjuntar la sesion: # - Terminal interactiva y FUERA de tmux: convertir ESA terminal en el # panel FleetView (exec reemplaza el proceso; al hacer detach vuelve la # shell). Asi `fleetclaude` no abre otra ventana: usa la actual. # - DENTRO de tmux (o sin TTY: atajo de escritorio, cron, script): abrir - # una ventana kitty nueva desacoplada (setsid). No hacemos `attach` + # una ventana de terminal NUEVA desacoplada. No hacemos `attach` # anidado dentro de otra sesion tmux (rompe / da el warning de nesting). if [ -t 0 ] && [ -t 1 ] && [ -z "${TMUX:-}" ]; then exec tmux -L "$session" attach -t "$session" fi - # Ruta ventana-nueva: necesitamos kitty para abrirla. - if ! command -v kitty >/dev/null 2>&1; then - echo "launch_fleetclaude: kitty no esta instalado (necesario para abrir ventana nueva)." >&2 - echo "launch_fleetclaude: lanzalo desde una terminal interactiva fuera de tmux, o instala kitty." >&2 - return 1 - fi - setsid kitty --title "FleetView ($session)" -e tmux -L "$session" attach -t "$session" /dev/null 2>&1 & - disown 2>/dev/null || true - echo "launch_fleetclaude: ventana kitty 'FleetView ($session)' adjunta al perfil '$session'." - return 0 + # ----------------------------------------------------------------------- + # Ruta ventana-nueva: AUTO-DETECTAR la terminal disponible (sin config por + # PC). El mismo `fleetclaude` funciona en un escritorio Linux con kitty y en + # un WSL sin kitty pero con Windows Terminal. + # 1. kitty instalado + display usable ($DISPLAY/$WAYLAND_DISPLAY) -> kitty + # (escritorio Linux nativo, o WSLg con kitty instalado). + # 2. WSL con wt.exe alcanzable -> Windows Terminal ejecutando wsl.exe que + # adjunta la sesion tmux (PCs WSL sin kitty: la ventana kitty nunca + # aparece sin una terminal Linux real, por eso "se lanza pero no se ve"). + # 3. Ninguna -> error claro con las dos salidas posibles. + # ----------------------------------------------------------------------- + if command -v kitty >/dev/null 2>&1 && [[ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]]; then + setsid kitty --title "FleetView ($session)" -e tmux -L "$session" attach -t "$session" /dev/null 2>&1 & + disown 2>/dev/null || true + echo "launch_fleetclaude: ventana kitty 'FleetView ($session)' adjunta al perfil '$session'." + return 0 + fi + + if command -v wt.exe >/dev/null 2>&1; then + # bash -lic dentro de wsl.exe: login+interactive para que tmux y + # el PATH del perfil esten disponibles en la ventana de Windows Terminal. + local attach_cmd + attach_cmd="tmux -L $(printf '%q' "$session") attach -t $(printf '%q' "$session")" + local distro="${WSL_DISTRO_NAME:-}" + local wsl_args=(wsl.exe) + [[ -n "$distro" ]] && wsl_args+=(-d "$distro") + wsl_args+=(-- bash -lic "$attach_cmd") + # cd a una ruta Windows (/mnt/c) evita el warning de wt.exe por cwd UNC + # (\\wsl.localhost\...). El cwd real de los panes lo fija la sesion tmux. + ( cd /mnt/c 2>/dev/null || cd / + wt.exe new-tab --title "FleetView ($session)" "${wsl_args[@]}" /dev/null 2>&1 & + disown 2>/dev/null || true ) + echo "launch_fleetclaude: Windows Terminal 'FleetView ($session)' adjunta al perfil '$session' (WSL distro '${distro:-default}')." + return 0 + fi + + echo "launch_fleetclaude: no hay terminal para abrir una ventana nueva." >&2 + echo "launch_fleetclaude: - escritorio Linux: instala kitty y exporta DISPLAY/WAYLAND_DISPLAY." >&2 + echo "launch_fleetclaude: - WSL: usa Windows Terminal (wt.exe debe estar en el PATH)." >&2 + echo "launch_fleetclaude: - o lanza fleetclaude desde una terminal interactiva fuera de tmux." >&2 + return 1 } # Permitir ejecutar el archivo directamente (no solo como funcion sourced).