@@ -6,7 +6,6 @@ import (
"io"
"log/slog"
"os"
- "sync"
"time"
tea "github.com/charmbracelet/bubbletea/v2"
@@ -86,23 +85,7 @@ to assist developers in writing, debugging, and understanding code directly from
slog.Error(fmt.Sprintf("Failed to create app instance: %v", err))
return err
}
-
- // Set up shutdown handling that works for both normal exit and signal interruption
- var shutdownOnce sync.Once
- shutdown := func() {
- shutdownOnce.Do(func() {
- slog.Info("Shutting down application")
- app.Shutdown()
- })
- }
- defer shutdown()
-
- // Handle context cancellation (from signals) in a goroutine
- go func() {
- <-ctx.Done()
- slog.Info("Context cancelled, initiating shutdown")
- shutdown()
- }()
+ defer app.Shutdown()
// Initialize MCP tools early for both modes
initMCPTools(ctx, app, cfg)
@@ -125,6 +108,7 @@ to assist developers in writing, debugging, and understanding code directly from
tea.WithAltScreen(),
tea.WithKeyReleases(),
tea.WithUniformKeyLayout(),
+ tea.WithContext(ctx),
tea.WithMouseCellMotion(), // Use cell motion instead of all motion to reduce event flooding
tea.WithFilter(tui.MouseEventFilter), // Filter mouse events based on focus state
)
@@ -800,11 +800,14 @@ func (a *agent) CancelAll() {
a.Cancel(key.(string)) // key is sessionID
return true
})
- for {
- if a.IsBusy() {
+
+ timeout := time.After(5 * time.Second)
+ for a.IsBusy() {
+ select {
+ case <-timeout:
+ return
+ default:
time.Sleep(200 * time.Millisecond)
- } else {
- break
}
}
}