chore: Bump version to 0.4.0
Key fix: Orphan cleanup now skips Claude processes in valid Gas Town tmux sessions (gt-*/hq-*), preventing false kills of witnesses, refineries, and deacon during startup. Updated all component versions: - gt CLI: 0.3.1 → 0.4.0 - npm package: 0.3.0 → 0.4.0 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+18
-40
@@ -184,10 +184,9 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
|
||||
// Track per-rig status for LED indicators and sorting
|
||||
type rigStatus struct {
|
||||
hasWitness bool
|
||||
hasRefinery bool
|
||||
polecatCount int
|
||||
opState string // "OPERATIONAL", "PARKED", or "DOCKED"
|
||||
hasWitness bool
|
||||
hasRefinery bool
|
||||
opState string // "OPERATIONAL", "PARKED", or "DOCKED"
|
||||
}
|
||||
rigStatuses := make(map[string]*rigStatus)
|
||||
|
||||
@@ -202,10 +201,8 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
working int
|
||||
}
|
||||
healthByType := map[AgentType]*agentHealth{
|
||||
AgentPolecat: {},
|
||||
AgentWitness: {},
|
||||
AgentRefinery: {},
|
||||
AgentDeacon: {},
|
||||
}
|
||||
|
||||
// Single pass: track rig status AND agent health
|
||||
@@ -215,7 +212,8 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
continue
|
||||
}
|
||||
|
||||
// Track rig-level status (witness/refinery/polecat presence)
|
||||
// Track rig-level status (witness/refinery presence)
|
||||
// Polecats are not tracked in tmux - they're a GC concern, not a display concern
|
||||
if agent.Rig != "" && registeredRigs[agent.Rig] {
|
||||
if rigStatuses[agent.Rig] == nil {
|
||||
rigStatuses[agent.Rig] = &rigStatus{}
|
||||
@@ -225,8 +223,6 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
rigStatuses[agent.Rig].hasWitness = true
|
||||
case AgentRefinery:
|
||||
rigStatuses[agent.Rig].hasRefinery = true
|
||||
case AgentPolecat:
|
||||
rigStatuses[agent.Rig].polecatCount++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,9 +250,10 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
var parts []string
|
||||
|
||||
// Add per-agent-type health in consistent order
|
||||
// Format: "1/10 😺" = 1 working out of 10 total
|
||||
// Format: "1/3 👁️" = 1 working out of 3 total
|
||||
// Only show agent types that have sessions
|
||||
agentOrder := []AgentType{AgentPolecat, AgentWitness, AgentRefinery, AgentDeacon}
|
||||
// Note: Polecats and Deacon excluded - idle state display is misleading noise
|
||||
agentOrder := []AgentType{AgentWitness, AgentRefinery}
|
||||
var agentParts []string
|
||||
for _, agentType := range agentOrder {
|
||||
health := healthByType[agentType]
|
||||
@@ -287,7 +284,7 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
rigs = append(rigs, rigInfo{name: rigName, status: status})
|
||||
}
|
||||
|
||||
// Sort by: 1) running state, 2) polecat count (desc), 3) operational state, 4) alphabetical
|
||||
// Sort by: 1) running state, 2) operational state, 3) alphabetical
|
||||
sort.Slice(rigs, func(i, j int) bool {
|
||||
isRunningI := rigs[i].status.hasWitness || rigs[i].status.hasRefinery
|
||||
isRunningJ := rigs[j].status.hasWitness || rigs[j].status.hasRefinery
|
||||
@@ -297,12 +294,7 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
return isRunningI
|
||||
}
|
||||
|
||||
// Secondary sort: polecat count (descending)
|
||||
if rigs[i].status.polecatCount != rigs[j].status.polecatCount {
|
||||
return rigs[i].status.polecatCount > rigs[j].status.polecatCount
|
||||
}
|
||||
|
||||
// Tertiary sort: operational state (for non-running rigs: OPERATIONAL < PARKED < DOCKED)
|
||||
// Secondary sort: operational state (for non-running rigs: OPERATIONAL < PARKED < DOCKED)
|
||||
stateOrder := map[string]int{"OPERATIONAL": 0, "PARKED": 1, "DOCKED": 2}
|
||||
stateI := stateOrder[rigs[i].status.opState]
|
||||
stateJ := stateOrder[rigs[j].status.opState]
|
||||
@@ -310,7 +302,7 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
return stateI < stateJ
|
||||
}
|
||||
|
||||
// Quaternary sort: alphabetical
|
||||
// Tertiary sort: alphabetical
|
||||
return rigs[i].name < rigs[j].name
|
||||
})
|
||||
|
||||
@@ -352,17 +344,12 @@ func runMayorStatusLine(t *tmux.Tmux) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Show polecat count if > 0
|
||||
// All icons get 1 space, Park gets 2
|
||||
space := " "
|
||||
if led == "🅿️" {
|
||||
space = " "
|
||||
}
|
||||
display := led + space + rig.name
|
||||
if status.polecatCount > 0 {
|
||||
display += fmt.Sprintf("(%d)", status.polecatCount)
|
||||
}
|
||||
rigParts = append(rigParts, display)
|
||||
rigParts = append(rigParts, led+space+rig.name)
|
||||
}
|
||||
|
||||
if len(rigParts) > 0 {
|
||||
@@ -421,7 +408,6 @@ func runDeaconStatusLine(t *tmux.Tmux) error {
|
||||
}
|
||||
|
||||
rigs := make(map[string]bool)
|
||||
polecatCount := 0
|
||||
for _, s := range sessions {
|
||||
agent := categorizeSession(s)
|
||||
if agent == nil {
|
||||
@@ -431,16 +417,13 @@ func runDeaconStatusLine(t *tmux.Tmux) error {
|
||||
if agent.Rig != "" && registeredRigs[agent.Rig] {
|
||||
rigs[agent.Rig] = true
|
||||
}
|
||||
if agent.Type == AgentPolecat && registeredRigs[agent.Rig] {
|
||||
polecatCount++
|
||||
}
|
||||
}
|
||||
rigCount := len(rigs)
|
||||
|
||||
// Build status
|
||||
// Note: Polecats excluded - they're ephemeral and idle detection is a GC concern
|
||||
var parts []string
|
||||
parts = append(parts, fmt.Sprintf("%d rigs", rigCount))
|
||||
parts = append(parts, fmt.Sprintf("%d 😺", polecatCount))
|
||||
|
||||
// Priority 1: Check for hooked work (town beads for deacon)
|
||||
hookedWork := ""
|
||||
@@ -466,7 +449,8 @@ func runDeaconStatusLine(t *tmux.Tmux) error {
|
||||
}
|
||||
|
||||
// runWitnessStatusLine outputs status for a witness session.
|
||||
// Shows: polecat count, crew count, hook or mail preview
|
||||
// Shows: crew count, hook or mail preview
|
||||
// Note: Polecats excluded - they're ephemeral and idle detection is a GC concern
|
||||
func runWitnessStatusLine(t *tmux.Tmux, rigName string) error {
|
||||
if rigName == "" {
|
||||
// Try to extract from session name: gt-<rig>-witness
|
||||
@@ -483,25 +467,20 @@ func runWitnessStatusLine(t *tmux.Tmux, rigName string) error {
|
||||
townRoot, _ = workspace.Find(paneDir)
|
||||
}
|
||||
|
||||
// Count polecats and crew in this rig
|
||||
// Count crew in this rig (crew are persistent, worth tracking)
|
||||
sessions, err := t.ListSessions()
|
||||
if err != nil {
|
||||
return nil // Silent fail
|
||||
}
|
||||
|
||||
polecatCount := 0
|
||||
crewCount := 0
|
||||
for _, s := range sessions {
|
||||
agent := categorizeSession(s)
|
||||
if agent == nil {
|
||||
continue
|
||||
}
|
||||
if agent.Rig == rigName {
|
||||
if agent.Type == AgentPolecat {
|
||||
polecatCount++
|
||||
} else if agent.Type == AgentCrew {
|
||||
crewCount++
|
||||
}
|
||||
if agent.Rig == rigName && agent.Type == AgentCrew {
|
||||
crewCount++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,7 +488,6 @@ func runWitnessStatusLine(t *tmux.Tmux, rigName string) error {
|
||||
|
||||
// Build status
|
||||
var parts []string
|
||||
parts = append(parts, fmt.Sprintf("%d 😺", polecatCount))
|
||||
if crewCount > 0 {
|
||||
parts = append(parts, fmt.Sprintf("%d crew", crewCount))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user