loop/webui: remove end session feedback survey functionality

Remove end session feedback survey system that was previously implemented
to collect user satisfaction ratings and comments when ending sessions.

Problem Analysis:
The feedback survey system added complexity to the end session flow
and included several components:
- Modal dialog with thumbs up/down rating buttons
- Optional text feedback collection
- Backend storage and processing of feedback data
- Complex synchronization logic with skaband clients
- Extended State struct and API surface area

The feedback collection mechanism, while well-implemented, added
unnecessary friction to session termination and required maintenance
of additional state management infrastructure.

Implementation Changes:

1. Frontend Simplification (sketch-app-shell.ts):
   - Replace custom survey modal with simple window.confirm dialog
   - Remove showEndSessionSurvey() method and associated UI logic
   - Simplify end session request to basic reason-only payload
   - Remove complex button state management and form handling

2. Type Definition Cleanup (types.ts):
   - Remove EndFeedback interface definition
   - Remove end field from State interface
   - Simplify TypeScript type definitions

3. Backend Refactoring (agent.go):
   - Remove EndFeedback struct definition
   - Remove GetEndFeedback/SetEndFeedback methods from CodingAgent interface
   - Remove endFeedback field from Agent struct
   - Eliminate feedback-related state management

4. HTTP Server Cleanup (loophttp.go):
   - Remove End field from State struct
   - Simplify /end endpoint request body parsing
   - Remove feedback storage and processing logic
   - Eliminate endWaitGroup synchronization mechanism
   - Remove wait_for_end query parameter handling
   - Simplify session termination to immediate exit with basic delay

5. Test Cleanup (loophttp_test.go):
   - Remove TestEndFeedback test function
   - Remove endFeedback field from mockAgent
   - Remove GetEndFeedback/SetEndFeedback mock methods
   - Simplify test fixtures and expectations

Technical Details:
- Session termination now uses simple confirmation dialog workflow
- /end endpoint accepts only reason field in request body
- Process exit occurs after 100ms delay without client coordination
- All existing session management functionality preserved
- TypeScript compilation verified with simplified type definitions

Benefits:
- Simplified end session user experience with standard confirmation
- Reduced code complexity and maintenance burden
- Eliminated complex state synchronization requirements
- Cleaner API surface with fewer fields and methods
- Faster session termination without feedback collection overhead
- Standard web UI patterns for session ending confirmation

Testing:
- All existing tests pass without regression
- TypeScript compilation succeeds with updated type definitions
- End session functionality verified through manual testing
- Build verification confirms no compilation errors

This change restores the end session flow to a simple, straightforward
confirmation-based approach while maintaining all core session management
functionality and improving overall system simplicity.

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s9406002b5ac20a89k
diff --git a/loop/server/loophttp_test.go b/loop/server/loophttp_test.go
index a6dab62..8575253 100644
--- a/loop/server/loophttp_test.go
+++ b/loop/server/loophttp_test.go
@@ -30,7 +30,6 @@
 	branchName               string
 	workingDir               string
 	sessionID                string
-	endFeedback              *loop.EndFeedback
 }
 
 func (m *mockAgent) NewIterator(ctx context.Context, nextMessageIdx int) loop.MessageIterator {
@@ -248,69 +247,8 @@
 func (m *mockAgent) IsInContainer() bool                        { return false }
 func (m *mockAgent) FirstMessageIndex() int                     { return 0 }
 func (m *mockAgent) DetectGitChanges(ctx context.Context) error { return nil }
-func (m *mockAgent) GetEndFeedback() *loop.EndFeedback          { return m.endFeedback }
-func (m *mockAgent) SetEndFeedback(feedback *loop.EndFeedback)  { m.endFeedback = feedback }
-func (m *mockAgent) GetPortMonitor() *loop.PortMonitor          { return loop.NewPortMonitor() }
 
-// TestEndFeedback tests the end session feedback functionality
-func TestEndFeedback(t *testing.T) {
-	// Test basic EndFeedback struct functionality
-	feedback := &loop.EndFeedback{
-		Happy:   true,
-		Comment: "Great experience!",
-	}
-
-	if feedback.Happy != true {
-		t.Errorf("Expected Happy to be true, got %v", feedback.Happy)
-	}
-	if feedback.Comment != "Great experience!" {
-		t.Errorf("Expected Comment to be 'Great experience!', got %s", feedback.Comment)
-	}
-
-	// Test mock agent methods
-	mockAgent := &mockAgent{
-		sessionID:    "test-session",
-		workingDir:   "/test",
-		messageCount: 0,
-	}
-
-	// Test initial state (no feedback)
-	if mockAgent.GetEndFeedback() != nil {
-		t.Error("Expected initial feedback to be nil")
-	}
-
-	// Test setting feedback
-	mockAgent.SetEndFeedback(feedback)
-	retrieved := mockAgent.GetEndFeedback()
-	if retrieved == nil {
-		t.Error("Expected feedback to be set, got nil")
-	} else {
-		if retrieved.Happy != true {
-			t.Errorf("Expected Happy to be true, got %v", retrieved.Happy)
-		}
-		if retrieved.Comment != "Great experience!" {
-			t.Errorf("Expected Comment to be 'Great experience!', got %s", retrieved.Comment)
-		}
-	}
-
-	// Test setting different feedback
-	negativeFeedback := &loop.EndFeedback{
-		Happy:   false,
-		Comment: "Could be better",
-	}
-	mockAgent.SetEndFeedback(negativeFeedback)
-	retrieved = mockAgent.GetEndFeedback()
-	if retrieved == nil {
-		t.Error("Expected feedback to be set, got nil")
-	} else {
-		if retrieved.Happy != false {
-			t.Errorf("Expected Happy to be false, got %v", retrieved.Happy)
-		}
-		if retrieved.Comment != "Could be better" {
-			t.Errorf("Expected Comment to be 'Could be better', got %s", retrieved.Comment)
-		}
-	}
-}
+func (m *mockAgent) GetPortMonitor() *loop.PortMonitor { return loop.NewPortMonitor() }
 
 // TestSSEStream tests the SSE stream endpoint
 func TestSSEStream(t *testing.T) {