task: task-1753636924-a1d4c708 - created

Change-Id: Ic78528c47ae38114b9b7504f1c4a76f95e93eb13
diff --git a/server/cmd/commands/list_tasks.go b/server/cmd/commands/list_tasks.go
new file mode 100644
index 0000000..09cc20b
--- /dev/null
+++ b/server/cmd/commands/list_tasks.go
@@ -0,0 +1,109 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+	"strings"
+
+	"github.com/iomodo/staff/tm"
+	"github.com/spf13/cobra"
+)
+
+var listTasksCmd = &cobra.Command{
+	Use:   "list-tasks",
+	Short: "List all tasks",
+	Long: `List all tasks with optional filtering by status, priority, or assignee.
+
+Examples:
+  staff list-tasks
+  staff list-tasks --status todo
+  staff list-tasks --priority high
+  staff list-tasks --assignee backend-engineer`,
+	RunE: runListTasks,
+}
+
+var (
+	filterStatus   string
+	filterPriority string
+	filterAssignee string
+	pageSize       int = 20
+	pageNum        int = 0
+)
+
+func init() {
+	listTasksCmd.Flags().StringVar(&filterStatus, "status", "", "Filter by status (todo, in_progress, completed, archived)")
+	listTasksCmd.Flags().StringVar(&filterPriority, "priority", "", "Filter by priority (low, medium, high)")
+	listTasksCmd.Flags().StringVar(&filterAssignee, "assignee", "", "Filter by assignee")
+	listTasksCmd.Flags().IntVar(&pageSize, "page-size", 20, "Number of tasks per page")
+	listTasksCmd.Flags().IntVar(&pageNum, "page", 0, "Page number (0-based)")
+}
+
+func runListTasks(cmd *cobra.Command, args []string) error {
+	// Build filter
+	filter := &tm.TaskFilter{}
+	
+	if filterStatus != "" {
+		status := tm.TaskStatus(filterStatus)
+		filter.Status = &status
+	}
+	
+	if filterPriority != "" {
+		priority := tm.TaskPriority(filterPriority)
+		filter.Priority = &priority
+	}
+
+	// Get tasks
+	taskList, err := taskManager.ListTasks(context.Background(), filter, pageNum, pageSize)
+	if err != nil {
+		return fmt.Errorf("failed to list tasks: %w", err)
+	}
+
+	// Filter by assignee if specified (not in TaskFilter interface yet)
+	var filteredTasks []*tm.Task
+	if filterAssignee != "" {
+		for _, task := range taskList.Tasks {
+			if task.Assignee == filterAssignee {
+				filteredTasks = append(filteredTasks, task)
+			}
+		}
+	} else {
+		filteredTasks = taskList.Tasks
+	}
+
+	// Display results
+	if len(filteredTasks) == 0 {
+		fmt.Println("No tasks found")
+		return nil
+	}
+
+	fmt.Printf("Found %d tasks (page %d/%d)\n\n", len(filteredTasks), pageNum+1, (taskList.TotalCount+pageSize-1)/pageSize)
+
+	// Display tasks in table format
+	fmt.Printf("%-20s %-10s %-10s %-15s %-50s\n", "ID", "Status", "Priority", "Assignee", "Title")
+	fmt.Printf("%s\n", strings.Repeat("-", 110))
+
+	for _, task := range filteredTasks {
+		assignee := task.Assignee
+		if assignee == "" {
+			assignee = "unassigned"
+		}
+		
+		title := task.Title
+		if len(title) > 47 {
+			title = title[:47] + "..."
+		}
+
+		fmt.Printf("%-20s %-10s %-10s %-15s %-50s\n", 
+			task.ID, 
+			string(task.Status), 
+			string(task.Priority), 
+			assignee, 
+			title)
+	}
+
+	if taskList.HasMore {
+		fmt.Printf("\nUse --page %d to see more tasks\n", pageNum+1)
+	}
+
+	return nil
+}
\ No newline at end of file