typescript-lsp plugin: semantic operations fail in Yarn 1 monorepos with hoisted dependencies
Bug Description
The typescript-lsp@claude-plugins-official plugin's semantic LSP operations (findReferences, goToDefinition, hover, documentSymbol) return no results in a Yarn 1 workspaces monorepo with hoisted node_modules. Only workspaceSymbol (which uses text-based indexing) works correctly.
Environment
- OS: Windows 10 Pro 10.0.19045
- Claude Code model: claude-opus-4-6
- Plugin:
typescript-lsp@claude-plugins-official - Monorepo setup: Yarn 1 workspaces + Turborepo
- TypeScript: 5.5.4
- tsconfig: Per-package configs extending a shared base with
moduleResolution: "Bundler"
Reproduction
Project structure (simplified):
repo-root/
├── node_modules/ # all dependencies hoisted here
├── package.json # workspaces: ["apps/*", "packages/*"]
├── packages/
│ └── ui/
│ ├── tsconfig.json # extends shared base config
│ ├── types.ts
│ ├── node_modules/ # only contains .bin (no packages)
│ └── components/atoms/button.tsx
└── apps/
└── my-app/
├── tsconfig.json
├── node_modules/ # only contains .bin
└── src/App.tsx
Steps:
- Enable the
typescript-lspplugin - Open any
.tsxfile in a monorepo package (e.g.,packages/ui/components/atoms/button.tsx) - Use LSP tool with
findReferenceson an exported function - Observe: "No references found"
- Use LSP tool with
hover— returns no content but triggers TS diagnostics showing module resolution failures:
Cannot find module '../../types' or its corresponding type declarations. [2307]This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found. [2875]
- Use LSP tool with
workspaceSymbol— works correctly, finds symbols
Root Cause Analysis
Yarn 1 hoists all dependencies to the repo-root node_modules/. Individual packages have only .bin in their local node_modules/.
The tsserver instance spawned by the plugin appears to set its project root to the individual package directory rather than the monorepo root. This means it cannot resolve:
- Dependencies like
react(hoisted to root) - Shared config packages (resolved via root
node_modules) - Cross-package type imports
Since workspaceSymbol uses text-based scanning (doesn't require type resolution), it works. All semantic operations (findReferences, hover, goToDefinition, documentSymbol) require a resolved module graph and therefore fail.
Expected Behavior
The LSP plugin should detect the monorepo root (e.g., by walking up to find the root package.json with workspaces) and configure tsserver with the correct project root so that hoisted node_modules are resolved.
Related Issues
- #15235 — plugin.json missing (different issue)
- #14803 — LSP plugins not recognized (different issue)
- #16291 — TypeScript LSP Plugin Not Registering (different issue)
Workaround
Currently none for semantic operations. workspaceSymbol can be used as a partial workaround for symbol discovery only.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗