feat(mq): Add priority-ordered queue display and processing (gt-si8rq.6)
Implements priority scoring for merge queue ordering: ## Changes to gt mq list - Add SCORE column showing priority score (higher = process first) - Sort MRs by score descending instead of simple priority - Add CONVOY column showing convoy ID if tracked ## New gt mq next command - Returns highest-score MR ready for processing - Supports --strategy=fifo for FIFO ordering fallback - Supports --quiet for just printing MR ID - Supports --json for programmatic access ## Changes to Refinery - Queue() now sorts by priority score instead of simple priority - Uses ScoreMR from mrqueue package for consistent scoring ## MR Fields Extended - Added retry_count, last_conflict_sha, conflict_task_id - Added convoy_id, convoy_created_at for convoy tracking - These fields feed into priority scoring function 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
// Package beads provides field parsing utilities for structured issue descriptions.
|
||||
package beads
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Note: AgentFields, ParseAgentFields, FormatAgentDescription, and CreateAgentBead are in beads.go
|
||||
|
||||
@@ -165,6 +168,15 @@ type MRFields struct {
|
||||
MergeCommit string // SHA of merge commit (set on close)
|
||||
CloseReason string // Reason for closing: merged, rejected, conflict, superseded
|
||||
AgentBead string // Agent bead ID that created this MR (for traceability)
|
||||
|
||||
// Conflict resolution fields (for priority scoring)
|
||||
RetryCount int // Number of conflict-resolution cycles
|
||||
LastConflictSHA string // SHA of main when conflict occurred
|
||||
ConflictTaskID string // Link to conflict-resolution task (if any)
|
||||
|
||||
// Convoy tracking (for priority scoring - convoy starvation prevention)
|
||||
ConvoyID string // Parent convoy ID if part of a convoy
|
||||
ConvoyCreatedAt string // Convoy creation time (ISO 8601) for starvation prevention
|
||||
}
|
||||
|
||||
// ParseMRFields extracts structured merge-request fields from an issue's description.
|
||||
@@ -222,6 +234,23 @@ func ParseMRFields(issue *Issue) *MRFields {
|
||||
case "agent_bead", "agent-bead", "agentbead":
|
||||
fields.AgentBead = value
|
||||
hasFields = true
|
||||
case "retry_count", "retry-count", "retrycount":
|
||||
if n, err := parseIntField(value); err == nil {
|
||||
fields.RetryCount = n
|
||||
hasFields = true
|
||||
}
|
||||
case "last_conflict_sha", "last-conflict-sha", "lastconflictsha":
|
||||
fields.LastConflictSHA = value
|
||||
hasFields = true
|
||||
case "conflict_task_id", "conflict-task-id", "conflicttaskid":
|
||||
fields.ConflictTaskID = value
|
||||
hasFields = true
|
||||
case "convoy_id", "convoy-id", "convoyid", "convoy":
|
||||
fields.ConvoyID = value
|
||||
hasFields = true
|
||||
case "convoy_created_at", "convoy-created-at", "convoycreatedat":
|
||||
fields.ConvoyCreatedAt = value
|
||||
hasFields = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +260,13 @@ func ParseMRFields(issue *Issue) *MRFields {
|
||||
return fields
|
||||
}
|
||||
|
||||
// parseIntField parses an integer from a string, returning 0 on error.
|
||||
func parseIntField(s string) (int, error) {
|
||||
var n int
|
||||
_, err := fmt.Sscanf(s, "%d", &n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// FormatMRFields formats MRFields as a string suitable for an issue description.
|
||||
// Only non-empty fields are included.
|
||||
func FormatMRFields(fields *MRFields) string {
|
||||
@@ -264,6 +300,21 @@ func FormatMRFields(fields *MRFields) string {
|
||||
if fields.AgentBead != "" {
|
||||
lines = append(lines, "agent_bead: "+fields.AgentBead)
|
||||
}
|
||||
if fields.RetryCount > 0 {
|
||||
lines = append(lines, fmt.Sprintf("retry_count: %d", fields.RetryCount))
|
||||
}
|
||||
if fields.LastConflictSHA != "" {
|
||||
lines = append(lines, "last_conflict_sha: "+fields.LastConflictSHA)
|
||||
}
|
||||
if fields.ConflictTaskID != "" {
|
||||
lines = append(lines, "conflict_task_id: "+fields.ConflictTaskID)
|
||||
}
|
||||
if fields.ConvoyID != "" {
|
||||
lines = append(lines, "convoy_id: "+fields.ConvoyID)
|
||||
}
|
||||
if fields.ConvoyCreatedAt != "" {
|
||||
lines = append(lines, "convoy_created_at: "+fields.ConvoyCreatedAt)
|
||||
}
|
||||
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
@@ -278,22 +329,38 @@ func SetMRFields(issue *Issue, fields *MRFields) string {
|
||||
|
||||
// Known MR field keys (lowercase)
|
||||
mrKeys := map[string]bool{
|
||||
"branch": true,
|
||||
"target": true,
|
||||
"source_issue": true,
|
||||
"source-issue": true,
|
||||
"sourceissue": true,
|
||||
"worker": true,
|
||||
"rig": true,
|
||||
"merge_commit": true,
|
||||
"merge-commit": true,
|
||||
"mergecommit": true,
|
||||
"close_reason": true,
|
||||
"close-reason": true,
|
||||
"closereason": true,
|
||||
"agent_bead": true,
|
||||
"agent-bead": true,
|
||||
"agentbead": true,
|
||||
"branch": true,
|
||||
"target": true,
|
||||
"source_issue": true,
|
||||
"source-issue": true,
|
||||
"sourceissue": true,
|
||||
"worker": true,
|
||||
"rig": true,
|
||||
"merge_commit": true,
|
||||
"merge-commit": true,
|
||||
"mergecommit": true,
|
||||
"close_reason": true,
|
||||
"close-reason": true,
|
||||
"closereason": true,
|
||||
"agent_bead": true,
|
||||
"agent-bead": true,
|
||||
"agentbead": true,
|
||||
"retry_count": true,
|
||||
"retry-count": true,
|
||||
"retrycount": true,
|
||||
"last_conflict_sha": true,
|
||||
"last-conflict-sha": true,
|
||||
"lastconflictsha": true,
|
||||
"conflict_task_id": true,
|
||||
"conflict-task-id": true,
|
||||
"conflicttaskid": true,
|
||||
"convoy_id": true,
|
||||
"convoy-id": true,
|
||||
"convoyid": true,
|
||||
"convoy": true,
|
||||
"convoy_created_at": true,
|
||||
"convoy-created-at": true,
|
||||
"convoycreatedat": true,
|
||||
}
|
||||
|
||||
// Collect non-MR lines from existing description
|
||||
|
||||
Reference in New Issue
Block a user