--- name: tmux_swap_window_into_console kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "func TmuxSwapWindowIntoConsole(socket, session, windowID string) error" description: "Conmuta que Claude esta a la derecha de la TUI fleetview en una sesion tmux de un socket aislado (tmux -L ). Trae el primer pane de al pane derecho de la window 'console' (al lado del pane 0 = la TUI), parkea en su propia window el Claude que estuviera a la derecha (detached, sin robar foco) y re-fija el ancho del pane 0 a 40 columnas. Idempotente: si el objetivo ya es la window console no hace nada. Capa de control tmux de la app TUI fleetview." tags: [claude-fleet, infra, tmux, claude, fleet, tui] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] params: - name: "socket" desc: "Nombre del socket tmux aislado (tmux -L ). En fleetview es 'fleet'. Nunca opera sobre el servidor tmux por defecto." - name: "session" desc: "Sesion tmux que contiene la window 'console' (ej 'fleet'). El pane 0 de console es la TUI; el resto, el Claude activo." - name: "windowID" desc: "window_id (@N) de la window cuyo primer pane se quiere traer a la derecha de la TUI. Tipicamente el devuelto por tmux_new_claude_window o por tmux_map_claude_panes." output: "nil en exito. Error si socket/session/windowID vienen vacios, si la window 'console' no existe en la sesion, o si alguno de los comandos tmux (list-panes, break-pane, join-pane, resize-pane) falla. El estado final de console: pane 0 = TUI (40 col) + pane derecho = el Claude de windowID." tested: true tests: ["TestTmuxSwapWindowIntoConsole", "TestTmuxSwapWindowIntoConsoleParksPrevious", "TestTmuxSwapWindowIntoConsoleEmptyArgs"] test_file_path: "functions/infra/tmux_swap_window_into_console_test.go" file_path: "functions/infra/tmux_swap_window_into_console.go" notes: "Build tag //go:build !windows. Comparte runTmux con tmux_new_claude_window y tmux_map_claude_panes (mismo paquete infra). Secuencia interna: (1) list-panes de console y localiza el pane no-0 actual; (2) break-pane -d de ese pane si existe (parking); (3) join-pane -h del primer pane de windowID a console.0 (lado a lado); (4) resize-pane -x 40 del pane 0. Caso borde: si windowID ya ES la window console, solo re-aplica el resize. break-pane requiere que la window destino sea distinta del origen, garantizado por la comprobacion consoleID != windowID." --- ## Ejemplo ```go package main import "fn-registry/functions/infra" func main() { // El usuario selecciona en fleetview el Claude que vive en la window @7. // Lo trae a la derecha de la TUI (pane 1 de console), parkeando el que // estuviera ahi. La TUI (pane 0) queda re-fijada a 40 columnas. if err := infra.TmuxSwapWindowIntoConsole("fleet", "fleet", "@7"); err != nil { panic(err) } } ``` ## Cuando usarla Cada vez que el usuario conmuta en fleetview que Claude quiere ver a la derecha. Llamala con el `window_id` del Claude destino (de `tmux_map_claude_panes` para los ya vivos en la sesion, o de `tmux_new_claude_window` para uno recien arrancado). Encadena de forma natural tras `tmux_new_claude_window` para mostrar inmediatamente el Claude nuevo. ## Gotchas - Idempotente: si el Claude objetivo ya es la window console, solo re-aplica el ancho de 40 col; no rompe nada. - El pane indice 0 de console es SIEMPRE la TUI y nunca se mueve ni se parkea: la funcion solo toca el pane derecho (indice != 0). - `join-pane` exige que la window origen sea distinta de console; la funcion lo comprueba (consoleID != windowID) y si coinciden no hace el join. - `break-pane -d` saca el Claude anterior a su propia window detached: sigue vivo y parkeado, no se mata. - El ancho de 40 col se re-fija SIEMPRE al final (incluso en el caso borde) para que la TUI no se reduzca tras el reflow del split. - Opera SIEMPRE sobre el socket aislado (`tmux -L `). Build tag `//go:build !windows`.