--- name: detect_fleet_context kind: function lang: bash domain: infra version: 1.0.0 purity: impure signature: "detect_fleet_context() -> JSON {in_fleet,in_tmux,socket,session,source}" description: "Detecta de forma robusta si el proceso corre dentro de una flota tmux FleetView, derivando socket y sesion de $TMUX (senal fiable) en vez de $FLEET_SOCKET (fragil, a veces vacia en un claude resumido/relanzado). Salida JSON con in_fleet/in_tmux/socket/session/source." tags: [orchestration, fleet, tmux, infra] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: error_go_core imports: [] tested: false file_path: "bash/functions/infra/detect_fleet_context.sh" params: - name: "(ninguno)" desc: "No recibe argumentos. Lee el entorno ($TMUX, con fallback a $FLEET_SOCKET/$FLEET_SESSION) y consulta el servidor tmux." output: "JSON en stdout: {\"in_fleet\":bool, \"in_tmux\":bool, \"socket\":str, \"session\":str, \"source\":\"tmux|fleet_socket|none\"}. in_tmux=true basta para lanzar una window; in_fleet es la senal semantica de 'estoy en una flota'." --- # detect_fleet_context Detecta el contexto de flota del proceso actual sin depender de `$FLEET_SOCKET`. ## Por que existe La deteccion de "estoy en una flota FleetView" dependia de la variable de entorno `$FLEET_SOCKET`, que `launch_fleetclaude` exporta con `tmux set-environment -g`. Esa variable solo llega a los procesos que tmux arranca **despues** de setearla: un `claude` relanzado o resumido a mano puede no heredarla y `$FLEET_SOCKET` queda vacia, aunque ese claude SI viva en una window de la flota. Cuando eso pasa, el modo orquestador cae al fallback kitty (`launch_claude_agent_kitty`) y lanza ejecutores en terminales sueltas en vez de como windows de la flota. La senal **fiable** es `$TMUX`: todo proceso dentro de tmux la tiene SIEMPRE, con el formato `/tmp/tmux-/,,`. De ahi se extrae el socket (basename del path antes de la primera coma) y, con `tmux -L display-message -p '#{session_name}'`, la sesion actual. ## Salida ```json {"in_fleet":true,"in_tmux":true,"socket":"fleet3","session":"fleet3","source":"tmux"} ``` | Campo | Significado | |---|---| | `in_fleet` | Heuristica de "estoy en una flota". `true` si en tmux Y (socket/sesion casan `fleet`, O hay window `fleetview`, O la sesion tiene >= 2 windows). | | `in_tmux` | `true` si el proceso esta dentro de tmux. Basta para lanzar una window (mejor que caer a kitty). | | `socket` | Socket tmux derivado de `$TMUX` (o de `$FLEET_SOCKET` en fallback). | | `session` | Sesion tmux actual resuelta con `display-message` (fallback a `$FLEET_SESSION` o al socket). | | `source` | `tmux` (derivado de `$TMUX`), `fleet_socket` (fallback), o `none`. | ## Ejemplo ```bash # Dentro de una window de la flota fleet3: bash bash/functions/infra/detect_fleet_context.sh # {"in_fleet":true,"in_tmux":true,"socket":"fleet3","session":"fleet3","source":"tmux"} # Fuera de tmux, sin FLEET_SOCKET: env -u TMUX -u FLEET_SOCKET bash bash/functions/infra/detect_fleet_context.sh # {"in_fleet":false,"in_tmux":false,"socket":"","session":"","source":"none"} # Parsear el socket con jq para pasarlo a spawn_fleet_agent: ctx=$(bash bash/functions/infra/detect_fleet_context.sh) sock=$(printf '%s' "$ctx" | jq -r .socket) ``` ## Cuando usarla Antes de lanzar un ejecutor de la flota: llama a esta funcion para saber si estas dentro de una flota tmux. Si `in_tmux=true`, lanza con `spawn_fleet_agent` (que ya la usa para auto-detectar el socket); NUNCA caigas a kitty. Tambien la usa el hook `hook_fleet_state_inject.sh` para recordarle al orquestador el socket de su flota cada turno. ## Gotchas - Es **impura**: consulta el servidor tmux (`display-message`, `list-windows`). No modifica estado. - `in_fleet` es **heuristico** a proposito. Para LANZAR basta `in_tmux=true` (lanzar una window en cualquier tmux supera a una kitty suelta). `in_fleet` es solo la senal semantica que consume el hook y la doctrina. - Fallback `source=fleet_socket`: si `$TMUX` no esta pero `$FLEET_SOCKET` si, devuelve `socket`/`session` de esas vars con `in_tmux=false`. Un `tmux -L new-window` puede seguir funcionando si el servidor existe, aunque el caller no este attached. - No requiere `jq` ni python: emite el JSON con `printf`, para poder ser el detector base que invocan hooks y otras funciones bash. - Si `tmux` no esta instalado y `$TMUX` esta seteada (raro), `socket` se deriva igual de `$TMUX` pero `session` cae al fallback y `in_fleet` no se puede afinar por windows.