package commands import ( "fmt" "os" "sort" "strings" "git.dws.rip/DWS/onyx/internal/core" "git.dws.rip/DWS/onyx/internal/models" "github.com/spf13/cobra" ) // ANSI color codes const ( colorReset = "\033[0m" colorGreen = "\033[32m" colorYellow = "\033[33m" colorBlue = "\033[34m" colorGray = "\033[90m" colorBold = "\033[1m" ) // NewListCmd creates the list command func NewListCmd() *cobra.Command { var showAll bool cmd := &cobra.Command{ Use: "list", Short: "List all workstreams", Long: `List all workstreams in the repository. Shows the current workstream (marked with *), the number of commits in each workstream, and the workstream status. Status indicators: * active - Currently being worked on (green) * merged - Has been merged (gray) * abandoned - No longer being worked on (gray) * archived - Archived for historical purposes (gray)`, Aliases: []string{"ls"}, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { return runList(showAll) }, } cmd.Flags().BoolVarP(&showAll, "all", "a", false, "Show all workstreams including merged and archived") return cmd } // runList executes the list command func runList(showAll bool) error { // Get current directory cwd, err := os.Getwd() if err != nil { return fmt.Errorf("failed to get current directory: %w", err) } // Check if this is an Onyx repository if !core.IsOnyxRepo(cwd) { return fmt.Errorf("not an Onyx repository") } // Open the repository repo, err := core.Open(cwd) if err != nil { return fmt.Errorf("failed to open repository: %w", err) } defer repo.Close() // Create workstream manager wsManager := core.NewWorkstreamManager(repo) // Get all workstreams workstreams, err := wsManager.ListWorkstreams() if err != nil { return fmt.Errorf("failed to list workstreams: %w", err) } // Get current workstream name currentName, err := wsManager.GetCurrentWorkstreamName() if err != nil { currentName = "" // No current workstream } // Filter workstreams if not showing all var displayWorkstreams []*models.Workstream for _, ws := range workstreams { if showAll || ws.Status == models.WorkstreamStatusActive { displayWorkstreams = append(displayWorkstreams, ws) } } // Check if there are any workstreams if len(displayWorkstreams) == 0 { if showAll { fmt.Println("No workstreams found.") } else { fmt.Println("No active workstreams found.") fmt.Println("Use 'onx new ' to create a new workstream.") fmt.Println("Use 'onx list --all' to see all workstreams including merged and archived.") } return nil } // Sort workstreams by name for consistent output sort.Slice(displayWorkstreams, func(i, j int) bool { return displayWorkstreams[i].Name < displayWorkstreams[j].Name }) // Display workstreams fmt.Println("Workstreams:") for _, ws := range displayWorkstreams { displayWorkstream(ws, ws.Name == currentName) } // Show helpful footer fmt.Println() fmt.Printf("Use 'onx switch ' to switch to a different workstream\n") if !showAll { fmt.Printf("Use 'onx list --all' to see all workstreams\n") } return nil } // displayWorkstream displays a single workstream with formatting func displayWorkstream(ws *models.Workstream, isCurrent bool) { // Determine the indicator indicator := " " if isCurrent { indicator = "*" } // Determine the color based on status color := colorReset switch ws.Status { case models.WorkstreamStatusActive: color = colorGreen case models.WorkstreamStatusMerged: color = colorGray case models.WorkstreamStatusAbandoned: color = colorGray case models.WorkstreamStatusArchived: color = colorGray } // Format the output name := ws.Name if isCurrent { name = colorBold + name + colorReset } commitCount := ws.GetCommitCount() commitText := "commit" if commitCount != 1 { commitText = "commits" } // Build status string statusStr := string(ws.Status) if ws.Status != models.WorkstreamStatusActive { statusStr = colorGray + statusStr + colorReset } // Build the line line := fmt.Sprintf("%s %s%s%s", indicator, color, name, colorReset) // Add base branch info baseBranchInfo := fmt.Sprintf(" (based on %s)", ws.BaseBranch) line += colorGray + baseBranchInfo + colorReset // Add commit count commitInfo := fmt.Sprintf(" - %d %s", commitCount, commitText) line += commitInfo // Add status if not active if ws.Status != models.WorkstreamStatusActive { line += fmt.Sprintf(" [%s]", statusStr) } fmt.Println(line) // Add description if present if ws.Description != "" { description := strings.TrimSpace(ws.Description) fmt.Printf(" %s%s%s\n", colorGray, description, colorReset) } }