Add Agent manager

Change-Id: Iaa68e9228165bd274f9c5be9d4320ef49a009ca8
diff --git a/server/tm/git_tm/git_task_manager.go b/server/tm/git_tm/git_task_manager.go
index b1aa39c..515fa51 100644
--- a/server/tm/git_tm/git_task_manager.go
+++ b/server/tm/git_tm/git_task_manager.go
@@ -21,10 +21,10 @@
 	DefaultFileMode = 0755
 	TaskFileMode    = 0644
 	TaskFileExt     = ".md"
-	
+
 	// Frontmatter constants
 	FrontmatterSeparator = "---\n"
-	
+
 	// Task ID format
 	TaskIDPrefix = "task-"
 )
@@ -230,8 +230,8 @@
 }
 
 // readTaskFile reads a task from a file
-func (gtm *GitTaskManager) readTaskFile(taskID string) (*tm.Task, error) {
-	filePath := filepath.Join(gtm.tasksDir, taskID+TaskFileExt)
+func (gtm *GitTaskManager) readTaskFile(taskFile string) (*tm.Task, error) {
+	filePath := filepath.Join(gtm.tasksDir, taskFile+TaskFileExt)
 
 	content, err := os.ReadFile(filePath)
 	if err != nil {
@@ -365,7 +365,7 @@
 func (gtm *GitTaskManager) UpdateTask(task *tm.Task) error {
 	// Set update time
 	task.UpdatedAt = time.Now()
-	
+
 	// Write task to file
 	return gtm.writeTaskFile(task)
 }
@@ -376,14 +376,12 @@
 	if err != nil {
 		return nil, err
 	}
-	
+
 	var tasks []*tm.Task
 	for _, taskFile := range taskFiles {
-		// Extract task ID from filename (task-{id}.md)
 		filename := filepath.Base(taskFile)
-		if strings.HasPrefix(filename, "task-") && strings.HasSuffix(filename, ".md") {
-			taskID := strings.TrimSuffix(strings.TrimPrefix(filename, "task-"), ".md")
-			task, err := gtm.readTaskFile(taskID)
+		if strings.HasPrefix(filename, "task-") {
+			task, err := gtm.readTaskFile(taskFile)
 			if err != nil {
 				gtm.logger.Warn("Failed to read task file", slog.String("file", taskFile), slog.String("error", err.Error()))
 				continue
@@ -391,7 +389,7 @@
 			tasks = append(tasks, task)
 		}
 	}
-	
+
 	return tasks, nil
 }
 
@@ -402,14 +400,14 @@
 	if err != nil {
 		return nil, err
 	}
-	
+
 	var assignedTasks []*tm.Task
 	for _, task := range tasks {
 		if task.Assignee == assignee {
 			assignedTasks = append(assignedTasks, task)
 		}
 	}
-	
+
 	return assignedTasks, nil
 }
 
@@ -419,11 +417,11 @@
 	if err != nil {
 		return err
 	}
-	
+
 	task.Status = tm.StatusArchived
 	now := time.Now()
 	task.ArchivedAt = &now
-	
+
 	return gtm.UpdateTask(task)
 }
 
@@ -529,14 +527,14 @@
 	if err != nil {
 		return nil, err
 	}
-	
+
 	task.Status = tm.StatusInProgress
-	
+
 	err = gtm.UpdateTask(task)
 	if err != nil {
 		return nil, err
 	}
-	
+
 	return task, nil
 }
 
@@ -546,16 +544,16 @@
 	if err != nil {
 		return nil, err
 	}
-	
+
 	task.Status = tm.StatusCompleted
 	now := time.Now()
 	task.CompletedAt = &now
-	
+
 	err = gtm.UpdateTask(task)
 	if err != nil {
 		return nil, err
 	}
-	
+
 	return task, nil
 }
 
diff --git a/server/tm/git_tm/git_task_manager_test.go b/server/tm/git_tm/git_task_manager_test.go
index 084200d..751ad89 100644
--- a/server/tm/git_tm/git_task_manager_test.go
+++ b/server/tm/git_tm/git_task_manager_test.go
@@ -509,17 +509,17 @@
 	// Get task and update fields
 	taskToUpdate, err := gtm.GetTask(originalTask.ID)
 	assert.NoError(t, err)
-	
+
 	taskToUpdate.Title = newTitle
 	taskToUpdate.Description = newDescription
 	taskToUpdate.Status = newStatus
 	taskToUpdate.Priority = newPriority
 	taskToUpdate.Owner.ID = newOwnerID
 	taskToUpdate.Owner.Name = newOwnerID
-	
+
 	err = gtm.UpdateTask(taskToUpdate)
 	assert.NoError(t, err)
-	
+
 	// Get updated task to verify
 	updatedTask, err := gtm.GetTask(originalTask.ID)
 	assert.NoError(t, err)
@@ -552,7 +552,7 @@
 
 	// Try to update non-existent task
 	fakeTask := &tm.Task{
-		ID: "non-existent-task",
+		ID:    "non-existent-task",
 		Title: "Updated Title",
 	}
 
@@ -636,7 +636,7 @@
 
 	err = gtm.UpdateTask(task)
 	assert.NoError(t, err)
-	
+
 	// Get updated task to verify
 	updatedTask, err := gtm.GetTask(task.ID)
 	assert.NoError(t, err)
@@ -644,14 +644,14 @@
 	assert.Equal(t, tm.StatusCompleted, updatedTask.Status)
 	assert.NotNil(t, updatedTask.CompletedAt)
 
-	// Test archiving a task  
+	// Test archiving a task
 	task.Status = tm.StatusArchived
 	now = time.Now()
 	task.ArchivedAt = &now
 
 	err = gtm.UpdateTask(task)
 	assert.NoError(t, err)
-	
+
 	// Get updated task to verify
 	updatedTask, err = gtm.GetTask(task.ID)
 	assert.NoError(t, err)
diff --git a/server/tm/interface.go b/server/tm/interface.go
index e3fa926..c505c65 100644
--- a/server/tm/interface.go
+++ b/server/tm/interface.go
@@ -8,8 +8,8 @@
 type TaskManager interface {
 	// Task operations
 	CreateTask(ctx context.Context, req *TaskCreateRequest) (*Task, error)
-	GetTask(taskID string) (*Task, error)                                    // Simplified for MVP
-	UpdateTask(task *Task) error                                             // Simplified for MVP
+	GetTask(taskID string) (*Task, error) // Simplified for MVP
+	UpdateTask(task *Task) error          // Simplified for MVP
 	ArchiveTask(ctx context.Context, id string) error
 	ListTasks(ctx context.Context, filter *TaskFilter, page, pageSize int) (*TaskList, error)
 
@@ -19,7 +19,7 @@
 
 	// Task queries
 	GetTasksByOwner(ctx context.Context, ownerID string, page, pageSize int) (*TaskList, error)
-	GetTasksByAssignee(assignee string) ([]*Task, error)                     // For MVP auto-assignment
+	GetTasksByAssignee(assignee string) ([]*Task, error) // For MVP auto-assignment
 	GetTasksByStatus(ctx context.Context, status TaskStatus, page, pageSize int) (*TaskList, error)
 	GetTasksByPriority(ctx context.Context, priority TaskPriority, page, pageSize int) (*TaskList, error)
 }
diff --git a/server/tm/types.go b/server/tm/types.go
index 052ba4a..5ff0567 100644
--- a/server/tm/types.go
+++ b/server/tm/types.go
@@ -9,10 +9,10 @@
 
 const (
 	StatusToDo       TaskStatus = "todo"
-	StatusPending    TaskStatus = "pending"    // For MVP compatibility
+	StatusPending    TaskStatus = "pending" // For MVP compatibility
 	StatusInProgress TaskStatus = "in_progress"
 	StatusCompleted  TaskStatus = "completed"
-	StatusFailed     TaskStatus = "failed"     // For error handling
+	StatusFailed     TaskStatus = "failed" // For error handling
 	StatusArchived   TaskStatus = "archived"
 )
 
@@ -37,10 +37,10 @@
 	Title          string       `json:"title"`
 	Description    string       `json:"description"`
 	Owner          Owner        `json:"owner"`
-	Assignee       string       `json:"assignee,omitempty"`       // For MVP auto-assignment
+	Assignee       string       `json:"assignee,omitempty"` // For MVP auto-assignment
 	Status         TaskStatus   `json:"status"`
 	Priority       TaskPriority `json:"priority"`
-	Solution       string       `json:"solution,omitempty"`       // Generated solution
+	Solution       string       `json:"solution,omitempty"`         // Generated solution
 	PullRequestURL string       `json:"pull_request_url,omitempty"` // GitHub PR URL
 	CreatedAt      time.Time    `json:"created_at"`
 	UpdatedAt      time.Time    `json:"updated_at"`