Skip to content

feat(lsp): add pygls-based LSP server for real-time diagnostics#184

Merged
Alberto-Codes merged 4 commits intomainfrom
feat/lsp-24-1-server-real-time-diagnostics
Feb 28, 2026
Merged

feat(lsp): add pygls-based LSP server for real-time diagnostics#184
Alberto-Codes merged 4 commits intomainfrom
feat/lsp-24-1-server-real-time-diagnostics

Conversation

@Alberto-Codes
Copy link
Owner

IDE users see docvet findings as inline squiggles without running CLI commands. Previously, docvet was CLI-only — users had to manually run docvet check and scan terminal output. Now, any LSP-capable editor can display docstring quality diagnostics in real time on file open and save.

  • Add src/docvet/lsp.py — pygls v2 LSP server with Finding-to-Diagnostic conversion, enrichment/coverage/griffe orchestration, and didOpen/didSave handlers
  • Add docvet lsp subcommand to CLI with lazy pygls import and graceful error when [lsp] extra is missing
  • Add lsp = ["pygls>=2.0,<3"] optional dependency to pyproject.toml
  • Add 23 unit tests covering diagnostic mapping, check orchestration, event handlers, and CLI wiring

Test: uv run pytest tests/unit/test_lsp.py -v

Closes #159

fix(lsp): decouple server global, narrow exception, fix handler test


PR Review

Checklist

  • Self-reviewed my code
  • Tests pass (uv run pytest)
  • Lint passes (uv run ruff check .)
  • Types pass (uv run ty check)
  • Breaking changes use ! in title and BREAKING CHANGE: in body

Review Focus

  • src/docvet/lsp.py — pygls v2 API usage (import paths, publish method, sync kind)
  • Finding → Diagnostic severity mapping: required → Warning, recommended → Hint (intentional deviation from FR138 based on LSP ecosystem conventions)
  • _check_file orchestrator: enrichment + coverage + griffe, no freshness (requires git context)
  • _resolve_src_root uses workspace folders with config fallback

Related

Add `docvet lsp` command that starts an LSP server on stdio, publishing
docstring quality diagnostics on textDocument/didOpen and didSave events.
The server runs enrichment, coverage, and griffe checks on individual
files (freshness excluded — requires git context).

- Create src/docvet/lsp.py with pygls v2 server, Finding-to-Diagnostic
  conversion (required->Warning, recommended->Hint), codeDescription.href
  linking to rule docs, and TextDocumentSyncKind.Full sync
- Add `lsp` CLI subcommand with lazy pygls import and graceful error
- Add `lsp = ["pygls>=2.0,<3"]` optional dependency
- Add 23 unit tests covering conversion, orchestrator, handlers, and CLI
Refactor _resolve_src_root and _check_file to accept ls parameter
instead of accessing module-level server global. Narrow griffe
exception catch from broad Exception to (ImportError, OSError).
Rewrite did_save fallback test to call handler directly.
@Alberto-Codes Alberto-Codes marked this pull request as ready for review February 28, 2026 00:56
Copilot AI review requested due to automatic review settings February 28, 2026 00:56
@codecov-commenter
Copy link

codecov-commenter commented Feb 28, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 95.52239% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/docvet/lsp.py 96.61% 2 Missing ⚠️
src/docvet/cli.py 87.50% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Add tests that call did_open() directly and exercise _resolve_src_root
with populated workspace folders, raising lsp.py patch coverage from 91%
to 97%.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a diagnostics-only LSP server to docvet so editors can display docvet findings as real-time inline diagnostics (on open/save), extending docvet beyond CLI-only workflows.

Changes:

  • Introduces a pygls v2-based LSP server with Finding→Diagnostic mapping and didOpen/didSave handlers.
  • Adds a docvet lsp CLI subcommand with optional-dependency behavior and adds pygls as an [lsp] extra.
  • Adds unit tests covering diagnostic mapping, orchestration, handlers, and CLI wiring.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/docvet/lsp.py New pygls-based LSP server implementation and helpers for converting/publishing diagnostics.
src/docvet/cli.py Adds docvet lsp command to launch the server with a graceful missing-dependency message.
pyproject.toml Adds [lsp] optional dependency and includes pygls in dev dependencies.
tests/unit/test_lsp.py New unit tests for LSP diagnostic mapping, orchestration, handlers, and CLI behavior.
_bmad-output/implementation-artifacts/sprint-status.yaml Updates story/epic status tracking.
_bmad-output/implementation-artifacts/epic-20-retro-2026-02-27.md Adds Epic 20 retrospective artifact.
_bmad-output/implementation-artifacts/24-1-lsp-server-for-real-time-diagnostics.md Adds Story 24.1 implementation artifact.

Prevents masking unrelated ImportErrors inside lsp.py when pygls is
installed but another import fails.
@Alberto-Codes Alberto-Codes merged commit e121c38 into main Feb 28, 2026
12 checks passed
@Alberto-Codes Alberto-Codes deleted the feat/lsp-24-1-server-real-time-diagnostics branch February 28, 2026 01:07
Alberto-Codes added a commit that referenced this pull request Feb 28, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.6.0](v1.5.0...v1.6.0)
(2026-02-28)


### Features

* **ci:** add cross-platform CI matrix and path normalization
([#174](#174))
([e418fbc](e418fbc)),
closes [#101](#101)
* **ci:** add pre-commit hook definition and tests
([#180](#180))
([5f11287](5f11287))
* **cli:** add --format json for structured machine-readable output
([#177](#177))
([da8e51d](da8e51d)),
closes [#151](#151)
* **cli:** add positional file arguments to all subcommands
([#175](#175))
([dee57cc](dee57cc)),
closes [#152](#152)
* **docs:** add "How to Fix" guidance to all 19 rule pages
([#166](#166))
([817f43c](817f43c)),
closes [#155](#155)
* **docs:** add AGENTS.md and AI Agent Integration docs page
([#171](#171))
([bc662a2](bc662a2)),
closes [#161](#161)
* **docs:** add AI Agent Integration section and enhance competitive
positioning ([#170](#170))
([df51114](df51114)),
closes [#153](#153)
[#162](#162)
* **docs:** add CONTRIBUTING.md contributor guide
([#172](#172))
([4ff286f](4ff286f)),
closes [#104](#104)
* **lsp:** add Claude Code plugin configuration
([#185](#185))
([17be1f3](17be1f3)),
closes [#63](#63)
* **lsp:** add pygls-based LSP server for real-time diagnostics
([#184](#184))
([e121c38](e121c38)),
closes [#159](#159)
* **reporting:** add format_json() for structured JSON output
([da8e51d](da8e51d))


### Bug Fixes

* **ci:** strengthen pre-commit hook YAML test assertions
([5f11287](5f11287))
* **docs:** code review fixes for AGENTS.md and ai-integration page
([bc662a2](bc662a2))
* **lsp:** decouple server global, narrow exception, fix handler test
([e121c38](e121c38))


### Documentation

* **cli:** document --format json schema and usage
([da8e51d](da8e51d))
* **meta:** reserve # references for GitHub issues and PRs only
([5f11287](5f11287))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: LSP server for real-time docstring diagnostics

3 participants