feat: add Claude Code marketplace and dexter-lsp plugin#59
Merged
Conversation
Explains how to wire up Dexter as the Elixir LSP for Claude Code's LSP tool (go-to-definition, hover docs, find references) using a local plugin manifest.
Turns the dexter repo into a Claude Code marketplace so users can install Dexter as their Elixir LSP with two commands: claude plugin marketplace add remoteoss/dexter claude plugin install dexter-lsp@dexter The plugin wires up `dexter lsp` for .ex/.exs/.heex files and exposes followDelegates and debug as user-configurable options.
Member
|
Thanks for the PR @pquadri! I think this is a great addition. Going to sleep on whether to keep this in the same repo or in a different one. If you have any docs on the matter, I'd also be glad to read them. Should be able to merge this tomorrow. |
JesseHerrick
reviewed
May 6, 2026
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Reviewed by Cursor Bugbot for commit 305f540. Configure here.
Claude Code plugin template substitution (${user_config.X}) always
produces a JSON string even when the userConfig type is "boolean".
The strict `.(bool)` type assertions silently dropped the user's
followDelegates/debug settings, leaving them stuck at hardcoded defaults.
Add a coerceBool helper that accepts both native bool and string forms
("true"/"false"/"1"/"0"). Expand the initializationOptions test to call
server.Initialize and cover both forms.
JesseHerrick
added a commit
that referenced
this pull request
May 25, 2026
"Headless" LSP clients such as Claude Code don't actually open files when doing lookups or changing them. This means that some of our tricks for looking things up via the context of the files breaks. This PR adds lazy disk-fallback to the document store so LSP clients that don't drive the full `didOpen`/`didChange`/`didClose` lifecycle (e.g. Claude Code) can still query definitions, hovers, references, and other text-dependent handlers. Use-injected lookups in particular: `lookupThroughUse`, `lookupThroughUseOf`. Alias merging also previously returned `nil` for any file the editor hadn't explicitly opened. The goal of these changes is enablement work for a proper Claude Code plugin: #59. ## What changed - **`DocumentStore.GetOrLoad(uri)`**: lazy disk read for any `file://` URI that isn't already in the store. Disk-loaded entries are marked `transient: true` and tracked in a Least Recently Used (LRU) cache. Non-`file://` URIs (e.g. `untitled:`) return `(false)` without touching disk to avoid the `uriToPath` panic. - **LRU eviction**: transient entries are capped (default 50). Editor-owned buffers (`Set` via `didOpen`) are never counted, never reordered, never evicted. `Set` cleanly promotes a transient entry to editor-owned, dropping its LRU bookkeeping. - **Cap is configurable**: new `maxTransientDocuments` initialization option (default 50, accepts integer or JSON number, clamps negatives to 0). Documented in `README.md`. - **Handler migration**: 18 read-only handlers (`Definition`, `Hover`, `References`, `Completion`, `CodeAction`, `Declaration`, `DocumentHighlight`, `DocumentSymbol`, `FoldingRanges`, `Implementation`, `PrepareRename`, `Rename`, `SignatureHelp`, `TypeDefinition`, `PrepareCallHierarchy`, …) now call `GetOrLoad`. `Formatting` deliberately keeps `Get` — it only makes sense for in-memory editor buffers. ## Correctness notes - File I/O happens outside the write lock; a re-check inside the lock returns the existing entry if a concurrent `Set` or `GetOrLoad` populated the URI first. - `bumpLRU` is a no-op if the URI was promoted to editor-owned between the RLock and Lock, so the fast-path race is safe. - `evictTransientLocked` closes the cached tree-sitter tree before deletion - no leak. - Race-clean under `go test -race`.
Member
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Turns the dexter repo into a Claude Code marketplace, so users can install Dexter as their Elixir LSP in Claude Code with just two commands:
Changes
.claude-plugin/marketplace.json— makes this repo a Claude Code marketplace nameddexterplugins/dexter-lsp/.claude-plugin/plugin.json— plugin manifest that wires updexter lspfor.ex,.exs, and.heexfiles, withfollowDelegatesanddebugexposed as user-configurable optionsREADME.md— adds a Claude Code section to the editor setup docsHow it works
Claude Code's LSP tool supports a plugin system. The
lspServersentry inplugin.jsontells Claude Code to spawndexter lspwhen opening Elixir files, giving it go-to-definition, hover docs, find references, workspace symbols, and more.Test plan
claude plugin marketplace add remoteoss/dextersucceedsclaude plugin install dexter-lsp@dextersucceeds.exfilesuserConfigprompts appear forfollowDelegatesanddebugon installNote
Low Risk
Plugin manifests, documentation, and defensive init-option parsing with expanded tests; no changes to indexing or core LSP behavior beyond config parsing.
Overview
This PR turns the dexter repo into a Claude Code marketplace and ships a dexter-lsp plugin that runs
dexter lspfor.ex,.exs, and.heex, with user settings for followDelegates and debug.The LSP server now accepts boolean initialization options as strings (via
coerceBool), because Claude Code’s${user_config.*}substitution sends strings instead of JSON booleans. Tests cover bools,"true"/"false","1"/"0", and invalid values.README adds a Claude Code editor section: enable
ENABLE_LSP_TOOL, thenclaude plugin marketplace add/plugin install.Reviewed by Cursor Bugbot for commit 23a339e. Bugbot is set up for automated code reviews on this repo. Configure here.