Skip to content

Commit ed73c0b

Browse files
committed
fix(claude-code): replace typescript-lsp with typescript-native-lsp (#194)
The official typescript-lsp plugin wraps tsserver, which TypeScript 7 no longer ships, so it fails every request on TS 7 projects. Install rubberduck-studio/typescript-native-lsp instead: it runs `tsc --lsp` on TS 7+ and falls back to typescript-language-server on TS 6 and older. Two plugins claiming .ts can't coexist, and the persistent ~/.claude volume keeps the old plugin installed, so init-plugins.sh now disables typescript-lsp when it's still enabled. Closes #194
1 parent 6ac7a49 commit ed73c0b

2 files changed

Lines changed: 28 additions & 3 deletions

File tree

‎claude-code/.devcontainer/init-plugins.sh‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ MARKETPLACES=(
2626
"GoogleChrome/modern-web-guidance"
2727
"AgriciDaniel/claude-seo"
2828
"cloudflare/skills"
29+
"rubberduck-studio/typescript-native-lsp"
2930
)
3031

3132
for marketplace in "${MARKETPLACES[@]}"; do
@@ -41,7 +42,6 @@ done
4142
PLUGINS=(
4243
"frontend-design@claude-plugins-official"
4344
"code-review@claude-plugins-official"
44-
"typescript-lsp@claude-plugins-official"
4545
"code-simplifier@claude-plugins-official"
4646
"playwright@claude-plugins-official"
4747
"superpowers@claude-plugins-official"
@@ -57,6 +57,10 @@ PLUGINS=(
5757
"ralphex@ralphex"
5858
"modern-web-guidance@googlechrome"
5959
"claude-seo@agricidaniel-claude-seo"
60+
# Replaces typescript-lsp@claude-plugins-official, which wraps tsserver and fails
61+
# every request on TypeScript 7 (no tsserver.js). Runs `tsc --lsp` on TS 7+ and
62+
# falls back to typescript-language-server on TS 6 and older (#194).
63+
"typescript-native-lsp@typescript-native-lsp"
6064
)
6165

6266
for plugin in "${PLUGINS[@]}"; do
@@ -67,6 +71,25 @@ for plugin in "${PLUGINS[@]}"; do
6771
fi
6872
done
6973

74+
# ── Conflicting plugins ─────────────────────────────────────────────────────
75+
# Plugins that claim the same file extensions as one in PLUGINS: Claude Code
76+
# starts only whichever registers first. Not installed above, but a persistent
77+
# ~/.claude volume may still hold them from an older run — disable if enabled.
78+
DISABLED_PLUGINS=(
79+
"typescript-lsp@claude-plugins-official" # superseded by typescript-native-lsp
80+
)
81+
82+
for plugin in "${DISABLED_PLUGINS[@]}"; do
83+
if claude plugin list --json 2>/dev/null \
84+
| jq -e --arg id "$plugin" 'any(.[]; .id == $id and .enabled)' >/dev/null; then
85+
if claude plugin disable "$plugin" 2>&1; then
86+
echo "✔ Disabled: $plugin"
87+
else
88+
echo "⚠ Failed to disable: $plugin" >&2
89+
fi
90+
fi
91+
done
92+
7093
# ~/.claude is a persistent volume, so `install` no-ops after the first run.
7194
# Refresh marketplace indexes first — `plugin update` resolves against the cache.
7295
if claude plugin marketplace update 2>&1; then

‎claude-code/README.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,12 @@ Mark as executable: `chmod +x init-plugins.sh`
104104

105105
#### Bundled plugins
106106

107-
`init-plugins.sh` registers five marketplaces and installs the following plugins:
107+
`init-plugins.sh` registers six marketplaces and installs the following plugins:
108108

109109
| Marketplace | Plugin | Purpose |
110110
|---|---|---|
111111
| `anthropics/claude-plugins-official` | `frontend-design` | Production-grade UI/UX scaffolding |
112112
| `anthropics/claude-plugins-official` | `code-review` | Multi-agent PR review |
113-
| `anthropics/claude-plugins-official` | `typescript-lsp` | TypeScript language-server tooling |
114113
| `anthropics/claude-plugins-official` | `code-simplifier` | Refactors for clarity and consistency |
115114
| `anthropics/claude-plugins-official` | `playwright` | Browser MCP (system chromium via `patch-playwright-mcp`) |
116115
| `anthropics/claude-plugins-official` | `superpowers` | Workflow skills (TDD, debugging, planning) |
@@ -122,6 +121,9 @@ Mark as executable: `chmod +x init-plugins.sh`
122121
| `umputun/ralphex` | `ralphex` | Autonomous plan execution |
123122
| `GoogleChrome/modern-web-guidance` | `modern-web-guidance` | Accessible, performant, secure modern web patterns ([docs](https://developer.chrome.com/docs/modern-web-guidance)) |
124123
| `AgriciDaniel/claude-seo` | `claude-seo` | SEO analysis toolkit — technical SEO, schema, E-E-A-T, GEO/AEO, Google APIs ([repo](https://github.com/AgriciDaniel/claude-seo)) |
124+
| `rubberduck-studio/typescript-native-lsp` | `typescript-native-lsp` | TypeScript/JavaScript LSP: TS 7's native server (`tsc --lsp`), falls back to `typescript-language-server` on TS 6 and older ([repo](https://github.com/rubberduck-studio/typescript-native-lsp)) |
125+
126+
> **Why not the official `typescript-lsp`:** it runs `typescript-language-server`, which wraps `tsserver`. TypeScript 7 (the native Go port) ships no `tsserver.js`, so on a TS 7 project the official plugin fails every request. `typescript-native-lsp` covers TS 7 and older versions in one plugin. The two must not be enabled together: when two plugins claim `.ts`, Claude Code starts only the first one it registers. That's why `init-plugins.sh` also disables `typescript-lsp` when a persisted `~/.claude` volume still has it (`DISABLED_PLUGINS`). TS 6 and older projects need `typescript-language-server` in the project (`bun add -d typescript-language-server`) or installed globally. The official plugin needed that too. Switch back once [anthropics/claude-plugins-official#4492](https://github.com/anthropics/claude-plugins-official/issues/4492) ships native TS 7 support (#194).
125127
126128
To remove a plugin in your project, delete its entry from the local `init-plugins.sh` — the script is a template, not image-baked, so each consumer controls its own list.
127129

0 commit comments

Comments
 (0)