feat(solidlsp): add Astro language server support (#2085)

* feat(solidlsp): add Astro language server support (T170)

* test(solidlsp): fix relative_paths type extraction in test_astro_basic

* refactor(solidlsp): replace asserts with explicit exceptions in Astro LSP

* docs(memories): document rule against assert in language server guide

* docs: add Astro language server documentation (README, docs, template, CHANGELOG)

* feat(solidlsp): implement dual-server architecture for Astro with companion TypeScript server (#2085)

- Implement companion AstroTypeScriptServer using @astrojs/ts-plugin for cross-file code intelligence between .ts and .astro components
- Route .ts/.js document symbols, definitions, references, and renames through companion TypeScript server
- Support two-way buffer edit forwarding between Astro LS and companion TS server
- Replace all assert statements with explicit SolidLSPException and FileNotFoundError
- Handle *.customData configuration requests for Volar HTML service
- Register .astro extension in src/serena/hooks.py
- Add test fixtures and tests for symbol retrieval and cross-file references from TypeScript to Astro components
- Update documentation and CHANGELOG

* fix(solidlsp): narrow astro_ls type to AstroLanguageServer in companion server test

* fix(solidlsp): prevent caching empty document symbols and poll initial compilation in Nextflow tests
This commit is contained in:
Aleksei Tcelishchev authored and GitHub committed 2026-09-23 15:38:19 +02:00
1 parent d764406ac6
commit 15502cee56
28 files changed
+1123 -23

No files matched your search

+11 -2
View File
@@ -24,8 +24,17 @@ class TestNextflowLanguageServer:
@pytest.mark.parametrize("language_server", [LanguageServerId.NEXTFLOW], indirect=True)
def test_document_symbols_workflows(self, language_server: SolidLanguageServer) -> None:
"""Workflows declared in a script are reported, with the ``workflow`` keyword stripped."""
all_symbols, _ = language_server.request_document_symbols("main.nf").get_all_symbols_and_roots()
names = [s["name"] for s in all_symbols]
import time
deadline = time.monotonic() + 10.0
names: list[str] = []
while time.monotonic() < deadline:
all_symbols, _ = language_server.request_document_symbols("main.nf").get_all_symbols_and_roots()
names = [s["name"] for s in all_symbols]
if "SAY_HELLO" in names:
break
time.sleep(0.5)
assert "SAY_HELLO" in names, f"SAY_HELLO not found in main.nf symbols. Found: {names}"
# the implicit entry workflow has no name of its own; the language server calls it "<entry>"
assert "<entry>" in names, f"entry workflow not found in main.nf symbols. Found: {names}"