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

@@ -0,0 +1,5 @@
node_modules/
dist/
.astro/
package-lock.json
.astro-install.lock
@@ -0,0 +1,5 @@
import { defineConfig } from 'astro/config';
export default defineConfig({
// Minimal config for testing
});
@@ -0,0 +1,8 @@
{
"name": "astro-test-repo",
"type": "module",
"version": "0.0.1",
"dependencies": {
"astro": "^5.0.0"
}
}
@@ -0,0 +1,24 @@
---
interface Props {
title: string;
body: string;
href: string;
}
const { href, title, body } = Astro.props;
function formatTitle(val: string): string {
return val.toUpperCase();
}
---
<li class="link-card">
<a href={href}>
<h2>
{formatTitle(title)}
<span>&rarr;</span>
</h2>
<p>
{body}
</p>
</a>
</li>
@@ -0,0 +1,7 @@
---
const year = new Date().getFullYear();
---
<footer>
<p>&copy; {year} Test Site</p>
</footer>
@@ -0,0 +1,13 @@
---
interface Props {
siteName: string;
}
const { siteName } = Astro.props;
---
<header>
<nav>
<a href="/">{siteName}</a>
</nav>
</header>
@@ -0,0 +1,19 @@
---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
</head>
<body>
<slot />
</body>
</html>
@@ -0,0 +1,18 @@
---
import Card from '../components/Card.astro';
import Layout from '../layouts/Layout.astro';
import Header from '../components/Header.astro';
import { createCounter } from '../stores/counter';
import { formatNumber } from '../utils/format';
const pageTitle = "Welcome to Astro";
const counter = createCounter();
---
<Layout title={pageTitle}>
<Header siteName="Test Site" />
<main>
<h1>{pageTitle}</h1>
<p>Count: {formatNumber(counter.count)}</p>
<Card href="https://astro.build" title="Docs" body="Documentation" />
</main>
</Layout>
@@ -0,0 +1,21 @@
export interface CounterStore {
count: number;
increment: () => void;
decrement: () => void;
}
export function createCounter(): CounterStore {
let count = 0;
return {
get count() {
return count;
},
increment() {
count++;
},
decrement() {
count--;
},
};
}
@@ -0,0 +1,13 @@
/**
* Format a number with thousands separators.
*/
export function formatNumber(value: number): string {
return value.toLocaleString();
}
/**
* Format a date to locale string.
*/
export function formatDate(date: Date): string {
return date.toLocaleDateString();
}
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"jsx": "preserve",
"strict": true
},
"include": ["**/*"],
"exclude": ["dist", "node_modules"]
}