Documentation
¶
Overview ¶
Package lsp provides Language Server Protocol integration for evva.
The lsp_request tool (deferred) allows the agent to query LSP servers for semantic code intelligence: go-to-definition, find references, hover, and document symbols. Servers are started lazily on first use and managed via the daemon system.
See docs/roadmap/lsp.md for architecture and implementation plan.
Index ¶
- func DiscoverServers(workdir string) map[string]LspServerConfig
- func FormatDiagnosticsReminder(diags []PendingDiagnostic) string
- func IsNotFoundError(err error) bool
- func Names() []tools.ToolName
- func NewTool(mgr *Manager, workDir string) *lspTool
- func SuggestServerForExt(ext string) string
- type Client
- func (c *Client) Close() error
- func (c *Client) Notify(ctx context.Context, method string, params any) error
- func (c *Client) OnNotify(method string, handler NotificationHandler)
- func (c *Client) Process() *os.Process
- func (c *Client) Request(ctx context.Context, method string, params any) (json.RawMessage, error)
- type DiagnosticRegistry
- type LspConfig
- type LspServerConfig
- type Manager
- func (m *Manager) CloseFile(ctx context.Context, filePath string) error
- func (m *Manager) DrainDiagnostics() []PendingDiagnostic
- func (m *Manager) EnsureServerStarted(ctx context.Context, filePath string) (*Server, error)
- func (m *Manager) FirstExtensionFor(serverName string) string
- func (m *Manager) NotifyFileChanged(filePath string)
- func (m *Manager) OpenFile(ctx context.Context, filePath, content string) error
- func (m *Manager) ServerForFile(filePath string) (*Server, bool)
- func (m *Manager) Servers() []string
- func (m *Manager) SetDaemonState(ds *daemon.DaemonState)
- func (m *Manager) Shutdown(ctx context.Context) error
- type NotificationHandler
- type PendingDiagnostic
- type Server
- func (s *Server) Capabilities() protocol.ServerCapabilities
- func (s *Server) IsHealthy() bool
- func (s *Server) MaxRestarts() int
- func (s *Server) Notify(ctx context.Context, method string, params any) error
- func (s *Server) OnNotify(method string, handler NotificationHandler)
- func (s *Server) Request(ctx context.Context, method string, params any) (json.RawMessage, error)
- func (s *Server) RestartCount() int
- func (s *Server) SetDiagHandler(h NotificationHandler)
- func (s *Server) Start(ctx context.Context) error
- func (s *Server) State() ServerState
- func (s *Server) Stop(ctx context.Context) error
- type ServerState
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DiscoverServers ¶
func DiscoverServers(workdir string) map[string]LspServerConfig
DiscoverServers scans the workdir for project markers and checks PATH for matching LSP servers. Returns configs for usable servers.
func FormatDiagnosticsReminder ¶
func FormatDiagnosticsReminder(diags []PendingDiagnostic) string
FormatDiagnosticsReminder renders diagnostics as a <system-reminder> block.
func IsNotFoundError ¶
IsNotFoundError reports whether err indicates the server binary was not found.
func SuggestServerForExt ¶
SuggestServerForExt returns the name of a known server that handles the given extension, or "" if none is known.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a JSON-RPC 2.0 client that speaks the LSP framing protocol (Content-Length header + JSON body) over stdin/stdout of a child process.
func Start ¶
func Start(ctx context.Context, command string, args []string, logger *slog.Logger) (*Client, error)
Start spawns the LSP server process and starts the reader goroutine. The caller owns the returned Client and must call Close to clean up.
func (*Client) Close ¶
Close sends a graceful shutdown sequence: shutdown request → exit notification → kill process. Callers should use Server.Stop instead of calling this directly — Server manages the handshake timeout.
func (*Client) OnNotify ¶
func (c *Client) OnNotify(method string, handler NotificationHandler)
OnNotify registers a handler for incoming notifications. Handlers are called synchronously from the reader goroutine — keep them fast.
type DiagnosticRegistry ¶
type DiagnosticRegistry struct {
// contains filtered or unexported fields
}
DiagnosticRegistry collects, deduplicates, and drains LSP diagnostics.
func NewDiagnosticRegistry ¶
func NewDiagnosticRegistry() *DiagnosticRegistry
NewDiagnosticRegistry creates a registry with default limits.
func (*DiagnosticRegistry) ClearFile ¶
func (r *DiagnosticRegistry) ClearFile(fileURI string)
ClearFile removes pending diagnostics for a file and marks their identity keys as delivered (so they don't re-appear if the server re-sends them).
func (*DiagnosticRegistry) Drain ¶
func (r *DiagnosticRegistry) Drain() []PendingDiagnostic
Drain returns all pending diagnostics and clears the queue.
func (*DiagnosticRegistry) Register ¶
func (r *DiagnosticRegistry) Register(serverName, fileURI string, diags []protocol.Diagnostic)
Register adds diagnostics for a file. Already-delivered diagnostics (matched by identity key) are dropped. Per-file and total caps are enforced.
type LspConfig ¶
type LspConfig struct {
Servers map[string]LspServerConfig `yaml:"servers"`
}
LspConfig is the top-level config file shape.
func LoadConfig ¶
LoadConfig reads project-level .evva/lsp_servers.yml with fallback to user-level ~/.evva/lsp_servers.yml. Project-level entries override user-level for the same server name. Returns a default empty config when neither file exists.
type LspServerConfig ¶
type LspServerConfig struct {
Command string `yaml:"command"`
Args []string `yaml:"args"`
Extensions map[string]string `yaml:"extensions"` // ".go" → "go", ".ts" → "typescript"
Env map[string]string `yaml:"env"`
StartupTimeout string `yaml:"startupTimeout"` // "30s"
MaxRestarts int `yaml:"maxRestarts"` // default 3
}
LspServerConfig describes one LSP server to manage.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager routes files to LSP servers based on extension and manages server lifecycles (lazy start, document sync, shutdown).
func NewManager ¶
NewManager creates a Manager from a list of server configs. Servers are registered but not started — they start lazily on first EnsureServerStarted.
func (*Manager) DrainDiagnostics ¶
func (m *Manager) DrainDiagnostics() []PendingDiagnostic
DrainDiagnostics returns all pending diagnostics and clears the queue. Called by the agent loop at the start of each iteration.
func (*Manager) EnsureServerStarted ¶
EnsureServerStarted lazily starts the server responsible for filePath. Uses singleflight to prevent duplicate starts — all concurrent callers for the same server share one start attempt and result.
func (*Manager) FirstExtensionFor ¶
FirstExtensionFor returns the first file extension (including leading dot) mapped to the given server name, or "" if none is mapped.
func (*Manager) NotifyFileChanged ¶
NotifyFileChanged clears diagnostics for a file. Call this after external file modifications (write, edit, bash) to invalidate stale diagnostics.
func (*Manager) OpenFile ¶
OpenFile sends textDocument/didOpen to the server responsible for filePath and tracks the open state.
func (*Manager) ServerForFile ¶
ServerForFile returns the server responsible for the given file path and whether one was found.
func (*Manager) SetDaemonState ¶
func (m *Manager) SetDaemonState(ds *daemon.DaemonState)
SetDaemonState installs the daemon catalog for LSP lifecycle tracking. When set, LSP servers are registered as daemons on start so daemon_list and daemon_output can introspect their state.
type NotificationHandler ¶
type NotificationHandler func(params json.RawMessage)
NotificationHandler receives incoming notifications from the server.
type PendingDiagnostic ¶
type PendingDiagnostic struct {
ServerName string
FileURI string
FilePath string
Diagnostics []protocol.Diagnostic
}
PendingDiagnostic holds diagnostics queued for delivery for a single file.
type Server ¶
type Server struct {
Name string
Config LspServerConfig
// contains filtered or unexported fields
}
Server wraps a single LSP server process with a state machine.
func NewServer ¶
NewServer creates a Server from the given config. The server is not started until Start is called.
func (*Server) Capabilities ¶
func (s *Server) Capabilities() protocol.ServerCapabilities
Capabilities returns the server's advertised capabilities.
func (*Server) MaxRestarts ¶
MaxRestarts returns the configured restart limit.
func (*Server) OnNotify ¶
func (s *Server) OnNotify(method string, handler NotificationHandler)
OnNotify registers a notification handler on the underlying client.
func (*Server) RestartCount ¶
RestartCount returns the number of restarts since the last successful start.
func (*Server) SetDiagHandler ¶
func (s *Server) SetDiagHandler(h NotificationHandler)
SetDiagHandler stores the publishDiagnostics handler for re-registration when the client is created in Start(). Called by Manager at construction.
type ServerState ¶
type ServerState int
ServerState is the lifecycle state of one LSP server instance.
const ( StateStopped ServerState = iota StateStarting StateRunning StateStopping StateError )
func (ServerState) String ¶
func (s ServerState) String() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package protocol holds hand-written LSP protocol types covering the subset of the LSP 3.17 spec needed by evva's Phase 1 operations (definition, references, hover, document symbols) plus the lifecycle handshake.
|
Package protocol holds hand-written LSP protocol types covering the subset of the LSP 3.17 spec needed by evva's Phase 1 operations (definition, references, hover, document symbols) plus the lifecycle handshake. |