dsh-lsp-actions 0.3.0 → 0.3.1

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 CHANGED
@@ -3,7 +3,13 @@
3
3
  All notable changes to dsh-lsp-actions are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
- ## 0.3.0 — 2026-08-19
6
+ ## 0.3.1 — 2026-08-19
7
+
8
+ ### Fixed
9
+
10
+ - The editor service's request-id serial is now instance-owned instead of module-level, matching its documented per-instance semantics — a plugin reload no longer shares counter state across mounts.
11
+
12
+ ## 0.3.0 — 2026-08-16
7
13
 
8
14
  ### Added
9
15
 
package/README.es.md CHANGED
@@ -2,98 +2,163 @@
2
2
 
3
3
  # 🛰️ dsh-lsp-actions
4
4
 
5
- **La superficie de acción LSP para DeepSeek Harness — servidores de lenguaje reales, retroalimentación real.**
5
+ **La superficie de acción LSP para DeepSeek Harness — servidores de lenguaje reales, retroalimentación real y el backend de integración IDE para editores.**
6
6
 
7
- Diagnósticos, formateo, completado de código, correcciones rápidas, símbolos, ayuda de firmas y sugerencias insertadas para el bucle del editor de tu agente, impulsados por los mismos servidores de lenguaje que usa tu IDE.
7
+ *Diagnósticos, formateo, completado, acciones de código, símbolos, ayuda de firmas, sugerencias insertadas y renombrado para el bucle de editor de tu agente — más el protocolo estable de acciones para editores (`lsp.actions.*`) que permite a cualquier editor consumirlos directamente.*
8
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
- [![CI](https://github.com/PerryLink/dsh-lsp-actions/actions/workflows/ci.yml/badge.svg)](https://github.com/PerryLink/dsh-lsp-actions/actions/workflows/ci.yml)
12
- [![npm](https://img.shields.io/npm/v/dsh-lsp-actions?style=flat-square)](https://www.npmjs.com/package/dsh-lsp-actions)
13
- [![npm downloads](https://img.shields.io/npm/dw/dsh-lsp-actions?style=flat-square)](https://www.npmjs.com/package/dsh-lsp-actions)
14
- [![License](https://img.shields.io/badge/License-Apache%202.0-D22128?style=flat-square)](LICENSE)
15
- [![Node](https://img.shields.io/badge/Node-%5E22.19%20%7C%7C%20%3E%3D24-43853D?style=flat-square)](package.json)
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-lsp-actions/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-lsp-actions/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-lsp-actions?label=version)](https://github.com/PerryLink/dsh-lsp-actions/releases)
14
+ [![npm version](https://img.shields.io/npm/v/dsh-lsp-actions)](https://www.npmjs.com/package/dsh-lsp-actions)
15
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-lsp-actions)](https://www.npmjs.com/package/dsh-lsp-actions)
16
16
 
17
- [English](README.md) · [简体中文](README.zh-CN.md) · [Español](README.es.md) · [हिन्दी](README.hi.md) · [Português](README.pt.md)
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
- > **Nuevo (v0.3.0):** backend de integración IDE — el protocolo de acciones para editores `lsp.actions.list` / `lsp.actions.run` / `lsp.events` (v1) y el ejemplo mínimo de VS Code. La especificación canónica del protocolo está documentada en [README.md](README.md) y [README.zh-CN.md](README.zh-CN.md) (arquitectura, versionado y compatibilidad hacia atrás); la especificación completa del wire: [docs/editor-protocol.md](docs/editor-protocol.md) / [docs/editor-protocol.zh-CN.md](docs/editor-protocol.zh-CN.md).
23
+ ## Compatibility
24
24
 
25
- ## Qué aporta este plugin a tu agente
25
+ | Surface | Status |
26
+ |---|---|
27
+ | Harness | DeepSeek Harness `0.1.0-rc.6` (compatibilidad declarada para `>=0.1.0-rc.6`) |
28
+ | Node | `^22.19.0 \|\| >=24.0.0` |
29
+ | Platforms | Todas (host puro; subprocesos + sistema de archivos, sin red) |
30
+ | Model | Cualquiera (las herramientas son independientes del modelo; el plugin nunca llama a un modelo) |
26
31
 
27
- El seam oficial `ctx.lsp` de DeepSeek Harness cubre la **navegación** (ir a definición, referencias, implementación, hover). `dsh-lsp-actions` completa la **superficie de acción**: el bucle de retroalimentación que un agente necesita mientras escribe y corrige código:
32
+ ## What you get
28
33
 
29
- | Herramienta | Qué hace | ¿Escribe? |
30
- | --- | --- | --- |
31
- | `lsp_diagnostics <file>` | Errores, advertencias y sugerencias del compilador/analizador con severidad, rango, mensaje y servidor de origen | ❌ solo lectura |
32
- | `lsp_format <file> [range?]` | Formatea un archivo o selección mediante el servidor de lenguaje y aplica el resultado, devolviendo el diff | ✅ vía `fs/write-intent` + política sandbox |
33
- | `lsp_completion <file> <line> <character>` | Sugerencias de completado en una posición del cursor, incluido el texto de inserción real | ❌ solo lectura |
34
- | `lsp_code_action <file> [range?] [only?]` | Correcciones/refactorizaciones verificadas por el servidor (con sus ediciones) para un rango o el primer diagnóstico | ❌ solo referencia |
35
- | `lsp_symbols <query?> <file_path?>` | Búsqueda de símbolos por nombre en todo el workspace, o el esquema de símbolos de un archivo | ❌ solo lectura |
36
- | `lsp_signature <file> <line> <character>` | Ayuda de firmas (parámetros y documentación) dentro de una llamada | ❌ solo lectura |
37
- | `lsp_inlay_hints <file> [range?]` | Anotaciones de tipo y sugerencias de nombres de parámetros del servidor | ❌ solo lectura |
38
- | `lsp_rename <file> <line> <character> <new_name>` | Renombrado de símbolo verificado por el servidor, aplicado en todo el workspace con diffs por archivo | ✅ vía `fs/write-intent` + política sandbox |
34
+ `dsh-lsp-actions` se monta como una única fila de host (`id: lsp-actions`, `name: dsh-lsp-actions`, `inject: [tools, fs, subprocess]`). El seam oficial `ctx.lsp` de DeepSeek Harness cubre la **navegación** (ir a definición, referencias, implementación, hover); este plugin completa la **superficie de acción**: el bucle de retroalimentación que un agente necesita mientras escribe y corrige código:
39
35
 
40
- > ✨ Una ejecución real de `typescript-language-server` forma parte de la suite de tests: diagnósticos, formateo, completado, búsqueda de símbolos y renombrado se verifican de extremo a extremo contra un servidor vivo, no solo con mocks. La suite es autocontenida (tsls es una devDependency) y corre en CI con Node 22/24 en Linux, Windows y macOS.
36
+ 1. **Ocho herramientas `lsp_*`** — diagnósticos, formateo, completado, acciones de código, símbolos, ayuda de firmas, sugerencias insertadas y renombrado, todas servidas por los mismos servidores de lenguaje que usa tu IDE.
37
+ 2. **Protocolo de acciones para editores v1** — una superficie JSON-RPC estable (`lsp.actions.list` / `lsp.actions.run` / `lsp.events`) que permite a cualquier editor (VS Code primero) consumir esas capacidades directamente.
38
+ 3. **Verificación con servidor real** — una ejecución real de `typescript-language-server` forma parte de la suite de tests (autocontenida, CI en Node 22/24 en Linux, Windows y macOS), no solo mocks.
41
39
 
42
- ## Inicio rápido
40
+ ## Quick start
43
41
 
44
42
  ```sh
45
- dsh plugin --profile <name> add <ruta-o-tarball-de-dsh-lsp-actions>
46
- ```
47
-
48
- Configura una entrada por servidor de lenguaje (la forma replica la configuración oficial de `lsp-stdio`):
49
-
50
- ```yaml
51
- # en el cordis.patch.yml de tu perfil (o en la fila del 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
- Las ocho herramientas se registran siempre. Con una **tabla `servers` vacía y ningún seam `ctx.lsp` montado, las llamadas fallan en voz alta** con `LSP_ACTION_UNAVAILABLE` indicando qué configurar — el plugin nunca arranca servidores que no configuraste. Un seam `ctx.lsp` montado **después** de este plugin se detecta en la siguiente llamada (la detección del seam es por llamada, así que el orden de carga no importa).
46
+ # or from npm (published releases)
47
+ dsh plugin --profile web add dsh-lsp-actions
80
48
 
81
- ## Por qué es seguro por construcción
49
+ # 2. restart and verify the row
50
+ dsh --profile web --dump-config | grep -A3 'id: lsp-actions'
51
+ ```
82
52
 
83
- - **El formateo y el renombrado son mutaciones reales, tratadas como `write`/`edit`.** Cada byte pasa por el waterfall `fs/write-intent` (observación → escritura protegida → observación) y por la política sandbox de cada llamada. `lsp_rename` pre-vuela cada archivo editado (contención en el workspace, comprobación de solapamientos, lectura con tope de bytes) *antes* de la primera escritura, de modo que una respuesta mala del servidor no puede dejar un renombrado a medio aplicar.
84
- - **Todo lo demás es de solo lectura por diseño.** Las acciones de código, completados, símbolos, firmas y sugerencias se reportan como material de referencia; aplicarlas es decisión propia del modelo con write/edit. Las formas de comando se reportan y **nunca se ejecutan**.
85
- - **Las sesiones de solo lectura fallan en voz alta, rápido y estructurado** — `LSP_ACTION_READ_ONLY` con el marcador compartido `[sandbox: …]`, lanzado *antes* de cualquier ida y vuelta con el servidor.
86
- - **La escalada coincide con las herramientas oficiales.** Bajo un sistema de archivos restrictivo, `lsp_format` y `lsp_rename` anuncian el mismo reintento único `sandbox_permissions` / `justification` que `write`/`edit`, resuelto mediante `ctx.approval`.
87
- - **Los conflictos nunca pisan nada.** Si el archivo cambió en disco después de leerse, la escritura protegida falla con `LSP_ACTION_CONFLICT` y se le dice al modelo que elija: releer y repetir, o aplicar el diff manualmente.
88
- - **Los timeouts son de la plataforma.** Cada herramienta declara `timeoutMs`; la política oficial `dsh-tool-call-timeout-policy` lo hace cumplir, y cada await respeta `exec.signal`.
89
- - **No se cachea nada.** Los resultados viven solo en el log de sesión; no hay persistencia entre sesiones.
53
+ ## Install & uninstall
54
+
55
+ - **git channel** (último `main`): `dsh plugin --profile web add "github:PerryLink/dsh-lsp-actions#main"` — el script `prepare` compila (`tsc --noEmitOnError`).
56
+ - **npm channel** (versiones publicadas): `dsh plugin --profile web add dsh-lsp-actions`.
57
+ - **tarball channel**: ejecuta `pnpm pack` en este repo y luego `dsh plugin --profile web add ./dsh-lsp-actions-<version>.tgz`.
58
+ - **uninstall**: `dsh plugin --profile web remove dsh-lsp-actions` (o quita la fila del patch del perfil).
59
+
60
+ ## Configuration
61
+
62
+ Todos los ajustes son campos Schemastery `Config` (modificables desde cordis.yml). Una sobrescritura dirigida por id reemplaza toda la fila — repite cada clave que necesites. `cordis.patch.yml` documenta cada clave en línea.
63
+
64
+ | Key | Default | Meaning |
65
+ |---|---|---|
66
+ | `servers` | `{}` | Servidores de lenguaje nombrados; una tabla vacía no activa ningún servidor |
67
+ | `editor.enabled` | `false` | Sirve el protocolo de acciones para editores por JSON-RPC stdio (solo backend headless) |
68
+ | `editor.requestTimeoutMs` | `60000` | Presupuesto de timeout por ejecución (ms) del protocolo de editor |
69
+ | `editor.diagnosticsCacheMaxFiles` | `64` | Tamaño de la caché LRU de diagnósticos (en archivos) |
70
+ | `maxDiagnostics` | `200` | Tope de diagnósticos por resultado |
71
+ | `maxCompletionItems` | `20` | Tope de elementos de completado por resultado |
72
+ | `maxCodeActions` | `50` | Tope de acciones de código por resultado |
73
+ | `maxSymbols` | `100` | Tope de resultados de símbolos |
74
+ | `maxSignatures` | `10` | Tope de ayuda de firmas |
75
+ | `maxInlayHints` | `200` | Tope de sugerencias insertadas |
76
+ | `maxResultChars` | `16000` | Tope del resultado renderizado (caracteres) |
77
+ | `maxDocumentBytes` | `4000000` | Tope de lectura de documento (bytes) |
78
+ | `timeoutMs` | `60000` | Timeout por llamada, aplicado por la política oficial de timeout |
79
+
80
+ Cada entrada de `servers` es un `LspServerEntry`: `command` (ejecutable resuelto en PATH al cargar) y `extensionToLanguage` (`".ts"` → `typescript`) son obligatorios; los opcionales `fileGlobs`, `args`, `env`, `initializationOptions`, `configuration`, `formattingOptions`, `maxMessageBytes`, `maxStderrBytes`, `killGraceMs`, `shutdownTimeoutMs`, `diagnosticsSettleMs`, `diagnosticsDebounceMs` e `idleTimeoutMs` (`0` = mantener vivo el proceso del servidor) ajustan el cliente stdio integrado.
81
+
82
+ ## Tools & surfaces
83
+
84
+ | Surface | Kind | Notes |
85
+ |---|---|---|
86
+ | `lsp_diagnostics` | tool | `<file>` — errores, advertencias y sugerencias del compilador/analizador con severidad, rango, mensaje y servidor de origen (solo lectura) |
87
+ | `lsp_format` | tool | `<file> [range?]` — formatea un archivo/selección mediante el servidor de lenguaje y lo aplica, devolviendo el diff (escribe vía `fs/write-intent`) |
88
+ | `lsp_completion` | tool | `<file> <line> <character>` — sugerencias de completado en una posición del cursor, incluido el texto de inserción (solo lectura) |
89
+ | `lsp_code_action` | tool | `<file> [range?] [only?]` — correcciones/refactorizaciones verificadas por el servidor con sus ediciones, para un rango o el primer diagnóstico (solo referencia) |
90
+ | `lsp_symbols` | tool | `<query?> <file_path?>` — búsqueda de símbolos por nombre en todo el workspace, o el esquema de un archivo (solo lectura) |
91
+ | `lsp_signature` | tool | `<file> <line> <character>` — ayuda de firmas (parámetros y documentación) dentro de una llamada (solo lectura) |
92
+ | `lsp_inlay_hints` | tool | `<file> [range?]` — anotaciones de tipo y sugerencias de nombres de parámetros del servidor (solo lectura) |
93
+ | `lsp_rename` | tool | `<file> <line> <character> <new_name>` — renombrado verificado por el servidor, aplicado en todo el workspace con diffs por archivo (escribe vía `fs/write-intent`) |
94
+ | `lsp.actions.*` | protocol | Protocolo de acciones para editores v1: `lsp.actions.list` / `lsp.actions.run` / `lsp.events` por JSON-RPC |
95
+ | `examples/vscode/` | extension | Extensión de VS Code solo-UI más la composición de backend headless a la que se conecta |
96
+
97
+ ## Editor action protocol v1
98
+
99
+ Cuando se establece `editor.enabled: true` en una composición headless dedicada, `dsh-lsp-actions` sirve un protocolo de editor estable por JSON-RPC 2.0 delimitado por saltos de línea (el mismo encuadre de wire que los transportes oficiales SDK/ACP):
100
+
101
+ | Method | What it does |
102
+ |---|---|
103
+ | `lsp.actions.list` | Devuelve la versión de protocolo `lsp-actions/v1`, el catálogo de acciones (`diagnostics.get`, `completion.get`, `quickfix.apply`, `format` — cada una marcada `writes`) y las sesiones DSH direccionables |
104
+ | `lsp.actions.run` | Ejecuta una acción con un sobre estructurado `{ requestId, action, status, result \| error }`; los errores llevan los códigos estables `LSP_ACTION_*` |
105
+ | `lsp.events` | Se suscribe a las notificaciones `lsp.event` transmitidas: `diagnostics.updated`, `action.status`, `file.changed`, `sessions.changed` |
106
+
107
+ Todas las acciones de escritura (`quickfix.apply`, `format`) pasan por los **presets de permisos oficiales y la aprobación**: una sesión `read-only` es rechazada con `LSP_ACTION_READ_ONLY` antes de cualquier ida y vuelta con el servidor, las ediciones viajan por el waterfall `fs/write-intent` y el par de escalado `sandbox_permissions` + `justification` se resuelve mediante el `approveEscalation` oficial (fail-closed cuando no hay quién decida). Especificación de wire completa, bilingüe: [`docs/editor-protocol.md`](docs/editor-protocol.md) · [`docs/editor-protocol.zh-CN.md`](docs/editor-protocol.zh-CN.md).
108
+
109
+ **Versionado y la promesa de compatibilidad hacia atrás**
110
+
111
+ - El protocolo está versionado — `lsp.actions.list` devuelve `protocol: "lsp-actions/v1"`, `version: 1`. **v1 está congelado:** los nombres de campos, ids de acción, tipos de evento y códigos de error se mantienen estables para siempre.
112
+ - La evolución es **solo aditiva**: nuevas acciones, campos y tipos de evento llegan sin subir la versión; la semántica existente nunca cambia en su sitio; un cambio que rompe compatibilidad se publica bajo una nueva versión de `protocol`, que los servidores pueden servir en paralelo.
113
+ - Los clientes deben ignorar campos, tipos de evento y acciones desconocidos, y enrutar por el `code` de error estable, nunca por el texto del mensaje.
114
+
115
+ **Códigos de error**
116
+
117
+ Cada fallo lleva un `code` estable; los modelos y llamadores enrutan por el código, nunca por el texto del mensaje.
118
+
119
+ | Code | Meaning |
120
+ |---|---|
121
+ | `LSP_ACTION_UNAVAILABLE` | Ninguna entrada de servidor ni provider del seam maneja este archivo |
122
+ | `LSP_ACTION_UNSUPPORTED` | El servidor (o el provider del seam) no anuncia la operación |
123
+ | `LSP_ACTION_SERVER_FAILED` | El servidor falló (con la cola de su stderr); los fallos de arranque reintentan una vez |
124
+ | `LSP_ACTION_MALFORMED_RESPONSE` | El servidor envió una carga estructuralmente inválida |
125
+ | `LSP_ACTION_CONFLICT` | El archivo cambió desde que se leyó, o las ediciones se solapan / salen de límites / salen del workspace |
126
+ | `LSP_ACTION_READ_ONLY` | El modo sandbox de la sesión prohíbe la escritura del formateo/renombrado |
127
+ | `LSP_ACTION_WORKSPACE_REQUIRED` | La sesión que llama no tiene un cwd de workspace donde enraizar el servidor |
128
+ | `LSP_ACTION_NO_SYMBOL` | El servidor no encontró un símbolo renombrable en la posición del cursor |
129
+ | `LSP_ACTION_UNKNOWN` | Protocolo de editor: id de acción desconocido, o ninguna acción de código coincidió con `title`/`index` |
130
+ | `LSP_ACTION_INVALID_ARGS` | Protocolo de editor: parámetros de acción mal formados |
131
+ | `LSP_ACTION_APPROVAL_UNAVAILABLE` | Protocolo de editor: la ruta de aprobación no pudo conceder un modo sandbox más amplio (fail-closed) |
132
+ | `LSP_PROTOCOL_VERSION_UNSUPPORTED` | Protocolo de editor: la versión de protocolo declarada no es compatible |
133
+
134
+ ## VS Code extension
135
+
136
+ [`examples/vscode/`](examples/vscode/) incluye una extensión **solo-UI** (barra lateral con las sesiones DSH, la lista de diagnósticos, aplicar quickfix con un clic, abrir en rango y formatear) más la composición de backend headless (`backend/cordis.yml`) a la que se conecta por JSON-RPC estilo ACP. La extensión implementa cero lógica LSP — cada capacidad y cada byte escrito pertenecen al plugin. Los pasos de instalación, ajustes y el script de grabación del gif de demostración están en [`examples/vscode/README.md`](examples/vscode/README.md).
137
+
138
+ ![Editor demo](docs/editor-demo.gif)
139
+
140
+ ## Permissions & data
141
+
142
+ - **Permisos**: el formateo y el renombrado viajan por los presets de permisos oficiales y la aprobación — el waterfall `fs/write-intent` y el par de escalado `sandbox_permissions` / `justification` resuelto mediante `ctx.approval`. El plugin declara `fs:read`, `fs:write`, `subprocess:spawn` y `network:none` en su manifiesto de workshop.
143
+ - **Datos**: no se almacena nada en disco; los resultados de las herramientas viven solo en el log de sesión (sin persistencia entre sesiones). El protocolo de editor mantiene una única caché LRU de diagnósticos en memoria, acotada, con sello de frescura y nunca persistida entre reinicios.
144
+ - **Sin red**: el plugin no hace peticiones de red; habla con los servidores de lenguaje por stdio de subprocesos locales.
145
+
146
+ ## Security boundaries
147
+
148
+ - **Solo lectura por defecto.** Seis de las ocho herramientas son solo de referencia; únicamente `lsp_format` y `lsp_rename` mutan, y lo hacen como mutaciones reales de `write`/`edit`.
149
+ - **Seams oficiales, no reimplementados.** Cada byte pasa por el waterfall `fs/write-intent` (observación → escritura protegida → observación) y por la política sandbox de cada llamada; el escalado coincide con las herramientas oficiales `write`/`edit`.
150
+ - **Falla en voz alta, rápido y estructurado.** `servers` vacío + sin seam `ctx.lsp` → `LSP_ACTION_UNAVAILABLE`; sesiones de solo lectura → `LSP_ACTION_READ_ONLY` antes de cualquier ida y vuelta con el servidor; las formas de comando se reportan y nunca se ejecutan.
151
+ - **Los conflictos nunca pisan nada.** Un archivo cambiado en disco tras leerse falla con `LSP_ACTION_CONFLICT`; `lsp_rename` pre-vuela cada archivo editado antes de la primera escritura.
152
+ - **Trabajo acotado.** Los topes de resultados, los topes de bytes y la política de timeout de la plataforma acotan cada llamada; la caché de diagnósticos es una LRU acotada.
153
+ - **Nada se cachea en la ruta del modelo.** Los resultados de las herramientas viven solo en el log de sesión; la caché de diagnósticos nunca persiste entre reinicios.
90
154
  - **Los servidores rotos fallan en voz alta.** Un ejecutable inexistente falla al cargar; un servidor que muere al arrancar falla la llamada con `LSP_ACTION_SERVER_FAILED` más la cola de su stderr (tras un reintento con proceso nuevo).
155
+ - **Higiene del prompt.** El plugin no inyecta persona ni prosa de prompt en el system prompt de la sesión — su superficie de cara al modelo son los ocho esquemas de herramientas.
91
156
 
92
- ## Arquitectura
157
+ ## Architecture
93
158
 
94
159
  Las acciones van **primero por el seam oficial** y caen al cliente stdio mínimo propio del 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 ← tabla servers (ctx.subprocess.spawn + JSON-RPC)
105
170
  ```
106
171
 
107
- La extensión del seam está propuesta upstream (`upstream/lsp-action-seam.patch`, descripción del PR en `upstream/PR-description.md`). Cuando aterrice, el plugin sigue funcionando sin cambios — el cliente integrado simplemente deja de usarse. El cliente integrado se conserva como respaldo independiente para la tabla `servers`. Notas completas de investigación y diseño: [`docs/seam-extension-notes.md`](docs/seam-extension-notes.md), [`upstream/README.md`](upstream/README.md).
108
-
109
- ## Referencia de configuración
110
-
111
- ```ts
112
- interface Config {
113
- /** Servidores de lenguaje nombrados; vacío = el cliente propio no sirve nada. */
114
- servers?: Record<string, LspServerEntry>
115
- maxDiagnostics?: number // por defecto 200
116
- maxCompletionItems?: number // por defecto 20
117
- maxCodeActions?: number // por defecto 50
118
- maxSymbols?: number // por defecto 100
119
- maxSignatures?: number // por defecto 10
120
- maxInlayHints?: number // por defecto 200
121
- maxResultChars?: number // por defecto 16000 (tope del resultado renderizado completo)
122
- maxDocumentBytes?: number // por defecto 4000000
123
- timeoutMs?: number // por defecto 60000 (aplicado por la política oficial de timeout)
124
- }
125
-
126
- interface LspServerEntry {
127
- command: string // ejecutable, resuelto en PATH al cargar
128
- extensionToLanguage: Record<string, string> // ".ts" → "typescript"
129
- fileGlobs?: string[] // opcional; los globs ganan al mapa de extensiones
130
- args?: string[] // sin shell
131
- env?: Record<string, string>
132
- initializationOptions?: unknown
133
- configuration?: unknown // forma de objeto responde workspace/configuration por sección
134
- formattingOptions?: unknown // p. ej. { tabSize: 2, insertSpaces: true }
135
- maxMessageBytes?: number // por defecto 16000000
136
- maxStderrBytes?: number // por defecto 1000000
137
- killGraceMs?: number // por defecto 2000
138
- shutdownTimeoutMs?: number // por defecto 5000
139
- diagnosticsSettleMs?: number // por defecto 2000 (ventana de diagnósticos solo push)
140
- diagnosticsDebounceMs?: number // por defecto 250 (período de calma tras el último lote empujado)
141
- idleTimeoutMs?: number // por defecto 0 (0 = mantener vivo el proceso del servidor)
142
- }
143
- ```
144
-
145
- ### Códigos de error
172
+ La extensión del seam está propuesta upstream (`upstream/lsp-action-seam.patch`, descripción del PR en `upstream/PR-description.md`). Cuando aterrice, el plugin sigue funcionando sin cambios — el cliente integrado simplemente deja de usarse. El cliente integrado se conserva como respaldo independiente para la tabla `servers`. El **protocolo de editor** usa el mismo runner, la misma ruta de escritura y la misma maquinaria de permisos. Notas completas de investigación y diseño: [`docs/seam-extension-notes.md`](docs/seam-extension-notes.md).
146
173
 
147
- Cada fallo lleva un `code` estable en el resultado de error; los modelos y llamadores enrutan por el código, nunca por el texto del mensaje.
174
+ ## Known limitations
148
175
 
149
- | Code | Significado |
150
- | --- | --- |
151
- | `LSP_ACTION_UNAVAILABLE` | Ninguna entrada de servidor ni provider del seam maneja este archivo. |
152
- | `LSP_ACTION_UNSUPPORTED` | El servidor (o el provider del seam) no anuncia la operación. |
153
- | `LSP_ACTION_SERVER_FAILED` | El servidor falló (con la cola de su stderr); los fallos de arranque reintentan una vez. |
154
- | `LSP_ACTION_MALFORMED_RESPONSE` | El servidor envió una carga estructuralmente inválida. |
155
- | `LSP_ACTION_CONFLICT` | El archivo cambió desde que se leyó, o las ediciones del servidor se solapan / salen de límites / salen del workspace. |
156
- | `LSP_ACTION_READ_ONLY` | El modo sandbox de la sesión prohíbe la escritura del formateo/renombrado. |
157
- | `LSP_ACTION_WORKSPACE_REQUIRED` | La sesión que llama no tiene un cwd de workspace donde enraizar el servidor. |
158
- | `LSP_ACTION_NO_SYMBOL` | El servidor no encontró un símbolo renombrable en la posición del cursor. |
176
+ - **Documentos transitorios.** Cada acción abre el archivo, ejecuta una petición y lo cierra de nuevo (igual que el host stdio oficial). Los servidores basados en proyecto que exigen un archivo abierto residente para peticiones sin documento (tsls rechaza `workspace/symbol` sin uno) se sirven pasando `file_path` a `lsp_symbols`. tsls también responde `textDocument/signatureHelp` con `null` bajo este ciclo de vida; otros servidores (gopls, pyright, rust-analyzer) lo sirven con normalidad.
177
+ - **El formateo de rango exige el provider de rango del servidor.** Los servidores que solo anuncian formateo de documento completo fallan las peticiones de rango con `LSP_ACTION_UNSUPPORTED`.
178
+ - **El renombrado solo aplica ediciones de texto.** Las operaciones de recursos (crear/borrar/renombrar archivos) en la respuesta de renombrado del servidor se rechazan con `LSP_ACTION_UNSUPPORTED`, y las ediciones fuera del workspace fallan como `LSP_ACTION_CONFLICT` antes de escribir nada.
159
179
 
160
- ### Versión de host soportada
180
+ ## Development
161
181
 
162
- El plugin declara los paquetes de DeepSeek Harness como **peer dependencies** (`@deepseek-ai/dsh-fs`, `dsh-llm`, `dsh-sandbox`, `dsh-subprocess`, `dsh-tools` ≥ `0.1.0-rc.6`), de modo que una sola copia sirve al host y al plugin. Probado contra `0.1.0-rc.6`.
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
- ### Limitaciones conocidas
192
+ ## Topics
165
193
 
166
- - **Documentos transitorios.** Cada acción abre el archivo, ejecuta una petición y lo cierra de nuevo (igual que el host stdio oficial). Los servidores basados en proyecto que exigen un archivo abierto residente para peticiones sin documento (tsls rechaza `workspace/symbol` sin uno) se sirven pasando `file_path` a `lsp_symbols`, que mantiene el archivo de enrutamiento abierto durante esa petición. tsls también responde `textDocument/signatureHelp` con `null` bajo este ciclo de vida; otros servidores (gopls, pyright, rust-analyzer) lo sirven con normalidad.
167
- - **El formateo de rango exige el provider de rango del servidor.** Los servidores que solo anuncian formateo de documento completo fallan las peticiones de rango con `LSP_ACTION_UNSUPPORTED`.
168
- - **El renombrado solo aplica ediciones de texto.** Las operaciones de recursos (crear/borrar/renombrar archivos) en la respuesta de renombrado del servidor se rechazan con `LSP_ACTION_UNSUPPORTED`, y las ediciones fuera del workspace fallan con `LSP_ACTION_CONFLICT` antes de escribir nada. En servidores `utf-8`/`utf-32`, las posiciones de renombrado entre archivos se decodifican leyendo cada archivo editado; un archivo editado ilegible falla la llamada como conflicto en lugar de decodificar mal las posiciones.
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
- ## Desarrollo
196
+ ## Contributors
171
197
 
172
- ```sh
173
- pnpm install
174
- pnpm run lint # oxlint sobre src/ y tests/
175
- pnpm test # más de 240 tests: unidad + integración con servidor fixture + e2e real con tsls
176
- pnpm run test:coverage # puertas: líneas/sentencias/funciones ≥ 90%, ramas ≥ 85%
177
- pnpm build # emite lib/
178
- ```
198
+ - [@PerryLink](https://github.com/PerryLink) — creador y mantenedor: el cliente de acciones LSP y el ciclo de vida del servidor, las ocho herramientas, el protocolo de acciones para editores, los tests, la CI y la documentación en cinco idiomas.
179
199
 
180
- ## Contribuidores
200
+ ## PerryLink DSH Plugin Family
181
201
 
182
- Gracias a todas las personas que han contribuido a este proyecto:
202
+ Este proyecto es uno de los [15 plugins de DeepSeek Harness](https://github.com/PerryLink) mantenidos por [PerryLink](https://github.com/PerryLink). Si este te ayuda, es probable que los demás también:
183
203
 
184
- - [PerryLink](https://github.com/PerryLink) — el plugin en sí: el cliente de acciones LSP y el ciclo de vida del servidor, las ocho herramientas, los tests, la CI y la documentación.
204
+ | Plugin | One-liner |
205
+ |---|---|
206
+ | [dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel) | Panel de runtime MCP de solo lectura: comando /mcp + pestaña de configuración con estado, herramientas y errores |
207
+ | [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | Guardia de disciplina de ingeniería: interrogatorio de requisitos, puertas de test, revisión adversaria |
208
+ | [dsh-background-agents](https://github.com/PerryLink/dsh-background-agents) | Agentes hijos en segundo plano duraderos con una barra lateral Web, mensajería e interrupción |
209
+ | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | Diagnósticos, formateo, completado, acciones de código y renombrado LSP sobre servidores de lenguaje |
210
+ | [dsh-output-styles](https://github.com/PerryLink/dsh-output-styles) | Cambio de estilo en tiempo de ejecución equivalente a outputStyles de Claude Code |
211
+ | [dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind) | Equivalente a /rewind de Claude Code: instantáneas, bifurcaciones de sesión, restauración de un solo paso |
212
+ | [dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules) | Reglas de permisos declarativas allow/deny/ask estilo Claude Code con auditoría |
213
+ | [dsh-auto-review](https://github.com/PerryLink/dsh-auto-review) | Auto-revisión con segundo modelo en la cadena de aprobación, fail-closed por defecto |
214
+ | [dsh-memento](https://github.com/PerryLink/dsh-memento) | Memoria entre sesiones con puerta de aprobación: seam ctx.memory + SQLite + herramienta memory |
215
+ | [dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security) | Paquete de habilidades de auditoría de seguridad: escaneo de secretos, revisión de dependencias y cadena de suministro |
216
+ | [dsh-session-pin](https://github.com/PerryLink/dsh-session-pin) | Fija sesiones en la barra lateral Web con orden duradero |
217
+ | [dsh-composer-history](https://github.com/PerryLink/dsh-composer-history) | Historial de entrada estilo terminal para el compositor web: flechas, búsqueda Ctrl+R |
218
+ | [dsh-github](https://github.com/PerryLink/dsh-github) | Integración de PR/issues de GitHub para DSH, cada escritura con puerta de aprobación |
219
+ | [dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide) | Base de conocimiento de desarrollo de plugins como habilidad de agente bajo demanda |
220
+ | [dsh-claude-move](https://github.com/PerryLink/dsh-claude-move) | Migra sesiones, memoria, habilidades y CLAUDE.md de Claude Code a 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