//go:build !windows package infra import ( "fmt" "os/exec" "strings" ) // TmuxNewClaudeWindow crea una window nueva en del socket // que corre `claude --dangerously-skip-permissions` en . Acepta argumentos // extra opcionales que se anaden al comando (ej. "--resume", "" para // reabrir una conversacion). Devuelve el window_id (ej "@7"). No cambia el foco // (-d). Opera SIEMPRE sobre el socket aislado pasado como parametro // (tmux -L ), nunca sobre el servidor tmux por defecto del usuario. func TmuxNewClaudeWindow(socket, session, cwd string, extraArgs ...string) (string, error) { if socket == "" { return "", fmt.Errorf("tmux_new_claude_window: socket vacio") } if session == "" { return "", fmt.Errorf("tmux_new_claude_window: session vacia") } if cwd == "" { return "", fmt.Errorf("tmux_new_claude_window: cwd vacio") } // El comando del pane: claude reemplaza al shell, asi que #{pane_pid} sera el // PID de claude. Se anaden los argumentos extra (ej. --resume ). command := "claude --dangerously-skip-permissions" if len(extraArgs) > 0 { command += " " + strings.Join(extraArgs, " ") } // -d: no cambia el foco. -P -F '#{window_id}': imprime el id de la window // creada. -t : la crea en esa sesion. -c : working dir del pane. out, stderr, err := runTmux(socket, "new-window", "-d", "-P", "-F", "#{window_id}", "-t", session, "-c", cwd, command, ) if err != nil { return "", fmt.Errorf("tmux_new_claude_window: new-window en %q: %w (%s)", session, err, stderr) } windowID := strings.TrimSpace(out) if windowID == "" { return "", fmt.Errorf("tmux_new_claude_window: new-window no devolvio window_id (stderr=%q)", stderr) } return windowID, nil } // runTmux ejecuta `tmux -L ` y devuelve stdout, stderr y el // error de ejecucion. Helper comun a la capa de control tmux de fleetview. func runTmux(socket string, args ...string) (stdout, stderr string, err error) { full := append([]string{"-L", socket}, args...) cmd := exec.Command("tmux", full...) var outBuf, errBuf strings.Builder cmd.Stdout = &outBuf cmd.Stderr = &errBuf err = cmd.Run() return outBuf.String(), errBuf.String(), err }