All notable changes to dsh-lsp-actions are documented here. The format follows Keep a Changelog.
- Align the devDependency pins to the published dsh
0.1.2-rc.1line, repoint the compat workflow (CLI/base/headless) from the stale0.1.2-alpha.3pins to0.1.2-rc.1, sync the editor backend example dependencies, and refresh the five-language README compatibility rows; no behavior change.
- Align the devDependency pins to the published dsh 0.1.2-alpha.5 line and re-verify the adaptation claims; no behavior change.
- Upgrade the
@deepseek-ai/dsh-*dev dependencies from0.1.2-alpha.2to0.1.2-alpha.3(peer ranges stay>=0.1.0-rc.8 <0.2.0), align the@deepseek-ai/cordis/@deepseek-ai/schemasterypeer and dev carets to^4.0.2/^3.18.2, refreshdshWorkshop.compatibility.dshVersions, sync the editor backend example dependencies to^0.1.2-alpha.3, repoint the compat workflow to the alpha.3 CLI/base/headless, and rewrite the five-language README compatibility rows to the alpha.3 fact (the plugin writes no session events itself).
- Stop importing the
CallIdruntime value from@deepseek-ai/dsh-llm(removed in DeepSeek Harness0.1.2-alpha.1; renamedToolCallId): the editor escalation-approval context now builds its call id through a local identity helper typed from the@deepseek-ai/dsh-toolsexecution contract, so approvals no longer crash on hosts without the old export.
- 常驻会话客户端(保 didOpen)+ runner 抽象为公开 provider 接口。
- Schemastery compatibility floor. The
@deepseek-ai/schemasterypeer and dev dependency floor is raised from^3.0.0to^3.18.0, matching the harness release line. No behavior changes.
- rc.2 compatibility release. All
@deepseek-ai/dsh-*dev dependencies are pinned to0.1.1-rc.2, the harness peer-dependency ranges stay>=0.1.0-rc.8 <0.2.0,dshWorkshop.compatibility.dshVersionsnow declares0.1.1-rc.2, the CI compat pins and the VS Code backend example track the same release line, and the READMEs declare DeepSeek Harness0.1.1-rc.2compatibility. No behavior changes — the full suite (including the real typescript-language-server e2e) passes against the rc.2 runtime.
- rc.8 compatibility release. All
@deepseek-ai/dsh-*dev dependencies are pinned to0.1.0-rc.8and the harness peer dependencies are widened to>=0.1.0-rc.8 <0.2.0; the VS Code backend example tracks the same release line, and the READMEs declare DeepSeek Harness0.1.0-rc.8compatibility. No behavior changes — the full suite (including the real typescript-language-server e2e) passes against the rc.8 runtime.
- 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.
- Editor action protocol v1 — the IDE integration backend. With
editor.enabled: truein a dedicated headless composition, the plugin serveslsp.actions.list/lsp.actions.run/lsp.eventsover newline-delimited JSON-RPC 2.0 (wire-framing-compatible with the official SDK/ACP transports), so any editor can consume the LSP capabilities directly — no agent round-trip.- Four v1 actions:
diagnostics.get(read-only),completion.get(read-only, zero-based LSP positions),quickfix.apply(selects a server-verified code action bytitle/indexand applies its edits), andformat(whole-file or range). runalways answers one structured{ requestId, action, status, result | error }envelope; failures carry the stableLSP_ACTION_*codes, extended withLSP_ACTION_UNKNOWN,LSP_ACTION_INVALID_ARGS,LSP_ACTION_APPROVAL_UNAVAILABLE, andLSP_PROTOCOL_VERSION_UNSUPPORTED.- Streamed
lsp.eventnotifications:diagnostics.updated,action.status,file.changed,sessions.changed;lsp.events {subscribe}controls the stream. - Versioning & backward compatibility:
lsp-actions/v1is frozen; evolution is additive only; breaking changes ship under a new protocol version. Documented in the bilingual specdocs/editor-protocol.md/docs/editor-protocol.zh-CN.md.
- Four v1 actions:
- Official permission presets and approval for editor writes.
quickfix.applyandformatresolve the addressed session's official sandbox policy (read-only sessions fail withLSP_ACTION_READ_ONLYbefore any server round-trip), write through thefs/write-intentwaterfall with guarded writes, and resolve thesandbox_permissions+justificationescalation pair through the officialapproveEscalationask (fail-closed withLSP_ACTION_APPROVAL_UNAVAILABLEwhen no answerer can decide). - Bounded LRU diagnostics cache (
editor.diagnosticsCacheMaxFiles, default 64): freshness-stamped snapshots, least-recently-used eviction, invalidated by filesystem observations and by the plugin's own writes; never persisted across restarts. Cached first-error ranges power range-lessquickfix.applytargeting. - Schema configuration for the backend:
editor.enabled(defaultfalse— only headless backends may claim stdio),editor.requestTimeoutMs(default 60000, enforced per run), andeditor.diagnosticsCacheMaxFiles. Misconfiguration fails at load. - Reversible registration. The transport, event listeners, and cache live entirely inside the plugin's effect scope; stopping or updating the plugin tears the whole surface down.
examples/vscode/: a minimal UI-only VS Code extension (sidebar with DSH sessions + diagnostics list + one-click quickfix + open-at-range + format) plus the headless backend composition (backend/cordis.yml+bin.mjs). The extension implements zero LSP logic.- Tests: bounded-LRU coverage, editor-protocol service semantics (permission gating, escalation fail-closed, timeouts, cache invalidation), and a full diagnostics → quickfix → format chain over real JSON-RPC frames against the fixture LSP server.
- Prompt hygiene commitment: the plugin injects no persona or prompt prose (model-facing surface = the eight tool schemas); any future prompt segment must open with one short role sentence and stay brief, aligned with the official Minimal persona style.
- README (EN/zh-CN) now documents the IDE-backend architecture (editor protocol × official ACP server × Python SDK), the versioning promise, the VS Code example, and the extended error-code table; es/hi/pt READMEs point at the canonical protocol docs.
lsp_renametool: a server-verified symbol rename (textDocument/prepareRename+textDocument/rename) applied workspace-wide through the filesystem write-intent waterfall and the per-call sandbox policy, exactly likelsp_format. Edits are pre-flighted before the first write (workspace containment, overlap check, byte-capped read), no-op files are dropped, and the result renders per-file diff cards. Cross-document positions fromutf-8/utf-32servers are decoded per document by reading each edited file; unreadable targets fail as a structured conflict instead of mis-decoding positions. File resource operations in a rename answer are refused as unsupported. NewLSP_ACTION_NO_SYMBOLerror code for a bare cursor.- Four new read-only tools:
lsp_code_action(server-verified quickfixes, reported never applied),lsp_symbols(workspace-wide name search and per-file symbol outline),lsp_signature(signature help at a cursor), andlsp_inlay_hints(type/parameter hints). - Operation-specific seam extras: the seam query forwards
query(workspace symbol search),onlyKinds(code-action filters), andnewName(rename), so a future seam vintage can serve the extended operations directly. - Structured JSON-RPC errors:
LspRpcErrorcarries the server's wire error code, so advisory round-trips (prepareRename) can distinguish error responses from transport failures. - Position encoding negotiation for
utf-8andutf-32servers: request positions are encoded and server results are decoded through a per-document codec, so non-utf-16 servers no longer fail the handshake. workspace/symbolwith an open routing file: whenlsp_symbolsreceivesfile_pathwith a query, the file stays transiently open for the request, so project-based servers (tsls) that refuse document-free symbol search work.- One fresh-spawn retry when a server dies during its handshake, matching the official stdio host's single bad-transport retry; mid-action failures never retry.
- Idle server eviction (
idleTimeoutMsper server entry, default 0 = keep alive). - Push-diagnostic debounce (
diagnosticsDebounceMsper server entry, default 250 ms): the latest pushed batch wins inside the settle window instead of the first. - Per-section
workspace/configurationanswers: a plain-objectconfigurationanswers each requested section, falling back to the whole value. - CI (GitHub Actions: Node 22/24 × ubuntu/windows/macos lint+build+test matrix with a separate coverage-gate job) and coverage gates (lines/statements/functions ≥ 90%, branches ≥ 85%), plus a tag-triggered publish workflow for npm releases.
- Real-server e2e for rename and workspace symbols through typescript-language-server (the
suite is self-contained via the
typescript-language-serverdevDependency).
- The action surface is eight tools: the write-path safety contract (
write-intent, sandbox policy, conflict handling) now coverslsp_renamealongsidelsp_format; the shared sandbox escalation schema names the action (formatting/rename) in its advertised descriptions. - Tools are always registered. With an empty
serverstable and noctx.lspseam, calls fail loudly withLSP_ACTION_UNAVAILABLEinstead of the plugin contributing nothing. - Seam detection is lazy per call: a
ctx.lspseam mounted after this plugin (or re-added mid-session) is served without a reload. - Completion results now render the insertion text (
textEdit.newText/insertText) on an indented arrow line, because the model only sees rendered content. - Glob routes prefer the file's own extension mapping for the language id, falling back to the entry's first mapping only when the extension is not mapped.
- Diagnostics, format, and inlay results carry columns (and the format summary names the line span), improving UI precision and model readback.
- The harness packages are peer dependencies (
>=0.1.0-rc.6), so a host harness shares one copy and cross-versioninstanceofmismatches cannot silently break error mapping.
- Server re-spelled file URIs no longer corrupt rename targets. Servers re-spell the root URI sent at initialize (lowercase drive letter and percent-encoded colon on Windows), and the workspace-relative mapping sliced the raw URI at the raw root's length — mis-cutting every such URI into a garbage path. Containment is now judged on decoded, case-insensitive forms while the relative path is sliced from the decoded URI.
- Diagnostics on servers whose
textDocumentSyncexcludes transient open now fail withLSP_ACTION_UNSUPPORTED(previously unchecked for diagnostics). - A caller abort racing a seam failure now surfaces the signal's reason instead of the seam's unrelated error.
- The e2e suite no longer depends on a sibling harness checkout's node_modules.
- Initial release:
lsp_diagnostics,lsp_format, andlsp_completiontools over the extendedctx.lspseam proposal and the built-in stdio client.