lsp

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package lsp provides the small language-server bridge used by yottacode's experimental code-intelligence tools. It intentionally owns only discovery, JSON-RPC framing, and result shaping; installation and long-lived IDE-style server management stay outside the agent.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidRenamePosition = errors.New("invalid rename position")

ErrInvalidRenamePosition marks a cursor position that the server rejected during textDocument/prepareRename before yottacode asked for rename edits.

View Source
var ErrProtocolMalformed = errors.New("malformed LSP protocol message")

ErrProtocolMalformed marks invalid JSON-RPC framing or response payloads.

View Source
var ErrRequestTimeout = errors.New("LSP request timed out")

ErrRequestTimeout marks a bounded LSP request or diagnostic wait timeout.

View Source
var ErrServerStartFailed = errors.New("LSP server start failed")

ErrServerStartFailed marks a configured server binary that exists but failed to launch or initialize successfully.

View Source
var ErrServerUnavailable = errors.New("LSP server unavailable")

ErrServerUnavailable marks a missing or intentionally disabled language server. Callers can fall back to parser/regex code intelligence.

View Source
var ErrUnsupportedCapability = errors.New("unsupported LSP capability")

ErrUnsupportedCapability marks an LSP method that the initialized server did not advertise. Tool wrappers turn this into an actionable unavailable result instead of showing a misleading empty response.

View Source
var ErrUnsupportedWorkspaceEdit = errors.New("unsupported LSP workspace edit")

ErrUnsupportedWorkspaceEdit marks LSP WorkspaceEdit shapes yottacode refuses to apply, such as file create/rename/delete operations. Text edits remain previewed and applied through yottacode's own validators.

Functions

func ApplyTextEdits

func ApplyTextEdits(text string, edits []TextEdit) (string, error)

func DefaultManagerMaxServers

func DefaultManagerMaxServers() int

func OffsetForPosition

func OffsetForPosition(text string, pos Position) (int, error)

OffsetForPosition converts a zero-based LSP UTF-16 position to a UTF-8 byte offset. It rejects positions in the middle of surrogate pairs.

func PreviewHash

func PreviewHash(text string) string

func RegisterSyntaxSymbolSource

func RegisterSyntaxSymbolSource(languageID string, source SyntaxSymbolSource)

RegisterSyntaxSymbolSource installs an offline symbol extractor for a stable language ID such as "go" or "typescript". Later registrations replace earlier ones so tests and future language packs can override the built-in default.

func ServerAvailable

func ServerAvailable(lang Language) bool

ServerAvailable reports whether a language server's binary is present on PATH. A language with no command is treated as unavailable so future entries cannot panic by indexing an empty command.

func SyntaxMode

func SyntaxMode(languageID string) string

SyntaxMode reports the offline structure backend available for a language. The value is intentionally compact because lsp_status prints it per language.

func WorkspaceEditSummary

func WorkspaceEditSummary(edit WorkspaceEdit) string

func WorkspaceRoot

func WorkspaceRoot(path string, lang Language, fallback string) string

WorkspaceRoot walks upward from path and returns the closest project root for lang based on common build/config markers. Falling back to the file directory keeps single-file projects working when no marker exists.

Types

type CallHierarchyItem

type CallHierarchyItem struct {
	Name      string
	Kind      string
	Detail    string
	Location  Location
	Direction string
}

CallHierarchyItem is one incoming/outgoing call hierarchy row.

type Capabilities

type Capabilities struct {
	WorkspaceSymbol   bool `json:"workspace_symbol"`
	DocumentSymbol    bool `json:"document_symbol"`
	DocumentHighlight bool `json:"document_highlight"`
	SelectionRange    bool `json:"selection_range"`
	Definition        bool `json:"definition"`
	TypeDefinition    bool `json:"type_definition"`
	Implementation    bool `json:"implementation"`
	References        bool `json:"references"`
	Hover             bool `json:"hover"`
	SignatureHelp     bool `json:"signature_help"`
	CodeAction        bool `json:"code_action"`
	CodeActionResolve bool `json:"code_action_resolve"`
	CallHierarchy     bool `json:"call_hierarchy"`
	Rename            bool `json:"rename"`
	RenamePrepare     bool `json:"rename_prepare"`
	Formatting        bool `json:"formatting"`
}

Capabilities is the stable, printable subset of initialized server capabilities that yottacode exposes through status and doctor output. It intentionally mirrors only methods used by the agent tool surface.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client owns one language-server subprocess. In normal TUI/oneshot sessions it is acquired through Manager and kept warm across tool calls; tests and fallback callers can still construct short-lived clients directly.

func NewClient

func NewClient(ctx context.Context, lang Language, root string) (*Client, error)

NewClient starts and initializes the server for lang at root.

func (*Client) CallHierarchy

func (c *Client) CallHierarchy(ctx context.Context, path string, pos Position) ([]CallHierarchyItem, error)

CallHierarchy returns incoming and outgoing calls for a source position.

func (*Client) Capabilities

func (c *Client) Capabilities() Capabilities

Capabilities returns the initialized server capability snapshot. A direct test client that bypassed initialize returns the zero-value snapshot.

func (*Client) Close

func (c *Client) Close() error

Close asks the server to shut down, then tears down the process if it is still running. Errors are intentionally swallowed by callers via defer; the tool result has already been produced by this point.

func (*Client) CloseDocument

func (c *Client) CloseDocument(ctx context.Context, path string) error

CloseDocument releases a document from the server's open set and removes the local version counter. The manager calls this during teardown or resync.

func (*Client) CodeActionPreview

func (c *Client) CodeActionPreview(ctx context.Context, path string, start, end Position, title string, index int) (WorkspaceEdit, error)

CodeActionPreview returns the WorkspaceEdit for one server-offered code action without applying it. Some servers return edits inline while others require codeAction/resolve; both paths still end at yottacode's preview/apply flow so the language server never writes files directly.

func (*Client) CodeActions

func (c *Client) CodeActions(ctx context.Context, path string, start, end Position) ([]CodeAction, error)

CodeActions lists server-offered actions for a range without applying them.

func (*Client) Definition

func (c *Client) Definition(ctx context.Context, path string, pos Position) ([]Location, error)

Definition runs textDocument/definition at pos.

func (*Client) Diagnostics

func (c *Client) Diagnostics(ctx context.Context, path string) (DiagnosticsSnapshot, error)

Diagnostics opens a document and waits briefly for publishDiagnostics.

func (*Client) DocumentHighlights

func (c *Client) DocumentHighlights(ctx context.Context, path string, pos Position) ([]DocumentHighlight, error)

DocumentHighlights returns current-file symbol occurrences at pos.

func (*Client) DocumentSymbols

func (c *Client) DocumentSymbols(ctx context.Context, path string) ([]Symbol, error)

DocumentSymbols runs textDocument/documentSymbol and returns normalized symbols from one source file. Hierarchical DocumentSymbol responses are flattened with the parent name as Container so tool output stays compact.

func (*Client) FormatPreview

func (c *Client) FormatPreview(ctx context.Context, path string) (WorkspaceEdit, error)

FormatPreview asks the server for whole-document formatting edits without applying them. The agent apply path remains yottacode-owned and approved.

func (*Client) Hover

func (c *Client) Hover(ctx context.Context, path string, pos Position) (string, error)

Hover returns type/doc information at a source position.

func (*Client) Implementation

func (c *Client) Implementation(ctx context.Context, path string, pos Position) ([]Location, error)

Implementation runs textDocument/implementation at pos.

func (*Client) NotifyChanged

func (c *Client) NotifyChanged(ctx context.Context, path, text string) error

NotifyChanged sends a full-document didChange for a path that yottacode just wrote. Full sync is less clever than incremental ranges but is safer for an agent whose edits may come from multiple tools and rollback paths.

func (*Client) NotifySaved

func (c *Client) NotifySaved(ctx context.Context, path string) error

NotifySaved tells the server that yottacode finished writing a document. Servers that ignore didSave simply drop the notification.

func (*Client) References

func (c *Client) References(ctx context.Context, path string, pos Position, includeDeclaration bool) ([]Location, error)

References runs textDocument/references at pos.

func (*Client) RenamePreview

func (c *Client) RenamePreview(ctx context.Context, path string, pos Position, newName string) (WorkspaceEdit, error)

RenamePreview asks the server for a semantic rename edit without applying it.

func (*Client) SelectionRanges

func (c *Client) SelectionRanges(ctx context.Context, path string, positions []Position) ([]SelectionRange, error)

SelectionRanges returns enclosing syntax ranges for one or more positions.

func (*Client) SignatureHelp

func (c *Client) SignatureHelp(ctx context.Context, path string, pos Position) (SignatureHelp, error)

SignatureHelp returns callable signatures visible at a source position.

func (*Client) TypeDefinition

func (c *Client) TypeDefinition(ctx context.Context, path string, pos Position) ([]Location, error)

TypeDefinition runs textDocument/typeDefinition at pos.

func (*Client) WorkspaceSymbols

func (c *Client) WorkspaceSymbols(ctx context.Context, query string) ([]Symbol, error)

WorkspaceSymbols runs workspace/symbol and returns normalized results.

type CodeAction

type CodeAction struct {
	Index             int
	Title             string
	Kind              string
	HasEdit           bool
	HasCommand        bool
	DiagnosticCount   int
	ResolveSupported  bool
	ResolveIncomplete bool
}

CodeAction is a read-only description of a server-offered fix/refactor.

type DetectedLanguage

type DetectedLanguage struct {
	Language
	FilesAvailable  int
	ServerAvailable bool
}

DetectedLanguage combines workspace detection with server readiness.

func ApplyOverridesToDetected

func ApplyOverridesToDetected(in []DetectedLanguage, overrides map[string][]string) []DetectedLanguage

ApplyOverridesToDetected returns detected languages with command overrides applied while preserving file counts and availability recalculated from the overridden binary.

func DetectWorkspace

func DetectWorkspace(ctx context.Context, root string, maxFiles int) ([]DetectedLanguage, error)

DetectWorkspace scans root for supported source files and reports the language families present. The scan is bounded and skips heavy directories so lsp_status is cheap enough to run as a normal read-only tool.

type Diagnostic

type Diagnostic struct {
	Path      string
	Line      int
	Character int
	Severity  string
	Source    string
	Code      string
	Tags      []string
	Related   []DiagnosticRelated
	Message   string
}

Diagnostic is a compile/type/lint message published by an LSP server.

type DiagnosticRelated

type DiagnosticRelated struct {
	Location Location
	Message  string
}

DiagnosticRelated points at supporting context for a diagnostic, such as the declaration that caused an implementation mismatch. It is intentionally small so tool output can stay bounded.

type DiagnosticsSnapshot

type DiagnosticsSnapshot struct {
	Published   bool
	Diagnostics []Diagnostic
}

DiagnosticsSnapshot is the latest diagnostic state yottacode could observe for a file. Published=false means the server did not publish diagnostics before the bounded settle timeout, which is distinct from a clean file.

type DocumentHighlight

type DocumentHighlight struct {
	Range TextRange
	Kind  string
}

DocumentHighlight is a current-document read/write/text occurrence range returned by textDocument/documentHighlight. Ranges use zero-based LSP UTF-16 coordinates.

type Language

type Language struct {
	ID             string
	Name           string
	Extensions     []string
	Command        []string
	InstallHint    string
	InstallCommand string
	// InitializationOptions are sent during initialize to prefer safe analysis
	// defaults for local subprocess servers that may otherwise execute project
	// build hooks or load repo-configured plugins while indexing.
	InitializationOptions map[string]any
}

Language describes one supported language-server family. Each entry includes a user-facing install hint and exact install command so unavailable servers degrade into actionable, approval-gated setup guidance instead of a bare "command not found" error.

func ApplyOverrides

func ApplyOverrides(lang Language, overrides map[string][]string) Language

ApplyOverrides returns a copy of lang with any user-configured command override applied. Empty overrides leave the built-in command intact.

func Languages

func Languages() []Language

Languages returns the supported language-server families in deterministic order. The first Command element is the binary checked on PATH and executed directly without a shell.

func ResolveFile

func ResolveFile(path string) (Language, bool)

ResolveFile maps a source file path to the language-server family that owns its extension. Matching is case-insensitive because editors commonly open generated or copied files with odd extension casing.

func ResolveID

func ResolveID(id string) (Language, bool)

ResolveID returns a language by its stable ID.

type Location

type Location struct {
	Path      string `json:"path"`
	Line      int    `json:"line"`
	Character int    `json:"character"`
}

Location is a compact source location returned to the agent tools.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager keeps a bounded pool of initialized LSP servers keyed by language, workspace root, and command. It avoids paying process startup on every tool call while still staying simple: all servers are closed at session teardown and idle/oldest entries are evicted before new starts.

func NewManager

func NewManager(maxServers int, idleTimeout time.Duration) *Manager

NewManager constructs a bounded LSP server manager. Zero values select safe defaults so callers do not need to tune this for ordinary sessions.

func (*Manager) Acquire

func (m *Manager) Acquire(ctx context.Context, lang Language, root string) (*PooledClient, error)

Acquire returns a reusable client wrapper. Closing the wrapper releases it back to the pool; CloseAll tears down the underlying subprocesses.

func (*Manager) CloseAll

func (m *Manager) CloseAll()

CloseAll terminates every pooled server. It is safe to call multiple times.

func (*Manager) CloseDocument

func (m *Manager) CloseDocument(ctx context.Context, lang Language, root, path string) error

CloseDocument removes one open document from a pooled server if that server is already running. It does not start a new server just to close a document.

func (*Manager) InvalidateAll

func (m *Manager) InvalidateAll()

InvalidateAll closes every pooled server after a bulk working-tree mutation. The next LSP tool call lazily starts fresh servers against the new on-disk state, avoiding stale diagnostics after rollback, reset, checkout, or switch.

func (*Manager) NotifyFileChanged

func (m *Manager) NotifyFileChanged(ctx context.Context, lang Language, root, path, text string) error

NotifyFileChanged updates the pooled server for a file that yottacode just wrote. It is best-effort by design: LSP diagnostics are advisory, and an edit must not fail only because a local language server is missing or busy.

func (*Manager) Stats

func (m *Manager) Stats() ManagerStats

Stats returns a lock-protected snapshot for lsp_status output.

type ManagerStats

type ManagerStats struct {
	OpenServers  int
	MaxServers   int
	Starts       int
	Reuses       int
	Evictions    int
	LastStart    time.Duration
	BusyServers  int
	Leases       int
	CapacityHits int
}

ManagerStats is a snapshot of the reusable LSP server pool. It is intentionally small and printable so status tools can surface latency and reuse without depending on internal pool details.

type ParameterInformation

type ParameterInformation struct {
	Label         string
	Documentation string
}

ParameterInformation describes one signature parameter returned by LSP.

type PooledClient

type PooledClient struct {
	*Client
	// contains filtered or unexported fields
}

PooledClient wraps a Client so tool-level Close releases the server for reuse.

func (*PooledClient) Close

func (c *PooledClient) Close() error

type Position

type Position struct {
	Line      int `json:"line"`
	Character int `json:"character"`
}

Position is a zero-based LSP text position.

func PositionForOffset

func PositionForOffset(text string, target int) (Position, error)

PositionForOffset converts a UTF-8 byte offset to a zero-based LSP UTF-16 position. Parser-backed syntax sources use this to normalize token.FileSet byte offsets into the same coordinates returned by language servers.

type SelectionRange

type SelectionRange struct {
	Path          string
	PositionIndex int
	Depth         int
	Range         TextRange
}

SelectionRange is one enclosing syntax range returned by textDocument/selectionRange. Depth starts at zero for the smallest range and increases as the server walks to larger parent ranges.

type ServerCommandOverrides

type ServerCommandOverrides map[string][]string

ServerCommandOverrides is the minimal config shape consumed by the LSP tool registration path. It avoids importing the config package into lsp/agent.

type SignatureHelp

type SignatureHelp struct {
	Signatures      []SignatureInformation
	ActiveSignature int
	ActiveParameter int
}

SignatureHelp is the normalized LSP signature-help response.

type SignatureInformation

type SignatureInformation struct {
	Label         string
	Documentation string
	Parameters    []ParameterInformation
}

SignatureInformation describes one callable signature at a source position.

type Symbol

type Symbol struct {
	Name      string
	Kind      string
	Container string
	Location  Location
	Range     TextRange
}

Symbol is a workspace or document symbol result from an LSP server.

func FallbackFileSymbols

func FallbackFileSymbols(path string) ([]Symbol, error)

FallbackFileSymbols scans one supported source file with the same conservative regexes used by FallbackSymbols. It is intended for outline-style callers that already walked the workspace and need deterministic per-file results.

func FallbackSymbols

func FallbackSymbols(ctx context.Context, root, query string, maxFiles int) ([]Symbol, error)

FallbackSymbols scans source files with conservative regexes when a real language server is unavailable. Results are intentionally approximate; the output marks Container as "fallback" so callers can surface that reduced precision to the model/user.

type SyntaxRange

type SyntaxRange struct {
	Kind   string
	Name   string
	Detail string
	Range  TextRange
}

SyntaxRange is one parser-backed structural range containing a source position. Ranges use the same zero-based UTF-16 coordinates as LSP so agents can compare parser output with lsp_selection_ranges without translation.

func SyntaxFileRanges

func SyntaxFileRanges(ctx context.Context, lang Language, path string, pos Position) ([]SyntaxRange, bool, error)

SyntaxFileRanges returns parser-backed enclosing ranges for a source file. The boolean is false when the language has no range-capable parser source.

type SyntaxRangeSource

type SyntaxRangeSource interface {
	Ranges(ctx context.Context, path string, pos Position) ([]SyntaxRange, error)
}

SyntaxRangeSource is the optional extension for parser backends that can return enclosing edit-target ranges, not just top-level symbols.

type SyntaxSymbolSource

type SyntaxSymbolSource interface {
	Symbols(ctx context.Context, path string) ([]Symbol, error)
}

SyntaxSymbolSource extracts structural symbols without starting a language server. Parser-backed implementations give yottacode an offline structure layer; languages without one keep using the conservative regex fallback.

type TextEdit

type TextEdit struct {
	Path         string    `json:"path"`
	Range        TextRange `json:"range"`
	NewText      string    `json:"new_text"`
	PreviewHash  string    `json:"preview_hash,omitempty"`
	PreviewBytes int       `json:"preview_bytes,omitempty"`
}

TextEdit is one text replacement proposed by an LSP WorkspaceEdit.

type TextRange

type TextRange struct {
	Start Position `json:"start"`
	End   Position `json:"end"`
}

TextRange is an LSP half-open range in zero-based line/UTF-16 character coordinates.

type WorkspaceEdit

type WorkspaceEdit struct {
	Edits []TextEdit `json:"edits"`
}

WorkspaceEdit is the normalized, path-keyed edit set yottacode previews and applies through its own validators rather than delegating writes to the server.

func (WorkspaceEdit) Paths

func (e WorkspaceEdit) Paths() []string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL