Files
gastown/internal/cmd/crew_status.go
Steve Yegge 9c3cc0255c refactor(cmd): split crew.go into focused modules
Break down 1184-line crew.go into 8 smaller, focused files:
- crew.go: command definitions, flags, init (229 lines)
- crew_helpers.go: shared utilities (235 lines)
- crew_lifecycle.go: remove/refresh/restart (219 lines)
- crew_status.go: status command (154 lines)
- crew_at.go: session attachment (142 lines)
- crew_maintenance.go: rename/pristine (121 lines)
- crew_list.go: list command (89 lines)
- crew_add.go: add command (74 lines)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 00:46:12 -08:00

155 lines
3.8 KiB
Go

package cmd
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/crew"
"github.com/steveyegge/gastown/internal/git"
"github.com/steveyegge/gastown/internal/mail"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/tmux"
)
// CrewStatusItem represents detailed status for a crew worker.
type CrewStatusItem struct {
Name string `json:"name"`
Rig string `json:"rig"`
Path string `json:"path"`
Branch string `json:"branch"`
HasSession bool `json:"has_session"`
SessionID string `json:"session_id,omitempty"`
GitClean bool `json:"git_clean"`
GitModified []string `json:"git_modified,omitempty"`
GitUntracked []string `json:"git_untracked,omitempty"`
MailTotal int `json:"mail_total"`
MailUnread int `json:"mail_unread"`
}
func runCrewStatus(cmd *cobra.Command, args []string) error {
crewMgr, r, err := getCrewManager(crewRig)
if err != nil {
return err
}
var workers []*crew.CrewWorker
if len(args) > 0 {
// Specific worker
name := args[0]
worker, err := crewMgr.Get(name)
if err != nil {
if err == crew.ErrCrewNotFound {
return fmt.Errorf("crew workspace '%s' not found", name)
}
return fmt.Errorf("getting crew worker: %w", err)
}
workers = []*crew.CrewWorker{worker}
} else {
// All workers
workers, err = crewMgr.List()
if err != nil {
return fmt.Errorf("listing crew workers: %w", err)
}
}
if len(workers) == 0 {
fmt.Println("No crew workspaces found.")
return nil
}
t := tmux.NewTmux()
var items []CrewStatusItem
for _, w := range workers {
sessionID := crewSessionName(r.Name, w.Name)
hasSession, _ := t.HasSession(sessionID)
// Git status
crewGit := git.NewGit(w.ClonePath)
gitStatus, _ := crewGit.Status()
branch, _ := crewGit.CurrentBranch()
gitClean := true
var modified, untracked []string
if gitStatus != nil {
gitClean = gitStatus.Clean
modified = append(gitStatus.Modified, gitStatus.Added...)
modified = append(modified, gitStatus.Deleted...)
untracked = gitStatus.Untracked
}
// Mail status
mailDir := filepath.Join(w.ClonePath, "mail")
mailTotal, mailUnread := 0, 0
if _, err := os.Stat(mailDir); err == nil {
mailbox := mail.NewMailbox(mailDir)
mailTotal, mailUnread, _ = mailbox.Count()
}
item := CrewStatusItem{
Name: w.Name,
Rig: r.Name,
Path: w.ClonePath,
Branch: branch,
HasSession: hasSession,
GitClean: gitClean,
GitModified: modified,
GitUntracked: untracked,
MailTotal: mailTotal,
MailUnread: mailUnread,
}
if hasSession {
item.SessionID = sessionID
}
items = append(items, item)
}
if crewJSON {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
return enc.Encode(items)
}
// Text output
for i, item := range items {
if i > 0 {
fmt.Println()
}
sessionStatus := style.Dim.Render("○ stopped")
if item.HasSession {
sessionStatus = style.Bold.Render("● running")
}
fmt.Printf("%s %s/%s\n", sessionStatus, item.Rig, item.Name)
fmt.Printf(" Path: %s\n", item.Path)
fmt.Printf(" Branch: %s\n", item.Branch)
if item.GitClean {
fmt.Printf(" Git: %s\n", style.Dim.Render("clean"))
} else {
fmt.Printf(" Git: %s\n", style.Bold.Render("dirty"))
if len(item.GitModified) > 0 {
fmt.Printf(" Modified: %s\n", strings.Join(item.GitModified, ", "))
}
if len(item.GitUntracked) > 0 {
fmt.Printf(" Untracked: %s\n", strings.Join(item.GitUntracked, ", "))
}
}
if item.MailUnread > 0 {
fmt.Printf(" Mail: %d unread / %d total\n", item.MailUnread, item.MailTotal)
} else {
fmt.Printf(" Mail: %s\n", style.Dim.Render(fmt.Sprintf("%d messages", item.MailTotal)))
}
}
return nil
}