From 04210801f02d2ee5db7ae89a7ec28e34d5d14d5b Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 9 Oct 2025 23:16:55 +0200 Subject: [PATCH 1/2] fix(lsp): small UI improvements (#1211) Signed-off-by: Carlos Alexandro Becker --- internal/tui/components/lsp/lsp.go | 51 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/internal/tui/components/lsp/lsp.go b/internal/tui/components/lsp/lsp.go index f5f4061045901c91ecb8bce1f47eab3ac1f7abcf..0c0384e91c36744b8f318f9bbc71e5e076a26abf 100644 --- a/internal/tui/components/lsp/lsp.go +++ b/internal/tui/components/lsp/lsp.go @@ -56,32 +56,7 @@ func RenderLSPList(lspClients *csync.Map[string, *lsp.Client], opts RenderOption break } - // Determine icon color and description based on state - icon := t.ItemOfflineIcon - description := l.LSP.Command - - if l.LSP.Disabled { - description = t.S().Subtle.Render("disabled") - } else if state, exists := lspStates[l.Name]; exists { - switch state.State { - case lsp.StateStarting: - icon = t.ItemBusyIcon - description = t.S().Subtle.Render("starting...") - case lsp.StateReady: - icon = t.ItemOnlineIcon - description = l.LSP.Command - case lsp.StateError: - icon = t.ItemErrorIcon - if state.Error != nil { - description = t.S().Subtle.Render(fmt.Sprintf("error: %s", state.Error.Error())) - } else { - description = t.S().Subtle.Render("error") - } - case lsp.StateDisabled: - icon = t.ItemOfflineIcon.Foreground(t.FgMuted) - description = t.S().Base.Foreground(t.FgMuted).Render("no root markers found") - } - } + icon, description := iconAndDescription(l, t, lspStates) // Calculate diagnostic counts if we have LSP clients var extraContent string @@ -134,6 +109,30 @@ func RenderLSPList(lspClients *csync.Map[string, *lsp.Client], opts RenderOption return lspList } +func iconAndDescription(l config.LSP, t *styles.Theme, states map[string]app.LSPClientInfo) (lipgloss.Style, string) { + if l.LSP.Disabled { + return t.ItemOfflineIcon.Foreground(t.FgMuted), t.S().Subtle.Render("disabled") + } + + info := states[l.Name] + switch info.State { + case lsp.StateStarting: + return t.ItemBusyIcon, t.S().Subtle.Render("starting...") + case lsp.StateReady: + return t.ItemOnlineIcon, "" + case lsp.StateError: + description := t.S().Subtle.Render("error") + if info.Error != nil { + description = t.S().Subtle.Render(fmt.Sprintf("error: %s", info.Error.Error())) + } + return t.ItemErrorIcon, description + case lsp.StateDisabled: + return t.ItemOfflineIcon.Foreground(t.FgMuted), t.S().Subtle.Render("inactive") + default: + return t.ItemOfflineIcon, "" + } +} + // RenderLSPBlock renders a complete LSP block with optional truncation indicator. func RenderLSPBlock(lspClients *csync.Map[string, *lsp.Client], opts RenderOptions, showTruncationIndicator bool) string { t := styles.CurrentTheme() From fd2d966b0e468aaf2f0a582aee602c5ddf2874b6 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 9 Oct 2025 22:07:11 -0300 Subject: [PATCH 2/2] fix(mcp): improve error handling Signed-off-by: Carlos Alexandro Becker --- internal/llm/agent/mcp-tools.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/llm/agent/mcp-tools.go b/internal/llm/agent/mcp-tools.go index 7ef24148c93c7c9d08156e25f59b55e1327c3534..67f0b39ccfb6eb8aad3abd337e7545a59766d872 100644 --- a/internal/llm/agent/mcp-tools.go +++ b/internal/llm/agent/mcp-tools.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "log/slog" "maps" "net/http" @@ -254,7 +255,10 @@ func updateMCPState(name string, state MCPState, err error, client *mcp.ClientSe func CloseMCPClients() error { var errs []error for name, c := range mcpClients.Seq2() { - if err := c.Close(); err != nil { + if err := c.Close(); err != nil && + !errors.Is(err, io.EOF) && + !errors.Is(err, context.Canceled) && + err.Error() != "signal: killed" { errs = append(errs, fmt.Errorf("close mcp: %s: %w", name, err)) } } @@ -367,7 +371,6 @@ func createMCPSession(ctx context.Context, name string, m config.MCPConfig, reso if err != nil { updateMCPState(name, MCPStateError, maybeTimeoutErr(err, timeout), nil, 0) slog.Error("error starting mcp client", "error", err, "name", name) - _ = session.Close() cancel() return nil, err }