fix: Honor town default_agent for town-level agents (mayor, deacon)
Previously, BuildStartupCommand, GetRuntimeCommand, and GetRuntimeCommandWithPrompt would fall back to DefaultRuntimeConfig() (hardcoded "claude") when rigPath was empty, instead of reading the town settings for the default_agent. This meant that `gt config default-agent` had no effect on town-level agents like the mayor. Fix: Added findTownRootFromCwd() to detect town root from cwd, then call ResolveAgentConfig() to read the town's default_agent setting and custom agents. Now `gt mayor attach` (and other town-level agents) correctly use the agent configured in town settings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -808,8 +808,13 @@ func fillRuntimeDefaults(rc *RuntimeConfig) *RuntimeConfig {
|
|||||||
// for starting an LLM session. It resolves the agent config and builds the command.
|
// for starting an LLM session. It resolves the agent config and builds the command.
|
||||||
func GetRuntimeCommand(rigPath string) string {
|
func GetRuntimeCommand(rigPath string) string {
|
||||||
if rigPath == "" {
|
if rigPath == "" {
|
||||||
|
// Try to detect town root from cwd for town-level agents (mayor, deacon)
|
||||||
|
townRoot, err := findTownRootFromCwd()
|
||||||
|
if err != nil {
|
||||||
return DefaultRuntimeConfig().BuildCommand()
|
return DefaultRuntimeConfig().BuildCommand()
|
||||||
}
|
}
|
||||||
|
return ResolveAgentConfig(townRoot, "").BuildCommand()
|
||||||
|
}
|
||||||
// Derive town root from rig path (rig is typically ~/gt/<rigname>)
|
// Derive town root from rig path (rig is typically ~/gt/<rigname>)
|
||||||
townRoot := filepath.Dir(rigPath)
|
townRoot := filepath.Dir(rigPath)
|
||||||
return ResolveAgentConfig(townRoot, rigPath).BuildCommand()
|
return ResolveAgentConfig(townRoot, rigPath).BuildCommand()
|
||||||
@@ -818,15 +823,50 @@ func GetRuntimeCommand(rigPath string) string {
|
|||||||
// GetRuntimeCommandWithPrompt returns the full command with an initial prompt.
|
// GetRuntimeCommandWithPrompt returns the full command with an initial prompt.
|
||||||
func GetRuntimeCommandWithPrompt(rigPath, prompt string) string {
|
func GetRuntimeCommandWithPrompt(rigPath, prompt string) string {
|
||||||
if rigPath == "" {
|
if rigPath == "" {
|
||||||
|
// Try to detect town root from cwd for town-level agents (mayor, deacon)
|
||||||
|
townRoot, err := findTownRootFromCwd()
|
||||||
|
if err != nil {
|
||||||
return DefaultRuntimeConfig().BuildCommandWithPrompt(prompt)
|
return DefaultRuntimeConfig().BuildCommandWithPrompt(prompt)
|
||||||
}
|
}
|
||||||
|
return ResolveAgentConfig(townRoot, "").BuildCommandWithPrompt(prompt)
|
||||||
|
}
|
||||||
townRoot := filepath.Dir(rigPath)
|
townRoot := filepath.Dir(rigPath)
|
||||||
return ResolveAgentConfig(townRoot, rigPath).BuildCommandWithPrompt(prompt)
|
return ResolveAgentConfig(townRoot, rigPath).BuildCommandWithPrompt(prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// findTownRootFromCwd locates the town root by walking up from cwd.
|
||||||
|
// It looks for the mayor/town.json marker file.
|
||||||
|
// Returns empty string and no error if not found (caller should use defaults).
|
||||||
|
func findTownRootFromCwd() (string, error) {
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("getting cwd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
absDir, err := filepath.Abs(cwd)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("resolving path: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const marker = "mayor/town.json"
|
||||||
|
|
||||||
|
current := absDir
|
||||||
|
for {
|
||||||
|
if _, err := os.Stat(filepath.Join(current, marker)); err == nil {
|
||||||
|
return current, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
parent := filepath.Dir(current)
|
||||||
|
if parent == current {
|
||||||
|
return "", fmt.Errorf("town root not found (no %s marker)", marker)
|
||||||
|
}
|
||||||
|
current = parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BuildStartupCommand builds a full startup command with environment exports.
|
// BuildStartupCommand builds a full startup command with environment exports.
|
||||||
// envVars is a map of environment variable names to values.
|
// envVars is a map of environment variable names to values.
|
||||||
// rigPath is optional - if empty, uses defaults.
|
// rigPath is optional - if empty, tries to detect town root from cwd.
|
||||||
// prompt is optional - if provided, appended as the initial prompt.
|
// prompt is optional - if provided, appended as the initial prompt.
|
||||||
func BuildStartupCommand(envVars map[string]string, rigPath, prompt string) string {
|
func BuildStartupCommand(envVars map[string]string, rigPath, prompt string) string {
|
||||||
var rc *RuntimeConfig
|
var rc *RuntimeConfig
|
||||||
@@ -835,7 +875,13 @@ func BuildStartupCommand(envVars map[string]string, rigPath, prompt string) stri
|
|||||||
townRoot := filepath.Dir(rigPath)
|
townRoot := filepath.Dir(rigPath)
|
||||||
rc = ResolveAgentConfig(townRoot, rigPath)
|
rc = ResolveAgentConfig(townRoot, rigPath)
|
||||||
} else {
|
} else {
|
||||||
|
// Try to detect town root from cwd for town-level agents (mayor, deacon)
|
||||||
|
townRoot, err := findTownRootFromCwd()
|
||||||
|
if err != nil {
|
||||||
rc = DefaultRuntimeConfig()
|
rc = DefaultRuntimeConfig()
|
||||||
|
} else {
|
||||||
|
rc = ResolveAgentConfig(townRoot, "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build environment export prefix
|
// Build environment export prefix
|
||||||
|
|||||||
Reference in New Issue
Block a user