feat: enhance UI with commit pulsing animation and improved copy icon

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s80fdaac660ea645ek
diff --git a/loop/agent.go b/loop/agent.go
index cb22b84..909700e 100644
--- a/loop/agent.go
+++ b/loop/agent.go
@@ -105,7 +105,7 @@
 	SessionID() string
 
 	// DetectGitChanges checks for new git commits and pushes them if found
-	DetectGitChanges(ctx context.Context)
+	DetectGitChanges(ctx context.Context) error
 
 	// OutstandingLLMCallCount returns the number of outstanding LLM calls.
 	OutstandingLLMCallCount() int
@@ -1421,13 +1421,14 @@
 }
 
 // DetectGitChanges checks for new git commits and pushes them if found
-func (a *Agent) DetectGitChanges(ctx context.Context) {
+func (a *Agent) DetectGitChanges(ctx context.Context) error {
 	// Check for git commits
 	_, err := a.handleGitCommits(ctx)
 	if err != nil {
-		// Just log the error, don't stop execution
 		slog.WarnContext(ctx, "Failed to check for new git commits", "error", err)
+		return fmt.Errorf("failed to check for new git commits: %w", err)
 	}
+	return nil
 }
 
 // processGitChanges checks for new git commits, runs autoformatters if needed, and returns any messages generated
diff --git a/loop/server/loophttp.go b/loop/server/loophttp.go
index 94cbb78..ede1644 100644
--- a/loop/server/loophttp.go
+++ b/loop/server/loophttp.go
@@ -1381,7 +1381,10 @@
 	}
 
 	// Detect git changes to push and notify user
-	s.agent.DetectGitChanges(r.Context())
+	if err = s.agent.DetectGitChanges(r.Context()); err != nil {
+		http.Error(w, fmt.Sprintf("Error detecting git changes: %v", err), http.StatusInternalServerError)
+		return
+	}
 
 	// Return simple success response
 	w.WriteHeader(http.StatusOK)
diff --git a/loop/server/loophttp_test.go b/loop/server/loophttp_test.go
index e3d144b..949a95a 100644
--- a/loop/server/loophttp_test.go
+++ b/loop/server/loophttp_test.go
@@ -242,7 +242,7 @@
 func (m *mockAgent) SuggestReprompt(ctx context.Context) (string, error) { return "", nil }
 func (m *mockAgent) IsInContainer() bool                                 { return false }
 func (m *mockAgent) FirstMessageIndex() int                              { return 0 }
-func (m *mockAgent) DetectGitChanges(ctx context.Context)                {} // TestSSEStream tests the SSE stream endpoint
+func (m *mockAgent) DetectGitChanges(ctx context.Context) error          { return nil } // TestSSEStream tests the SSE stream endpoint
 func TestSSEStream(t *testing.T) {
 	// Create a mock agent with initial messages
 	mockAgent := &mockAgent{