dsh-lsp-actions 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/LICENSE +201 -0
  3. package/README.es.md +177 -0
  4. package/README.hi.md +177 -0
  5. package/README.md +183 -0
  6. package/README.pt.md +177 -0
  7. package/README.zh-CN.md +181 -0
  8. package/cordis.patch.yml +17 -0
  9. package/lib/abort.d.ts +13 -0
  10. package/lib/abort.d.ts.map +1 -0
  11. package/lib/abort.js +31 -0
  12. package/lib/abort.js.map +1 -0
  13. package/lib/client.d.ts +173 -0
  14. package/lib/client.d.ts.map +1 -0
  15. package/lib/client.js +926 -0
  16. package/lib/client.js.map +1 -0
  17. package/lib/connection.d.ts +103 -0
  18. package/lib/connection.d.ts.map +1 -0
  19. package/lib/connection.js +241 -0
  20. package/lib/connection.js.map +1 -0
  21. package/lib/edits.d.ts +17 -0
  22. package/lib/edits.d.ts.map +1 -0
  23. package/lib/edits.js +76 -0
  24. package/lib/edits.js.map +1 -0
  25. package/lib/extension.d.ts +9 -0
  26. package/lib/extension.d.ts.map +1 -0
  27. package/lib/extension.js +17 -0
  28. package/lib/extension.js.map +1 -0
  29. package/lib/extra-tools.d.ts +45 -0
  30. package/lib/extra-tools.d.ts.map +1 -0
  31. package/lib/extra-tools.js +406 -0
  32. package/lib/extra-tools.js.map +1 -0
  33. package/lib/framing.d.ts +33 -0
  34. package/lib/framing.d.ts.map +1 -0
  35. package/lib/framing.js +80 -0
  36. package/lib/framing.js.map +1 -0
  37. package/lib/host.d.ts +64 -0
  38. package/lib/host.d.ts.map +1 -0
  39. package/lib/host.js +152 -0
  40. package/lib/host.js.map +1 -0
  41. package/lib/index.d.ts +42 -0
  42. package/lib/index.d.ts.map +1 -0
  43. package/lib/index.js +78 -0
  44. package/lib/index.js.map +1 -0
  45. package/lib/render.d.ts +364 -0
  46. package/lib/render.d.ts.map +1 -0
  47. package/lib/render.js +485 -0
  48. package/lib/render.js.map +1 -0
  49. package/lib/runner.d.ts +55 -0
  50. package/lib/runner.d.ts.map +1 -0
  51. package/lib/runner.js +149 -0
  52. package/lib/runner.js.map +1 -0
  53. package/lib/sandbox.d.ts +69 -0
  54. package/lib/sandbox.d.ts.map +1 -0
  55. package/lib/sandbox.js +98 -0
  56. package/lib/sandbox.js.map +1 -0
  57. package/lib/seam.d.ts +67 -0
  58. package/lib/seam.d.ts.map +1 -0
  59. package/lib/seam.js +62 -0
  60. package/lib/seam.js.map +1 -0
  61. package/lib/servers.d.ts +120 -0
  62. package/lib/servers.d.ts.map +1 -0
  63. package/lib/servers.js +216 -0
  64. package/lib/servers.js.map +1 -0
  65. package/lib/session-cwd.d.ts +15 -0
  66. package/lib/session-cwd.d.ts.map +1 -0
  67. package/lib/session-cwd.js +16 -0
  68. package/lib/session-cwd.js.map +1 -0
  69. package/lib/tools.d.ts +150 -0
  70. package/lib/tools.d.ts.map +1 -0
  71. package/lib/tools.js +543 -0
  72. package/lib/tools.js.map +1 -0
  73. package/lib/translate.d.ts +181 -0
  74. package/lib/translate.d.ts.map +1 -0
  75. package/lib/translate.js +715 -0
  76. package/lib/translate.js.map +1 -0
  77. package/lib/vocabulary.d.ts +167 -0
  78. package/lib/vocabulary.d.ts.map +1 -0
  79. package/lib/vocabulary.js +20 -0
  80. package/lib/vocabulary.js.map +1 -0
  81. package/package.json +95 -0
@@ -0,0 +1,181 @@
1
+ <div align="center">
2
+
3
+ # 🛰️ dsh-lsp-actions
4
+
5
+ **DeepSeek Harness 的 LSP 动作面 —— 真实的语言服务器,真实的反馈。**
6
+
7
+ 为你的 agent 编辑循环提供诊断、格式化、补全、快速修复、符号、签名提示与内联提示,驱动它们的正是你 IDE 所用的那些语言服务器。
8
+
9
+ [![Topic: dsh](https://img.shields.io/badge/Topic-dsh-4D6BFE?style=for-the-badge)](https://github.com/topics/dsh)
10
+ [![Topic: dsh-plugin](https://img.shields.io/badge/Topic-dsh--plugin-8257D0?style=for-the-badge)](https://github.com/topics/dsh-plugin)
11
+ [![License](https://img.shields.io/badge/License-Apache%202.0-D22128?style=flat-square)](LICENSE)
12
+ [![Node](https://img.shields.io/badge/Node-%5E22.19%20%7C%7C%20%3E%3D24-43853D?style=flat-square)](package.json)
13
+
14
+ [English](README.md) · [简体中文](README.zh-CN.md) · [Español](README.es.md) · [हिन्दी](README.hi.md) · [Português](README.pt.md)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## 这个插件给 agent 带来什么
21
+
22
+ 官方 DeepSeek Harness 的 `ctx.lsp` seam 只覆盖**导航**(跳转定义、引用、实现、悬停)。`dsh-lsp-actions` 补齐了**动作面** —— agent 写代码和修代码时需要的反馈闭环:
23
+
24
+ | 工具 | 做什么 | 写盘? |
25
+ | --- | --- | --- |
26
+ | `lsp_diagnostics <file>` | 编译器/分析器的错误、警告与提示(含严重级、范围、消息与来源服务器) | ❌ 只读 |
27
+ | `lsp_format <file> [range?]` | 通过语言服务器格式化文件或选区并写入,返回 diff | ✅ 走 `fs/write-intent` + 沙箱策略 |
28
+ | `lsp_completion <file> <line> <character>` | 光标处的补全建议,含实际插入文本 | ❌ 只读 |
29
+ | `lsp_code_action <file> [range?] [only?]` | 服务器验证过的快速修复/重构(含其编辑) | ❌ 仅参考 |
30
+ | `lsp_symbols <query?> <file_path?>` | 按名字全局搜索符号,或列出单个文件的符号大纲 | ❌ 只读 |
31
+ | `lsp_signature <file> <line> <character>` | 调用点处的签名提示(参数与文档) | ❌ 只读 |
32
+ | `lsp_inlay_hints <file> [range?]` | 服务器的类型标注与参数名提示 | ❌ 只读 |
33
+ | `lsp_rename <file> <line> <character> <new_name>` | 服务器验证过的符号重命名,跨工作区应用并返回逐文件 diff | ✅ 走 `fs/write-intent` + 沙箱策略 |
34
+
35
+ > ✨ 测试套件包含一次真实的 `typescript-language-server` 运行:诊断、格式化、补全、符号搜索与重命名都是对着活服务器端到端验证的,而非只有 mock。套件自包含(tsls 是 devDependency),并在 CI 中以 Node 22/24 × Linux/Windows/macOS 矩阵运行。
36
+
37
+ ## 快速开始
38
+
39
+ ```sh
40
+ dsh plugin --profile <name> add <path-or-tarball-of-dsh-lsp-actions>
41
+ ```
42
+
43
+ 每个语言服务器配一条 entry(形态与官方 `lsp-stdio` 配置一致):
44
+
45
+ ```yaml
46
+ # 写在 profile 的 cordis.patch.yml(或 bundle 行)里
47
+ - insert:
48
+ - id: lsp-actions
49
+ name: dsh-lsp-actions
50
+ inject: [tools, fs, subprocess]
51
+ config:
52
+ servers:
53
+ ts:
54
+ command: typescript-language-server
55
+ args: [--stdio]
56
+ extensionToLanguage:
57
+ ".ts": typescript
58
+ formattingOptions: { tabSize: 2, insertSpaces: true }
59
+ py:
60
+ command: pyright-langserver
61
+ args: [--stdio]
62
+ extensionToLanguage:
63
+ ".py": python
64
+ maxDiagnostics: 200
65
+ maxCompletionItems: 20
66
+ maxCodeActions: 50
67
+ maxSymbols: 100
68
+ maxSignatures: 10
69
+ maxInlayHints: 200
70
+ maxResultChars: 16000
71
+ timeoutMs: 60000
72
+ ```
73
+
74
+ 八个工具**始终注册**。当 `servers` 表为空且没有挂载 `ctx.lsp` seam 时,调用会**响亮失败**(`LSP_ACTION_UNAVAILABLE`,错误信息指明该配置什么)—— 插件绝不会启动你没有配置的服务器。**在插件之后**挂载的 `ctx.lsp` seam 会在下一次调用时被识别(seam 探测按调用惰性解析,加载顺序无关)。
75
+
76
+ ## 为什么按构造就安全
77
+
78
+ - **格式化与重命名是真实写入,按 `write`/`edit` 同等对待。** 每个字节都经过 `fs/write-intent` waterfall(观测 → 守卫写 → 观测)与每次调用的沙箱策略。`lsp_rename` 会在第一笔写入**之前**对每个待改文件做预检(工作区包含性、重叠检查、字节上限读取),坏服务器响应不可能留下写了一半的重命名。
79
+ - **其余一切按设计只读。** 代码动作、补全、符号、签名与提示都作为参考材料返回;应用它们由模型自行决定用 write/edit 完成。命令形态只报告、**绝不执行**。
80
+ - **只读会话响亮、快速、结构化地失败** —— 在任何服务器往返之前抛出带共享 `[sandbox: …]` 标记的 `LSP_ACTION_READ_ONLY`。
81
+ - **升级路径与官方工具一致。** 在受限文件系统下,`lsp_format` 与 `lsp_rename` 广告与 `write`/`edit` 相同的 `sandbox_permissions` / `justification` 一次性重试,经 `ctx.approval` 裁决。
82
+ - **冲突绝不覆盖。** 若文件在读后被改动,守卫写以 `LSP_ACTION_CONFLICT` 失败,并让模型二选一:重读后重跑,或手工应用 diff。
83
+ - **超时是平台职责。** 每个工具声明 `timeoutMs`,由官方 `dsh-tool-call-timeout-policy` 执行,所有 await 尊重 `exec.signal`。
84
+ - **不缓存任何东西。** 结果只存在于会话日志,无跨会话持久化。
85
+ - **坏服务器响亮失败。** 命令缺失在加载期即失败;启动即死的服务器以 `LSP_ACTION_SERVER_FAILED` + stderr 尾部失败(启动失败先自动换新进程重试一次)。
86
+
87
+ ## 架构
88
+
89
+ 动作**优先走官方 seam**,未命中则回落插件自带的最小 stdio 客户端:
90
+
91
+ ```
92
+ lsp_diagnostics / lsp_format / lsp_completion / lsp_code_action /
93
+ lsp_symbols / lsp_signature / lsp_inlay_hints / lsp_rename
94
+ │
95
+ ▼
96
+ ctx.lsp seam(扩展后:diagnostics / formatDocument / completion)
97
+ │ 缺席 · 旧版 · 该文件无 provider
98
+ ▼
99
+ 内置 stdio 客户端 ← servers 表(ctx.subprocess.spawn + JSON-RPC)
100
+ ```
101
+
102
+ seam 扩展已向上游提案(`upstream/lsp-action-seam.patch`,PR 描述见 `upstream/PR-description.md`)。合入后插件无需改动即自动迁移 —— 内置客户端停止被使用即可。内置客户端会保留为 `servers` 表的独立兜底。完整调研与设计笔记:[`docs/seam-extension-notes.md`](docs/seam-extension-notes.md)、[`upstream/README.md`](upstream/README.md)。
103
+
104
+ ## 配置参考
105
+
106
+ ```ts
107
+ interface Config {
108
+ /** 命名的语言服务器;为空 = 插件自带客户端不服务任何文件。 */
109
+ servers?: Record<string, LspServerEntry>
110
+ maxDiagnostics?: number // 默认 200
111
+ maxCompletionItems?: number // 默认 20
112
+ maxCodeActions?: number // 默认 50
113
+ maxSymbols?: number // 默认 100
114
+ maxSignatures?: number // 默认 10
115
+ maxInlayHints?: number // 默认 200
116
+ maxResultChars?: number // 默认 16000(完整渲染结果上限)
117
+ maxDocumentBytes?: number // 默认 4000000
118
+ timeoutMs?: number // 默认 60000(由官方超时策略执行)
119
+ }
120
+
121
+ interface LspServerEntry {
122
+ command: string // 可执行文件,加载期在 PATH 上解析
123
+ extensionToLanguage: Record<string, string> // ".ts" → "typescript"
124
+ fileGlobs?: string[] // 可选;glob 命中优先于扩展名映射
125
+ args?: string[] // 不经 shell
126
+ env?: Record<string, string>
127
+ initializationOptions?: unknown
128
+ configuration?: unknown // 对象形态按 section 应答 workspace/configuration
129
+ formattingOptions?: unknown // 例如 { tabSize: 2, insertSpaces: true }
130
+ maxMessageBytes?: number // 默认 16000000
131
+ maxStderrBytes?: number // 默认 1000000
132
+ killGraceMs?: number // 默认 2000
133
+ shutdownTimeoutMs?: number // 默认 5000
134
+ diagnosticsSettleMs?: number // 默认 2000(仅推送诊断的收集窗口)
135
+ diagnosticsDebounceMs?: number // 默认 250(最后一批推送后的安静期)
136
+ idleTimeoutMs?: number // 默认 0(0 = 服务器进程常驻)
137
+ }
138
+ ```
139
+
140
+ ### 错误码
141
+
142
+ 每个失败都在错误结果上携带稳定 `code`;模型与调用方按 code 路由,绝不解析消息文本。
143
+
144
+ | Code | 含义 |
145
+ | --- | --- |
146
+ | `LSP_ACTION_UNAVAILABLE` | 没有服务器 entry、seam provider 也不处理该文件。 |
147
+ | `LSP_ACTION_UNSUPPORTED` | 服务器(或 seam provider)未广告该操作。 |
148
+ | `LSP_ACTION_SERVER_FAILED` | 服务器失败(附 stderr 尾部);启动失败重试一次。 |
149
+ | `LSP_ACTION_MALFORMED_RESPONSE` | 服务器返回了结构非法的负载。 |
150
+ | `LSP_ACTION_CONFLICT` | 文件读后已变,或服务器返回的编辑重叠/越界/越出工作区。 |
151
+ | `LSP_ACTION_READ_ONLY` | 会话沙箱模式禁止格式化/重命名写入。 |
152
+ | `LSP_ACTION_WORKSPACE_REQUIRED` | 调用会话没有可扎根的 workspace cwd。 |
153
+ | `LSP_ACTION_NO_SYMBOL` | 服务器在光标位置找不到可重命名的符号。 |
154
+
155
+ ### 宿主版本支持
156
+
157
+ 插件把 DeepSeek Harness 各包声明为 **peerDependencies**(`@deepseek-ai/dsh-fs`、`dsh-llm`、`dsh-sandbox`、`dsh-subprocess`、`dsh-tools` ≥ `0.1.0-rc.6`),宿主与插件共享同一份副本。已在 `0.1.0-rc.6` 上实测。
158
+
159
+ ### 已知限制
160
+
161
+ - **瞬态文档。** 每次动作都是打开文件 → 发一个请求 → 关闭文件(与官方 stdio host 一致)。依赖常驻打开文件的基于项目的服务器(tsls 在无打开文档时拒绝 `workspace/symbol`)可通过给 `lsp_symbols` 传 `file_path` 解决 —— 插件会在该请求期间保持路由文件打开。tsls 在该生命周期下对 `textDocument/signatureHelp` 返回 `null`;其他服务器(gopls、pyright、rust-analyzer)正常应答。
162
+ - **范围格式化要求服务器广告 range provider。** 只广告全文格式化的服务器对范围请求以 `LSP_ACTION_UNSUPPORTED` 失败。
163
+ - **重命名只应用文本编辑。** 服务器重命名结果中的资源操作(新建/删除/重命名文件)以 `LSP_ACTION_UNSUPPORTED` 拒绝;越出工作区的编辑在任何写入发生前以 `LSP_ACTION_CONFLICT` 失败。在 `utf-8`/`utf-32` 服务器上,跨文件重命名位置通过逐个读取被编辑文件来解码;被编辑文件不可读时以冲突失败,绝不错误解码位置。
164
+
165
+ ## 开发
166
+
167
+ ```sh
168
+ pnpm install
169
+ pnpm run lint # oxlint 检查 src/ 与 tests/
170
+ pnpm test # 240+ 测试:单元 + fixture 服务器集成 + 真实 tsls e2e
171
+ pnpm run test:coverage # 门禁:行/语句/函数 ≥ 90%,分支 ≥ 85%
172
+ pnpm build # 产出 lib/
173
+ ```
174
+
175
+ ### 发布
176
+
177
+ CI 在每次推送与 PR 上运行 lint/构建/测试矩阵 + 覆盖率门禁。推送 `v*` tag 会触发发布工作流:先验证全套测试再发布到 npm —— 需要在仓库里一次性配置 `NPM_TOKEN` Actions secret(发布权限的 npm access token)。版本号在打 tag 前于 `package.json` / `CHANGELOG.md` 中手动提升。
178
+
179
+ ## License
180
+
181
+ [Apache License 2.0](LICENSE)
@@ -0,0 +1,17 @@
1
+ # LSP action surface: diagnostics, formatting, completion, code actions, symbols, signature
2
+ # help, inlay hints, and rename over language servers.
3
+ # Default config activates no servers (empty table); add one entry per language server.
4
+ - insert:
5
+ - id: lsp-actions
6
+ name: dsh-lsp-actions
7
+ inject: [tools, fs, subprocess]
8
+ config:
9
+ servers: {}
10
+ maxDiagnostics: 200
11
+ maxCompletionItems: 20
12
+ maxCodeActions: 50
13
+ maxSymbols: 100
14
+ maxSignatures: 10
15
+ maxInlayHints: 200
16
+ maxResultChars: 16000
17
+ timeoutMs: 60000
package/lib/abort.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Abort helpers: race any promise against a signal, and throw the signal's reason once it fires.
3
+ * @module dsh-lsp-actions/abort
4
+ */
5
+ /**
6
+ * Race `promise` against `signal`; the returned promise rejects with the signal's reason the
7
+ * moment it aborts, without disturbing the underlying promise's own settlement.
8
+ * @param promise - the work to race.
9
+ * @param signal - optional cancellation; undefined returns the promise unchanged.
10
+ * @returns the raced promise.
11
+ */
12
+ export declare function abortable<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;
13
+ //# sourceMappingURL=abort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort.d.ts","sourceRoot":"","sources":["../src/abort.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAoB7F"}
package/lib/abort.js ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Abort helpers: race any promise against a signal, and throw the signal's reason once it fires.
3
+ * @module dsh-lsp-actions/abort
4
+ */
5
+ /**
6
+ * Race `promise` against `signal`; the returned promise rejects with the signal's reason the
7
+ * moment it aborts, without disturbing the underlying promise's own settlement.
8
+ * @param promise - the work to race.
9
+ * @param signal - optional cancellation; undefined returns the promise unchanged.
10
+ * @returns the raced promise.
11
+ */
12
+ export function abortable(promise, signal) {
13
+ if (signal === undefined)
14
+ return promise;
15
+ return new Promise((resolve, reject) => {
16
+ if (signal.aborted) {
17
+ reject(signal.reason);
18
+ return;
19
+ }
20
+ const onAbort = () => { reject(signal.reason); };
21
+ signal.addEventListener('abort', onAbort, { once: true });
22
+ promise.then((value) => {
23
+ signal.removeEventListener('abort', onAbort);
24
+ resolve(value);
25
+ }, (error) => {
26
+ signal.removeEventListener('abort', onAbort);
27
+ reject(error);
28
+ });
29
+ });
30
+ }
31
+ //# sourceMappingURL=abort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort.js","sourceRoot":"","sources":["../src/abort.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAI,OAAmB,EAAE,MAA+B;IAC/E,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,OAAO,CAAA;IACxC,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YACrB,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,GAAS,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAA;QACrD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QACzD,OAAO,CAAC,IAAI,CACV,CAAC,KAAK,EAAE,EAAE;YACR,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5C,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YACjB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5C,MAAM,CAAC,KAAK,CAAC,CAAA;QACf,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * The plugin's own minimal LSP action client — the fallback for compositions where the official
3
+ * `ctx.lsp` seam does not serve action operations yet. One server process per (server entry,
4
+ * canonical workspace), lazily spawned and serialized; each action runs the transient
5
+ * didOpen→request→didClose lifecycle the servers expect, and teardown is bounded. See
6
+ * `docs/seam-extension-notes.md` for the migration story to the official seam.
7
+ * @module dsh-lsp-actions/client
8
+ */
9
+ import type { FileSystem } from '@deepseek-ai/dsh-fs';
10
+ import type { Context } from '@deepseek-ai/cordis';
11
+ import type { HostSource } from './host.ts';
12
+ import type { LspCodeActionsResult, LspCompletionResult, LspDiagnosticsResult, LspEditsResult, LspInlayHintsResult, LspPosition, LspRange, LspRenameResult, LspSignaturesResult, LspSymbolsResult } from './vocabulary.ts';
13
+ import type { ResolvedServer } from './servers.ts';
14
+ /** One action call as the client receives it: everything the tool already knows. */
15
+ export interface ActionRequest {
16
+ /** The source file (relative to `workspaceRoot` or absolute). */
17
+ readonly filePath: string;
18
+ /** The workspace root the client resolves against and indexes. */
19
+ readonly workspaceRoot: string;
20
+ /** The pre-read, byte-capped source the didOpen synchronizes with the server. */
21
+ readonly source: HostSource;
22
+ /** The LSP language id for `filePath`, from the routed server's extension mapping. */
23
+ readonly languageId: string;
24
+ /** The cursor position, for completion and signature help. */
25
+ readonly position?: LspPosition;
26
+ /** The formatting/code-action/inlay-hint range, when the caller narrowed it. */
27
+ readonly range?: LspRange;
28
+ /** CodeActionKind filters for code actions (e.g. `quickfix`). */
29
+ readonly onlyKinds?: readonly string[];
30
+ }
31
+ /**
32
+ * Pooled minimal LSP action client. Instances are single-flight per canonical workspace and are
33
+ * evicted as soon as they die; every await observes cancellation.
34
+ */
35
+ export declare class LspActionClient {
36
+ private readonly subprocess;
37
+ private readonly fs;
38
+ /** Byte cap for documents the rename flow reads back to decode cross-file positions. */
39
+ private readonly maxDocumentBytes;
40
+ private readonly instances;
41
+ private readonly lifetime;
42
+ private disposed;
43
+ constructor(subprocess: Context['subprocess'], fs: FileSystem,
44
+ /** Byte cap for documents the rename flow reads back to decode cross-file positions. */
45
+ maxDocumentBytes?: number);
46
+ /** Spawn one connection through the subprocess seam (the real provider at runtime). */
47
+ private readonly spawner;
48
+ /**
49
+ * Run the diagnostics action through the routed server.
50
+ * @param server - the routed server entry.
51
+ * @param request - the action request.
52
+ * @param signal - optional cancellation.
53
+ * @returns the normalized diagnostics result.
54
+ */
55
+ diagnostics(server: ResolvedServer, request: ActionRequest, signal?: AbortSignal): Promise<LspDiagnosticsResult>;
56
+ /**
57
+ * Run the formatting action through the routed server; the client only RETURNS edits, it never
58
+ * writes files — the tool applies them through `ctx.fs` write-intent.
59
+ * @param server - the routed server entry.
60
+ * @param request - the action request (carries the optional range).
61
+ * @param signal - optional cancellation.
62
+ * @returns the normalized edits result.
63
+ */
64
+ formatDocument(server: ResolvedServer, request: ActionRequest, signal?: AbortSignal): Promise<LspEditsResult>;
65
+ /**
66
+ * Run the completion action through the routed server.
67
+ * @param server - the routed server entry.
68
+ * @param request - the action request (carries the cursor position).
69
+ * @param signal - optional cancellation.
70
+ * @returns the normalized completion result.
71
+ */
72
+ completion(server: ResolvedServer, request: ActionRequest, signal?: AbortSignal): Promise<LspCompletionResult>;
73
+ /**
74
+ * Run the code actions action through the routed server; the client only REPORTS edits and
75
+ * commands, it never applies them — applying one is the model's own write/edit decision.
76
+ * @param server - the routed server entry.
77
+ * @param request - the action request (carries the optional range and kind filters).
78
+ * @param signal - optional cancellation.
79
+ * @returns the normalized code actions result.
80
+ */
81
+ codeActions(server: ResolvedServer, request: ActionRequest, signal?: AbortSignal): Promise<LspCodeActionsResult>;
82
+ /**
83
+ * Run a workspace-wide symbol search through the routed server (no document involved).
84
+ * @param server - the routed server entry.
85
+ * @param workspaceRoot - the workspace to search.
86
+ * @param query - the symbol name query.
87
+ * @param signal - optional cancellation.
88
+ * @returns the normalized symbols result.
89
+ */
90
+ workspaceSymbols(server: ResolvedServer, workspaceRoot: string, query: string, signal?: AbortSignal): Promise<LspSymbolsResult>;
91
+ /**
92
+ * Run a workspace-wide symbol search with one document kept open: project-based servers (tsls)
93
+ * refuse document-free `workspace/symbol`, so the routing file stays transiently open for the
94
+ * request and closes afterwards.
95
+ * @param server - the routed server entry.
96
+ * @param request - the action request (whose source is kept open during the search).
97
+ * @param query - the symbol name query.
98
+ * @param signal - optional cancellation.
99
+ * @returns the normalized symbols result.
100
+ */
101
+ workspaceSymbolsInDocument(server: ResolvedServer, request: ActionRequest, query: string, signal?: AbortSignal): Promise<LspSymbolsResult>;
102
+ /**
103
+ * Run a document symbol listing through the routed server.
104
+ * @param server - the routed server entry.
105
+ * @param request - the action request.
106
+ * @param signal - optional cancellation.
107
+ * @returns the normalized symbols result.
108
+ */
109
+ documentSymbols(server: ResolvedServer, request: ActionRequest, signal?: AbortSignal): Promise<LspSymbolsResult>;
110
+ /**
111
+ * Run signature help through the routed server.
112
+ * @param server - the routed server entry.
113
+ * @param request - the action request (carries the cursor position).
114
+ * @param signal - optional cancellation.
115
+ * @returns the normalized signatures result.
116
+ */
117
+ signatureHelp(server: ResolvedServer, request: ActionRequest, signal?: AbortSignal): Promise<LspSignaturesResult>;
118
+ /**
119
+ * Run inlay hints through the routed server.
120
+ * @param server - the routed server entry.
121
+ * @param request - the action request (carries the optional range).
122
+ * @param signal - optional cancellation.
123
+ * @returns the normalized inlay hints result.
124
+ */
125
+ inlayHints(server: ResolvedServer, request: ActionRequest, signal?: AbortSignal): Promise<LspInlayHintsResult>;
126
+ /**
127
+ * Run a symbol rename through the routed server; the client only RETURNS the grouped edits, it
128
+ * never writes files — the tool applies them through `ctx.fs` write-intent. Cross-document
129
+ * positions are decoded per document (reading the target text for non-utf-16 servers), so the
130
+ * returned edits are utf-16 for every document.
131
+ * @param server - the routed server entry.
132
+ * @param request - the action request (carries the cursor position).
133
+ * @param newName - the new symbol name.
134
+ * @param signal - optional cancellation.
135
+ * @returns the normalized, decoded rename result.
136
+ */
137
+ rename(server: ResolvedServer, request: ActionRequest, newName: string, signal?: AbortSignal): Promise<LspRenameResult>;
138
+ /** Disposed flag through a method so an await cannot narrow it to a literal. */
139
+ private isDisposed;
140
+ /** Reject work that cannot publish or use a client-owned instance. */
141
+ private assertActive;
142
+ /** Fuse caller cancellation with client disposal for every filesystem and protocol await. */
143
+ private querySignal;
144
+ private run;
145
+ /** The document-free sibling of {@link run}: serves workspace-scoped actions (symbol search). */
146
+ private runBare;
147
+ /** Serialize and run one action attempt pair (retry-once included) for a canonical workspace. */
148
+ private runScoped;
149
+ /** One attempt: publish/borrow the instance, run the action, evict the dead, arm the idle timer. */
150
+ private runOnce;
151
+ /** Idle-eviction timers per workspace key; a use resets, a fire disposes and evicts. */
152
+ private readonly idleTimers;
153
+ private armIdleTimer;
154
+ private clearIdleTimer;
155
+ /** Serialize one complete action lifecycle per canonical workspace. */
156
+ private enqueue;
157
+ /** The serialization tail for one workspace key (per-instance queues live on the instance). */
158
+ private tails;
159
+ private tailFor;
160
+ private setTail;
161
+ /** Return or synchronously publish the one instance for a canonical workspace. */
162
+ private instanceFor;
163
+ /** Dispose every live instance and block further actions. */
164
+ disposeAll(): Promise<void>;
165
+ /**
166
+ * Decode one rename's grouped wire edits into utf-16, per document: the origin document uses
167
+ * the source text the server saw; any other document is read back for its codec (utf-16 servers
168
+ * need no read — their positions are already utf-16). An unreadable or out-of-workspace target
169
+ * on a non-utf-16 server is a structured conflict, never silently mis-decoded positions.
170
+ */
171
+ private decodeRenameEdits;
172
+ }
173
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}