Update logging

Change-Id: I13279582aa717edad5d56323866b941db1919404
diff --git a/server/agent/agent.go b/server/agent/agent.go
index 6de4784..ed4706d 100644
--- a/server/agent/agent.go
+++ b/server/agent/agent.go
@@ -3,7 +3,7 @@
 import (
 	"context"
 	"fmt"
-	"log"
+	"log/slog"
 	"os"
 	"path/filepath"
 	"strings"
@@ -11,6 +11,7 @@
 
 	"github.com/iomodo/staff/git"
 	"github.com/iomodo/staff/llm"
+	_ "github.com/iomodo/staff/llm/openai" // Import for side effects (registers provider)
 	"github.com/iomodo/staff/tm"
 )
 
@@ -58,10 +59,11 @@
 	gitInterface git.GitInterface
 	ctx          context.Context
 	cancel       context.CancelFunc
+	logger       *slog.Logger
 }
 
 // NewAgent creates a new agent instance
-func NewAgent(config AgentConfig) (*Agent, error) {
+func NewAgent(config AgentConfig, logger *slog.Logger) (*Agent, error) {
 	// Validate configuration
 	if err := validateConfig(config); err != nil {
 		return nil, fmt.Errorf("invalid config: %w", err)
@@ -89,7 +91,7 @@
 			Timeout:             30 * time.Second,
 			PullRequestProvider: gerritPRProvider,
 		}
-		gitInterface = git.NewGitWithPullRequests(config.GitRepoPath, gitConfig, gerritPRProvider)
+		gitInterface = git.NewGitWithPullRequests(config.GitRepoPath, gitConfig, gerritPRProvider, logger)
 	} else {
 		// Use default git interface (GitHub)
 		gitInterface = git.DefaultGit(config.GitRepoPath)
@@ -104,6 +106,7 @@
 		gitInterface: gitInterface,
 		ctx:          ctx,
 		cancel:       cancel,
+		logger:       logger,
 	}
 
 	return agent, nil
@@ -134,8 +137,8 @@
 
 // Run starts the agent's main loop
 func (a *Agent) Run() error {
-	log.Printf("Starting agent %s (%s)", a.Config.Name, a.Config.Role)
-	defer log.Printf("Agent %s stopped", a.Config.Name)
+	a.logger.Info("Starting agent", slog.String("name", a.Config.Name), slog.String("role", a.Config.Role))
+	defer a.logger.Info("Agent stopped", slog.String("name", a.Config.Name))
 
 	// Initialize git repository if needed
 	if err := a.initializeGit(); err != nil {
@@ -149,7 +152,7 @@
 			return a.ctx.Err()
 		default:
 			if err := a.processNextTask(); err != nil {
-				log.Printf("Error processing task: %v", err)
+				a.logger.Error("Error processing task", slog.String("error", err.Error()))
 				// Continue running even if there's an error
 				time.Sleep(30 * time.Second)
 			}
@@ -159,7 +162,7 @@
 
 // Stop stops the agent
 func (a *Agent) Stop() {
-	log.Printf("Stopping agent %s", a.Config.Name)
+	a.logger.Info("Stopping agent", slog.String("name", a.Config.Name))
 	a.cancel()
 	if a.llmProvider != nil {
 		a.llmProvider.Close()
@@ -248,7 +251,7 @@
 				}
 			}
 		} else {
-			log.Printf("Already on target branch: %s", a.Config.GitBranch)
+			a.logger.Info("Already on target branch", slog.String("branch", a.Config.GitBranch))
 		}
 	}
 
@@ -280,7 +283,7 @@
 		return nil
 	}
 
-	log.Printf("Processing task: %s - %s", taskToProcess.ID, taskToProcess.Title)
+	a.logger.Info("Processing task", slog.String("id", taskToProcess.ID), slog.String("title", taskToProcess.Title))
 
 	// Start the task
 	startedTask, err := a.Config.TaskManager.StartTask(ctx, taskToProcess.ID)
@@ -292,7 +295,7 @@
 	solution, err := a.processTaskWithLLM(startedTask)
 	if err != nil {
 		// Mark task as failed or retry
-		log.Printf("Failed to process task with LLM: %v", err)
+		a.logger.Error("Failed to process task with LLM", slog.String("error", err.Error()))
 		return err
 	}
 
@@ -306,7 +309,7 @@
 		return fmt.Errorf("failed to complete task: %w", err)
 	}
 
-	log.Printf("Successfully completed task: %s", startedTask.ID)
+	a.logger.Info("Successfully completed task", slog.String("id", startedTask.ID))
 	return nil
 }
 
@@ -416,7 +419,7 @@
 		if err := a.gitInterface.Push(ctx, "origin", gerritRef, git.PushOptions{}); err != nil {
 			return fmt.Errorf("failed to push to Gerrit: %w", err)
 		}
-		log.Printf("Created Gerrit change for task %s by pushing to %s", task.ID, gerritRef)
+		a.logger.Info("Created Gerrit change for task", slog.String("id", task.ID), slog.String("ref", gerritRef))
 	} else {
 		// For GitHub: Push branch and create PR
 		if err := a.gitInterface.Push(ctx, "origin", branchName, git.PushOptions{SetUpstream: true}); err != nil {
@@ -438,7 +441,7 @@
 			return fmt.Errorf("failed to create pull request: %w", err)
 		}
 
-		log.Printf("Created pull request for task %s: %s (ID: %s)", task.ID, pr.Title, pr.ID)
+		a.logger.Info("Created pull request for task", slog.String("id", task.ID), slog.String("title", pr.Title), slog.String("pr_id", pr.ID))
 	}
 
 	return nil
diff --git a/server/agent/agent_test.go b/server/agent/agent_test.go
index 405e5b7..6ec2adc 100644
--- a/server/agent/agent_test.go
+++ b/server/agent/agent_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"context"
+	"log/slog"
 	"os"
 	"path/filepath"
 	"testing"
@@ -104,8 +105,11 @@
 	err = gitInterface.SetUserConfig(ctx, userConfig)
 	require.NoError(t, err)
 
+	// Create logger for testing
+	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
+
 	// Create task manager
-	taskManager := git_tm.NewGitTaskManager(gitInterface, tasksDir)
+	taskManager := git_tm.NewGitTaskManagerWithLogger(gitInterface, tasksDir, logger)
 
 	// Create LLM config (using a mock configuration)
 	llmConfig := llm.Config{
@@ -132,6 +136,9 @@
 		GitBranch:    "main",
 	}
 
+	// Create logger for testing
+	logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
+
 	// Create agent with mock LLM provider
 	agent := &Agent{
 		Config:       config,
@@ -139,6 +146,7 @@
 		gitInterface: git.DefaultGit(codeRepoDir),
 		ctx:          context.Background(),
 		cancel:       func() {},
+		logger:       logger,
 	}
 
 	cleanup := func() {
@@ -150,8 +158,73 @@
 }
 
 func TestNewAgent(t *testing.T) {
-	agent, cleanup := setupTestAgent(t)
-	defer cleanup()
+	// Create temporary directories
+	tempDir, err := os.MkdirTemp("", "agent-test")
+	require.NoError(t, err)
+	defer os.RemoveAll(tempDir)
+
+	tasksDir := filepath.Join(tempDir, "tasks")
+	workspaceDir := filepath.Join(tempDir, "workspace")
+	codeRepoDir := filepath.Join(tempDir, "code-repo")
+
+	// Create directories
+	require.NoError(t, os.MkdirAll(tasksDir, 0755))
+	require.NoError(t, os.MkdirAll(workspaceDir, 0755))
+	require.NoError(t, os.MkdirAll(codeRepoDir, 0755))
+
+	// Initialize git repositories
+	gitInterface := git.DefaultGit(tasksDir)
+	ctx := context.Background()
+
+	err = gitInterface.Init(ctx, tasksDir)
+	require.NoError(t, err)
+
+	// Set git user config
+	userConfig := git.UserConfig{
+		Name:  "Test User",
+		Email: "test@example.com",
+	}
+	err = gitInterface.SetUserConfig(ctx, userConfig)
+	require.NoError(t, err)
+
+	// Create logger for testing
+	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
+
+	// Create task manager
+	taskManager := git_tm.NewGitTaskManagerWithLogger(gitInterface, tasksDir, logger)
+
+	// Create LLM config (using a mock configuration)
+	llmConfig := llm.Config{
+		Provider: llm.ProviderOpenAI,
+		APIKey:   "test-key",
+		BaseURL:  "https://api.openai.com/v1",
+		Timeout:  30 * time.Second,
+	}
+
+	// Create agent config
+	config := AgentConfig{
+		Name:         "test-agent",
+		Role:         "Test Engineer",
+		GitUsername:  "test-agent",
+		GitEmail:     "test-agent@test.com",
+		WorkingDir:   workspaceDir,
+		LLMProvider:  llm.ProviderOpenAI,
+		LLMModel:     "gpt-3.5-turbo",
+		LLMConfig:    llmConfig,
+		SystemPrompt: "You are a test agent. Provide simple, clear solutions.",
+		TaskManager:  taskManager,
+		GitRepoPath:  codeRepoDir,
+		GitRemote:    "origin",
+		GitBranch:    "main",
+	}
+
+	// Create logger for testing
+	logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
+
+	// Create agent using NewAgent function
+	agent, err := NewAgent(config, logger)
+	require.NoError(t, err)
+	defer agent.Stop()
 
 	assert.NotNil(t, agent)
 	assert.Equal(t, "test-agent", agent.Config.Name)
diff --git a/server/agent/example.go b/server/agent/example.go
index 1233bdc..a7faea9 100644
--- a/server/agent/example.go
+++ b/server/agent/example.go
@@ -2,7 +2,8 @@
 
 import (
 	"context"
-	"log"
+	"log/slog"
+	"os"
 	"time"
 
 	"github.com/iomodo/staff/git"
@@ -13,11 +14,14 @@
 
 // ExampleAgent demonstrates how to create and run an agent
 func ExampleAgent() {
+	// Create logger
+	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
+
 	// Create git interface for task management
 	gitInterface := git.DefaultGit("./tasks-repo")
 
 	// Create task manager
-	taskManager := git_tm.NewGitTaskManager(gitInterface, "./tasks-repo")
+	taskManager := git_tm.NewGitTaskManagerWithLogger(gitInterface, "./tasks-repo", logger)
 
 	// Create LLM configuration
 	llmConfig := llm.Config{
@@ -57,9 +61,10 @@
 	}
 
 	// Create agent
-	agent, err := NewAgent(config)
+	agent, err := NewAgent(config, logger)
 	if err != nil {
-		log.Fatalf("Failed to create agent: %v", err)
+		logger.Error("Failed to create agent", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
 	// Create a sample task
@@ -71,15 +76,16 @@
 		Priority:    tm.PriorityHigh,
 	})
 	if err != nil {
-		log.Fatalf("Failed to create task: %v", err)
+		logger.Error("Failed to create task", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	log.Printf("Created task: %s", task.ID)
+	logger.Info("Created task", slog.String("id", task.ID))
 
 	// Run the agent (this will process tasks in an infinite loop)
 	go func() {
 		if err := agent.Run(); err != nil {
-			log.Printf("Agent stopped with error: %v", err)
+			logger.Error("Agent stopped with error", slog.String("error", err.Error()))
 		}
 	}()
 
@@ -92,9 +98,12 @@
 
 // ExampleMultipleAgents demonstrates how to create multiple agents with different roles
 func ExampleMultipleAgents() {
+	// Create logger
+	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
+
 	// Create shared git interface for task management
 	gitInterface := git.DefaultGit("./tasks-repo")
-	taskManager := git_tm.NewGitTaskManager(gitInterface, "./tasks-repo")
+	taskManager := git_tm.NewGitTaskManagerWithLogger(gitInterface, "./tasks-repo", logger)
 
 	// Create agents with different roles
 	agents := []AgentConfig{
@@ -177,16 +186,16 @@
 
 	// Create and start all agents
 	for _, config := range agents {
-		agent, err := NewAgent(config)
+		agent, err := NewAgent(config, logger)
 		if err != nil {
-			log.Printf("Failed to create agent %s: %v", config.Name, err)
+			logger.Error("Failed to create agent", slog.String("name", config.Name), slog.String("error", err.Error()))
 			continue
 		}
 
 		go func(agent *Agent, name string) {
-			log.Printf("Starting agent: %s", name)
+			logger.Info("Starting agent", slog.String("name", name))
 			if err := agent.Run(); err != nil {
-				log.Printf("Agent %s stopped with error: %v", name, err)
+				logger.Error("Agent stopped with error", slog.String("name", name), slog.String("error", err.Error()))
 			}
 		}(agent, config.Name)
 	}
diff --git a/server/git/example.go b/server/git/example.go
index c261604..1bea27c 100644
--- a/server/git/example.go
+++ b/server/git/example.go
@@ -2,39 +2,43 @@
 
 import (
 	"context"
-	"fmt"
-	"log"
+	"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 {
-		log.Fatalf("Failed to get status: %v", err)
+		logger.Error("Failed to get status", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Printf("Current branch: %s\n", status.Branch)
-	fmt.Printf("Repository is clean: %t\n", status.IsClean)
+	logger.Info("Repository status", slog.String("branch", status.Branch), slog.Bool("clean", status.IsClean))
 
 	// List branches
 	branches, err := git.ListBranches(ctx)
 	if err != nil {
-		log.Fatalf("Failed to list branches: %v", err)
+		logger.Error("Failed to list branches", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Println("Branches:")
+	logger.Info("Branches found", slog.Int("count", len(branches)))
 	for _, branch := range branches {
 		current := ""
 		if branch.IsCurrent {
 			current = " (current)"
 		}
-		fmt.Printf("  %s%s\n", branch.Name, current)
+		logger.Info("Branch", slog.String("name", branch.Name+current))
 	}
 
 	// Get recent commits
@@ -45,12 +49,13 @@
 
 	commits, err := git.Log(ctx, logOptions)
 	if err != nil {
-		log.Fatalf("Failed to get log: %v", err)
+		logger.Error("Failed to get log", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Println("Recent commits:")
+	logger.Info("Recent commits", slog.Int("count", len(commits)))
 	for _, commit := range commits {
-		fmt.Printf("  %s: %s\n", commit.Hash[:8], commit.Message)
+		logger.Info("Commit", slog.String("hash", commit.Hash[:8]), slog.String("message", commit.Message))
 	}
 }
 
@@ -58,12 +63,16 @@
 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 {
-		log.Fatalf("Failed to initialize repository: %v", err)
+		logger.Error("Failed to initialize repository", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
 	// Set user configuration
@@ -73,7 +82,8 @@
 	}
 
 	if err := git.SetUserConfig(ctx, userConfig); err != nil {
-		log.Fatalf("Failed to set user config: %v", err)
+		logger.Error("Failed to set user config", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
 	// Create a new file and add it
@@ -81,7 +91,8 @@
 
 	// Stage all changes
 	if err := git.AddAll(ctx); err != nil {
-		log.Fatalf("Failed to add files: %v", err)
+		logger.Error("Failed to add files", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
 	// Commit the changes
@@ -90,42 +101,50 @@
 	}
 
 	if err := git.Commit(ctx, "Initial commit", commitOptions); err != nil {
-		log.Fatalf("Failed to commit: %v", err)
+		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 {
-		log.Fatalf("Failed to create branch: %v", err)
+		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 {
-		log.Fatalf("Failed to checkout branch: %v", err)
+		logger.Error("Failed to checkout branch", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Println("Repository initialized and feature branch created!")
+	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 {
-		log.Fatalf("Failed to add remote: %v", err)
+		logger.Error("Failed to add remote", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
 	// List remotes
 	remotes, err := git.ListRemotes(ctx)
 	if err != nil {
-		log.Fatalf("Failed to list remotes: %v", err)
+		logger.Error("Failed to list remotes", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Println("Remotes:")
+	logger.Info("Remotes found", slog.Int("count", len(remotes)))
 	for _, remote := range remotes {
-		fmt.Printf("  %s: %s\n", remote.Name, remote.URL)
+		logger.Info("Remote", slog.String("name", remote.Name), slog.String("url", remote.URL))
 	}
 
 	// Fetch from remote
@@ -135,7 +154,8 @@
 	}
 
 	if err := git.Fetch(ctx, "", fetchOptions); err != nil {
-		log.Fatalf("Failed to fetch: %v", err)
+		logger.Error("Failed to fetch", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
 	// Push to remote
@@ -144,6 +164,7 @@
 	}
 
 	if err := git.Push(ctx, "origin", "main", pushOptions); err != nil {
-		log.Fatalf("Failed to push: %v", err)
+		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 dc3885f..9aa1ae2 100644
--- a/server/git/git.go
+++ b/server/git/git.go
@@ -3,6 +3,7 @@
 import (
 	"context"
 	"fmt"
+	"log/slog"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -189,6 +190,7 @@
 	repoPath   string
 	config     GitConfig
 	prProvider PullRequestProvider
+	logger     *slog.Logger
 }
 
 // GitConfig holds configuration for Git operations
@@ -199,7 +201,7 @@
 }
 
 // NewGit creates a new Git instance
-func NewGit(repoPath string, config GitConfig) GitInterface {
+func NewGit(repoPath string, config GitConfig, logger *slog.Logger) GitInterface {
 	if config.Timeout == 0 {
 		config.Timeout = 30 * time.Second
 	}
@@ -208,6 +210,7 @@
 		repoPath:   repoPath,
 		config:     config,
 		prProvider: config.PullRequestProvider,
+		logger:     logger,
 	}
 }
 
@@ -215,14 +218,13 @@
 func DefaultGit(repoPath string) GitInterface {
 	return NewGit(repoPath, GitConfig{
 		Timeout: 30 * time.Second,
-		Env:     make(map[string]string),
-	})
+	}, slog.Default())
 }
 
 // NewGitWithPullRequests creates a Git instance with pull request capabilities
-func NewGitWithPullRequests(repoPath string, config GitConfig, prProvider PullRequestProvider) GitInterface {
+func NewGitWithPullRequests(repoPath string, config GitConfig, prProvider PullRequestProvider, logger *slog.Logger) GitInterface {
 	config.PullRequestProvider = prProvider
-	return NewGit(repoPath, config)
+	return NewGit(repoPath, config, logger)
 }
 
 // Ensure Git implements GitInterface
diff --git a/server/git/git_test.go b/server/git/git_test.go
index bccf477..d3862ce 100644
--- a/server/git/git_test.go
+++ b/server/git/git_test.go
@@ -3,6 +3,7 @@
 import (
 	"context"
 	"fmt"
+	"log/slog"
 	"os"
 	"path/filepath"
 	"testing"
@@ -10,6 +11,9 @@
 )
 
 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 {
@@ -23,7 +27,7 @@
 			"GIT_AUTHOR_NAME": "Test User",
 		},
 	}
-	git = NewGit("/tmp/test-repo", config)
+	git = NewGit("/tmp/test-repo", config, logger)
 	if git == nil {
 		t.Fatal("NewGit returned nil")
 	}
diff --git a/server/git/pull_request_example.go b/server/git/pull_request_example.go
index 5e34dc4..5c70d21 100644
--- a/server/git/pull_request_example.go
+++ b/server/git/pull_request_example.go
@@ -2,25 +2,28 @@
 
 import (
 	"context"
-	"fmt"
-	"log"
+	"log/slog"
 	"net/http"
+	"os"
 	"time"
 )
 
-// ExamplePullRequestUsage demonstrates how to use the pull request capabilities
+// ExamplePullRequestUsage demonstrates how to use pull request functionality
 func ExamplePullRequestUsage() {
 	ctx := context.Background()
 
-	// Example 1: GitHub Pull Requests
-	exampleGitHubPullRequests(ctx)
+	// Create logger
+	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
 
-	// Example 2: Gerrit Pull Requests
-	exampleGerritPullRequests(ctx)
+	// Example with GitHub
+	exampleGitHubPullRequests(ctx, logger)
+
+	// Example with Gerrit
+	exampleGerritPullRequests(ctx, logger)
 }
 
-func exampleGitHubPullRequests(ctx context.Context) {
-	fmt.Println("=== GitHub Pull Request Example ===")
+func exampleGitHubPullRequests(ctx context.Context, logger *slog.Logger) {
+	logger.Info("=== GitHub Pull Request Example ===")
 
 	// Create GitHub configuration
 	githubConfig := GitHubConfig{
@@ -35,7 +38,7 @@
 	// Create Git instance with GitHub pull request capabilities
 	git := NewGitWithPullRequests("/path/to/repo", GitConfig{
 		Timeout: 30 * time.Second,
-	}, githubProvider)
+	}, githubProvider, logger)
 
 	// Create a new pull request
 	prOptions := PullRequestOptions{
@@ -51,11 +54,11 @@
 
 	pr, err := git.CreatePullRequest(ctx, prOptions)
 	if err != nil {
-		log.Printf("Failed to create pull request: %v", err)
+		logger.Error("Failed to create pull request", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Created pull request: %s (#%d)\n", pr.Title, pr.Number)
+	logger.Info("Created pull request", slog.String("title", pr.Title), slog.Int("number", pr.Number))
 
 	// List pull requests
 	listOptions := ListPullRequestOptions{
@@ -67,20 +70,20 @@
 
 	prs, err := git.ListPullRequests(ctx, listOptions)
 	if err != nil {
-		log.Printf("Failed to list pull requests: %v", err)
+		logger.Error("Failed to list pull requests", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Found %d pull requests\n", len(prs))
+	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 {
-		log.Printf("Failed to get pull request: %v", err)
+		logger.Error("Failed to get pull request", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Pull request status: %s\n", pr.State)
+	logger.Info("Pull request status", slog.String("state", pr.State))
 
 	// Update a pull request
 	updateOptions := PullRequestOptions{
@@ -91,11 +94,11 @@
 
 	updatedPR, err := git.UpdatePullRequest(ctx, pr.ID, updateOptions)
 	if err != nil {
-		log.Printf("Failed to update pull request: %v", err)
+		logger.Error("Failed to update pull request", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Updated pull request: %s\n", updatedPR.Title)
+	logger.Info("Updated pull request", slog.String("title", updatedPR.Title))
 
 	// Merge a pull request
 	mergeOptions := MergePullRequestOptions{
@@ -106,15 +109,15 @@
 
 	err = git.MergePullRequest(ctx, pr.ID, mergeOptions)
 	if err != nil {
-		log.Printf("Failed to merge pull request: %v", err)
+		logger.Error("Failed to merge pull request", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Println("Pull request merged successfully")
+	logger.Info("Pull request merged successfully")
 }
 
-func exampleGerritPullRequests(ctx context.Context) {
-	fmt.Println("=== Gerrit Pull Request Example ===")
+func exampleGerritPullRequests(ctx context.Context, logger *slog.Logger) {
+	logger.Info("=== Gerrit Pull Request Example ===")
 
 	// Create Gerrit configuration
 	gerritConfig := GerritConfig{
@@ -130,7 +133,7 @@
 	// Create Git instance with Gerrit pull request capabilities
 	git := NewGitWithPullRequests("/path/to/repo", GitConfig{
 		Timeout: 30 * time.Second,
-	}, gerritProvider)
+	}, gerritProvider, logger)
 
 	// Create a new change (pull request)
 	prOptions := PullRequestOptions{
@@ -142,11 +145,11 @@
 
 	pr, err := git.CreatePullRequest(ctx, prOptions)
 	if err != nil {
-		log.Printf("Failed to create change: %v", err)
+		logger.Error("Failed to create change", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Created change: %s (#%d)\n", pr.Title, pr.Number)
+	logger.Info("Created change", slog.String("title", pr.Title), slog.Int("number", pr.Number))
 
 	// List changes
 	listOptions := ListPullRequestOptions{
@@ -158,20 +161,20 @@
 
 	prs, err := git.ListPullRequests(ctx, listOptions)
 	if err != nil {
-		log.Printf("Failed to list changes: %v", err)
+		logger.Error("Failed to list changes", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Found %d changes\n", len(prs))
+	logger.Info("Found changes", slog.Int("count", len(prs)))
 
 	// Get a specific change
 	pr, err = git.GetPullRequest(ctx, pr.ID)
 	if err != nil {
-		log.Printf("Failed to get change: %v", err)
+		logger.Error("Failed to get change", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Change status: %s\n", pr.State)
+	logger.Info("Change status", slog.String("state", pr.State))
 
 	// Update a change
 	updateOptions := PullRequestOptions{
@@ -181,11 +184,11 @@
 
 	updatedPR, err := git.UpdatePullRequest(ctx, pr.ID, updateOptions)
 	if err != nil {
-		log.Printf("Failed to update change: %v", err)
+		logger.Error("Failed to update change", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Updated change: %s\n", updatedPR.Title)
+	logger.Info("Updated change", slog.String("title", updatedPR.Title))
 
 	// Submit a change (merge)
 	mergeOptions := MergePullRequestOptions{
@@ -195,11 +198,11 @@
 
 	err = git.MergePullRequest(ctx, pr.ID, mergeOptions)
 	if err != nil {
-		log.Printf("Failed to submit change: %v", err)
+		logger.Error("Failed to submit change", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Println("Change submitted successfully")
+	logger.Info("Change submitted successfully")
 }
 
 // Example of using both providers in the same application
@@ -218,7 +221,7 @@
 			BaseURL: "https://api.github.com",
 		}
 		githubProvider := NewGitHubPullRequestProvider("owner", "repo", githubConfig)
-		git = NewGitWithPullRequests("/path/to/repo", GitConfig{}, githubProvider)
+		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{
@@ -227,7 +230,7 @@
 			BaseURL:  "https://gerrit.example.com",
 		}
 		gerritProvider := NewGerritPullRequestProvider("project", gerritConfig)
-		git = NewGitWithPullRequests("/path/to/repo", GitConfig{}, gerritProvider)
+		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
@@ -240,9 +243,9 @@
 
 	pr, err := git.CreatePullRequest(ctx, prOptions)
 	if err != nil {
-		log.Printf("Failed to create pull request: %v", err)
+		slog.Error("Failed to create pull request", slog.String("error", err.Error()))
 		return
 	}
 
-	fmt.Printf("Created pull request: %s\n", pr.Title)
+	slog.Info("Created pull request", slog.String("title", pr.Title))
 }
diff --git a/server/server/server.go b/server/server/server.go
index fc0d230..4dbb8b1 100644
--- a/server/server/server.go
+++ b/server/server/server.go
@@ -100,9 +100,12 @@
 	}
 
 	// Create shared task manager
-	gitRepo := git.DefaultGit(workingDir)
+	gitConfig := git.GitConfig{
+		Timeout: 30 * time.Second,
+	}
+	gitRepo := git.NewGit(workingDir, gitConfig, a.logger)
 	tasksDir := filepath.Join(workingDir, "operations", "tasks")
-	taskManager := git_tm.NewGitTaskManager(gitRepo, tasksDir)
+	taskManager := git_tm.NewGitTaskManagerWithLogger(gitRepo, tasksDir, a.logger)
 
 	// Load and start agents
 	agentsDir := filepath.Join(workingDir, "operations", "agents")
@@ -150,7 +153,7 @@
 			GerritConfig:  gerritConfig,
 		}
 
-		ag, err := agent.NewAgent(config)
+		ag, err := agent.NewAgent(config, a.logger)
 		if err != nil {
 			a.logger.Error("Failed to create agent", slog.String("agent", agentName), slog.String("error", err.Error()))
 			continue
@@ -210,8 +213,11 @@
 func (a *Server) initializeNewRepository(workingDir, remoteRepoURL string) error {
 	ctx := context.Background()
 
-	// Initialize git repository
-	gitRepo := git.DefaultGit(workingDir)
+	// Initialize git repository with logger
+	gitConfig := git.GitConfig{
+		Timeout: 30 * time.Second,
+	}
+	gitRepo := git.NewGit(workingDir, gitConfig, a.logger)
 
 	a.logger.Info("Initializing git repository", slog.String("path", workingDir))
 	if err := gitRepo.Init(ctx, workingDir); err != nil {
@@ -282,7 +288,10 @@
 	ctx := context.Background()
 
 	// Check if it's a git repository
-	gitRepo := git.DefaultGit(workingDir)
+	gitConfig := git.GitConfig{
+		Timeout: 30 * time.Second,
+	}
+	gitRepo := git.NewGit(workingDir, gitConfig, a.logger)
 	isRepo, err := gitRepo.IsRepository(ctx, workingDir)
 	if err != nil {
 		return fmt.Errorf("failed to check if directory is git repository: %w", err)
diff --git a/server/tm/git_tm/example.go b/server/tm/git_tm/example.go
index 39541fa..3c2816d 100644
--- a/server/tm/git_tm/example.go
+++ b/server/tm/git_tm/example.go
@@ -3,7 +3,8 @@
 import (
 	"context"
 	"fmt"
-	"log"
+	"log/slog"
+	"os"
 	"time"
 
 	"github.com/iomodo/staff/git"
@@ -12,11 +13,14 @@
 
 // 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 := NewGitTaskManager(gitInterface, "./tasks-repo")
+	taskManager := NewGitTaskManagerWithLogger(gitInterface, "./tasks-repo", logger)
 
 	// Create a new task
 	ctx := context.Background()
@@ -32,46 +36,50 @@
 
 	task, err := taskManager.CreateTask(ctx, createReq)
 	if err != nil {
-		log.Fatalf("Failed to create task: %v", err)
+		logger.Error("Failed to create task", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Printf("Created task: %s\n", task.ID)
+	logger.Info("Created task", slog.String("id", task.ID))
 
 	// Get the task
 	retrievedTask, err := taskManager.GetTask(ctx, task.ID)
 	if err != nil {
-		log.Fatalf("Failed to get task: %v", err)
+		logger.Error("Failed to get task", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Printf("Retrieved task: %s - %s\n", retrievedTask.ID, retrievedTask.Title)
+	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 {
-		log.Fatalf("Failed to start task: %v", err)
+		logger.Error("Failed to start task", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Printf("Started task: %s (status: %s)\n", startedTask.ID, startedTask.Status)
+	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 {
-		log.Fatalf("Failed to list tasks: %v", err)
+		logger.Error("Failed to list tasks", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Printf("Total tasks: %d\n", taskList.TotalCount)
+	logger.Info("Total tasks", slog.Int("count", taskList.TotalCount))
 	for _, t := range taskList.Tasks {
-		fmt.Printf("- %s: %s (%s)\n", t.ID, t.Title, t.Status)
+		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 {
-		log.Fatalf("Failed to complete task: %v", err)
+		logger.Error("Failed to complete task", slog.String("error", err.Error()))
+		os.Exit(1)
 	}
 
-	fmt.Printf("Completed task: %s (completed at: %s)\n",
-		completedTask.ID, completedTask.CompletedAt.Format(time.RFC3339))
+	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
diff --git a/server/tm/git_tm/git_task_manager.go b/server/tm/git_tm/git_task_manager.go
index 02d5197..6a8735e 100644
--- a/server/tm/git_tm/git_task_manager.go
+++ b/server/tm/git_tm/git_task_manager.go
@@ -3,6 +3,7 @@
 import (
 	"context"
 	"fmt"
+	"log/slog"
 	"os"
 	"path/filepath"
 	"sort"
@@ -20,14 +21,29 @@
 	git      git.GitInterface
 	repoPath string
 	tasksDir string
+	logger   *slog.Logger
 }
 
 // NewGitTaskManager creates a new GitTaskManager instance
-func NewGitTaskManager(git git.GitInterface, repoPath string) *GitTaskManager {
+func NewGitTaskManager(git git.GitInterface, repoPath string, logger *slog.Logger) *GitTaskManager {
 	return &GitTaskManager{
 		git:      git,
 		repoPath: repoPath,
 		tasksDir: filepath.Join(repoPath, "tasks"),
+		logger:   logger,
+	}
+}
+
+// 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,
 	}
 }
 
diff --git a/server/tm/git_tm/git_task_manager_test.go b/server/tm/git_tm/git_task_manager_test.go
index cd37838..f7da286 100644
--- a/server/tm/git_tm/git_task_manager_test.go
+++ b/server/tm/git_tm/git_task_manager_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"context"
+	"log/slog"
 	"os"
 	"path/filepath"
 	"testing"
@@ -41,7 +42,10 @@
 	err = gitImpl.SetUserConfig(ctx, userConfig)
 	require.NoError(t, err)
 
-	gtm := NewGitTaskManager(gitImpl, repoPath)
+	// Create logger for testing
+	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
+
+	gtm := NewGitTaskManagerWithLogger(gitImpl, repoPath, logger)
 	return gtm, gitImpl
 }
 
@@ -51,7 +55,11 @@
 	defer cleanup()
 
 	gitImpl := git.DefaultGit(tempDir)
-	gtm := NewGitTaskManager(gitImpl, 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)