PerryLink / dsh-lsp-actions

목록에 있음

LSP action surface for DeepSeek Harness: diagnostics, formatting, completion, code actions, symbols, signature help, inlay hints, and rename tools over language servers

main도구 소스 보기

설치

npx -y @deepseek-ai/dsh plugin --profile web add github:PerryLink/dsh-lsp-actions

이 설치 명령은 GitHub 저장소 주소에서 생성된 확인되지 않은 시작점입니다.

README

유지 관리자가 작성한 문서 스냅샷입니다.

GitHub에서 보기 ↗
커밋 04cf09e동기화 2026. 8. 17.

🛰️ dsh-lsp-actions

The LSP action surface for DeepSeek Harness — real language servers, real feedback, and the IDE integration backend for editors.

Diagnostics, formatting, completion, code actions, symbols, signature help, inlay hints, and rename for your agent's editor loop — plus the stable editor action protocol (lsp.actions.*) that lets any editor consume them directly.

License DSH plugin Node CI Version npm version npm downloads

English · 简体中文 · Español · Português · हिन्दी


Compatibility

SurfaceStatus
HarnessDeepSeek Harness 0.1.0-rc.6 (compat declared for >=0.1.0-rc.6)
Node^22.19.0 || >=24.0.0
PlatformsAll (pure host; subprocess + filesystem, no network)
ModelAny (tools are model-agnostic; the plugin never calls a model)

What you get

dsh-lsp-actions mounts as a single host row (id: lsp-actions, name: dsh-lsp-actions, inject: [tools, fs, subprocess]). The official DeepSeek Harness ctx.lsp seam covers navigation (go-to-definition, references, implementation, hover); this plugin completes the action surface — the feedback loop an agent needs while it writes and fixes code:

  1. Eight lsp_* tools — diagnostics, formatting, completion, code actions, symbols, signature help, inlay hints, and rename, all served by the same language servers your IDE uses.
  2. Editor action protocol v1 — a stable JSON-RPC surface (lsp.actions.list / lsp.actions.run / lsp.events) that lets any editor (VS Code first) consume those capabilities directly.
  3. Real-server verification — a real typescript-language-server run is part of the test suite (self-contained, CI on Node 22/24 across Linux, Windows, and macOS), not just mocks.

Quick start

# 1. install the bundle into your profile
dsh plugin --profile web add "github:PerryLink/dsh-lsp-actions#main"

# or from npm (published releases)
dsh plugin --profile web add dsh-lsp-actions

# 2. restart and verify the row
dsh --profile web --dump-config | grep -A3 'id: lsp-actions'

Install & uninstall

  • git channel (latest main): dsh plugin --profile web add "github:PerryLink/dsh-lsp-actions#main" — the prepare script builds (tsc --noEmitOnError).
  • npm channel (published releases): dsh plugin --profile web add dsh-lsp-actions.
  • tarball channel: pnpm pack in this repo, then dsh plugin --profile web add ./dsh-lsp-actions-<version>.tgz.
  • uninstall: dsh plugin --profile web remove dsh-lsp-actions (or remove the row from the profile patch).

Configuration

All tunables are Schemastery Config fields (changeable from cordis.yml). An id-targeted override replaces the whole row — restate every key you need. cordis.patch.yml documents each key inline.

KeyDefaultMeaning
servers{}Named language servers; an empty table activates no servers
editor.enabledfalseServe the editor action protocol over JSON-RPC stdio (headless backend only)
editor.requestTimeoutMs60000Per-run timeout budget (ms) for the editor protocol
editor.diagnosticsCacheMaxFiles64Bounded LRU diagnostics-cache size (files)
maxDiagnostics200Diagnostics cap per result
maxCompletionItems20Completion-items cap per result
maxCodeActions50Code-actions cap per result
maxSymbols100Symbol-results cap
maxSignatures10Signature-help cap
maxInlayHints200Inlay-hints cap
maxResultChars16000Rendered-result cap (chars)
maxDocumentBytes4000000Document-read cap (bytes)
timeoutMs60000Per-call timeout, enforced by the official timeout policy

Each servers entry is an LspServerEntry: command (executable resolved on PATH at load) and extensionToLanguage (".ts"typescript) are required; optional fileGlobs, args, env, initializationOptions, configuration, formattingOptions, maxMessageBytes, maxStderrBytes, killGraceMs, shutdownTimeoutMs, diagnosticsSettleMs, diagnosticsDebounceMs, and idleTimeoutMs (0 = keep the server process alive) tune the built-in stdio client.

Tools & surfaces

SurfaceKindNotes
lsp_diagnosticstool<file> — compiler/analyzer errors, warnings, and hints with severity, range, message, and source server (read-only)
lsp_formattool<file> [range?] — formats a file/selection through the language server and applies it, returning the diff (writes via fs/write-intent)
lsp_completiontool<file> <line> <character> — completion suggestions at a cursor position, including the insertion text (read-only)
lsp_code_actiontool<file> [range?] [only?] — server-verified quickfixes/refactorings with their edits, for a range or the first diagnostic (reference-only)
lsp_symbolstool<query?> <file_path?> — workspace-wide symbol search by name, or one file's outline (read-only)
lsp_signaturetool<file> <line> <character> — signature help (parameters and documentation) inside a call (read-only)
lsp_inlay_hintstool<file> [range?] — type annotations and parameter-name hints from the server (read-only)
lsp_renametool<file> <line> <character> <new_name> — server-verified rename, applied workspace-wide with per-file diffs (writes via fs/write-intent)
lsp.actions.*protocolEditor action protocol v1: lsp.actions.list / lsp.actions.run / lsp.events over JSON-RPC
examples/vscode/extensionUI-only VS Code extension plus the headless backend composition it connects to

Editor action protocol v1

When editor.enabled: true is set in a dedicated headless composition, dsh-lsp-actions serves a stable editor protocol over newline-delimited JSON-RPC 2.0 (the same wire framing as the official SDK/ACP transports):

MethodWhat it does
lsp.actions.listReturns the lsp-actions/v1 protocol version, the action catalog (diagnostics.get, completion.get, quickfix.apply, format — each flagged writes), and the addressable DSH sessions
lsp.actions.runExecutes one action with a structured { requestId, action, status, result | error } envelope; errors carry the stable LSP_ACTION_* codes
lsp.eventsSubscribes to the streamed lsp.event notifications: diagnostics.updated, action.status, file.changed, sessions.changed

All write actions (quickfix.apply, format) go through the official permission presets and approval: a read-only session is refused with LSP_ACTION_READ_ONLY before any server round-trip, edits ride the fs/write-intent waterfall, and the sandbox_permissions + justification escalation pair resolves through the official approveEscalation ask (fail-closed when no answerer can decide). Full wire spec, bilingual: docs/editor-protocol.md · docs/editor-protocol.zh-CN.md.

Versioning and the backward-compatibility promise

  • The protocol is versioned — lsp.actions.list returns protocol: "lsp-actions/v1", version: 1. v1 is frozen: field names, action ids, event kinds, and error codes stay stable forever.
  • Evolution is additive only: new actions, fields, and event kinds arrive without a version bump; existing semantics never change in place; a breaking change ships under a new protocol version, which servers may serve side by side.
  • Clients must ignore unknown fields, unknown event kinds, and unknown actions, and route on the stable error code, never on message text.

Error codes

Every failure carries a stable code; models and callers route on the code, never on message text.

CodeMeaning
LSP_ACTION_UNAVAILABLENo server entry and no seam provider handles this file
LSP_ACTION_UNSUPPORTEDThe server (or seam provider) does not advertise the operation
LSP_ACTION_SERVER_FAILEDThe server failed (with its stderr tail); startup failures retry once
LSP_ACTION_MALFORMED_RESPONSEThe server sent a structurally invalid payload
LSP_ACTION_CONFLICTThe file changed since it was read, or the edits overlap / go out of bounds / leave the workspace
LSP_ACTION_READ_ONLYThe session's sandbox mode forbids the formatting/rename write
LSP_ACTION_WORKSPACE_REQUIREDThe calling session has no workspace cwd to root the server in
LSP_ACTION_NO_SYMBOLThe server found no renameable symbol at the cursor position
LSP_ACTION_UNKNOWNEditor protocol: unknown action id, or no code action matched title/index
LSP_ACTION_INVALID_ARGSEditor protocol: malformed action parameters
LSP_ACTION_APPROVAL_UNAVAILABLEEditor protocol: the approval path could not grant a wider sandbox mode (fail-closed)
LSP_PROTOCOL_VERSION_UNSUPPORTEDEditor protocol: the declared protocol version is not supported

VS Code extension

examples/vscode/ ships a UI-only extension (sidebar with the DSH sessions, the diagnostics list, one-click quickfix apply, open-at-range, and format) plus the headless backend composition (backend/cordis.yml) it connects to over ACP-style JSON-RPC. The extension implements zero LSP logic — every capability and every byte written belongs to the plugin. Install steps, settings, and the demo-gif recording script are in examples/vscode/README.md.

Editor demo

Permissions & data

  • Permissions: formatting and rename ride the official permission presets and approval — the fs/write-intent waterfall and the sandbox_permissions / justification escalation pair resolved through ctx.approval. The plugin declares fs:read, fs:write, subprocess:spawn, and network:none in its workshop manifest.
  • Data: nothing is stored on disk; tool results live only in the session log (no cross-session persistence). The editor protocol keeps one bounded in-memory LRU diagnostics cache, freshness-stamped and never persisted across restarts.
  • No network: the plugin makes no network requests; it talks to language servers over local subprocess stdio.

Security boundaries

  • Read-only by default. Six of the eight tools are reference-only; only lsp_format and lsp_rename mutate, and they do so as real write/edit mutations.
  • Official seams, not re-implemented. Every byte goes through the fs/write-intent waterfall (observation → guarded write → observation) and the per-call sandbox policy; escalation matches the official write/edit tools.
  • Fail loud, fast, structured. Empty servers + no ctx.lsp seam → LSP_ACTION_UNAVAILABLE; read-only sessions → LSP_ACTION_READ_ONLY before any server round-trip; command forms are reported and never executed.
  • Conflicts never clobber. A file changed on disk after it was read fails with LSP_ACTION_CONFLICT; lsp_rename pre-flights every edited file before the first write.
  • Bounded work. Result caps, byte caps, and the platform's timeout policy bound every call; the diagnostics cache is a bounded LRU.
  • Nothing cached on the model path. Tool results live only in the session log; the diagnostics cache never persists across restarts.
  • Bad servers fail loudly. A missing executable fails at load; a server that dies at startup fails the call with LSP_ACTION_SERVER_FAILED plus its stderr tail (after one fresh-spawn retry).
  • Prompt hygiene. The plugin injects no persona or prompt prose into the session system prompt — its model-facing surface is the eight tool schemas.

Architecture

Actions run official-seam-first and fall back to the plugin's own minimal stdio client:

lsp_diagnostics / lsp_format / lsp_completion / lsp_code_action /
lsp_symbols / lsp_signature / lsp_inlay_hints / lsp_rename
        │
        ▼
   ctx.lsp seam (extended: diagnostics / formatDocument / completion)
        │  absent · legacy · no provider for this file
        ▼
   built-in stdio client  ←  servers table (ctx.subprocess.spawn + JSON-RPC)

The seam extension is proposed upstream (upstream/lsp-action-seam.patch, PR description in upstream/PR-description.md). Once it lands, the plugin keeps working unchanged — the built-in client simply stops being used. The built-in client stays as the standalone fallback for the servers table. The editor protocol rides the same runner, the same write path, and the same permission machinery. Full research and design notes: docs/seam-extension-notes.md.

Known limitations

  • Transient documents. Every action opens the file, runs one request, and closes it again (matching the official stdio host). Project-based servers that require a resident open file for document-free requests (tsls refuses workspace/symbol without one) are served by passing file_path to lsp_symbols. tsls also answers textDocument/signatureHelp with null under this lifecycle; other servers (gopls, pyright, rust-analyzer) serve it normally.
  • Range formatting requires the server's range provider. Servers that only advertise whole-document formatting fail range requests with LSP_ACTION_UNSUPPORTED.
  • Rename applies text edits only. Resource operations (create/delete/rename files) in a server's rename answer are refused with LSP_ACTION_UNSUPPORTED, and edits outside the workspace fail as LSP_ACTION_CONFLICT before anything is written.

Development

pnpm install            # node ^22.19 || >=24
pnpm run lint           # oxlint over src/ and tests/
pnpm test               # vitest: unit + fixture-server integration + editor-protocol e2e + real tsls e2e
pnpm run test:coverage  # coverage gate
pnpm build              # tsc --noEmitOnError → lib/
pnpm run prepare        # tsc --noEmitOnError (runs on install)
pnpm run prepublishOnly # tsc --noEmitOnError (runs before publish)

Topics

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

Contributors

  • @PerryLink — creator and maintainer: the LSP action client and server lifecycle, all eight tools, the editor action protocol, tests, CI, and the five-language docs.

This project is one of the 15 DeepSeek Harness plugins maintained by PerryLink. If this one helps you, the others likely will too:

PluginOne-liner
dsh-mcp-panelRead-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors
dsh-doublecheckEngineering-discipline guard: requirements grill, test gates, adversary review
dsh-background-agentsDurable background child agents with a Web UI sidebar, messaging and interrupt
dsh-lsp-actionsLSP diagnostics, formatting, completion, code actions and rename over language servers
dsh-output-stylesClaude Code outputStyles-equivalent runtime style switching
dsh-checkpoint-rewindClaude Code /rewind-equivalent: snapshots, session forks, one-shot restore
dsh-permission-rulesClaude Code-style declarative allow/deny/ask permission rules with audit
dsh-auto-reviewSecond-model auto-review on the approval chain, fail-closed by default
dsh-mementoApproval-gated cross-session memory: ctx.memory seam + SQLite + memory tool
dsh-skill-pack-securitySecurity-audit skill pack: secret scan, dependency and supply-chain review
dsh-session-pinPin sessions in the Web sidebar with durable ordering
dsh-composer-historyTerminal-style input history for the web composer: arrows, Ctrl+R search
dsh-githubGitHub PR/issues integration for DSH, every write gated by approval
dsh-plugin-guidePlugin-development knowledge base as an on-demand agent skill
dsh-claude-moveMigrate Claude Code sessions, memory, skills and CLAUDE.md into DSH

License

Apache License 2.0 © 2026 dsh-lsp-actions contributors

프로젝트 파일 및 신호

표시된 항목은 디렉터리 스냅샷에서 감지된 공개 저장소 신호입니다.

테스트감지됨
보안 정책감지됨
문서감지됨
예제감지됨

저장소 정보

언어
TypeScript
라이선스
Apache-2.0
최신 릴리스
v0.3.0
마지막 업데이트
2026. 8. 17. AM 5:18

신중하게 설치하기

소스 코드, 권한, 수명 주기 스크립트, 의존성 및 네트워크 접근을 검토하고 신뢰하지 않는 플러그인은 격리 환경에서 테스트하세요.