From 4a03cbaf3cf5e96cb5f6ac849817de025558e642 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Mon, 2 Feb 2026 11:30:51 -0300 Subject: [PATCH] fix(lsp): improve lsp tools (#2089) With auto discovery, the user configured lsps might be empty, but we might still configure some LSPs. We need to check the proper places, as well as refresh the tool list if LSPs are actually started. This is an alternative implementation to #2079 Signed-off-by: Carlos Alexandro Becker --- internal/agent/coordinator.go | 2 +- internal/agent/tools/mcp/init.go | 1 + internal/app/app.go | 5 +---- internal/app/lsp.go | 20 +++++++++++++++----- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/internal/agent/coordinator.go b/internal/agent/coordinator.go index 780327089b3390d088e858fe26c5eec205aedf1e..09313f363d5d692971801354e0f5d609a20015ca 100644 --- a/internal/agent/coordinator.go +++ b/internal/agent/coordinator.go @@ -435,7 +435,7 @@ func (c *coordinator) buildTools(ctx context.Context, agent config.Agent) ([]fan tools.NewWriteTool(c.lspClients, c.permissions, c.history, c.filetracker, c.cfg.WorkingDir()), ) - if len(c.cfg.LSP) > 0 { + if c.lspClients.Len() > 0 { allTools = append(allTools, tools.NewDiagnosticsTool(c.lspClients), tools.NewReferencesTool(c.lspClients), tools.NewLSPRestartTool(c.lspClients)) } diff --git a/internal/agent/tools/mcp/init.go b/internal/agent/tools/mcp/init.go index 05ac2eaeba29c2ce4411c8acc355d645037a6f55..c37f238e6d915d265153518b6df27f07bb6e456e 100644 --- a/internal/agent/tools/mcp/init.go +++ b/internal/agent/tools/mcp/init.go @@ -135,6 +135,7 @@ func Close() error { // Initialize initializes MCP clients based on the provided configuration. func Initialize(ctx context.Context, permissions permission.Service, cfg *config.Config) { + slog.Info("Initializing MCP clients") var wg sync.WaitGroup // Initialize states for all configured MCPs for name, m := range cfg.MCP { diff --git a/internal/app/app.go b/internal/app/app.go index c5294c2ae21f91486861a037b639cb1c00bd531f..219b66f3cb79abcb6f004d08a6dc07bd539198ec 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -109,10 +109,7 @@ func New(ctx context.Context, conn *sql.DB, cfg *config.Config) (*App, error) { // Check for updates in the background. go app.checkForUpdates(ctx) - go func() { - slog.Info("Initializing MCP clients") - mcp.Initialize(ctx, app.Permissions, cfg) - }() + go mcp.Initialize(ctx, app.Permissions, cfg) // cleanup database upon app shutdown app.cleanupFuncs = append(app.cleanupFuncs, conn.Close, mcp.Close) diff --git a/internal/app/lsp.go b/internal/app/lsp.go index 14f1c99587bf4bfe052f9ac2078cdf03d859cfa1..21709bc44128bdda7e93230ab7885d3a96e9f21e 100644 --- a/internal/app/lsp.go +++ b/internal/app/lsp.go @@ -5,6 +5,7 @@ import ( "log/slog" "os/exec" "slices" + "sync" "time" "github.com/charmbracelet/crush/internal/config" @@ -58,16 +59,25 @@ func (app *App) initLSPClients(ctx context.Context) { updateLSPState(name, lsp.StateDisabled, nil, nil, 0) } } + + var wg sync.WaitGroup for name, server := range filtered { if app.config.Options.AutoLSP != nil && !*app.config.Options.AutoLSP && !slices.Contains(userConfiguredLSPs, name) { slog.Debug("Ignoring non user-define LSP client due to AutoLSP being disabled", "name", name) continue } - go app.createAndStartLSPClient( - ctx, name, - toOurConfig(server), - slices.Contains(userConfiguredLSPs, name), - ) + wg.Go(func() { + app.createAndStartLSPClient( + ctx, name, + toOurConfig(server), + slices.Contains(userConfiguredLSPs, name), + ) + }) + } + wg.Wait() + + if err := app.AgentCoordinator.UpdateModels(ctx); err != nil { + slog.Error("Failed to refresh tools after LSP startup", "error", err) } }