Refactor startup paths to use RuntimeConfig (gt-j0546)
Replaced all hardcoded 'claude --dangerously-skip-permissions' invocations with configurable helpers from internal/config: - GetRuntimeCommand(rigPath) - simple command string - GetRuntimeCommandWithPrompt(rigPath, prompt) - with initial prompt - BuildAgentStartupCommand(role, bdActor, rigPath, prompt) - generic agent - BuildPolecatStartupCommand(rigName, polecatName, rigPath, prompt) - polecat - BuildCrewStartupCommand(rigName, crewName, rigPath, prompt) - crew - BuildStartupCommand(envVars, rigPath, prompt) - custom env vars Files updated: - internal/cmd/start.go (4 locations) - internal/cmd/crew_lifecycle.go (2 locations) - internal/cmd/crew_at.go (2 locations) - internal/cmd/deacon.go - internal/cmd/witness.go - internal/cmd/up.go (2 locations) - internal/cmd/handoff.go (2 locations) - internal/daemon/daemon.go (3 locations) - internal/daemon/lifecycle.go - internal/session/manager.go - internal/refinery/manager.go - internal/boot/boot.go This enables future support for alternative LLM runtimes (aider, etc.) via rig/town settings configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
0c75088727
commit
626a24e013
@@ -11,6 +11,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/steveyegge/gastown/internal/config"
|
||||||
"github.com/steveyegge/gastown/internal/tmux"
|
"github.com/steveyegge/gastown/internal/tmux"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -191,7 +192,7 @@ func (b *Boot) spawnTmux() error {
|
|||||||
|
|
||||||
// Launch Claude with environment exported inline and initial triage prompt
|
// Launch Claude with environment exported inline and initial triage prompt
|
||||||
// The "gt boot triage" prompt tells Boot to immediately start triage (GUPP principle)
|
// The "gt boot triage" prompt tells Boot to immediately start triage (GUPP principle)
|
||||||
startCmd := `export GT_ROLE=boot BD_ACTOR=deacon-boot && claude --dangerously-skip-permissions "gt boot triage"`
|
startCmd := config.BuildAgentStartupCommand("boot", "deacon-boot", "", "gt boot triage")
|
||||||
if err := b.tmux.SendKeys(SessionName, startCmd); err != nil {
|
if err := b.tmux.SendKeys(SessionName, startCmd); err != nil {
|
||||||
return fmt.Errorf("sending startup command: %w", err)
|
return fmt.Errorf("sending startup command: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,8 +150,7 @@ func runCrewAt(cmd *cobra.Command, args []string) error {
|
|||||||
// This gives cleaner lifecycle: Claude exits → session ends (no intermediate shell)
|
// This gives cleaner lifecycle: Claude exits → session ends (no intermediate shell)
|
||||||
// Pass "gt prime" as initial prompt so Claude loads context immediately
|
// Pass "gt prime" as initial prompt so Claude loads context immediately
|
||||||
// Export GT_ROLE and BD_ACTOR since tmux SetEnvironment only affects new panes
|
// Export GT_ROLE and BD_ACTOR since tmux SetEnvironment only affects new panes
|
||||||
bdActor := fmt.Sprintf("%s/crew/%s", r.Name, name)
|
claudeCmd := config.BuildCrewStartupCommand(r.Name, name, r.Path, "gt prime")
|
||||||
claudeCmd := fmt.Sprintf(`export GT_ROLE=crew GT_RIG=%s GT_CREW=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions "gt prime"`, r.Name, name, bdActor, bdActor)
|
|
||||||
if err := t.RespawnPane(paneID, claudeCmd); err != nil {
|
if err := t.RespawnPane(paneID, claudeCmd); err != nil {
|
||||||
return fmt.Errorf("starting claude: %w", err)
|
return fmt.Errorf("starting claude: %w", err)
|
||||||
}
|
}
|
||||||
@@ -175,8 +174,7 @@ func runCrewAt(cmd *cobra.Command, args []string) error {
|
|||||||
// Use respawn-pane to replace shell with Claude directly
|
// Use respawn-pane to replace shell with Claude directly
|
||||||
// Pass "gt prime" as initial prompt so Claude loads context immediately
|
// Pass "gt prime" as initial prompt so Claude loads context immediately
|
||||||
// Export GT_ROLE and BD_ACTOR since tmux SetEnvironment only affects new panes
|
// Export GT_ROLE and BD_ACTOR since tmux SetEnvironment only affects new panes
|
||||||
bdActor := fmt.Sprintf("%s/crew/%s", r.Name, name)
|
claudeCmd := config.BuildCrewStartupCommand(r.Name, name, r.Path, "gt prime")
|
||||||
claudeCmd := fmt.Sprintf(`export GT_ROLE=crew GT_RIG=%s GT_CREW=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions "gt prime"`, r.Name, name, bdActor, bdActor)
|
|
||||||
if err := t.RespawnPane(paneID, claudeCmd); err != nil {
|
if err := t.RespawnPane(paneID, claudeCmd); err != nil {
|
||||||
return fmt.Errorf("restarting claude: %w", err)
|
return fmt.Errorf("restarting claude: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/steveyegge/gastown/internal/beads"
|
"github.com/steveyegge/gastown/internal/beads"
|
||||||
|
"github.com/steveyegge/gastown/internal/config"
|
||||||
"github.com/steveyegge/gastown/internal/constants"
|
"github.com/steveyegge/gastown/internal/constants"
|
||||||
"github.com/steveyegge/gastown/internal/crew"
|
"github.com/steveyegge/gastown/internal/crew"
|
||||||
"github.com/steveyegge/gastown/internal/mail"
|
"github.com/steveyegge/gastown/internal/mail"
|
||||||
@@ -335,8 +336,7 @@ func runCrewRestart(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
// Start claude with skip permissions (crew workers are trusted)
|
// Start claude with skip permissions (crew workers are trusted)
|
||||||
// Export GT_ROLE and BD_ACTOR since tmux SetEnvironment only affects new panes
|
// Export GT_ROLE and BD_ACTOR since tmux SetEnvironment only affects new panes
|
||||||
bdActor := fmt.Sprintf("%s/crew/%s", r.Name, name)
|
claudeCmd := config.BuildCrewStartupCommand(r.Name, name, r.Path, "")
|
||||||
claudeCmd := fmt.Sprintf("export GT_ROLE=crew GT_RIG=%s GT_CREW=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions", r.Name, name, bdActor, bdActor)
|
|
||||||
if err := t.SendKeys(sessionID, claudeCmd); err != nil {
|
if err := t.SendKeys(sessionID, claudeCmd); err != nil {
|
||||||
fmt.Printf("Error starting claude for %s: %v\n", arg, err)
|
fmt.Printf("Error starting claude for %s: %v\n", arg, err)
|
||||||
lastErr = err
|
lastErr = err
|
||||||
@@ -511,8 +511,7 @@ func restartCrewSession(rigName, crewName, clonePath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start claude with skip permissions
|
// Start claude with skip permissions
|
||||||
bdActor := fmt.Sprintf("%s/crew/%s", rigName, crewName)
|
claudeCmd := config.BuildCrewStartupCommand(rigName, crewName, "", "")
|
||||||
claudeCmd := fmt.Sprintf("export GT_ROLE=crew GT_RIG=%s GT_CREW=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions", rigName, crewName, bdActor, bdActor)
|
|
||||||
if err := t.SendKeys(sessionID, claudeCmd); err != nil {
|
if err := t.SendKeys(sessionID, claudeCmd); err != nil {
|
||||||
return fmt.Errorf("starting claude: %w", err)
|
return fmt.Errorf("starting claude: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/steveyegge/gastown/internal/config"
|
||||||
"github.com/steveyegge/gastown/internal/constants"
|
"github.com/steveyegge/gastown/internal/constants"
|
||||||
"github.com/steveyegge/gastown/internal/deacon"
|
"github.com/steveyegge/gastown/internal/deacon"
|
||||||
"github.com/steveyegge/gastown/internal/polecat"
|
"github.com/steveyegge/gastown/internal/polecat"
|
||||||
@@ -291,7 +292,7 @@ func startDeaconSession(t *tmux.Tmux) error {
|
|||||||
// Restarts are handled by daemon via ensureDeaconRunning on each heartbeat
|
// Restarts are handled by daemon via ensureDeaconRunning on each heartbeat
|
||||||
// The startup hook handles context loading automatically
|
// The startup hook handles context loading automatically
|
||||||
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
||||||
if err := t.SendKeys(DeaconSessionName, "export GT_ROLE=deacon BD_ACTOR=deacon GIT_AUTHOR_NAME=deacon && claude --dangerously-skip-permissions"); err != nil {
|
if err := t.SendKeys(DeaconSessionName, config.BuildAgentStartupCommand("deacon", "deacon", "", "")); err != nil {
|
||||||
return fmt.Errorf("sending command: %w", err)
|
return fmt.Errorf("sending command: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/steveyegge/gastown/internal/config"
|
||||||
"github.com/steveyegge/gastown/internal/events"
|
"github.com/steveyegge/gastown/internal/events"
|
||||||
"github.com/steveyegge/gastown/internal/session"
|
"github.com/steveyegge/gastown/internal/session"
|
||||||
"github.com/steveyegge/gastown/internal/style"
|
"github.com/steveyegge/gastown/internal/style"
|
||||||
@@ -327,10 +328,11 @@ func buildRestartCommand(sessionName string) (string, error) {
|
|||||||
// IMPORTANT: Passing "gt prime" as argument injects it as the first prompt,
|
// IMPORTANT: Passing "gt prime" as argument injects it as the first prompt,
|
||||||
// which triggers the agent to execute immediately. Without this, agents
|
// which triggers the agent to execute immediately. Without this, agents
|
||||||
// wait for user input despite all GUPP prompting in hooks.
|
// wait for user input despite all GUPP prompting in hooks.
|
||||||
|
runtimeCmd := config.GetRuntimeCommandWithPrompt("", "gt prime")
|
||||||
if gtRole != "" {
|
if gtRole != "" {
|
||||||
return fmt.Sprintf("cd %s && export GT_ROLE=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && exec claude --dangerously-skip-permissions \"gt prime\"", workDir, gtRole, gtRole, gtRole), nil
|
return fmt.Sprintf("cd %s && export GT_ROLE=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && exec %s", workDir, gtRole, gtRole, gtRole, runtimeCmd), nil
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("cd %s && exec claude --dangerously-skip-permissions \"gt prime\"", workDir), nil
|
return fmt.Sprintf("cd %s && exec %s", workDir, runtimeCmd), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// sessionWorkDir returns the correct working directory for a session.
|
// sessionWorkDir returns the correct working directory for a session.
|
||||||
|
|||||||
@@ -341,7 +341,8 @@ func ensureRefinerySession(rigName string, r *rig.Rig) (bool, error) {
|
|||||||
|
|
||||||
// Launch Claude in a respawn loop
|
// Launch Claude in a respawn loop
|
||||||
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
||||||
loopCmd := `export GT_ROLE=refinery BD_ACTOR=` + bdActor + ` GIT_AUTHOR_NAME=` + bdActor + ` && while true; do echo "🛢️ Starting Refinery for ` + rigName + `..."; claude --dangerously-skip-permissions; echo ""; echo "Refinery exited. Restarting in 2s... (Ctrl-C to stop)"; sleep 2; done`
|
runtimeCmd := config.GetRuntimeCommand(r.Path)
|
||||||
|
loopCmd := `export GT_ROLE=refinery BD_ACTOR=` + bdActor + ` GIT_AUTHOR_NAME=` + bdActor + ` && while true; do echo "🛢️ Starting Refinery for ` + rigName + `..."; ` + runtimeCmd + `; echo ""; echo "Refinery exited. Restarting in 2s... (Ctrl-C to stop)"; sleep 2; done`
|
||||||
if err := t.SendKeysDelayed(sessionName, loopCmd, 200); err != nil {
|
if err := t.SendKeysDelayed(sessionName, loopCmd, 200); err != nil {
|
||||||
return false, fmt.Errorf("sending command: %w", err)
|
return false, fmt.Errorf("sending command: %w", err)
|
||||||
}
|
}
|
||||||
@@ -744,7 +745,7 @@ func runStartCrew(cmd *cobra.Command, args []string) error {
|
|||||||
if !t.IsClaudeRunning(sessionID) {
|
if !t.IsClaudeRunning(sessionID) {
|
||||||
// Claude has exited, restart it
|
// Claude has exited, restart it
|
||||||
fmt.Printf("Session exists, restarting Claude...\n")
|
fmt.Printf("Session exists, restarting Claude...\n")
|
||||||
if err := t.SendKeys(sessionID, "claude --dangerously-skip-permissions"); err != nil {
|
if err := t.SendKeys(sessionID, config.GetRuntimeCommand(r.Path)); err != nil {
|
||||||
return fmt.Errorf("restarting claude: %w", err)
|
return fmt.Errorf("restarting claude: %w", err)
|
||||||
}
|
}
|
||||||
// Wait for Claude to start, then prime
|
// Wait for Claude to start, then prime
|
||||||
@@ -785,7 +786,7 @@ func runStartCrew(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start claude with skip permissions
|
// Start claude with skip permissions
|
||||||
if err := t.SendKeys(sessionID, "claude --dangerously-skip-permissions"); err != nil {
|
if err := t.SendKeys(sessionID, config.GetRuntimeCommand(r.Path)); err != nil {
|
||||||
return fmt.Errorf("starting claude: %w", err)
|
return fmt.Errorf("starting claude: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -926,7 +927,7 @@ func startCrewMember(rigName, crewName, townRoot string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start claude
|
// Start claude
|
||||||
if err := t.SendKeys(sessionID, "claude --dangerously-skip-permissions"); err != nil {
|
if err := t.SendKeys(sessionID, config.GetRuntimeCommand(r.Path)); err != nil {
|
||||||
return fmt.Errorf("starting claude: %w", err)
|
return fmt.Errorf("starting claude: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -262,11 +262,12 @@ func ensureSession(t *tmux.Tmux, sessionName, workDir, role string) error {
|
|||||||
// Launch Claude
|
// Launch Claude
|
||||||
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
||||||
var claudeCmd string
|
var claudeCmd string
|
||||||
|
runtimeCmd := config.GetRuntimeCommand("")
|
||||||
if role == "deacon" {
|
if role == "deacon" {
|
||||||
// Deacon uses respawn loop
|
// Deacon uses respawn loop
|
||||||
claudeCmd = `export GT_ROLE=deacon BD_ACTOR=deacon GIT_AUTHOR_NAME=deacon && while true; do echo "⛪ Starting Deacon session..."; claude --dangerously-skip-permissions; echo ""; echo "Deacon exited. Restarting in 2s... (Ctrl-C to stop)"; sleep 2; done`
|
claudeCmd = `export GT_ROLE=deacon BD_ACTOR=deacon GIT_AUTHOR_NAME=deacon && while true; do echo "⛪ Starting Deacon session..."; ` + runtimeCmd + `; echo ""; echo "Deacon exited. Restarting in 2s... (Ctrl-C to stop)"; sleep 2; done`
|
||||||
} else {
|
} else {
|
||||||
claudeCmd = fmt.Sprintf(`export GT_ROLE=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions`, role, role, role)
|
claudeCmd = config.BuildAgentStartupCommand(role, role, "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.SendKeysDelayed(sessionName, claudeCmd, 200); err != nil {
|
if err := t.SendKeysDelayed(sessionName, claudeCmd, 200); err != nil {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/steveyegge/gastown/internal/claude"
|
"github.com/steveyegge/gastown/internal/claude"
|
||||||
|
"github.com/steveyegge/gastown/internal/config"
|
||||||
"github.com/steveyegge/gastown/internal/constants"
|
"github.com/steveyegge/gastown/internal/constants"
|
||||||
"github.com/steveyegge/gastown/internal/rig"
|
"github.com/steveyegge/gastown/internal/rig"
|
||||||
"github.com/steveyegge/gastown/internal/session"
|
"github.com/steveyegge/gastown/internal/session"
|
||||||
@@ -333,7 +334,7 @@ func ensureWitnessSession(rigName string, r *rig.Rig) (bool, error) {
|
|||||||
// Restarts are handled by daemon via LIFECYCLE mail or deacon health-scan
|
// Restarts are handled by daemon via LIFECYCLE mail or deacon health-scan
|
||||||
// NOTE: No gt prime injection needed - SessionStart hook handles it automatically
|
// 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
|
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
|
||||||
if err := t.SendKeys(sessionName, fmt.Sprintf("export GT_ROLE=witness BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions", bdActor, bdActor)); err != nil {
|
if err := t.SendKeys(sessionName, config.BuildAgentStartupCommand("witness", bdActor, "", "")); err != nil {
|
||||||
return false, fmt.Errorf("sending command: %w", err)
|
return false, fmt.Errorf("sending command: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/steveyegge/gastown/internal/beads"
|
"github.com/steveyegge/gastown/internal/beads"
|
||||||
"github.com/steveyegge/gastown/internal/boot"
|
"github.com/steveyegge/gastown/internal/boot"
|
||||||
|
"github.com/steveyegge/gastown/internal/config"
|
||||||
"github.com/steveyegge/gastown/internal/constants"
|
"github.com/steveyegge/gastown/internal/constants"
|
||||||
"github.com/steveyegge/gastown/internal/feed"
|
"github.com/steveyegge/gastown/internal/feed"
|
||||||
"github.com/steveyegge/gastown/internal/polecat"
|
"github.com/steveyegge/gastown/internal/polecat"
|
||||||
@@ -284,7 +285,7 @@ func (d *Daemon) ensureDeaconRunning() {
|
|||||||
// Launch Claude directly (no shell respawn loop)
|
// Launch Claude directly (no shell respawn loop)
|
||||||
// The daemon will detect if Claude exits and restart it on next heartbeat
|
// The daemon will detect if Claude exits and restart it on next heartbeat
|
||||||
// Export GT_ROLE and BD_ACTOR so Claude inherits them (tmux SetEnvironment doesn't export to processes)
|
// Export GT_ROLE and BD_ACTOR so Claude inherits them (tmux SetEnvironment doesn't export to processes)
|
||||||
if err := d.tmux.SendKeys(DeaconSessionName, "export GT_ROLE=deacon BD_ACTOR=deacon GIT_AUTHOR_NAME=deacon && claude --dangerously-skip-permissions"); err != nil {
|
if err := d.tmux.SendKeys(DeaconSessionName, config.BuildAgentStartupCommand("deacon", "deacon", "", "")); err != nil {
|
||||||
d.logger.Printf("Error launching Claude in Deacon session: %v", err)
|
d.logger.Printf("Error launching Claude in Deacon session: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -333,8 +334,13 @@ func (d *Daemon) ensureWitnessRunning(rigName string) {
|
|||||||
|
|
||||||
// Launch Claude
|
// Launch Claude
|
||||||
bdActor := fmt.Sprintf("%s/witness", rigName)
|
bdActor := fmt.Sprintf("%s/witness", rigName)
|
||||||
envExport := fmt.Sprintf("export GT_ROLE=witness GT_RIG=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions", rigName, bdActor, bdActor)
|
envVars := map[string]string{
|
||||||
if err := d.tmux.SendKeys(sessionName, envExport); err != nil {
|
"GT_ROLE": "witness",
|
||||||
|
"GT_RIG": rigName,
|
||||||
|
"BD_ACTOR": bdActor,
|
||||||
|
"GIT_AUTHOR_NAME": bdActor,
|
||||||
|
}
|
||||||
|
if err := d.tmux.SendKeys(sessionName, config.BuildStartupCommand(envVars, "", "")); err != nil {
|
||||||
d.logger.Printf("Error launching Claude in witness session for %s: %v", rigName, err)
|
d.logger.Printf("Error launching Claude in witness session for %s: %v", rigName, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -631,8 +637,7 @@ func (d *Daemon) restartPolecatSession(rigName, polecatName, sessionName string)
|
|||||||
_ = d.tmux.SetPaneDiedHook(sessionName, agentID)
|
_ = d.tmux.SetPaneDiedHook(sessionName, agentID)
|
||||||
|
|
||||||
// Launch Claude with environment exported inline
|
// Launch Claude with environment exported inline
|
||||||
startCmd := fmt.Sprintf("export GT_ROLE=polecat GT_RIG=%s GT_POLECAT=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions",
|
startCmd := config.BuildPolecatStartupCommand(rigName, polecatName, "", "")
|
||||||
rigName, polecatName, bdActor, bdActor)
|
|
||||||
if err := d.tmux.SendKeys(sessionName, startCmd); err != nil {
|
if err := d.tmux.SendKeys(sessionName, startCmd); err != nil {
|
||||||
return fmt.Errorf("sending startup command: %w", err)
|
return fmt.Errorf("sending startup command: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -416,21 +416,19 @@ func (d *Daemon) getNeedsPreSync(config *beads.RoleConfig, parsed *ParsedIdentit
|
|||||||
|
|
||||||
// getStartCommand determines the startup command for an agent.
|
// getStartCommand determines the startup command for an agent.
|
||||||
// Uses role bead config if available, falls back to hardcoded defaults.
|
// Uses role bead config if available, falls back to hardcoded defaults.
|
||||||
func (d *Daemon) getStartCommand(config *beads.RoleConfig, parsed *ParsedIdentity) string {
|
func (d *Daemon) getStartCommand(roleConfig *beads.RoleConfig, parsed *ParsedIdentity) string {
|
||||||
// If role bead has explicit config, use it
|
// If role bead has explicit config, use it
|
||||||
if config != nil && config.StartCommand != "" {
|
if roleConfig != nil && roleConfig.StartCommand != "" {
|
||||||
// Expand any patterns in the command
|
// Expand any patterns in the command
|
||||||
return beads.ExpandRolePattern(config.StartCommand, d.config.TownRoot, parsed.RigName, parsed.AgentName, parsed.RoleType)
|
return beads.ExpandRolePattern(roleConfig.StartCommand, d.config.TownRoot, parsed.RigName, parsed.AgentName, parsed.RoleType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default command for all agents
|
// Default command for all agents - use runtime config
|
||||||
defaultCmd := "exec claude --dangerously-skip-permissions"
|
defaultCmd := "exec " + config.GetRuntimeCommand("")
|
||||||
|
|
||||||
// Polecats need environment variables set in the command
|
// Polecats need environment variables set in the command
|
||||||
if parsed.RoleType == "polecat" {
|
if parsed.RoleType == "polecat" {
|
||||||
bdActor := fmt.Sprintf("%s/polecats/%s", parsed.RigName, parsed.AgentName)
|
return config.BuildPolecatStartupCommand(parsed.RigName, parsed.AgentName, "", "")
|
||||||
return fmt.Sprintf("export GT_ROLE=polecat GT_RIG=%s GT_POLECAT=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && %s",
|
|
||||||
parsed.RigName, parsed.AgentName, bdActor, bdActor, defaultCmd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultCmd
|
return defaultCmd
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ func (m *Manager) Start(foreground bool) error {
|
|||||||
// Start Claude agent with full permissions (like polecats)
|
// Start Claude agent with full permissions (like polecats)
|
||||||
// NOTE: No gt prime injection needed - SessionStart hook handles it automatically
|
// NOTE: No gt prime injection needed - SessionStart hook handles it automatically
|
||||||
// Restarts are handled by daemon via LIFECYCLE mail, not shell loops
|
// Restarts are handled by daemon via LIFECYCLE mail, not shell loops
|
||||||
command := "claude --dangerously-skip-permissions"
|
command := config.GetRuntimeCommand("")
|
||||||
if err := t.SendKeys(sessionID, command); err != nil {
|
if err := t.SendKeys(sessionID, command); err != nil {
|
||||||
// Clean up the session on failure (best-effort cleanup)
|
// Clean up the session on failure (best-effort cleanup)
|
||||||
_ = t.KillSession(sessionID)
|
_ = t.KillSession(sessionID)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/steveyegge/gastown/internal/claude"
|
"github.com/steveyegge/gastown/internal/claude"
|
||||||
|
"github.com/steveyegge/gastown/internal/config"
|
||||||
"github.com/steveyegge/gastown/internal/constants"
|
"github.com/steveyegge/gastown/internal/constants"
|
||||||
"github.com/steveyegge/gastown/internal/rig"
|
"github.com/steveyegge/gastown/internal/rig"
|
||||||
"github.com/steveyegge/gastown/internal/tmux"
|
"github.com/steveyegge/gastown/internal/tmux"
|
||||||
@@ -178,9 +179,7 @@ func (m *Manager) Start(polecat string, opts StartOptions) error {
|
|||||||
if command == "" {
|
if command == "" {
|
||||||
// Polecats run with full permissions - Gas Town is for grownups
|
// Polecats run with full permissions - Gas Town is for grownups
|
||||||
// Export env vars inline so Claude's role detection works
|
// Export env vars inline so Claude's role detection works
|
||||||
bdActor := fmt.Sprintf("%s/polecats/%s", m.rig.Name, polecat)
|
command = config.BuildPolecatStartupCommand(m.rig.Name, polecat, m.rig.Path, "")
|
||||||
command = fmt.Sprintf("export GT_ROLE=polecat GT_RIG=%s GT_POLECAT=%s BD_ACTOR=%s GIT_AUTHOR_NAME=%s && claude --dangerously-skip-permissions",
|
|
||||||
m.rig.Name, polecat, bdActor, bdActor)
|
|
||||||
}
|
}
|
||||||
if err := m.tmux.SendKeys(sessionID, command); err != nil {
|
if err := m.tmux.SendKeys(sessionID, command); err != nil {
|
||||||
return fmt.Errorf("sending command: %w", err)
|
return fmt.Errorf("sending command: %w", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user