diff --git a/internal/doctor/agent_beads_check.go b/internal/doctor/agent_beads_check.go index e343efdf..601cfcb7 100644 --- a/internal/doctor/agent_beads_check.go +++ b/internal/doctor/agent_beads_check.go @@ -33,6 +33,12 @@ func NewAgentBeadsCheck() *AgentBeadsCheck { } } +// rigInfo holds the rig name and its beads path from routes. +type rigInfo struct { + name string // rig name (first component of path) + beadsPath string // full path to beads directory relative to town root +} + // Run checks if agent beads exist for all expected agents. func (c *AgentBeadsCheck) Run(ctx *CheckContext) *CheckResult { // Load routes to get prefixes (routes.jsonl is source of truth for prefixes) @@ -46,16 +52,19 @@ func (c *AgentBeadsCheck) Run(ctx *CheckContext) *CheckResult { } } - // Build prefix -> rigName map from routes - // Routes have format: prefix "gt-" -> path "gastown/mayor/rig" - prefixToRig := make(map[string]string) // prefix (without hyphen) -> rigName + // Build prefix -> rigInfo map from routes + // Routes have format: prefix "gt-" -> path "gastown/mayor/rig" or "my-saas" + prefixToRig := make(map[string]rigInfo) // prefix (without hyphen) -> rigInfo for _, r := range routes { - // Extract rig name from path like "gastown/mayor/rig" + // Extract rig name from path (first component) parts := strings.Split(r.Path, "/") if len(parts) >= 1 && parts[0] != "." { rigName := parts[0] prefix := strings.TrimSuffix(r.Prefix, "-") - prefixToRig[prefix] = rigName + prefixToRig[prefix] = rigInfo{ + name: rigName, + beadsPath: r.Path, // Use the full route path + } } } @@ -73,20 +82,21 @@ func (c *AgentBeadsCheck) Run(ctx *CheckContext) *CheckResult { // Find the first rig (by name, alphabetically) for global agents // Only consider gt-prefix rigs since other prefixes can't have agent beads yet var firstRigName string - for prefix, rigName := range prefixToRig { + for prefix, info := range prefixToRig { if prefix != "gt" { continue // Skip non-gt prefixes for first rig selection } - if firstRigName == "" || rigName < firstRigName { - firstRigName = rigName + if firstRigName == "" || info.name < firstRigName { + firstRigName = info.name } } // Check each rig for its agents - for prefix, rigName := range prefixToRig { - // Get beads client for this rig - rigBeadsPath := filepath.Join(ctx.TownRoot, rigName, "mayor", "rig") + for prefix, info := range prefixToRig { + // Get beads client for this rig using the route path directly + rigBeadsPath := filepath.Join(ctx.TownRoot, info.beadsPath) bd := beads.New(rigBeadsPath) + rigName := info.name // Check rig-specific agents (using canonical naming: prefix-rig-role-name) witnessID := beads.WitnessBeadIDWithPrefix(prefix, rigName) @@ -155,14 +165,17 @@ func (c *AgentBeadsCheck) Fix(ctx *CheckContext) error { return fmt.Errorf("loading routes.jsonl: %w", err) } - // Build prefix -> rigName map from routes - prefixToRig := make(map[string]string) + // Build prefix -> rigInfo map from routes + prefixToRig := make(map[string]rigInfo) for _, r := range routes { parts := strings.Split(r.Path, "/") if len(parts) >= 1 && parts[0] != "." { rigName := parts[0] prefix := strings.TrimSuffix(r.Prefix, "-") - prefixToRig[prefix] = rigName + prefixToRig[prefix] = rigInfo{ + name: rigName, + beadsPath: r.Path, // Use the full route path + } } } @@ -172,19 +185,21 @@ func (c *AgentBeadsCheck) Fix(ctx *CheckContext) error { // Find the first rig for global agents (only gt-prefix rigs) var firstRigName string - for prefix, rigName := range prefixToRig { + for prefix, info := range prefixToRig { if prefix != "gt" { continue } - if firstRigName == "" || rigName < firstRigName { - firstRigName = rigName + if firstRigName == "" || info.name < firstRigName { + firstRigName = info.name } } // Create missing agents for each rig - for prefix, rigName := range prefixToRig { - rigBeadsPath := filepath.Join(ctx.TownRoot, rigName, "mayor", "rig") + for prefix, info := range prefixToRig { + // Use the route path directly instead of hardcoding /mayor/rig + rigBeadsPath := filepath.Join(ctx.TownRoot, info.beadsPath) bd := beads.New(rigBeadsPath) + rigName := info.name // Create rig-specific agents if missing (using canonical naming: prefix-rig-role-name) witnessID := beads.WitnessBeadIDWithPrefix(prefix, rigName)