* Add LastActivity calculation for convoy dashboard (hq-x2xy) Adds internal/activity package with color-coded activity tracking: - Green: <2 minutes (active) - Yellow: 2-5 minutes (stale) - Red: >5 minutes (stuck) Features: - Calculate() function returns Info with formatted age and color class - Helper methods: IsActive(), IsStale(), IsStuck() - Handles edge cases: zero time, future time (clock skew) Tests: 8 test functions with 25 sub-tests covering all thresholds. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add convoy dashboard HTML template with Last Activity (hq-fq1g) Adds internal/web package with convoy dashboard template: - convoy.html with Last Activity column and color coding - Green (<2min), Yellow (2-5min), Red (>5min) activity indicators - htmx auto-refresh every 30 seconds - Progress bars for convoy completion - Status indicators for open/closed convoys - Empty state when no convoys Also includes internal/activity package (dependency from hq-x2xy): - Calculate() returns Info with formatted age and color class - Helper methods: IsActive(), IsStale(), IsStuck() Tests: 6 template tests + 8 activity tests, all passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add convoy list handler with activity data (hq-3edt) Adds HTTP handler that wires convoy dashboard template to real data: - ConvoyHandler: HTTP handler for GET / rendering convoy dashboard - LiveConvoyFetcher: Fetches convoys from beads with activity data - ConvoyFetcher interface: Enables mocking for tests Features: - Fetches open convoys from town beads - Calculates progress (completed/total) from tracked issues - Gets Last Activity from worker agent beads - Color codes activity: Green (<2min), Yellow (2-5min), Red (>5min) Includes dependencies (not yet merged): - internal/activity: Activity calculation (hq-x2xy) - internal/web/templates: HTML template (hq-fq1g) Tests: 5 handler tests + 6 template tests + 8 activity tests = 19 total 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add 'gt dashboard' CLI command (hq-s1bg) Add dashboard command to start the convoy tracking web server. Usage: gt dashboard [--port=8080] [--open] Features: - --port: Configurable HTTP port (default 8080) - --open: Auto-open browser on start - Cross-platform browser launch (darwin/linux/windows) - Graceful workspace detection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
59 lines
1.4 KiB
Go
59 lines
1.4 KiB
Go
package cmd
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func TestDashboardCmd_FlagsExist(t *testing.T) {
|
|
// Verify required flags exist with correct defaults
|
|
portFlag := dashboardCmd.Flags().Lookup("port")
|
|
if portFlag == nil {
|
|
t.Fatal("--port flag should exist")
|
|
}
|
|
if portFlag.DefValue != "8080" {
|
|
t.Errorf("--port default should be 8080, got %s", portFlag.DefValue)
|
|
}
|
|
|
|
openFlag := dashboardCmd.Flags().Lookup("open")
|
|
if openFlag == nil {
|
|
t.Fatal("--open flag should exist")
|
|
}
|
|
if openFlag.DefValue != "false" {
|
|
t.Errorf("--open default should be false, got %s", openFlag.DefValue)
|
|
}
|
|
}
|
|
|
|
func TestDashboardCmd_IsRegistered(t *testing.T) {
|
|
// Verify command is registered under root
|
|
found := false
|
|
for _, cmd := range rootCmd.Commands() {
|
|
if cmd.Name() == "dashboard" {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Error("dashboard command should be registered with rootCmd")
|
|
}
|
|
}
|
|
|
|
func TestDashboardCmd_HasCorrectGroup(t *testing.T) {
|
|
if dashboardCmd.GroupID != GroupDiag {
|
|
t.Errorf("dashboard should be in diag group, got %s", dashboardCmd.GroupID)
|
|
}
|
|
}
|
|
|
|
func TestDashboardCmd_RequiresWorkspace(t *testing.T) {
|
|
// Create a test command that simulates running outside workspace
|
|
cmd := &cobra.Command{}
|
|
cmd.SetArgs([]string{})
|
|
|
|
// The actual workspace check happens in runDashboard
|
|
// This test verifies the command structure is correct
|
|
if dashboardCmd.RunE == nil {
|
|
t.Error("dashboard command should have RunE set")
|
|
}
|
|
}
|