diff --git a/internal/cmd/dog.go b/internal/cmd/dog.go index 9a8174c0..6c8cb147 100644 --- a/internal/cmd/dog.go +++ b/internal/cmd/dog.go @@ -808,7 +808,7 @@ func runDogDispatch(cmd *cobra.Command, args []string) error { // Build startup command with initial prompt to check mail and execute plugin initialPrompt := fmt.Sprintf("I am dog %s. Check my mail inbox with 'gt mail inbox' and execute the plugin instructions I received.", targetDog.Name) - startCmd := config.BuildAgentStartupCommand("dog", "", townRoot, targetDog.Path, initialPrompt) + startCmd := config.BuildDogStartupCommand(targetDog.Name, targetDog.Path, townRoot, initialPrompt) // Create session from dog's directory if err := t.NewSessionWithCommand(dogSessionName, targetDog.Path, startCmd); err != nil { @@ -818,7 +818,9 @@ func runDogDispatch(cmd *cobra.Command, args []string) error { // Non-fatal: mail was sent, dog is marked as working, but no session to execute // The deacon or human can manually start the session later } else { - // Set environment for the dog session + // Also set tmux environment as a fallback (belt and suspenders). + // The startup command exports these vars, but setting them in tmux + // environment ensures new panes/windows in the session inherit them. envVars := config.AgentEnv(config.AgentEnvConfig{ Role: "dog", AgentName: targetDog.Name, diff --git a/internal/cmd/mail_identity.go b/internal/cmd/mail_identity.go index 70d087ba..2a2264a6 100644 --- a/internal/cmd/mail_identity.go +++ b/internal/cmd/mail_identity.go @@ -129,6 +129,14 @@ func detectSenderFromRole(role string) string { return fmt.Sprintf("%s/refinery", rig) } return detectSenderFromCwd() + case "dog": + // Dogs use BD_ACTOR directly since they're town-level (no rig) + // Format: deacon/dogs/ + actor := os.Getenv("BD_ACTOR") + if actor != "" { + return actor + } + return detectSenderFromCwd() default: // Unknown role, try cwd detection return detectSenderFromCwd() diff --git a/internal/config/loader.go b/internal/config/loader.go index 612f6cae..6ab24a18 100644 --- a/internal/config/loader.go +++ b/internal/config/loader.go @@ -1472,6 +1472,18 @@ func BuildCrewStartupCommandWithAgentOverride(rigName, crewName, rigPath, prompt return BuildStartupCommandWithAgentOverride(envVars, rigPath, prompt, agentOverride) } +// BuildDogStartupCommand builds the startup command for a deacon dog. +// Dogs are town-level agents, so they don't have a rig. +// Sets GT_ROLE=dog, BD_ACTOR=deacon/dogs/, and GT_ROOT. +func BuildDogStartupCommand(dogName, dogPath, townRoot, prompt string) string { + envVars := AgentEnv(AgentEnvConfig{ + Role: "dog", + AgentName: dogName, + TownRoot: townRoot, + }) + return BuildStartupCommand(envVars, dogPath, prompt) +} + // ExpectedPaneCommands returns tmux pane command names that indicate the runtime is running. // Claude can report as "node" (older versions) or "claude" (newer versions). // Other runtimes typically report their executable name.