From 77531e6f282226259c3c47ad33db63c1c906ff59 Mon Sep 17 00:00:00 2001 From: furiosa Date: Fri, 23 Jan 2026 15:47:18 -0800 Subject: [PATCH] feat(goals): show assignee for each bead in gt goals output Add assignee display to both list and single-goal views. In list view, assignee appears on the second line when present. In single-goal view, it appears as a dedicated field after priority. JSON output also includes the assignee field. Closes: gt-libj Co-Authored-By: Claude Opus 4.5 --- internal/cmd/goals.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/internal/cmd/goals.go b/internal/cmd/goals.go index 726afbda..acddb314 100644 --- a/internal/cmd/goals.go +++ b/internal/cmd/goals.go @@ -75,6 +75,7 @@ type goalInfo struct { Title string `json:"title"` Status string `json:"status"` Priority int `json:"priority"` + Assignee string `json:"assignee,omitempty"` ConvoyCount int `json:"convoy_count"` LastMovement time.Time `json:"last_movement,omitempty"` StalenessHrs float64 `json:"staleness_hours"` @@ -99,6 +100,7 @@ func showGoal(goalID string) error { Status string `json:"status"` Priority int `json:"priority"` IssueType string `json:"issue_type"` + Assignee string `json:"assignee"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } @@ -131,6 +133,7 @@ func showGoal(goalID string) error { Title: goal.Title, Status: goal.Status, Priority: goal.Priority, + Assignee: goal.Assignee, ConvoyCount: len(convoys), LastMovement: lastMovement, StalenessHrs: stalenessHrs, @@ -145,6 +148,9 @@ func showGoal(goalID string) error { fmt.Printf("%s P%d %s: %s\n\n", icon, goal.Priority, style.Bold.Render(goal.ID), goal.Title) fmt.Printf(" Status: %s\n", goal.Status) fmt.Printf(" Priority: P%d\n", goal.Priority) + if goal.Assignee != "" { + fmt.Printf(" Assignee: @%s\n", goal.Assignee) + } fmt.Printf(" Convoys: %d\n", len(convoys)) fmt.Printf(" Last activity: %s\n", formatLastActivity(lastMovement)) @@ -222,6 +228,7 @@ func listGoals() error { Title: epic.Title, Status: epic.Status, Priority: epic.Priority, + Assignee: epic.Assignee, ConvoyCount: len(convoys), LastMovement: lastMovement, StalenessHrs: stalenessHrs, @@ -264,9 +271,13 @@ func listGoals() error { fmt.Printf(" %s %s %s: %s\n", g.StalenessIcon, priorityStr, g.ID, g.Title) - // Second line with convoy count and staleness + // Second line with convoy count, staleness, and assignee (if any) activityStr := formatActivityShort(g.StalenessHrs) - fmt.Printf(" %d convoy(s) | %s\n\n", g.ConvoyCount, activityStr) + if g.Assignee != "" { + fmt.Printf(" %d convoy(s) | %s | @%s\n\n", g.ConvoyCount, activityStr, g.Assignee) + } else { + fmt.Printf(" %d convoy(s) | %s\n\n", g.ConvoyCount, activityStr) + } } return nil @@ -458,6 +469,7 @@ type epicRecord struct { Status string `json:"status"` Priority int `json:"priority"` UpdatedAt string `json:"updated_at"` + Assignee string `json:"assignee"` } // collectEpicsFromAllRigs queries all rigs for epics and aggregates them.