diff --git a/internal/cmd/crew.go b/internal/cmd/crew.go index 01bdc1e7..e28d743a 100644 --- a/internal/cmd/crew.go +++ b/internal/cmd/crew.go @@ -463,12 +463,37 @@ func runCrewAt(cmd *cobra.Command, args []string) error { fmt.Printf("%s Created session for %s/%s\n", style.Bold.Render("✓"), r.Name, name) + } else { + // Session exists - check if Claude is still running + paneCmd, err := t.GetPaneCommand(sessionID) + if err == nil && isShellCommand(paneCmd) { + // Claude has exited, restart it + fmt.Printf("Claude exited, restarting...\n") + if err := t.SendKeys(sessionID, "claude --dangerously-skip-permissions"); err != nil { + return fmt.Errorf("restarting claude: %w", err) + } + // Prime after restart + if err := t.SendKeysDelayed(sessionID, "gt prime", 2000); err != nil { + fmt.Printf("Warning: Could not send prime command: %v\n", err) + } + } } // Attach to session using exec to properly forward TTY return attachToTmuxSession(sessionID) } +// isShellCommand checks if the command is a shell (meaning Claude has exited). +func isShellCommand(cmd string) bool { + shells := []string{"bash", "zsh", "sh", "fish", "tcsh", "ksh"} + for _, shell := range shells { + if cmd == shell { + return true + } + } + return false +} + // attachToTmuxSession attaches to a tmux session with proper TTY forwarding. func attachToTmuxSession(sessionID string) error { tmuxPath, err := exec.LookPath("tmux") diff --git a/internal/tmux/tmux.go b/internal/tmux/tmux.go index 8db4a620..4070a69a 100644 --- a/internal/tmux/tmux.go +++ b/internal/tmux/tmux.go @@ -133,6 +133,16 @@ func (t *Tmux) SendKeysDelayed(session, keys string, delayMs int) error { return t.SendKeys(session, keys) } +// GetPaneCommand returns the current command running in a pane. +// Returns "bash", "zsh", "claude", "node", etc. +func (t *Tmux) GetPaneCommand(session string) (string, error) { + out, err := t.run("list-panes", "-t", session, "-F", "#{pane_current_command}") + if err != nil { + return "", err + } + return strings.TrimSpace(out), nil +} + // CapturePane captures the visible content of a pane. func (t *Tmux) CapturePane(session string, lines int) (string, error) { return t.run("capture-pane", "-p", "-t", session, "-S", fmt.Sprintf("-%d", lines))