5e32375f0e
架构变更: - 采用 pnpm workspaces 实现 Monorepo 结构 - 将现有代码迁移到 packages/core - 新增 packages/server HTTP 服务层 Server 功能: - REST API: 会话管理、工具管理、配置管理 - WebSocket: 实时双向通信支持 - SSE: 服务端事件推送 - Hono + Bun 作为运行时 API 端点: - GET/POST /api/sessions - 会话 CRUD - GET/POST /api/sessions/:id/messages - 消息管理 - GET /api/sessions/:id/events - SSE 事件流 - WS /api/ws/:sessionId - WebSocket 连接 - GET/POST /api/tools - 工具管理 - GET/PUT /api/config - 配置管理
337 lines
8.0 KiB
TypeScript
337 lines
8.0 KiB
TypeScript
/**
|
||
* 语言服务器定义
|
||
* 定义各种语言的 LSP 服务器配置
|
||
*/
|
||
|
||
import type { LanguageId } from './language.js';
|
||
|
||
// 安装命令配置
|
||
export interface InstallConfig {
|
||
/** npm 全局安装包名 */
|
||
npm?: string;
|
||
/** pip 安装包名 */
|
||
pip?: string;
|
||
/** go install 路径 */
|
||
go?: string;
|
||
/** cargo install 包名 */
|
||
cargo?: string;
|
||
/** brew 安装包名 */
|
||
brew?: string;
|
||
/** gem 安装包名 */
|
||
gem?: string;
|
||
/** rustup component */
|
||
rustup?: string;
|
||
/** 自定义安装命令 */
|
||
custom?: string;
|
||
/** 安装说明(当无法自动安装时) */
|
||
manual?: string;
|
||
}
|
||
|
||
// 服务器配置接口
|
||
export interface ServerConfig {
|
||
/** 服务器命令 */
|
||
command: string;
|
||
/** 命令参数 */
|
||
args: string[];
|
||
/** 环境变量 */
|
||
env?: Record<string, string>;
|
||
/** 初始化选项 */
|
||
initializationOptions?: Record<string, unknown>;
|
||
/** 安装配置 */
|
||
install: InstallConfig;
|
||
/** 显示名称 */
|
||
displayName: string;
|
||
/** 描述 */
|
||
description: string;
|
||
}
|
||
|
||
// 语言服务器定义
|
||
const serverConfigs: Partial<Record<LanguageId, ServerConfig>> = {
|
||
// TypeScript/JavaScript - 使用 typescript-language-server
|
||
typescript: {
|
||
command: 'typescript-language-server',
|
||
args: ['--stdio'],
|
||
initializationOptions: {
|
||
preferences: {
|
||
includeInlayParameterNameHints: 'all',
|
||
includeInlayPropertyDeclarationTypeHints: true,
|
||
includeInlayFunctionLikeReturnTypeHints: true,
|
||
},
|
||
},
|
||
install: {
|
||
npm: 'typescript-language-server typescript',
|
||
},
|
||
displayName: 'TypeScript',
|
||
description: 'TypeScript/JavaScript 语言服务器',
|
||
},
|
||
javascript: {
|
||
command: 'typescript-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'typescript-language-server typescript',
|
||
},
|
||
displayName: 'JavaScript',
|
||
description: 'JavaScript 语言服务器(共用 TypeScript)',
|
||
},
|
||
typescriptreact: {
|
||
command: 'typescript-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'typescript-language-server typescript',
|
||
},
|
||
displayName: 'TypeScript React',
|
||
description: 'TSX 语言服务器(共用 TypeScript)',
|
||
},
|
||
javascriptreact: {
|
||
command: 'typescript-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'typescript-language-server typescript',
|
||
},
|
||
displayName: 'JavaScript React',
|
||
description: 'JSX 语言服务器(共用 TypeScript)',
|
||
},
|
||
|
||
// Python - 使用 pyright
|
||
python: {
|
||
command: 'pyright-langserver',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'pyright',
|
||
pip: 'pyright',
|
||
},
|
||
displayName: 'Python',
|
||
description: 'Python 语言服务器 (Pyright)',
|
||
},
|
||
|
||
// Go - 使用 gopls
|
||
go: {
|
||
command: 'gopls',
|
||
args: ['serve'],
|
||
install: {
|
||
go: 'golang.org/x/tools/gopls@latest',
|
||
},
|
||
displayName: 'Go',
|
||
description: 'Go 语言服务器 (gopls)',
|
||
},
|
||
|
||
// Rust - 使用 rust-analyzer
|
||
rust: {
|
||
command: 'rust-analyzer',
|
||
args: [],
|
||
install: {
|
||
rustup: 'rust-analyzer',
|
||
brew: 'rust-analyzer',
|
||
},
|
||
displayName: 'Rust',
|
||
description: 'Rust 语言服务器 (rust-analyzer)',
|
||
},
|
||
|
||
// C/C++ - 使用 clangd
|
||
c: {
|
||
command: 'clangd',
|
||
args: ['--background-index'],
|
||
install: {
|
||
brew: 'llvm',
|
||
manual: 'Ubuntu: sudo apt install clangd\nmacOS: brew install llvm',
|
||
},
|
||
displayName: 'C',
|
||
description: 'C 语言服务器 (clangd)',
|
||
},
|
||
cpp: {
|
||
command: 'clangd',
|
||
args: ['--background-index'],
|
||
install: {
|
||
brew: 'llvm',
|
||
manual: 'Ubuntu: sudo apt install clangd\nmacOS: brew install llvm',
|
||
},
|
||
displayName: 'C++',
|
||
description: 'C++ 语言服务器 (clangd)',
|
||
},
|
||
|
||
// Java - 使用 jdtls
|
||
java: {
|
||
command: 'jdtls',
|
||
args: [],
|
||
install: {
|
||
brew: 'jdtls',
|
||
manual: '请访问 https://github.com/eclipse/eclipse.jdt.ls 获取安装说明',
|
||
},
|
||
displayName: 'Java',
|
||
description: 'Java 语言服务器 (Eclipse JDT.LS)',
|
||
},
|
||
|
||
// C# - 使用 OmniSharp
|
||
csharp: {
|
||
command: 'omnisharp',
|
||
args: ['-lsp'],
|
||
install: {
|
||
brew: 'omnisharp/omnisharp-roslyn/omnisharp-mono',
|
||
manual: '请访问 https://github.com/OmniSharp/omnisharp-roslyn 获取安装说明',
|
||
},
|
||
displayName: 'C#',
|
||
description: 'C# 语言服务器 (OmniSharp)',
|
||
},
|
||
|
||
// PHP - 使用 intelephense
|
||
php: {
|
||
command: 'intelephense',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'intelephense',
|
||
},
|
||
displayName: 'PHP',
|
||
description: 'PHP 语言服务器 (Intelephense)',
|
||
},
|
||
|
||
// Ruby - 使用 solargraph
|
||
ruby: {
|
||
command: 'solargraph',
|
||
args: ['stdio'],
|
||
install: {
|
||
gem: 'solargraph',
|
||
},
|
||
displayName: 'Ruby',
|
||
description: 'Ruby 语言服务器 (Solargraph)',
|
||
},
|
||
|
||
// Vue - 使用 vue-language-server
|
||
vue: {
|
||
command: 'vue-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: '@vue/language-server',
|
||
},
|
||
displayName: 'Vue',
|
||
description: 'Vue 语言服务器',
|
||
},
|
||
|
||
// Svelte - 使用 svelte-language-server
|
||
svelte: {
|
||
command: 'svelteserver',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'svelte-language-server',
|
||
},
|
||
displayName: 'Svelte',
|
||
description: 'Svelte 语言服务器',
|
||
},
|
||
|
||
// HTML - 使用 vscode-html-language-server
|
||
html: {
|
||
command: 'vscode-html-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'vscode-langservers-extracted',
|
||
},
|
||
displayName: 'HTML',
|
||
description: 'HTML 语言服务器',
|
||
},
|
||
|
||
// CSS/SCSS/Less - 使用 vscode-css-language-server
|
||
css: {
|
||
command: 'vscode-css-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'vscode-langservers-extracted',
|
||
},
|
||
displayName: 'CSS',
|
||
description: 'CSS 语言服务器',
|
||
},
|
||
scss: {
|
||
command: 'vscode-css-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'vscode-langservers-extracted',
|
||
},
|
||
displayName: 'SCSS',
|
||
description: 'SCSS 语言服务器(共用 CSS)',
|
||
},
|
||
less: {
|
||
command: 'vscode-css-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'vscode-langservers-extracted',
|
||
},
|
||
displayName: 'Less',
|
||
description: 'Less 语言服务器(共用 CSS)',
|
||
},
|
||
|
||
// JSON - 使用 vscode-json-language-server
|
||
json: {
|
||
command: 'vscode-json-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'vscode-langservers-extracted',
|
||
},
|
||
displayName: 'JSON',
|
||
description: 'JSON 语言服务器',
|
||
},
|
||
|
||
// YAML - 使用 yaml-language-server
|
||
yaml: {
|
||
command: 'yaml-language-server',
|
||
args: ['--stdio'],
|
||
install: {
|
||
npm: 'yaml-language-server',
|
||
},
|
||
displayName: 'YAML',
|
||
description: 'YAML 语言服务器',
|
||
},
|
||
};
|
||
|
||
/**
|
||
* 获取语言服务器配置
|
||
*/
|
||
export function getServerConfig(languageId: LanguageId): ServerConfig | undefined {
|
||
return serverConfigs[languageId];
|
||
}
|
||
|
||
/**
|
||
* 检查语言是否有可用的服务器配置
|
||
*/
|
||
export function hasServerConfig(languageId: LanguageId): boolean {
|
||
return languageId in serverConfigs;
|
||
}
|
||
|
||
/**
|
||
* 获取所有支持的语言 ID
|
||
*/
|
||
export function getSupportedLanguages(): LanguageId[] {
|
||
return Object.keys(serverConfigs) as LanguageId[];
|
||
}
|
||
|
||
/**
|
||
* 获取所有服务器配置(用于 CLI)
|
||
*/
|
||
export function getAllServerConfigs(): Partial<Record<LanguageId, ServerConfig>> {
|
||
return serverConfigs;
|
||
}
|
||
|
||
/**
|
||
* 获取唯一的服务器列表(去重相同命令的服务器)
|
||
*/
|
||
export function getUniqueServers(): Array<{ id: string; config: ServerConfig; languages: LanguageId[] }> {
|
||
const commandMap = new Map<string, { config: ServerConfig; languages: LanguageId[] }>();
|
||
|
||
for (const [langId, config] of Object.entries(serverConfigs)) {
|
||
if (!config) continue;
|
||
|
||
const existing = commandMap.get(config.command);
|
||
if (existing) {
|
||
existing.languages.push(langId as LanguageId);
|
||
} else {
|
||
commandMap.set(config.command, {
|
||
config,
|
||
languages: [langId as LanguageId],
|
||
});
|
||
}
|
||
}
|
||
|
||
return Array.from(commandMap.entries()).map(([command, data]) => ({
|
||
id: command,
|
||
config: data.config,
|
||
languages: data.languages,
|
||
}));
|
||
}
|