#1178·skills

dotnet plugin's Claude manifest references the wrong-shaped LSP file, and version-sync would silently revert any fix

Author: Ander89BRCreated Sep 15, 2026Updated Sep 17, 2026
Labelsarea-dotnetTriagedbug

Summary

plugins/dotnet/.claude-plugin/plugin.json declares:

"lspServers": "./lsp.json"

lsp.json uses the Copilot CLI shape. Claude Code reads .claude-plugin/plugin.json and expects a different shape for the referenced file — the one already shipped at plugins/dotnet/.lsp.json (added in #298 / e03f2f2 for exactly this reason).

Copilot CLI shape (lsp.json) Claude Code shape (.lsp.json)
Outer wrapper { "lspServers": { "csharp": {...} } } { "csharp": {...} } (no wrapper)
Extension key fileExtensions extensionToLanguage
Referenced by root plugin.json .claude-plugin/plugin.json

Impact

An explicit lspServers reference to the wrong-shaped file takes precedence over Claude Code's own auto-discovery of .lsp.json, so Claude Code registers zero LSP servers for this plugin instead of falling back to the correct file.

Verified locally: pointing .claude-plugin/plugin.json's lspServers at ./.lsp.json fixes LSP registration in Claude Code.

Why this isn't a one-line fix

eng/version/Sync-PluginVersions.ps1 currently treats .claude-plugin/plugin.json as a byte-identical generated copy of the root plugin.json:

[IO.File]::WriteAllText($claudeManifest, [IO.File]::ReadAllText($manifest))

This runs on every /version-bump and the weekly version sync. Since the root manifest must keep referencing ./lsp.json for Copilot CLI, simply editing .claude-plugin/plugin.json's lspServers value would be silently reverted at the next stamp.

Proposed fix

  • In Sync-PluginVersions.ps1, treat the Claude manifest like the Codex manifest: keep only the version field in sync (regex-based Set-ManifestVersion), bootstrapping a missing file as a full copy but never overwriting an existing file's other fields. This step is required regardless of which option below is chosen — without it, any manual edit to .claude-plugin/plugin.json is silently reverted at the next /version-bump or weekly sync.
  • Update plugins/dotnet/.claude-plugin/plugin.json so Claude Code resolves the correct LSP file, leaving the root plugin.json (read by Copilot CLI) unchanged at ./lsp.json. Two options:
    • Point lspServers explicitly at ./.lsp.json — verified locally to work; documents the intent in the manifest itself.
    • Remove the lspServers field entirely — relies on Claude Code's own auto-discovery of .lsp.json at the plugin root; one line simpler, but untested here, and leaves the LSP declaration implicit (a future contributor "fixing" the manifests back into sync could more easily reintroduce the bug than if the correct reference is spelled out).
  • Update eng/version/Test-Sync-PluginVersions.ps1 and document the divergence in CONTRIBUTING.md.