Add merge queue observability to gt status
- Add State (idle/processing/blocked) and Health (healthy/stale/empty) fields to MQSummary - Display state indicator (● for processing, ○ for idle/blocked) - Show [stale] warning when queue has >10 pending items with no processing - Include new fields in JSON output for automation (gt-hpcyt) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
dba5f688b9
commit
fd1afc1340
@@ -88,9 +88,11 @@ type RigStatus struct {
|
|||||||
|
|
||||||
// MQSummary represents the merge queue status for a rig.
|
// MQSummary represents the merge queue status for a rig.
|
||||||
type MQSummary struct {
|
type MQSummary struct {
|
||||||
Pending int `json:"pending"` // Open MRs ready to merge (no blockers)
|
Pending int `json:"pending"` // Open MRs ready to merge (no blockers)
|
||||||
InFlight int `json:"in_flight"` // MRs currently being processed
|
InFlight int `json:"in_flight"` // MRs currently being processed
|
||||||
Blocked int `json:"blocked"` // MRs waiting on dependencies
|
Blocked int `json:"blocked"` // MRs waiting on dependencies
|
||||||
|
State string `json:"state"` // idle, processing, or blocked
|
||||||
|
Health string `json:"health"` // healthy, stale, or empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// AgentHookInfo represents an agent's hook (pinned work) status.
|
// AgentHookInfo represents an agent's hook (pinned work) status.
|
||||||
@@ -336,7 +338,20 @@ func outputStatusText(status TownStatus) error {
|
|||||||
mqParts = append(mqParts, style.Dim.Render(fmt.Sprintf("%d blocked", r.MQ.Blocked)))
|
mqParts = append(mqParts, style.Dim.Render(fmt.Sprintf("%d blocked", r.MQ.Blocked)))
|
||||||
}
|
}
|
||||||
if len(mqParts) > 0 {
|
if len(mqParts) > 0 {
|
||||||
fmt.Printf(" MQ: %s\n", strings.Join(mqParts, ", "))
|
// Add state indicator
|
||||||
|
stateIcon := "○" // idle
|
||||||
|
switch r.MQ.State {
|
||||||
|
case "processing":
|
||||||
|
stateIcon = style.Success.Render("●")
|
||||||
|
case "blocked":
|
||||||
|
stateIcon = style.Error.Render("○")
|
||||||
|
}
|
||||||
|
// Add health warning if stale
|
||||||
|
healthSuffix := ""
|
||||||
|
if r.MQ.Health == "stale" {
|
||||||
|
healthSuffix = style.Error.Render(" [stale]")
|
||||||
|
}
|
||||||
|
fmt.Printf(" MQ: %s %s%s\n", stateIcon, strings.Join(mqParts, ", "), healthSuffix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
@@ -741,6 +756,28 @@ func getMQSummary(r *rig.Rig) *MQSummary {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine queue state
|
||||||
|
state := "idle"
|
||||||
|
if len(inProgressMRs) > 0 {
|
||||||
|
state = "processing"
|
||||||
|
} else if pending > 0 {
|
||||||
|
state = "idle" // Has work but not processing yet
|
||||||
|
} else if blocked > 0 {
|
||||||
|
state = "blocked" // Only blocked items, nothing processable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine queue health
|
||||||
|
health := "empty"
|
||||||
|
total := pending + len(inProgressMRs) + blocked
|
||||||
|
if total > 0 {
|
||||||
|
health = "healthy"
|
||||||
|
// Check for potential issues
|
||||||
|
if pending > 10 && len(inProgressMRs) == 0 {
|
||||||
|
// Large queue but nothing processing - may be stuck
|
||||||
|
health = "stale"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only return summary if there's something to show
|
// Only return summary if there's something to show
|
||||||
if pending == 0 && len(inProgressMRs) == 0 && blocked == 0 {
|
if pending == 0 && len(inProgressMRs) == 0 && blocked == 0 {
|
||||||
return nil
|
return nil
|
||||||
@@ -750,6 +787,8 @@ func getMQSummary(r *rig.Rig) *MQSummary {
|
|||||||
Pending: pending,
|
Pending: pending,
|
||||||
InFlight: len(inProgressMRs),
|
InFlight: len(inProgressMRs),
|
||||||
Blocked: blocked,
|
Blocked: blocked,
|
||||||
|
State: state,
|
||||||
|
Health: health,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user