feat: allow witness restart agent override

This commit is contained in:
joshuavial
2026-01-09 22:24:09 +13:00
committed by Steve Yegge
parent 24136ebaa1
commit 0d3f6c9654
8 changed files with 2880 additions and 2604 deletions

View File

@@ -99,7 +99,8 @@ func (m *Manager) witnessDir() string {
// Start starts the witness.
// If foreground is true, only updates state (no tmux session - deprecated).
// Otherwise, spawns a Claude agent in a tmux session.
func (m *Manager) Start(foreground bool) error {
// agentOverride optionally specifies a different agent alias to use.
func (m *Manager) Start(foreground bool, agentOverride string) error {
w, err := m.loadState()
if err != nil {
return err
@@ -152,15 +153,8 @@ func (m *Manager) Start(foreground bool) error {
return fmt.Errorf("ensuring Claude settings: %w", err)
}
// Build startup command first
// Pass m.rig.Path so rig agent settings are honored (not town-level defaults)
bdActor := fmt.Sprintf("%s/witness", m.rig.Name)
command := config.BuildAgentStartupCommand("witness", bdActor, m.rig.Path, "")
runtimeConfig := config.LoadRuntimeConfig(m.rig.Path)
// 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 {
// Create new tmux session
if err := t.NewSession(sessionID, witnessDir); err != nil {
return fmt.Errorf("creating tmux session: %w", err)
}
@@ -192,8 +186,28 @@ func (m *Manager) Start(foreground bool) error {
return fmt.Errorf("saving state: %w", err)
}
// Wait for runtime to start and show its prompt (non-fatal)
if err := t.WaitForRuntimeReady(sessionID, runtimeConfig, constants.ClaudeStartTimeout); err != nil {
// 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 := config.BuildAgentStartupCommandWithAgentOverride("witness", bdActor, m.rig.Path, "", agentOverride)
if err != nil {
_ = t.KillSession(sessionID)
return fmt.Errorf("building startup command: %w", 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
}