|
| 1 | +package cmd |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "fmt" |
| 6 | + "os" |
| 7 | + "strings" |
| 8 | + |
| 9 | + "github.com/spf13/cobra" |
| 10 | +) |
| 11 | + |
| 12 | +var infoCmd = &cobra.Command{ |
| 13 | + Use: "info", |
| 14 | + GroupID: GroupDiag, |
| 15 | + Short: "Show Gas Town information and what's new", |
| 16 | + Long: `Display information about the current Gas Town installation. |
| 17 | +
|
| 18 | +This command shows: |
| 19 | + - Version information |
| 20 | + - What's new in recent versions (with --whats-new flag) |
| 21 | +
|
| 22 | +Examples: |
| 23 | + gt info |
| 24 | + gt info --whats-new |
| 25 | + gt info --whats-new --json`, |
| 26 | + Run: func(cmd *cobra.Command, args []string) { |
| 27 | + whatsNewFlag, _ := cmd.Flags().GetBool("whats-new") |
| 28 | + jsonFlag, _ := cmd.Flags().GetBool("json") |
| 29 | + |
| 30 | + if whatsNewFlag { |
| 31 | + showWhatsNew(jsonFlag) |
| 32 | + return |
| 33 | + } |
| 34 | + |
| 35 | + // Default: show basic info |
| 36 | + info := map[string]interface{}{ |
| 37 | + "version": Version, |
| 38 | + "build": Build, |
| 39 | + } |
| 40 | + |
| 41 | + if commit := resolveCommitHash(); commit != "" { |
| 42 | + info["commit"] = shortCommit(commit) |
| 43 | + } |
| 44 | + if branch := resolveBranch(); branch != "" { |
| 45 | + info["branch"] = branch |
| 46 | + } |
| 47 | + |
| 48 | + if jsonFlag { |
| 49 | + enc := json.NewEncoder(os.Stdout) |
| 50 | + enc.SetIndent("", " ") |
| 51 | + enc.Encode(info) |
| 52 | + return |
| 53 | + } |
| 54 | + |
| 55 | + fmt.Printf("Gas Town v%s (%s)\n", Version, Build) |
| 56 | + if commit, ok := info["commit"].(string); ok { |
| 57 | + if branch, ok := info["branch"].(string); ok { |
| 58 | + fmt.Printf(" %s@%s\n", branch, commit) |
| 59 | + } else { |
| 60 | + fmt.Printf(" %s\n", commit) |
| 61 | + } |
| 62 | + } |
| 63 | + fmt.Println("\nUse 'gt info --whats-new' to see recent changes") |
| 64 | + }, |
| 65 | +} |
| 66 | + |
| 67 | +// VersionChange represents agent-relevant changes for a specific version |
| 68 | +type VersionChange struct { |
| 69 | + Version string `json:"version"` |
| 70 | + Date string `json:"date"` |
| 71 | + Changes []string `json:"changes"` |
| 72 | +} |
| 73 | + |
| 74 | +// versionChanges contains agent-actionable changes for recent versions |
| 75 | +var versionChanges = []VersionChange{ |
| 76 | + { |
| 77 | + Version: "0.2.0", |
| 78 | + Date: "2026-01-04", |
| 79 | + Changes: []string{ |
| 80 | + "NEW: Convoy Dashboard - Web UI for monitoring Gas Town (gt dashboard)", |
| 81 | + "NEW: Two-level beads architecture - hq-* prefix for town, rig prefixes for projects", |
| 82 | + "NEW: Multi-agent support with pluggable registry", |
| 83 | + "NEW: gt rig start/stop/restart/status - Multi-rig management commands", |
| 84 | + "NEW: Ephemeral polecat model - Immediate recycling after each work unit", |
| 85 | + "NEW: gt costs command - Session cost tracking and reporting", |
| 86 | + "NEW: Conflict resolution workflow for polecats with merge-slot gates", |
| 87 | + "NEW: gt convoy --tree and gt convoy check for cross-rig coordination", |
| 88 | + "NEW: Batch slinging - gt sling supports multiple beads at once", |
| 89 | + "NEW: spawn alias for start across all role subcommands", |
| 90 | + "NEW: gt mail archive supports multiple message IDs", |
| 91 | + "NEW: gt mail --all flag for clearing all mail", |
| 92 | + "NEW: Circuit breaker for stuck agents", |
| 93 | + "NEW: Binary age detection in gt status", |
| 94 | + "NEW: Shell completion installation instructions", |
| 95 | + "CHANGED: Handoff migrated to skills format", |
| 96 | + "CHANGED: Crew workers push directly to main (no PRs)", |
| 97 | + "CHANGED: Session names include town name", |
| 98 | + "FIX: Thread-safety for agent session resume", |
| 99 | + "FIX: Orphan daemon prevention via file locking", |
| 100 | + "FIX: Zombie tmux session cleanup", |
| 101 | + "FIX: Default branch detection (no longer hardcodes 'main')", |
| 102 | + "FIX: Enter key retry logic for reliable delivery", |
| 103 | + "FIX: Beads prefix routing for cross-rig operations", |
| 104 | + }, |
| 105 | + }, |
| 106 | + { |
| 107 | + Version: "0.1.1", |
| 108 | + Date: "2026-01-02", |
| 109 | + Changes: []string{ |
| 110 | + "FIX: Tmux keybindings scoped to Gas Town sessions only", |
| 111 | + "NEW: OSS project files - CHANGELOG.md, .golangci.yml, RELEASING.md", |
| 112 | + "NEW: Version bump script - scripts/bump-version.sh", |
| 113 | + "FIX: gt rig add and gt crew add CLI syntax documentation", |
| 114 | + "FIX: Rig prefix routing for agent beads", |
| 115 | + "FIX: Beads init targets correct database", |
| 116 | + }, |
| 117 | + }, |
| 118 | + { |
| 119 | + Version: "0.1.0", |
| 120 | + Date: "2026-01-02", |
| 121 | + Changes: []string{ |
| 122 | + "Initial public release of Gas Town", |
| 123 | + "NEW: Town structure - Hierarchical workspace with rigs, crews, and polecats", |
| 124 | + "NEW: Rig management - gt rig add/list/remove", |
| 125 | + "NEW: Crew workspaces - gt crew add for persistent developer workspaces", |
| 126 | + "NEW: Polecat workers - Transient agent workers managed by Witness", |
| 127 | + "NEW: Mayor - Global coordinator for cross-rig work", |
| 128 | + "NEW: Deacon - Town-level lifecycle patrol and heartbeat", |
| 129 | + "NEW: Witness - Per-rig polecat lifecycle manager", |
| 130 | + "NEW: Refinery - Merge queue processor with code review", |
| 131 | + "NEW: Convoy system - gt convoy create/list/status", |
| 132 | + "NEW: Sling workflow - gt sling <bead> <rig>", |
| 133 | + "NEW: Molecule workflows - Formula-based multi-step task execution", |
| 134 | + "NEW: Mail system - gt mail inbox/send/read", |
| 135 | + "NEW: Escalation protocol - gt escalate with severity levels", |
| 136 | + "NEW: Handoff mechanism - gt handoff for context-preserving session cycling", |
| 137 | + "NEW: Beads integration - Issue tracking via beads (bd commands)", |
| 138 | + "NEW: Tmux sessions with theming", |
| 139 | + "NEW: Status dashboard - gt status", |
| 140 | + "NEW: Activity feed - gt feed", |
| 141 | + "NEW: Nudge system - gt nudge for reliable message delivery", |
| 142 | + }, |
| 143 | + }, |
| 144 | +} |
| 145 | + |
| 146 | +// showWhatsNew displays agent-relevant changes from recent versions |
| 147 | +func showWhatsNew(jsonOutput bool) { |
| 148 | + if jsonOutput { |
| 149 | + enc := json.NewEncoder(os.Stdout) |
| 150 | + enc.SetIndent("", " ") |
| 151 | + enc.Encode(map[string]interface{}{ |
| 152 | + "current_version": Version, |
| 153 | + "recent_changes": versionChanges, |
| 154 | + }) |
| 155 | + return |
| 156 | + } |
| 157 | + |
| 158 | + // Human-readable output |
| 159 | + fmt.Printf("\nWhat's New in Gas Town (Current: v%s)\n", Version) |
| 160 | + fmt.Println(strings.Repeat("=", 50)) |
| 161 | + fmt.Println() |
| 162 | + |
| 163 | + for _, vc := range versionChanges { |
| 164 | + // Highlight if this is the current version |
| 165 | + versionMarker := "" |
| 166 | + if vc.Version == Version { |
| 167 | + versionMarker = " <- current" |
| 168 | + } |
| 169 | + |
| 170 | + fmt.Printf("## v%s (%s)%s\n\n", vc.Version, vc.Date, versionMarker) |
| 171 | + |
| 172 | + for _, change := range vc.Changes { |
| 173 | + fmt.Printf(" * %s\n", change) |
| 174 | + } |
| 175 | + fmt.Println() |
| 176 | + } |
| 177 | + |
| 178 | + fmt.Println("Tip: Use 'gt info --whats-new --json' for machine-readable output") |
| 179 | + fmt.Println() |
| 180 | +} |
| 181 | + |
| 182 | +func init() { |
| 183 | + infoCmd.Flags().Bool("whats-new", false, "Show agent-relevant changes from recent versions") |
| 184 | + infoCmd.Flags().Bool("json", false, "Output in JSON format") |
| 185 | + rootCmd.AddCommand(infoCmd) |
| 186 | +} |
0 commit comments