dsh-lsp-diagnostics
v0.1.1
Published
Real-time LSP diagnostics for DeepSeek Harness — model-visible lsp_diagnostics / lsp_workspace_errors / lsp_hover tools plus an auto-injected post-edit diagnostics section, closing the edit → diagnostics → fix loop.
Maintainers
Readme
dsh-lsp-diagnostics
English | 中文
实时编译器/LSP 诊断 — DeepSeek Harness(dsh)插件,闭合 编辑 → 诊断 → 修复 循环:模型改完文件,立刻看到哪里坏了(file:line:col + 错误码 + 消息),然后修掉。这是 Cursor 的杀手级特性,现在 dsh agent 也有。
模型获得什么
| 工具 | 用途 |
|---|---|
| lsp_diagnostics | 当前某个文件(或所有已见文件)的诊断,可按严重级别过滤、限量截断。编辑完文件后立刻调用。 |
| lsp_workspace_errors | 整个工作区的全部错误 — "现在到底哪里坏了"视图。 |
| lsp_hover | 某个位置的类型/签名信息(辅助工具)。 |
外加一个可选的自动注入系统提示词段落(lsp:diagnostics,order 70):模型通过 harness 写入/编辑文件后,插件订阅 fs/observed 事件,在语言服务器上刷新该文件,只注入本次编辑新增/变化的诊断 — 绝不灌入整个工作区。过期的增量会失效(sectionTtlMs,默认 30 秒)。设置 autoInject: false 可关闭,仅靠工具调用。
闭环示意
模型编辑文件 ──► dsh 写盘(fs 工具)
│
▼ fs/observed 事件
插件在对应 LSP 服务器上刷新该文件
│
▼ publishDiagnostics
增量注入提示词(或按需调用 lsp_diagnostics)
│
▼
模型读到 "src/a.ts:12:3 error TS2322 …" ──► 修复安装
需要 dsh(npx、npm 或源码安装均可)、Node ≥ 22,以及 PATH 上的 LSP 服务器:
npm i -g typescript-language-server typescript
npm i -g pyright两个服务器都可以用 npm 安装 — 无需 Python 运行时,没有原生二进制。
# 从 npm(预构建)
npx @deepseek-ai/dsh plugin --profile web add dsh-lsp-diagnostics
# 或从包含本仓库的目录
npx @deepseek-ai/dsh plugin --profile web add ./dsh-lsp-diagnostics重启 Web UI(npx @deepseek-ai/dsh web)— 启动日志会确认每个工具注册:
[dsh-lsp-diagnostics] plugin loaded
[dsh-lsp-diagnostics] registered tool: lsp_diagnostics
...缺服务器?工具会明确告诉你,并附上安装命令:LSP server "pyright-langserver" is not installed or failed to start. Install it with: npm i -g pyright。
使用
在工作区会话里对 agent 说:
- "把
src/extract.ts里的解析器拆出来,然后用 lsp_diagnostics 检查一下。" - "现在工作区里有什么是坏的?"(
lsp_workspace_errors) - "121 行的
code是什么类型?"(lsp_hover)
示例(输入 → 输出):
lsp_diagnostics { file: "src/extract.ts" }
# diagnostics (3 errors, 1 warning)
src/extract.ts:121:10 error TS2304 Cannot find name 'foo'
src/extract.ts:144:3 error TS2322 Type 'string' is not assignable to 'number'
src/store.ts:8:5 warn TS6133 'x' is declared but never usedexecute 返回的是规范化 JSON(severity、range、code、message、source);上面这张紧凑表格是渲染后的视图。
配置
配置以插件行 config 的形式传入 profile patch(缺省用默认值):
# $DSH_HOME/profiles/<name>/cordis.patch.yml — 裸行按 id 覆盖。
- id: lsp-diagnostics
config:
maxDiagnostics: 30
autoInject: true| 键 | 默认 | 含义 |
|---|---|---|
| autoInject | true | 注册自动注入的诊断段落(及 fs/observed 监听) |
| maxDiagnostics | 50 | 工具输出与注入段落的诊断硬上限(token 成本护栏) |
| languages | ['typescript','javascript','python'] | 启动哪些语言的服务器;TS 与 JS 共用一个服务器 |
| serverPath | {} | 按服务器覆盖二进制路径({typescript: …, python: …});以 .js/.mjs/.cjs 结尾的路径用当前 Node 运行 |
| sectionTtlMs | 30000 | 注入的增量保持"新鲜"的时长(最小 1000) |
支持的语言
- TypeScript / JavaScript:
typescript-language-server(.ts .tsx .mts .cts .js .jsx .mjs .cjs) - Python:
pyright-langserver(.py .pyi)
Rust(rust-analyzer 是原生二进制)有意推迟 — servers.ts 就是后续服务器接入的接缝(command、args、安装提示)。
工作原理
- LSP 客户端(
src/lspClient.ts):每个服务器进程一个无头 JSON-RPC 客户端(stdio),只依赖vscode-languageserver-protocol+vscode-jsonrpc(无 VS Code 依赖)。initialize/initialized握手 → 全文didOpen/didChange同步 → 订阅publishDiagnostics→ 干净的shutdown/exit/kill 拆除。 - 生命周期(
src/manager.ts):每个(工作区根,语言)一个服务器,首次使用时懒启动。崩溃的服务器重启一次(自动重放已打开的文档);再次崩溃则把该语言标记为 degraded 并给出清晰消息,不做无限重启循环。插件卸载时杀掉所有已生成的服务器(有生命周期测试验证)。 - 编辑检测(
src/section.ts):订阅 harness 的fs/observed事件(@deepseek-ai/dsh-tool-fs在 read/write/edit 成功后发出)。监听器只把文件入队(同步、绝不抛错);去抖后的刷新会把新诊断与该文件此前状态做差分,渲染出增量。 - 工作区解析:会话 cwd → 向上走到最近的
.git(有界),与 dsh-code-index 相同。仓库之外的文件会被拒绝。 - Token 成本意识:所有出口 — 工具输出与注入段落 — 都受
maxDiagnostics硬约束;注入的是单次编辑的增量,而不是整个工作区。
已知限制
lsp_workspace_errors只覆盖服务器本会话见过的文件(文件第一次被lsp_diagnostics检查时加入集合)— 标准 LSP 打开文件语义,不是全仓库批量扫描。- TypeScript 7(Go 原生版)没有
lib/tsserver.js;工作区里请保证typescript@5可解析(工作区不固定版本时,typescript-language-server 会回退到它自带的 5.x)。 - 自动注入依赖 harness 的文件事件;用户在 harness 之外直接改文件不会被观察到,直到调用工具。
- 服务器必须在
PATH上(或通过serverPath覆盖);本插件按设计不捆绑任何服务器。 - 开发者预览版 harness:上游 harness/插件 API 可能出现破坏性变更。
开发
pnpm install
pnpm test # vitest — 对着假 LSP 服务器测握手/映射/工具/生命周期
pnpm typecheck
pnpm build # tsup → dist/index.js(ESM,外部依赖)测试套件基于 tests/helpers/fakeLspServer.mjs — 一个极简 stdio LSP 服务器,从 // diag: <severity> <code> <message> 标记生成诊断 — 因此 CI 无需真实的 pyright/tsserver。
反馈
发现 bug,或者想要下一个服务器/语言?请提 issue。
许可
MIT。与 DeepSeek 无隶属关系;构建于公开的 dsh 插件接口之上。
