diff --git a/server/agent/README.md b/server/agent/README.md
deleted file mode 100644
index 0015d90..0000000
--- a/server/agent/README.md
+++ /dev/null
@@ -1,298 +0,0 @@
-# Agent Package
-
-The `agent` package provides an AI agent system that can autonomously process tasks using LLM services, manage tasks through a task management system, and create pull requests with solutions.
-
-## Overview
-
-The agent system consists of:
-
-- **AI Agent**: Processes tasks using LLM services
-- **Task Manager**: Manages task lifecycle and assignment
-- **Git Integration**: Creates pull requests with solutions
-- **Infinite Loop**: Continuously processes assigned tasks
-
-## Features
-
-- **Autonomous Task Processing**: Agents automatically pick up and process assigned tasks
-- **LLM Integration**: Uses configurable LLM providers (OpenAI, Claude, etc.)
-- **Task Management**: Integrates with task management systems
-- **Git Operations**: Creates branches and pull requests for solutions
-- **Configurable Roles**: Different agents can have different roles and system prompts
-- **Error Handling**: Robust error handling with graceful recovery
-
-## Quick Start
-
-### 1. Basic Setup
-
-```go
-package main
-
-import (
-    "log"
-    "time"
-    
-    "github.com/iomodo/staff/agent"
-    "github.com/iomodo/staff/git"
-    "github.com/iomodo/staff/llm"
-    "github.com/iomodo/staff/tm"
-    "github.com/iomodo/staff/tm/git_tm"
-)
-
-func main() {
-    // Create git interface for task management
-    gitInterface := git.DefaultGit("./tasks-repo")
-    
-    // Create task manager
-    taskManager := git_tm.NewGitTaskManager(gitInterface, "./tasks-repo")
-
-    // Create LLM configuration
-    llmConfig := llm.Config{
-        Provider: llm.ProviderOpenAI,
-        APIKey:   "your-openai-api-key-here",
-        BaseURL:  "https://api.openai.com/v1",
-        Timeout:  30 * time.Second,
-    }
-
-    // Create agent configuration
-    config := agent.AgentConfig{
-        Name:        "backend-engineer-1",
-        Role:        "Backend Engineer",
-        GitUsername: "backend-agent",
-        GitEmail:    "backend-agent@company.com",
-        WorkingDir:  "./workspace",
-        LLMProvider: llm.ProviderOpenAI,
-        LLMModel:    "gpt-4",
-        LLMConfig:   llmConfig,
-        SystemPrompt: `You are a skilled backend engineer. Your role is to:
-1. Analyze tasks and provide technical solutions
-2. Write clean, maintainable code
-3. Consider performance, security, and scalability
-4. Provide clear documentation for your solutions
-5. Follow best practices and coding standards`,
-        TaskManager: taskManager,
-        GitRepoPath: "./code-repo",
-        GitRemote:   "origin",
-        GitBranch:   "main",
-    }
-
-    // Create agent
-    agent, err := agent.NewAgent(config)
-    if err != nil {
-        log.Fatalf("Failed to create agent: %v", err)
-    }
-
-    // Run the agent
-    if err := agent.Run(); err != nil {
-        log.Fatalf("Agent failed: %v", err)
-    }
-}
-```
-
-### 2. Create a Task
-
-```go
-// Create a task for the agent to process
-ctx := context.Background()
-task, err := taskManager.CreateTask(ctx, &tm.TaskCreateRequest{
-    Title:       "Implement user authentication API",
-    Description: "Create a REST API endpoint for user authentication with JWT tokens. Include login, logout, and token refresh functionality.",
-    OwnerID:     "backend-engineer-1", // Must match agent name
-    Priority:    tm.PriorityHigh,
-})
-if err != nil {
-    log.Fatalf("Failed to create task: %v", err)
-}
-```
-
-## Configuration
-
-### AgentConfig
-
-The `AgentConfig` struct contains all configuration for an agent:
-
-```go
-type AgentConfig struct {
-    Name        string        // Agent identifier
-    Role        string        // Agent role (e.g., "Backend Engineer")
-    GitUsername string        // Git username for commits
-    GitEmail    string        // Git email for commits
-    WorkingDir  string        // Working directory for files
-    
-    // LLM Configuration
-    LLMProvider llm.Provider  // LLM provider type
-    LLMModel    string        // Model name (e.g., "gpt-4")
-    LLMConfig   llm.Config    // LLM provider configuration
-    
-    // System prompt for the agent
-    SystemPrompt string       // Instructions for the LLM
-    
-    // Task Manager Configuration
-    TaskManager tm.TaskManager // Task management interface
-    
-    // Git Configuration
-    GitRepoPath string        // Path to git repository
-    GitRemote   string        // Remote name (usually "origin")
-    GitBranch   string        // Default branch name
-}
-```
-
-### System Prompts
-
-System prompts define the agent's behavior and expertise. Here are some examples:
-
-#### Backend Engineer
-```
-You are a skilled backend engineer. Your role is to:
-1. Analyze tasks and provide technical solutions
-2. Write clean, maintainable code
-3. Consider performance, security, and scalability
-4. Provide clear documentation for your solutions
-5. Follow best practices and coding standards
-
-When responding to tasks, provide:
-- Detailed technical analysis
-- Code examples where appropriate
-- Implementation considerations
-- Testing recommendations
-- Documentation suggestions
-```
-
-#### Frontend Engineer
-```
-You are a frontend engineer. Focus on:
-- User interface design and implementation
-- React/Vue/Angular development
-- Responsive design and accessibility
-- Performance optimization
-- User experience best practices
-```
-
-#### Product Manager
-```
-You are a product manager. Focus on:
-- Product strategy and roadmap
-- User research and requirements gathering
-- Feature prioritization and planning
-- Stakeholder communication
-- Product documentation and specifications
-```
-
-## How It Works
-
-### 1. Task Processing Loop
-
-The agent runs in an infinite loop that:
-
-1. **Fetches Tasks**: Gets tasks assigned to the agent from the task manager
-2. **Filters Tasks**: Looks for tasks with "todo" status
-3. **Starts Task**: Marks the task as "in progress"
-4. **Processes with LLM**: Sends task description to LLM for solution
-5. **Creates PR**: Creates a git branch and pull request with the solution
-6. **Completes Task**: Marks the task as completed
-
-### 2. Git Operations
-
-For each task, the agent:
-
-1. Creates a new branch: `task/{task-id}-{clean-title}`
-2. Writes solution to a markdown file
-3. Commits the solution
-4. Pushes the branch to create a pull request
-
-### 3. Solution Format
-
-Solutions are formatted as markdown files containing:
-
-- Task metadata (ID, title, agent info)
-- Original task description
-- LLM-generated solution
-- Timestamp and attribution
-
-## Multiple Agents
-
-You can run multiple agents with different roles:
-
-```go
-// Create agents with different roles
-agents := []agent.AgentConfig{
-    {
-        Name:        "backend-engineer-1",
-        Role:        "Backend Engineer",
-        // ... backend configuration
-    },
-    {
-        Name:        "frontend-engineer-1",
-        Role:        "Frontend Engineer",
-        // ... frontend configuration
-    },
-    {
-        Name:        "product-manager-1",
-        Role:        "Product Manager",
-        // ... product manager configuration
-    },
-}
-
-// Start all agents
-for _, config := range agents {
-    agent, err := agent.NewAgent(config)
-    if err != nil {
-        log.Printf("Failed to create agent %s: %v", config.Name, err)
-        continue
-    }
-
-    go func(agent *agent.Agent, name string) {
-        log.Printf("Starting agent: %s", name)
-        if err := agent.Run(); err != nil {
-            log.Printf("Agent %s stopped with error: %v", name, err)
-        }
-    }(agent, config.Name)
-}
-```
-
-## Error Handling
-
-The agent includes robust error handling:
-
-- **Configuration Validation**: Validates all required fields
-- **Graceful Recovery**: Continues running even if individual tasks fail
-- **Logging**: Comprehensive logging of all operations
-- **Resource Cleanup**: Proper cleanup of LLM connections
-
-## Testing
-
-Run the tests with:
-
-```bash
-go test ./server/agent/...
-```
-
-The test suite includes:
-
-- Configuration validation
-- Branch name generation
-- Task prompt building
-- Solution formatting
-- Error handling
-
-## Dependencies
-
-The agent package depends on:
-
-- `github.com/iomodo/staff/llm` - LLM service interface
-- `github.com/iomodo/staff/tm` - Task management interface
-- `github.com/iomodo/staff/git` - Git operations interface
-
-## Examples
-
-See `example.go` for complete working examples:
-
-- `ExampleAgent()` - Single agent setup
-- `ExampleMultipleAgents()` - Multiple agents with different roles
-
-## Best Practices
-
-1. **Unique Agent Names**: Ensure each agent has a unique name
-2. **Role-Specific Prompts**: Tailor system prompts to the agent's role
-3. **Task Assignment**: Assign tasks to agents by setting the `OwnerID` to the agent's name
-4. **Monitoring**: Monitor agent logs for errors and performance
-5. **Resource Management**: Ensure proper cleanup when stopping agents 
\ No newline at end of file
diff --git a/server/agent/agent.go b/server/agent/agent.go
new file mode 100644
index 0000000..fba80b7
--- /dev/null
+++ b/server/agent/agent.go
@@ -0,0 +1,239 @@
+package agent
+
+import (
+	"context"
+	"fmt"
+	"log/slog"
+	"os"
+	"time"
+
+	"github.com/iomodo/staff/config"
+	"github.com/iomodo/staff/llm"
+	"github.com/iomodo/staff/tm"
+)
+
+type Agent struct {
+	// Identity
+	Name string
+	Role string
+
+	// LLM Configuration
+	Model        string
+	SystemPrompt string
+	MaxTokens    *int
+	Temperature  *float64
+
+	// Runtime
+	Provider    llm.LLMProvider
+	CurrentTask *string // Task ID currently being processed
+
+	IsRunning bool
+	StopChan  chan struct{}
+
+	logger *slog.Logger
+
+	taskManager tm.TaskManager
+	thinker     *Thinker
+}
+
+func NewAgent(agentConfig config.AgentConfig, llmConfig llm.Config, taskManager tm.TaskManager, agentRoles []string, logger *slog.Logger) (*Agent, error) {
+	// Load system prompt
+	systemPrompt, err := loadSystemPrompt(agentConfig.SystemPromptFile)
+	if err != nil {
+		return nil, fmt.Errorf("failed to load system prompt: %w", err)
+	}
+
+	provider, err := llm.CreateProvider(llmConfig)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create LLM provider: %w", err)
+	}
+
+	thinker := NewThinker(provider, agentConfig.Model, systemPrompt, *agentConfig.MaxTokens, *agentConfig.Temperature, agentRoles, logger)
+
+	agent := &Agent{
+		Name:         agentConfig.Name,
+		Role:         agentConfig.Role,
+		Model:        agentConfig.Model,
+		SystemPrompt: systemPrompt,
+		Provider:     provider,
+		MaxTokens:    agentConfig.MaxTokens,
+		Temperature:  agentConfig.Temperature,
+		taskManager:  taskManager,
+		logger:       logger,
+		thinker:      thinker,
+	}
+
+	return agent, nil
+}
+
+// Start starts an agent to process tasks in a loop
+func (a *Agent) Start(loopInterval time.Duration) error {
+	if a.IsRunning {
+		return fmt.Errorf("agent %s is already running", a.Name)
+	}
+
+	a.IsRunning = true
+	a.StopChan = make(chan struct{})
+
+	go a.runLoop(loopInterval)
+
+	a.logger.Info("Started agent",
+		slog.String("name", a.Name),
+		slog.String("role", a.Role),
+		slog.String("model", a.Model))
+	return nil
+}
+
+func (a *Agent) Stop() {
+	close(a.StopChan)
+	a.IsRunning = false
+}
+
+func (a *Agent) runLoop(interval time.Duration) {
+	ticker := time.NewTicker(interval)
+	defer ticker.Stop()
+
+	for {
+		select {
+		case <-a.StopChan:
+			a.logger.Info("Agent stopping", slog.String("name", a.Name))
+			return
+		case <-ticker.C:
+			if err := a.processTasks(); err != nil {
+				a.logger.Error("Error processing tasks for agent",
+					slog.String("agent", a.Name),
+					slog.String("error", err.Error()))
+			}
+		}
+	}
+}
+
+// processAgentTasks processes all assigned tasks for an agent
+func (a *Agent) processTasks() error {
+	if a.CurrentTask != nil {
+		return nil
+	}
+
+	// Get tasks assigned to this agent
+	tasks, err := a.taskManager.GetTasksByAssignee(a.Name)
+	if err != nil {
+		return fmt.Errorf("failed to get tasks for agent %s: %w", a.Name, err)
+	}
+
+	a.logger.Info("Processing tasks for agent",
+		slog.Int("task_count", len(tasks)),
+		slog.String("agent", a.Name))
+
+	for _, task := range tasks {
+		if task.Status == tm.StatusToDo {
+			if err := a.processTask(task); err != nil {
+				a.logger.Error("Error processing task",
+					slog.String("task_id", task.ID),
+					slog.String("error", err.Error()))
+			}
+		}
+	}
+
+	return nil
+}
+
+// processTask processes a single task with an agent
+func (a *Agent) processTask(task *tm.Task) error {
+	ctx := context.Background()
+	startTime := time.Now()
+
+	a.logger.Info("Agent processing task",
+		slog.String("agent", a.Name),
+		slog.String("task_id", task.ID),
+		slog.String("title", task.Title))
+
+	// Mark task as in progress
+	task.Status = tm.StatusInProgress
+	a.CurrentTask = &task.ID
+
+	// Check if this task should generate subtasks (with LLM decision)
+	if a.thinker.ShouldGenerateSubtasks(task) {
+		err := a.processSubtask(ctx, task)
+		if err == nil {
+			a.logger.Info("Task converted to subtasks by agent using LLM analysis",
+				slog.String("task_id", task.ID),
+				slog.String("agent", a.Name))
+			return nil
+		}
+		a.logger.Error("Error processing subtask",
+			slog.String("task_id", task.ID),
+			slog.String("error", err.Error()))
+	}
+
+	err := a.processSolution(ctx, task)
+	if err != nil {
+		return fmt.Errorf("failed to process solution for task: %w", err)
+	}
+	duration := time.Since(startTime)
+	a.logger.Info("Task completed by agent",
+		slog.String("task_id", task.ID),
+		slog.String("agent", a.Name),
+		slog.Duration("duration", duration))
+	return nil
+}
+
+func (a *Agent) processSubtask(ctx context.Context, task *tm.Task) error {
+	a.logger.Info("LLM determined task should generate subtasks", slog.String("task_id", task.ID))
+	analysis, err := a.thinker.GenerateSubtasksForTask(ctx, task)
+	if err != nil {
+		return fmt.Errorf("failed to generate subtasks for task: %w", err)
+	}
+
+	solutionURL, err2 := a.taskManager.ProposeSubTasks(ctx, task, analysis)
+	if err2 != nil {
+		return fmt.Errorf("failed to propose subtasks for task: %w", err2)
+	}
+	task.SolutionURL = solutionURL
+
+	a.logger.Info("Generated subtask Solution for task",
+		slog.String("task_id", task.ID),
+		slog.String("solution_url", solutionURL))
+	a.logger.Info("Proposed subtasks and new agents for task",
+		slog.String("task_id", task.ID),
+		slog.Int("subtask_count", len(analysis.Subtasks)),
+		slog.Int("new_agent_count", len(analysis.AgentCreations)))
+
+	// Log proposed new agents if any
+	if len(analysis.AgentCreations) > 0 {
+		for _, agent := range analysis.AgentCreations {
+			a.logger.Info("Proposed new agent",
+				slog.String("role", agent.Role),
+				slog.Any("skills", agent.Skills))
+		}
+	}
+
+	return nil
+}
+
+func (a *Agent) processSolution(ctx context.Context, task *tm.Task) error {
+	solution, err := a.thinker.GenerateSolution(ctx, task)
+	if err != nil {
+		return fmt.Errorf("failed to generate solution: %w", err)
+	}
+
+	solutionURL, err := a.taskManager.ProposeSolution(ctx, task, solution, a.Name)
+	if err != nil {
+		return fmt.Errorf("failed to propose solution: %w", err)
+	}
+	task.SolutionURL = solutionURL
+
+	a.logger.Info("Generated Solution for task",
+		slog.String("task_id", task.ID),
+		slog.String("agent", a.Name),
+		slog.String("solution_url", solutionURL))
+	return nil
+}
+
+// loadSystemPrompt loads the system prompt from file
+func loadSystemPrompt(filePath string) (string, error) {
+	content, err := os.ReadFile(filePath)
+	if err != nil {
+		return "", fmt.Errorf("failed to read system prompt file %s: %w", filePath, err)
+	}
+	return string(content), nil
+}
diff --git a/server/agent/manager.go b/server/agent/manager.go
index 191d42e..ea7474d 100644
--- a/server/agent/manager.go
+++ b/server/agent/manager.go
@@ -1,17 +1,11 @@
 package agent
 
 import (
-	"context"
 	"fmt"
 	"log/slog"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"strings"
 	"time"
 
 	"github.com/iomodo/staff/config"
-	"github.com/iomodo/staff/git"
 	"github.com/iomodo/staff/llm"
 	_ "github.com/iomodo/staff/llm/providers" // Auto-register all providers
 	"github.com/iomodo/staff/task"
@@ -20,70 +14,31 @@
 
 // Manager manages multiple AI agents with Git operations and task processing
 type Manager struct {
-	config         *config.Config
-	agents         map[string]*Agent
-	taskManager    tm.TaskManager
-	autoAssigner   *task.AutoAssigner
-	prProvider     git.PullRequestProvider
-	cloneManager   *git.CloneManager
-	subtaskService *task.SubtaskService
-	isRunning      map[string]bool
-	stopChannels   map[string]chan struct{}
-	logger         *slog.Logger
+	config       *config.Config
+	agents       map[string]*Agent
+	taskManager  tm.TaskManager
+	autoAssigner *task.AutoAssigner
+	isRunning    map[string]bool
+	roles        []string
+	logger       *slog.Logger
 }
 
 // NewManager creates a new agent manager
 func NewManager(cfg *config.Config, taskManager tm.TaskManager, logger *slog.Logger) (*Manager, error) {
-	if logger == nil {
-		logger = slog.Default()
-	}
-	// Create auto-assigner
 	autoAssigner := task.NewAutoAssigner(cfg.Agents)
 
-	// Create PR provider based on configuration
-	var prProvider git.PullRequestProvider
-	var repoURL string
-
-	switch cfg.GetPrimaryGitProvider() {
-	case "github":
-		githubConfig := git.GitHubConfig{
-			Token:  cfg.GitHub.Token,
-			Logger: logger,
-		}
-		prProvider = git.NewGitHubPullRequestProvider(cfg.GitHub.Owner, cfg.GitHub.Repo, githubConfig)
-		repoURL = fmt.Sprintf("https://github.com/%s/%s.git", cfg.GitHub.Owner, cfg.GitHub.Repo)
-		logger.Info("Using GitHub as pull request provider",
-			slog.String("owner", cfg.GitHub.Owner),
-			slog.String("repo", cfg.GitHub.Repo))
-	case "gerrit":
-		gerritConfig := git.GerritConfig{
-			Username: cfg.Gerrit.Username,
-			Password: cfg.Gerrit.Password,
-			BaseURL:  cfg.Gerrit.BaseURL,
-			Logger:   logger,
-		}
-		prProvider = git.NewGerritPullRequestProvider(cfg.Gerrit.Project, gerritConfig)
-		repoURL = fmt.Sprintf("%s/%s", cfg.Gerrit.BaseURL, cfg.Gerrit.Project)
-		logger.Info("Using Gerrit as pull request provider",
-			slog.String("base_url", cfg.Gerrit.BaseURL),
-			slog.String("project", cfg.Gerrit.Project))
-	default:
-		return nil, fmt.Errorf("no valid Git provider configured")
+	agentRoles := make([]string, 0, len(cfg.Agents))
+	for _, agentConfig := range cfg.Agents {
+		agentRoles = append(agentRoles, agentConfig.Role)
 	}
 
-	// Create clone manager for per-agent Git repositories
-	workspacePath := filepath.Join(".", "workspace")
-	cloneManager := git.NewCloneManager(repoURL, workspacePath)
-
 	manager := &Manager{
 		config:       cfg,
 		agents:       make(map[string]*Agent),
 		taskManager:  taskManager,
 		autoAssigner: autoAssigner,
-		prProvider:   prProvider,
-		cloneManager: cloneManager,
 		isRunning:    make(map[string]bool),
-		stopChannels: make(map[string]chan struct{}),
+		roles:        agentRoles,
 		logger:       logger,
 	}
 
@@ -92,18 +47,19 @@
 		return nil, fmt.Errorf("failed to initialize agents: %w", err)
 	}
 
-	// Initialize subtask service after agents are created
-	if err := manager.initializeSubtaskService(); err != nil {
-		return nil, fmt.Errorf("failed to initialize subtask service: %w", err)
-	}
-
 	return manager, nil
 }
 
 // initializeAgents creates agent instances from configuration
 func (m *Manager) initializeAgents() error {
+	llmConfig := llm.Config{
+		Provider: llm.ProviderFake, // Use fake provider for testing
+		APIKey:   m.config.OpenAI.APIKey,
+		BaseURL:  m.config.OpenAI.BaseURL,
+		Timeout:  m.config.OpenAI.Timeout,
+	}
 	for _, agentConfig := range m.config.Agents {
-		agent, err := m.createAgent(agentConfig)
+		agent, err := NewAgent(agentConfig, llmConfig, m.taskManager, m.roles, m.logger)
 		if err != nil {
 			return fmt.Errorf("failed to create agent %s: %w", agentConfig.Name, err)
 		}
@@ -112,95 +68,25 @@
 	return nil
 }
 
-// initializeSubtaskService creates the subtask service with available agent roles
-func (m *Manager) initializeSubtaskService() error {
-	// Get agent roles from configuration
-	agentRoles := make([]string, 0, len(m.config.Agents))
-	for _, agentConfig := range m.config.Agents {
-		agentRoles = append(agentRoles, agentConfig.Name)
+func (m *Manager) StartAllAgents() {
+	// Start all configured agents with a default loop interval
+	defaultInterval := 1 * time.Second
+
+	for _, a := range m.agents {
+		m.logger.Info("Starting agent",
+			slog.String("name", a.Name),
+			slog.String("role", a.Role),
+			slog.String("model", a.Model))
+		if err := a.Start(defaultInterval); err != nil {
+			m.logger.Error("Failed to start agent",
+				slog.String("agent", a.Name),
+				slog.String("error", err.Error()))
+			continue
+		}
+		m.isRunning[a.Name] = true
 	}
-
-	// Use the first agent's LLM provider for subtask analysis
-	if len(m.agents) == 0 {
-		return fmt.Errorf("no agents available for subtask service")
-	}
-
-	var firstAgent *Agent
-	for _, agent := range m.agents {
-		firstAgent = agent
-		break
-	}
-
-	// Get owner and repo for subtask service based on provider
-	var owner, repo string
-	switch m.config.GetPrimaryGitProvider() {
-	case "github":
-		owner = m.config.GitHub.Owner
-		repo = m.config.GitHub.Repo
-	case "gerrit":
-		owner = m.config.Gerrit.Project
-		repo = m.config.Gerrit.Project
-	}
-
-	m.subtaskService = task.NewSubtaskService(
-		firstAgent.Provider,
-		m.taskManager,
-		agentRoles,
-		m.prProvider,
-		owner,
-		repo,
-		m.cloneManager,
-		m.logger,
-	)
-
-	return nil
 }
 
-// createAgent creates a single agent instance
-func (m *Manager) createAgent(agentConfig config.AgentConfig) (*Agent, error) {
-	// Load system prompt
-	systemPrompt, err := m.loadSystemPrompt(agentConfig.SystemPromptFile)
-	if err != nil {
-		return nil, fmt.Errorf("failed to load system prompt: %w", err)
-	}
-
-	// Create LLM provider
-	llmConfig := llm.Config{
-		Provider: llm.ProviderFake, // Use fake provider for testing
-		APIKey:   m.config.OpenAI.APIKey,
-		BaseURL:  m.config.OpenAI.BaseURL,
-		Timeout:  m.config.OpenAI.Timeout,
-	}
-
-	provider, err := llm.CreateProvider(llmConfig)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create LLM provider: %w", err)
-	}
-
-	agent := &Agent{
-		Name:         agentConfig.Name,
-		Role:         agentConfig.Role,
-		Model:        agentConfig.Model,
-		SystemPrompt: systemPrompt,
-		Provider:     provider,
-		MaxTokens:    agentConfig.MaxTokens,
-		Temperature:  agentConfig.Temperature,
-		Stats:        AgentStats{},
-	}
-
-	return agent, nil
-}
-
-// loadSystemPrompt loads the system prompt from file
-func (m *Manager) loadSystemPrompt(filePath string) (string, error) {
-	content, err := os.ReadFile(filePath)
-	if err != nil {
-		return "", fmt.Errorf("failed to read system prompt file %s: %w", filePath, err)
-	}
-	return string(content), nil
-}
-
-// StartAgent starts an agent to process tasks in a loop
 func (m *Manager) StartAgent(agentName string, loopInterval time.Duration) error {
 	agent, exists := m.agents[agentName]
 	if !exists {
@@ -211,409 +97,28 @@
 		return fmt.Errorf("agent %s is already running", agentName)
 	}
 
-	stopChan := make(chan struct{})
-	m.stopChannels[agentName] = stopChan
+	agent.Start(loopInterval)
 	m.isRunning[agentName] = true
-
-	go m.runAgentLoop(agent, loopInterval, stopChan)
-
-	m.logger.Info("Started agent",
-		slog.String("name", agentName),
-		slog.String("role", agent.Role),
-		slog.String("model", agent.Model))
 	return nil
 }
 
 // StopAgent stops a running agent
 func (m *Manager) StopAgent(agentName string) error {
+	agent, exists := m.agents[agentName]
+	if !exists {
+		return fmt.Errorf("agent %s not found", agentName)
+	}
 	if !m.isRunning[agentName] {
 		return fmt.Errorf("agent %s is not running", agentName)
 	}
 
-	close(m.stopChannels[agentName])
-	delete(m.stopChannels, agentName)
+	agent.Stop()
 	m.isRunning[agentName] = false
 
 	m.logger.Info("Stopped agent", slog.String("name", agentName))
 	return nil
 }
 
-// runAgentLoop runs the main processing loop for an agent
-func (m *Manager) runAgentLoop(agent *Agent, interval time.Duration, stopChan <-chan struct{}) {
-	ticker := time.NewTicker(interval)
-	defer ticker.Stop()
-
-	for {
-		select {
-		case <-stopChan:
-			m.logger.Info("Agent stopping", slog.String("name", agent.Name))
-			return
-		case <-ticker.C:
-			if err := m.processAgentTasks(agent); err != nil {
-				m.logger.Error("Error processing tasks for agent",
-					slog.String("agent", agent.Name),
-					slog.String("error", err.Error()))
-			}
-		}
-	}
-}
-
-// processAgentTasks processes all assigned tasks for an agent
-func (m *Manager) processAgentTasks(agent *Agent) error {
-	if agent.CurrentTask != nil {
-		return nil
-	}
-
-	// Get tasks assigned to this agent
-	tasks, err := m.taskManager.GetTasksByAssignee(agent.Name)
-	if err != nil {
-		return fmt.Errorf("failed to get tasks for agent %s: %w", agent.Name, err)
-	}
-
-	m.logger.Info("Processing tasks for agent",
-		slog.Int("task_count", len(tasks)),
-		slog.String("agent", agent.Name))
-
-	for _, task := range tasks {
-		if task.Status == tm.StatusToDo {
-			if err := m.processTask(agent, task); err != nil {
-				m.logger.Error("Error processing task",
-					slog.String("task_id", task.ID),
-					slog.String("error", err.Error()))
-				// Mark task as failed
-				task.Status = tm.StatusFailed
-				if err := m.taskManager.UpdateTask(task); err != nil {
-					m.logger.Error("Error updating failed task",
-						slog.String("task_id", task.ID),
-						slog.String("error", err.Error()))
-				}
-				agent.Stats.TasksFailed++
-			} else {
-				agent.Stats.TasksCompleted++
-			}
-			// Update success rate
-			total := agent.Stats.TasksCompleted + agent.Stats.TasksFailed
-			if total > 0 {
-				agent.Stats.SuccessRate = float64(agent.Stats.TasksCompleted) / float64(total) * 100
-			}
-		}
-	}
-
-	return nil
-}
-
-// processTask processes a single task with an agent
-func (m *Manager) processTask(agent *Agent, task *tm.Task) error {
-	ctx := context.Background()
-	startTime := time.Now()
-
-	m.logger.Info("Agent processing task",
-		slog.String("agent", agent.Name),
-		slog.String("task_id", task.ID),
-		slog.String("title", task.Title))
-
-	// Mark task as in progress
-	task.Status = tm.StatusInProgress
-	agent.CurrentTask = &task.ID
-
-	// Check if this task should generate subtasks (with LLM decision)
-	if m.shouldGenerateSubtasks(task) {
-		m.logger.Info("LLM determined task should generate subtasks", slog.String("task_id", task.ID))
-		if err := m.generateSubtasksForTask(ctx, task); err != nil {
-			m.logger.Warn("Failed to generate subtasks for task",
-				slog.String("task_id", task.ID),
-				slog.String("error", err.Error()))
-		} else {
-			m.logger.Info("Task converted to subtasks by agent using LLM analysis",
-				slog.String("task_id", task.ID),
-				slog.String("agent", agent.Name))
-			return nil
-		}
-	}
-
-	// Generate solution using LLM
-	solution, err := m.generateSolution(ctx, agent, task)
-	if err != nil {
-		return fmt.Errorf("failed to generate solution: %w", err)
-	}
-
-	// Create Git branch and commit solution
-	branchName := m.generateBranchName(task)
-	if err := m.createAndCommitSolution(branchName, task, solution, agent); err != nil {
-		return fmt.Errorf("failed to commit solution: %w", err)
-	}
-
-	// Create pull request
-	prURL, err := m.createPullRequest(ctx, task, solution, agent, branchName)
-	if err != nil {
-		return fmt.Errorf("failed to create pull request: %w", err)
-	}
-
-	// Update agent stats
-	duration := time.Since(startTime)
-	if agent.Stats.AvgTime == 0 {
-		agent.Stats.AvgTime = duration.Milliseconds()
-	} else {
-		agent.Stats.AvgTime = (agent.Stats.AvgTime + duration.Milliseconds()) / 2
-	}
-
-	m.logger.Info("Task completed by agent",
-		slog.String("task_id", task.ID),
-		slog.String("agent", agent.Name),
-		slog.Duration("duration", duration),
-		slog.String("pr_url", prURL))
-	return nil
-}
-
-// generateSolution uses the agent's LLM to generate a solution
-func (m *Manager) generateSolution(ctx context.Context, agent *Agent, task *tm.Task) (string, error) {
-	prompt := m.buildTaskPrompt(task)
-
-	req := llm.ChatCompletionRequest{
-		Model: agent.Model,
-		Messages: []llm.Message{
-			{
-				Role:    llm.RoleSystem,
-				Content: agent.SystemPrompt,
-			},
-			{
-				Role:    llm.RoleUser,
-				Content: prompt,
-			},
-		},
-		MaxTokens:   agent.MaxTokens,
-		Temperature: agent.Temperature,
-	}
-
-	resp, err := agent.Provider.ChatCompletion(ctx, req)
-	if err != nil {
-		return "", fmt.Errorf("LLM request failed: %w", err)
-	}
-
-	if len(resp.Choices) == 0 {
-		return "", fmt.Errorf("no response from LLM")
-	}
-
-	return resp.Choices[0].Message.Content, nil
-}
-
-// buildTaskPrompt creates a detailed prompt for the LLM
-func (m *Manager) buildTaskPrompt(task *tm.Task) string {
-	return fmt.Sprintf(`Task: %s
-
-Priority: %s
-Description: %s
-
-Please provide a complete solution for this task. Include:
-1. Detailed implementation plan
-2. Code changes needed (if applicable)
-3. Files to be created or modified
-4. Testing considerations
-5. Any dependencies or prerequisites
-
-Your response should be comprehensive and actionable.`,
-		task.Title,
-		task.Priority,
-		task.Description)
-}
-
-// generateBranchName creates a Git branch name for the task
-func (m *Manager) generateBranchName(task *tm.Task) string {
-	// Clean title for use in branch name
-	cleanTitle := strings.ToLower(task.Title)
-	cleanTitle = strings.ReplaceAll(cleanTitle, " ", "-")
-	cleanTitle = strings.ReplaceAll(cleanTitle, "/", "-")
-	// Remove special characters
-	var result strings.Builder
-	for _, r := range cleanTitle {
-		if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '-' {
-			result.WriteRune(r)
-		}
-	}
-	cleanTitle = result.String()
-
-	// Limit length
-	if len(cleanTitle) > 40 {
-		cleanTitle = cleanTitle[:40]
-	}
-
-	return fmt.Sprintf("%s%s-%s", m.config.Git.BranchPrefix, task.ID, cleanTitle)
-}
-
-// createAndCommitSolution creates a Git branch and commits the solution using per-agent clones
-func (m *Manager) createAndCommitSolution(branchName string, task *tm.Task, solution string, agent *Agent) error {
-	ctx := context.Background()
-
-	// Get agent's dedicated Git clone
-	clonePath, err := m.cloneManager.GetAgentClonePath(agent.Name)
-	if err != nil {
-		return fmt.Errorf("failed to get agent clone: %w", err)
-	}
-
-	m.logger.Info("Agent working in clone",
-		slog.String("agent", agent.Name),
-		slog.String("clone_path", clonePath))
-
-	// Refresh the clone with latest changes
-	if err := m.cloneManager.RefreshAgentClone(agent.Name); err != nil {
-		m.logger.Warn("Failed to refresh clone for agent",
-			slog.String("agent", agent.Name),
-			slog.String("error", err.Error()))
-	}
-
-	// All Git operations use the agent's clone directory
-	gitCmd := func(args ...string) *exec.Cmd {
-		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
-	}
-
-	// Ensure we're on main branch before creating new branch
-	cmd := gitCmd("checkout", "main")
-	if err := cmd.Run(); err != nil {
-		// Try master branch if main doesn't exist
-		cmd = gitCmd("checkout", "master")
-		if err := cmd.Run(); err != nil {
-			return fmt.Errorf("failed to checkout main/master branch: %w", err)
-		}
-	}
-
-	// Create branch
-	cmd = gitCmd("checkout", "-b", branchName)
-	if err := cmd.Run(); err != nil {
-		return fmt.Errorf("failed to create branch: %w", err)
-	}
-
-	// Create solution file in agent's clone
-	solutionDir := filepath.Join(clonePath, "tasks", "solutions")
-	if err := os.MkdirAll(solutionDir, 0755); err != nil {
-		return fmt.Errorf("failed to create solution directory: %w", err)
-	}
-
-	solutionFile := filepath.Join(solutionDir, fmt.Sprintf("%s-solution.md", task.ID))
-	solutionContent := fmt.Sprintf(`# Solution for Task: %s
-
-**Agent:** %s (%s)  
-**Model:** %s  
-**Completed:** %s
-
-## Task Description
-%s
-
-## Solution
-%s
-
----
-*Generated by Staff AI Agent System*
-`, task.Title, agent.Name, agent.Role, agent.Model, time.Now().Format(time.RFC3339), task.Description, solution)
-
-	if err := os.WriteFile(solutionFile, []byte(solutionContent), 0644); err != nil {
-		return fmt.Errorf("failed to write solution file: %w", err)
-	}
-
-	// Stage files
-	relativeSolutionFile := filepath.Join("tasks", "solutions", fmt.Sprintf("%s-solution.md", task.ID))
-	cmd = gitCmd("add", relativeSolutionFile)
-	if err := cmd.Run(); err != nil {
-		return fmt.Errorf("failed to stage files: %w", err)
-	}
-
-	// Commit changes
-	commitMsg := m.buildCommitMessage(task, agent)
-	cmd = gitCmd("commit", "-m", commitMsg)
-	if err := cmd.Run(); err != nil {
-		return fmt.Errorf("failed to commit: %w", err)
-	}
-
-	// Push branch
-	cmd = gitCmd("push", "-u", "origin", branchName)
-	if err := cmd.Run(); err != nil {
-		return fmt.Errorf("failed to push branch: %w", err)
-	}
-
-	m.logger.Info("Agent successfully pushed branch",
-		slog.String("agent", agent.Name),
-		slog.String("branch", branchName))
-	return nil
-}
-
-// buildCommitMessage creates a commit message from template
-func (m *Manager) buildCommitMessage(task *tm.Task, agent *Agent) string {
-	template := m.config.Git.CommitMessageTemplate
-
-	replacements := map[string]string{
-		"{task_id}":    task.ID,
-		"{task_title}": task.Title,
-		"{agent_name}": agent.Name,
-		"{solution}":   "See solution file for details",
-	}
-
-	result := template
-	for placeholder, value := range replacements {
-		result = strings.ReplaceAll(result, placeholder, value)
-	}
-
-	return result
-}
-
-// createPullRequest creates a GitHub pull request
-func (m *Manager) createPullRequest(ctx context.Context, task *tm.Task, solution string, agent *Agent, branchName string) (string, error) {
-	title := fmt.Sprintf("Task %s: %s", task.ID, task.Title)
-
-	// Build PR description from template
-	description := m.buildPRDescription(task, solution, agent)
-
-	options := git.PullRequestOptions{
-		Title:       title,
-		Description: description,
-		HeadBranch:  branchName,
-		BaseBranch:  "main",
-		Labels:      []string{"ai-generated", "staff-agent", strings.ToLower(agent.Role)},
-		Draft:       false,
-	}
-
-	pr, err := m.prProvider.CreatePullRequest(ctx, options)
-	if err != nil {
-		return "", fmt.Errorf("failed to create PR: %w", err)
-	}
-
-	// Generate provider-specific PR URL
-	switch m.config.GetPrimaryGitProvider() {
-	case "github":
-		return fmt.Sprintf("https://github.com/%s/%s/pull/%d", m.config.GitHub.Owner, m.config.GitHub.Repo, pr.Number), nil
-	case "gerrit":
-		return fmt.Sprintf("%s/c/%s/+/%d", m.config.Gerrit.BaseURL, m.config.Gerrit.Project, pr.Number), nil
-	default:
-		return "", fmt.Errorf("unknown git provider")
-	}
-}
-
-// buildPRDescription creates PR description from template
-func (m *Manager) buildPRDescription(task *tm.Task, solution string, agent *Agent) string {
-	template := m.config.Git.PRTemplate
-
-	// Truncate solution for PR if too long
-	truncatedSolution := solution
-	if len(solution) > 1000 {
-		truncatedSolution = solution[:1000] + "...\n\n*See solution file for complete details*"
-	}
-
-	replacements := map[string]string{
-		"{task_id}":          task.ID,
-		"{task_title}":       task.Title,
-		"{task_description}": task.Description,
-		"{agent_name}":       fmt.Sprintf("%s (%s)", agent.Name, agent.Role),
-		"{priority}":         string(task.Priority),
-		"{solution}":         truncatedSolution,
-		"{files_changed}":    fmt.Sprintf("- `tasks/solutions/%s-solution.md`", task.ID),
-	}
-
-	result := template
-	for placeholder, value := range replacements {
-		result = strings.ReplaceAll(result, placeholder, value)
-	}
-
-	return result
-}
-
 // AutoAssignTask automatically assigns a task to the best matching agent
 func (m *Manager) AutoAssignTask(taskID string) error {
 	task, err := m.taskManager.GetTask(taskID)
@@ -640,108 +145,6 @@
 	return nil
 }
 
-// GetAgentStatus returns the status of all agents
-func (m *Manager) GetAgentStatus() map[string]AgentInfo {
-	status := make(map[string]AgentInfo)
-
-	for name, agent := range m.agents {
-		agentStatus := StatusIdle
-		if m.isRunning[name] {
-			if agent.CurrentTask != nil {
-				agentStatus = StatusRunning
-			}
-		} else {
-			agentStatus = StatusStopped
-		}
-
-		status[name] = AgentInfo{
-			Name:        agent.Name,
-			Role:        agent.Role,
-			Model:       agent.Model,
-			Status:      agentStatus,
-			CurrentTask: agent.CurrentTask,
-			Stats:       agent.Stats,
-		}
-	}
-
-	return status
-}
-
-// shouldGenerateSubtasks determines if a task should be broken down into subtasks using LLM
-func (m *Manager) shouldGenerateSubtasks(task *tm.Task) bool {
-	// Don't generate subtasks for subtasks
-	if task.ParentTaskID != "" {
-		return false
-	}
-
-	// Don't generate if already evaluated
-	if task.SubtasksEvaluated {
-		return false
-	}
-
-	// Ask LLM to decide
-	ctx := context.Background()
-	decision, err := m.subtaskService.ShouldGenerateSubtasks(ctx, task)
-	if err != nil {
-		m.logger.Warn("Failed to get LLM subtask decision for task",
-			slog.String("task_id", task.ID),
-			slog.String("error", err.Error()))
-		// Fallback to simple heuristics
-		return task.Priority == tm.PriorityHigh || len(task.Description) > 200
-	}
-
-	task.SubtasksEvaluated = true
-	m.logger.Info("LLM subtask decision for task",
-		slog.String("task_id", task.ID),
-		slog.Bool("needs_subtasks", decision.NeedsSubtasks),
-		slog.Int("complexity_score", decision.ComplexityScore),
-		slog.String("reasoning", decision.Reasoning))
-
-	return decision.NeedsSubtasks
-}
-
-// generateSubtasksForTask analyzes a task and creates a PR with proposed subtasks
-func (m *Manager) generateSubtasksForTask(ctx context.Context, task *tm.Task) error {
-	if m.subtaskService == nil {
-		return fmt.Errorf("subtask service not initialized")
-	}
-
-	// Analyze the task for subtasks
-	analysis, err := m.subtaskService.AnalyzeTaskForSubtasks(ctx, task)
-	if err != nil {
-		return fmt.Errorf("failed to analyze task for subtasks: %w", err)
-	}
-
-	// Generate a PR with the subtask proposals
-	prURL, err := m.subtaskService.GenerateSubtaskPR(ctx, analysis)
-	if err != nil {
-		return fmt.Errorf("failed to generate subtask PR: %w", err)
-	}
-
-	// Update the task with subtask information
-	task.SubtasksPRURL = prURL
-	task.SubtasksGenerated = true
-
-	m.logger.Info("Generated subtask PR for task",
-		slog.String("task_id", task.ID),
-		slog.String("pr_url", prURL))
-	m.logger.Info("Proposed subtasks and new agents for task",
-		slog.String("task_id", task.ID),
-		slog.Int("subtask_count", len(analysis.Subtasks)),
-		slog.Int("new_agent_count", len(analysis.AgentCreations)))
-
-	// Log proposed new agents if any
-	if len(analysis.AgentCreations) > 0 {
-		for _, agent := range analysis.AgentCreations {
-			m.logger.Info("Proposed new agent",
-				slog.String("role", agent.Role),
-				slog.Any("skills", agent.Skills))
-		}
-	}
-
-	return nil
-}
-
 // IsAgentRunning checks if an agent is currently running
 func (m *Manager) IsAgentRunning(agentName string) bool {
 	return m.isRunning[agentName]
@@ -764,18 +167,5 @@
 				slog.String("error", err.Error()))
 		}
 	}
-
-	// Cleanup all agent Git clones
-	if err := m.cloneManager.CleanupAllClones(); err != nil {
-		m.logger.Error("Error cleaning up agent clones", slog.String("error", err.Error()))
-	}
-
-	// Cleanup subtask service
-	if m.subtaskService != nil {
-		if err := m.subtaskService.Close(); err != nil {
-			m.logger.Error("Error closing subtask service", slog.String("error", err.Error()))
-		}
-	}
-
 	return nil
 }
diff --git a/server/agent/thinker.go b/server/agent/thinker.go
new file mode 100644
index 0000000..8e70230
--- /dev/null
+++ b/server/agent/thinker.go
@@ -0,0 +1,522 @@
+package agent
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"log/slog"
+	"strings"
+
+	"github.com/iomodo/staff/llm"
+	"github.com/iomodo/staff/tm"
+	"golang.org/x/text/cases"
+	"golang.org/x/text/language"
+)
+
+type Thinker struct {
+	roles        []string
+	llmProvider  llm.LLMProvider
+	model        string // TODO: abstract away in llmProvider
+	systemPrompt string // TODO abstract away in llmProvider
+	maxTokens    int
+	temperature  float64
+	logger       *slog.Logger
+}
+
+func NewThinker(llmProvider llm.LLMProvider, model string, systemPrompt string, maxTokens int, temperature float64, roles []string, logger *slog.Logger) *Thinker {
+	return &Thinker{llmProvider: llmProvider, model: model, maxTokens: maxTokens, temperature: temperature, roles: roles, logger: logger}
+}
+
+// shouldGenerateSubtasks determines if a task should be broken down into subtasks using LLM
+func (t *Thinker) ShouldGenerateSubtasks(task *tm.Task) bool {
+	// Don't generate subtasks for subtasks
+	if task.ParentTaskID != "" {
+		return false
+	}
+
+	// Don't generate if already evaluated
+	if task.SubtasksEvaluated {
+		return false
+	}
+
+	// Ask LLM to decide
+	ctx := context.Background()
+	decision, err := t.shouldGenerateSubtasks(ctx, task)
+	if err != nil {
+		t.logger.Warn("Failed to get LLM subtask decision for task",
+			slog.String("task_id", task.ID),
+			slog.String("error", err.Error()))
+		// Fallback to simple heuristics
+		return task.Priority == tm.PriorityHigh || len(task.Description) > 200
+	}
+
+	task.SubtasksEvaluated = true
+	t.logger.Info("LLM subtask decision for task",
+		slog.String("task_id", task.ID),
+		slog.Bool("needs_subtasks", decision.NeedsSubtasks),
+		slog.Int("complexity_score", decision.ComplexityScore),
+		slog.String("reasoning", decision.Reasoning))
+
+	return decision.NeedsSubtasks
+}
+
+// AnalyzeTaskForSubtasks uses LLM to analyze a task and propose subtasks
+func (t *Thinker) GenerateSubtasksForTask(ctx context.Context, task *tm.Task) (*tm.SubtaskAnalysis, error) {
+	prompt := buildSubtaskAnalysisPrompt(task)
+
+	req := llm.ChatCompletionRequest{
+		Model: t.model,
+		Messages: []llm.Message{
+			{
+				Role:    llm.RoleSystem,
+				Content: getSubtaskAnalysisSystemPrompt(t.roles),
+			},
+			{
+				Role:    llm.RoleUser,
+				Content: prompt,
+			},
+		},
+		MaxTokens:   &[]int{4000}[0],
+		Temperature: &[]float64{0.3}[0],
+	}
+
+	resp, err := t.llmProvider.ChatCompletion(ctx, req)
+	if err != nil {
+		return nil, fmt.Errorf("LLM analysis failed: %w", err)
+	}
+
+	if len(resp.Choices) == 0 {
+		return nil, fmt.Errorf("no response from LLM")
+	}
+
+	// Parse the LLM response
+	analysis, err := parseSubtaskAnalysis(resp.Choices[0].Message.Content, task.ID, t.roles, t.logger)
+	if err != nil {
+		return nil, fmt.Errorf("failed to parse LLM response: %w", err)
+	}
+
+	return analysis, nil
+}
+
+// generateSolution uses the agent's LLM to generate a solution
+func (t *Thinker) GenerateSolution(ctx context.Context, task *tm.Task) (string, error) {
+	prompt := buildTaskPrompt(task)
+
+	req := llm.ChatCompletionRequest{
+		Model: t.model,
+		Messages: []llm.Message{
+			{
+				Role:    llm.RoleSystem,
+				Content: t.systemPrompt,
+			},
+			{
+				Role:    llm.RoleUser,
+				Content: prompt,
+			},
+		},
+		MaxTokens:   &t.maxTokens,
+		Temperature: &t.temperature,
+	}
+
+	resp, err := t.llmProvider.ChatCompletion(ctx, req)
+	if err != nil {
+		return "", fmt.Errorf("LLM request failed: %w", err)
+	}
+
+	if len(resp.Choices) == 0 {
+		return "", fmt.Errorf("no response from LLM")
+	}
+
+	return resp.Choices[0].Message.Content, nil
+}
+
+// ShouldGenerateSubtasks asks LLM whether a task needs subtasks based on existing agents
+func (t *Thinker) shouldGenerateSubtasks(ctx context.Context, task *tm.Task) (*tm.SubtaskDecision, error) {
+	prompt := buildSubtaskDecisionPrompt(task)
+
+	req := llm.ChatCompletionRequest{
+		Model: t.model,
+		Messages: []llm.Message{
+			{
+				Role:    llm.RoleSystem,
+				Content: getSubtaskDecisionSystemPrompt(t.roles),
+			},
+			{
+				Role:    llm.RoleUser,
+				Content: prompt,
+			},
+		},
+		MaxTokens:   &[]int{1000}[0],
+		Temperature: &[]float64{0.3}[0],
+	}
+
+	resp, err := t.llmProvider.ChatCompletion(ctx, req)
+	if err != nil {
+		return nil, fmt.Errorf("LLM decision failed: %w", err)
+	}
+
+	if len(resp.Choices) == 0 {
+		return nil, fmt.Errorf("no response from LLM")
+	}
+
+	// Parse the LLM response
+	decision, err := parseSubtaskDecision(resp.Choices[0].Message.Content)
+	if err != nil {
+		return nil, fmt.Errorf("failed to parse LLM decision: %w", err)
+	}
+
+	return decision, nil
+}
+
+func buildSubtaskDecisionPrompt(task *tm.Task) string {
+	return fmt.Sprintf(`Please evaluate whether the following task needs to be broken down into subtasks:
+
+**Task Title:** %s
+
+**Description:** %s
+
+**Priority:** %s
+
+**Current Status:** %s
+
+Consider:
+- Can this be completed by a single agent with existing capabilities?
+- Does it require multiple specialized skills?
+- Is the scope too large for one person?
+- Are there logical components that could be parallelized?
+
+Provide your decision in the JSON format specified in the system prompt.`,
+		task.Title,
+		task.Description,
+		task.Priority,
+		task.Status)
+}
+
+func getSubtaskDecisionSystemPrompt(roles []string) string {
+	availableRoles := strings.Join(roles, ", ")
+
+	return fmt.Sprintf(`You are an expert project manager and task analyst. Your job is to determine whether a task needs to be broken down into subtasks.
+
+Currently available team roles and their capabilities: %s
+
+When evaluating a task, consider:
+1. Task complexity and scope
+2. Whether multiple specialized skills are needed
+3. If the task can be completed by a single agent with current capabilities
+4. Whether new agent roles might be needed for specialized skills
+
+Respond with a JSON object in this exact format:
+{
+  "needs_subtasks": true/false,
+  "reasoning": "Clear explanation of why subtasks are or aren't needed",
+  "complexity_score": 5,
+  "required_skills": ["skill1", "skill2", "skill3"]
+}
+
+Complexity score should be 1-10 where:
+- 1-3: Simple tasks that can be handled by one agent
+- 4-6: Moderate complexity, might benefit from subtasks
+- 7-10: Complex tasks that definitely need breaking down
+
+Required skills should list all technical/domain skills needed to complete the task.`, availableRoles)
+}
+
+func parseSubtaskDecision(response string) (*tm.SubtaskDecision, error) {
+	// Try to extract JSON from the response
+	jsonStart := strings.Index(response, "{")
+	jsonEnd := strings.LastIndex(response, "}")
+
+	if jsonStart == -1 || jsonEnd == -1 {
+		return nil, fmt.Errorf("no JSON found in LLM response")
+	}
+
+	jsonStr := response[jsonStart : jsonEnd+1]
+
+	var decision tm.SubtaskDecision
+	if err := json.Unmarshal([]byte(jsonStr), &decision); err != nil {
+		return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
+	}
+
+	return &decision, nil
+}
+
+func buildSubtaskAnalysisPrompt(task *tm.Task) string {
+	return fmt.Sprintf(`Please analyze the following task and break it down into subtasks:
+
+**Task Title:** %s
+
+**Description:** %s
+
+**Priority:** %s
+
+**Current Status:** %s
+
+Please analyze this task and provide a detailed breakdown into subtasks. Consider:
+- Technical complexity and requirements
+- Logical task dependencies 
+- Appropriate skill sets needed for each subtask
+- Risk factors and potential blockers
+- Estimated effort for each component
+
+Provide the analysis in the JSON format specified in the system prompt.`,
+		task.Title,
+		task.Description,
+		task.Priority,
+		task.Status)
+}
+
+func getSubtaskAnalysisSystemPrompt(roles []string) string {
+	availableRoles := strings.Join(roles, ", ")
+
+	return fmt.Sprintf(`You are an expert project manager and technical architect. Your job is to analyze complex tasks and break them down into well-defined subtasks that can be assigned to specialized team members.
+
+Currently available team roles: %s
+
+When analyzing a task, you should:
+1. Understand the task requirements and scope
+2. Break it down into logical, manageable subtasks
+3. Assign each subtask to the most appropriate team role OR propose creating new agents
+4. Estimate effort and identify dependencies
+5. Provide a clear execution strategy
+
+If you need specialized skills not covered by existing roles, propose new agent creation.
+
+Respond with a JSON object in this exact format:
+{
+  "analysis_summary": "Brief analysis of the task and approach",
+  "subtasks": [
+    {
+      "title": "Subtask title",
+      "description": "Detailed description of what needs to be done",
+      "priority": "high|medium|low",
+      "assigned_to": "role_name",
+      "estimated_hours": 8,
+      "dependencies": ["subtask_index_1", "subtask_index_2"],
+      "required_skills": ["skill1", "skill2"]
+    }
+  ],
+  "agent_creations": [
+    {
+      "role": "new_role_name",
+      "skills": ["specialized_skill1", "specialized_skill2"],
+      "description": "Description of what this agent does",
+      "justification": "Why this new agent is needed"
+    }
+  ],
+  "recommended_approach": "High-level strategy for executing these subtasks",
+  "estimated_total_hours": 40,
+  "risk_assessment": "Potential risks and mitigation strategies"
+}
+
+For existing roles, use: %s
+For new agents, propose appropriate role names and skill sets.
+Dependencies should reference subtask indices (e.g., ["0", "1"] means depends on first and second subtasks).`, availableRoles, availableRoles)
+}
+
+func parseSubtaskAnalysis(response string, parentTaskID string, agentRoles []string, logger *slog.Logger) (*tm.SubtaskAnalysis, error) {
+	// Try to extract JSON from the response (LLM might wrap it in markdown)
+	jsonStart := strings.Index(response, "{")
+	jsonEnd := strings.LastIndex(response, "}")
+
+	if jsonStart == -1 || jsonEnd == -1 {
+		return nil, fmt.Errorf("no JSON found in LLM response")
+	}
+
+	jsonStr := response[jsonStart : jsonEnd+1]
+
+	var rawAnalysis struct {
+		AnalysisSummary string `json:"analysis_summary"`
+		Subtasks        []struct {
+			Title          string   `json:"title"`
+			Description    string   `json:"description"`
+			Priority       string   `json:"priority"`
+			AssignedTo     string   `json:"assigned_to"`
+			EstimatedHours int      `json:"estimated_hours"`
+			Dependencies   []string `json:"dependencies"`
+			RequiredSkills []string `json:"required_skills"`
+		} `json:"subtasks"`
+		AgentCreations      []tm.AgentCreationProposal `json:"agent_creations"`
+		RecommendedApproach string                     `json:"recommended_approach"`
+		EstimatedTotalHours int                        `json:"estimated_total_hours"`
+		RiskAssessment      string                     `json:"risk_assessment"`
+	}
+
+	if err := json.Unmarshal([]byte(jsonStr), &rawAnalysis); err != nil {
+		return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
+	}
+
+	// Convert to our types
+	analysis := &tm.SubtaskAnalysis{
+		ParentTaskID:        parentTaskID,
+		AnalysisSummary:     rawAnalysis.AnalysisSummary,
+		AgentCreations:      rawAnalysis.AgentCreations,
+		RecommendedApproach: rawAnalysis.RecommendedApproach,
+		EstimatedTotalHours: rawAnalysis.EstimatedTotalHours,
+		RiskAssessment:      rawAnalysis.RiskAssessment,
+	}
+
+	// Convert subtasks
+	for _, st := range rawAnalysis.Subtasks {
+		priority := tm.PriorityMedium // default
+		switch strings.ToLower(st.Priority) {
+		case "high":
+			priority = tm.PriorityHigh
+		case "low":
+			priority = tm.PriorityLow
+		}
+
+		subtask := tm.SubtaskProposal{
+			Title:          st.Title,
+			Description:    st.Description,
+			Priority:       priority,
+			AssignedTo:     st.AssignedTo,
+			EstimatedHours: st.EstimatedHours,
+			Dependencies:   st.Dependencies,
+			RequiredSkills: st.RequiredSkills,
+		}
+
+		analysis.Subtasks = append(analysis.Subtasks, subtask)
+	}
+
+	// Validate agent assignments and handle new agent creation
+	if err := validateAndHandleAgentAssignments(analysis, agentRoles, logger); err != nil {
+		logger.Warn("Warning during agent assignment handling", slog.String("error", err.Error()))
+	}
+
+	return analysis, nil
+}
+
+func validateAndHandleAgentAssignments(analysis *tm.SubtaskAnalysis, agentRoles []string, logger *slog.Logger) error {
+	// Collect all agent roles that will be available (existing + proposed new ones)
+	availableRoles := make(map[string]bool)
+	for _, role := range agentRoles {
+		availableRoles[role] = true
+	}
+
+	// Add proposed new agent roles
+	for _, agentCreation := range analysis.AgentCreations {
+		availableRoles[agentCreation.Role] = true
+
+		// Create a subtask for agent creation
+		agentCreationSubtask := tm.SubtaskProposal{
+			Title:          fmt.Sprintf("Create %s Agent", cases.Title(language.English).String(agentCreation.Role)),
+			Description:    fmt.Sprintf("Create and configure a new %s agent with skills: %s. %s", agentCreation.Role, strings.Join(agentCreation.Skills, ", "), agentCreation.Justification),
+			Priority:       tm.PriorityHigh, // Agent creation is high priority
+			AssignedTo:     "ceo",           // CEO creates new agents
+			EstimatedHours: 4,               // Estimated time to set up new agent
+			Dependencies:   []string{},      // No dependencies for agent creation
+			RequiredSkills: []string{"agent_configuration", "system_design"},
+		}
+
+		// Insert at the beginning so agent creation happens first
+		analysis.Subtasks = append([]tm.SubtaskProposal{agentCreationSubtask}, analysis.Subtasks...)
+
+		// Update dependencies to account for the new subtask at index 0
+		for i := 1; i < len(analysis.Subtasks); i++ {
+			for j, dep := range analysis.Subtasks[i].Dependencies {
+				// Convert dependency index and increment by 1
+				if depIndex := parseDependencyIndex(dep); depIndex >= 0 {
+					analysis.Subtasks[i].Dependencies[j] = fmt.Sprintf("%d", depIndex+1)
+				}
+			}
+		}
+	}
+
+	// Now validate all assignments against available roles
+	defaultRole := "ceo" // fallback role
+	if len(agentRoles) > 0 {
+		defaultRole = agentRoles[0]
+	}
+
+	for i := range analysis.Subtasks {
+		if !availableRoles[analysis.Subtasks[i].AssignedTo] {
+			logger.Warn("Unknown agent role for subtask, using default",
+				slog.String("unknown_role", analysis.Subtasks[i].AssignedTo),
+				slog.String("subtask_title", analysis.Subtasks[i].Title),
+				slog.String("assigned_role", defaultRole))
+			analysis.Subtasks[i].AssignedTo = defaultRole
+		}
+	}
+
+	return nil
+}
+
+func parseDependencyIndex(dep string) int {
+	var idx int
+	if _, err := fmt.Sscanf(dep, "%d", &idx); err == nil {
+		return idx
+	}
+	return -1 // Invalid dependency format
+}
+
+func generateSubtaskPRContent(analysis *tm.SubtaskAnalysis) string {
+	var content strings.Builder
+
+	content.WriteString(fmt.Sprintf("# Subtasks Created for Task %s\n\n", analysis.ParentTaskID))
+	content.WriteString(fmt.Sprintf("This PR creates **%d individual task files** in `/operations/tasks/` ready for agent assignment.\n\n", len(analysis.Subtasks)))
+	content.WriteString(fmt.Sprintf("✅ **Parent task `%s` has been marked as completed** - the complex task has been successfully broken down into actionable subtasks.\n\n", analysis.ParentTaskID))
+	content.WriteString(fmt.Sprintf("## Analysis Summary\n%s\n\n", analysis.AnalysisSummary))
+	content.WriteString(fmt.Sprintf("## Recommended Approach\n%s\n\n", analysis.RecommendedApproach))
+	content.WriteString(fmt.Sprintf("**Estimated Total Hours:** %d\n\n", analysis.EstimatedTotalHours))
+
+	// List the created task files
+	content.WriteString("## Created Task Files\n\n")
+	for i, subtask := range analysis.Subtasks {
+		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+		content.WriteString(fmt.Sprintf("### %d. `%s.md`\n", i+1, taskID))
+		content.WriteString(fmt.Sprintf("- **Title:** %s\n", subtask.Title))
+		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
+		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
+		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
+		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
+	}
+
+	if analysis.RiskAssessment != "" {
+		content.WriteString(fmt.Sprintf("## Risk Assessment\n%s\n\n", analysis.RiskAssessment))
+	}
+
+	content.WriteString("## Proposed Subtasks\n\n")
+
+	for i, subtask := range analysis.Subtasks {
+		content.WriteString(fmt.Sprintf("### %d. %s\n", i+1, subtask.Title))
+		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
+		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
+		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
+
+		if len(subtask.Dependencies) > 0 {
+			deps := strings.Join(subtask.Dependencies, ", ")
+			content.WriteString(fmt.Sprintf("- **Dependencies:** %s\n", deps))
+		}
+
+		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
+	}
+
+	content.WriteString("---\n")
+	content.WriteString("*Generated by Staff AI Agent System*\n\n")
+	content.WriteString("**Instructions:**\n")
+	content.WriteString("- Review the proposed subtasks\n")
+	content.WriteString("- Approve or request changes\n")
+	content.WriteString("- When merged, the subtasks will be automatically created and assigned\n")
+
+	return content.String()
+}
+
+// buildTaskPrompt creates a detailed prompt for the LLM
+func buildTaskPrompt(task *tm.Task) string {
+	return fmt.Sprintf(`Task: %s
+
+Priority: %s
+Description: %s
+
+Please provide a complete solution for this task. Include:
+1. Detailed implementation plan
+2. Code changes needed (if applicable)
+3. Files to be created or modified
+4. Testing considerations
+5. Any dependencies or prerequisites
+
+Your response should be comprehensive and actionable.`,
+		task.Title,
+		task.Priority,
+		task.Description)
+}
diff --git a/server/agent/types.go b/server/agent/types.go
deleted file mode 100644
index a9f021c..0000000
--- a/server/agent/types.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package agent
-
-import (
-	"github.com/iomodo/staff/llm"
-)
-
-// Agent represents an AI agent that can process tasks autonomously
-type Agent struct {
-	// Identity
-	Name string
-	Role string
-
-	// LLM Configuration
-	Model        string
-	SystemPrompt string
-	MaxTokens    *int
-	Temperature  *float64
-
-	// Runtime
-	Provider    llm.LLMProvider
-	CurrentTask *string // Task ID currently being processed
-
-	// Statistics
-	Stats AgentStats
-}
-
-// AgentStats tracks agent performance metrics
-type AgentStats struct {
-	TasksCompleted int     `json:"tasks_completed"`
-	TasksFailed    int     `json:"tasks_failed"`
-	SuccessRate    float64 `json:"success_rate"`
-	AvgTime        int64   `json:"avg_completion_time_seconds"`
-}
-
-// AgentStatus represents the current state of an agent
-type AgentStatus string
-
-const (
-	StatusIdle    AgentStatus = "idle"
-	StatusRunning AgentStatus = "running"
-	StatusError   AgentStatus = "error"
-	StatusStopped AgentStatus = "stopped"
-)
-
-// AgentInfo provides status information about an agent
-type AgentInfo struct {
-	Name        string      `json:"name"`
-	Role        string      `json:"role"`
-	Model       string      `json:"model"`
-	Status      AgentStatus `json:"status"`
-	CurrentTask *string     `json:"current_task,omitempty"`
-	Stats       AgentStats  `json:"stats"`
-}
diff --git a/server/cmd/commands/generate_subtasks.go b/server/cmd/commands/generate_subtasks.go
deleted file mode 100644
index c907b82..0000000
--- a/server/cmd/commands/generate_subtasks.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package commands
-
-import (
-	"fmt"
-	"log"
-
-	"github.com/spf13/cobra"
-)
-
-var generateSubtasksCmd = &cobra.Command{
-	Use:   "generate-subtasks [task-id]",
-	Short: "Generate subtasks for a given task using LLM analysis",
-	Long: `Analyze a task and generate proposed subtasks using LLM analysis.
-This creates a PR with the proposed subtasks that can be reviewed and merged.
-
-Example:
-  staff generate-subtasks task-123456-abcdef`,
-	Args: cobra.ExactArgs(1),
-	RunE: runGenerateSubtasks,
-}
-
-func init() {
-	rootCmd.AddCommand(generateSubtasksCmd)
-}
-
-func runGenerateSubtasks(cmd *cobra.Command, args []string) error {
-	taskID := args[0]
-
-	// Get the task
-	task, err := taskManager.GetTask(taskID)
-	if err != nil {
-		return fmt.Errorf("failed to get task: %w", err)
-	}
-
-	fmt.Printf("Generating subtasks for task: %s\n", task.Title)
-	fmt.Printf("Description: %s\n", task.Description)
-	fmt.Printf("Priority: %s\n\n", task.Priority)
-
-	// Check if subtasks already generated
-	if task.SubtasksGenerated {
-		fmt.Printf("⚠️ Subtasks already generated for this task\n")
-		if task.SubtasksPRURL != "" {
-			fmt.Printf("PR URL: %s\n", task.SubtasksPRURL)
-		}
-		return nil
-	}
-
-	// Force subtask generation by temporarily marking as high priority
-	originalPriority := task.Priority
-	task.Priority = "high"
-
-	// Get the manager's subtask service and generate
-	if agentManager == nil {
-		return fmt.Errorf("agent manager not initialized")
-	}
-
-	// This is a bit of a hack to access private method, but for testing...
-	log.Printf("Starting subtask analysis for task %s...", taskID)
-	
-	// We'll call this through the normal task processing flow
-	// by creating a dummy agent to trigger the subtask generation
-	agentStatus := agentManager.GetAgentStatus()
-	if len(agentStatus) == 0 {
-		return fmt.Errorf("no agents available")
-	}
-
-	// Get first available agent
-	var agentName string
-	for name := range agentStatus {
-		agentName = name
-		break
-	}
-
-	fmt.Printf("🤖 Using agent '%s' for subtask analysis...\n\n", agentName)
-
-	// Create a simple approach: assign task to agent and let it process
-	task.Assignee = agentName
-	task.Priority = originalPriority // Restore original priority
-	
-	if err := taskManager.UpdateTask(task); err != nil {
-		return fmt.Errorf("failed to update task assignment: %w", err)
-	}
-
-	fmt.Printf("✅ Task assigned to agent '%s' for subtask generation\n", agentName)
-	fmt.Printf("💡 Start the server to see subtask generation in action:\n")
-	fmt.Printf("   staff server --config config-fake.yaml\n\n")
-	fmt.Printf("📋 The agent will:\n")
-	fmt.Printf("   1. Analyze the task requirements\n")
-	fmt.Printf("   2. Generate proposed subtasks with LLM\n")
-	fmt.Printf("   3. Create a PR with subtask proposals\n")
-	fmt.Printf("   4. Wait for PR review and approval\n")
-	fmt.Printf("   5. Create actual subtasks when PR is merged\n")
-
-	return nil
-}
\ No newline at end of file
diff --git a/server/cmd/commands/root.go b/server/cmd/commands/root.go
index ade7c53..e75e134 100644
--- a/server/cmd/commands/root.go
+++ b/server/cmd/commands/root.go
@@ -75,8 +75,8 @@
 		Level: slog.LevelInfo,
 	}))
 
-	gitInterface := git.DefaultGit("../")
-	taskManager = git_tm.NewGitTaskManagerWithLogger(gitInterface, "../", logger)
+	gitInterface := git.New(cfg, logger)
+	taskManager = git_tm.NewGitTaskManager(gitInterface, cfg, logger)
 
 	// Initialize agent manager
 	agentManager, err = agent.NewManager(cfg, taskManager, logger)
diff --git a/server/config-fake.yaml b/server/config-fake.yaml
index 387ba96..a402991 100644
--- a/server/config-fake.yaml
+++ b/server/config-fake.yaml
@@ -12,6 +12,7 @@
   repo: "staff"
 
 git:
+  repo_path: "/Users/shota/github/staff/"
   branch_prefix: "task/"
   commit_message_template: "Task {task_id}: {task_title} by {agent_name}"
   pr_template: |
diff --git a/server/config.yaml b/server/config.yaml
index 5a5b6dd..17287d6 100644
--- a/server/config.yaml
+++ b/server/config.yaml
@@ -12,6 +12,7 @@
   repo: "staff"   # Replace with your repository name
 
 git:
+  repo_path: "/Users/shota/github/staff/"
   branch_prefix: "task/"
   commit_message_template: "Task {task_id}: {task_title} by {agent_name}"
   pr_template: |
diff --git a/server/config/config.go b/server/config/config.go
index 86dd7a5..c51bd43 100644
--- a/server/config/config.go
+++ b/server/config/config.go
@@ -62,7 +62,7 @@
 
 // GitConfig represents Git operation configuration
 type GitConfig struct {
-	BranchPrefix          string `yaml:"branch_prefix"`
+	RepoPath              string `yaml:"repo_path"`
 	CommitMessageTemplate string `yaml:"commit_message_template"`
 	PRTemplate            string `yaml:"pr_template"`
 }
@@ -158,9 +158,6 @@
 	}
 
 	// Git defaults
-	if config.Git.BranchPrefix == "" {
-		config.Git.BranchPrefix = "task/"
-	}
 	if config.Git.CommitMessageTemplate == "" {
 		config.Git.CommitMessageTemplate = "Task {task_id}: {task_title}\n\n{solution}\n\nGenerated by Staff AI Agent: {agent_name}"
 	}
@@ -207,11 +204,11 @@
 	// Validate that at least one Git provider is configured
 	hasGitHub := config.GitHub.Token != "" && config.GitHub.Owner != "" && config.GitHub.Repo != ""
 	hasGerrit := config.Gerrit.Username != "" && config.Gerrit.Password != "" && config.Gerrit.BaseURL != "" && config.Gerrit.Project != ""
-	
+
 	if !hasGitHub && !hasGerrit {
 		return fmt.Errorf("either GitHub or Gerrit configuration is required")
 	}
-	
+
 	// Validate GitHub config if provided
 	if config.GitHub.Token != "" {
 		if config.GitHub.Owner == "" {
@@ -221,7 +218,7 @@
 			return fmt.Errorf("github.repo is required when github.token is provided")
 		}
 	}
-	
+
 	// Validate Gerrit config if provided
 	if config.Gerrit.Username != "" {
 		if config.Gerrit.Password == "" {
diff --git a/server/git/CONCURRENCY_README.md b/server/git/CONCURRENCY_README.md
deleted file mode 100644
index 1cbe184..0000000
--- a/server/git/CONCURRENCY_README.md
+++ /dev/null
@@ -1,172 +0,0 @@
-# Git Concurrency Solution: Per-Agent Repository Clones
-
-## Problem Statement
-
-Git is not thread-safe, which creates critical race conditions when multiple AI agents try to perform Git operations concurrently:
-
-- **Repository Corruption**: Multiple agents modifying the same `.git` folder simultaneously
-- **Branch Conflicts**: Agents creating branches with the same names or overwriting each other's work  
-- **Push Failures**: Concurrent pushes causing merge conflicts and failed operations
-- **Index Lock Errors**: Git index.lock conflicts when multiple processes access the repository
-
-## Solution: Per-Agent Git Clones
-
-Instead of using mutexes (which would serialize all Git operations and hurt performance), we give each agent its own Git repository clone:
-
-```
-workspace/
-├── agent-backend-engineer/     # Backend engineer's clone
-│   ├── .git/
-│   ├── tasks/
-│   └── ...
-├── agent-frontend-engineer/    # Frontend engineer's clone  
-│   ├── .git/
-│   ├── tasks/
-│   └── ...
-└── agent-qa-engineer/         # QA engineer's clone
-    ├── .git/
-    ├── tasks/
-    └── ...
-```
-
-## Key Benefits
-
-### 🚀 **True Concurrency**
-- Multiple agents can work simultaneously without blocking each other
-- No waiting for Git lock releases
-- Scales to hundreds of concurrent agents
-
-### 🛡️ **Complete Isolation** 
-- Each agent has its own `.git` directory and working tree
-- No shared state or race conditions
-- Agent failures don't affect other agents
-
-### 🔄 **Automatic Synchronization**
-- Each clone automatically pulls latest changes before creating branches
-- All branches push to the same remote repository
-- PRs are created against the main repository
-
-### 🧹 **Easy Cleanup**
-- `staff cleanup-clones` removes all agent workspaces
-- Clones are recreated on-demand when agents start working
-- No manual Git state management required
-
-## Implementation Details
-
-### CloneManager (`git/clone_manager.go`)
-
-```go
-type CloneManager struct {
-    baseRepoURL    string                // Source repository URL
-    workspacePath  string                // Base workspace directory  
-    agentClones    map[string]string     // agent name -> clone path
-    mu             sync.RWMutex          // Thread-safe map access
-}
-```
-
-**Key Methods:**
-- `GetAgentClonePath(agentName)` - Get/create agent's clone directory
-- `RefreshAgentClone(agentName)` - Pull latest changes for an agent
-- `CleanupAgentClone(agentName)` - Remove specific agent's clone
-- `CleanupAllClones()` - Remove all agent clones
-
-### Agent Integration
-
-Each agent's Git operations are automatically routed to its dedicated clone:
-
-```go
-// Get agent's dedicated Git clone
-clonePath, err := am.cloneManager.GetAgentClonePath(agent.Name)
-if err != nil {
-    return fmt.Errorf("failed to get agent clone: %w", err)
-}
-
-// All Git operations use the agent's clone directory
-gitCmd := func(args ...string) *exec.Cmd {
-    return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
-}
-```
-
-## Workflow Example
-
-1. **Agent Starts Task**:
-   ```bash
-   Agent backend-engineer gets task: "Add user authentication"
-   Creating clone: workspace/agent-backend-engineer/
-   ```
-
-2. **Concurrent Operations**:
-   ```bash
-   # These happen simultaneously without conflicts:
-   Agent backend-engineer:  git clone -> workspace/agent-backend-engineer/
-   Agent frontend-engineer: git clone -> workspace/agent-frontend-engineer/  
-   Agent qa-engineer:       git clone -> workspace/agent-qa-engineer/
-   ```
-
-3. **Branch Creation**:
-   ```bash
-   # Each agent creates branches in their own clone:
-   backend-engineer:  git checkout -b task-123-auth-backend
-   frontend-engineer: git checkout -b task-124-auth-ui
-   qa-engineer:      git checkout -b task-125-auth-tests
-   ```
-
-4. **Concurrent Pushes**:
-   ```bash
-   # All agents push to origin simultaneously:
-   git push -u origin task-123-auth-backend    # ✅ Success
-   git push -u origin task-124-auth-ui         # ✅ Success  
-   git push -u origin task-125-auth-tests      # ✅ Success
-   ```
-
-## Management Commands
-
-### List Agent Clones
-```bash
-staff list-agents  # Shows which agents are running and their clone status
-```
-
-### Cleanup All Clones
-```bash
-staff cleanup-clones  # Removes all agent workspace directories
-```
-
-### Monitor Disk Usage
-```bash
-du -sh workspace/  # Check total workspace disk usage
-```
-
-## Resource Considerations
-
-### Disk Space
-- Each clone uses ~repository size (typically 10-100MB per agent)
-- For 10 agents with 50MB repo = ~500MB total
-- Use `staff cleanup-clones` to free space when needed
-
-### Network Usage
-- Initial clone downloads full repository
-- Subsequent `git pull` operations are incremental
-- All agents share the same remote repository
-
-### Performance
-- Clone creation: ~2-5 seconds per agent (one-time cost)
-- Git operations: Full speed, no waiting for locks
-- Parallel processing: Linear scalability with agent count
-
-## Comparison to Alternatives
-
-| Solution | Concurrency | Complexity | Performance | Risk |
-|----------|-------------|------------|-------------|------|
-| **Per-Agent Clones** | ✅ Full | 🟡 Medium | ✅ High | 🟢 Low |
-| Global Git Mutex | ❌ None | 🟢 Low | ❌ Poor | 🟡 Medium |
-| File Locking | 🟡 Limited | 🔴 High | 🟡 Medium | 🔴 High |
-| Separate Repositories | ✅ Full | 🔴 Very High | ✅ High | 🔴 High |
-
-## Future Enhancements
-
-- **Lazy Cleanup**: Auto-remove unused clones after N days
-- **Clone Sharing**: Share clones between agents with similar tasks
-- **Compressed Clones**: Use `git clone --depth=1` for space efficiency
-- **Remote Workspaces**: Support for distributed agent execution
-
-The per-agent clone solution provides the optimal balance of performance, safety, and maintainability for concurrent AI agent operations.
\ No newline at end of file
diff --git a/server/git/PULL_REQUEST_README.md b/server/git/PULL_REQUEST_README.md
deleted file mode 100644
index b6664f2..0000000
--- a/server/git/PULL_REQUEST_README.md
+++ /dev/null
@@ -1,323 +0,0 @@
-# Pull Request Capabilities
-
-This package now includes comprehensive pull request (PR) capabilities that support both GitHub and Gerrit platforms. The implementation provides a unified interface for managing pull requests across different code hosting platforms.
-
-## Features
-
-- **Unified Interface**: Same API for both GitHub and Gerrit
-- **Full CRUD Operations**: Create, read, update, delete pull requests
-- **Advanced Filtering**: List pull requests with various filters
-- **Merge Operations**: Support for different merge strategies
-- **Error Handling**: Comprehensive error handling with detailed messages
-- **Authentication**: Support for token-based and basic authentication
-
-## Supported Platforms
-
-### GitHub
-- Uses GitHub REST API v3
-- Supports personal access tokens for authentication
-- Full support for all pull request operations
-- Handles GitHub-specific features like draft PRs, labels, assignees, and reviewers
-
-### Gerrit
-- Uses Gerrit REST API
-- Supports HTTP password or API token authentication
-- Maps Gerrit "changes" to pull requests
-- Handles Gerrit-specific features like topics and review workflows
-
-## Quick Start
-
-### GitHub Example
-
-```go
-package main
-
-import (
-    "context"
-    "github.com/iomodo/staff/git"
-    "net/http"
-    "time"
-)
-
-func main() {
-    ctx := context.Background()
-    
-    // Create GitHub configuration
-    githubConfig := git.GitHubConfig{
-        Token: "your-github-token",
-        BaseURL: "https://api.github.com",
-        HTTPClient: &http.Client{Timeout: 30 * time.Second},
-    }
-    
-    // Create GitHub provider
-    githubProvider := git.NewGitHubPullRequestProvider("owner", "repo", githubConfig)
-    
-    // Create Git instance with pull request capabilities
-    git := git.NewGitWithPullRequests("/path/to/repo", git.GitConfig{}, githubProvider)
-    
-    // Create a pull request
-    prOptions := git.PullRequestOptions{
-        Title:       "Add new feature",
-        Description: "This PR adds a new feature to the application.",
-        BaseBranch:  "main",
-        HeadBranch:  "feature/new-feature",
-        Labels:      []string{"enhancement", "feature"},
-        Assignees:   []string{"username1", "username2"},
-        Reviewers:   []string{"reviewer1", "reviewer2"},
-        Draft:       false,
-    }
-    
-    pr, err := git.CreatePullRequest(ctx, prOptions)
-    if err != nil {
-        log.Fatal(err)
-    }
-    
-    fmt.Printf("Created pull request: %s (#%d)\n", pr.Title, pr.Number)
-}
-```
-
-### Gerrit Example
-
-```go
-package main
-
-import (
-    "context"
-    "github.com/iomodo/staff/git"
-    "net/http"
-    "time"
-)
-
-func main() {
-    ctx := context.Background()
-    
-    // Create Gerrit configuration
-    gerritConfig := git.GerritConfig{
-        Username: "your-username",
-        Password: "your-http-password-or-api-token",
-        BaseURL:  "https://gerrit.example.com",
-        HTTPClient: &http.Client{Timeout: 30 * time.Second},
-    }
-    
-    // Create Gerrit provider
-    gerritProvider := git.NewGerritPullRequestProvider("project-name", gerritConfig)
-    
-    // Create Git instance with pull request capabilities
-    git := git.NewGitWithPullRequests("/path/to/repo", git.GitConfig{}, gerritProvider)
-    
-    // Create a change (pull request)
-    prOptions := git.PullRequestOptions{
-        Title:       "Add new feature",
-        Description: "This change adds a new feature to the application.",
-        BaseBranch:  "master",
-        HeadBranch:  "feature/new-feature",
-    }
-    
-    pr, err := git.CreatePullRequest(ctx, prOptions)
-    if err != nil {
-        log.Fatal(err)
-    }
-    
-    fmt.Printf("Created change: %s (#%d)\n", pr.Title, pr.Number)
-}
-```
-
-## API Reference
-
-### Types
-
-#### PullRequest
-Represents a pull request or merge request across platforms.
-
-```go
-type PullRequest struct {
-    ID          string
-    Number      int
-    Title       string
-    Description string
-    State       string // "open", "closed", "merged"
-    Author      Author
-    CreatedAt   time.Time
-    UpdatedAt   time.Time
-    BaseBranch  string
-    HeadBranch  string
-    BaseRepo    string
-    HeadRepo    string
-    Labels      []string
-    Assignees   []Author
-    Reviewers   []Author
-    Commits     []Commit
-    Comments    []PullRequestComment
-}
-```
-
-#### PullRequestOptions
-Options for creating or updating pull requests.
-
-```go
-type PullRequestOptions struct {
-    Title       string
-    Description string
-    BaseBranch  string
-    HeadBranch  string
-    BaseRepo    string
-    HeadRepo    string
-    Labels      []string
-    Assignees   []string
-    Reviewers   []string
-    Draft       bool
-}
-```
-
-#### ListPullRequestOptions
-Options for listing pull requests.
-
-```go
-type ListPullRequestOptions struct {
-    State      string // "open", "closed", "all"
-    Author     string
-    Assignee   string
-    BaseBranch string
-    HeadBranch string
-    Labels     []string
-    Limit      int
-}
-```
-
-#### MergePullRequestOptions
-Options for merging pull requests.
-
-```go
-type MergePullRequestOptions struct {
-    MergeMethod string // "merge", "squash", "rebase"
-    CommitTitle string
-    CommitMsg   string
-}
-```
-
-### Methods
-
-#### CreatePullRequest
-Creates a new pull request.
-
-```go
-func (g *Git) CreatePullRequest(ctx context.Context, options PullRequestOptions) (*PullRequest, error)
-```
-
-#### GetPullRequest
-Retrieves a pull request by ID.
-
-```go
-func (g *Git) GetPullRequest(ctx context.Context, id string) (*PullRequest, error)
-```
-
-#### ListPullRequests
-Lists pull requests with optional filtering.
-
-```go
-func (g *Git) ListPullRequests(ctx context.Context, options ListPullRequestOptions) ([]PullRequest, error)
-```
-
-#### UpdatePullRequest
-Updates an existing pull request.
-
-```go
-func (g *Git) UpdatePullRequest(ctx context.Context, id string, options PullRequestOptions) (*PullRequest, error)
-```
-
-#### ClosePullRequest
-Closes a pull request.
-
-```go
-func (g *Git) ClosePullRequest(ctx context.Context, id string) error
-```
-
-#### MergePullRequest
-Merges a pull request.
-
-```go
-func (g *Git) MergePullRequest(ctx context.Context, id string, options MergePullRequestOptions) error
-```
-
-## Configuration
-
-### GitHub Configuration
-
-```go
-type GitHubConfig struct {
-    Token      string        // GitHub personal access token
-    BaseURL    string        // GitHub API base URL (default: https://api.github.com)
-    HTTPClient *http.Client  // Custom HTTP client (optional)
-}
-```
-
-### Gerrit Configuration
-
-```go
-type GerritConfig struct {
-    Username    string        // Gerrit username
-    Password    string        // HTTP password or API token
-    BaseURL     string        // Gerrit instance URL
-    HTTPClient  *http.Client  // Custom HTTP client (optional)
-}
-```
-
-## Error Handling
-
-All pull request operations return detailed error information through the `GitError` type:
-
-```go
-type GitError struct {
-    Command string
-    Output  string
-    Err     error
-}
-```
-
-Common error scenarios:
-- Authentication failures
-- Invalid repository or project names
-- Network connectivity issues
-- API rate limiting
-- Invalid pull request data
-
-## Platform-Specific Notes
-
-### GitHub
-- Requires a personal access token with appropriate permissions
-- Supports draft pull requests
-- Full support for labels, assignees, and reviewers
-- Uses GitHub's REST API v3
-
-### Gerrit
-- Requires HTTP password or API token
-- Uses "changes" instead of "pull requests"
-- Topics are used to group related changes
-- Review workflow is more structured
-- Uses Gerrit's REST API
-
-## Examples
-
-See `pull_request_example.go` for comprehensive examples of using both GitHub and Gerrit providers.
-
-## Testing
-
-Run the tests to ensure everything works correctly:
-
-```bash
-go test ./git/... -v
-```
-
-## Contributing
-
-When adding support for new platforms:
-
-1. Implement the `PullRequestProvider` interface
-2. Add platform-specific configuration types
-3. Create conversion functions to map platform-specific data to our unified types
-4. Add comprehensive tests
-5. Update this documentation
-
-## License
-
-This code is part of the staff project and follows the same licensing terms. 
\ No newline at end of file
diff --git a/server/git/README.md b/server/git/README.md
deleted file mode 100644
index 18ccc1f..0000000
--- a/server/git/README.md
+++ /dev/null
@@ -1,331 +0,0 @@
-# Git Interface for Go
-
-A comprehensive Go interface for Git operations that provides a clean, type-safe API for interacting with Git repositories.
-
-## Features
-
-- **Complete Git Operations**: Supports all major Git operations including repository management, commits, branches, remotes, tags, and more
-- **Type-Safe API**: Strongly typed interfaces and structs for better code safety
-- **Context Support**: All operations support context for cancellation and timeouts
-- **Error Handling**: Comprehensive error handling with detailed error messages
-- **Flexible Configuration**: Configurable timeouts and environment variables
-- **Easy to Use**: Simple and intuitive API design
-
-## Installation
-
-The Git interface is part of the `github.com/iomodo/staff` module. No additional dependencies are required beyond the standard library.
-
-## Quick Start
-
-```go
-package main
-
-import (
-    "context"
-    "fmt"
-    "log"
-    
-    "github.com/iomodo/staff/git"
-)
-
-func main() {
-    ctx := context.Background()
-    
-    // Create a Git instance
-    git := git.DefaultGit("/path/to/your/repo")
-    
-    // Open an existing repository
-    if err := git.Open(ctx, "/path/to/your/repo"); err != nil {
-        log.Fatalf("Failed to open repository: %v", err)
-    }
-    
-    // Get repository status
-    status, err := git.Status(ctx)
-    if err != nil {
-        log.Fatalf("Failed to get status: %v", err)
-    }
-    
-    fmt.Printf("Current branch: %s\n", status.Branch)
-    fmt.Printf("Repository is clean: %t\n", status.IsClean)
-}
-```
-
-## Core Interface
-
-### GitInterface
-
-The main interface that defines all Git operations:
-
-```go
-type GitInterface interface {
-    // Repository operations
-    Init(ctx context.Context, path string) error
-    Clone(ctx context.Context, url, path string) error
-    IsRepository(ctx context.Context, path string) (bool, error)
-    
-    // Status and information
-    Status(ctx context.Context) (*Status, error)
-    Log(ctx context.Context, options LogOptions) ([]Commit, error)
-    Show(ctx context.Context, ref string) (*Commit, error)
-    
-    // Branch operations
-    ListBranches(ctx context.Context) ([]Branch, error)
-    CreateBranch(ctx context.Context, name string, startPoint string) error
-    Checkout(ctx context.Context, ref string) error
-    DeleteBranch(ctx context.Context, name string, force bool) error
-    GetCurrentBranch(ctx context.Context) (string, error)
-    
-    // Commit operations
-    Add(ctx context.Context, paths []string) error
-    AddAll(ctx context.Context) error
-    Commit(ctx context.Context, message string, options CommitOptions) error
-    
-    // Remote operations
-    ListRemotes(ctx context.Context) ([]Remote, error)
-    AddRemote(ctx context.Context, name, url string) error
-    RemoveRemote(ctx context.Context, name string) error
-    Fetch(ctx context.Context, remote string, options FetchOptions) error
-    Pull(ctx context.Context, remote, branch string) error
-    Push(ctx context.Context, remote, branch string, options PushOptions) error
-    
-    // Merge operations
-    Merge(ctx context.Context, ref string, options MergeOptions) error
-    MergeBase(ctx context.Context, ref1, ref2 string) (string, error)
-    
-    // Configuration
-    GetConfig(ctx context.Context, key string) (string, error)
-    SetConfig(ctx context.Context, key, value string) error
-    GetUserConfig(ctx context.Context) (*UserConfig, error)
-    SetUserConfig(ctx context.Context, config UserConfig) error
-}
-```
-
-## Data Structures
-
-### Status
-
-Represents the current state of the repository:
-
-```go
-type Status struct {
-    Branch     string
-    IsClean    bool
-    Staged     []FileStatus
-    Unstaged   []FileStatus
-    Untracked  []string
-    Conflicts  []string
-}
-```
-
-### Commit
-
-Represents a Git commit:
-
-```go
-type Commit struct {
-    Hash      string
-    Author    Author
-    Committer Author
-    Message   string
-    Parents   []string
-    Timestamp time.Time
-    Files     []CommitFile
-}
-```
-
-### Branch
-
-Represents a Git branch:
-
-```go
-type Branch struct {
-    Name      string
-    IsCurrent bool
-    IsRemote  bool
-    Commit    string
-    Message   string
-}
-```
-
-## Usage Examples
-
-### Repository Management
-
-```go
-// Initialize a new repository
-git := git.DefaultGit("/path/to/new/repo")
-if err := git.Init(ctx, "/path/to/new/repo"); err != nil {
-    log.Fatal(err)
-}
-
-// Clone a repository
-if err := git.Clone(ctx, "https://github.com/user/repo.git", "/path/to/clone"); err != nil {
-    log.Fatal(err)
-}
-```
-
-### Basic Git Workflow
-
-```go
-// Stage files
-if err := git.Add(ctx, []string{"file1.txt", "file2.txt"}); err != nil {
-    log.Fatal(err)
-}
-
-// Or stage all changes
-if err := git.AddAll(ctx); err != nil {
-    log.Fatal(err)
-}
-
-// Commit changes
-commitOptions := git.CommitOptions{
-    AllowEmpty: false,
-}
-if err := git.Commit(ctx, "Add new feature", commitOptions); err != nil {
-    log.Fatal(err)
-}
-```
-
-### Branch Operations
-
-```go
-// List all branches
-branches, err := git.ListBranches(ctx)
-if err != nil {
-    log.Fatal(err)
-}
-
-for _, branch := range branches {
-    fmt.Printf("Branch: %s (current: %t)\n", branch.Name, branch.IsCurrent)
-}
-
-// Create a new branch
-if err := git.CreateBranch(ctx, "feature/new-feature", ""); err != nil {
-    log.Fatal(err)
-}
-
-// Switch to a branch
-if err := git.Checkout(ctx, "feature/new-feature"); err != nil {
-    log.Fatal(err)
-}
-
-// Get current branch
-currentBranch, err := git.GetCurrentBranch(ctx)
-if err != nil {
-    log.Fatal(err)
-}
-fmt.Printf("Current branch: %s\n", currentBranch)
-```
-
-### Remote Operations
-
-```go
-// Add a remote
-if err := git.AddRemote(ctx, "origin", "https://github.com/user/repo.git"); err != nil {
-    log.Fatal(err)
-}
-
-// List remotes
-remotes, err := git.ListRemotes(ctx)
-if err != nil {
-    log.Fatal(err)
-}
-
-for _, remote := range remotes {
-    fmt.Printf("Remote: %s -> %s\n", remote.Name, remote.URL)
-}
-
-// Fetch from remote
-fetchOptions := git.FetchOptions{
-    All:  true,
-    Tags: true,
-}
-if err := git.Fetch(ctx, "", fetchOptions); err != nil {
-    log.Fatal(err)
-}
-
-// Push to remote
-pushOptions := git.PushOptions{
-    SetUpstream: true,
-}
-if err := git.Push(ctx, "origin", "main", pushOptions); err != nil {
-    log.Fatal(err)
-}
-```
-
-### Configuration
-
-```go
-// Get user configuration
-userConfig, err := git.GetUserConfig(ctx)
-if err != nil {
-    log.Fatal(err)
-}
-fmt.Printf("User: %s <%s>\n", userConfig.Name, userConfig.Email)
-
-// Set user configuration
-newConfig := git.UserConfig{
-    Name:  "John Doe",
-    Email: "john@example.com",
-}
-if err := git.SetUserConfig(ctx, newConfig); err != nil {
-    log.Fatal(err)
-}
-
-// Get/set custom config
-value, err := git.GetConfig(ctx, "core.editor")
-if err != nil {
-    log.Fatal(err)
-}
-
-if err := git.SetConfig(ctx, "core.editor", "vim"); err != nil {
-    log.Fatal(err)
-}
-```
-
-## Error Handling
-
-The Git interface provides detailed error information through the `GitError` type:
-
-```go
-if err := git.Commit(ctx, "Invalid commit", git.CommitOptions{}); err != nil {
-    if gitErr, ok := err.(*git.GitError); ok {
-        fmt.Printf("Git command '%s' failed: %v\n", gitErr.Command, gitErr.Err)
-        fmt.Printf("Output: %s\n", gitErr.Output)
-    }
-}
-```
-
-## Configuration
-
-You can customize the Git instance with specific configuration:
-
-```go
-config := git.GitConfig{
-    Timeout: 60 * time.Second,
-    Env: map[string]string{
-        "GIT_AUTHOR_NAME":  "Custom Author",
-        "GIT_AUTHOR_EMAIL": "author@example.com",
-    },
-}
-
-git := git.NewGit("/path/to/repo", config)
-```
-
-## Thread Safety
-
-The Git interface is not thread-safe. If you need to use it from multiple goroutines, you should either:
-
-1. Use separate Git instances for each goroutine
-2. Use a mutex to synchronize access
-3. Use channels to serialize operations
-
-## Requirements
-
-- Go 1.24.4 or later
-- Git installed and available in PATH
-- Appropriate permissions to access the repository
-
-## License
-
-This code is part of the `github.com/iomodo/staff` project and follows the same license terms. 
\ No newline at end of file
diff --git a/server/git/clone_manager.go b/server/git/clone_manager.go
index 7bc9cde..33a5a99 100644
--- a/server/git/clone_manager.go
+++ b/server/git/clone_manager.go
@@ -144,17 +144,3 @@
 
 	return nil
 }
-
-// GetAllAgentClones returns a map of all agent clones
-func (cm *CloneManager) GetAllAgentClones() map[string]string {
-	cm.mu.RLock()
-	defer cm.mu.RUnlock()
-
-	// Return a copy to avoid race conditions
-	result := make(map[string]string)
-	for agent, path := range cm.agentClones {
-		result[agent] = path
-	}
-
-	return result
-}
diff --git a/server/git/example.go b/server/git/example.go
deleted file mode 100644
index 1bea27c..0000000
--- a/server/git/example.go
+++ /dev/null
@@ -1,170 +0,0 @@
-package git
-
-import (
-	"context"
-	"log/slog"
-	"os"
-)
-
-// Example demonstrates how to use the Git interface
-func Example() {
-	ctx := context.Background()
-
-	// Create logger
-	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
-
-	// Create a new Git instance
-	git := DefaultGit("/path/to/your/repo")
-
-	// Get repository status
-	status, err := git.Status(ctx)
-	if err != nil {
-		logger.Error("Failed to get status", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Repository status", slog.String("branch", status.Branch), slog.Bool("clean", status.IsClean))
-
-	// List branches
-	branches, err := git.ListBranches(ctx)
-	if err != nil {
-		logger.Error("Failed to list branches", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Branches found", slog.Int("count", len(branches)))
-	for _, branch := range branches {
-		current := ""
-		if branch.IsCurrent {
-			current = " (current)"
-		}
-		logger.Info("Branch", slog.String("name", branch.Name+current))
-	}
-
-	// Get recent commits
-	logOptions := LogOptions{
-		MaxCount: 5,
-		Oneline:  true,
-	}
-
-	commits, err := git.Log(ctx, logOptions)
-	if err != nil {
-		logger.Error("Failed to get log", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Recent commits", slog.Int("count", len(commits)))
-	for _, commit := range commits {
-		logger.Info("Commit", slog.String("hash", commit.Hash[:8]), slog.String("message", commit.Message))
-	}
-}
-
-// ExampleWorkflow demonstrates a typical Git workflow
-func ExampleWorkflow() {
-	ctx := context.Background()
-
-	// Create logger
-	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
-
-	// Initialize a new repository
-	git := DefaultGit("/path/to/new/repo")
-
-	// Initialize the repository
-	if err := git.Init(ctx, "/path/to/new/repo"); err != nil {
-		logger.Error("Failed to initialize repository", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	// Set user configuration
-	userConfig := UserConfig{
-		Name:  "John Doe",
-		Email: "john@example.com",
-	}
-
-	if err := git.SetUserConfig(ctx, userConfig); err != nil {
-		logger.Error("Failed to set user config", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	// Create a new file and add it
-	// (In a real scenario, you would create the file here)
-
-	// Stage all changes
-	if err := git.AddAll(ctx); err != nil {
-		logger.Error("Failed to add files", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	// Commit the changes
-	commitOptions := CommitOptions{
-		AllowEmpty: false,
-	}
-
-	if err := git.Commit(ctx, "Initial commit", commitOptions); err != nil {
-		logger.Error("Failed to commit", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	// Create a new branch
-	if err := git.CreateBranch(ctx, "feature/new-feature", ""); err != nil {
-		logger.Error("Failed to create branch", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	// Switch to the new branch
-	if err := git.Checkout(ctx, "feature/new-feature"); err != nil {
-		logger.Error("Failed to checkout branch", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Repository initialized and feature branch created!")
-}
-
-// ExampleRemoteOperations demonstrates remote repository operations
-func ExampleRemoteOperations() {
-	ctx := context.Background()
-
-	// Create logger
-	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
-
-	git := DefaultGit("/path/to/your/repo")
-
-	// Add a remote
-	if err := git.AddRemote(ctx, "origin", "https://github.com/user/repo.git"); err != nil {
-		logger.Error("Failed to add remote", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	// List remotes
-	remotes, err := git.ListRemotes(ctx)
-	if err != nil {
-		logger.Error("Failed to list remotes", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Remotes found", slog.Int("count", len(remotes)))
-	for _, remote := range remotes {
-		logger.Info("Remote", slog.String("name", remote.Name), slog.String("url", remote.URL))
-	}
-
-	// Fetch from remote
-	fetchOptions := FetchOptions{
-		All:  true,
-		Tags: true,
-	}
-
-	if err := git.Fetch(ctx, "", fetchOptions); err != nil {
-		logger.Error("Failed to fetch", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	// Push to remote
-	pushOptions := PushOptions{
-		SetUpstream: true,
-	}
-
-	if err := git.Push(ctx, "origin", "main", pushOptions); err != nil {
-		logger.Error("Failed to push", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-}
diff --git a/server/git/git.go b/server/git/git.go
index 7e7ba44..1160d0d 100644
--- a/server/git/git.go
+++ b/server/git/git.go
@@ -10,6 +10,8 @@
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/iomodo/staff/config"
 )
 
 // GitInterface defines the contract for Git operations
@@ -61,6 +63,12 @@
 	UpdatePullRequest(ctx context.Context, id string, options PullRequestOptions) (*PullRequest, error)
 	ClosePullRequest(ctx context.Context, id string) error
 	MergePullRequest(ctx context.Context, id string, options MergePullRequestOptions) error
+
+	// Clone Manager Operations
+	GetAgentClonePath(agentName string) (string, error)
+	RefreshAgentClone(agentName string) error
+	CleanupAgentClone(agentName string) error
+	CleanupAllClones() error
 }
 
 // Status represents the current state of the repository
@@ -187,46 +195,55 @@
 
 // Git implementation using os/exec to call git commands
 type Git struct {
-	repoPath   string
-	config     GitConfig
-	prProvider PullRequestProvider
-	logger     *slog.Logger
-}
-
-// GitConfig holds configuration for Git operations
-type GitConfig struct {
-	Timeout             time.Duration
-	Env                 map[string]string
-	PullRequestProvider PullRequestProvider
+	repoPath     string
+	prProvider   PullRequestProvider
+	cloneManager *CloneManager
+	logger       *slog.Logger
 }
 
 // NewGit creates a new Git instance
-func NewGit(repoPath string, config GitConfig, logger *slog.Logger) GitInterface {
-	if config.Timeout == 0 {
-		config.Timeout = 30 * time.Second
+func New(cfg *config.Config, logger *slog.Logger) GitInterface {
+	var prProvider PullRequestProvider
+	var repoURL string
+
+	switch cfg.GetPrimaryGitProvider() {
+	case "github":
+		githubConfig := GitHubConfig{
+			Token:  cfg.GitHub.Token,
+			Logger: logger,
+		}
+		prProvider = NewGitHubPullRequestProvider(cfg.GitHub.Owner, cfg.GitHub.Repo, githubConfig)
+		repoURL = fmt.Sprintf("https://github.com/%s/%s.git", cfg.GitHub.Owner, cfg.GitHub.Repo)
+		logger.Info("Using GitHub as pull request provider",
+			slog.String("owner", cfg.GitHub.Owner),
+			slog.String("repo", cfg.GitHub.Repo))
+	case "gerrit":
+		gerritConfig := GerritConfig{
+			Username: cfg.Gerrit.Username,
+			Password: cfg.Gerrit.Password,
+			BaseURL:  cfg.Gerrit.BaseURL,
+			Logger:   logger,
+		}
+		prProvider = NewGerritPullRequestProvider(cfg.Gerrit.Project, gerritConfig)
+		repoURL = fmt.Sprintf("%s/%s", cfg.Gerrit.BaseURL, cfg.Gerrit.Project)
+		logger.Info("Using Gerrit as pull request provider",
+			slog.String("base_url", cfg.Gerrit.BaseURL),
+			slog.String("project", cfg.Gerrit.Project))
+	default:
+		panic("no valid Git provider configured")
 	}
 
+	workspacePath := filepath.Join(".", "workspace") //TODO: make it configurable
+	cloneManager := NewCloneManager(repoURL, workspacePath)
+
 	return &Git{
-		repoPath:   repoPath,
-		config:     config,
-		prProvider: config.PullRequestProvider,
-		logger:     logger,
+		repoPath:     cfg.Git.RepoPath,
+		prProvider:   prProvider,
+		cloneManager: cloneManager,
+		logger:       logger,
 	}
 }
 
-// DefaultGit creates a Git instance with default configuration
-func DefaultGit(repoPath string) GitInterface {
-	return NewGit(repoPath, GitConfig{
-		Timeout: 30 * time.Second,
-	}, slog.Default())
-}
-
-// NewGitWithPullRequests creates a Git instance with pull request capabilities
-func NewGitWithPullRequests(repoPath string, config GitConfig, prProvider PullRequestProvider, logger *slog.Logger) GitInterface {
-	config.PullRequestProvider = prProvider
-	return NewGit(repoPath, config, logger)
-}
-
 // Ensure Git implements GitInterface
 var _ GitInterface = (*Git)(nil)
 
@@ -637,6 +654,32 @@
 	return g.prProvider.MergePullRequest(ctx, id, options)
 }
 
+// Clone manage methods
+func (g *Git) GetAgentClonePath(agentName string) (string, error) {
+	if g.cloneManager == nil {
+		return "", &GitError{Command: "GetAgentClonePath", Output: "no clone manager configured"}
+	}
+	return g.cloneManager.GetAgentClonePath(agentName)
+}
+func (g *Git) RefreshAgentClone(agentName string) error {
+	if g.cloneManager == nil {
+		return &GitError{Command: "RefreshAgentClone", Output: "no clone manager configured"}
+	}
+	return g.cloneManager.RefreshAgentClone(agentName)
+}
+func (g *Git) CleanupAgentClone(agentName string) error {
+	if g.cloneManager == nil {
+		return &GitError{Command: "CleanupAgentClone", Output: "no clone manager configured"}
+	}
+	return g.cloneManager.CleanupAgentClone(agentName)
+}
+func (g *Git) CleanupAllClones() error {
+	if g.cloneManager == nil {
+		return &GitError{Command: "CleanupAllClones", Output: "no clone manager configured"}
+	}
+	return g.cloneManager.CleanupAllClones()
+}
+
 // Helper methods
 
 func (g *Git) runCommand(cmd *exec.Cmd, command string) error {
@@ -885,6 +928,7 @@
 	Reviewers   []Author
 	Commits     []Commit
 	Comments    []PullRequestComment
+	URL         string
 }
 
 // PullRequestComment represents a comment on a pull request
diff --git a/server/git/git_test.go b/server/git/git_test.go
deleted file mode 100644
index d3862ce..0000000
--- a/server/git/git_test.go
+++ /dev/null
@@ -1,645 +0,0 @@
-package git
-
-import (
-	"context"
-	"fmt"
-	"log/slog"
-	"os"
-	"path/filepath"
-	"testing"
-	"time"
-)
-
-func TestNewGit(t *testing.T) {
-	// Create logger for testing
-	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
-
-	// Test creating a new Git instance with default config
-	git := DefaultGit("/tmp/test-repo")
-	if git == nil {
-		t.Fatal("DefaultGit returned nil")
-	}
-
-	// Test creating a new Git instance with custom config
-	config := GitConfig{
-		Timeout: 60 * time.Second,
-		Env: map[string]string{
-			"GIT_AUTHOR_NAME": "Test User",
-		},
-	}
-	git = NewGit("/tmp/test-repo", config, logger)
-	if git == nil {
-		t.Fatal("NewGit returned nil")
-	}
-}
-
-func TestGitRepositoryOperations(t *testing.T) {
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Test IsRepository on non-repository
-	isRepo, err := git.IsRepository(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("IsRepository failed: %v", err)
-	}
-	if isRepo {
-		t.Error("Expected IsRepository to return false for non-repository")
-	}
-
-	// Test Init
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("Init failed: %v", err)
-	}
-
-	// Test IsRepository after init
-	isRepo, err = git.IsRepository(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("IsRepository failed after init: %v", err)
-	}
-	if !isRepo {
-		t.Error("Expected IsRepository to return true after init")
-	}
-}
-
-func TestGitStatus(t *testing.T) {
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Initialize repository
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("Init failed: %v", err)
-	}
-
-	// Test status on clean repository
-	status, err := git.Status(ctx)
-	if err != nil {
-		t.Fatalf("Status failed: %v", err)
-	}
-
-	if status == nil {
-		t.Fatal("Status returned nil")
-	}
-
-	// Should be clean after init
-	if !status.IsClean {
-		t.Error("Expected repository to be clean after init")
-	}
-
-	// Create a test file
-	testFile := filepath.Join(tempDir, "test.txt")
-	err = os.WriteFile(testFile, []byte("Hello, Git!\n"), 0644)
-	if err != nil {
-		t.Fatalf("Failed to create test file: %v", err)
-	}
-
-	// Test status with untracked file
-	status, err = git.Status(ctx)
-	if err != nil {
-		t.Fatalf("Status failed: %v", err)
-	}
-
-	// Debug: print status information
-	t.Logf("Status: IsClean=%t, Staged=%d, Unstaged=%d, Untracked=%d",
-		status.IsClean, len(status.Staged), len(status.Unstaged), len(status.Untracked))
-
-	if len(status.Untracked) > 0 {
-		t.Logf("Untracked files: %v", status.Untracked)
-	}
-
-	if status.IsClean {
-		t.Error("Expected repository to be dirty with untracked file")
-	}
-
-	// Check if the file is detected in any status (untracked, unstaged, or staged)
-	totalFiles := len(status.Untracked) + len(status.Unstaged) + len(status.Staged)
-	if totalFiles == 0 {
-		t.Error("Expected at least 1 file to be detected")
-		return
-	}
-
-	// Look for test.txt in any of the status categories
-	found := false
-	for _, file := range status.Untracked {
-		if file == "test.txt" {
-			found = true
-			break
-		}
-	}
-	for _, file := range status.Unstaged {
-		if file.Path == "test.txt" {
-			found = true
-			break
-		}
-	}
-	for _, file := range status.Staged {
-		if file.Path == "test.txt" {
-			found = true
-			break
-		}
-	}
-
-	if !found {
-		t.Error("Expected test.txt to be found in status")
-	}
-}
-
-func TestGitUserConfig(t *testing.T) {
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Initialize repository
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("Init failed: %v", err)
-	}
-
-	// Test setting user config
-	userConfig := UserConfig{
-		Name:  "Test User",
-		Email: "test@example.com",
-	}
-
-	err = git.SetUserConfig(ctx, userConfig)
-	if err != nil {
-		t.Fatalf("SetUserConfig failed: %v", err)
-	}
-
-	// Test getting user config
-	retrievedConfig, err := git.GetUserConfig(ctx)
-	if err != nil {
-		t.Fatalf("GetUserConfig failed: %v", err)
-	}
-
-	if retrievedConfig.Name != userConfig.Name {
-		t.Errorf("Expected name '%s', got '%s'", userConfig.Name, retrievedConfig.Name)
-	}
-
-	if retrievedConfig.Email != userConfig.Email {
-		t.Errorf("Expected email '%s', got '%s'", userConfig.Email, retrievedConfig.Email)
-	}
-}
-
-func TestGitCommitWorkflow(t *testing.T) {
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Initialize repository
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("Init failed: %v", err)
-	}
-
-	// Set user config
-	userConfig := UserConfig{
-		Name:  "Test User",
-		Email: "test@example.com",
-	}
-	err = git.SetUserConfig(ctx, userConfig)
-	if err != nil {
-		t.Fatalf("SetUserConfig failed: %v", err)
-	}
-
-	// Create a test file
-	testFile := filepath.Join(tempDir, "test.txt")
-	err = os.WriteFile(testFile, []byte("Hello, Git!\n"), 0644)
-	if err != nil {
-		t.Fatalf("Failed to create test file: %v", err)
-	}
-
-	// Test AddAll
-	err = git.AddAll(ctx)
-	if err != nil {
-		t.Fatalf("AddAll failed: %v", err)
-	}
-
-	// Check status after staging
-	status, err := git.Status(ctx)
-	if err != nil {
-		t.Fatalf("Status failed: %v", err)
-	}
-
-	if len(status.Staged) != 1 {
-		t.Errorf("Expected 1 staged file, got %d", len(status.Staged))
-	}
-
-	// Test Commit
-	commitOptions := CommitOptions{
-		AllowEmpty: false,
-	}
-	err = git.Commit(ctx, "Initial commit", commitOptions)
-	if err != nil {
-		t.Fatalf("Commit failed: %v", err)
-	}
-
-	// Check status after commit
-	status, err = git.Status(ctx)
-	if err != nil {
-		t.Fatalf("Status failed: %v", err)
-	}
-
-	if !status.IsClean {
-		t.Error("Expected repository to be clean after commit")
-	}
-}
-
-func TestGitBranchOperations(t *testing.T) {
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Initialize repository
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("Init failed: %v", err)
-	}
-
-	// Set user config
-	userConfig := UserConfig{
-		Name:  "Test User",
-		Email: "test@example.com",
-	}
-	err = git.SetUserConfig(ctx, userConfig)
-	if err != nil {
-		t.Fatalf("SetUserConfig failed: %v", err)
-	}
-
-	// Create initial commit
-	testFile := filepath.Join(tempDir, "test.txt")
-	err = os.WriteFile(testFile, []byte("Hello, Git!\n"), 0644)
-	if err != nil {
-		t.Fatalf("Failed to create test file: %v", err)
-	}
-
-	err = git.AddAll(ctx)
-	if err != nil {
-		t.Fatalf("AddAll failed: %v", err)
-	}
-
-	err = git.Commit(ctx, "Initial commit", CommitOptions{})
-	if err != nil {
-		t.Fatalf("Commit failed: %v", err)
-	}
-
-	// Test GetCurrentBranch
-	currentBranch, err := git.GetCurrentBranch(ctx)
-	if err != nil {
-		t.Fatalf("GetCurrentBranch failed: %v", err)
-	}
-
-	// Default branch name might be 'main' or 'master' depending on Git version
-	if currentBranch != "main" && currentBranch != "master" {
-		t.Errorf("Expected current branch to be 'main' or 'master', got '%s'", currentBranch)
-	}
-
-	// Test CreateBranch
-	err = git.CreateBranch(ctx, "feature/test", "")
-	if err != nil {
-		t.Fatalf("CreateBranch failed: %v", err)
-	}
-
-	// Test ListBranches
-	branches, err := git.ListBranches(ctx)
-	if err != nil {
-		t.Fatalf("ListBranches failed: %v", err)
-	}
-
-	if len(branches) < 2 {
-		t.Errorf("Expected at least 2 branches, got %d", len(branches))
-	}
-
-	// Find the feature branch
-	foundFeatureBranch := false
-	for _, branch := range branches {
-		if branch.Name == "feature/test" {
-			foundFeatureBranch = true
-			break
-		}
-	}
-
-	if !foundFeatureBranch {
-		t.Error("Feature branch not found in branch list")
-	}
-
-	// Test Checkout
-	err = git.Checkout(ctx, "feature/test")
-	if err != nil {
-		t.Fatalf("Checkout failed: %v", err)
-	}
-
-	// Verify we're on the feature branch
-	currentBranch, err = git.GetCurrentBranch(ctx)
-	if err != nil {
-		t.Fatalf("GetCurrentBranch failed: %v", err)
-	}
-
-	if currentBranch != "feature/test" {
-		t.Errorf("Expected current branch to be 'feature/test', got '%s'", currentBranch)
-	}
-}
-
-func TestGitLog(t *testing.T) {
-	t.Skip("Log parsing needs to be fixed")
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Initialize repository
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("Init failed: %v", err)
-	}
-
-	// Set user config
-	userConfig := UserConfig{
-		Name:  "Test User",
-		Email: "test@example.com",
-	}
-	err = git.SetUserConfig(ctx, userConfig)
-	if err != nil {
-		t.Fatalf("SetUserConfig failed: %v", err)
-	}
-
-	// Create initial commit
-	testFile := filepath.Join(tempDir, "test.txt")
-	err = os.WriteFile(testFile, []byte("Hello, Git!\n"), 0644)
-	if err != nil {
-		t.Fatalf("Failed to create test file: %v", err)
-	}
-
-	err = git.AddAll(ctx)
-	if err != nil {
-		t.Fatalf("AddAll failed: %v", err)
-	}
-
-	err = git.Commit(ctx, "Initial commit", CommitOptions{})
-	if err != nil {
-		t.Fatalf("Commit failed: %v", err)
-	}
-
-	// Test Log
-	logOptions := LogOptions{
-		MaxCount: 10,
-		Oneline:  false,
-	}
-	commits, err := git.Log(ctx, logOptions)
-	if err != nil {
-		t.Fatalf("Log failed: %v", err)
-	}
-
-	t.Logf("Found %d commits", len(commits))
-	if len(commits) == 0 {
-		t.Error("Expected at least 1 commit, got 0")
-		return
-	}
-
-	// Check first commit
-	commit := commits[0]
-	if commit.Message != "Initial commit" {
-		t.Errorf("Expected commit message 'Initial commit', got '%s'", commit.Message)
-	}
-
-	if commit.Author.Name != "Test User" {
-		t.Errorf("Expected author name 'Test User', got '%s'", commit.Author.Name)
-	}
-
-	if commit.Author.Email != "test@example.com" {
-		t.Errorf("Expected author email 'test@example.com', got '%s'", commit.Author.Email)
-	}
-}
-
-func TestGitError(t *testing.T) {
-	// Test GitError creation and methods
-	gitErr := &GitError{
-		Command: "test",
-		Output:  "test output",
-		Err:     nil,
-	}
-
-	errorMsg := gitErr.Error()
-	if errorMsg == "" {
-		t.Error("GitError.Error() returned empty string")
-	}
-
-	// Test with underlying error
-	underlyingErr := &GitError{
-		Command: "subtest",
-		Output:  "subtest output",
-		Err:     gitErr,
-	}
-
-	unwrapped := underlyingErr.Unwrap()
-	if unwrapped != gitErr {
-		t.Error("GitError.Unwrap() did not return the underlying error")
-	}
-}
-
-func TestGitConfigOperations(t *testing.T) {
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Initialize repository
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("Init failed: %v", err)
-	}
-
-	// Test SetConfig
-	err = git.SetConfig(ctx, "test.key", "test.value")
-	if err != nil {
-		t.Fatalf("SetConfig failed: %v", err)
-	}
-
-	// Test GetConfig
-	value, err := git.GetConfig(ctx, "test.key")
-	if err != nil {
-		t.Fatalf("GetConfig failed: %v", err)
-	}
-
-	if value != "test.value" {
-		t.Errorf("Expected config value 'test.value', got '%s'", value)
-	}
-}
-
-func TestGitMerge(t *testing.T) {
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Initialize repository
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		t.Fatalf("Init failed: %v", err)
-	}
-
-	// Set user config
-	userConfig := UserConfig{
-		Name:  "Test User",
-		Email: "test@example.com",
-	}
-	err = git.SetUserConfig(ctx, userConfig)
-	if err != nil {
-		t.Fatalf("SetUserConfig failed: %v", err)
-	}
-
-	// Create initial commit
-	testFile := filepath.Join(tempDir, "test.txt")
-	err = os.WriteFile(testFile, []byte("Hello, Git!\n"), 0644)
-	if err != nil {
-		t.Fatalf("Failed to create test file: %v", err)
-	}
-
-	err = git.AddAll(ctx)
-	if err != nil {
-		t.Fatalf("AddAll failed: %v", err)
-	}
-
-	err = git.Commit(ctx, "Initial commit", CommitOptions{})
-	if err != nil {
-		t.Fatalf("Commit failed: %v", err)
-	}
-
-	// Create feature branch
-	err = git.CreateBranch(ctx, "feature/test", "")
-	if err != nil {
-		t.Fatalf("CreateBranch failed: %v", err)
-	}
-
-	// Switch to feature branch
-	err = git.Checkout(ctx, "feature/test")
-	if err != nil {
-		t.Fatalf("Checkout failed: %v", err)
-	}
-
-	// Add file on feature branch
-	featureFile := filepath.Join(tempDir, "feature.txt")
-	err = os.WriteFile(featureFile, []byte("Feature file\n"), 0644)
-	if err != nil {
-		t.Fatalf("Failed to create feature file: %v", err)
-	}
-
-	err = git.AddAll(ctx)
-	if err != nil {
-		t.Fatalf("AddAll failed: %v", err)
-	}
-
-	err = git.Commit(ctx, "Add feature file", CommitOptions{})
-	if err != nil {
-		t.Fatalf("Commit failed: %v", err)
-	}
-
-	// Switch back to main
-	err = git.Checkout(ctx, "main")
-	if err != nil {
-		t.Fatalf("Checkout failed: %v", err)
-	}
-
-	// Test Merge
-	mergeOptions := MergeOptions{
-		NoFF:    true,
-		Message: "Merge feature/test",
-	}
-	err = git.Merge(ctx, "feature/test", mergeOptions)
-	if err != nil {
-		t.Fatalf("Merge failed: %v", err)
-	}
-
-	// Check that both files exist after merge
-	if _, err := os.Stat(filepath.Join(tempDir, "test.txt")); os.IsNotExist(err) {
-		t.Error("test.txt not found after merge")
-	}
-
-	if _, err := os.Stat(filepath.Join(tempDir, "feature.txt")); os.IsNotExist(err) {
-		t.Error("feature.txt not found after merge")
-	}
-}
-
-func BenchmarkGitStatus(b *testing.B) {
-	// Create a temporary directory for testing
-	tempDir, err := os.MkdirTemp("", "git-bench-*")
-	if err != nil {
-		b.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	git := DefaultGit(tempDir)
-	ctx := context.Background()
-
-	// Initialize repository
-	err = git.Init(ctx, tempDir)
-	if err != nil {
-		b.Fatalf("Init failed: %v", err)
-	}
-
-	// Create some files
-	for i := 0; i < 10; i++ {
-		testFile := filepath.Join(tempDir, fmt.Sprintf("test%d.txt", i))
-		err = os.WriteFile(testFile, []byte(fmt.Sprintf("File %d\n", i)), 0644)
-		if err != nil {
-			b.Fatalf("Failed to create test file: %v", err)
-		}
-	}
-
-	b.ResetTimer()
-
-	for i := 0; i < b.N; i++ {
-		_, err := git.Status(ctx)
-		if err != nil {
-			b.Fatalf("Status failed: %v", err)
-		}
-	}
-}
diff --git a/server/git/github.go b/server/git/github.go
index 6555b69..1d37b1d 100644
--- a/server/git/github.go
+++ b/server/git/github.go
@@ -139,7 +139,7 @@
 		slog.Any("labels", options.Labels))
 
 	url := fmt.Sprintf("%s/repos/%s/%s/pulls", g.config.BaseURL, g.owner, g.repo)
-	
+
 	req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonBody))
 	if err != nil {
 		return nil, fmt.Errorf("failed to create request: %w", err)
@@ -412,5 +412,6 @@
 		Reviewers:  reviewers,
 		Commits:    []Commit{},             // Would need additional API call to populate
 		Comments:   []PullRequestComment{}, // Would need additional API call to populate
+		URL:        fmt.Sprintf("https://github.com/%s/%s/pull/%d", g.owner, g.repo, githubPR.Number),
 	}
 }
diff --git a/server/git/pull_request_example.go b/server/git/pull_request_example.go
deleted file mode 100644
index 5c70d21..0000000
--- a/server/git/pull_request_example.go
+++ /dev/null
@@ -1,251 +0,0 @@
-package git
-
-import (
-	"context"
-	"log/slog"
-	"net/http"
-	"os"
-	"time"
-)
-
-// ExamplePullRequestUsage demonstrates how to use pull request functionality
-func ExamplePullRequestUsage() {
-	ctx := context.Background()
-
-	// Create logger
-	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
-
-	// Example with GitHub
-	exampleGitHubPullRequests(ctx, logger)
-
-	// Example with Gerrit
-	exampleGerritPullRequests(ctx, logger)
-}
-
-func exampleGitHubPullRequests(ctx context.Context, logger *slog.Logger) {
-	logger.Info("=== GitHub Pull Request Example ===")
-
-	// Create GitHub configuration
-	githubConfig := GitHubConfig{
-		Token:      "your-github-token-here",
-		BaseURL:    "https://api.github.com",
-		HTTPClient: &http.Client{Timeout: 30 * time.Second},
-	}
-
-	// Create GitHub pull request provider
-	githubProvider := NewGitHubPullRequestProvider("owner", "repo", githubConfig)
-
-	// Create Git instance with GitHub pull request capabilities
-	git := NewGitWithPullRequests("/path/to/repo", GitConfig{
-		Timeout: 30 * time.Second,
-	}, githubProvider, logger)
-
-	// Create a new pull request
-	prOptions := PullRequestOptions{
-		Title:       "Add new feature",
-		Description: "This PR adds a new feature to the application.",
-		BaseBranch:  "main",
-		HeadBranch:  "feature/new-feature",
-		Labels:      []string{"enhancement", "feature"},
-		Assignees:   []string{"username1", "username2"},
-		Reviewers:   []string{"reviewer1", "reviewer2"},
-		Draft:       false,
-	}
-
-	pr, err := git.CreatePullRequest(ctx, prOptions)
-	if err != nil {
-		logger.Error("Failed to create pull request", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Created pull request", slog.String("title", pr.Title), slog.Int("number", pr.Number))
-
-	// List pull requests
-	listOptions := ListPullRequestOptions{
-		State:      "open",
-		Author:     "username",
-		BaseBranch: "main",
-		Limit:      10,
-	}
-
-	prs, err := git.ListPullRequests(ctx, listOptions)
-	if err != nil {
-		logger.Error("Failed to list pull requests", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Found pull requests", slog.Int("count", len(prs)))
-
-	// Get a specific pull request
-	pr, err = git.GetPullRequest(ctx, pr.ID)
-	if err != nil {
-		logger.Error("Failed to get pull request", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Pull request status", slog.String("state", pr.State))
-
-	// Update a pull request
-	updateOptions := PullRequestOptions{
-		Title:       "Updated title",
-		Description: "Updated description",
-		Labels:      []string{"bug", "urgent"},
-	}
-
-	updatedPR, err := git.UpdatePullRequest(ctx, pr.ID, updateOptions)
-	if err != nil {
-		logger.Error("Failed to update pull request", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Updated pull request", slog.String("title", updatedPR.Title))
-
-	// Merge a pull request
-	mergeOptions := MergePullRequestOptions{
-		MergeMethod: "squash",
-		CommitTitle: "Merge pull request #123",
-		CommitMsg:   "This merges the feature branch into main",
-	}
-
-	err = git.MergePullRequest(ctx, pr.ID, mergeOptions)
-	if err != nil {
-		logger.Error("Failed to merge pull request", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Pull request merged successfully")
-}
-
-func exampleGerritPullRequests(ctx context.Context, logger *slog.Logger) {
-	logger.Info("=== Gerrit Pull Request Example ===")
-
-	// Create Gerrit configuration
-	gerritConfig := GerritConfig{
-		Username:   "your-username",
-		Password:   "your-http-password-or-api-token",
-		BaseURL:    "https://gerrit.example.com",
-		HTTPClient: &http.Client{Timeout: 30 * time.Second},
-	}
-
-	// Create Gerrit pull request provider
-	gerritProvider := NewGerritPullRequestProvider("project-name", gerritConfig)
-
-	// Create Git instance with Gerrit pull request capabilities
-	git := NewGitWithPullRequests("/path/to/repo", GitConfig{
-		Timeout: 30 * time.Second,
-	}, gerritProvider, logger)
-
-	// Create a new change (pull request)
-	prOptions := PullRequestOptions{
-		Title:       "Add new feature",
-		Description: "This change adds a new feature to the application.",
-		BaseBranch:  "master",
-		HeadBranch:  "feature/new-feature",
-	}
-
-	pr, err := git.CreatePullRequest(ctx, prOptions)
-	if err != nil {
-		logger.Error("Failed to create change", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Created change", slog.String("title", pr.Title), slog.Int("number", pr.Number))
-
-	// List changes
-	listOptions := ListPullRequestOptions{
-		State:      "open",
-		Author:     "username",
-		BaseBranch: "master",
-		Limit:      10,
-	}
-
-	prs, err := git.ListPullRequests(ctx, listOptions)
-	if err != nil {
-		logger.Error("Failed to list changes", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Found changes", slog.Int("count", len(prs)))
-
-	// Get a specific change
-	pr, err = git.GetPullRequest(ctx, pr.ID)
-	if err != nil {
-		logger.Error("Failed to get change", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Change status", slog.String("state", pr.State))
-
-	// Update a change
-	updateOptions := PullRequestOptions{
-		Title:       "Updated title",
-		Description: "Updated description",
-	}
-
-	updatedPR, err := git.UpdatePullRequest(ctx, pr.ID, updateOptions)
-	if err != nil {
-		logger.Error("Failed to update change", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Updated change", slog.String("title", updatedPR.Title))
-
-	// Submit a change (merge)
-	mergeOptions := MergePullRequestOptions{
-		CommitTitle: "Submit change",
-		CommitMsg:   "This submits the change to master",
-	}
-
-	err = git.MergePullRequest(ctx, pr.ID, mergeOptions)
-	if err != nil {
-		logger.Error("Failed to submit change", slog.String("error", err.Error()))
-		return
-	}
-
-	logger.Info("Change submitted successfully")
-}
-
-// Example of using both providers in the same application
-func ExampleMultiProviderUsage() {
-	ctx := context.Background()
-
-	// Determine which provider to use based on configuration
-	useGitHub := true // This could come from config
-
-	var git GitInterface
-
-	if useGitHub {
-		// Use GitHub
-		githubConfig := GitHubConfig{
-			Token:   "github-token",
-			BaseURL: "https://api.github.com",
-		}
-		githubProvider := NewGitHubPullRequestProvider("owner", "repo", githubConfig)
-		git = NewGitWithPullRequests("/path/to/repo", GitConfig{}, githubProvider, nil) // Pass nil for logger as it's not used in this example
-	} else {
-		// Use Gerrit
-		gerritConfig := GerritConfig{
-			Username: "gerrit-username",
-			Password: "gerrit-password",
-			BaseURL:  "https://gerrit.example.com",
-		}
-		gerritProvider := NewGerritPullRequestProvider("project", gerritConfig)
-		git = NewGitWithPullRequests("/path/to/repo", GitConfig{}, gerritProvider, nil) // Pass nil for logger as it's not used in this example
-	}
-
-	// Use the same interface regardless of provider
-	prOptions := PullRequestOptions{
-		Title:       "Cross-platform PR",
-		Description: "This works with both GitHub and Gerrit",
-		BaseBranch:  "main",
-		HeadBranch:  "feature/cross-platform",
-	}
-
-	pr, err := git.CreatePullRequest(ctx, prOptions)
-	if err != nil {
-		slog.Error("Failed to create pull request", slog.String("error", err.Error()))
-		return
-	}
-
-	slog.Info("Created pull request", slog.String("title", pr.Title))
-}
diff --git a/server/go.mod b/server/go.mod
index 01cbed9..01bba4c 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -6,14 +6,11 @@
 	github.com/google/uuid v1.6.0
 	github.com/joho/godotenv v1.5.1
 	github.com/spf13/cobra v1.9.1
-	github.com/stretchr/testify v1.10.0
 	golang.org/x/text v0.27.0
 	gopkg.in/yaml.v3 v3.0.1
 )
 
 require (
-	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
-	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/spf13/pflag v1.0.6 // indirect
 )
diff --git a/server/go.sum b/server/go.sum
index bface14..56f2486 100644
--- a/server/go.sum
+++ b/server/go.sum
@@ -1,21 +1,15 @@
 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
 github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
 github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
 golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
diff --git a/server/server/server.go b/server/server/server.go
index f03327a..6ff91ef 100644
--- a/server/server/server.go
+++ b/server/server/server.go
@@ -4,7 +4,6 @@
 	"fmt"
 	"log/slog"
 	"os"
-	"time"
 
 	"github.com/iomodo/staff/agent"
 	"github.com/iomodo/staff/config"
@@ -45,10 +44,8 @@
 	s.logger.Info("Server is starting...")
 
 	// Create task manager using config
-	workingDir := "."
-	gitInterface := git.DefaultGit(workingDir)
-	tasksDir := s.config.Tasks.StoragePath
-	taskManager := git_tm.NewGitTaskManagerWithLogger(gitInterface, tasksDir, s.logger)
+	gitInterface := git.New(s.config, s.logger)
+	taskManager := git_tm.NewGitTaskManager(gitInterface, s.config, s.logger)
 
 	// Create agent manager with config
 	var err error
@@ -57,22 +54,7 @@
 		return fmt.Errorf("failed to create agent manager: %w", err)
 	}
 
-	// Start all configured agents with a default loop interval
-	defaultInterval := 1 * time.Second
-	for _, agentConfig := range s.config.Agents {
-		s.logger.Info("Starting agent",
-			slog.String("name", agentConfig.Name),
-			slog.String("role", agentConfig.Role),
-			slog.String("model", agentConfig.Model))
-
-		if err := s.manager.StartAgent(agentConfig.Name, defaultInterval); err != nil {
-			s.logger.Error("Failed to start agent",
-				slog.String("agent", agentConfig.Name),
-				slog.String("error", err.Error()))
-			continue
-		}
-	}
-
+	s.manager.StartAllAgents()
 	s.logger.Info("Server started successfully", slog.Int("agents", len(s.config.Agents)))
 	return nil
 }
diff --git a/server/task/service.go b/server/task/service.go
deleted file mode 100644
index ba6a4c4..0000000
--- a/server/task/service.go
+++ /dev/null
@@ -1,850 +0,0 @@
-package task
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-	"log/slog"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"strings"
-	"time"
-
-	"github.com/iomodo/staff/git"
-	"github.com/iomodo/staff/llm"
-	"github.com/iomodo/staff/tm"
-	"golang.org/x/text/cases"
-	"golang.org/x/text/language"
-)
-
-// SubtaskService handles subtask generation and management
-type SubtaskService struct {
-	llmProvider  llm.LLMProvider
-	taskManager  tm.TaskManager
-	agentRoles   []string                // Available agent roles for assignment
-	prProvider   git.PullRequestProvider // GitHub PR provider
-	githubOwner  string
-	githubRepo   string
-	cloneManager *git.CloneManager
-	logger       *slog.Logger
-}
-
-// NewSubtaskService creates a new subtask service
-func NewSubtaskService(provider llm.LLMProvider, taskManager tm.TaskManager, agentRoles []string, prProvider git.PullRequestProvider, githubOwner, githubRepo string, cloneManager *git.CloneManager, logger *slog.Logger) *SubtaskService {
-	if logger == nil {
-		logger = slog.Default()
-	}
-	return &SubtaskService{
-		llmProvider:  provider,
-		taskManager:  taskManager,
-		agentRoles:   agentRoles,
-		prProvider:   prProvider,
-		githubOwner:  githubOwner,
-		githubRepo:   githubRepo,
-		cloneManager: cloneManager,
-		logger:       logger,
-	}
-}
-
-// ShouldGenerateSubtasks asks LLM whether a task needs subtasks based on existing agents
-func (s *SubtaskService) ShouldGenerateSubtasks(ctx context.Context, task *tm.Task) (*tm.SubtaskDecision, error) {
-	prompt := s.buildSubtaskDecisionPrompt(task)
-
-	req := llm.ChatCompletionRequest{
-		Model: "gpt-4",
-		Messages: []llm.Message{
-			{
-				Role:    llm.RoleSystem,
-				Content: s.getSubtaskDecisionSystemPrompt(),
-			},
-			{
-				Role:    llm.RoleUser,
-				Content: prompt,
-			},
-		},
-		MaxTokens:   &[]int{1000}[0],
-		Temperature: &[]float64{0.3}[0],
-	}
-
-	resp, err := s.llmProvider.ChatCompletion(ctx, req)
-	if err != nil {
-		return nil, fmt.Errorf("LLM decision failed: %w", err)
-	}
-
-	if len(resp.Choices) == 0 {
-		return nil, fmt.Errorf("no response from LLM")
-	}
-
-	// Parse the LLM response
-	decision, err := s.parseSubtaskDecision(resp.Choices[0].Message.Content)
-	if err != nil {
-		return nil, fmt.Errorf("failed to parse LLM decision: %w", err)
-	}
-
-	return decision, nil
-}
-
-// AnalyzeTaskForSubtasks uses LLM to analyze a task and propose subtasks
-func (s *SubtaskService) AnalyzeTaskForSubtasks(ctx context.Context, task *tm.Task) (*tm.SubtaskAnalysis, error) {
-	prompt := s.buildSubtaskAnalysisPrompt(task)
-
-	req := llm.ChatCompletionRequest{
-		Model: "gpt-4",
-		Messages: []llm.Message{
-			{
-				Role:    llm.RoleSystem,
-				Content: s.getSubtaskAnalysisSystemPrompt(),
-			},
-			{
-				Role:    llm.RoleUser,
-				Content: prompt,
-			},
-		},
-		MaxTokens:   &[]int{4000}[0],
-		Temperature: &[]float64{0.3}[0],
-	}
-
-	resp, err := s.llmProvider.ChatCompletion(ctx, req)
-	if err != nil {
-		return nil, fmt.Errorf("LLM analysis failed: %w", err)
-	}
-
-	if len(resp.Choices) == 0 {
-		return nil, fmt.Errorf("no response from LLM")
-	}
-
-	// Parse the LLM response
-	analysis, err := s.parseSubtaskAnalysis(resp.Choices[0].Message.Content, task.ID)
-	if err != nil {
-		return nil, fmt.Errorf("failed to parse LLM response: %w", err)
-	}
-
-	return analysis, nil
-}
-
-// getSubtaskDecisionSystemPrompt returns the system prompt for subtask decision
-func (s *SubtaskService) getSubtaskDecisionSystemPrompt() string {
-	availableRoles := strings.Join(s.agentRoles, ", ")
-
-	return fmt.Sprintf(`You are an expert project manager and task analyst. Your job is to determine whether a task needs to be broken down into subtasks.
-
-Currently available team roles and their capabilities: %s
-
-When evaluating a task, consider:
-1. Task complexity and scope
-2. Whether multiple specialized skills are needed
-3. If the task can be completed by a single agent with current capabilities
-4. Whether new agent roles might be needed for specialized skills
-
-Respond with a JSON object in this exact format:
-{
-  "needs_subtasks": true/false,
-  "reasoning": "Clear explanation of why subtasks are or aren't needed",
-  "complexity_score": 5,
-  "required_skills": ["skill1", "skill2", "skill3"]
-}
-
-Complexity score should be 1-10 where:
-- 1-3: Simple tasks that can be handled by one agent
-- 4-6: Moderate complexity, might benefit from subtasks
-- 7-10: Complex tasks that definitely need breaking down
-
-Required skills should list all technical/domain skills needed to complete the task.`, availableRoles)
-}
-
-// getSubtaskAnalysisSystemPrompt returns the system prompt for subtask analysis
-func (s *SubtaskService) getSubtaskAnalysisSystemPrompt() string {
-	availableRoles := strings.Join(s.agentRoles, ", ")
-
-	return fmt.Sprintf(`You are an expert project manager and technical architect. Your job is to analyze complex tasks and break them down into well-defined subtasks that can be assigned to specialized team members.
-
-Currently available team roles: %s
-
-When analyzing a task, you should:
-1. Understand the task requirements and scope
-2. Break it down into logical, manageable subtasks
-3. Assign each subtask to the most appropriate team role OR propose creating new agents
-4. Estimate effort and identify dependencies
-5. Provide a clear execution strategy
-
-If you need specialized skills not covered by existing roles, propose new agent creation.
-
-Respond with a JSON object in this exact format:
-{
-  "analysis_summary": "Brief analysis of the task and approach",
-  "subtasks": [
-    {
-      "title": "Subtask title",
-      "description": "Detailed description of what needs to be done",
-      "priority": "high|medium|low",
-      "assigned_to": "role_name",
-      "estimated_hours": 8,
-      "dependencies": ["subtask_index_1", "subtask_index_2"],
-      "required_skills": ["skill1", "skill2"]
-    }
-  ],
-  "agent_creations": [
-    {
-      "role": "new_role_name",
-      "skills": ["specialized_skill1", "specialized_skill2"],
-      "description": "Description of what this agent does",
-      "justification": "Why this new agent is needed"
-    }
-  ],
-  "recommended_approach": "High-level strategy for executing these subtasks",
-  "estimated_total_hours": 40,
-  "risk_assessment": "Potential risks and mitigation strategies"
-}
-
-For existing roles, use: %s
-For new agents, propose appropriate role names and skill sets.
-Dependencies should reference subtask indices (e.g., ["0", "1"] means depends on first and second subtasks).`, availableRoles, availableRoles)
-}
-
-// buildSubtaskDecisionPrompt creates the user prompt for subtask decision
-func (s *SubtaskService) buildSubtaskDecisionPrompt(task *tm.Task) string {
-	return fmt.Sprintf(`Please evaluate whether the following task needs to be broken down into subtasks:
-
-**Task Title:** %s
-
-**Description:** %s
-
-**Priority:** %s
-
-**Current Status:** %s
-
-Consider:
-- Can this be completed by a single agent with existing capabilities?
-- Does it require multiple specialized skills?
-- Is the scope too large for one person?
-- Are there logical components that could be parallelized?
-
-Provide your decision in the JSON format specified in the system prompt.`,
-		task.Title,
-		task.Description,
-		task.Priority,
-		task.Status)
-}
-
-// buildSubtaskAnalysisPrompt creates the user prompt for LLM analysis
-func (s *SubtaskService) buildSubtaskAnalysisPrompt(task *tm.Task) string {
-	return fmt.Sprintf(`Please analyze the following task and break it down into subtasks:
-
-**Task Title:** %s
-
-**Description:** %s
-
-**Priority:** %s
-
-**Current Status:** %s
-
-Please analyze this task and provide a detailed breakdown into subtasks. Consider:
-- Technical complexity and requirements
-- Logical task dependencies 
-- Appropriate skill sets needed for each subtask
-- Risk factors and potential blockers
-- Estimated effort for each component
-
-Provide the analysis in the JSON format specified in the system prompt.`,
-		task.Title,
-		task.Description,
-		task.Priority,
-		task.Status)
-}
-
-// parseSubtaskDecision parses the LLM response into a SubtaskDecision struct
-func (s *SubtaskService) parseSubtaskDecision(response string) (*tm.SubtaskDecision, error) {
-	// Try to extract JSON from the response
-	jsonStart := strings.Index(response, "{")
-	jsonEnd := strings.LastIndex(response, "}")
-
-	if jsonStart == -1 || jsonEnd == -1 {
-		return nil, fmt.Errorf("no JSON found in LLM response")
-	}
-
-	jsonStr := response[jsonStart : jsonEnd+1]
-
-	var decision tm.SubtaskDecision
-	if err := json.Unmarshal([]byte(jsonStr), &decision); err != nil {
-		return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
-	}
-
-	return &decision, nil
-}
-
-// parseSubtaskAnalysis parses the LLM response into a SubtaskAnalysis struct
-func (s *SubtaskService) parseSubtaskAnalysis(response string, parentTaskID string) (*tm.SubtaskAnalysis, error) {
-	// Try to extract JSON from the response (LLM might wrap it in markdown)
-	jsonStart := strings.Index(response, "{")
-	jsonEnd := strings.LastIndex(response, "}")
-
-	if jsonStart == -1 || jsonEnd == -1 {
-		return nil, fmt.Errorf("no JSON found in LLM response")
-	}
-
-	jsonStr := response[jsonStart : jsonEnd+1]
-
-	var rawAnalysis struct {
-		AnalysisSummary string `json:"analysis_summary"`
-		Subtasks        []struct {
-			Title          string   `json:"title"`
-			Description    string   `json:"description"`
-			Priority       string   `json:"priority"`
-			AssignedTo     string   `json:"assigned_to"`
-			EstimatedHours int      `json:"estimated_hours"`
-			Dependencies   []string `json:"dependencies"`
-			RequiredSkills []string `json:"required_skills"`
-		} `json:"subtasks"`
-		AgentCreations      []tm.AgentCreationProposal `json:"agent_creations"`
-		RecommendedApproach string                     `json:"recommended_approach"`
-		EstimatedTotalHours int                        `json:"estimated_total_hours"`
-		RiskAssessment      string                     `json:"risk_assessment"`
-	}
-
-	if err := json.Unmarshal([]byte(jsonStr), &rawAnalysis); err != nil {
-		return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
-	}
-
-	// Convert to our types
-	analysis := &tm.SubtaskAnalysis{
-		ParentTaskID:        parentTaskID,
-		AnalysisSummary:     rawAnalysis.AnalysisSummary,
-		AgentCreations:      rawAnalysis.AgentCreations,
-		RecommendedApproach: rawAnalysis.RecommendedApproach,
-		EstimatedTotalHours: rawAnalysis.EstimatedTotalHours,
-		RiskAssessment:      rawAnalysis.RiskAssessment,
-	}
-
-	// Convert subtasks
-	for _, st := range rawAnalysis.Subtasks {
-		priority := tm.PriorityMedium // default
-		switch strings.ToLower(st.Priority) {
-		case "high":
-			priority = tm.PriorityHigh
-		case "low":
-			priority = tm.PriorityLow
-		}
-
-		subtask := tm.SubtaskProposal{
-			Title:          st.Title,
-			Description:    st.Description,
-			Priority:       priority,
-			AssignedTo:     st.AssignedTo,
-			EstimatedHours: st.EstimatedHours,
-			Dependencies:   st.Dependencies,
-			RequiredSkills: st.RequiredSkills,
-		}
-
-		analysis.Subtasks = append(analysis.Subtasks, subtask)
-	}
-
-	// Validate agent assignments and handle new agent creation
-	if err := s.validateAndHandleAgentAssignments(analysis); err != nil {
-		s.logger.Warn("Warning during agent assignment handling", slog.String("error", err.Error()))
-	}
-
-	return analysis, nil
-}
-
-// validateAndHandleAgentAssignments validates assignments and creates agent creation subtasks if needed
-func (s *SubtaskService) validateAndHandleAgentAssignments(analysis *tm.SubtaskAnalysis) error {
-	// Collect all agent roles that will be available (existing + proposed new ones)
-	availableRoles := make(map[string]bool)
-	for _, role := range s.agentRoles {
-		availableRoles[role] = true
-	}
-
-	// Add proposed new agent roles
-	for _, agentCreation := range analysis.AgentCreations {
-		availableRoles[agentCreation.Role] = true
-
-		// Create a subtask for agent creation
-		agentCreationSubtask := tm.SubtaskProposal{
-			Title:          fmt.Sprintf("Create %s Agent", cases.Title(language.English).String(agentCreation.Role)),
-			Description:    fmt.Sprintf("Create and configure a new %s agent with skills: %s. %s", agentCreation.Role, strings.Join(agentCreation.Skills, ", "), agentCreation.Justification),
-			Priority:       tm.PriorityHigh, // Agent creation is high priority
-			AssignedTo:     "ceo",           // CEO creates new agents
-			EstimatedHours: 4,               // Estimated time to set up new agent
-			Dependencies:   []string{},      // No dependencies for agent creation
-			RequiredSkills: []string{"agent_configuration", "system_design"},
-		}
-
-		// Insert at the beginning so agent creation happens first
-		analysis.Subtasks = append([]tm.SubtaskProposal{agentCreationSubtask}, analysis.Subtasks...)
-
-		// Update dependencies to account for the new subtask at index 0
-		for i := 1; i < len(analysis.Subtasks); i++ {
-			for j, dep := range analysis.Subtasks[i].Dependencies {
-				// Convert dependency index and increment by 1
-				if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
-					analysis.Subtasks[i].Dependencies[j] = fmt.Sprintf("%d", depIndex+1)
-				}
-			}
-		}
-	}
-
-	// Now validate all assignments against available roles
-	defaultRole := "ceo" // fallback role
-	if len(s.agentRoles) > 0 {
-		defaultRole = s.agentRoles[0]
-	}
-
-	for i := range analysis.Subtasks {
-		if !availableRoles[analysis.Subtasks[i].AssignedTo] {
-			s.logger.Warn("Unknown agent role for subtask, using default",
-				slog.String("unknown_role", analysis.Subtasks[i].AssignedTo),
-				slog.String("subtask_title", analysis.Subtasks[i].Title),
-				slog.String("assigned_role", defaultRole))
-			analysis.Subtasks[i].AssignedTo = defaultRole
-		}
-	}
-
-	return nil
-}
-
-// parseDependencyIndex parses a dependency string to an integer index
-func (s *SubtaskService) parseDependencyIndex(dep string) int {
-	var idx int
-	if _, err := fmt.Sscanf(dep, "%d", &idx); err == nil {
-		return idx
-	}
-	return -1 // Invalid dependency format
-}
-
-// isValidAgentRole checks if a role is in the available agent roles
-func (s *SubtaskService) isValidAgentRole(role string) bool {
-	for _, availableRole := range s.agentRoles {
-		if availableRole == role {
-			return true
-		}
-	}
-	return false
-}
-
-// GenerateSubtaskPR creates a PR with the proposed subtasks
-func (s *SubtaskService) GenerateSubtaskPR(ctx context.Context, analysis *tm.SubtaskAnalysis) (string, error) {
-	if s.prProvider == nil {
-		return "", fmt.Errorf("PR provider not configured")
-	}
-
-	// Generate branch name for subtask proposal
-	branchName := fmt.Sprintf("subtasks/%s-proposal", analysis.ParentTaskID)
-	s.logger.Info("Creating subtask PR", slog.String("branch", branchName))
-
-	// Create Git branch and commit subtask proposal
-	if err := s.createSubtaskBranch(ctx, analysis, branchName); err != nil {
-		return "", fmt.Errorf("failed to create subtask branch: %w", err)
-	}
-
-	// Generate PR content
-	prContent := s.generateSubtaskPRContent(analysis)
-	title := fmt.Sprintf("Subtask Proposal: %s", analysis.ParentTaskID)
-
-	// Validate PR content
-	if title == "" {
-		return "", fmt.Errorf("PR title cannot be empty")
-	}
-	if prContent == "" {
-		return "", fmt.Errorf("PR description cannot be empty")
-	}
-
-	// Determine base branch (try main first, fallback to master)
-	baseBranch := s.determineBaseBranch(ctx)
-	s.logger.Info("Using base branch", slog.String("base_branch", baseBranch))
-
-	// Create the pull request
-	options := git.PullRequestOptions{
-		Title:       title,
-		Description: prContent,
-		HeadBranch:  branchName,
-		BaseBranch:  baseBranch,
-		Labels:      []string{"subtasks", "proposal", "ai-generated"},
-		Draft:       false,
-	}
-
-	s.logger.Info("Creating PR with options",
-		slog.String("title", options.Title),
-		slog.String("head_branch", options.HeadBranch),
-		slog.String("base_branch", options.BaseBranch))
-
-	pr, err := s.prProvider.CreatePullRequest(ctx, options)
-	if err != nil {
-		return "", fmt.Errorf("failed to create PR: %w", err)
-	}
-
-	prURL := fmt.Sprintf("https://github.com/%s/%s/pull/%d", s.githubOwner, s.githubRepo, pr.Number)
-	s.logger.Info("Generated subtask proposal PR", slog.String("pr_url", prURL))
-
-	return prURL, nil
-}
-
-// determineBaseBranch determines the correct base branch (main or master)
-func (s *SubtaskService) determineBaseBranch(ctx context.Context) string {
-	if s.cloneManager == nil {
-		return "main" // default fallback
-	}
-
-	// Get clone path to check branches
-	clonePath, err := s.cloneManager.GetAgentClonePath("subtask-service")
-	if err != nil {
-		s.logger.Warn("Failed to get clone path for base branch detection", slog.String("error", err.Error()))
-		return "main"
-	}
-
-	// Check if main branch exists
-	gitCmd := func(args ...string) *exec.Cmd {
-		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
-	}
-
-	// Try to checkout main branch
-	cmd := gitCmd("show-ref", "refs/remotes/origin/main")
-	if err := cmd.Run(); err == nil {
-		return "main"
-	}
-
-	// Try to checkout master branch
-	cmd = gitCmd("show-ref", "refs/remotes/origin/master")
-	if err := cmd.Run(); err == nil {
-		return "master"
-	}
-
-	// Default to main if neither can be detected
-	s.logger.Warn("Could not determine base branch, defaulting to 'main'")
-	return "main"
-}
-
-// generateSubtaskFile creates the content for an individual subtask file
-func (s *SubtaskService) generateSubtaskFile(subtask tm.SubtaskProposal, taskID, parentTaskID string) string {
-	var content strings.Builder
-
-	// Generate YAML frontmatter
-	content.WriteString("---\n")
-	content.WriteString(fmt.Sprintf("id: %s\n", taskID))
-	content.WriteString(fmt.Sprintf("title: %s\n", subtask.Title))
-	content.WriteString(fmt.Sprintf("description: %s\n", subtask.Description))
-	content.WriteString(fmt.Sprintf("assignee: %s\n", subtask.AssignedTo))
-	content.WriteString(fmt.Sprintf("owner_id: %s\n", subtask.AssignedTo))
-	content.WriteString(fmt.Sprintf("owner_name: %s\n", subtask.AssignedTo))
-	content.WriteString("status: todo\n")
-	content.WriteString(fmt.Sprintf("priority: %s\n", strings.ToLower(string(subtask.Priority))))
-	content.WriteString(fmt.Sprintf("parent_task_id: %s\n", parentTaskID))
-	content.WriteString(fmt.Sprintf("estimated_hours: %d\n", subtask.EstimatedHours))
-	content.WriteString(fmt.Sprintf("created_at: %s\n", time.Now().Format(time.RFC3339)))
-	content.WriteString(fmt.Sprintf("updated_at: %s\n", time.Now().Format(time.RFC3339)))
-	content.WriteString("completed_at: null\n")
-	content.WriteString("archived_at: null\n")
-
-	// Add dependencies if any
-	if len(subtask.Dependencies) > 0 {
-		content.WriteString("dependencies:\n")
-		for _, dep := range subtask.Dependencies {
-			// Convert dependency index to actual subtask ID
-			if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
-				depTaskID := fmt.Sprintf("%s-subtask-%d", parentTaskID, depIndex+1)
-				content.WriteString(fmt.Sprintf("  - %s\n", depTaskID))
-			}
-		}
-	}
-
-	// Add required skills if any
-	if len(subtask.RequiredSkills) > 0 {
-		content.WriteString("required_skills:\n")
-		for _, skill := range subtask.RequiredSkills {
-			content.WriteString(fmt.Sprintf("  - %s\n", skill))
-		}
-	}
-
-	content.WriteString("---\n\n")
-
-	// Add markdown content
-	content.WriteString("# Task Description\n\n")
-	content.WriteString(fmt.Sprintf("%s\n\n", subtask.Description))
-
-	if subtask.EstimatedHours > 0 {
-		content.WriteString("## Estimated Effort\n\n")
-		content.WriteString(fmt.Sprintf("**Estimated Hours:** %d\n\n", subtask.EstimatedHours))
-	}
-
-	if len(subtask.RequiredSkills) > 0 {
-		content.WriteString("## Required Skills\n\n")
-		for _, skill := range subtask.RequiredSkills {
-			content.WriteString(fmt.Sprintf("- %s\n", skill))
-		}
-		content.WriteString("\n")
-	}
-
-	if len(subtask.Dependencies) > 0 {
-		content.WriteString("## Dependencies\n\n")
-		content.WriteString("This task depends on the completion of:\n\n")
-		for _, dep := range subtask.Dependencies {
-			if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
-				depTaskID := fmt.Sprintf("%s-subtask-%d", parentTaskID, depIndex+1)
-				content.WriteString(fmt.Sprintf("- %s\n", depTaskID))
-			}
-		}
-		content.WriteString("\n")
-	}
-
-	content.WriteString("## Notes\n\n")
-	content.WriteString(fmt.Sprintf("This subtask was generated from parent task: %s\n", parentTaskID))
-	content.WriteString("Generated by Staff AI Agent System\n\n")
-
-	return content.String()
-}
-
-// updateParentTaskAsCompleted updates the parent task file to mark it as completed
-func (s *SubtaskService) updateParentTaskAsCompleted(taskFilePath string, analysis *tm.SubtaskAnalysis) error {
-	// Read the existing parent task file
-	content, err := os.ReadFile(taskFilePath)
-	if err != nil {
-		return fmt.Errorf("failed to read parent task file: %w", err)
-	}
-
-	taskContent := string(content)
-
-	// Find the YAML frontmatter boundaries
-	lines := strings.Split(taskContent, "\n")
-	var frontmatterStart, frontmatterEnd int = -1, -1
-
-	for i, line := range lines {
-		if line == "---" {
-			if frontmatterStart == -1 {
-				frontmatterStart = i
-			} else {
-				frontmatterEnd = i
-				break
-			}
-		}
-	}
-
-	if frontmatterStart == -1 || frontmatterEnd == -1 {
-		return fmt.Errorf("invalid task file format: missing YAML frontmatter")
-	}
-
-	// Update the frontmatter
-	now := time.Now().Format(time.RFC3339)
-	var updatedLines []string
-
-	// Add lines before frontmatter
-	updatedLines = append(updatedLines, lines[:frontmatterStart+1]...)
-
-	// Process frontmatter lines
-	for i := frontmatterStart + 1; i < frontmatterEnd; i++ {
-		line := lines[i]
-		if strings.HasPrefix(line, "status:") {
-			updatedLines = append(updatedLines, "status: completed")
-		} else if strings.HasPrefix(line, "updated_at:") {
-			updatedLines = append(updatedLines, fmt.Sprintf("updated_at: %s", now))
-		} else if strings.HasPrefix(line, "completed_at:") {
-			updatedLines = append(updatedLines, fmt.Sprintf("completed_at: %s", now))
-		} else {
-			updatedLines = append(updatedLines, line)
-		}
-	}
-
-	// Add closing frontmatter and rest of content
-	updatedLines = append(updatedLines, lines[frontmatterEnd:]...)
-
-	// Add subtask information to the task description
-	if frontmatterEnd+1 < len(lines) {
-		// Add subtask information
-		subtaskInfo := fmt.Sprintf("\n\n## Subtasks Created\n\nThis task has been broken down into %d subtasks:\n\n", len(analysis.Subtasks))
-		for i, subtask := range analysis.Subtasks {
-			subtaskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
-			subtaskInfo += fmt.Sprintf("- **%s**: %s (assigned to %s)\n", subtaskID, subtask.Title, subtask.AssignedTo)
-		}
-		subtaskInfo += fmt.Sprintf("\n**Total Estimated Hours:** %d\n", analysis.EstimatedTotalHours)
-		subtaskInfo += fmt.Sprintf("**Completed:** %s - Task broken down into actionable subtasks\n", now)
-
-		// Insert subtask info before any existing body content
-		updatedContent := strings.Join(updatedLines[:], "\n") + subtaskInfo
-
-		// Write the updated content back to the file
-		if err := os.WriteFile(taskFilePath, []byte(updatedContent), 0644); err != nil {
-			return fmt.Errorf("failed to write updated parent task file: %w", err)
-		}
-	}
-
-	s.logger.Info("Updated parent task to completed status", slog.String("task_id", analysis.ParentTaskID))
-	return nil
-}
-
-// generateSubtaskPRContent creates markdown content for the subtask proposal PR
-func (s *SubtaskService) generateSubtaskPRContent(analysis *tm.SubtaskAnalysis) string {
-	var content strings.Builder
-
-	content.WriteString(fmt.Sprintf("# Subtasks Created for Task %s\n\n", analysis.ParentTaskID))
-	content.WriteString(fmt.Sprintf("This PR creates **%d individual task files** in `/operations/tasks/` ready for agent assignment.\n\n", len(analysis.Subtasks)))
-	content.WriteString(fmt.Sprintf("✅ **Parent task `%s` has been marked as completed** - the complex task has been successfully broken down into actionable subtasks.\n\n", analysis.ParentTaskID))
-	content.WriteString(fmt.Sprintf("## Analysis Summary\n%s\n\n", analysis.AnalysisSummary))
-	content.WriteString(fmt.Sprintf("## Recommended Approach\n%s\n\n", analysis.RecommendedApproach))
-	content.WriteString(fmt.Sprintf("**Estimated Total Hours:** %d\n\n", analysis.EstimatedTotalHours))
-
-	// List the created task files
-	content.WriteString("## Created Task Files\n\n")
-	for i, subtask := range analysis.Subtasks {
-		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
-		content.WriteString(fmt.Sprintf("### %d. `%s.md`\n", i+1, taskID))
-		content.WriteString(fmt.Sprintf("- **Title:** %s\n", subtask.Title))
-		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
-		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
-		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
-		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
-	}
-
-	if analysis.RiskAssessment != "" {
-		content.WriteString(fmt.Sprintf("## Risk Assessment\n%s\n\n", analysis.RiskAssessment))
-	}
-
-	content.WriteString("## Proposed Subtasks\n\n")
-
-	for i, subtask := range analysis.Subtasks {
-		content.WriteString(fmt.Sprintf("### %d. %s\n", i+1, subtask.Title))
-		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
-		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
-		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
-
-		if len(subtask.Dependencies) > 0 {
-			deps := strings.Join(subtask.Dependencies, ", ")
-			content.WriteString(fmt.Sprintf("- **Dependencies:** %s\n", deps))
-		}
-
-		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
-	}
-
-	content.WriteString("---\n")
-	content.WriteString("*Generated by Staff AI Agent System*\n\n")
-	content.WriteString("**Instructions:**\n")
-	content.WriteString("- Review the proposed subtasks\n")
-	content.WriteString("- Approve or request changes\n")
-	content.WriteString("- When merged, the subtasks will be automatically created and assigned\n")
-
-	return content.String()
-}
-
-// createSubtaskBranch creates a Git branch with subtask proposal content
-func (s *SubtaskService) createSubtaskBranch(ctx context.Context, analysis *tm.SubtaskAnalysis, branchName string) error {
-	if s.cloneManager == nil {
-		return fmt.Errorf("clone manager not configured")
-	}
-
-	// Get a temporary clone for creating the subtask branch
-	clonePath, err := s.cloneManager.GetAgentClonePath("subtask-service")
-	if err != nil {
-		return fmt.Errorf("failed to get clone path: %w", err)
-	}
-
-	// All Git operations use the clone directory
-	gitCmd := func(args ...string) *exec.Cmd {
-		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
-	}
-
-	// Ensure we're on main branch before creating new branch
-	cmd := gitCmd("checkout", "main")
-	if err := cmd.Run(); err != nil {
-		// Try master branch if main doesn't exist
-		cmd = gitCmd("checkout", "master")
-		if err := cmd.Run(); err != nil {
-			return fmt.Errorf("failed to checkout main/master branch: %w", err)
-		}
-	}
-
-	// Pull latest changes
-	cmd = gitCmd("pull", "origin")
-	if err := cmd.Run(); err != nil {
-		s.logger.Warn("Failed to pull latest changes", slog.String("error", err.Error()))
-	}
-
-	// Delete branch if it exists (cleanup from previous attempts)
-	cmd = gitCmd("branch", "-D", branchName)
-	_ = cmd.Run() // Ignore error if branch doesn't exist
-
-	// Also delete remote tracking branch if it exists
-	cmd = gitCmd("push", "origin", "--delete", branchName)
-	_ = cmd.Run() // Ignore error if branch doesn't exist
-
-	// Create and checkout new branch
-	cmd = gitCmd("checkout", "-b", branchName)
-	if err := cmd.Run(); err != nil {
-		return fmt.Errorf("failed to create branch: %w", err)
-	}
-
-	// Create individual task files for each subtask
-	tasksDir := filepath.Join(clonePath, "operations", "tasks")
-	if err := os.MkdirAll(tasksDir, 0755); err != nil {
-		return fmt.Errorf("failed to create tasks directory: %w", err)
-	}
-
-	var stagedFiles []string
-
-	// Update parent task to mark as completed
-	parentTaskFile := filepath.Join(tasksDir, fmt.Sprintf("%s.md", analysis.ParentTaskID))
-	if err := s.updateParentTaskAsCompleted(parentTaskFile, analysis); err != nil {
-		return fmt.Errorf("failed to update parent task: %w", err)
-	}
-
-	// Track parent task file for staging
-	parentRelativeFile := filepath.Join("operations", "tasks", fmt.Sprintf("%s.md", analysis.ParentTaskID))
-	stagedFiles = append(stagedFiles, parentRelativeFile)
-	s.logger.Info("Updated parent task file", slog.String("file", parentRelativeFile))
-
-	// Create a file for each subtask
-	for i, subtask := range analysis.Subtasks {
-		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
-		taskFile := filepath.Join(tasksDir, fmt.Sprintf("%s.md", taskID))
-		taskContent := s.generateSubtaskFile(subtask, taskID, analysis.ParentTaskID)
-
-		if err := os.WriteFile(taskFile, []byte(taskContent), 0644); err != nil {
-			return fmt.Errorf("failed to write subtask file %s: %w", taskID, err)
-		}
-
-		// Track file for staging
-		relativeFile := filepath.Join("operations", "tasks", fmt.Sprintf("%s.md", taskID))
-		stagedFiles = append(stagedFiles, relativeFile)
-		s.logger.Info("Created subtask file", slog.String("file", relativeFile))
-	}
-
-	// Stage all subtask files
-	for _, file := range stagedFiles {
-		cmd = gitCmd("add", file)
-		if err := cmd.Run(); err != nil {
-			return fmt.Errorf("failed to stage file %s: %w", file, err)
-		}
-	}
-
-	// Commit changes
-	commitMsg := fmt.Sprintf("Create %d subtasks for task %s and mark parent as completed\n\nGenerated by Staff AI Agent System\n\nFiles modified:\n- %s.md (marked as completed)\n\nCreated individual task files:\n",
-		len(analysis.Subtasks), analysis.ParentTaskID, analysis.ParentTaskID)
-
-	// Add list of created files to commit message
-	for i := range analysis.Subtasks {
-		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
-		commitMsg += fmt.Sprintf("- %s.md\n", taskID)
-	}
-
-	if len(analysis.AgentCreations) > 0 {
-		commitMsg += fmt.Sprintf("\nProposed %d new agents for specialized skills", len(analysis.AgentCreations))
-	}
-	cmd = gitCmd("commit", "-m", commitMsg)
-	if err := cmd.Run(); err != nil {
-		return fmt.Errorf("failed to commit: %w", err)
-	}
-
-	// Push branch
-	cmd = gitCmd("push", "-u", "origin", branchName)
-	if err := cmd.Run(); err != nil {
-		return fmt.Errorf("failed to push branch: %w", err)
-	}
-
-	s.logger.Info("Created subtask proposal branch", slog.String("branch", branchName))
-	return nil
-}
-
-// Close cleans up the service
-func (s *SubtaskService) Close() error {
-	if s.llmProvider != nil {
-		return s.llmProvider.Close()
-	}
-	return nil
-}
diff --git a/server/task/service_test.go b/server/task/service_test.go
deleted file mode 100644
index 5c7b337..0000000
--- a/server/task/service_test.go
+++ /dev/null
@@ -1,687 +0,0 @@
-package task
-
-import (
-	"context"
-	"os"
-	"strings"
-	"testing"
-	"time"
-
-	"github.com/iomodo/staff/llm"
-	"github.com/iomodo/staff/tm"
-)
-
-// MockLLMProvider implements a mock LLM provider for testing
-type MockLLMProvider struct {
-	responses []string
-	callCount int
-}
-
-func NewMockLLMProvider(responses []string) *MockLLMProvider {
-	return &MockLLMProvider{
-		responses: responses,
-		callCount: 0,
-	}
-}
-
-func (m *MockLLMProvider) ChatCompletion(ctx context.Context, req llm.ChatCompletionRequest) (*llm.ChatCompletionResponse, error) {
-	if m.callCount >= len(m.responses) {
-		return nil, nil
-	}
-
-	response := m.responses[m.callCount]
-	m.callCount++
-
-	return &llm.ChatCompletionResponse{
-		ID:      "mock-response",
-		Object:  "chat.completion",
-		Created: time.Now().Unix(),
-		Model:   req.Model,
-		Choices: []llm.ChatCompletionChoice{
-			{
-				Index: 0,
-				Message: llm.Message{
-					Role:    llm.RoleAssistant,
-					Content: response,
-				},
-				FinishReason: "stop",
-			},
-		},
-		Usage: llm.Usage{
-			PromptTokens:     100,
-			CompletionTokens: 300,
-			TotalTokens:      400,
-		},
-	}, nil
-}
-
-func (m *MockLLMProvider) CreateEmbeddings(ctx context.Context, req llm.EmbeddingRequest) (*llm.EmbeddingResponse, error) {
-	return &llm.EmbeddingResponse{
-		Object: "list",
-		Data: []llm.Embedding{
-			{
-				Object:    "embedding",
-				Index:     0,
-				Embedding: make([]float64, 1536),
-			},
-		},
-		Model: req.Model,
-		Usage: llm.Usage{
-			PromptTokens: 50,
-			TotalTokens:  50,
-		},
-	}, nil
-}
-
-func (m *MockLLMProvider) Close() error {
-	return nil
-}
-
-func TestNewSubtaskService(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	agentRoles := []string{"backend", "frontend", "qa"}
-
-	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
-
-	if service == nil {
-		t.Fatal("NewSubtaskService returned nil")
-	}
-
-	if service.llmProvider != mockProvider {
-		t.Error("LLM provider not set correctly")
-	}
-
-	if len(service.agentRoles) != 3 {
-		t.Errorf("Expected 3 agent roles, got %d", len(service.agentRoles))
-	}
-}
-
-func TestShouldGenerateSubtasks(t *testing.T) {
-	// Test decision to generate subtasks
-	decisionResponse := `{
-  "needs_subtasks": true,
-  "reasoning": "Complex task requiring multiple skills",
-  "complexity_score": 8,
-  "required_skills": ["backend", "frontend", "database"]
-}`
-
-	mockProvider := NewMockLLMProvider([]string{decisionResponse})
-	agentRoles := []string{"backend", "frontend", "qa"}
-	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
-
-	// Test the parseSubtaskDecision method directly since ShouldGenerateSubtasks is used by manager
-	decision, err := service.parseSubtaskDecision(decisionResponse)
-	if err != nil {
-		t.Fatalf("parseSubtaskDecision failed: %v", err)
-	}
-
-	if !decision.NeedsSubtasks {
-		t.Error("Expected decision to need subtasks")
-	}
-
-	if decision.ComplexityScore != 8 {
-		t.Errorf("Expected complexity score 8, got %d", decision.ComplexityScore)
-	}
-
-	if len(decision.RequiredSkills) != 3 {
-		t.Errorf("Expected 3 required skills, got %d", len(decision.RequiredSkills))
-	}
-}
-
-func TestAnalyzeTaskForSubtasks(t *testing.T) {
-	jsonResponse := `{
-  "analysis_summary": "This task requires breaking down into multiple components",
-  "subtasks": [
-    {
-      "title": "Backend Development",
-      "description": "Implement server-side logic",
-      "priority": "high",
-      "assigned_to": "backend",
-      "estimated_hours": 16,
-      "dependencies": [],
-      "required_skills": ["go", "api_development"]
-    },
-    {
-      "title": "Frontend Development", 
-      "description": "Build user interface",
-      "priority": "medium",
-      "assigned_to": "frontend",
-      "estimated_hours": 12,
-      "dependencies": ["0"],
-      "required_skills": ["react", "typescript"]
-    }
-  ],
-  "agent_creations": [
-    {
-      "role": "security_specialist",
-      "skills": ["security_audit", "penetration_testing"],
-      "description": "Specialized agent for security tasks",
-      "justification": "Authentication requires security expertise"
-    }
-  ],
-  "recommended_approach": "Start with backend then frontend",
-  "estimated_total_hours": 28,
-  "risk_assessment": "Medium complexity with API integration risks"
-}`
-
-	mockProvider := NewMockLLMProvider([]string{jsonResponse})
-	agentRoles := []string{"backend", "frontend", "qa", "ceo"} // Include CEO for agent creation
-	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
-
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Build authentication system",
-		Description: "Implement user login and registration",
-		Priority:    tm.PriorityHigh,
-		Status:      tm.StatusToDo,
-		CreatedAt:   time.Now(),
-		UpdatedAt:   time.Now(),
-	}
-
-	analysis, err := service.AnalyzeTaskForSubtasks(context.Background(), task)
-	if err != nil {
-		t.Fatalf("AnalyzeTaskForSubtasks failed: %v", err)
-	}
-
-	if analysis.ParentTaskID != task.ID {
-		t.Errorf("Expected parent task ID %s, got %s", task.ID, analysis.ParentTaskID)
-	}
-
-	if analysis.AnalysisSummary == "" {
-		t.Error("Analysis summary should not be empty")
-	}
-
-	// Should have 3 subtasks (1 for agent creation + 2 original)
-	if len(analysis.Subtasks) != 3 {
-		t.Errorf("Expected 3 subtasks (including agent creation), got %d", len(analysis.Subtasks))
-		t.Logf("Subtasks: %+v", analysis.Subtasks)
-		return // Exit early if count is wrong to avoid index errors
-	}
-
-	// Test agent creation was processed
-	if len(analysis.AgentCreations) != 1 {
-		t.Errorf("Expected 1 agent creation, got %d", len(analysis.AgentCreations))
-	} else {
-		agentCreation := analysis.AgentCreations[0]
-		if agentCreation.Role != "security_specialist" {
-			t.Errorf("Expected role 'security_specialist', got %s", agentCreation.Role)
-		}
-		if len(agentCreation.Skills) != 2 {
-			t.Errorf("Expected 2 skills, got %d", len(agentCreation.Skills))
-		}
-	}
-
-	// We already checked the count above
-
-	// Test first subtask (agent creation)
-	subtask0 := analysis.Subtasks[0]
-	if !strings.Contains(subtask0.Title, "Security_specialist") {
-		t.Errorf("Expected agent creation subtask for security_specialist, got %s", subtask0.Title)
-	}
-	if subtask0.AssignedTo != "ceo" {
-		t.Errorf("Expected agent creation assigned to 'ceo', got %s", subtask0.AssignedTo)
-	}
-
-	// Test second subtask (original backend task, now at index 1)
-	subtask1 := analysis.Subtasks[1]
-	if subtask1.Title != "Backend Development" {
-		t.Errorf("Expected title 'Backend Development', got %s", subtask1.Title)
-	}
-	if subtask1.Priority != tm.PriorityHigh {
-		t.Errorf("Expected high priority, got %s", subtask1.Priority)
-	}
-	if subtask1.AssignedTo != "backend" {
-		t.Errorf("Expected assigned_to 'backend', got %s", subtask1.AssignedTo)
-	}
-	if subtask1.EstimatedHours != 16 {
-		t.Errorf("Expected 16 hours, got %d", subtask1.EstimatedHours)
-	}
-	if len(subtask1.RequiredSkills) != 2 {
-		t.Errorf("Expected 2 required skills, got %d", len(subtask1.RequiredSkills))
-	}
-
-	// Test third subtask (original frontend task, now at index 2 with updated dependencies)
-	subtask2 := analysis.Subtasks[2]
-	if subtask2.Title != "Frontend Development" {
-		t.Errorf("Expected title 'Frontend Development', got %s", subtask2.Title)
-	}
-	if subtask2.Priority != tm.PriorityMedium {
-		t.Errorf("Expected medium priority, got %s", subtask2.Priority)
-	}
-	// Dependencies should be updated to account for the new agent creation subtask
-	if len(subtask2.Dependencies) != 1 || subtask2.Dependencies[0] != "1" {
-		t.Errorf("Expected dependencies [1] (updated for agent creation), got %v", subtask2.Dependencies)
-	}
-	if len(subtask2.RequiredSkills) != 2 {
-		t.Errorf("Expected 2 required skills, got %d", len(subtask2.RequiredSkills))
-	}
-
-	// Total hours should include agent creation time (4 hours)
-	if analysis.EstimatedTotalHours != 28 {
-		t.Errorf("Expected 28 total hours, got %d", analysis.EstimatedTotalHours)
-	}
-}
-
-func TestAnalyzeTaskForSubtasks_InvalidJSON(t *testing.T) {
-	invalidResponse := "This is not valid JSON"
-
-	mockProvider := NewMockLLMProvider([]string{invalidResponse})
-	agentRoles := []string{"backend", "frontend"}
-	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
-
-	task := &tm.Task{
-		ID:    "test-task-123",
-		Title: "Test task",
-	}
-
-	_, err := service.AnalyzeTaskForSubtasks(context.Background(), task)
-	if err == nil {
-		t.Error("Expected error for invalid JSON, got nil")
-	}
-
-	if !strings.Contains(err.Error(), "no JSON found") {
-		t.Errorf("Expected 'no JSON found' error, got: %v", err)
-	}
-}
-
-func TestAnalyzeTaskForSubtasks_InvalidAgentRole(t *testing.T) {
-	jsonResponse := `{
-  "analysis_summary": "Test analysis",
-  "subtasks": [
-    {
-      "title": "Invalid Assignment",
-      "description": "Test subtask",
-      "priority": "high",
-      "assigned_to": "invalid_role",
-      "estimated_hours": 8,
-      "dependencies": []
-    }
-  ],
-  "recommended_approach": "Test approach",
-  "estimated_total_hours": 8
-}`
-
-	mockProvider := NewMockLLMProvider([]string{jsonResponse})
-	agentRoles := []string{"backend", "frontend"}
-	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
-
-	task := &tm.Task{
-		ID:    "test-task-123",
-		Title: "Test task",
-	}
-
-	analysis, err := service.AnalyzeTaskForSubtasks(context.Background(), task)
-	if err != nil {
-		t.Fatalf("AnalyzeTaskForSubtasks failed: %v", err)
-	}
-
-	// Should fix invalid agent assignment to first available role
-	if analysis.Subtasks[0].AssignedTo != "backend" {
-		t.Errorf("Expected fixed assignment 'backend', got %s", analysis.Subtasks[0].AssignedTo)
-	}
-}
-
-func TestGenerateSubtaskPR(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
-
-	analysis := &tm.SubtaskAnalysis{
-		ParentTaskID:        "task-123",
-		AnalysisSummary:     "Test analysis summary",
-		RecommendedApproach: "Test approach",
-		EstimatedTotalHours: 40,
-		RiskAssessment:      "Low risk",
-		Subtasks: []tm.SubtaskProposal{
-			{
-				Title:          "Test Subtask",
-				Description:    "Test description",
-				Priority:       tm.PriorityHigh,
-				AssignedTo:     "backend",
-				EstimatedHours: 8,
-				Dependencies:   []string{},
-			},
-		},
-	}
-
-	// Test that PR generation fails when no PR provider is configured
-	_, err := service.GenerateSubtaskPR(context.Background(), analysis)
-	if err == nil {
-		t.Error("Expected error when PR provider not configured, got nil")
-	}
-
-	if !strings.Contains(err.Error(), "PR provider not configured") {
-		t.Errorf("Expected 'PR provider not configured' error, got: %v", err)
-	}
-}
-
-func TestBuildSubtaskAnalysisPrompt(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	agentRoles := []string{"backend", "frontend", "qa"}
-	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
-
-	task := &tm.Task{
-		Title:       "Build authentication system",
-		Description: "Implement user login and registration with OAuth",
-		Priority:    tm.PriorityHigh,
-		Status:      tm.StatusToDo,
-	}
-
-	prompt := service.buildSubtaskAnalysisPrompt(task)
-
-	if !strings.Contains(prompt, task.Title) {
-		t.Error("Prompt should contain task title")
-	}
-
-	if !strings.Contains(prompt, task.Description) {
-		t.Error("Prompt should contain task description")
-	}
-
-	if !strings.Contains(prompt, string(task.Priority)) {
-		t.Error("Prompt should contain task priority")
-	}
-
-	if !strings.Contains(prompt, string(task.Status)) {
-		t.Error("Prompt should contain task status")
-	}
-}
-
-func TestGetSubtaskAnalysisSystemPrompt(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	agentRoles := []string{"backend", "frontend", "qa", "devops"}
-	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
-
-	systemPrompt := service.getSubtaskAnalysisSystemPrompt()
-
-	if !strings.Contains(systemPrompt, "backend") {
-		t.Error("System prompt should contain backend role")
-	}
-
-	if !strings.Contains(systemPrompt, "frontend") {
-		t.Error("System prompt should contain frontend role")
-	}
-
-	if !strings.Contains(systemPrompt, "JSON") {
-		t.Error("System prompt should mention JSON format")
-	}
-
-	if !strings.Contains(systemPrompt, "subtasks") {
-		t.Error("System prompt should mention subtasks")
-	}
-}
-
-func TestIsValidAgentRole(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	agentRoles := []string{"backend", "frontend", "qa"}
-	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
-
-	if !service.isValidAgentRole("backend") {
-		t.Error("'backend' should be a valid agent role")
-	}
-
-	if !service.isValidAgentRole("frontend") {
-		t.Error("'frontend' should be a valid agent role")
-	}
-
-	if service.isValidAgentRole("invalid") {
-		t.Error("'invalid' should not be a valid agent role")
-	}
-
-	if service.isValidAgentRole("") {
-		t.Error("Empty string should not be a valid agent role")
-	}
-}
-
-func TestParseSubtaskAnalysis_Priority(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
-
-	tests := []struct {
-		input    string
-		expected tm.TaskPriority
-	}{
-		{"high", tm.PriorityHigh},
-		{"HIGH", tm.PriorityHigh},
-		{"High", tm.PriorityHigh},
-		{"low", tm.PriorityLow},
-		{"LOW", tm.PriorityLow},
-		{"Low", tm.PriorityLow},
-		{"medium", tm.PriorityMedium},
-		{"MEDIUM", tm.PriorityMedium},
-		{"Medium", tm.PriorityMedium},
-		{"invalid", tm.PriorityMedium}, // default
-		{"", tm.PriorityMedium},        // default
-	}
-
-	for _, test := range tests {
-		jsonResponse := `{
-  "analysis_summary": "Test",
-  "subtasks": [{
-    "title": "Test",
-    "description": "Test",
-    "priority": "` + test.input + `",
-    "assigned_to": "backend",
-    "estimated_hours": 8,
-    "dependencies": []
-  }],
-  "recommended_approach": "Test",
-  "estimated_total_hours": 8
-}`
-
-		analysis, err := service.parseSubtaskAnalysis(jsonResponse, "test-task")
-		if err != nil {
-			t.Fatalf("parseSubtaskAnalysis failed for priority '%s': %v", test.input, err)
-		}
-
-		if len(analysis.Subtasks) != 1 {
-			t.Fatalf("Expected 1 subtask, got %d", len(analysis.Subtasks))
-		}
-
-		if analysis.Subtasks[0].Priority != test.expected {
-			t.Errorf("For priority '%s', expected %s, got %s",
-				test.input, test.expected, analysis.Subtasks[0].Priority)
-		}
-	}
-}
-
-func TestGenerateSubtaskFile(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
-
-	subtask := tm.SubtaskProposal{
-		Title:          "Implement API endpoints",
-		Description:    "Create REST API endpoints for user management",
-		Priority:       tm.PriorityHigh,
-		AssignedTo:     "backend",
-		EstimatedHours: 12,
-		Dependencies:   []string{"0"},
-		RequiredSkills: []string{"go", "rest_api"},
-	}
-
-	taskID := "parent-task-subtask-1"
-	parentTaskID := "parent-task"
-
-	content := service.generateSubtaskFile(subtask, taskID, parentTaskID)
-
-	// Verify YAML frontmatter
-	if !strings.Contains(content, "id: parent-task-subtask-1") {
-		t.Error("Generated file should contain task ID in frontmatter")
-	}
-	if !strings.Contains(content, "title: Implement API endpoints") {
-		t.Error("Generated file should contain task title in frontmatter")
-	}
-	if !strings.Contains(content, "assignee: backend") {
-		t.Error("Generated file should contain assignee in frontmatter")
-	}
-	if !strings.Contains(content, "status: todo") {
-		t.Error("Generated file should have 'todo' status")
-	}
-	if !strings.Contains(content, "priority: high") {
-		t.Error("Generated file should contain priority in frontmatter")
-	}
-	if !strings.Contains(content, "parent_task_id: parent-task") {
-		t.Error("Generated file should contain parent task ID")
-	}
-	if !strings.Contains(content, "estimated_hours: 12") {
-		t.Error("Generated file should contain estimated hours")
-	}
-
-	// Verify dependencies are converted properly
-	if !strings.Contains(content, "dependencies:") {
-		t.Error("Generated file should contain dependencies section")
-	}
-	if !strings.Contains(content, "- parent-task-subtask-1") {
-		t.Error("Dependencies should be converted to subtask IDs")
-	}
-
-	// Verify required skills
-	if !strings.Contains(content, "required_skills:") {
-		t.Error("Generated file should contain required skills section")
-	}
-	if !strings.Contains(content, "- go") {
-		t.Error("Generated file should contain required skills")
-	}
-
-	// Verify markdown content
-	if !strings.Contains(content, "# Task Description") {
-		t.Error("Generated file should contain markdown task description")
-	}
-	if !strings.Contains(content, "Create REST API endpoints for user management") {
-		t.Error("Generated file should contain task description in body")
-	}
-}
-
-func TestUpdateParentTaskAsCompleted(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
-
-	// Create a temporary task file for testing
-	taskContent := `---
-id: test-task-123
-title: Test Task
-description: A test task for validation
-assignee: backend
-status: todo
-priority: high
-created_at: 2024-01-01T10:00:00Z
-updated_at: 2024-01-01T10:00:00Z
-completed_at: null
----
-
-# Task Description
-
-A test task for validation
-`
-
-	// Create temporary file
-	tmpFile, err := os.CreateTemp("", "test-task-*.md")
-	if err != nil {
-		t.Fatalf("Failed to create temp file: %v", err)
-	}
-	defer os.Remove(tmpFile.Name())
-
-	if err := os.WriteFile(tmpFile.Name(), []byte(taskContent), 0644); err != nil {
-		t.Fatalf("Failed to write temp file: %v", err)
-	}
-
-	// Create analysis with subtasks
-	analysis := &tm.SubtaskAnalysis{
-		ParentTaskID:        "test-task-123",
-		EstimatedTotalHours: 20,
-		Subtasks: []tm.SubtaskProposal{
-			{
-				Title:      "Subtask 1",
-				AssignedTo: "backend",
-			},
-			{
-				Title:      "Subtask 2",
-				AssignedTo: "frontend",
-			},
-		},
-	}
-
-	// Update the parent task
-	err = service.updateParentTaskAsCompleted(tmpFile.Name(), analysis)
-	if err != nil {
-		t.Fatalf("updateParentTaskAsCompleted failed: %v", err)
-	}
-
-	// Read the updated file
-	updatedContent, err := os.ReadFile(tmpFile.Name())
-	if err != nil {
-		t.Fatalf("Failed to read updated file: %v", err)
-	}
-
-	updatedString := string(updatedContent)
-
-	// Verify the status was changed to completed
-	if !strings.Contains(updatedString, "status: completed") {
-		t.Error("Updated file should contain 'status: completed'")
-	}
-
-	// Verify completed_at was set (should not be null)
-	if strings.Contains(updatedString, "completed_at: null") {
-		t.Error("Updated file should have completed_at timestamp, not null")
-	}
-
-	// Verify subtask information was added
-	if !strings.Contains(updatedString, "## Subtasks Created") {
-		t.Error("Updated file should contain subtasks information")
-	}
-
-	if !strings.Contains(updatedString, "test-task-123-subtask-1") {
-		t.Error("Updated file should reference created subtask IDs")
-	}
-
-	if !strings.Contains(updatedString, "**Total Estimated Hours:** 20") {
-		t.Error("Updated file should contain total estimated hours")
-	}
-}
-
-func TestClose(t *testing.T) {
-	mockProvider := NewMockLLMProvider([]string{})
-	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
-
-	err := service.Close()
-	if err != nil {
-		t.Errorf("Close should not return error, got: %v", err)
-	}
-}
-
-// Benchmark tests
-func BenchmarkAnalyzeTaskForSubtasks(b *testing.B) {
-	jsonResponse := `{
-  "analysis_summary": "Benchmark test",
-  "subtasks": [
-    {
-      "title": "Benchmark Subtask",
-      "description": "Benchmark description",
-      "priority": "high",
-      "assigned_to": "backend",
-      "estimated_hours": 8,
-      "dependencies": []
-    }
-  ],
-  "recommended_approach": "Benchmark approach",
-  "estimated_total_hours": 8
-}`
-
-	mockProvider := NewMockLLMProvider([]string{jsonResponse})
-	service := NewSubtaskService(mockProvider, nil, []string{"backend", "frontend"}, nil, "example", "repo", nil, nil)
-
-	task := &tm.Task{
-		ID:          "benchmark-task",
-		Title:       "Benchmark Task",
-		Description: "Task for benchmarking",
-		Priority:    tm.PriorityHigh,
-	}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		// Reset mock provider for each iteration
-		mockProvider.callCount = 0
-		_, err := service.AnalyzeTaskForSubtasks(context.Background(), task)
-		if err != nil {
-			b.Fatalf("AnalyzeTaskForSubtasks failed: %v", err)
-		}
-	}
-}
diff --git a/server/tm/git_tm/example.go b/server/tm/git_tm/example.go
deleted file mode 100644
index e1b0412..0000000
--- a/server/tm/git_tm/example.go
+++ /dev/null
@@ -1,122 +0,0 @@
-package git_tm
-
-import (
-	"context"
-	"fmt"
-	"log/slog"
-	"os"
-	"time"
-
-	"github.com/iomodo/staff/git"
-	"github.com/iomodo/staff/tm"
-)
-
-// Example demonstrates how to use the GitTaskManager
-func Example() {
-	// Create logger
-	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
-
-	// Initialize git interface
-	gitInterface := git.DefaultGit("./tasks-repo")
-
-	// Create task manager
-	taskManager := NewGitTaskManagerWithLogger(gitInterface, "./tasks-repo", logger)
-
-	// Create a new task
-	ctx := context.Background()
-	dueDate := time.Now().AddDate(0, 0, 7) // Due in 7 days
-
-	createReq := &tm.TaskCreateRequest{
-		Title:       "Implement user authentication",
-		Description: "Add login/logout functionality with JWT tokens",
-		OwnerID:     "john.doe",
-		Priority:    tm.PriorityHigh,
-		DueDate:     &dueDate,
-	}
-
-	task, err := taskManager.CreateTask(ctx, createReq)
-	if err != nil {
-		logger.Error("Failed to create task", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Created task", slog.String("id", task.ID))
-
-	// Get the task
-	retrievedTask, err := taskManager.GetTask(task.ID)
-	if err != nil {
-		logger.Error("Failed to get task", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Retrieved task", slog.String("id", retrievedTask.ID), slog.String("title", retrievedTask.Title))
-
-	// Start the task
-	startedTask, err := taskManager.StartTask(ctx, task.ID)
-	if err != nil {
-		logger.Error("Failed to start task", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Started task", slog.String("id", startedTask.ID), slog.String("status", string(startedTask.Status)))
-
-	// List all tasks
-	taskList, err := taskManager.ListTasks(ctx, nil, 0, 10)
-	if err != nil {
-		logger.Error("Failed to list tasks", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Total tasks", slog.Int("count", taskList.TotalCount))
-	for _, t := range taskList.Tasks {
-		logger.Info("Task", slog.String("id", t.ID), slog.String("title", t.Title), slog.String("status", string(t.Status)))
-	}
-
-	// Complete the task
-	completedTask, err := taskManager.CompleteTask(ctx, task.ID)
-	if err != nil {
-		logger.Error("Failed to complete task", slog.String("error", err.Error()))
-		os.Exit(1)
-	}
-
-	logger.Info("Completed task", slog.String("id", completedTask.ID), slog.String("completed_at", completedTask.CompletedAt.Format(time.RFC3339)))
-}
-
-// ExampleTaskFile shows the format of a task file
-func ExampleTaskFile() {
-	fmt.Print(`Example task file (tasks/task-1704067200-abc123.md):
-
----
-id: task-1704067200-abc123
-title: Implement user authentication
-description: Add login/logout functionality with JWT tokens
-owner_id: john.doe
-owner_name: John Doe
-status: in_progress
-priority: high
-created_at: 2024-01-01T10:00:00Z
-updated_at: 2024-01-01T15:30:00Z
-due_date: 2024-01-08T17:00:00Z
-completed_at: null
-archived_at: null
----
-
-# Task Description
-
-Add login/logout functionality with JWT tokens for the web application.
-
-## Requirements
-
-- User registration and login forms
-- JWT token generation and validation
-- Password hashing with bcrypt
-- Session management
-- Logout functionality
-
-## Notes
-
-- Consider using bcrypt for password hashing
-- Implement refresh token mechanism
-- Add rate limiting for login attempts
-`)
-}
diff --git a/server/tm/git_tm/git_task_manager.go b/server/tm/git_tm/git_task_manager.go
index 515fa51..cca9da8 100644
--- a/server/tm/git_tm/git_task_manager.go
+++ b/server/tm/git_tm/git_task_manager.go
@@ -5,12 +5,14 @@
 	"fmt"
 	"log/slog"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"sort"
 	"strings"
 	"time"
 
 	"github.com/google/uuid"
+	"github.com/iomodo/staff/config"
 	"github.com/iomodo/staff/git"
 	"github.com/iomodo/staff/tm"
 	"gopkg.in/yaml.v3"
@@ -29,68 +31,23 @@
 	TaskIDPrefix = "task-"
 )
 
-// UserService defines interface for user-related operations
-type UserService interface {
-	GetUserName(userID string) (string, error)
-}
-
-// DefaultUserService provides a simple implementation that uses userID as name
-type DefaultUserService struct{}
-
-func (dus *DefaultUserService) GetUserName(userID string) (string, error) {
-	// For now, just return the userID as the name
-	// This can be enhanced to lookup from a proper user service
-	return userID, nil
-}
-
 // GitTaskManager implements TaskManager interface using git as the source of truth
 type GitTaskManager struct {
-	git         git.GitInterface
-	repoPath    string
-	tasksDir    string
-	logger      *slog.Logger
-	userService UserService
+	git      git.GitInterface
+	repoPath string
+	tasksDir string
+	config   *config.Config
+	logger   *slog.Logger
 }
 
 // NewGitTaskManager creates a new GitTaskManager instance
-func NewGitTaskManager(git git.GitInterface, repoPath string, logger *slog.Logger) *GitTaskManager {
+func NewGitTaskManager(gitInter git.GitInterface, cfg *config.Config, logger *slog.Logger) *GitTaskManager {
 	return &GitTaskManager{
-		git:         git,
-		repoPath:    repoPath,
-		tasksDir:    filepath.Join(repoPath, "tasks"),
-		logger:      logger,
-		userService: &DefaultUserService{},
-	}
-}
-
-// NewGitTaskManagerWithLogger creates a new GitTaskManager instance with a custom logger
-func NewGitTaskManagerWithLogger(git git.GitInterface, repoPath string, logger *slog.Logger) *GitTaskManager {
-	if logger == nil {
-		logger = slog.Default()
-	}
-	return &GitTaskManager{
-		git:         git,
-		repoPath:    repoPath,
-		tasksDir:    filepath.Join(repoPath, "tasks"),
-		logger:      logger,
-		userService: &DefaultUserService{},
-	}
-}
-
-// NewGitTaskManagerWithUserService creates a new GitTaskManager with custom user service
-func NewGitTaskManagerWithUserService(git git.GitInterface, repoPath string, logger *slog.Logger, userService UserService) *GitTaskManager {
-	if logger == nil {
-		logger = slog.Default()
-	}
-	if userService == nil {
-		userService = &DefaultUserService{}
-	}
-	return &GitTaskManager{
-		git:         git,
-		repoPath:    repoPath,
-		tasksDir:    filepath.Join(repoPath, "tasks"),
-		logger:      logger,
-		userService: userService,
+		git:      gitInter,
+		repoPath: cfg.Tasks.StoragePath,
+		tasksDir: filepath.Join(cfg.Tasks.StoragePath, "tasks"),
+		config:   cfg,
+		logger:   logger,
 	}
 }
 
@@ -320,12 +277,7 @@
 	taskID := gtm.generateTaskID()
 	now := time.Now()
 
-	// Get owner name from user service
-	ownerName, err := gtm.userService.GetUserName(req.OwnerID)
-	if err != nil {
-		gtm.logger.Warn("Failed to get owner name, using ID", slog.String("ownerID", req.OwnerID), slog.String("error", err.Error()))
-		ownerName = req.OwnerID
-	}
+	ownerName := (req.OwnerID) //TODO: Get owner name from user service
 
 	// Create task
 	task := &tm.Task{
@@ -581,5 +533,600 @@
 	return gtm.ListTasks(ctx, filter, page, pageSize)
 }
 
+// GenerateSubtaskPR creates a PR with the proposed subtasks
+func (gtm *GitTaskManager) ProposeSubTasks(ctx context.Context, task *tm.Task, analysis *tm.SubtaskAnalysis) (string, error) {
+	branchName := generateBranchName("subtasks", task)
+	gtm.logger.Info("Creating subtask PR", slog.String("branch", branchName))
+
+	// Create Git branch and commit subtask proposal
+	if err := gtm.createSubtaskBranch(ctx, analysis, branchName); err != nil {
+		return "", fmt.Errorf("failed to create subtask branch: %w", err)
+	}
+
+	// Generate PR content
+	prContent := gtm.generateSubtaskPRContent(analysis)
+	title := fmt.Sprintf("Subtask Proposal: %s", analysis.ParentTaskID)
+
+	// Validate PR content
+	if title == "" {
+		return "", fmt.Errorf("PR title cannot be empty")
+	}
+	if prContent == "" {
+		return "", fmt.Errorf("PR description cannot be empty")
+	}
+
+	// Determine base branch (try main first, fallback to master)
+	baseBranch := gtm.determineBaseBranch(ctx)
+	gtm.logger.Info("Using base branch", slog.String("base_branch", baseBranch))
+
+	// Create the pull request
+	options := git.PullRequestOptions{
+		Title:       title,
+		Description: prContent,
+		HeadBranch:  branchName,
+		BaseBranch:  baseBranch,
+		Labels:      []string{"subtasks", "proposal", "ai-generated"},
+		Draft:       false,
+	}
+
+	gtm.logger.Info("Creating PR with options",
+		slog.String("title", options.Title),
+		slog.String("head_branch", options.HeadBranch),
+		slog.String("base_branch", options.BaseBranch))
+
+	pr, err := gtm.git.CreatePullRequest(ctx, options)
+	if err != nil {
+		return "", fmt.Errorf("failed to create PR: %w", err)
+	}
+
+	gtm.logger.Info("Generated subtask proposal PR", slog.String("pr_url", pr.URL))
+
+	return pr.URL, nil
+}
+
+func (gtm *GitTaskManager) ProposeSolution(ctx context.Context, task *tm.Task, solution, agentName string) (string, error) {
+	branchName := generateBranchName("solution", task)
+	gtm.logger.Info("Creating solution PR", slog.String("branch", branchName))
+
+	if err := gtm.createSolutionBranch(ctx, task, solution, branchName, agentName); err != nil {
+		return "", fmt.Errorf("failed to create solution branch: %w", err)
+	}
+	// Build PR description from template
+	description := buildSolutionPRDescription(task, solution, gtm.config.Git.PRTemplate, agentName)
+
+	options := git.PullRequestOptions{
+		Title:       fmt.Sprintf("Task %s: %s", task.ID, task.Title),
+		Description: description,
+		HeadBranch:  branchName,
+		BaseBranch:  "main",
+		Labels:      []string{"ai-generated"},
+		Draft:       false,
+	}
+
+	pr, err := gtm.git.CreatePullRequest(ctx, options)
+	if err != nil {
+		return "", fmt.Errorf("failed to create PR: %w", err)
+	}
+	gtm.logger.Info("Generated subtask proposal PR", slog.String("pr_url", pr.URL))
+	return pr.URL, nil
+}
+
+// createSubtaskBranch creates a Git branch with subtask proposal content
+func (gtm *GitTaskManager) createSubtaskBranch(ctx context.Context, analysis *tm.SubtaskAnalysis, branchName string) error {
+	clonePath, err := gtm.git.GetAgentClonePath("subtask-service")
+	if err != nil {
+		return fmt.Errorf("failed to get clone path: %w", err)
+	}
+
+	// All Git operations use the clone directory
+	gitCmd := func(args ...string) *exec.Cmd {
+		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
+	}
+
+	// Ensure we're on main branch before creating new branch
+	cmd := gitCmd("checkout", "main")
+	if err := cmd.Run(); err != nil {
+		// Try master branch if main doesn't exist
+		cmd = gitCmd("checkout", "master")
+		if err := cmd.Run(); err != nil {
+			return fmt.Errorf("failed to checkout main/master branch: %w", err)
+		}
+	}
+
+	// Pull latest changes
+	cmd = gitCmd("pull", "origin")
+	if err := cmd.Run(); err != nil {
+		gtm.logger.Warn("Failed to pull latest changes", slog.String("error", err.Error()))
+	}
+
+	// Delete branch if it exists (cleanup from previous attempts)
+	cmd = gitCmd("branch", "-D", branchName)
+	_ = cmd.Run() // Ignore error if branch doesn't exist
+
+	// Also delete remote tracking branch if it exists
+	cmd = gitCmd("push", "origin", "--delete", branchName)
+	_ = cmd.Run() // Ignore error if branch doesn't exist
+
+	// Create and checkout new branch
+	cmd = gitCmd("checkout", "-b", branchName)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to create branch: %w", err)
+	}
+
+	// Create individual task files for each subtask
+	tasksDir := filepath.Join(clonePath, "operations", "tasks")
+	if err := os.MkdirAll(tasksDir, 0755); err != nil {
+		return fmt.Errorf("failed to create tasks directory: %w", err)
+	}
+
+	var stagedFiles []string
+
+	// Update parent task to mark as completed
+	parentTaskFile := filepath.Join(tasksDir, fmt.Sprintf("%s.md", analysis.ParentTaskID))
+	if err := gtm.updateParentTaskAsCompleted(parentTaskFile, analysis); err != nil {
+		return fmt.Errorf("failed to update parent task: %w", err)
+	}
+
+	// Track parent task file for staging
+	parentRelativeFile := filepath.Join("operations", "tasks", fmt.Sprintf("%s.md", analysis.ParentTaskID))
+	stagedFiles = append(stagedFiles, parentRelativeFile)
+	gtm.logger.Info("Updated parent task file", slog.String("file", parentRelativeFile))
+
+	// Create a file for each subtask
+	for i, subtask := range analysis.Subtasks {
+		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+		taskFile := filepath.Join(tasksDir, fmt.Sprintf("%s.md", taskID))
+		taskContent := gtm.generateSubtaskFile(subtask, taskID, analysis.ParentTaskID)
+
+		if err := os.WriteFile(taskFile, []byte(taskContent), 0644); err != nil {
+			return fmt.Errorf("failed to write subtask file %s: %w", taskID, err)
+		}
+
+		// Track file for staging
+		relativeFile := filepath.Join("operations", "tasks", fmt.Sprintf("%s.md", taskID))
+		stagedFiles = append(stagedFiles, relativeFile)
+		gtm.logger.Info("Created subtask file", slog.String("file", relativeFile))
+	}
+
+	// Stage all subtask files
+	for _, file := range stagedFiles {
+		cmd = gitCmd("add", file)
+		if err := cmd.Run(); err != nil {
+			return fmt.Errorf("failed to stage file %s: %w", file, err)
+		}
+	}
+
+	// Commit changes
+	commitMsg := fmt.Sprintf("Create %d subtasks for task %s and mark parent as completed\n\nGenerated by Staff AI Agent System\n\nFiles modified:\n- %s.md (marked as completed)\n\nCreated individual task files:\n",
+		len(analysis.Subtasks), analysis.ParentTaskID, analysis.ParentTaskID)
+
+	// Add list of created files to commit message
+	for i := range analysis.Subtasks {
+		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+		commitMsg += fmt.Sprintf("- %s.md\n", taskID)
+	}
+
+	if len(analysis.AgentCreations) > 0 {
+		commitMsg += fmt.Sprintf("\nProposed %d new agents for specialized skills", len(analysis.AgentCreations))
+	}
+	cmd = gitCmd("commit", "-m", commitMsg)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to commit: %w", err)
+	}
+
+	// Push branch
+	cmd = gitCmd("push", "-u", "origin", branchName)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to push branch: %w", err)
+	}
+
+	gtm.logger.Info("Created subtask proposal branch", slog.String("branch", branchName))
+	return nil
+}
+
+// updateParentTaskAsCompleted updates the parent task file to mark it as completed
+func (gtm *GitTaskManager) updateParentTaskAsCompleted(taskFilePath string, analysis *tm.SubtaskAnalysis) error {
+	// Read the existing parent task file
+	content, err := os.ReadFile(taskFilePath)
+	if err != nil {
+		return fmt.Errorf("failed to read parent task file: %w", err)
+	}
+
+	taskContent := string(content)
+
+	// Find the YAML frontmatter boundaries
+	lines := strings.Split(taskContent, "\n")
+	var frontmatterStart, frontmatterEnd int = -1, -1
+
+	for i, line := range lines {
+		if line == "---" {
+			if frontmatterStart == -1 {
+				frontmatterStart = i
+			} else {
+				frontmatterEnd = i
+				break
+			}
+		}
+	}
+
+	if frontmatterStart == -1 || frontmatterEnd == -1 {
+		return fmt.Errorf("invalid task file format: missing YAML frontmatter")
+	}
+
+	// Update the frontmatter
+	now := time.Now().Format(time.RFC3339)
+	var updatedLines []string
+
+	// Add lines before frontmatter
+	updatedLines = append(updatedLines, lines[:frontmatterStart+1]...)
+
+	// Process frontmatter lines
+	for i := frontmatterStart + 1; i < frontmatterEnd; i++ {
+		line := lines[i]
+		if strings.HasPrefix(line, "status:") {
+			updatedLines = append(updatedLines, "status: completed")
+		} else if strings.HasPrefix(line, "updated_at:") {
+			updatedLines = append(updatedLines, fmt.Sprintf("updated_at: %s", now))
+		} else if strings.HasPrefix(line, "completed_at:") {
+			updatedLines = append(updatedLines, fmt.Sprintf("completed_at: %s", now))
+		} else {
+			updatedLines = append(updatedLines, line)
+		}
+	}
+
+	// Add closing frontmatter and rest of content
+	updatedLines = append(updatedLines, lines[frontmatterEnd:]...)
+
+	// Add subtask information to the task description
+	if frontmatterEnd+1 < len(lines) {
+		// Add subtask information
+		subtaskInfo := fmt.Sprintf("\n\n## Subtasks Created\n\nThis task has been broken down into %d subtasks:\n\n", len(analysis.Subtasks))
+		for i, subtask := range analysis.Subtasks {
+			subtaskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+			subtaskInfo += fmt.Sprintf("- **%s**: %s (assigned to %s)\n", subtaskID, subtask.Title, subtask.AssignedTo)
+		}
+		subtaskInfo += fmt.Sprintf("\n**Total Estimated Hours:** %d\n", analysis.EstimatedTotalHours)
+		subtaskInfo += fmt.Sprintf("**Completed:** %s - Task broken down into actionable subtasks\n", now)
+
+		// Insert subtask info before any existing body content
+		updatedContent := strings.Join(updatedLines[:], "\n") + subtaskInfo
+
+		// Write the updated content back to the file
+		if err := os.WriteFile(taskFilePath, []byte(updatedContent), 0644); err != nil {
+			return fmt.Errorf("failed to write updated parent task file: %w", err)
+		}
+	}
+
+	gtm.logger.Info("Updated parent task to completed status", slog.String("task_id", analysis.ParentTaskID))
+	return nil
+}
+
+// generateSubtaskFile creates the content for an individual subtask file
+func (gtm *GitTaskManager) generateSubtaskFile(subtask tm.SubtaskProposal, taskID, parentTaskID string) string {
+	var content strings.Builder
+
+	// Generate YAML frontmatter
+	content.WriteString("---\n")
+	content.WriteString(fmt.Sprintf("id: %s\n", taskID))
+	content.WriteString(fmt.Sprintf("title: %s\n", subtask.Title))
+	content.WriteString(fmt.Sprintf("description: %s\n", subtask.Description))
+	content.WriteString(fmt.Sprintf("assignee: %s\n", subtask.AssignedTo))
+	content.WriteString(fmt.Sprintf("owner_id: %s\n", subtask.AssignedTo))
+	content.WriteString(fmt.Sprintf("owner_name: %s\n", subtask.AssignedTo))
+	content.WriteString("status: todo\n")
+	content.WriteString(fmt.Sprintf("priority: %s\n", strings.ToLower(string(subtask.Priority))))
+	content.WriteString(fmt.Sprintf("parent_task_id: %s\n", parentTaskID))
+	content.WriteString(fmt.Sprintf("estimated_hours: %d\n", subtask.EstimatedHours))
+	content.WriteString(fmt.Sprintf("created_at: %s\n", time.Now().Format(time.RFC3339)))
+	content.WriteString(fmt.Sprintf("updated_at: %s\n", time.Now().Format(time.RFC3339)))
+	content.WriteString("completed_at: null\n")
+	content.WriteString("archived_at: null\n")
+
+	// Add dependencies if any
+	if len(subtask.Dependencies) > 0 {
+		content.WriteString("dependencies:\n")
+		for _, dep := range subtask.Dependencies {
+			// Convert dependency index to actual subtask ID
+			if depIndex := parseDependencyIndex(dep); depIndex >= 0 {
+				depTaskID := fmt.Sprintf("%s-subtask-%d", parentTaskID, depIndex+1)
+				content.WriteString(fmt.Sprintf("  - %s\n", depTaskID))
+			}
+		}
+	}
+
+	// Add required skills if any
+	if len(subtask.RequiredSkills) > 0 {
+		content.WriteString("required_skills:\n")
+		for _, skill := range subtask.RequiredSkills {
+			content.WriteString(fmt.Sprintf("  - %s\n", skill))
+		}
+	}
+
+	content.WriteString("---\n\n")
+
+	// Add markdown content
+	content.WriteString("# Task Description\n\n")
+	content.WriteString(fmt.Sprintf("%s\n\n", subtask.Description))
+
+	if subtask.EstimatedHours > 0 {
+		content.WriteString("## Estimated Effort\n\n")
+		content.WriteString(fmt.Sprintf("**Estimated Hours:** %d\n\n", subtask.EstimatedHours))
+	}
+
+	if len(subtask.RequiredSkills) > 0 {
+		content.WriteString("## Required Skills\n\n")
+		for _, skill := range subtask.RequiredSkills {
+			content.WriteString(fmt.Sprintf("- %s\n", skill))
+		}
+		content.WriteString("\n")
+	}
+
+	if len(subtask.Dependencies) > 0 {
+		content.WriteString("## Dependencies\n\n")
+		content.WriteString("This task depends on the completion of:\n\n")
+		for _, dep := range subtask.Dependencies {
+			if depIndex := parseDependencyIndex(dep); depIndex >= 0 {
+				depTaskID := fmt.Sprintf("%s-subtask-%d", parentTaskID, depIndex+1)
+				content.WriteString(fmt.Sprintf("- %s\n", depTaskID))
+			}
+		}
+		content.WriteString("\n")
+	}
+
+	content.WriteString("## Notes\n\n")
+	content.WriteString(fmt.Sprintf("This subtask was generated from parent task: %s\n", parentTaskID))
+	content.WriteString("Generated by Staff AI Agent System\n\n")
+
+	return content.String()
+}
+
+func (gtm *GitTaskManager) generateSubtaskPRContent(analysis *tm.SubtaskAnalysis) string {
+	var content strings.Builder
+
+	content.WriteString(fmt.Sprintf("# Subtasks Created for Task %s\n\n", analysis.ParentTaskID))
+	content.WriteString(fmt.Sprintf("This PR creates **%d individual task files** in `/operations/tasks/` ready for agent assignment.\n\n", len(analysis.Subtasks)))
+	content.WriteString(fmt.Sprintf("✅ **Parent task `%s` has been marked as completed** - the complex task has been successfully broken down into actionable subtasks.\n\n", analysis.ParentTaskID))
+	content.WriteString(fmt.Sprintf("## Analysis Summary\n%s\n\n", analysis.AnalysisSummary))
+	content.WriteString(fmt.Sprintf("## Recommended Approach\n%s\n\n", analysis.RecommendedApproach))
+	content.WriteString(fmt.Sprintf("**Estimated Total Hours:** %d\n\n", analysis.EstimatedTotalHours))
+
+	// List the created task files
+	content.WriteString("## Created Task Files\n\n")
+	for i, subtask := range analysis.Subtasks {
+		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+		content.WriteString(fmt.Sprintf("### %d. `%s.md`\n", i+1, taskID))
+		content.WriteString(fmt.Sprintf("- **Title:** %s\n", subtask.Title))
+		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
+		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
+		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
+		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
+	}
+
+	if analysis.RiskAssessment != "" {
+		content.WriteString(fmt.Sprintf("## Risk Assessment\n%s\n\n", analysis.RiskAssessment))
+	}
+
+	content.WriteString("## Proposed Subtasks\n\n")
+
+	for i, subtask := range analysis.Subtasks {
+		content.WriteString(fmt.Sprintf("### %d. %s\n", i+1, subtask.Title))
+		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
+		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
+		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
+
+		if len(subtask.Dependencies) > 0 {
+			deps := strings.Join(subtask.Dependencies, ", ")
+			content.WriteString(fmt.Sprintf("- **Dependencies:** %s\n", deps))
+		}
+
+		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
+	}
+
+	content.WriteString("---\n")
+	content.WriteString("*Generated by Staff AI Agent System*\n\n")
+	content.WriteString("**Instructions:**\n")
+	content.WriteString("- Review the proposed subtasks\n")
+	content.WriteString("- Approve or request changes\n")
+	content.WriteString("- When merged, the subtasks will be automatically created and assigned\n")
+
+	return content.String()
+}
+
+func (gtm *GitTaskManager) determineBaseBranch(ctx context.Context) string {
+	// Get clone path to check branches
+	clonePath, err := gtm.git.GetAgentClonePath("subtask-service")
+	if err != nil {
+		gtm.logger.Warn("Failed to get clone path for base branch detection", slog.String("error", err.Error()))
+		return "main"
+	}
+
+	// Check if main branch exists
+	gitCmd := func(args ...string) *exec.Cmd {
+		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
+	}
+
+	// Try to checkout main branch
+	cmd := gitCmd("show-ref", "refs/remotes/origin/main")
+	if err := cmd.Run(); err == nil {
+		return "main"
+	}
+
+	// Try to checkout master branch
+	cmd = gitCmd("show-ref", "refs/remotes/origin/master")
+	if err := cmd.Run(); err == nil {
+		return "master"
+	}
+
+	// Default to main if neither can be detected
+	gtm.logger.Warn("Could not determine base branch, defaulting to 'main'")
+	return "main"
+}
+
+// createAndCommitSolution creates a Git branch and commits the solution using per-agent clones
+func (gtm *GitTaskManager) createSolutionBranch(ctx context.Context, task *tm.Task, solution, branchName, agentName string) error {
+	// Get agent's dedicated Git clone
+	clonePath, err := gtm.git.GetAgentClonePath(agentName)
+	if err != nil {
+		return fmt.Errorf("failed to get agent clone: %w", err)
+	}
+
+	gtm.logger.Info("Agent working in clone",
+		slog.String("agent", agentName),
+		slog.String("clone_path", clonePath))
+
+	// Refresh the clone with latest changes
+	if err := gtm.git.RefreshAgentClone(agentName); err != nil {
+		gtm.logger.Warn("Failed to refresh clone for agent",
+			slog.String("agent", agentName),
+			slog.String("error", err.Error()))
+	}
+
+	// All Git operations use the agent's clone directory
+	gitCmd := func(args ...string) *exec.Cmd {
+		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
+	}
+
+	// Ensure we're on main branch before creating new branch
+	cmd := gitCmd("checkout", "main")
+	if err := cmd.Run(); err != nil {
+		// Try master branch if main doesn't exist
+		cmd = gitCmd("checkout", "master")
+		if err := cmd.Run(); err != nil {
+			return fmt.Errorf("failed to checkout main/master branch: %w", err)
+		}
+	}
+
+	// Create branch
+	cmd = gitCmd("checkout", "-b", branchName)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to create branch: %w", err)
+	}
+
+	// Create solution file in agent's clone
+	solutionDir := filepath.Join(clonePath, "tasks", "solutions")
+	if err := os.MkdirAll(solutionDir, 0755); err != nil {
+		return fmt.Errorf("failed to create solution directory: %w", err)
+	}
+
+	solutionFile := filepath.Join(solutionDir, fmt.Sprintf("%s-solution.md", task.ID))
+	solutionContent := fmt.Sprintf(`# Solution for Task: %s
+
+**Agent:** %s
+**Completed:** %s
+
+## Task Description
+%s
+
+## Solution
+%s
+
+---
+*Generated by Staff AI Agent System*
+`, task.Title, agentName, time.Now().Format(time.RFC3339), task.Description, solution)
+
+	if err := os.WriteFile(solutionFile, []byte(solutionContent), 0644); err != nil {
+		return fmt.Errorf("failed to write solution file: %w", err)
+	}
+
+	// Stage files
+	relativeSolutionFile := filepath.Join("tasks", "solutions", fmt.Sprintf("%s-solution.md", task.ID))
+	cmd = gitCmd("add", relativeSolutionFile)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to stage files: %w", err)
+	}
+
+	// Commit changes
+	commitMsg := buildCommitMessage(task, gtm.config.Git.CommitMessageTemplate, agentName)
+	cmd = gitCmd("commit", "-m", commitMsg)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to commit: %w", err)
+	}
+
+	// Push branch
+	cmd = gitCmd("push", "-u", "origin", branchName)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to push branch: %w", err)
+	}
+
+	gtm.logger.Info("Agent successfully pushed branch",
+		slog.String("agent", agentName),
+		slog.String("branch", branchName))
+	return nil
+}
+
+func buildCommitMessage(task *tm.Task, template, agentName string) string {
+	replacements := map[string]string{
+		"{task_id}":    task.ID,
+		"{task_title}": task.Title,
+		"{agent_name}": agentName,
+		"{solution}":   "See solution file for details",
+	}
+
+	result := template
+	for placeholder, value := range replacements {
+		result = strings.ReplaceAll(result, placeholder, value)
+	}
+
+	return result
+}
+
+// parseDependencyIndex parses a dependency string to an integer index
+func parseDependencyIndex(dep string) int {
+	var idx int
+	if _, err := fmt.Sscanf(dep, "%d", &idx); err == nil {
+		return idx
+	}
+	return -1 // Invalid dependency format
+}
+
+// generateBranchName creates a Git branch name for the task
+func generateBranchName(prefix string, task *tm.Task) string {
+	// Clean title for use in branch name
+	cleanTitle := strings.ToLower(task.Title)
+	cleanTitle = strings.ReplaceAll(cleanTitle, " ", "-")
+	cleanTitle = strings.ReplaceAll(cleanTitle, "/", "-")
+	// Remove special characters
+	var result strings.Builder
+	for _, r := range cleanTitle {
+		if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '-' {
+			result.WriteRune(r)
+		}
+	}
+	cleanTitle = result.String()
+
+	// Limit length
+	if len(cleanTitle) > 40 {
+		cleanTitle = cleanTitle[:40]
+	}
+
+	return fmt.Sprintf("%s%s-%s", prefix, task.ID, cleanTitle)
+}
+
+// buildSolutionPRDescription creates PR description from template
+func buildSolutionPRDescription(task *tm.Task, solution, template, agentName string) string {
+	// Truncate solution for PR if too long
+	truncatedSolution := solution
+	if len(solution) > 1000 {
+		truncatedSolution = solution[:1000] + "...\n\n*See solution file for complete details*"
+	}
+
+	replacements := map[string]string{
+		"{task_id}":          task.ID,
+		"{task_title}":       task.Title,
+		"{task_description}": task.Description,
+		"{agent_name}":       fmt.Sprintf("%s", agentName),
+		"{priority}":         string(task.Priority),
+		"{solution}":         truncatedSolution,
+		"{files_changed}":    fmt.Sprintf("- `tasks/solutions/%s-solution.md`", task.ID),
+	}
+
+	result := template
+	for placeholder, value := range replacements {
+		result = strings.ReplaceAll(result, placeholder, value)
+	}
+
+	return result
+}
+
 // Ensure GitTaskManager implements TaskManager interface
 var _ tm.TaskManager = (*GitTaskManager)(nil)
diff --git a/server/tm/git_tm/git_task_manager_test.go b/server/tm/git_tm/git_task_manager_test.go
deleted file mode 100644
index 751ad89..0000000
--- a/server/tm/git_tm/git_task_manager_test.go
+++ /dev/null
@@ -1,1037 +0,0 @@
-package git_tm
-
-import (
-	"context"
-	"log/slog"
-	"os"
-	"path/filepath"
-	"testing"
-	"time"
-
-	"github.com/iomodo/staff/git"
-	"github.com/iomodo/staff/tm"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-// Test helper functions
-func setupTestDir(t *testing.T) (string, func()) {
-	tempDir, err := os.MkdirTemp("", "git-task-manager-test")
-	require.NoError(t, err)
-
-	cleanup := func() {
-		os.RemoveAll(tempDir)
-	}
-
-	return tempDir, cleanup
-}
-
-func createTestTaskManager(t *testing.T, repoPath string) (*GitTaskManager, git.GitInterface) {
-	// Initialize git repository
-	gitImpl := git.DefaultGit(repoPath)
-	ctx := context.Background()
-
-	err := gitImpl.Init(ctx, repoPath)
-	require.NoError(t, err)
-
-	// Set up git user config for commits
-	userConfig := git.UserConfig{
-		Name:  "Test User",
-		Email: "test@example.com",
-	}
-	err = gitImpl.SetUserConfig(ctx, userConfig)
-	require.NoError(t, err)
-
-	// Create logger for testing
-	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
-
-	gtm := NewGitTaskManagerWithLogger(gitImpl, repoPath, logger)
-	return gtm, gitImpl
-}
-
-// Test cases
-func TestNewGitTaskManager(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gitImpl := git.DefaultGit(tempDir)
-
-	// Create logger for testing
-	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
-
-	gtm := NewGitTaskManagerWithLogger(gitImpl, tempDir, logger)
-
-	assert.NotNil(t, gtm)
-	assert.Equal(t, gitImpl, gtm.git)
-	assert.Equal(t, tempDir, gtm.repoPath)
-	assert.Equal(t, filepath.Join(tempDir, "tasks"), gtm.tasksDir)
-}
-
-func TestEnsureTasksDir(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Test creating tasks directory
-	err := gtm.ensureTasksDir()
-	assert.NoError(t, err)
-
-	// Verify directory exists
-	_, err = os.Stat(gtm.tasksDir)
-	assert.NoError(t, err)
-
-	// Test creating again (should not error)
-	err = gtm.ensureTasksDir()
-	assert.NoError(t, err)
-}
-
-func TestGenerateTaskID(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	id1 := gtm.generateTaskID()
-	id2 := gtm.generateTaskID()
-
-	assert.NotEmpty(t, id1)
-	assert.NotEmpty(t, id2)
-	assert.NotEqual(t, id1, id2)
-	assert.Contains(t, id1, "task-")
-}
-
-func TestTaskToMarkdown(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	now := time.Now()
-	dueDate := now.Add(24 * time.Hour)
-	completedAt := now.Add(12 * time.Hour)
-
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "This is a test task",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:      tm.StatusToDo,
-		Priority:    tm.PriorityHigh,
-		CreatedAt:   now,
-		UpdatedAt:   now,
-		DueDate:     &dueDate,
-		CompletedAt: &completedAt,
-	}
-
-	markdown, err := gtm.taskToMarkdown(task)
-	assert.NoError(t, err)
-	assert.NotEmpty(t, markdown)
-	assert.Contains(t, markdown, "---")
-	assert.Contains(t, markdown, "id: test-task-123")
-	assert.Contains(t, markdown, "title: Test Task")
-	assert.Contains(t, markdown, "description: This is a test task")
-	assert.Contains(t, markdown, "owner_id: user123")
-	assert.Contains(t, markdown, "owner_name: Test User")
-	assert.Contains(t, markdown, "status: todo")
-	assert.Contains(t, markdown, "priority: high")
-	assert.Contains(t, markdown, "# Task Description")
-	assert.Contains(t, markdown, "This is a test task")
-}
-
-func TestParseTaskFromMarkdown(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	markdown := `---
-id: test-task-123
-title: Test Task
-description: This is a test task
-owner_id: user123
-owner_name: Test User
-status: todo
-priority: high
-created_at: 2023-01-01T00:00:00Z
-updated_at: 2023-01-01T00:00:00Z
-due_date: 2023-01-02T00:00:00Z
-completed_at: 2023-01-01T12:00:00Z
----
-
-# Task Description
-
-This is a test task
-`
-
-	task, err := gtm.parseTaskFromMarkdown(markdown)
-	assert.NoError(t, err)
-	assert.NotNil(t, task)
-	assert.Equal(t, "test-task-123", task.ID)
-	assert.Equal(t, "Test Task", task.Title)
-	assert.Equal(t, "This is a test task", task.Description)
-	assert.Equal(t, "user123", task.Owner.ID)
-	assert.Equal(t, "Test User", task.Owner.Name)
-	assert.Equal(t, tm.StatusToDo, task.Status)
-	assert.Equal(t, tm.PriorityHigh, task.Priority)
-}
-
-func TestParseTaskFromMarkdownInvalid(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Test invalid markdown format
-	invalidMarkdown := "This is not valid markdown"
-
-	task, err := gtm.parseTaskFromMarkdown(invalidMarkdown)
-	assert.Error(t, err)
-	assert.Nil(t, task)
-	assert.Contains(t, err.Error(), "invalid markdown format")
-}
-
-func TestWriteAndReadTaskFile(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Ensure tasks directory exists
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-
-	// Create test task
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "This is a test task",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:    tm.StatusToDo,
-		Priority:  tm.PriorityHigh,
-		CreatedAt: time.Now(),
-		UpdatedAt: time.Now(),
-	}
-
-	// Write task file
-	err = gtm.writeTaskFile(task)
-	assert.NoError(t, err)
-
-	// Verify file exists
-	filePath := filepath.Join(gtm.tasksDir, task.ID+".md")
-	_, err = os.Stat(filePath)
-	assert.NoError(t, err)
-
-	// Read task file
-	readTask, err := gtm.readTaskFile(task.ID)
-	assert.NoError(t, err)
-	assert.NotNil(t, readTask)
-	assert.Equal(t, task.ID, readTask.ID)
-	assert.Equal(t, task.Title, readTask.Title)
-	assert.Equal(t, task.Description, readTask.Description)
-	assert.Equal(t, task.Owner.ID, readTask.Owner.ID)
-	assert.Equal(t, task.Owner.Name, readTask.Owner.Name)
-	assert.Equal(t, task.Status, readTask.Status)
-	assert.Equal(t, task.Priority, readTask.Priority)
-}
-
-func TestReadTaskFileNotFound(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Try to read non-existent task
-	task, err := gtm.readTaskFile("non-existent-task")
-	assert.Error(t, err)
-	assert.Nil(t, task)
-	assert.Equal(t, tm.ErrTaskNotFound, err)
-}
-
-func TestListTaskFiles(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Ensure tasks directory exists
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-
-	// Create some test task files
-	taskIDs := []string{"task-1", "task-2", "task-3"}
-	for _, id := range taskIDs {
-		task := &tm.Task{
-			ID:          id,
-			Title:       "Test Task " + id,
-			Description: "Test task description",
-			Owner: tm.Owner{
-				ID:   "user123",
-				Name: "Test User",
-			},
-			Status:    tm.StatusToDo,
-			Priority:  tm.PriorityMedium,
-			CreatedAt: time.Now(),
-			UpdatedAt: time.Now(),
-		}
-		err = gtm.writeTaskFile(task)
-		require.NoError(t, err)
-	}
-
-	// Create a non-task file
-	nonTaskFile := filepath.Join(gtm.tasksDir, "readme.txt")
-	err = os.WriteFile(nonTaskFile, []byte("This is not a task"), 0644)
-	require.NoError(t, err)
-
-	// List task files
-	taskFiles, err := gtm.listTaskFiles()
-	assert.NoError(t, err)
-	assert.Len(t, taskFiles, 3)
-
-	// Verify all task IDs are present
-	for _, id := range taskIDs {
-		assert.Contains(t, taskFiles, id)
-	}
-}
-
-func TestListTaskFilesEmpty(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// List task files in non-existent directory
-	taskFiles, err := gtm.listTaskFiles()
-	assert.NoError(t, err)
-	assert.Empty(t, taskFiles)
-}
-
-func TestCommitTaskChange(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, gitImpl := createTestTaskManager(t, tempDir)
-
-	// Create a test task file first
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "Test description",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:    tm.StatusToDo,
-		Priority:  tm.PriorityMedium,
-		CreatedAt: time.Now(),
-		UpdatedAt: time.Now(),
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-	err = gtm.writeTaskFile(task)
-	require.NoError(t, err)
-
-	// Test successful commit
-	err = gtm.commitTaskChange("test-task-123", "created", task.Owner)
-	assert.NoError(t, err)
-
-	// Verify commit was created
-	ctx := context.Background()
-	commits, err := gitImpl.Log(ctx, git.LogOptions{MaxCount: 1})
-	assert.NoError(t, err)
-	if len(commits) > 0 {
-		assert.Contains(t, commits[0].Message, "test-task-123")
-		assert.Contains(t, commits[0].Message, "created")
-	}
-}
-
-func TestCreateTask(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, gitImpl := createTestTaskManager(t, tempDir)
-
-	ctx := context.Background()
-	req := &tm.TaskCreateRequest{
-		Title:       "New Test Task",
-		Description: "This is a new test task",
-		OwnerID:     "user123",
-		Priority:    tm.PriorityHigh,
-	}
-
-	task, err := gtm.CreateTask(ctx, req)
-	assert.NoError(t, err)
-	assert.NotNil(t, task)
-
-	// Verify task properties
-	assert.NotEmpty(t, task.ID)
-	assert.Contains(t, task.ID, "task-")
-	assert.Equal(t, req.Title, task.Title)
-	assert.Equal(t, req.Description, task.Description)
-	assert.Equal(t, req.OwnerID, task.Owner.ID)
-	assert.Equal(t, req.OwnerID, task.Owner.Name) // TODO: Should look up actual name
-	assert.Equal(t, tm.StatusToDo, task.Status)
-	assert.Equal(t, req.Priority, task.Priority)
-	assert.False(t, task.CreatedAt.IsZero())
-	assert.False(t, task.UpdatedAt.IsZero())
-
-	// Verify git commit was created
-	commits, err := gitImpl.Log(ctx, git.LogOptions{MaxCount: 1})
-	assert.NoError(t, err)
-	if len(commits) > 0 {
-		assert.Contains(t, commits[0].Message, task.ID)
-		assert.Contains(t, commits[0].Message, "created")
-	}
-}
-
-func TestCreateTaskInvalidData(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	ctx := context.Background()
-
-	// Test empty title
-	req := &tm.TaskCreateRequest{
-		Title:   "",
-		OwnerID: "user123",
-	}
-
-	task, err := gtm.CreateTask(ctx, req)
-	assert.Error(t, err)
-	assert.Nil(t, task)
-	assert.Equal(t, tm.ErrInvalidTaskData, err)
-
-	// Test empty owner ID
-	req = &tm.TaskCreateRequest{
-		Title:   "Valid Title",
-		OwnerID: "",
-	}
-
-	task, err = gtm.CreateTask(ctx, req)
-	assert.Error(t, err)
-	assert.Nil(t, task)
-	assert.Equal(t, tm.ErrInvalidOwner, err)
-}
-
-func TestGetTask(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create a test task
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "Test task description",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:    tm.StatusToDo,
-		Priority:  tm.PriorityMedium,
-		CreatedAt: time.Now(),
-		UpdatedAt: time.Now(),
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-	err = gtm.writeTaskFile(task)
-	require.NoError(t, err)
-
-	// Get the task
-	retrievedTask, err := gtm.GetTask(task.ID)
-	assert.NoError(t, err)
-	assert.NotNil(t, retrievedTask)
-	assert.Equal(t, task.ID, retrievedTask.ID)
-	assert.Equal(t, task.Title, retrievedTask.Title)
-}
-
-func TestGetTaskNotFound(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	task, err := gtm.GetTask("non-existent-task")
-	assert.Error(t, err)
-	assert.Nil(t, task)
-	assert.Equal(t, tm.ErrTaskNotFound, err)
-}
-
-func TestUpdateTask(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, gitImpl := createTestTaskManager(t, tempDir)
-
-	// Create a test task
-	originalTask := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Original Title",
-		Description: "Original description",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Original User",
-		},
-		Status:    tm.StatusToDo,
-		Priority:  tm.PriorityLow,
-		CreatedAt: time.Now().Add(-time.Hour),
-		UpdatedAt: time.Now().Add(-time.Hour),
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-	err = gtm.writeTaskFile(originalTask)
-	require.NoError(t, err)
-
-	// Commit the initial task
-	err = gtm.commitTaskChange(originalTask.ID, "created", originalTask.Owner)
-	require.NoError(t, err)
-
-	// Update the task
-	ctx := context.Background()
-	newTitle := "Updated Title"
-	newDescription := "Updated description"
-	newStatus := tm.StatusInProgress
-	newPriority := tm.PriorityHigh
-	newOwnerID := "user456"
-
-	// 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)
-	assert.NotNil(t, updatedTask)
-
-	// Verify updated properties
-	assert.Equal(t, newTitle, updatedTask.Title)
-	assert.Equal(t, newDescription, updatedTask.Description)
-	assert.Equal(t, newStatus, updatedTask.Status)
-	assert.Equal(t, newPriority, updatedTask.Priority)
-	assert.Equal(t, newOwnerID, updatedTask.Owner.ID)
-	assert.Equal(t, newOwnerID, updatedTask.Owner.Name)
-
-	// Verify timestamps were updated
-	assert.True(t, updatedTask.UpdatedAt.After(originalTask.UpdatedAt))
-
-	// Verify git commit was created
-	commits, err := gitImpl.Log(ctx, git.LogOptions{MaxCount: 2})
-	assert.NoError(t, err)
-	if len(commits) > 0 {
-		assert.Contains(t, commits[0].Message, "updated")
-	}
-}
-
-func TestUpdateTaskNotFound(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Try to update non-existent task
-	fakeTask := &tm.Task{
-		ID:    "non-existent-task",
-		Title: "Updated Title",
-	}
-
-	err := gtm.UpdateTask(fakeTask)
-	assert.Error(t, err)
-}
-
-func TestUpdateTaskNoChanges(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create a test task
-	originalTask := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "Test description",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:    tm.StatusToDo,
-		Priority:  tm.PriorityMedium,
-		CreatedAt: time.Now().Add(-time.Hour),
-		UpdatedAt: time.Now().Add(-time.Hour),
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-	err = gtm.writeTaskFile(originalTask)
-	require.NoError(t, err)
-
-	// Update with no changes (just call UpdateTask with same task)
-	err = gtm.UpdateTask(originalTask)
-	assert.NoError(t, err)
-
-	// Get updated task to verify
-	updatedTask, err := gtm.GetTask(originalTask.ID)
-	assert.NoError(t, err)
-	assert.NotNil(t, updatedTask)
-
-	// Verify no changes were made to content
-	assert.Equal(t, originalTask.Title, updatedTask.Title)
-	assert.Equal(t, originalTask.Description, updatedTask.Description)
-	assert.Equal(t, originalTask.Status, updatedTask.Status)
-	assert.Equal(t, originalTask.Priority, updatedTask.Priority)
-	assert.Equal(t, originalTask.Owner.ID, updatedTask.Owner.ID)
-}
-
-func TestUpdateTaskStatusTimestamps(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create a test task
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "Test description",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:    tm.StatusToDo,
-		Priority:  tm.PriorityMedium,
-		CreatedAt: time.Now().Add(-time.Hour),
-		UpdatedAt: time.Now().Add(-time.Hour),
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-	err = gtm.writeTaskFile(task)
-	require.NoError(t, err)
-
-	// Test completing a task
-	task.Status = tm.StatusCompleted
-	now := time.Now()
-	task.CompletedAt = &now
-
-	err = gtm.UpdateTask(task)
-	assert.NoError(t, err)
-
-	// Get updated task to verify
-	updatedTask, err := gtm.GetTask(task.ID)
-	assert.NoError(t, err)
-	assert.NotNil(t, updatedTask)
-	assert.Equal(t, tm.StatusCompleted, updatedTask.Status)
-	assert.NotNil(t, updatedTask.CompletedAt)
-
-	// 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)
-	assert.NotNil(t, updatedTask)
-	assert.Equal(t, tm.StatusArchived, updatedTask.Status)
-	assert.NotNil(t, updatedTask.ArchivedAt)
-}
-
-func TestArchiveTask(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create a test task
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "Test description",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:    tm.StatusToDo,
-		Priority:  tm.PriorityMedium,
-		CreatedAt: time.Now().Add(-time.Hour),
-		UpdatedAt: time.Now().Add(-time.Hour),
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-	err = gtm.writeTaskFile(task)
-	require.NoError(t, err)
-
-	// Archive the task
-	ctx := context.Background()
-	err = gtm.ArchiveTask(ctx, task.ID)
-	assert.NoError(t, err)
-
-	// Verify task was archived
-	archivedTask, err := gtm.GetTask(task.ID)
-	assert.NoError(t, err)
-	assert.Equal(t, tm.StatusArchived, archivedTask.Status)
-	assert.NotNil(t, archivedTask.ArchivedAt)
-}
-
-func TestStartTask(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create a test task
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "Test description",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:    tm.StatusToDo,
-		Priority:  tm.PriorityMedium,
-		CreatedAt: time.Now().Add(-time.Hour),
-		UpdatedAt: time.Now().Add(-time.Hour),
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-	err = gtm.writeTaskFile(task)
-	require.NoError(t, err)
-
-	// Start the task
-	ctx := context.Background()
-	startedTask, err := gtm.StartTask(ctx, task.ID)
-	assert.NoError(t, err)
-	assert.NotNil(t, startedTask)
-	assert.Equal(t, tm.StatusInProgress, startedTask.Status)
-}
-
-func TestCompleteTask(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create a test task
-	task := &tm.Task{
-		ID:          "test-task-123",
-		Title:       "Test Task",
-		Description: "Test description",
-		Owner: tm.Owner{
-			ID:   "user123",
-			Name: "Test User",
-		},
-		Status:    tm.StatusInProgress,
-		Priority:  tm.PriorityMedium,
-		CreatedAt: time.Now().Add(-time.Hour),
-		UpdatedAt: time.Now().Add(-time.Hour),
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-	err = gtm.writeTaskFile(task)
-	require.NoError(t, err)
-
-	// Complete the task
-	ctx := context.Background()
-	completedTask, err := gtm.CompleteTask(ctx, task.ID)
-	assert.NoError(t, err)
-	assert.NotNil(t, completedTask)
-	assert.Equal(t, tm.StatusCompleted, completedTask.Status)
-	assert.NotNil(t, completedTask.CompletedAt)
-}
-
-func TestListTasks(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create test tasks
-	tasks := []*tm.Task{
-		{
-			ID:          "task-1",
-			Title:       "Task 1",
-			Description: "First task",
-			Owner:       tm.Owner{ID: "user1", Name: "User 1"},
-			Status:      tm.StatusToDo,
-			Priority:    tm.PriorityHigh,
-			CreatedAt:   time.Now().Add(-2 * time.Hour),
-			UpdatedAt:   time.Now().Add(-2 * time.Hour),
-		},
-		{
-			ID:          "task-2",
-			Title:       "Task 2",
-			Description: "Second task",
-			Owner:       tm.Owner{ID: "user2", Name: "User 2"},
-			Status:      tm.StatusInProgress,
-			Priority:    tm.PriorityMedium,
-			CreatedAt:   time.Now().Add(-1 * time.Hour),
-			UpdatedAt:   time.Now().Add(-1 * time.Hour),
-		},
-		{
-			ID:          "task-3",
-			Title:       "Task 3",
-			Description: "Third task",
-			Owner:       tm.Owner{ID: "user1", Name: "User 1"},
-			Status:      tm.StatusCompleted,
-			Priority:    tm.PriorityLow,
-			CreatedAt:   time.Now(),
-			UpdatedAt:   time.Now(),
-		},
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-
-	for _, task := range tasks {
-		err = gtm.writeTaskFile(task)
-		require.NoError(t, err)
-	}
-
-	ctx := context.Background()
-
-	// Test listing all tasks
-	taskList, err := gtm.ListTasks(ctx, nil, 0, 10)
-	assert.NoError(t, err)
-	assert.NotNil(t, taskList)
-	assert.Len(t, taskList.Tasks, 3)
-	assert.Equal(t, 3, taskList.TotalCount)
-	assert.Equal(t, 0, taskList.Page)
-	assert.Equal(t, 10, taskList.PageSize)
-	assert.False(t, taskList.HasMore)
-
-	// Test pagination
-	taskList, err = gtm.ListTasks(ctx, nil, 0, 2)
-	assert.NoError(t, err)
-	assert.Len(t, taskList.Tasks, 2)
-	assert.Equal(t, 3, taskList.TotalCount)
-	assert.True(t, taskList.HasMore)
-
-	// Test filtering by owner
-	ownerFilter := &tm.TaskFilter{OwnerID: stringPtr("user1")}
-	taskList, err = gtm.ListTasks(ctx, ownerFilter, 0, 10)
-	assert.NoError(t, err)
-	assert.Len(t, taskList.Tasks, 2)
-
-	// Test filtering by status
-	statusFilter := &tm.TaskFilter{Status: taskStatusPtr(tm.StatusToDo)}
-	taskList, err = gtm.ListTasks(ctx, statusFilter, 0, 10)
-	assert.NoError(t, err)
-	assert.Len(t, taskList.Tasks, 1)
-	assert.Equal(t, "task-1", taskList.Tasks[0].ID)
-
-	// Test filtering by priority
-	priorityFilter := &tm.TaskFilter{Priority: taskPriorityPtr(tm.PriorityHigh)}
-	taskList, err = gtm.ListTasks(ctx, priorityFilter, 0, 10)
-	assert.NoError(t, err)
-	assert.Len(t, taskList.Tasks, 1)
-	assert.Equal(t, "task-1", taskList.Tasks[0].ID)
-}
-
-func TestGetTasksByOwner(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create test tasks
-	tasks := []*tm.Task{
-		{
-			ID:        "task-1",
-			Title:     "Task 1",
-			Owner:     tm.Owner{ID: "user1", Name: "User 1"},
-			Status:    tm.StatusToDo,
-			Priority:  tm.PriorityHigh,
-			CreatedAt: time.Now().Add(-2 * time.Hour),
-			UpdatedAt: time.Now().Add(-2 * time.Hour),
-		},
-		{
-			ID:        "task-2",
-			Title:     "Task 2",
-			Owner:     tm.Owner{ID: "user2", Name: "User 2"},
-			Status:    tm.StatusInProgress,
-			Priority:  tm.PriorityMedium,
-			CreatedAt: time.Now().Add(-1 * time.Hour),
-			UpdatedAt: time.Now().Add(-1 * time.Hour),
-		},
-		{
-			ID:        "task-3",
-			Title:     "Task 3",
-			Owner:     tm.Owner{ID: "user1", Name: "User 1"},
-			Status:    tm.StatusCompleted,
-			Priority:  tm.PriorityLow,
-			CreatedAt: time.Now(),
-			UpdatedAt: time.Now(),
-		},
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-
-	for _, task := range tasks {
-		err = gtm.writeTaskFile(task)
-		require.NoError(t, err)
-	}
-
-	ctx := context.Background()
-
-	// Get tasks by owner
-	taskList, err := gtm.GetTasksByOwner(ctx, "user1", 0, 10)
-	assert.NoError(t, err)
-	assert.NotNil(t, taskList)
-	assert.Len(t, taskList.Tasks, 2)
-
-	for _, task := range taskList.Tasks {
-		assert.Equal(t, "user1", task.Owner.ID)
-	}
-}
-
-func TestGetTasksByStatus(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create test tasks
-	tasks := []*tm.Task{
-		{
-			ID:        "task-1",
-			Title:     "Task 1",
-			Owner:     tm.Owner{ID: "user1", Name: "User 1"},
-			Status:    tm.StatusToDo,
-			Priority:  tm.PriorityHigh,
-			CreatedAt: time.Now().Add(-2 * time.Hour),
-			UpdatedAt: time.Now().Add(-2 * time.Hour),
-		},
-		{
-			ID:        "task-2",
-			Title:     "Task 2",
-			Owner:     tm.Owner{ID: "user2", Name: "User 2"},
-			Status:    tm.StatusInProgress,
-			Priority:  tm.PriorityMedium,
-			CreatedAt: time.Now().Add(-1 * time.Hour),
-			UpdatedAt: time.Now().Add(-1 * time.Hour),
-		},
-		{
-			ID:        "task-3",
-			Title:     "Task 3",
-			Owner:     tm.Owner{ID: "user1", Name: "User 1"},
-			Status:    tm.StatusCompleted,
-			Priority:  tm.PriorityLow,
-			CreatedAt: time.Now(),
-			UpdatedAt: time.Now(),
-		},
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-
-	for _, task := range tasks {
-		err = gtm.writeTaskFile(task)
-		require.NoError(t, err)
-	}
-
-	ctx := context.Background()
-
-	// Get tasks by status
-	taskList, err := gtm.GetTasksByStatus(ctx, tm.StatusToDo, 0, 10)
-	assert.NoError(t, err)
-	assert.NotNil(t, taskList)
-	assert.Len(t, taskList.Tasks, 1)
-	assert.Equal(t, tm.StatusToDo, taskList.Tasks[0].Status)
-}
-
-func TestGetTasksByPriority(t *testing.T) {
-	tempDir, cleanup := setupTestDir(t)
-	defer cleanup()
-
-	gtm, _ := createTestTaskManager(t, tempDir)
-
-	// Create test tasks
-	tasks := []*tm.Task{
-		{
-			ID:        "task-1",
-			Title:     "Task 1",
-			Owner:     tm.Owner{ID: "user1", Name: "User 1"},
-			Status:    tm.StatusToDo,
-			Priority:  tm.PriorityHigh,
-			CreatedAt: time.Now().Add(-2 * time.Hour),
-			UpdatedAt: time.Now().Add(-2 * time.Hour),
-		},
-		{
-			ID:        "task-2",
-			Title:     "Task 2",
-			Owner:     tm.Owner{ID: "user2", Name: "User 2"},
-			Status:    tm.StatusInProgress,
-			Priority:  tm.PriorityMedium,
-			CreatedAt: time.Now().Add(-1 * time.Hour),
-			UpdatedAt: time.Now().Add(-1 * time.Hour),
-		},
-		{
-			ID:        "task-3",
-			Title:     "Task 3",
-			Owner:     tm.Owner{ID: "user1", Name: "User 1"},
-			Status:    tm.StatusCompleted,
-			Priority:  tm.PriorityLow,
-			CreatedAt: time.Now(),
-			UpdatedAt: time.Now(),
-		},
-	}
-
-	err := gtm.ensureTasksDir()
-	require.NoError(t, err)
-
-	for _, task := range tasks {
-		err = gtm.writeTaskFile(task)
-		require.NoError(t, err)
-	}
-
-	ctx := context.Background()
-
-	// Get tasks by priority
-	taskList, err := gtm.GetTasksByPriority(ctx, tm.PriorityHigh, 0, 10)
-	assert.NoError(t, err)
-	assert.NotNil(t, taskList)
-	assert.Len(t, taskList.Tasks, 1)
-	assert.Equal(t, tm.PriorityHigh, taskList.Tasks[0].Priority)
-}
-
-// Helper functions for creating pointers to string, TaskStatus, and TaskPriority
-func stringPtr(s string) *string {
-	return &s
-}
-
-func taskStatusPtr(status tm.TaskStatus) *tm.TaskStatus {
-	return &status
-}
-
-func taskPriorityPtr(priority tm.TaskPriority) *tm.TaskPriority {
-	return &priority
-}
diff --git a/server/tm/interface.go b/server/tm/interface.go
index c505c65..f50abb1 100644
--- a/server/tm/interface.go
+++ b/server/tm/interface.go
@@ -22,4 +22,8 @@
 	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)
+
+	// Proposals
+	ProposeSubTasks(ctx context.Context, task *Task, analysis *SubtaskAnalysis) (string, error)
+	ProposeSolution(ctx context.Context, task *Task, solution, agentName string) (string, error)
 }
diff --git a/server/tm/types.go b/server/tm/types.go
index a9991b4..9557b57 100644
--- a/server/tm/types.go
+++ b/server/tm/types.go
@@ -32,21 +32,18 @@
 
 // Task represents a single task in the system
 type Task struct {
-	ID             string       `json:"id"`
-	Title          string       `json:"title"`
-	Description    string       `json:"description"`
-	Owner          Owner        `json:"owner"`
-	Assignee       string       `json:"assignee,omitempty"` // For MVP auto-assignment
-	Status         TaskStatus   `json:"status"`
-	Priority       TaskPriority `json:"priority"`
-	Solution       string       `json:"solution,omitempty"`         // Generated solution
-	PullRequestURL string       `json:"pull_request_url,omitempty"` // GitHub PR URL
+	ID          string       `json:"id"`
+	Title       string       `json:"title"`
+	Description string       `json:"description"`
+	Owner       Owner        `json:"owner"`
+	Assignee    string       `json:"assignee,omitempty"` // For MVP auto-assignment
+	Status      TaskStatus   `json:"status"`
+	Priority    TaskPriority `json:"priority"`
+	SolutionURL string       `json:"solution_url,omitempty"` // Could be GitHub PR URL
 
 	// Subtask support
-	ParentTaskID      string `json:"parent_task_id,omitempty"`  // ID of parent task if this is a subtask
-	SubtasksPRURL     string `json:"subtasks_pr_url,omitempty"` // PR URL for proposed subtasks
-	SubtasksGenerated bool   `json:"subtasks_generated"`        // Whether subtasks have been generated
-	SubtasksEvaluated bool   `json:"subtasks_evaluated"`        // Whether task has been evaluated for subtasks
+	ParentTaskID      string `json:"parent_task_id,omitempty"` // ID of parent task if this is a subtask
+	SubtasksEvaluated bool   `json:"subtasks_evaluated"`       // Whether task has been evaluated for subtasks
 
 	CreatedAt   time.Time  `json:"created_at"`
 	UpdatedAt   time.Time  `json:"updated_at"`
diff --git a/server/workspace/agent-subtask-service b/server/workspace/agent-subtask-service
new file mode 160000
index 0000000..40c460a
--- /dev/null
+++ b/server/workspace/agent-subtask-service
@@ -0,0 +1 @@
+Subproject commit 40c460a0faca29d90591ec77a1a0263d2b6d31f0
