feat(lsp): LSP capability seam, generic stdio provider, and lsp tool

Implements the LSP capability seam RFC as three packages: dsh-lsp (the
ctx.lsp interface — provider registry by branded id + exclusive extension
mapping, per-query order-independent selection, closed request/result
vocabulary, LspError taxonomy), dsh-lsp-local (a generic stdio language-server
provider — Content-Length JSON-RPC framing, per-(provider, workspace) process
single-flight, transient didOpen/query/didClose, an abortable per-instance
queue, UTF-16 negotiation, host-namespace source reads outside ctx.fs, and
bounded shutdown/kill teardown), and dsh-tool-lsp (the model-facing lsp tool —
four operations, one-based UTF-16 cursor conversion, workspace-grouped location
rendering, hover capping, a required session workspace, and a timeout budget).

Why: an agent had text search and file reads but no way to identify a program
symbol — follow an alias, connect an interface to implementations, or read an
inferred type — before changing code. Splitting model contract, seam, and local
subprocess behavior keeps the four semantic queries stable across future remote
or sandbox-native providers without leaking a JSON-RPC escape hatch.
This commit is contained in:
Dudu-0223
2026-07-16 12:05:35 +08:00
parent 66b2cfc609
commit d0029d8d60
56 changed files with 4527 additions and 30 deletions

View File

@@ -419,6 +419,42 @@ export interface Config {
Source: [`packages/support/llm-replay/src/index.ts:306`](../packages/support/llm-replay/src/index.ts)
## `@deepseek-ai/dsh-lsp-local`
Requires: `lsp`
```ts config-catalog
/** Plugin configuration: one server command plus its extension mapping and host bounds. */
export interface Config {
/** Stable provider id, reserved on `ctx.lsp` with the extensions. */
providerId: string
/** Executable to spawn (absolute, or resolved on PATH at load). */
command: string
/** Arguments passed to the executable (no shell). */
args: string[]
/** Extra env vars merged on top of the scrubbed ambient env. */
env: Record<string, string>
/** Lowercase leading-dot extension → LSP language id (e.g. `{ '.ts': 'typescript' }`). */
extensionToLanguage: Record<string, string>
/** Static `initialize` options forwarded to the server. */
initializationOptions: unknown
/** Static answer to every `workspace/configuration` item. */
configuration: unknown
/** Largest single framed message accepted from the server (bytes). */
maxMessageBytes: number
/** Largest stderr tail retained for diagnostics (bytes). */
maxStderrBytes: number
/** Largest source file this host will open (bytes). */
maxDocumentBytes: number
/** Graceful `shutdown`/`exit` budget before escalation (ms). */
shutdownTimeoutMs: number
/** SIGTERM→SIGKILL grace after graceful shutdown fails (ms). */
killGraceMs: number
}
```
Source: [`packages/lsp/lsp-local/src/index.ts:59`](../packages/lsp/lsp-local/src/index.ts)
## `@deepseek-ai/dsh-mcp-client`
Requires: `tools`
@@ -901,6 +937,24 @@ export interface Config {
Source: [`packages/fs/tool-fs/src/index.ts:22`](../packages/fs/tool-fs/src/index.ts)
## `@deepseek-ai/dsh-tool-lsp`
Requires: `tools` · `lsp` · `systemPrompt`
```ts config-catalog
/** Plugin configuration: result caps and the timeout budget. */
export interface Config {
/** Largest number of rendered locations before an omission marker (default 100). */
maxLocations?: number
/** Largest hover length in characters after normalization (default 16000). */
maxHoverChars?: number
/** Tool-call timeout budget in ms (default 60000). */
timeoutMs?: number
}
```
Source: [`packages/lsp/tool-lsp/src/index.ts:56`](../packages/lsp/tool-lsp/src/index.ts)
## `@deepseek-ai/dsh-tool-skill`
Requires: `tools` · `skills`
@@ -1214,6 +1268,7 @@ These load from a `cordis.yml` entry with no `config:` block; they declare no co
- `@deepseek-ai/dsh-fs-policy` ([`packages/fs/fs-policy/src/index.ts`](../packages/fs/fs-policy/src/index.ts))
- `@deepseek-ai/dsh-invariants` — requires `sessions` ([`packages/support/invariants/src/index.ts`](../packages/support/invariants/src/index.ts))
- `@deepseek-ai/dsh-llm` ([`packages/llm/llm/src/index.ts`](../packages/llm/llm/src/index.ts))
- `@deepseek-ai/dsh-lsp` ([`packages/lsp/lsp/src/index.ts`](../packages/lsp/lsp/src/index.ts))
- `@deepseek-ai/dsh-session` ([`packages/core/session/src/index.ts`](../packages/core/session/src/index.ts))
- `@deepseek-ai/dsh-subagent` ([`packages/subagent/subagent/src/index.ts`](../packages/subagent/subagent/src/index.ts))
- `@deepseek-ai/dsh-timeout-policy` — requires `tools` ([`packages/timeout/timeout-policy/src/index.ts`](../packages/timeout/timeout-policy/src/index.ts))