Skip to main content

knowledge-extension-ecosystem-lsp-code-intelligence

覆盖 Session 级 LSP 配置快照、stdio 进程、文档同步、语义查询、诊断回注、崩溃恢复 和子 Session 继承。进入条件:新增语言服务器、修改 LSP 工具、排查诊断缺失/重复、 处理 worktree 或 ACP 差异、修复进程泄漏或 transport 代际问题。不包含:VS Code 扩展桥接(见 ../../interaction-surfaces/vscode-bridge/)、通用进程管理(见 ../../tool-and-automation-platform/shell-process-and-worktree/)。关键词: LspSessionManager、LspClient、WorkspaceLspResources、publishDiagnostics、LSP。

Informations de source

Dépôt
echoVic/blade-code
Dernière activité de la source
26 août 2026 à 19:57
Langue détectée de SKILL.md
chinois
Étoiles
181
Forks
28

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
knowledge-extension-ecosystem-lsp-code-intelligence
description
覆盖 Session 级 LSP 配置快照、stdio 进程、文档同步、语义查询、诊断回注、崩溃恢复 和子 Session 继承。进入条件:新增语言服务器、修改 LSP 工具、排查诊断缺失/重复、 处理 worktree 或 ACP 差异、修复进程泄漏或 transport 代际问题。不包含:VS Code 扩展桥接(见 ../../interaction-surfaces/vscode-bridge/)、通用进程管理(见 ../../tool-and-automation-platform/shell-process-and-worktree/)。关键词: LspSessionManager、LspClient、WorkspaceLspResources、publishDiagnostics、LSP。
## Module Structure LSP 配置按 source project 解析并冻结,`SessionRuntime` 再以 execution workspace 创建私有 manager;语言服务器按目标文件扩展名懒启动,语义查询和写后诊断共享同一连接。 ### Directory Layout - `packages/cli/src/lsp/` — LSP client、Session manager 与 Workspace 资源快照 - `packages/cli/src/config/lspSettings.ts` — LSP server 配置规范化和硬边界 - `packages/cli/src/tools/builtin/lsp/` — ReadOnly LSP 工具与协议结果格式化 - `packages/cli/src/ide/` — IDE 检测和 Blade IDE 扩展安装入口 - `docs/reference/lsp-session-intelligence.md` — Session LSP 行为契约与资格要求 ### Key Entry Points - `resolveWorkspaceLspResources()` in `packages/cli/src/lsp/WorkspaceLspResources.ts` — 合并用户、项目和插件服务器并冻结快照 - `LspSessionManager.query()` in `packages/cli/src/lsp/LspSessionManager.ts` — 执行语义查询 - `LspSessionManager.afterToolUse()` in `packages/cli/src/lsp/LspSessionManager.ts` — 写后同步并回注新诊断 - `LspClient.start()` / `LspClient.stop()` in `packages/cli/src/lsp/LspClient.ts` — 管理 stdio JSON-RPC 与 owned process tree - `createLspTool()` in `packages/cli/src/tools/builtin/lsp/lsp.ts` — 将 manager 暴露为统一只读工具 ## API Surface ### Workspace LSP Resources - `resolveWorkspaceLspResources(projectRoot, base)` — 合并 Workspace 配置和插件 `.lsp.json` - `snapshotWorkspaceLspResources(resources)` — 规范化、深拷贝并冻结 Session 配置 ### LspSessionManager - `available` — 仅在存在启用服务器、Session 非 ACP remote 且未 dispose 时为真 - `query(input, signal)` — 路由 definition、references、hover、symbols、implementation、call hierarchy 或 diagnostics - `afterToolUse(toolName, params, result, context)` — 同步成功写操作并把新诊断追加到 ToolResult - `getStatus()` — 返回服务器状态、重启次数、扩展映射和最近错误 - `dispose()` — 解除 waiter、发送 shutdown/exit 并回收所有服务器进程 ### LspClient - `start(options)` / `initialize(params, timeout, signal)` — 建立 stdio transport 与协议握手 - `request(method, params, timeout, signal)` — 带 JSON-RPC cancellation 和本地 timeout 的请求 - `stop(timeout)` — 尝试协议关闭后以 owned process tree 作为最终回收边界 ## Usage Examples ### Session 创建私有 Manager (`packages/cli/src/agent/runtime/SessionRuntime.ts`) ```typescript this.lspManager = new LspSessionManager({ sessionId: this.sessionId, workspaceRoot: this.workspaceRoot, environment: this.sessionEnvironment, servers: this.lspResources.servers, }); ``` ### 工具成功后同步诊断 (`packages/cli/src/tools/execution/ToolExecutor.ts`) ```typescript await runPostToolUseHooks(tool, params, result, context, hookResult.toolUseId); if (context.signal?.aborted) return createCancellationResult(false); await this.lspManager?.afterToolUse(tool.name, params, result, context); ``` ### 子代理继承父 Session 快照 (`packages/cli/src/agent/subagents/SubagentExecutor.ts`) ```typescript runtime = await SessionRuntime.create({ sessionId: agentId, workspaceRoot, agentResources: this.agentResources, modelResources: this.modelResources, lspResources: this.lspResources, }); ``` ## Gotchas - ACP remote Session 即使带有 LSP 配置也不会启动宿主本地服务器,`query()` 会明确返回 remote-files unavailable;不能把 IDE 远端路径交给本地 realpath(`packages/cli/src/lsp/LspSessionManager.ts`) - 只要本地 Session 配置了至少一个启用服务器,`available` 就为真并关闭 AutoVerify fallback;服务器后续启动失败或没有覆盖某类文件时不会自动恢复 package-script 验证(`packages/cli/src/agent/runtime/SessionRuntime.ts`, `packages/cli/src/lsp/LspSessionManager.ts`) - 同一扩展名只选择一个 server,规则是 priority 降序、名称升序;配置多个同语言服务器不会并行聚合诊断或查询结果(`packages/cli/src/lsp/LspSessionManager.ts`) - `LSP` 工具接收 1-based line/character,manager 在发协议请求前转为 0-based;直接调用 manager API 时也应遵循工具侧 1-based 契约(`packages/cli/src/tools/builtin/lsp/lsp.ts`, `packages/cli/src/lsp/LspSessionManager.ts`) - 目标文件先 realpath 并验证位于 Session workspace 内;symlink 逃逸会拒绝,删除文件则通过最近存在祖先重建 canonical path 后再发送 didClose(`packages/cli/src/lsp/LspSessionManager.ts`) - 只有成功的 Write/Edit 和带标准 `metadata.changes` 的 ApplyPatch 会触发同步;失败结果、其他写工具或自定义 metadata 不会产生 didChange/didSave(`packages/cli/src/lsp/LspSessionManager.ts`) - 写后诊断在 PostToolUse Hook 之后、AutoVerify 之前追加到同一 ToolResult;Hook 看不到本次新 LSP 诊断,模型看到的最终结果则可以包含两者(`packages/cli/src/tools/execution/ToolExecutor.ts`) - 诊断按内容 hash 跨轮去重,每文件最多注入 10 条、单次最多 30 条;重复问题仍可通过显式 `diagnostics` 查询看到,但不会反复附加到写工具结果(`packages/cli/src/lsp/LspSessionManager.ts`) - server crash 只把状态设为 error 并清空 opened-files;真正重启发生在下一次相关查询或写同步,超过 `maxRestarts` 后 fail closed(`packages/cli/src/lsp/LspSessionManager.ts`) - 已 dispose transport 的迟到 child close 或 JSON-RPC close 必须被 identity guard 忽略,否则会把新 transport 错误标记为未初始化;该回归由独立代际测试锁定(`packages/cli/src/lsp/LspClient.ts`, `packages/cli/tests/unit/services/lsp-client.test.ts`, `git:8a29b24e`) - 只有 JSON-RPC `ContentModified` 会最多重试 4 次并做指数退避;timeout、abort、server error 和其他协议错误都直接返回(`packages/cli/src/lsp/LspSessionManager.ts`) - LSP 文件读取上限是 10 MiB,服务器 stderr 只保留前 64 KiB 且崩溃消息只带 512 字符预览;不能依赖完整 stderr 做长期诊断(`packages/cli/src/lsp/LspSessionManager.ts`, `packages/cli/src/lsp/LspClient.ts`) ## Architecture - Workspace 配置先与受信项目配置合并,再由 active plugins 按名称覆盖,最后通过 `normalizeLspServers()` 深拷贝并冻结;Session 不观察后续插件刷新(`packages/cli/src/lsp/WorkspaceLspResources.ts`, `packages/cli/src/config/lspSettings.ts`) - 每个 Session/server 拥有独立进程、connection、opened-file versions、diagnostics、waiters 和 restart count;同名服务器不会跨 Session 共享状态(`packages/cli/src/lsp/LspSessionManager.ts`, `packages/cli/tests/integration/lsp-session-manager.test.ts`) - 文档首次访问发送 didOpen version 1,后续写入发送全量 didChange、didSave 并短暂等待新的 diagnostics sequence;删除发送 didClose 并清除缓存(`packages/cli/src/lsp/LspSessionManager.ts`) - LspClient 使用 `spawnOwnedProcess()` 启动不经 shell 的命令参数,优先协议 shutdown/exit,最终以进程树终止保证子进程不残留(`packages/cli/src/lsp/LspClient.ts`) ## Decisions - LSP 采用 Session 私有而非进程共享架构,是为了让 worktree、并行 Session、子代理和不同环境变量拥有确定的文档版本与诊断状态(`packages/cli/src/lsp/LspSessionManager.ts`, `git:8a878e32`) - 配置规范化拒绝未知字段并对服务器数、参数、扩展、JSON options、timeout 和 restart 设置硬上限,避免插件或项目配置创建无界运行时(`packages/cli/src/config/lspSettings.ts`) - LSP 工具标记为 ReadOnly、并发安全和可重试,但写后诊断属于 ToolExecutor side effect;新增语义操作应走 manager/query,而不是绕过 Session 生命周期直连 client(`packages/cli/src/tools/builtin/lsp/lsp.ts`, `packages/cli/src/tools/execution/ToolExecutor.ts`) ## Patterns - extension key 统一转小写并补 `.`,同一文件的语言 ID 来自被选 server 的 `extensionToLanguage`;插件服务器名称在加载时加 `plugin:<name>:` 前缀(`packages/cli/src/config/lspSettings.ts`, `packages/cli/src/plugins/PluginLoader.ts`) - request timeout 与 turn abort 都映射为 JSON-RPC cancellation,dispose 还会解析所有 diagnostics waiter,避免 Session 结束后留下等待 Promise(`packages/cli/src/lsp/LspClient.ts`, `packages/cli/src/lsp/LspSessionManager.ts`) ## Consumer Analysis - `packages/cli/src/agent/runtime/SessionRuntime.ts` — 持有不可变配置、创建 manager、决定 LSP 与 AutoVerify 二选一并负责最终 dispose(`packages/cli/src/agent/runtime/SessionRuntime.ts`) - `packages/cli/src/tools/execution/ToolExecutor.ts` — 在 PostToolUse 后调用 `afterToolUse()`,把增量诊断并入最终工具结果(`packages/cli/src/tools/execution/ToolExecutor.ts`) - `packages/cli/src/tools/builtin/index.ts` — 仅当 manager 可用时注册 LSP 工具,避免暴露必然失败的 schema(`packages/cli/src/tools/builtin/index.ts`) - `packages/cli/src/agent/subagents/SubagentExecutor.ts` 与 `packages/cli/src/agent/teams/TeamRuntime.ts` — 将父级 LSP 资源快照传给新 Runtime,但每个 child 仍创建独立进程与诊断状态(`packages/cli/src/agent/subagents/SubagentExecutor.ts`, `packages/cli/src/agent/teams/TeamRuntime.ts`) - `packages/cli/src/plugins/PluginLoader.ts` — 读取 `.lsp.json`、展开 immutable plugin root 并命名空间化服务器;实际进程仍由 Session manager 延迟启动(`packages/cli/src/plugins/PluginLoader.ts`, `packages/cli/tests/unit/services/plugin-lsp-loader.test.ts`)
Voir sur GitHub