Download src/plugins/bundle-lsp.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 5.31 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/plugins/bundle-lsp.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/plugins/bundle-lsp.ts
-
curl -L -o bundle-lsp.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/plugins/bundle-lsp.ts
5.31 kB
| // Bundles language-server metadata exposed by plugins. | |
| import path from "node:path"; | |
| import { applyMergePatch } from "../config/merge-patch.js"; | |
| import type { OpenClawConfig } from "../config/types.openclaw.js"; | |
| import { isRecord } from "../utils.js"; | |
| import { | |
| inspectBundleServerRuntimeSupport, | |
| loadEnabledBundleConfig, | |
| readBundleJsonObject, | |
| resolveBundleJsonOpenFailure, | |
| } from "./bundle-config-shared.js"; | |
| import { | |
| CLAUDE_BUNDLE_MANIFEST_RELATIVE_PATH, | |
| mergeBundlePathLists, | |
| normalizeBundlePathList, | |
| } from "./bundle-manifest.js"; | |
| import type { PluginManifestRegistry } from "./manifest-registry.js"; | |
| import type { PluginBundleFormat } from "./manifest-types.js"; | |
| import { pluginCacheExistsSync } from "./plugin-cache-files.js"; | |
| /** LSP server config block loaded from plugin bundle metadata. */ | |
| export type BundleLspServerConfig = Record<string, unknown>; | |
| /** Merged LSP config contributed by enabled plugin bundles. */ | |
| type BundleLspConfig = { | |
| lspServers: Record<string, BundleLspServerConfig>; | |
| }; | |
| /** Runtime support summary for bundle-declared LSP servers. */ | |
| type BundleLspRuntimeSupport = { | |
| hasStdioServer: boolean; | |
| supportedServerNames: string[]; | |
| unsupportedServerNames: string[]; | |
| diagnostics: string[]; | |
| }; | |
| const MANIFEST_PATH_BY_FORMAT: Partial<Record<PluginBundleFormat, string>> = { | |
| claude: CLAUDE_BUNDLE_MANIFEST_RELATIVE_PATH, | |
| }; | |
| function extractLspServerMap(raw: unknown): Record<string, BundleLspServerConfig> { | |
| if (!isRecord(raw)) { | |
| return {}; | |
| } | |
| const nested = isRecord(raw.lspServers) ? raw.lspServers : raw; | |
| if (!isRecord(nested)) { | |
| return {}; | |
| } | |
| const result: Record<string, BundleLspServerConfig> = {}; | |
| for (const [serverName, serverRaw] of Object.entries(nested)) { | |
| if (!isRecord(serverRaw)) { | |
| continue; | |
| } | |
| result[serverName] = { ...serverRaw }; | |
| } | |
| return result; | |
| } | |
| function resolveBundleLspConfigPaths(params: { | |
| raw: Record<string, unknown>; | |
| rootDir: string; | |
| }): string[] { | |
| const declared = normalizeBundlePathList(params.raw.lspServers); | |
| const defaults = pluginCacheExistsSync(path.join(params.rootDir, ".lsp.json")) | |
| ? [".lsp.json"] | |
| : []; | |
| return mergeBundlePathLists(defaults, declared); | |
| } | |
| function loadBundleLspConfigFile(params: { rootDir: string; relativePath: string }): { | |
| config: BundleLspConfig; | |
| diagnostics: string[]; | |
| } { | |
| const result = readBundleJsonObject({ | |
| rootDir: params.rootDir, | |
| relativePath: params.relativePath, | |
| onOpenFailure: (failure) => | |
| resolveBundleJsonOpenFailure({ | |
| failure, | |
| relativePath: params.relativePath, | |
| allowMissing: true, | |
| }), | |
| }); | |
| if (!result.ok) { | |
| return { | |
| config: { lspServers: {} }, | |
| diagnostics: [ | |
| result.reason === "open" | |
| ? result.error | |
| : `unable to read ${params.relativePath}: ${result.error}`, | |
| ], | |
| }; | |
| } | |
| return { config: { lspServers: extractLspServerMap(result.raw) }, diagnostics: [] }; | |
| } | |
| function loadBundleLspConfig(params: { | |
| pluginId: string; | |
| rootDir: string; | |
| bundleFormat: PluginBundleFormat; | |
| }): { config: BundleLspConfig; diagnostics: string[] } { | |
| const manifestRelativePath = MANIFEST_PATH_BY_FORMAT[params.bundleFormat]; | |
| if (!manifestRelativePath) { | |
| return { config: { lspServers: {} }, diagnostics: [] }; | |
| } | |
| const manifestLoaded = readBundleJsonObject({ | |
| rootDir: params.rootDir, | |
| relativePath: manifestRelativePath, | |
| }); | |
| if (!manifestLoaded.ok) { | |
| return { config: { lspServers: {} }, diagnostics: [manifestLoaded.error] }; | |
| } | |
| let merged: BundleLspConfig = { lspServers: {} }; | |
| const filePaths = resolveBundleLspConfigPaths({ | |
| raw: manifestLoaded.raw, | |
| rootDir: params.rootDir, | |
| }); | |
| const diagnostics: string[] = []; | |
| for (const relativePath of filePaths) { | |
| const loaded = loadBundleLspConfigFile({ | |
| rootDir: params.rootDir, | |
| relativePath, | |
| }); | |
| diagnostics.push(...loaded.diagnostics); | |
| merged = applyMergePatch(merged, loaded.config) as BundleLspConfig; | |
| } | |
| return { config: merged, diagnostics }; | |
| } | |
| /** Inspects whether one plugin bundle has supported LSP runtime servers. */ | |
| export function inspectBundleLspRuntimeSupport(params: { | |
| pluginId: string; | |
| rootDir: string; | |
| bundleFormat: PluginBundleFormat; | |
| }): BundleLspRuntimeSupport { | |
| const support = inspectBundleServerRuntimeSupport({ | |
| loaded: loadBundleLspConfig(params), | |
| resolveServers: (config) => config.lspServers, | |
| }); | |
| return { | |
| hasStdioServer: support.hasSupportedServer, | |
| supportedServerNames: support.supportedServerNames, | |
| unsupportedServerNames: support.unsupportedServerNames, | |
| diagnostics: support.diagnostics, | |
| }; | |
| } | |
| /** Loads and merges enabled bundle LSP config across plugin manifests. */ | |
| export function loadEnabledBundleLspConfig(params: { | |
| workspaceDir: string; | |
| cfg?: OpenClawConfig; | |
| manifestRegistry?: Pick<PluginManifestRegistry, "plugins">; | |
| }): { config: BundleLspConfig; diagnostics: Array<{ pluginId: string; message: string }> } { | |
| return loadEnabledBundleConfig({ | |
| workspaceDir: params.workspaceDir, | |
| cfg: params.cfg, | |
| manifestRegistry: params.manifestRegistry, | |
| createEmptyConfig: () => ({ lspServers: {} }), | |
| loadBundleConfig: loadBundleLspConfig, | |
| createDiagnostic: (pluginId, message) => ({ pluginId, message }), | |
| }); | |
| } | |