feat(solidlsp): prototype registrable language server adapters

This commit is contained in:
Vitaly Ruhl authored and Dominik Jain committed 2026-09-05 12:36:53 +02:00
1 parent 13ac8c5b1d
commit 6000f16680
19 files changed
+892 -54

No files matched your search

+5 -2
View File
@@ -190,8 +190,11 @@ Some languages require additional installations or setup steps, as noted.
* **Zig**
(requires installation of ZLS - Zig Language Server)
Support for further languages can easily be added by providing a shallow adapter for a new language server implementation,
see Serena's [memory on that](https://github.com/oraios/serena/blob/main/.serena/memories/adding_new_language_support_guide.md).
Support for further languages can be added either as a built-in Serena language-server implementation or as an external Python adapter.
External adapters are supplied by installed packages and registered through the
[external language-server adapter](030_external_language_server_adapters) entry-point mechanism.
The external mechanism does not participate in automatic language detection; add the registered ID explicitly to `project.yml`.
For built-in integrations, see Serena's [guide for adding new language support](https://github.com/oraios/serena/blob/main/.serena/memories/adding_new_language_support_guide.md).
## The Serena JetBrains Plugin
@@ -0,0 +1,55 @@
# External Language Server Adapters
Serena can load language-server integrations provided by installed Python packages. This lets a project use an external language server without adding its adapter to the Serena core.
## How It Works
An adapter package exposes a Python entry point in the `serena.language_servers` group:
```toml
[project.entry-points."serena.language_servers"]
example = "example_serena_adapter:register"
```
Serena discovers these entry points with Python's `importlib.metadata.entry_points()` at the regular `ProjectConfig.load()` lifecycle boundary. The loaded registration function provides the actual Python `SolidLanguageServer` implementation and calls the existing registry API:
```python
from solidlsp.ls_config import FilenameMatcher, register_ls
def register() -> None:
register_ls(
id="example",
matcher=FilenameMatcher(".example"),
implementation=ExampleLanguageServer,
)
```
Several external adapters can be installed and registered at the same time. Their IDs can then be used in a project's `.serena/project.yml`:
```yaml
language_servers:
- example
```
The registered implementation is started and managed by Serena. Serena launches the external server using the adapter's process configuration; it does not search for already-running LSP processes.
## Trust and Security
Only entry points exposed by installed Python packages are considered. Project configuration does not import Python code, accept arbitrary module paths, or perform filesystem-based plugin discovery. Serena does not install plugins automatically or download adapters from a marketplace.
An installed adapter contains executable Python code and therefore has the same trust implications as any other installed Python package. Install adapters only from sources you trust. The project can reference a registered ID, but it cannot cause an arbitrary Python module to be loaded through `project.yml`.
## Errors and IDs
The first discovery is serialized across concurrent project loads and completes once entry-point metadata has been read successfully. A failure while reading the installed entry-point metadata is reported and leaves discovery retryable. If one adapter fails while loading or registering, Serena reports the entry-point name and distribution when available, rolls back that adapter's registrations, and continues loading other adapters.
A failed adapter ID is not available afterward. If a project references it, normal language-server configuration validation reports an unknown ID. Registered IDs must be unique and cannot replace a built-in Serena language-server ID.
Adapter IDs must be non-empty, trimmed, and lowercase. Each external `SolidLanguageServer` implementation class can be registered under only one external ID.
## Built-in and External Integrations
Built-in Serena language servers are implemented and mapped inside the Serena distribution and use the existing built-in language-server IDs. An external adapter is implemented in its own Python package, registers its ID through the entry-point contract above, and supplies the integration required to launch and communicate with its language server.
This mechanism does not change Serena's language auto-detection. External adapters are available when explicitly registered and referenced in project configuration.
+5 -2
View File
@@ -45,8 +45,11 @@ within the project directory.
The file allows you to configure ...
* the name by which you want to refer to the project (relevant when telling the LLM to dynamically activate the project)
* the set of programming languages for which language servers are spawned (not relevant when using the JetBrains plugin)
Note that you can dynamically add/remove language servers while Serena is running via the [Dashboard](060_dashboard).
* the set of built-in language servers and explicitly registered external adapters for which servers are spawned
(not relevant when using the JetBrains plugin). External adapter IDs become available after their Python package is installed;
see [External Language Server Adapters](../01-about/030_external_language_server_adapters).
The [Dashboard](060_dashboard) can dynamically add or remove built-in language servers and installed, registered external
adapters while Serena is running. It does not install adapter packages or offer unregistered adapter IDs.
* the [language backend](per-project-language-backend) to use for this project (overriding the global setting)
* the encoding used in source files
* ignore rules