ai-agent 0.88.0

Idiomatic agent sdk inspired by the claude code source leak
Documentation
//! LSP Client - Language Server Protocol client
//!
//! This is a stub implementation.

use serde::{Deserialize, Serialize};

/// LSP server capabilities
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ServerCapabilities {
    #[serde(rename = "textDocumentSync")]
    pub text_document_sync: Option<serde_json::Value>,
    #[serde(rename = "hoverProvider")]
    pub hover_provider: Option<bool>,
    #[serde(rename = "completionProvider")]
    pub completion_provider: Option<serde_json::Value>,
    #[serde(rename = "definitionProvider")]
    pub definition_provider: Option<bool>,
    #[serde(rename = "referencesProvider")]
    pub references_provider: Option<bool>,
    #[serde(rename = "documentFormattingProvider")]
    pub document_formatting_provider: Option<bool>,
    #[serde(rename = "documentRangeFormattingProvider")]
    pub document_range_formatting_provider: Option<bool>,
    #[serde(rename = "codeActionProvider")]
    pub code_action_provider: Option<bool>,
}

/// Initialize params for LSP server
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct InitializeParams {
    #[serde(rename = "processId")]
    pub process_id: Option<i64>,
    #[serde(rename = "rootUri")]
    pub root_uri: Option<String>,
    #[serde(rename = "rootPath")]
    pub root_path: Option<String>,
    #[serde(rename = "workspaceFolders")]
    pub workspace_folders: Option<Vec<serde_json::Value>>,
    #[serde(rename = "initializationOptions")]
    pub initialization_options: Option<serde_json::Value>,
}

/// Initialize result from LSP server
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct InitializeResult {
    pub capabilities: ServerCapabilities,
    #[serde(rename = "serverInfo")]
    pub server_info: Option<ServerInfo>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ServerInfo {
    pub name: String,
    pub version: Option<String>,
}

/// Options for starting LSP server
#[derive(Debug, Clone, Default)]
pub struct LspStartOptions {
    pub env: Option<std::collections::HashMap<String, String>>,
    pub cwd: Option<String>,
}

/// LSP client - simple implementation
pub struct LspClientImpl {
    initialized: bool,
    capabilities: Option<ServerCapabilities>,
}

impl LspClientImpl {
    pub fn new() -> Self {
        Self {
            initialized: false,
            capabilities: None,
        }
    }

    pub fn capabilities(&self) -> Option<&ServerCapabilities> {
        self.capabilities.as_ref()
    }

    pub fn is_initialized(&self) -> bool {
        self.initialized
    }

    pub async fn start(
        &mut self,
        _command: &str,
        _args: &[String],
        _options: Option<LspStartOptions>,
    ) -> Result<(), String> {
        Ok(())
    }

    pub async fn initialize(
        &mut self,
        _params: InitializeParams,
    ) -> Result<InitializeResult, String> {
        self.initialized = true;
        Ok(InitializeResult::default())
    }

    pub async fn stop(&mut self) -> Result<(), String> {
        self.initialized = false;
        Ok(())
    }
}

impl Default for LspClientImpl {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_server_capabilities_default() {
        let caps = ServerCapabilities::default();
        assert!(caps.hover_provider.is_none());
    }

    #[test]
    fn test_initialize_params_default() {
        let params = InitializeParams::default();
        assert!(params.process_id.is_none());
    }
}