refactor(doctor): show detected LSP servers and extensions instead of hardcoded counts

Replace the hardcoded 4-server list in doctor LSP check with getAllServers()
from server-resolution.ts, which covers all 40+ builtin servers plus user
config. Output now shows server count with supported extensions, and verbose
mode expands to per-server detail lines.

Status:  LSP 3 servers (.go, .py, .pyi, .ts, .tsx)
Verbose: LSP 3 servers (.go, .py, .pyi, .ts, .tsx)
           typescript (.ts, .tsx, .js, .jsx)
           pyright (.py, .pyi)
           gopls (.go)

Closes #2587
This commit is contained in:
acamq
2026-03-15 18:39:56 -06:00
parent 5073efef48
commit 03da2e94a2
8 changed files with 32 additions and 41 deletions
+6 -22
View File
@@ -1,25 +1,9 @@
import type { LspServerInfo } from "../types"
import { isServerInstalled } from "../../../tools/lsp/config"
import { getAllServers } from "../../../tools/lsp/config"
const DEFAULT_LSP_SERVERS: Array<{ id: string; binary: string; extensions: string[] }> = [
{ id: "typescript-language-server", binary: "typescript-language-server", extensions: [".ts", ".tsx", ".js", ".jsx"] },
{ id: "pyright", binary: "pyright-langserver", extensions: [".py"] },
{ id: "rust-analyzer", binary: "rust-analyzer", extensions: [".rs"] },
{ id: "gopls", binary: "gopls", extensions: [".go"] },
]
export function getInstalledLspServers(): Array<{ id: string; extensions: string[] }> {
const servers = getAllServers()
export function getLspServersInfo(): LspServerInfo[] {
return DEFAULT_LSP_SERVERS.map((server) => ({
id: server.id,
installed: isServerInstalled([server.binary]),
extensions: server.extensions,
source: "builtin",
}))
}
export function getLspServerStats(servers: LspServerInfo[]): { installed: number; total: number } {
return {
installed: servers.filter((server) => server.installed).length,
total: servers.length,
}
return servers
.filter((s) => s.installed && !s.disabled)
.map((s) => ({ id: s.id, extensions: s.extensions }))
}
+5 -7
View File
@@ -1,6 +1,6 @@
import { checkAstGrepCli, checkAstGrepNapi, checkCommentChecker } from "./dependencies"
import { getGhCliInfo } from "./tools-gh"
import { getLspServerStats, getLspServersInfo } from "./tools-lsp"
import { getInstalledLspServers } from "./tools-lsp"
import { getBuiltinMcpInfo, getUserMcpInfo } from "./tools-mcp"
import { CHECK_IDS, CHECK_NAMES } from "../constants"
import type { CheckResult, DoctorIssue, ToolsSummary } from "../types"
@@ -13,14 +13,12 @@ export async function gatherToolsSummary(): Promise<ToolsSummary> {
getGhCliInfo(),
])
const lspServers = getLspServersInfo()
const lspStats = getLspServerStats(lspServers)
const lspServers = getInstalledLspServers()
const builtinMcp = getBuiltinMcpInfo()
const userMcp = getUserMcpInfo()
return {
lspInstalled: lspStats.installed,
lspTotal: lspStats.total,
lspServers,
astGrepCli: astGrepCliInfo.installed,
astGrepNapi: astGrepNapiInfo.installed,
commentChecker: commentCheckerInfo.installed,
@@ -57,7 +55,7 @@ function buildToolIssues(summary: ToolsSummary): DoctorIssue[] {
})
}
if (summary.lspInstalled === 0) {
if (summary.lspServers.length === 0) {
issues.push({
title: "No LSP servers detected",
description: "LSP-dependent tools will be limited until at least one server is installed.",
@@ -109,7 +107,7 @@ export async function checkTools(): Promise<CheckResult> {
details: [
`AST-Grep: cli=${summary.astGrepCli ? "yes" : "no"}, napi=${summary.astGrepNapi ? "yes" : "no"}`,
`Comment checker: ${summary.commentChecker ? "yes" : "no"}`,
`LSP: ${summary.lspInstalled}/${summary.lspTotal}`,
`LSP: ${summary.lspServers.length > 0 ? `${summary.lspServers.length} server(s)` : "none"}`,
`GH CLI: ${summary.ghCli.installed ? "installed" : "missing"}${summary.ghCli.authenticated ? " (authenticated)" : ""}`,
`MCP: builtin=${summary.mcpBuiltin.length}, user=${summary.mcpUser.length}`,
],