fix(crew): don't kill pane processes when creating new session
KillPaneProcesses was being called on new sessions before respawn, which killed the fresh shell and destroyed the pane. This caused "can't find pane" errors on session creation. Now KillPaneProcesses is only called when restarting in an existing session where Claude/Node processes might be running and ignoring SIGHUP. For new sessions, we just use respawn-pane directly. Also added retry limit and error checking for the stale session recovery path. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,9 @@ import (
|
||||
"github.com/steveyegge/gastown/internal/workspace"
|
||||
)
|
||||
|
||||
// crewAtRetried tracks if we've already retried after stale session cleanup
|
||||
var crewAtRetried bool
|
||||
|
||||
func runCrewAt(cmd *cobra.Command, args []string) error {
|
||||
var name string
|
||||
|
||||
@@ -210,19 +213,11 @@ func runCrewAt(cmd *cobra.Command, args []string) error {
|
||||
if runtimeConfig.Session != nil && runtimeConfig.Session.ConfigDirEnv != "" && claudeConfigDir != "" {
|
||||
startupCmd = config.PrependEnv(startupCmd, map[string]string{runtimeConfig.Session.ConfigDirEnv: claudeConfigDir})
|
||||
}
|
||||
// Kill all processes in the pane before respawning to prevent orphan leaks
|
||||
// RespawnPane's -k flag only sends SIGHUP which Claude/Node may ignore
|
||||
if err := t.KillPaneProcesses(paneID); err != nil {
|
||||
// Non-fatal but log the warning
|
||||
style.PrintWarning("could not kill pane processes: %v", err)
|
||||
}
|
||||
// Note: Don't call KillPaneProcesses here - this is a NEW session with just
|
||||
// a fresh shell. Killing it would destroy the pane before we can respawn.
|
||||
// KillPaneProcesses is only needed when restarting in an EXISTING session
|
||||
// where Claude/Node processes might be running and ignoring SIGHUP.
|
||||
if err := t.RespawnPane(paneID, startupCmd); err != nil {
|
||||
// If pane is stale (session exists but pane doesn't), recreate the session
|
||||
if strings.Contains(err.Error(), "can't find pane") {
|
||||
fmt.Printf("Stale session detected, recreating...\n")
|
||||
_ = t.KillSession(sessionID)
|
||||
return runCrewAt(cmd, args) // Retry with fresh session
|
||||
}
|
||||
return fmt.Errorf("starting runtime: %w", err)
|
||||
}
|
||||
|
||||
@@ -274,8 +269,15 @@ func runCrewAt(cmd *cobra.Command, args []string) error {
|
||||
if err := t.RespawnPane(paneID, startupCmd); err != nil {
|
||||
// If pane is stale (session exists but pane doesn't), recreate the session
|
||||
if strings.Contains(err.Error(), "can't find pane") {
|
||||
if crewAtRetried {
|
||||
return fmt.Errorf("stale session persists after cleanup: %w", err)
|
||||
}
|
||||
fmt.Printf("Stale session detected, recreating...\n")
|
||||
_ = t.KillSession(sessionID)
|
||||
if killErr := t.KillSession(sessionID); killErr != nil {
|
||||
return fmt.Errorf("failed to kill stale session: %w", killErr)
|
||||
}
|
||||
crewAtRetried = true
|
||||
defer func() { crewAtRetried = false }()
|
||||
return runCrewAt(cmd, args) // Retry with fresh session
|
||||
}
|
||||
return fmt.Errorf("restarting runtime: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user