Fix bd gate list: Separate closed gates into own section

Previously, displayGates() always showed 'Open Gates' header even when
closed gates were included via --all flag. Also, closed gates would
appear mixed with open gates under the misleading 'Open Gates' header.

Changes:
- Modified displayGates() to accept showAll parameter
- Separates gates into 'Open Gates' and 'Closed Gates' sections
- Closed gates only shown when --all flag is used
- Fixed handleGateList RPC handler to use ExcludeStatus instead of
  Status filter for consistency with CLI behavior

Fixes gas-town issue go-47m
This commit is contained in:
nux
2026-01-13 00:46:50 -08:00
committed by Spencer Tobin
parent a55b9c3064
commit d69bf4faa8
2 changed files with 62 additions and 32 deletions

View File

@@ -101,7 +101,7 @@ By default, shows only open gates. Use --all to include closed gates.`,
return return
} }
displayGates(issues) displayGates(issues, allFlag)
return return
} }
@@ -117,56 +117,86 @@ By default, shows only open gates. Use --all to include closed gates.`,
return return
} }
displayGates(issues) displayGates(issues, allFlag)
}, },
} }
// displayGates formats and displays gate issues // displayGates formats and displays gate issues, separating open and closed gates
func displayGates(gates []*types.Issue) { func displayGates(gates []*types.Issue, showAll bool) {
if len(gates) == 0 { if len(gates) == 0 {
fmt.Println("No gates found.") fmt.Println("No gates found.")
return return
} }
fmt.Printf("\n%s Open Gates (%d):\n\n", ui.RenderAccent("⏳"), len(gates)) // Separate open and closed gates
var openGates, closedGates []*types.Issue
for _, gate := range gates { for _, gate := range gates {
statusSym := "○"
if gate.Status == types.StatusClosed { if gate.Status == types.StatusClosed {
statusSym = "●" closedGates = append(closedGates, gate)
} else {
openGates = append(openGates, gate)
} }
}
// Format gate info // Display open gates
gateInfo := gate.AwaitType if len(openGates) > 0 {
if gate.AwaitID != "" { fmt.Printf("\n%s Open Gates (%d):\n\n", ui.RenderAccent(""), len(openGates))
gateInfo = fmt.Sprintf("%s %s", gate.AwaitType, gate.AwaitID) for _, gate := range openGates {
displaySingleGate(gate)
} }
}
// Format timeout if present // Display closed gates only if --all was used
timeoutStr := "" if showAll && len(closedGates) > 0 {
if gate.Timeout > 0 { fmt.Printf("\n%s Closed Gates (%d):\n\n", ui.RenderMuted("●"), len(closedGates))
timeoutStr = fmt.Sprintf(" (timeout: %s)", gate.Timeout) for _, gate := range closedGates {
displaySingleGate(gate)
} }
}
// Find blocked step from ID (gate ID format: parent.gate-stepid) if len(openGates) == 0 && (!showAll || len(closedGates) == 0) {
blockedStep := "" fmt.Println("No gates found.")
if strings.Contains(gate.ID, ".gate-") { return
parts := strings.Split(gate.ID, ".gate-")
if len(parts) == 2 {
blockedStep = fmt.Sprintf("%s.%s", parts[0], parts[1])
}
}
fmt.Printf("%s %s - %s%s\n", statusSym, ui.RenderID(gate.ID), gateInfo, timeoutStr)
if blockedStep != "" {
fmt.Printf(" Blocks: %s\n", blockedStep)
}
fmt.Println()
} }
fmt.Printf("To resolve a gate: bd close <gate-id>\n") fmt.Printf("To resolve a gate: bd close <gate-id>\n")
} }
// displaySingleGate formats and displays a single gate issue
func displaySingleGate(gate *types.Issue) {
statusSym := "○"
if gate.Status == types.StatusClosed {
statusSym = "●"
}
// Format gate info
gateInfo := gate.AwaitType
if gate.AwaitID != "" {
gateInfo = fmt.Sprintf("%s %s", gate.AwaitType, gate.AwaitID)
}
// Format timeout if present
timeoutStr := ""
if gate.Timeout > 0 {
timeoutStr = fmt.Sprintf(" (timeout: %s)", gate.Timeout)
}
// Find blocked step from ID (gate ID format: parent.gate-stepid)
blockedStep := ""
if strings.Contains(gate.ID, ".gate-") {
parts := strings.Split(gate.ID, ".gate-")
if len(parts) == 2 {
blockedStep = fmt.Sprintf("%s.%s", parts[0], parts[1])
}
}
fmt.Printf("%s %s - %s%s\n", statusSym, ui.RenderID(gate.ID), gateInfo, timeoutStr)
if blockedStep != "" {
fmt.Printf(" Blocks: %s\n", blockedStep)
}
fmt.Println()
}
// gateAddWaiterCmd adds a waiter to a gate // gateAddWaiterCmd adds a waiter to a gate
var gateAddWaiterCmd = &cobra.Command{ var gateAddWaiterCmd = &cobra.Command{
Use: "add-waiter <gate-id> <waiter>", Use: "add-waiter <gate-id> <waiter>",

View File

@@ -2108,9 +2108,9 @@ func (s *Server) handleGateList(req *Request) Response {
filter := types.IssueFilter{ filter := types.IssueFilter{
IssueType: &gateType, IssueType: &gateType,
} }
// By default, exclude closed gates (consistent with CLI behavior)
if !args.All { if !args.All {
openStatus := types.StatusOpen filter.ExcludeStatus = []types.Status{types.StatusClosed}
filter.Status = &openStatus
} }
gates, err := store.SearchIssues(ctx, "", filter) gates, err := store.SearchIssues(ctx, "", filter)