feat(spawn): migrate to NewSessionWithCommand pattern
Migrate witness, boot, and deacon spawns to use NewSessionWithCommand instead of NewSession+SendKeys to ensure BD_ACTOR is visible in the process tree for orphan detection via ps. Refs: gt-emi5b Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
beads/crew/emma
parent
e7b0af0295
commit
38bedc03e8
+19
-30
@@ -153,23 +153,28 @@ func (m *Manager) Start(foreground bool, agentOverride string, envOverrides []st
|
||||
return fmt.Errorf("ensuring Claude settings: %w", err)
|
||||
}
|
||||
|
||||
// Create new tmux session
|
||||
if err := t.NewSession(sessionID, witnessDir); err != nil {
|
||||
return fmt.Errorf("creating tmux session: %w", err)
|
||||
}
|
||||
|
||||
// Apply Gas Town theming (non-fatal: theming failure doesn't affect operation)
|
||||
theme := tmux.AssignTheme(m.rig.Name)
|
||||
_ = t.ConfigureGasTownSession(sessionID, theme, m.rig.Name, "witness", "witness")
|
||||
|
||||
roleConfig, err := m.roleConfig()
|
||||
if err != nil {
|
||||
_ = t.KillSession(sessionID)
|
||||
return err
|
||||
}
|
||||
|
||||
townRoot := m.townRoot()
|
||||
|
||||
// Build startup command first
|
||||
// NOTE: No gt prime injection needed - SessionStart hook handles it automatically
|
||||
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
||||
// Pass m.rig.Path so rig agent settings are honored (not town-level defaults)
|
||||
command, err := buildWitnessStartCommand(m.rig.Path, m.rig.Name, townRoot, agentOverride, roleConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create session with command directly to avoid send-keys race condition.
|
||||
// See: https://github.com/anthropics/gastown/issues/280
|
||||
if err := t.NewSessionWithCommand(sessionID, witnessDir, command); err != nil {
|
||||
return fmt.Errorf("creating tmux session: %w", err)
|
||||
}
|
||||
|
||||
// Set environment variables (non-fatal: session works without these)
|
||||
// Use centralized AgentEnv for consistency across all role startup paths
|
||||
envVars := config.AgentEnv(config.AgentEnvConfig{
|
||||
@@ -192,6 +197,10 @@ func (m *Manager) Start(foreground bool, agentOverride string, envOverrides []st
|
||||
}
|
||||
}
|
||||
|
||||
// Apply Gas Town theming (non-fatal: theming failure doesn't affect operation)
|
||||
theme := tmux.AssignTheme(m.rig.Name)
|
||||
_ = t.ConfigureGasTownSession(sessionID, theme, m.rig.Name, "witness", "witness")
|
||||
|
||||
// Update state to running
|
||||
now := time.Now()
|
||||
w.State = StateRunning
|
||||
@@ -203,26 +212,6 @@ func (m *Manager) Start(foreground bool, agentOverride string, envOverrides []st
|
||||
return fmt.Errorf("saving state: %w", err)
|
||||
}
|
||||
|
||||
// Launch Claude directly (no shell respawn loop)
|
||||
// Restarts are handled by daemon via LIFECYCLE mail or deacon health-scan
|
||||
// NOTE: No gt prime injection needed - SessionStart hook handles it automatically
|
||||
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
||||
// Pass m.rig.Path so rig agent settings are honored (not town-level defaults)
|
||||
command, err := buildWitnessStartCommand(m.rig.Path, m.rig.Name, townRoot, agentOverride, roleConfig)
|
||||
if err != nil {
|
||||
_ = t.KillSession(sessionID)
|
||||
return err
|
||||
}
|
||||
// Wait for shell to be ready before sending keys (prevents "can't find pane" under load)
|
||||
if err := t.WaitForShellReady(sessionID, 5*time.Second); err != nil {
|
||||
_ = t.KillSession(sessionID)
|
||||
return fmt.Errorf("waiting for shell: %w", err)
|
||||
}
|
||||
if err := t.SendKeys(sessionID, command); err != nil {
|
||||
_ = t.KillSession(sessionID) // best-effort cleanup
|
||||
return fmt.Errorf("starting Claude agent: %w", err)
|
||||
}
|
||||
|
||||
// Wait for Claude to start (non-fatal).
|
||||
if err := t.WaitForCommand(sessionID, constants.SupportedShells, constants.ClaudeStartTimeout); err != nil {
|
||||
// Non-fatal - try to continue anyway
|
||||
|
||||
Reference in New Issue
Block a user