LSP client: spawn language servers, expose code intelligence tools

New lsp.rs: LspRegistry manages persistent LSP server connections.
Spawns child processes, speaks LSP protocol (Content-Length framed
JSON-RPC over stdio). Server indexes the project once; queries are
cheap.

Tools: lsp_definition, lsp_references, lsp_hover, lsp_symbols,
lsp_callers. Each takes file/line/character, queries the running
language server.

LspRegistry lives on Agent as Option<Arc>, shared across forks.
Still needs: config-driven server startup (like MCP).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-09 12:07:50 -04:00
parent 8b5614ba99
commit 6ec0e1c766
3 changed files with 437 additions and 0 deletions

View file

@ -109,6 +109,8 @@ pub struct Config {
pub agent_types: Vec<String>,
#[serde(default)]
pub mcp_servers: Vec<McpServerConfig>,
#[serde(default)]
pub lsp_servers: Vec<LspServerConfig>,
/// Surface agent timeout in seconds.
#[serde(default)]
pub surface_timeout_secs: Option<u32>,
@ -167,6 +169,7 @@ impl Default for Config {
surface_conversation_bytes: None,
surface_hooks: vec![],
mcp_servers: vec![],
lsp_servers: vec![],
}
}
}
@ -351,6 +354,8 @@ pub struct AppConfig {
pub default_model: String,
#[serde(default)]
pub mcp_servers: Vec<McpServerConfig>,
#[serde(default)]
pub lsp_servers: Vec<LspServerConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -361,6 +366,16 @@ pub struct McpServerConfig {
pub args: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LspServerConfig {
pub name: String,
pub command: String,
#[serde(default)]
pub args: Vec<String>,
#[serde(default)]
pub languages: Vec<String>, // e.g. ["rust"], ["c", "cpp"]. Empty = auto-detect
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct BackendConfig {
#[serde(default)]
@ -450,6 +465,7 @@ impl Default for AppConfig {
models: HashMap::new(),
default_model: String::new(),
mcp_servers: Vec::new(),
lsp_servers: Vec::new(),
}
}
}