--- name: launch_fleetclaude kind: function lang: bash domain: infra version: "1.7.0" purity: impure signature: "launch_fleetclaude [--cwd ] [--bin ] [--session ] [--reuse] [--new] [--cols ]" 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. REUSO DE CONTEXTO: si se invoca DENTRO de una flota tmux viva (su window 'console') sin --new, NO abre ventana ni crea un perfil nuevo; trae la TUI al pane/contexto actual (equivale a 'fleetview show'). El flag --new fuerza una flota+ventana nueva aunque estes en tmux. 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: fuera de tmux, o con --new, 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)." - name: --bin desc: "Ruta al binario de la TUI fleetview que corre en el pane izquierdo. Opcional. Default: /apps/fleetview/fleetview. Si no es ejecutable, el pane izquierdo muestra un mensaje de como compilarla y deja una shell viva." - name: --session desc: "Fija el perfil (socket+sesion tmux comparten nombre) por nombre exacto; reutiliza el existente si ya vive (idempotente sobre ese nombre). Opcional. Sin esta opcion, el perfil se elige automaticamente (primer nombre libre de la secuencia fleet, fleet2, ...). Invocado DENTRO de tmux con un nombre DISTINTO al de la flota actual equivale a --new (pides otra flota: ventana nueva, sin reuse de contexto)." - name: --reuse 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: --new desc: "Fuerza una flota NUEVA en una ventana NUEVA (kitty/wt.exe) incluso estando dentro de una flota tmux. Opcional. Es la via explicita para abrir una FleetView aparte; sin este flag, invocado dentro de una flota viva se reusa el contexto actual (no abre ventana ni crea perfil)." - name: --cols desc: "Ancho en columnas del pane izquierdo (la TUI). Opcional. Default: 40." output: "Caso reuse de contexto (dentro de una flota tmux viva, sin --new): trae la TUI al pane/contexto actual con select-window de la window 'console' (o 'fleetview show' si el binario existe) y retorna 0, sin abrir nada. Caso ventana-nueva (fuera de tmux, o con --new): crea/reutiliza una sesion tmux detached con dos panes y lanza una ventana de terminal 'FleetView' adjunta (kitty o Windows Terminal segun auto-deteccion), desacoplada del shell padre. Imprime el estado por stdout. Sin valor de retorno; exit 0 en exito, !=0 con mensaje claro si no hay terminal ni contexto que reusar." uses_functions: - supervise_fleetview_tui_bash_infra uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] tested: false tests: [] test_file_path: "" file_path: "bash/functions/infra/launch_fleetclaude.sh" --- ## Ejemplo ```bash # DENTRO de una flota tmux viva (p. ej. en el pane del orquestador): reusa el # contexto, trae la TUI al pane actual. NO abre ventana ni crea perfil nuevo. fleetclaude # FUERA de tmux: perfil nuevo automatico (fleet la 1a vez; fleet2, ... si ya hay # uno) en una ventana de terminal nueva, reutilizando la terminal actual (attach): fleetclaude # Forzar una flota+ventana NUEVA aunque estes dentro de una flota tmux: fleetclaude --new # Reattach a la flota principal 'fleet' (comportamiento idempotente clasico): fleetclaude --reuse # Perfil con nombre fijo y ancho de pane personalizado: fleetclaude --session trabajo --cols 50 # Via fn run (resuelve por nombre o ID): fn run launch_fleetclaude ``` Dentro de una flota viva, `fleetclaude` sin args reusa el contexto (la window `console` pasa al frente). Fuera de tmux (o con `--new`) 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 con `--new`. ## Cuando usarla Usala cuando quieras un unico punto de entrada a la flota de Claudes en vez de N ventanas kitty sueltas: lanzas `fleetclaude` y tienes la TUI de control y un Claude listo para trabajar en la misma ventana. Tipico al empezar la jornada o al retomar el trabajo en el repo `fn_registry`. Si **ya estas dentro de una flota** (en el pane del orquestador) y solo quieres volver a ver la TUI, lanza `fleetclaude` sin args: trae el panel al contexto actual sin abrir otra ventana ni arrancar una flota duplicada. Usa `--new` solo cuando quieras DELIBERADAMENTE una segunda flota aparte. ## Gotchas - **Perfiles multiples (default = perfil nuevo)**: sin `--session` ni `--reuse`, cada invocacion abre un perfil NUEVO usando el primer nombre libre de la secuencia `fleet`, `fleet2`, `fleet3`, ... (socket+sesion tmux comparten el nombre del perfil). Asi puedes tener varias FleetView abiertas a la vez, cada una con su flota independiente. Un perfil cerrado libera su nombre: tras matar `fleet`, el siguiente lanzamiento vuelve a `fleet`. Para reattach a una flota concreta: `--reuse` (principal `fleet`) o `--session ` (idempotente sobre ese nombre, reusa el layout si ya vive). - **Perfil ↔ TUI por entorno**: el launcher inyecta `FLEET_SOCKET`/`FLEET_SESSION` al pane de la TUI (y los fija en el server con `set-environment -g`, para que `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 una flota tmux viva: reuse de contexto (no ventana nueva)**: si invocas `fleetclaude` sin `--new` desde dentro de una flota fleetview viva (`$TMUX` definido y el socket actual tiene una sesion homonima con window `console`), NO abre ventana ni crea un perfil `fleetN+1`: trae la TUI al pane actual (`fleetview show`, o `tmux -L select-window -t :console` si el binario no esta compilado) y retorna 0. El perfil de la flota actual se deriva de `$TMUX` (basename del socket = nombre `-L`), senal fiable aunque `$FLEET_SOCKET` venga vacio (ver `detect_fleet_context`). **`--new`** fuerza el comportamiento clasico (flota+ventana nueva); pasar `--session ` distinto al perfil actual equivale a `--new` implicito. Fuera de tmux y con TTY, reutiliza la terminal actual con `exec tmux attach` (nunca `attach` anidado dentro de tmux). Sin TTY ni contexto que reusar (atajo de escritorio/cron) cae a la ruta ventana-nueva. Antes de este fix (v1.6.0 y anteriores) cualquier `fleetclaude` dentro de tmux abria una kitty nueva y un socket `fleetN+1` — el sintoma que acumulaba 6+ sockets `fleet*`. - **`local x` unbound bajo `set -u`**: el archivo corre con `set -euo pipefail`. `local left_pane right_pane` dejaba esas vars *unbound* (no vacias), asi que la rama "reutilizar sesion existente" (`--reuse`/`--session `) reventaba con `left_pane: unbound variable` al evaluar `[[ -z "$left_pane" ]]`. Se inicializan explicitamente a `""` (`local left_pane="" right_pane=""`). Si tocas estas vars, no vuelvas a declararlas sin valor. - **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 pierde por un fallo puntual. El supervisor para limpio con su sentinel (`touch ~/.claude/fleet/tui_stop_` y deja salir la TUI) o se rinde si la TUI entra en crash-loop; en ambos casos el pane cae a una shell viva (no se cierra solo) para inspeccionar. Es la mitad "auto-recuperacion" del par de fixes que blindan FleetView; la otra es el Guard 3 anti-TUI/console de `kill_fleet_agent` (la causa raiz del cierre accidental). Si el script del supervisor no estuviera en disco, cae al `exec fleetview` clasico. - **`exec` en los demas panes**: `claude` (orquestador e idle) se lanza con `exec`, asi que al terminar el proceso el pane se cierra en vez de dejar una shell zombie. Excepcion: el fallback cuando `fleetview` no esta compilado deja una shell interactiva a proposito (para que veas el mensaje y puedas compilar). - **Requiere fleetview compilado**: el default `--bin` apunta a `/apps/fleetview/fleetview`. Si ese binario no existe, el pane izquierdo muestra `cd apps/fleetview && go build -o fleetview .` en lugar de fallar en silencio. Compila la TUI antes para el flujo completo. - **Socket tmux aislado por perfil (`-L `)**: cada perfil vive en su propio server tmux (socket = nombre del perfil), separado del tmux por defecto del usuario y de los demas perfiles. Asi los atajos `bind -n` NO afectan otras sesiones (ej. una sesion `mobile-1` del movil) y matar un perfil no toca los otros: `tmux -L kill-server` (o `alt+q` dentro de la TUI). - **Atajos en el socket, NO en kitty.conf**: instala `bind -n` para `alt+flechas` (mover el cursor de la TUI), `alt+enter` (conmutar al Claude seleccionado) y `alt+n` (abrir Claude nuevo). Son bindings de tmux que redirigen la tecla al pane de la TUI (`send-keys -t console.0`), asi funcionan ESTES DONDE ESTES (incluido escribiendo en el pane de Claude). No modifican la configuracion de kitty ni los atajos globales del escritorio. - **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; terminal (kitty/wt.exe) solo en la ruta ventana-nueva**: `tmux` es obligatorio (aborta != 0 si falta). Una terminal nueva (kitty o Windows Terminal) solo se necesita en la ruta ventana-nueva: `--new`, o sin TTY ni flota viva que reusar (atajo de escritorio, cron, script). Dentro de una flota viva sin `--new` se reusa el contexto (ni kitty ni wt.exe). Invocado desde una terminal interactiva fuera de tmux (el caso normal del alias `fleetclaude`), reutiliza la terminal actual con `exec tmux attach` y tampoco necesita kitty ni wt.exe. ## Capability growth log - v1.7.0 (2026-06-30) — **reuse de contexto dentro de la flota + flag `--new`**. Invocado sin `--new` desde dentro de una flota tmux viva (su window `console`), `fleetclaude` ya NO abre una kitty nueva ni crea un perfil `fleetN+1`: trae la TUI al pane/contexto actual (`fleetview show`, o `tmux -L select-window -t :console` como fallback sin binario) y retorna 0. El perfil actual se deriva de `$TMUX` (basename del socket); pasar `--session ` distinto al actual equivale a `--new` implicito. Nuevo flag `--new` para forzar la ruta clasica (flota+ventana nueva) aun dentro de tmux. Fuera de tmux el comportamiento es intacto (`exec tmux attach` reutiliza la terminal). Arregla el sintoma de que lanzar `fleetclaude` dentro de una flota abria ventana kitty + socket nuevo (`fleet7`, `fleet8`, ...). Fix incidental: `local left_pane="" right_pane=""` (antes `local left_pane right_pane` reventaba con `unbound variable` bajo `set -u` al reutilizar una sesion existente). - 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 proceso o pane). Asi el panel de control NUNCA se pierde por un fallo puntual. Parada voluntaria via sentinel; crash-loop guard para no relanzar en bucle cerrado. Complementa el Guard 3 anti-TUI/console de `kill_fleet_agent` (causa raiz del cierre accidental). Nueva dependencia: `supervise_fleetview_tui_bash_infra`. - v1.4.0 (2026-06-18) — **perfiles multiples**. Socket+sesion tmux ya no son el fijo `fleet`: cada perfil tiene los suyos (mismo nombre). Sin `--session`/ `--reuse`, cada invocacion abre el primer perfil libre (`fleet`, `fleet2`, ...), asi abrir FleetView con uno ya abierto arranca otra flota en vez de reusarla. Nuevo flag `--reuse` para el reattach idempotente clasico. El launcher inyecta `FLEET_SOCKET`/`FLEET_SESSION` (env + `set-environment -g`) y `main.go` de `fleetview` los lee (fallback `fleet`), de modo que cada panel ve solo su flota. Titulo de kitty `FleetView ()`. Guard anti-nesting: invocado dentro de tmux abre ventana kitty nueva en vez de `attach` anidado. - v1.3.2 (2026-06-17) — targeting de panes por **pane ID** (`%0`/`%1`) en vez de por indice (`console.0`). Antes fallaba con `can't find pane: 0` en hosts cuyo `~/.tmux.conf` define `base-index 1`/`pane-base-index 1` (el socket `-L fleet` hereda esa config). Los pane ID son inmunes al base-index. Bug latente que el fix de kitty (v1.3.1) destapo al dejar de abortar antes de montar la sesion. - v1.3.1 (2026-06-17) — el guard de `kitty` se movio a la rama sin-TTY. La ruta interactiva (`exec tmux attach`) ya no exige kitty, asi que `fleetclaude` funciona en hosts sin kitty (p.ej. WSL) reutilizando la terminal actual. - v1.3.0 (2026-06-17) — renombrada de `launch_kittyclaude` a `launch_fleetclaude` (comando `fleetclaude`). Atajos: `alt+0` (= alt+n, abrir Claude nuevo), `alt+k` (kill con confirmacion), `alt+r` (picker de reanudar sesiones cerradas) y `alt+flecha-izquierda` (volver atras desde el picker). Cierra la window al salir el Claude (`remain-on-exit off`). - v1.2.0 (2026-06-16) — ancho del sidebar por defecto 47 columnas; `ctrl+0` como atajo alterno para abrir Claude nuevo; `mouse on` (clic/rueda enrutados a la TUI) y `extended-keys on` (para que `ctrl+0` llegue distinguible por el protocolo de teclado de kitty). - v1.1.0 (2026-06-16) — socket tmux aislado `-L fleet`; instala atajos `alt+flechas` / `alt+enter` / `alt+n` que controlan la TUI desde cualquier pane; hooks que mantienen fijo el ancho del sidebar tras attach/conmutar.