fix(statusline): Correct rig count and polecat count in tmux status bar
The status bar was incorrectly counting rigs and polecats due to: 1. Inconsistent witness session naming (gt-<rig>-witness vs gt-witness-<rig>) caused "witness" to be counted as a rig name 2. Non-polecat sessions (witness, refinery, crew) were counted as polecats Added extractRigFromSession() to handle all session naming patterns and isPolecatSession() to properly identify actual polecat workers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -97,13 +97,19 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
polecatCount := 0
|
||||
rigs := make(map[string]bool)
|
||||
for _, s := range sessions {
|
||||
if strings.HasPrefix(s, "gt-") && s != "gt-mayor" {
|
||||
if !strings.HasPrefix(s, "gt-") || s == "gt-mayor" || s == "gt-deacon" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Extract rig name based on session type
|
||||
rig := extractRigFromSession(s)
|
||||
if rig != "" {
|
||||
rigs[rig] = true
|
||||
}
|
||||
|
||||
// Only count actual polecats (not witness, refinery, crew)
|
||||
if isPolecatSession(s) {
|
||||
polecatCount++
|
||||
// Extract rig name: gt-<rig>-<worker>
|
||||
parts := strings.SplitN(s, "-", 3)
|
||||
if len(parts) >= 2 {
|
||||
rigs[parts[1]] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
rigCount := len(rigs)
|
||||
@@ -143,3 +149,46 @@ func getUnreadMailCount(identity string) int {
|
||||
|
||||
return unread
|
||||
}
|
||||
|
||||
// extractRigFromSession extracts the rig name from a tmux session name.
|
||||
// Handles different session naming patterns:
|
||||
// - gt-<rig>-<worker> (polecats)
|
||||
// - gt-<rig>-crew-<name> (crew workers)
|
||||
// - gt-<rig>-witness (daemon-style witness)
|
||||
// - gt-witness-<rig> (witness.go-style witness)
|
||||
// - gt-<rig>-refinery (refinery)
|
||||
func extractRigFromSession(s string) string {
|
||||
parts := strings.SplitN(s, "-", 4)
|
||||
if len(parts) < 3 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Handle gt-witness-<rig> pattern (inconsistent naming from witness.go)
|
||||
if parts[1] == "witness" {
|
||||
return parts[2]
|
||||
}
|
||||
|
||||
// Standard pattern: gt-<rig>-<something>
|
||||
return parts[1]
|
||||
}
|
||||
|
||||
// isPolecatSession returns true if the session is a polecat worker session.
|
||||
// Excludes witness, refinery, and crew sessions.
|
||||
func isPolecatSession(s string) bool {
|
||||
// Not a polecat if it ends with known suffixes or contains crew marker
|
||||
if strings.HasSuffix(s, "-witness") {
|
||||
return false
|
||||
}
|
||||
if strings.HasSuffix(s, "-refinery") {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(s, "-crew-") {
|
||||
return false
|
||||
}
|
||||
// Also handle gt-witness-<rig> pattern
|
||||
parts := strings.SplitN(s, "-", 3)
|
||||
if len(parts) >= 2 && parts[1] == "witness" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
75
internal/cmd/statusline_test.go
Normal file
75
internal/cmd/statusline_test.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package cmd
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestExtractRigFromSession(t *testing.T) {
|
||||
tests := []struct {
|
||||
session string
|
||||
want string
|
||||
}{
|
||||
// Standard polecat sessions
|
||||
{"gt-gastown-slit", "gastown"},
|
||||
{"gt-gastown-Toast", "gastown"},
|
||||
{"gt-myrig-worker", "myrig"},
|
||||
|
||||
// Crew sessions
|
||||
{"gt-gastown-crew-max", "gastown"},
|
||||
{"gt-myrig-crew-user", "myrig"},
|
||||
|
||||
// Witness sessions (daemon.go style: gt-<rig>-witness)
|
||||
{"gt-gastown-witness", "gastown"},
|
||||
{"gt-myrig-witness", "myrig"},
|
||||
|
||||
// Witness sessions (witness.go style: gt-witness-<rig>)
|
||||
{"gt-witness-gastown", "gastown"},
|
||||
{"gt-witness-myrig", "myrig"},
|
||||
|
||||
// Refinery sessions
|
||||
{"gt-gastown-refinery", "gastown"},
|
||||
{"gt-myrig-refinery", "myrig"},
|
||||
|
||||
// Edge cases
|
||||
{"gt-a-b", "a"}, // minimum valid
|
||||
{"gt-ab", ""}, // too short, no worker
|
||||
{"gt-", ""}, // invalid
|
||||
{"gt", ""}, // invalid
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.session, func(t *testing.T) {
|
||||
got := extractRigFromSession(tt.session)
|
||||
if got != tt.want {
|
||||
t.Errorf("extractRigFromSession(%q) = %q, want %q", tt.session, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsPolecatSession(t *testing.T) {
|
||||
tests := []struct {
|
||||
session string
|
||||
want bool
|
||||
}{
|
||||
// Polecat sessions (should return true)
|
||||
{"gt-gastown-slit", true},
|
||||
{"gt-gastown-Toast", true},
|
||||
{"gt-myrig-worker", true},
|
||||
{"gt-a-b", true},
|
||||
|
||||
// Non-polecat sessions (should return false)
|
||||
{"gt-gastown-witness", false},
|
||||
{"gt-witness-gastown", false},
|
||||
{"gt-gastown-refinery", false},
|
||||
{"gt-gastown-crew-max", false},
|
||||
{"gt-myrig-crew-user", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.session, func(t *testing.T) {
|
||||
got := isPolecatSession(tt.session)
|
||||
if got != tt.want {
|
||||
t.Errorf("isPolecatSession(%q) = %v, want %v", tt.session, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user