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
 }
