Add Convoy Tracking Web UI Dashboard (hq-vr35)

Complete convoy dashboard feature with real-time status tracking:

- Activity package: LastActivity calculation with color thresholds
  (green <2min, yellow 2-5min, red >5min)
- Web package: Template, handler, fetcher for convoy list
- CLI: `gt dashboard [--port=8080] [--open]` command
- Browser E2E tests with rod (headless Chrome)

Features:
- Real-time convoy status with htmx auto-refresh (30s)
- Progress tracking for each convoy
- Last activity indicator with color coding
- Empty state handling

Supersedes: PRs #55, #57, #58, #65, #66

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
dag
2026-01-03 12:32:35 -08:00
committed by Mike Lady
parent 5186cd90be
commit fc805595bb
3 changed files with 403 additions and 0 deletions

View File

@@ -122,6 +122,7 @@ func (f *LiveConvoyFetcher) getTrackedIssues(convoyID string) []trackedIssueInfo
// Query tracked dependencies from SQLite
safeConvoyID := strings.ReplaceAll(convoyID, "'", "''")
// #nosec G204 -- sqlite3 path is from trusted config, convoyID is escaped
queryCmd := exec.Command("sqlite3", "-json", dbPath,
fmt.Sprintf(`SELECT depends_on_id, type FROM dependencies WHERE issue_id = '%s' AND type = 'tracks'`, safeConvoyID))
@@ -200,6 +201,7 @@ func (f *LiveConvoyFetcher) getIssueDetailsBatch(issueIDs []string) map[string]*
args := append([]string{"show"}, issueIDs...)
args = append(args, "--json")
// #nosec G204 -- bd is a trusted internal tool, args are issue IDs
showCmd := exec.Command("bd", args...)
var stdout bytes.Buffer
showCmd.Stdout = &stdout
@@ -262,6 +264,7 @@ func (f *LiveConvoyFetcher) getWorkersForIssues(issueIDs []string) map[string]*w
`SELECT id, hook_bead, last_activity FROM issues WHERE issue_type = 'agent' AND status = 'open' AND hook_bead = '%s' LIMIT 1`,
safeID)
// #nosec G204 -- sqlite3 path is from trusted glob, issueID is escaped
queryCmd := exec.Command("sqlite3", "-json", dbPath, query)
var stdout bytes.Buffer
queryCmd.Stdout = &stdout