dsh-lsp-actions 0.3.0 → 0.3.2
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.
- package/CHANGELOG.md +17 -1
- package/README.es.md +173 -137
- package/README.hi.md +173 -137
- package/README.md +131 -192
- package/README.pt.md +173 -137
- package/README.zh.md +224 -0
- package/examples/vscode/backend/package.json +6 -6
- package/lib/client.d.ts +3 -3
- package/lib/editor/actions.d.ts +5 -5
- package/lib/editor/cache.d.ts +1 -1
- package/lib/editor/server.d.ts +4 -4
- package/lib/editor/service.d.ts +9 -5
- package/lib/editor/service.d.ts.map +1 -1
- package/lib/editor/service.js +8 -7
- package/lib/editor/service.js.map +1 -1
- package/lib/editor/types.d.ts +1 -1
- package/lib/edits.d.ts +1 -1
- package/lib/extra-tools.d.ts +3 -3
- package/lib/index.d.ts +17 -17
- package/lib/runner.d.ts +5 -5
- package/lib/seam.d.ts +1 -1
- package/lib/tools.d.ts +5 -5
- package/lib/translate.d.ts +1 -1
- package/package.json +26 -21
- package/README.zh-CN.md +0 -285
package/README.pt.md
CHANGED
|
@@ -2,98 +2,163 @@
|
|
|
2
2
|
|
|
3
3
|
# 🛰️ dsh-lsp-actions
|
|
4
4
|
|
|
5
|
-
**A superfície de ação LSP para o DeepSeek Harness — servidores de linguagem reais, feedback real.**
|
|
5
|
+
**A superfície de ação LSP para o DeepSeek Harness — servidores de linguagem reais, feedback real e o backend de integração IDE para editores.**
|
|
6
6
|
|
|
7
|
-
Diagnósticos, formatação, autocompletar de código,
|
|
7
|
+
*Diagnósticos, formatação, autocompletar, ações de código, símbolos, ajuda de assinatura, dicas embutidas e renomeação para o loop do editor do seu agente — mais o protocolo estável de ações para editores (`lsp.actions.*`) que permite a qualquer editor consumi-los diretamente.*
|
|
8
8
|
|
|
9
|
-
[](LICENSE)
|
|
10
|
+
[](https://github.com/topics/dsh-plugin)
|
|
11
|
+
[](#)
|
|
12
|
+
[](https://github.com/PerryLink/dsh-lsp-actions/actions)
|
|
13
|
+
[](https://github.com/PerryLink/dsh-lsp-actions/releases)
|
|
14
|
+
[](https://www.npmjs.com/package/dsh-lsp-actions)
|
|
15
|
+
[](https://www.npmjs.com/package/dsh-lsp-actions)
|
|
16
16
|
|
|
17
|
-
[English](README.md) · [简体中文](README.zh
|
|
17
|
+
[English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
## Compatibility
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
| Surface | Status |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Harness | DeepSeek Harness `0.1.0-rc.8` (compatibilidade declarada para `>=0.1.0-rc.8 <0.2.0`) |
|
|
28
|
+
| Node | `^22.19.0 \|\| >=24.0.0` |
|
|
29
|
+
| Platforms | Todas (host puro; subprocessos + sistema de arquivos, sem rede) |
|
|
30
|
+
| Model | Qualquer (as ferramentas são independentes do modelo; o plugin nunca chama um modelo) |
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
## What you get
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
| --- | --- | --- |
|
|
31
|
-
| `lsp_diagnostics <file>` | Erros, avisos e dicas do compilador/analisador com severidade, intervalo, mensagem e servidor de origem | ❌ somente leitura |
|
|
32
|
-
| `lsp_format <file> [range?]` | Formata um arquivo ou seleção pelo servidor de linguagem e aplica o resultado, devolvendo o diff | ✅ via `fs/write-intent` + política de sandbox |
|
|
33
|
-
| `lsp_completion <file> <line> <character>` | Sugestões de autocompletar em uma posição do cursor, incluindo o texto de inserção real | ❌ somente leitura |
|
|
34
|
-
| `lsp_code_action <file> [range?] [only?]` | Correções/refatorações verificadas pelo servidor (com suas edições) para um intervalo ou o primeiro diagnóstico | ❌ somente referência |
|
|
35
|
-
| `lsp_symbols <query?> <file_path?>` | Busca de símbolos por nome em todo o workspace, ou o esboço de símbolos de um arquivo | ❌ somente leitura |
|
|
36
|
-
| `lsp_signature <file> <line> <character>` | Ajuda de assinatura (parâmetros e documentação) dentro de uma chamada | ❌ somente leitura |
|
|
37
|
-
| `lsp_inlay_hints <file> [range?]` | Anotações de tipo e dicas de nomes de parâmetros do servidor | ❌ somente leitura |
|
|
38
|
-
| `lsp_rename <file> <line> <character> <new_name>` | Renomeação de símbolo verificada pelo servidor, aplicada em todo o workspace com diffs por arquivo | ✅ via `fs/write-intent` + política de sandbox |
|
|
34
|
+
O `dsh-lsp-actions` é montado como uma única linha de host (`id: lsp-actions`, `name: dsh-lsp-actions`, `inject: [tools, fs, subprocess]`). O seam oficial `ctx.lsp` do DeepSeek Harness cobre a **navegação** (ir para definição, referências, implementação, hover); este plugin completa a **superfície de ação** — o loop de feedback que um agente precisa enquanto escreve e corrige código:
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
1. **Oito ferramentas `lsp_*`** — diagnósticos, formatação, autocompletar, ações de código, símbolos, ajuda de assinatura, dicas embutidas e renomeação, todas servidas pelos mesmos servidores de linguagem que o seu IDE usa.
|
|
37
|
+
2. **Protocolo de ações para editores v1** — uma superfície JSON-RPC estável (`lsp.actions.list` / `lsp.actions.run` / `lsp.events`) que permite a qualquer editor (VS Code primeiro) consumir essas capacidades diretamente.
|
|
38
|
+
3. **Verificação com servidor real** — uma execução real do `typescript-language-server` faz parte da suíte de testes (autocontida, CI em Node 22/24 no Linux, Windows e macOS), não apenas mocks.
|
|
41
39
|
|
|
42
|
-
##
|
|
40
|
+
## Quick start
|
|
43
41
|
|
|
44
42
|
```sh
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
Configure uma entrada por servidor de linguagem (a forma espelha a configuração oficial do `lsp-stdio`):
|
|
49
|
-
|
|
50
|
-
```yaml
|
|
51
|
-
# no cordis.patch.yml do seu perfil (ou na linha do bundle)
|
|
52
|
-
- insert:
|
|
53
|
-
- id: lsp-actions
|
|
54
|
-
name: dsh-lsp-actions
|
|
55
|
-
inject: [tools, fs, subprocess]
|
|
56
|
-
config:
|
|
57
|
-
servers:
|
|
58
|
-
ts:
|
|
59
|
-
command: typescript-language-server
|
|
60
|
-
args: [--stdio]
|
|
61
|
-
extensionToLanguage:
|
|
62
|
-
".ts": typescript
|
|
63
|
-
formattingOptions: { tabSize: 2, insertSpaces: true }
|
|
64
|
-
py:
|
|
65
|
-
command: pyright-langserver
|
|
66
|
-
args: [--stdio]
|
|
67
|
-
extensionToLanguage:
|
|
68
|
-
".py": python
|
|
69
|
-
maxDiagnostics: 200
|
|
70
|
-
maxCompletionItems: 20
|
|
71
|
-
maxCodeActions: 50
|
|
72
|
-
maxSymbols: 100
|
|
73
|
-
maxSignatures: 10
|
|
74
|
-
maxInlayHints: 200
|
|
75
|
-
maxResultChars: 16000
|
|
76
|
-
timeoutMs: 60000
|
|
77
|
-
```
|
|
43
|
+
# 1. install the bundle into your profile
|
|
44
|
+
dsh plugin --profile web add "github:PerryLink/dsh-lsp-actions#main"
|
|
78
45
|
|
|
79
|
-
|
|
46
|
+
# or from npm (published releases)
|
|
47
|
+
dsh plugin --profile web add dsh-lsp-actions
|
|
80
48
|
|
|
81
|
-
|
|
49
|
+
# 2. restart and verify the row
|
|
50
|
+
dsh --profile web --dump-config | grep -A3 'id: lsp-actions'
|
|
51
|
+
```
|
|
82
52
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- **
|
|
86
|
-
- **
|
|
87
|
-
- **
|
|
88
|
-
- **
|
|
89
|
-
|
|
53
|
+
## Install & uninstall
|
|
54
|
+
|
|
55
|
+
- **git channel** (`main` mais recente): `dsh plugin --profile web add "github:PerryLink/dsh-lsp-actions#main"` — o script `prepare` compila (`tsc --noEmitOnError`).
|
|
56
|
+
- **npm channel** (versões publicadas): `dsh plugin --profile web add dsh-lsp-actions`.
|
|
57
|
+
- **tarball channel**: execute `pnpm pack` neste repo e depois `dsh plugin --profile web add ./dsh-lsp-actions-<version>.tgz`.
|
|
58
|
+
- **uninstall**: `dsh plugin --profile web remove dsh-lsp-actions` (ou remova a linha do patch do perfil).
|
|
59
|
+
|
|
60
|
+
## Configuration
|
|
61
|
+
|
|
62
|
+
Todos os ajustes são campos Schemastery `Config` (alteráveis pelo cordis.yml). Uma sobrescrita direcionada por id substitui a linha inteira — repita cada chave de que precisar. O `cordis.patch.yml` documenta cada chave em linha.
|
|
63
|
+
|
|
64
|
+
| Key | Default | Meaning |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `servers` | `{}` | Servidores de linguagem nomeados; uma tabela vazia não ativa nenhum servidor |
|
|
67
|
+
| `editor.enabled` | `false` | Serve o protocolo de ações para editores por JSON-RPC stdio (somente backend headless) |
|
|
68
|
+
| `editor.requestTimeoutMs` | `60000` | Orçamento de timeout por execução (ms) do protocolo de editor |
|
|
69
|
+
| `editor.diagnosticsCacheMaxFiles` | `64` | Tamanho da cache LRU de diagnósticos (em arquivos) |
|
|
70
|
+
| `maxDiagnostics` | `200` | Teto de diagnósticos por resultado |
|
|
71
|
+
| `maxCompletionItems` | `20` | Teto de itens de autocompletar por resultado |
|
|
72
|
+
| `maxCodeActions` | `50` | Teto de ações de código por resultado |
|
|
73
|
+
| `maxSymbols` | `100` | Teto de resultados de símbolos |
|
|
74
|
+
| `maxSignatures` | `10` | Teto de ajuda de assinatura |
|
|
75
|
+
| `maxInlayHints` | `200` | Teto de dicas embutidas |
|
|
76
|
+
| `maxResultChars` | `16000` | Teto do resultado renderizado (caracteres) |
|
|
77
|
+
| `maxDocumentBytes` | `4000000` | Teto de leitura de documento (bytes) |
|
|
78
|
+
| `timeoutMs` | `60000` | Timeout por chamada, aplicado pela política oficial de timeout |
|
|
79
|
+
|
|
80
|
+
Cada entrada de `servers` é um `LspServerEntry`: `command` (executável resolvido no PATH no carregamento) e `extensionToLanguage` (`".ts"` → `typescript`) são obrigatórios; os opcionais `fileGlobs`, `args`, `env`, `initializationOptions`, `configuration`, `formattingOptions`, `maxMessageBytes`, `maxStderrBytes`, `killGraceMs`, `shutdownTimeoutMs`, `diagnosticsSettleMs`, `diagnosticsDebounceMs` e `idleTimeoutMs` (`0` = manter vivo o processo do servidor) ajustam o cliente stdio integrado.
|
|
81
|
+
|
|
82
|
+
## Tools & surfaces
|
|
83
|
+
|
|
84
|
+
| Surface | Kind | Notes |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `lsp_diagnostics` | tool | `<file>` — erros, avisos e dicas do compilador/analisador com severidade, intervalo, mensagem e servidor de origem (somente leitura) |
|
|
87
|
+
| `lsp_format` | tool | `<file> [range?]` — formata um arquivo/seleção pelo servidor de linguagem e o aplica, devolvendo o diff (grava via `fs/write-intent`) |
|
|
88
|
+
| `lsp_completion` | tool | `<file> <line> <character>` — sugestões de autocompletar em uma posição do cursor, incluindo o texto de inserção (somente leitura) |
|
|
89
|
+
| `lsp_code_action` | tool | `<file> [range?] [only?]` — correções/refatorações verificadas pelo servidor com suas edições, para um intervalo ou o primeiro diagnóstico (somente referência) |
|
|
90
|
+
| `lsp_symbols` | tool | `<query?> <file_path?>` — busca de símbolos por nome em todo o workspace, ou o esboço de um arquivo (somente leitura) |
|
|
91
|
+
| `lsp_signature` | tool | `<file> <line> <character>` — ajuda de assinatura (parâmetros e documentação) dentro de uma chamada (somente leitura) |
|
|
92
|
+
| `lsp_inlay_hints` | tool | `<file> [range?]` — anotações de tipo e dicas de nomes de parâmetros do servidor (somente leitura) |
|
|
93
|
+
| `lsp_rename` | tool | `<file> <line> <character> <new_name>` — renomeação verificada pelo servidor, aplicada em todo o workspace com diffs por arquivo (grava via `fs/write-intent`) |
|
|
94
|
+
| `lsp.actions.*` | protocol | Protocolo de ações para editores v1: `lsp.actions.list` / `lsp.actions.run` / `lsp.events` por JSON-RPC |
|
|
95
|
+
| `examples/vscode/` | extension | Extensão VS Code somente-UI mais a composição de backend headless à qual se conecta |
|
|
96
|
+
|
|
97
|
+
## Editor action protocol v1
|
|
98
|
+
|
|
99
|
+
Quando `editor.enabled: true` é definido em uma composição headless dedicada, o `dsh-lsp-actions` serve um protocolo de editor estável por JSON-RPC 2.0 delimitado por quebras de linha (o mesmo enquadramento de wire dos transportes oficiais SDK/ACP):
|
|
100
|
+
|
|
101
|
+
| Method | What it does |
|
|
102
|
+
|---|---|
|
|
103
|
+
| `lsp.actions.list` | Devolve a versão de protocolo `lsp-actions/v1`, o catálogo de ações (`diagnostics.get`, `completion.get`, `quickfix.apply`, `format` — cada uma marcada `writes`) e as sessões DSH endereçáveis |
|
|
104
|
+
| `lsp.actions.run` | Executa uma ação com um envelope estruturado `{ requestId, action, status, result \| error }`; os erros carregam os códigos estáveis `LSP_ACTION_*` |
|
|
105
|
+
| `lsp.events` | Assina as notificações `lsp.event` transmitidas: `diagnostics.updated`, `action.status`, `file.changed`, `sessions.changed` |
|
|
106
|
+
|
|
107
|
+
Todas as ações de escrita (`quickfix.apply`, `format`) passam pelos **presets de permissão oficiais e pela aprovação**: uma sessão `read-only` é recusada com `LSP_ACTION_READ_ONLY` antes de qualquer ida e volta com o servidor, as edições viajam pelo waterfall `fs/write-intent` e o par de escalada `sandbox_permissions` + `justification` se resolve pelo `approveEscalation` oficial (fail-closed quando ninguém pode decidir). Especificação de wire completa, bilíngue: [`docs/editor-protocol.md`](docs/editor-protocol.md) · [`docs/editor-protocol.zh-CN.md`](docs/editor-protocol.zh-CN.md).
|
|
108
|
+
|
|
109
|
+
**Versionamento e a promessa de compatibilidade retroativa**
|
|
110
|
+
|
|
111
|
+
- O protocolo é versionado — `lsp.actions.list` devolve `protocol: "lsp-actions/v1"`, `version: 1`. **O v1 está congelado:** nomes de campos, ids de ação, tipos de evento e códigos de erro permanecem estáveis para sempre.
|
|
112
|
+
- A evolução é **apenas aditiva**: novas ações, campos e tipos de evento chegam sem subir a versão; a semântica existente nunca muda no lugar; uma mudança que quebra compatibilidade é publicada sob uma nova versão de `protocol`, que os servidores podem servir lado a lado.
|
|
113
|
+
- Os clientes devem ignorar campos, tipos de evento e ações desconhecidos, e rotear pelo `code` de erro estável, nunca pelo texto da mensagem.
|
|
114
|
+
|
|
115
|
+
**Códigos de erro**
|
|
116
|
+
|
|
117
|
+
Cada falha carrega um `code` estável; modelos e chamadores roteiam pelo código, nunca pelo texto da mensagem.
|
|
118
|
+
|
|
119
|
+
| Code | Meaning |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `LSP_ACTION_UNAVAILABLE` | Nenhuma entrada de servidor nem provider do seam trata este arquivo |
|
|
122
|
+
| `LSP_ACTION_UNSUPPORTED` | O servidor (ou o provider do seam) não anuncia a operação |
|
|
123
|
+
| `LSP_ACTION_SERVER_FAILED` | O servidor falhou (com o final do seu stderr); falhas de inicialização tentam de novo uma vez |
|
|
124
|
+
| `LSP_ACTION_MALFORMED_RESPONSE` | O servidor enviou uma carga estruturalmente inválida |
|
|
125
|
+
| `LSP_ACTION_CONFLICT` | O arquivo mudou desde que foi lido, ou as edições se sobrepõem / saem dos limites / saem do workspace |
|
|
126
|
+
| `LSP_ACTION_READ_ONLY` | O modo sandbox da sessão proíbe a escrita da formatação/renomeação |
|
|
127
|
+
| `LSP_ACTION_WORKSPACE_REQUIRED` | A sessão chamadora não tem um cwd de workspace para enraizar o servidor |
|
|
128
|
+
| `LSP_ACTION_NO_SYMBOL` | O servidor não encontrou um símbolo renomeável na posição do cursor |
|
|
129
|
+
| `LSP_ACTION_UNKNOWN` | Protocolo de editor: id de ação desconhecido, ou nenhuma ação de código coincidiu com `title`/`index` |
|
|
130
|
+
| `LSP_ACTION_INVALID_ARGS` | Protocolo de editor: parâmetros de ação mal formados |
|
|
131
|
+
| `LSP_ACTION_APPROVAL_UNAVAILABLE` | Protocolo de editor: a rota de aprovação não pôde conceder um modo sandbox mais amplo (fail-closed) |
|
|
132
|
+
| `LSP_PROTOCOL_VERSION_UNSUPPORTED` | Protocolo de editor: a versão de protocolo declarada não é suportada |
|
|
133
|
+
|
|
134
|
+
## VS Code extension
|
|
135
|
+
|
|
136
|
+
[`examples/vscode/`](examples/vscode/) inclui uma extensão **somente-UI** (barra lateral com as sessões DSH, a lista de diagnósticos, aplicar quickfix com um clique, abrir no intervalo e formatar) mais a composição de backend headless (`backend/cordis.yml`) à qual se conecta por JSON-RPC estilo ACP. A extensão implementa zero lógica LSP — cada capacidade e cada byte escrito pertencem ao plugin. Os passos de instalação, ajustes e o script de gravação do gif de demonstração estão em [`examples/vscode/README.md`](examples/vscode/README.md).
|
|
137
|
+
|
|
138
|
+

|
|
139
|
+
|
|
140
|
+
## Permissions & data
|
|
141
|
+
|
|
142
|
+
- **Permissões**: a formatação e a renomeação viajam pelos presets de permissão oficiais e pela aprovação — o waterfall `fs/write-intent` e o par de escalada `sandbox_permissions` / `justification` resolvido por `ctx.approval`. O plugin declara `fs:read`, `fs:write`, `subprocess:spawn` e `network:none` em seu manifesto de workshop.
|
|
143
|
+
- **Dados**: nada é armazenado em disco; os resultados das ferramentas vivem apenas no log da sessão (sem persistência entre sessões). O protocolo de editor mantém uma única cache LRU de diagnósticos em memória, limitada, com selo de frescor e nunca persistida entre reinícios.
|
|
144
|
+
- **Sem rede**: o plugin não faz requisições de rede; ele fala com os servidores de linguagem por stdio de subprocessos locais.
|
|
145
|
+
|
|
146
|
+
## Security boundaries
|
|
147
|
+
|
|
148
|
+
- **Somente leitura por padrão.** Seis das oito ferramentas são apenas de referência; somente `lsp_format` e `lsp_rename` mutam, e o fazem como mutações reais de `write`/`edit`.
|
|
149
|
+
- **Seams oficiais, não reimplementados.** Cada byte passa pelo waterfall `fs/write-intent` (observação → escrita protegida → observação) e pela política sandbox de cada chamada; a escalada acompanha as ferramentas oficiais `write`/`edit`.
|
|
150
|
+
- **Falha em alto e bom som, rápido e estruturado.** `servers` vazio + sem seam `ctx.lsp` → `LSP_ACTION_UNAVAILABLE`; sessões somente leitura → `LSP_ACTION_READ_ONLY` antes de qualquer ida e volta com o servidor; formas de comando são reportadas e nunca executadas.
|
|
151
|
+
- **Conflitos nunca sobrescrevem.** Um arquivo mudado em disco após a leitura falha com `LSP_ACTION_CONFLICT`; o `lsp_rename` faz o pré-voo de cada arquivo editado antes da primeira escrita.
|
|
152
|
+
- **Trabalho limitado.** Os tetos de resultados, os tetos de bytes e a política de timeout da plataforma limitam cada chamada; a cache de diagnósticos é uma LRU limitada.
|
|
153
|
+
- **Nada é cacheado no caminho do modelo.** Os resultados das ferramentas vivem apenas no log da sessão; a cache de diagnósticos nunca persiste entre reinícios.
|
|
90
154
|
- **Servidores ruins falham em alto e bom som.** Um executável inexistente falha no carregamento; um servidor que morre na inicialização falha a chamada com `LSP_ACTION_SERVER_FAILED` mais o final do seu stderr (após uma nova tentativa com processo novo).
|
|
155
|
+
- **Higiene do prompt.** O plugin não injeta persona nem prosa de prompt no system prompt da sessão — sua superfície de cara ao modelo são os oito esquemas de ferramentas.
|
|
91
156
|
|
|
92
|
-
##
|
|
157
|
+
## Architecture
|
|
93
158
|
|
|
94
159
|
As ações vão **primeiro pelo seam oficial** e caem para o cliente stdio mínimo do próprio plugin:
|
|
95
160
|
|
|
96
|
-
```
|
|
161
|
+
```text
|
|
97
162
|
lsp_diagnostics / lsp_format / lsp_completion / lsp_code_action /
|
|
98
163
|
lsp_symbols / lsp_signature / lsp_inlay_hints / lsp_rename
|
|
99
164
|
│
|
|
@@ -104,85 +169,56 @@ lsp_symbols / lsp_signature / lsp_inlay_hints / lsp_rename
|
|
|
104
169
|
cliente stdio integrado ← tabela servers (ctx.subprocess.spawn + JSON-RPC)
|
|
105
170
|
```
|
|
106
171
|
|
|
107
|
-
A extensão do seam está proposta upstream (`upstream/lsp-action-seam.patch`, descrição do PR em `upstream/PR-description.md`). Quando for integrada, o plugin continua funcionando sem mudanças — o cliente integrado simplesmente deixa de ser usado. O cliente integrado permanece como fallback independente para a tabela `servers`. Notas completas de pesquisa e design: [`docs/seam-extension-notes.md`](docs/seam-extension-notes.md)
|
|
108
|
-
|
|
109
|
-
## Referência de configuração
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
interface Config {
|
|
113
|
-
/** Servidores de linguagem nomeados; vazio = o cliente próprio não serve nada. */
|
|
114
|
-
servers?: Record<string, LspServerEntry>
|
|
115
|
-
maxDiagnostics?: number // padrão 200
|
|
116
|
-
maxCompletionItems?: number // padrão 20
|
|
117
|
-
maxCodeActions?: number // padrão 50
|
|
118
|
-
maxSymbols?: number // padrão 100
|
|
119
|
-
maxSignatures?: number // padrão 10
|
|
120
|
-
maxInlayHints?: number // padrão 200
|
|
121
|
-
maxResultChars?: number // padrão 16000 (teto do resultado renderizado completo)
|
|
122
|
-
maxDocumentBytes?: number // padrão 4000000
|
|
123
|
-
timeoutMs?: number // padrão 60000 (aplicado pela política oficial de timeout)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
interface LspServerEntry {
|
|
127
|
-
command: string // executável, resolvido no PATH no carregamento
|
|
128
|
-
extensionToLanguage: Record<string, string> // ".ts" → "typescript"
|
|
129
|
-
fileGlobs?: string[] // opcional; globs vencem o mapa de extensões
|
|
130
|
-
args?: string[] // sem shell
|
|
131
|
-
env?: Record<string, string>
|
|
132
|
-
initializationOptions?: unknown
|
|
133
|
-
configuration?: unknown // forma de objeto responde workspace/configuration por seção
|
|
134
|
-
formattingOptions?: unknown // p. ex. { tabSize: 2, insertSpaces: true }
|
|
135
|
-
maxMessageBytes?: number // padrão 16000000
|
|
136
|
-
maxStderrBytes?: number // padrão 1000000
|
|
137
|
-
killGraceMs?: number // padrão 2000
|
|
138
|
-
shutdownTimeoutMs?: number // padrão 5000
|
|
139
|
-
diagnosticsSettleMs?: number // padrão 2000 (janela de diagnósticos só por push)
|
|
140
|
-
diagnosticsDebounceMs?: number // padrão 250 (período de calma após o último lote enviado)
|
|
141
|
-
idleTimeoutMs?: number // padrão 0 (0 = manter o processo do servidor vivo)
|
|
142
|
-
}
|
|
143
|
-
```
|
|
172
|
+
A extensão do seam está proposta upstream (`upstream/lsp-action-seam.patch`, descrição do PR em `upstream/PR-description.md`). Quando for integrada, o plugin continua funcionando sem mudanças — o cliente integrado simplesmente deixa de ser usado. O cliente integrado permanece como fallback independente para a tabela `servers`. O **protocolo de editor** usa o mesmo runner, o mesmo caminho de escrita e a mesma maquinaria de permissões. Notas completas de pesquisa e design: [`docs/seam-extension-notes.md`](docs/seam-extension-notes.md).
|
|
144
173
|
|
|
145
|
-
|
|
174
|
+
## Known limitations
|
|
146
175
|
|
|
147
|
-
Cada
|
|
176
|
+
- **Documentos transitórios.** Cada ação abre o arquivo, executa uma requisição e o fecha de novo (igual ao host stdio oficial). Servidores baseados em projeto que exigem um arquivo aberto residente para requisições sem documento (o tsls recusa `workspace/symbol` sem um) são atendidos passando `file_path` para `lsp_symbols`. O tsls também responde `textDocument/signatureHelp` com `null` sob esse ciclo de vida; outros servidores (gopls, pyright, rust-analyzer) o atendem normalmente.
|
|
177
|
+
- **A formatação de intervalo exige o provider de intervalo do servidor.** Servidores que só anunciam formatação de documento completo falham requisições de intervalo com `LSP_ACTION_UNSUPPORTED`.
|
|
178
|
+
- **A renomeação aplica apenas edições de texto.** Operações de recursos (criar/excluir/renomear arquivos) na resposta de renomeação do servidor são recusadas com `LSP_ACTION_UNSUPPORTED`, e edições fora do workspace falham como `LSP_ACTION_CONFLICT` antes de qualquer escrita.
|
|
148
179
|
|
|
149
|
-
|
|
150
|
-
| --- | --- |
|
|
151
|
-
| `LSP_ACTION_UNAVAILABLE` | Nenhuma entrada de servidor nem provider do seam trata este arquivo. |
|
|
152
|
-
| `LSP_ACTION_UNSUPPORTED` | O servidor (ou o provider do seam) não anuncia a operação. |
|
|
153
|
-
| `LSP_ACTION_SERVER_FAILED` | O servidor falhou (com o final do seu stderr); falhas de inicialização tentam de novo uma vez. |
|
|
154
|
-
| `LSP_ACTION_MALFORMED_RESPONSE` | O servidor enviou uma carga estruturalmente inválida. |
|
|
155
|
-
| `LSP_ACTION_CONFLICT` | O arquivo mudou desde que foi lido, ou as edições do servidor se sobrepõem / saem dos limites / saem do workspace. |
|
|
156
|
-
| `LSP_ACTION_READ_ONLY` | O modo de sandbox da sessão proíbe a escrita da formatação/renomeação. |
|
|
157
|
-
| `LSP_ACTION_WORKSPACE_REQUIRED` | A sessão chamadora não tem um cwd de workspace para enraizar o servidor. |
|
|
158
|
-
| `LSP_ACTION_NO_SYMBOL` | O servidor não encontrou um símbolo renomeável na posição do cursor. |
|
|
180
|
+
## Development
|
|
159
181
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
182
|
+
```sh
|
|
183
|
+
pnpm install # node ^22.19 || >=24
|
|
184
|
+
pnpm run lint # oxlint over src/ and tests/
|
|
185
|
+
pnpm test # vitest: unit + fixture-server integration + editor-protocol e2e + real tsls e2e
|
|
186
|
+
pnpm run test:coverage # coverage gate
|
|
187
|
+
pnpm build # tsc --noEmitOnError → lib/
|
|
188
|
+
pnpm run prepare # tsc --noEmitOnError (runs on install)
|
|
189
|
+
pnpm run prepublishOnly # tsc --noEmitOnError (runs before publish)
|
|
190
|
+
```
|
|
163
191
|
|
|
164
|
-
|
|
192
|
+
## Topics
|
|
165
193
|
|
|
166
|
-
-
|
|
167
|
-
- **Formatação de intervalo exige o provider de intervalo do servidor.** Servidores que só anunciam formatação de documento completo falham requisições de intervalo com `LSP_ACTION_UNSUPPORTED`.
|
|
168
|
-
- **A renomeação aplica apenas edições de texto.** Operações de recursos (criar/excluir/renomear arquivos) na resposta de renomeação do servidor são recusadas com `LSP_ACTION_UNSUPPORTED`, e edições fora do workspace falham com `LSP_ACTION_CONFLICT` antes de qualquer escrita. Em servidores `utf-8`/`utf-32`, as posições de renomeação entre arquivos são decodificadas lendo cada arquivo editado; um arquivo editado ilegível falha a chamada como conflito em vez de decodificar mal as posições.
|
|
194
|
+
`dsh`, `dsh-plugin`, `deepseek-harness`, `lsp`, `language-server`, `diagnostics`, `formatting`, `completion`, `code-action`, `symbols`, `signature-help`, `inlay-hints`, `rename`, `refactor`, `ide`, `editor`, `vscode`, `acp`, `json-rpc`
|
|
169
195
|
|
|
170
|
-
##
|
|
196
|
+
## Contributors
|
|
171
197
|
|
|
172
|
-
|
|
173
|
-
pnpm install
|
|
174
|
-
pnpm run lint # oxlint sobre src/ e tests/
|
|
175
|
-
pnpm test # mais de 240 testes: unidade + integração com servidor fixture + e2e real com tsls
|
|
176
|
-
pnpm run test:coverage # portões: linhas/instruções/funções ≥ 90%, ramos ≥ 85%
|
|
177
|
-
pnpm build # emite lib/
|
|
178
|
-
```
|
|
198
|
+
- [@PerryLink](https://github.com/PerryLink) — criador e mantenedor: o cliente de ações LSP e o ciclo de vida do servidor, as oito ferramentas, o protocolo de ações para editores, os testes, a CI e a documentação em cinco idiomas.
|
|
179
199
|
|
|
180
|
-
##
|
|
200
|
+
## PerryLink DSH Plugin Family
|
|
181
201
|
|
|
182
|
-
|
|
202
|
+
Este projeto é um dos [15 plugins do DeepSeek Harness](https://github.com/PerryLink) mantidos por [PerryLink](https://github.com/PerryLink). Se este ajuda você, os outros provavelmente também ajudarão:
|
|
183
203
|
|
|
184
|
-
|
|
204
|
+
| Plugin | One-liner |
|
|
205
|
+
|---|---|
|
|
206
|
+
| [dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel) | Painel de runtime MCP somente leitura: comando /mcp + aba de configurações com status, ferramentas e erros |
|
|
207
|
+
| [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | Guardião de disciplina de engenharia: interrogatório de requisitos, portões de teste, revisão adversária |
|
|
208
|
+
| [dsh-background-agents](https://github.com/PerryLink/dsh-background-agents) | Agentes filhos em segundo plano duráveis com barra lateral Web, mensagens e interrupção |
|
|
209
|
+
| **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | Diagnósticos, formatação, autocompletar, ações de código e renomeação LSP sobre servidores de linguagem |
|
|
210
|
+
| [dsh-output-styles](https://github.com/PerryLink/dsh-output-styles) | Troca de estilo em tempo de execução equivalente ao outputStyles do Claude Code |
|
|
211
|
+
| [dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind) | Equivalente ao /rewind do Claude Code: snapshots, bifurcações de sessão, restauração em um passo |
|
|
212
|
+
| [dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules) | Regras de permissão declarativas allow/deny/ask estilo Claude Code com auditoria |
|
|
213
|
+
| [dsh-auto-review](https://github.com/PerryLink/dsh-auto-review) | Auto-revisão com segundo modelo na cadeia de aprovação, fail-closed por padrão |
|
|
214
|
+
| [dsh-memento](https://github.com/PerryLink/dsh-memento) | Memória entre sessões com portão de aprovação: seam ctx.memory + SQLite + ferramenta memory |
|
|
215
|
+
| [dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security) | Pacote de habilidades de auditoria de segurança: varredura de segredos, revisão de dependências e cadeia de suprimentos |
|
|
216
|
+
| [dsh-session-pin](https://github.com/PerryLink/dsh-session-pin) | Fixa sessões na barra lateral Web com ordenação durável |
|
|
217
|
+
| [dsh-composer-history](https://github.com/PerryLink/dsh-composer-history) | Histórico de entrada estilo terminal para o compositor web: setas, busca Ctrl+R |
|
|
218
|
+
| [dsh-github](https://github.com/PerryLink/dsh-github) | Integração de PR/issues do GitHub para DSH, cada escrita com portão de aprovação |
|
|
219
|
+
| [dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide) | Base de conhecimento de desenvolvimento de plugins como habilidade de agente sob demanda |
|
|
220
|
+
| [dsh-claude-move](https://github.com/PerryLink/dsh-claude-move) | Migra sessões, memória, habilidades e CLAUDE.md do Claude Code para o DSH |
|
|
185
221
|
|
|
186
222
|
## License
|
|
187
223
|
|
|
188
|
-
[Apache License 2.0](LICENSE)
|
|
224
|
+
[Apache License 2.0](LICENSE) © 2026 dsh-lsp-actions contributors
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 🛰️ dsh-lsp-actions
|
|
4
|
+
|
|
5
|
+
**DeepSeek Harness 的 LSP 动作面 —— 真实的语言服务器、真实的反馈,以及面向编辑器的 IDE 集成后端。**
|
|
6
|
+
|
|
7
|
+
*为你的 agent 编辑循环提供诊断、格式化、补全、代码动作、符号、签名提示、内联提示与重命名 —— 外加稳定的编辑器 action 协议(`lsp.actions.*`),让任何编辑器都能直接消费这些能力。*
|
|
8
|
+
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://github.com/topics/dsh-plugin)
|
|
11
|
+
[](#)
|
|
12
|
+
[](https://github.com/PerryLink/dsh-lsp-actions/actions)
|
|
13
|
+
[](https://github.com/PerryLink/dsh-lsp-actions/releases)
|
|
14
|
+
[](https://www.npmjs.com/package/dsh-lsp-actions)
|
|
15
|
+
[](https://www.npmjs.com/package/dsh-lsp-actions)
|
|
16
|
+
|
|
17
|
+
[English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Compatibility
|
|
24
|
+
|
|
25
|
+
| Surface | Status |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Harness | DeepSeek Harness `0.1.0-rc.8`(对 `>=0.1.0-rc.8 <0.2.0` 声明兼容) |
|
|
28
|
+
| Node | `^22.19.0 \|\| >=24.0.0` |
|
|
29
|
+
| Platforms | 全部(纯 host;子进程 + 文件系统,无网络) |
|
|
30
|
+
| Model | 任意(工具与模型无关;插件从不调用模型) |
|
|
31
|
+
|
|
32
|
+
## What you get
|
|
33
|
+
|
|
34
|
+
`dsh-lsp-actions` 以单个 host 行挂载(`id: lsp-actions`、`name: dsh-lsp-actions`、`inject: [tools, fs, subprocess]`)。官方 DeepSeek Harness 的 `ctx.lsp` seam 覆盖**导航**(跳转定义、引用、实现、悬停);本插件补齐了**动作面** —— agent 写代码和修代码时需要的反馈闭环:
|
|
35
|
+
|
|
36
|
+
1. **八个 `lsp_*` 工具** —— 诊断、格式化、补全、代码动作、符号、签名提示、内联提示与重命名,全部由你 IDE 所用的那些语言服务器提供。
|
|
37
|
+
2. **编辑器 action 协议 v1** —— 稳定的 JSON-RPC 面(`lsp.actions.list` / `lsp.actions.run` / `lsp.events`),让任何编辑器(先行 VS Code)直接消费这些能力。
|
|
38
|
+
3. **真实服务器验证** —— 测试套件包含一次真实的 `typescript-language-server` 运行(自包含,CI 在 Node 22/24 × Linux/Windows/macOS 上运行),而非只有 mock。
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
# 1. install the bundle into your profile
|
|
44
|
+
dsh plugin --profile web add "github:PerryLink/dsh-lsp-actions#main"
|
|
45
|
+
|
|
46
|
+
# or from npm (published releases)
|
|
47
|
+
dsh plugin --profile web add dsh-lsp-actions
|
|
48
|
+
|
|
49
|
+
# 2. restart and verify the row
|
|
50
|
+
dsh --profile web --dump-config | grep -A3 'id: lsp-actions'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Install & uninstall
|
|
54
|
+
|
|
55
|
+
- **git channel**(最新 `main`):`dsh plugin --profile web add "github:PerryLink/dsh-lsp-actions#main"` —— `prepare` 脚本负责构建(`tsc --noEmitOnError`)。
|
|
56
|
+
- **npm channel**(发布版本):`dsh plugin --profile web add dsh-lsp-actions`。
|
|
57
|
+
- **tarball channel**:在本仓库执行 `pnpm pack`,然后 `dsh plugin --profile web add ./dsh-lsp-actions-<version>.tgz`。
|
|
58
|
+
- **uninstall**:`dsh plugin --profile web remove dsh-lsp-actions`(或从 profile patch 中移除该行)。
|
|
59
|
+
|
|
60
|
+
## Configuration
|
|
61
|
+
|
|
62
|
+
所有可调项都是 Schemastery `Config` 字段(可从 cordis.yml 修改)。以 id 为目标的覆盖会替换整行 —— 你需要重述每一个键。`cordis.patch.yml` 对每个键都有内联说明。
|
|
63
|
+
|
|
64
|
+
| Key | Default | Meaning |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `servers` | `{}` | 命名的语言服务器;空表不激活任何服务器 |
|
|
67
|
+
| `editor.enabled` | `false` | 通过 JSON-RPC stdio 提供编辑器 action 协议(仅限 headless 后端) |
|
|
68
|
+
| `editor.requestTimeoutMs` | `60000` | 编辑器协议每次运行的超时预算(毫秒) |
|
|
69
|
+
| `editor.diagnosticsCacheMaxFiles` | `64` | 有界 LRU 诊断缓存大小(按文件数) |
|
|
70
|
+
| `maxDiagnostics` | `200` | 每次结果的诊断上限 |
|
|
71
|
+
| `maxCompletionItems` | `20` | 每次结果的补全项上限 |
|
|
72
|
+
| `maxCodeActions` | `50` | 每次结果的代码动作上限 |
|
|
73
|
+
| `maxSymbols` | `100` | 符号结果上限 |
|
|
74
|
+
| `maxSignatures` | `10` | 签名提示上限 |
|
|
75
|
+
| `maxInlayHints` | `200` | 内联提示上限 |
|
|
76
|
+
| `maxResultChars` | `16000` | 渲染结果上限(字符数) |
|
|
77
|
+
| `maxDocumentBytes` | `4000000` | 文档读取上限(字节数) |
|
|
78
|
+
| `timeoutMs` | `60000` | 每次调用的超时,由官方 timeout 策略执行 |
|
|
79
|
+
|
|
80
|
+
每个 `servers` 条目都是一个 `LspServerEntry`:`command`(可执行文件,加载期在 PATH 上解析)与 `extensionToLanguage`(`".ts"` → `typescript`)为必填;可选的 `fileGlobs`、`args`、`env`、`initializationOptions`、`configuration`、`formattingOptions`、`maxMessageBytes`、`maxStderrBytes`、`killGraceMs`、`shutdownTimeoutMs`、`diagnosticsSettleMs`、`diagnosticsDebounceMs` 与 `idleTimeoutMs`(`0` = 保持服务器进程存活)用于调校内置 stdio 客户端。
|
|
81
|
+
|
|
82
|
+
## Tools & surfaces
|
|
83
|
+
|
|
84
|
+
| Surface | Kind | Notes |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `lsp_diagnostics` | tool | `<file>` —— 编译器/分析器的错误、警告与提示,含严重级、范围、消息与来源服务器(只读) |
|
|
87
|
+
| `lsp_format` | tool | `<file> [range?]` —— 通过语言服务器格式化文件/选区并应用,返回 diff(经 `fs/write-intent` 写盘) |
|
|
88
|
+
| `lsp_completion` | tool | `<file> <line> <character>` —— 光标处的补全建议,含插入文本(只读) |
|
|
89
|
+
| `lsp_code_action` | tool | `<file> [range?] [only?]` —— 服务器验证过的快速修复/重构(含其编辑),作用于某范围或首个诊断(仅参考) |
|
|
90
|
+
| `lsp_symbols` | tool | `<query?> <file_path?>` —— 按名字全局搜索符号,或列出单个文件的大纲(只读) |
|
|
91
|
+
| `lsp_signature` | tool | `<file> <line> <character>` —— 调用点处的签名提示(参数与文档)(只读) |
|
|
92
|
+
| `lsp_inlay_hints` | tool | `<file> [range?]` —— 服务器给出的类型标注与参数名提示(只读) |
|
|
93
|
+
| `lsp_rename` | tool | `<file> <line> <character> <new_name>` —— 服务器验证过的重命名,跨工作区应用并返回逐文件 diff(经 `fs/write-intent` 写盘) |
|
|
94
|
+
| `lsp.actions.*` | protocol | 编辑器 action 协议 v1:经 JSON-RPC 的 `lsp.actions.list` / `lsp.actions.run` / `lsp.events` |
|
|
95
|
+
| `examples/vscode/` | extension | 纯 UI 的 VS Code 扩展,及其所连接的 headless 后端组合 |
|
|
96
|
+
|
|
97
|
+
## Editor action protocol v1
|
|
98
|
+
|
|
99
|
+
在专用 headless 组合中设置 `editor.enabled: true` 后,`dsh-lsp-actions` 通过换行分帧的 JSON-RPC 2.0(与官方 SDK/ACP 传输同一线格式)提供稳定的编辑器协议:
|
|
100
|
+
|
|
101
|
+
| Method | What it does |
|
|
102
|
+
|---|---|
|
|
103
|
+
| `lsp.actions.list` | 返回 `lsp-actions/v1` 协议版本、动作目录(`diagnostics.get`、`completion.get`、`quickfix.apply`、`format`,逐个标注 `writes`)与可寻址的 DSH 会话 |
|
|
104
|
+
| `lsp.actions.run` | 执行一个动作,返回结构化 `{ requestId, action, status, result \| error }` 信封;错误携带稳定的 `LSP_ACTION_*` 码 |
|
|
105
|
+
| `lsp.events` | 订阅流式 `lsp.event` 通知:`diagnostics.updated`、`action.status`、`file.changed`、`sessions.changed` |
|
|
106
|
+
|
|
107
|
+
所有写动作(`quickfix.apply`、`format`)都走**官方权限预设与审批**:`read-only` 会话在任何服务器往返前以 `LSP_ACTION_READ_ONLY` 拒绝;编辑走 `fs/write-intent` waterfall;`sandbox_permissions` + `justification` 升级对经官方 `approveEscalation` 询问(无应答方时 fail-closed)。完整线上规范(双语):[`docs/editor-protocol.md`](docs/editor-protocol.md) · [`docs/editor-protocol.zh-CN.md`](docs/editor-protocol.zh-CN.md)。
|
|
108
|
+
|
|
109
|
+
**版本化与向后兼容承诺**
|
|
110
|
+
|
|
111
|
+
- 协议带版本 —— `lsp.actions.list` 返回 `protocol: "lsp-actions/v1"`、`version: 1`。**v1 已冻结:**字段名、动作 id、事件类型与错误码永久稳定。
|
|
112
|
+
- 演进**只做加法**:新动作、新字段、新事件类型无需升版本;既有语义绝不原地变更;破坏性变更以新的 `protocol` 版本发布,服务端可并行服务多版本。
|
|
113
|
+
- 客户端必须忽略未知字段、未知事件类型与未知动作,并按稳定的错误 `code` 路由,绝不解析消息文本。
|
|
114
|
+
|
|
115
|
+
**错误码**
|
|
116
|
+
|
|
117
|
+
每个失败都携带稳定 `code`;模型与调用方按 code 路由,绝不解析消息文本。
|
|
118
|
+
|
|
119
|
+
| Code | Meaning |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `LSP_ACTION_UNAVAILABLE` | 没有服务器 entry、seam provider 也不处理该文件 |
|
|
122
|
+
| `LSP_ACTION_UNSUPPORTED` | 服务器(或 seam provider)未广告该操作 |
|
|
123
|
+
| `LSP_ACTION_SERVER_FAILED` | 服务器失败(附 stderr 尾部);启动失败重试一次 |
|
|
124
|
+
| `LSP_ACTION_MALFORMED_RESPONSE` | 服务器返回了结构非法的负载 |
|
|
125
|
+
| `LSP_ACTION_CONFLICT` | 文件读后已变,或编辑重叠 / 越界 / 越出工作区 |
|
|
126
|
+
| `LSP_ACTION_READ_ONLY` | 会话沙箱模式禁止格式化/重命名写入 |
|
|
127
|
+
| `LSP_ACTION_WORKSPACE_REQUIRED` | 调用会话没有可扎根的 workspace cwd |
|
|
128
|
+
| `LSP_ACTION_NO_SYMBOL` | 服务器在光标位置找不到可重命名的符号 |
|
|
129
|
+
| `LSP_ACTION_UNKNOWN` | 编辑器协议:未知动作 id,或没有 code action 匹配 `title`/`index` |
|
|
130
|
+
| `LSP_ACTION_INVALID_ARGS` | 编辑器协议:动作参数不合法 |
|
|
131
|
+
| `LSP_ACTION_APPROVAL_UNAVAILABLE` | 编辑器协议:审批路径未能授予更宽沙箱模式(fail-closed) |
|
|
132
|
+
| `LSP_PROTOCOL_VERSION_UNSUPPORTED` | 编辑器协议:所声明的协议版本不被支持 |
|
|
133
|
+
|
|
134
|
+
## VS Code extension
|
|
135
|
+
|
|
136
|
+
[`examples/vscode/`](examples/vscode/) 附带**纯 UI** 扩展(侧栏:DSH 会话、诊断列表、quickfix 一键应用、点击定位、格式化)及其经 ACP 风格 JSON-RPC 连接的 headless 后端组合(`backend/cordis.yml`)。扩展不实现任何 LSP 逻辑——所有能力与每一笔写入都属于插件。安装步骤、设置项与动图录制脚本见 [`examples/vscode/README.md`](examples/vscode/README.md)。
|
|
137
|
+
|
|
138
|
+

|
|
139
|
+
|
|
140
|
+
## Permissions & data
|
|
141
|
+
|
|
142
|
+
- **权限**:格式化与重命名走官方权限预设与审批 —— `fs/write-intent` waterfall 与 `sandbox_permissions` / `justification` 升级对,经 `ctx.approval` 裁决。插件在其 workshop manifest 中声明 `fs:read`、`fs:write`、`subprocess:spawn` 与 `network:none`。
|
|
143
|
+
- **数据**:不向磁盘写入任何东西;工具结果只存在于会话日志(无跨会话持久化)。编辑器协议只保留一个有界的内存 LRU 诊断缓存,带新鲜度戳,绝不跨重启持久化。
|
|
144
|
+
- **无网络**:插件不发起任何网络请求;它通过本地子进程 stdio 与语言服务器通信。
|
|
145
|
+
|
|
146
|
+
## Security boundaries
|
|
147
|
+
|
|
148
|
+
- **默认只读。** 八个工具中有六个仅作参考;只有 `lsp_format` 与 `lsp_rename` 会变更,且按真实的 `write`/`edit` 变更对待。
|
|
149
|
+
- **走官方 seam,而非另起炉灶。** 每个字节都经过 `fs/write-intent` waterfall(观测 → 守卫写 → 观测)与每次调用的沙箱策略;升级路径与官方 `write`/`edit` 工具一致。
|
|
150
|
+
- **响亮、快速、结构化地失败。** `servers` 为空且无 `ctx.lsp` seam → `LSP_ACTION_UNAVAILABLE`;只读会话在任何服务器往返前 → `LSP_ACTION_READ_ONLY`;命令形态只报告、绝不执行。
|
|
151
|
+
- **冲突绝不覆盖。** 文件读后已变则以 `LSP_ACTION_CONFLICT` 失败;`lsp_rename` 在第一笔写入前预检每个待改文件。
|
|
152
|
+
- **有界工作。** 结果上限、字节上限与平台的 timeout 策略约束每一次调用;诊断缓存是有界 LRU。
|
|
153
|
+
- **模型路径不缓存任何东西。** 工具结果只存在于会话日志;诊断缓存绝不跨重启持久化。
|
|
154
|
+
- **坏服务器响亮失败。** 命令缺失在加载期即失败;启动即死的服务器以 `LSP_ACTION_SERVER_FAILED` + stderr 尾部失败(启动失败先自动换新进程重试一次)。
|
|
155
|
+
- **提示词卫生。** 本插件不向会话系统提示词注入任何 persona 或提示词段落——面向模型的接口只有八个工具 Schema。
|
|
156
|
+
|
|
157
|
+
## Architecture
|
|
158
|
+
|
|
159
|
+
动作**优先走官方 seam**,未命中则回落插件自带的最小 stdio 客户端:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
lsp_diagnostics / lsp_format / lsp_completion / lsp_code_action /
|
|
163
|
+
lsp_symbols / lsp_signature / lsp_inlay_hints / lsp_rename
|
|
164
|
+
│
|
|
165
|
+
▼
|
|
166
|
+
ctx.lsp seam(扩展后:diagnostics / formatDocument / completion)
|
|
167
|
+
│ 缺席 · 旧版 · 该文件无 provider
|
|
168
|
+
▼
|
|
169
|
+
内置 stdio 客户端 ← servers 表(ctx.subprocess.spawn + JSON-RPC)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
seam 扩展已向上游提案(`upstream/lsp-action-seam.patch`,PR 描述见 `upstream/PR-description.md`)。合入后插件无需改动即自动迁移——内置客户端停止被使用即可。内置客户端会保留为 `servers` 表的独立兜底。**编辑器协议**复用同一 runner、同一写入路径与同一权限机制。完整调研与设计笔记:[`docs/seam-extension-notes.md`](docs/seam-extension-notes.md)。
|
|
173
|
+
|
|
174
|
+
## Known limitations
|
|
175
|
+
|
|
176
|
+
- **瞬态文档。** 每次动作都是打开文件 → 发一个请求 → 关闭文件(与官方 stdio host 一致)。依赖常驻打开文件的基于项目的服务器(tsls 在无打开文档时拒绝 `workspace/symbol`)可通过给 `lsp_symbols` 传 `file_path` 解决。tsls 在该生命周期下对 `textDocument/signatureHelp` 返回 `null`;其他服务器(gopls、pyright、rust-analyzer)正常应答。
|
|
177
|
+
- **范围格式化要求服务器的 range provider。** 只广告全文格式化的服务器对范围请求以 `LSP_ACTION_UNSUPPORTED` 失败。
|
|
178
|
+
- **重命名只应用文本编辑。** 服务器重命名结果中的资源操作(新建/删除/重命名文件)以 `LSP_ACTION_UNSUPPORTED` 拒绝;越出工作区的编辑在任何写入发生前以 `LSP_ACTION_CONFLICT` 失败。
|
|
179
|
+
|
|
180
|
+
## Development
|
|
181
|
+
|
|
182
|
+
```sh
|
|
183
|
+
pnpm install # node ^22.19 || >=24
|
|
184
|
+
pnpm run lint # oxlint over src/ and tests/
|
|
185
|
+
pnpm test # vitest: unit + fixture-server integration + editor-protocol e2e + real tsls e2e
|
|
186
|
+
pnpm run test:coverage # coverage gate
|
|
187
|
+
pnpm build # tsc --noEmitOnError → lib/
|
|
188
|
+
pnpm run prepare # tsc --noEmitOnError (runs on install)
|
|
189
|
+
pnpm run prepublishOnly # tsc --noEmitOnError (runs before publish)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Topics
|
|
193
|
+
|
|
194
|
+
`dsh`, `dsh-plugin`, `deepseek-harness`, `lsp`, `language-server`, `diagnostics`, `formatting`, `completion`, `code-action`, `symbols`, `signature-help`, `inlay-hints`, `rename`, `refactor`, `ide`, `editor`, `vscode`, `acp`, `json-rpc`
|
|
195
|
+
|
|
196
|
+
## Contributors
|
|
197
|
+
|
|
198
|
+
- [@PerryLink](https://github.com/PerryLink) —— 创建者与维护者:LSP 动作客户端与服务器生命周期、全部八个工具、编辑器 action 协议、测试、CI,以及五语种文档。
|
|
199
|
+
|
|
200
|
+
## PerryLink DSH Plugin Family
|
|
201
|
+
|
|
202
|
+
本项目是 [PerryLink](https://github.com/PerryLink) 维护的 [15 个 DeepSeek Harness 插件](https://github.com/PerryLink)之一。如果你觉得这个插件有用,其余的很可能同样有用:
|
|
203
|
+
|
|
204
|
+
| Plugin | One-liner |
|
|
205
|
+
|---|---|
|
|
206
|
+
| [dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel) | 只读 MCP 运行时面板:/mcp 命令 + 设置页,状态/工具/错误一览 |
|
|
207
|
+
| [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | 工程纪律守门:需求审讯、测试证据门、对抗评审 |
|
|
208
|
+
| [dsh-background-agents](https://github.com/PerryLink/dsh-background-agents) | 持久化后台子代理:Web 侧边栏进度、随时留言与打断 |
|
|
209
|
+
| **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | 基于语言服务器的诊断/格式化/补全/代码动作/重命名 |
|
|
210
|
+
| [dsh-output-styles](https://github.com/PerryLink/dsh-output-styles) | 对标 Claude Code outputStyles 的运行时风格切换 |
|
|
211
|
+
| [dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind) | 对标 Claude Code /rewind:快照、会话 fork、一键回退 |
|
|
212
|
+
| [dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules) | Claude Code 风格声明式 allow/deny/ask 权限规则,带审计 |
|
|
213
|
+
| [dsh-auto-review](https://github.com/PerryLink/dsh-auto-review) | 审批链上的第二模型自动审查,默认 fail-closed |
|
|
214
|
+
| [dsh-memento](https://github.com/PerryLink/dsh-memento) | 带审批门的跨会话记忆:ctx.memory + SQLite + memory 工具 |
|
|
215
|
+
| [dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security) | 安全审计技能包:密钥扫描、依赖与供应链审查 |
|
|
216
|
+
| [dsh-session-pin](https://github.com/PerryLink/dsh-session-pin) | 在 Web 侧边栏置顶会话,持久排序 |
|
|
217
|
+
| [dsh-composer-history](https://github.com/PerryLink/dsh-composer-history) | Web 作曲器终端式输入历史:方向键、Ctrl+R 搜索 |
|
|
218
|
+
| [dsh-github](https://github.com/PerryLink/dsh-github) | DSH 的 GitHub PR/issue 集成,所有写操作经审批门 |
|
|
219
|
+
| [dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide) | 插件开发知识库,随 bundle 安装的按需 agent 技能 |
|
|
220
|
+
| [dsh-claude-move](https://github.com/PerryLink/dsh-claude-move) | 把 Claude Code 会话、记忆、技能和 CLAUDE.md 迁入 DSH |
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
[Apache License 2.0](LICENSE) © 2026 dsh-lsp-actions contributors
|