cli-lsp-client 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,7 @@ CLI tool for getting LSP diagnostics. Uses a background daemon to keep LSP serve
10
10
  - Built in Claude Code hook to provide feedback on file edit tool calls
11
11
  - Comprehensive daemon management (`list`, `stop-all` commands)
12
12
  - Multi-project support with isolated daemon instances per directory
13
+ - [Custom language server support via config files](#custom-language-servers-config-file)
13
14
 
14
15
  ## Supported Languages
15
16
 
@@ -24,6 +25,7 @@ CLI tool for getting LSP diagnostics. Uses a background daemon to keep LSP serve
24
25
  | GraphQL | `graphql-language-service-cli` | ✓ (via bunx) | `.graphql`, `.gql` |
25
26
  | **R** | **R languageserver** | **✗** | **`.r`, `.R`, `.rmd`, `.Rmd` - see [R Installation](#r-installation-guide) below** |
26
27
  | **C#** | **OmniSharp-Roslyn** | **✗** | **`.cs` - see [C# Installation](#c-installation-guide) below** |
28
+ | **Swift** | **SourceKit-LSP** | **✗** | **`.swift` - see [Swift Configuration](#swift-configuration) below** |
27
29
  | Go | `gopls` | ✗ | Requires manual install: `go install golang.org/x/tools/gopls@latest` |
28
30
  | Java | `jdtls` (Eclipse JDT) | ✗ | `.java` - see [Java Installation](#java-installation-guide) below |
29
31
  | Lua | `lua-language-server` | ✗ | `.lua` - requires manual install via package manager (brew, scoop) or from [releases](https://github.com/LuaLS/lua-language-server/releases) |
@@ -39,7 +41,7 @@ CLI tool for getting LSP diagnostics. Uses a background daemon to keep LSP serve
39
41
 
40
42
  ### Real-time Diagnostics Hook
41
43
 
42
- Get instant diagnostic feedback for TypeScript, Python, JSON, CSS, YAML, Bash, GraphQL, R, C#, Go, Java, and Lua files as you edit in Claude Code.
44
+ Get instant diagnostic feedback for TypeScript, Python, JSON, CSS, YAML, Bash, GraphQL, R, C#, Swift, Go, Java, and Lua files as you edit in Claude Code.
43
45
 
44
46
  #### Setup
45
47
 
@@ -97,6 +99,72 @@ ERROR at line 3, column 9:
97
99
  Code: 2322
98
100
  ```
99
101
 
102
+ ## Custom Language Servers (Config File)
103
+
104
+ You can extend the built-in language servers by creating a custom configuration file. This allows you to add support for any LSP server not included by default.
105
+
106
+ ### Configuration File
107
+
108
+ Create a config file at `~/.config/cli-lsp-client/settings.json` (default location) or use `--config-file` to specify a custom path:
109
+
110
+ ```json
111
+ {
112
+ "servers": [
113
+ {
114
+ "id": "svelte",
115
+ "extensions": [".svelte"],
116
+ "rootPatterns": ["svelte.config.js", "package.json"],
117
+ "command": ["bunx", "svelte-language-server", "--stdio"],
118
+ "env": {
119
+ "NODE_ENV": "development"
120
+ },
121
+ "initialization": {
122
+ "settings": {
123
+ "svelte": {
124
+ "compilerWarnings": true
125
+ }
126
+ }
127
+ }
128
+ }
129
+ ],
130
+ "languageExtensions": {
131
+ ".svelte": "svelte"
132
+ }
133
+ }
134
+ ```
135
+
136
+ ### Using Custom Config
137
+
138
+ **Default config file location:**
139
+
140
+ ```bash
141
+ # Uses ~/.config/cli-lsp-client/settings.json automatically
142
+ npx cli-lsp-client diagnostics Component.svelte
143
+ ```
144
+
145
+ **Custom config file location:**
146
+
147
+ ```bash
148
+ # Specify custom config file path
149
+ npx cli-lsp-client --config-file ./my-config.json diagnostics Component.svelte
150
+ npx cli-lsp-client --config-file ./my-config.json hover Component.svelte myFunction
151
+ npx cli-lsp-client --config-file ./my-config.json status
152
+ ```
153
+
154
+ **Important:** When using `--config-file`, you must include it on every command. The CLI automatically restarts the daemon when switching between different config files to ensure the correct language servers are loaded.
155
+
156
+ ### Config File Schema
157
+
158
+ - `servers`: Array of custom language server definitions
159
+ - `id`: Unique identifier for the server
160
+ - `extensions`: File extensions this server handles (e.g. `[".svelte"]`)
161
+ - `rootPatterns`: Files/patterns used to detect project root (e.g. `["package.json"]`)
162
+ - `command`: Command array to start the LSP server (e.g. `["bunx", "svelte-language-server", "--stdio"]`)
163
+ - `env`: Optional environment variables for the server process
164
+ - `initialization`: Optional LSP initialization parameters
165
+
166
+ - `languageExtensions`: Maps file extensions to LSP language identifiers
167
+
100
168
  ## Usage
101
169
 
102
170
  ### Get Diagnostics
@@ -110,6 +178,9 @@ npx cli-lsp-client diagnostics app.py
110
178
  npx cli-lsp-client diagnostics main.go
111
179
  npx cli-lsp-client diagnostics analysis.R
112
180
  npx cli-lsp-client diagnostics Program.cs
181
+
182
+ # Check Swift files (requires config file)
183
+ npx cli-lsp-client diagnostics Sources/App/main.swift
113
184
  ```
114
185
 
115
186
  Exit codes: 0 for no issues, 2 for issues found.
@@ -132,6 +203,9 @@ npx cli-lsp-client hover src/main.ts myFunction
132
203
  npx cli-lsp-client hover app.py MyClass
133
204
  npx cli-lsp-client hover analysis.R mean
134
205
  npx cli-lsp-client hover Program.cs Console
206
+
207
+ # Get hover info for Swift symbols (requires config file)
208
+ npx cli-lsp-client hover Sources/App/main.swift greetUser
135
209
  ```
136
210
 
137
211
  ````bash
@@ -255,11 +329,13 @@ The R language server requires R runtime and the `languageserver` package:
255
329
  1. **Install R**: Download and install R from [CRAN](https://cran.r-project.org/) or use a package manager:
256
330
 
257
331
  **macOS (Homebrew)**:
332
+
258
333
  ```bash
259
334
  brew install r
260
335
  ```
261
336
 
262
337
  **Ubuntu/Debian**:
338
+
263
339
  ```bash
264
340
  sudo apt-get update
265
341
  sudo apt-get install r-base
@@ -268,11 +344,13 @@ The R language server requires R runtime and the `languageserver` package:
268
344
  **Windows**: Download installer from [CRAN Windows](https://cran.r-project.org/bin/windows/base/)
269
345
 
270
346
  2. **Install R languageserver package**: Open R and run:
347
+
271
348
  ```r
272
349
  install.packages("languageserver")
273
350
  ```
274
351
 
275
352
  Or from command line:
353
+
276
354
  ```bash
277
355
  R --slave -e 'install.packages("languageserver", repos="https://cran.rstudio.com/")'
278
356
  ```
@@ -280,6 +358,7 @@ The R language server requires R runtime and the `languageserver` package:
280
358
  ### Verification
281
359
 
282
360
  Test that the language server works:
361
+
283
362
  ```bash
284
363
  R --slave -e 'languageserver::run()'
285
364
  ```
@@ -287,8 +366,9 @@ R --slave -e 'languageserver::run()'
287
366
  ### Project Detection
288
367
 
289
368
  The R LSP automatically detects R projects based on these files:
369
+
290
370
  - `DESCRIPTION` (R packages)
291
- - `NAMESPACE` (R packages)
371
+ - `NAMESPACE` (R packages)
292
372
  - `.Rproj` (RStudio projects)
293
373
  - `renv.lock` (renv dependency management)
294
374
  - Any `.r`, `.R`, `.rmd`, `.Rmd` files
@@ -304,11 +384,13 @@ The C# language server requires .NET SDK and OmniSharp-Roslyn:
304
384
  1. **Install .NET SDK**: Download .NET 6.0+ from [Microsoft .NET](https://dotnet.microsoft.com/download) or use a package manager:
305
385
 
306
386
  **macOS (Homebrew)**:
387
+
307
388
  ```bash
308
389
  brew install dotnet
309
390
  ```
310
391
 
311
392
  **Ubuntu/Debian**:
393
+
312
394
  ```bash
313
395
  # Add Microsoft package repository
314
396
  wget https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
@@ -322,11 +404,12 @@ The C# language server requires .NET SDK and OmniSharp-Roslyn:
322
404
  2. **Install OmniSharp-Roslyn**: Download the latest release from [OmniSharp releases](https://github.com/OmniSharp/omnisharp-roslyn/releases):
323
405
 
324
406
  **Automatic script** (recommended):
407
+
325
408
  ```bash
326
409
  # Download and extract OmniSharp to ~/.omnisharp/
327
410
  mkdir -p ~/.omnisharp
328
411
  curl -L https://github.com/OmniSharp/omnisharp-roslyn/releases/latest/download/omnisharp-osx-arm64-net6.0.tar.gz | tar -xz -C ~/.omnisharp/
329
-
412
+
330
413
  # Create symlink to make omnisharp available in PATH
331
414
  sudo ln -sf ~/.omnisharp/OmniSharp /usr/local/bin/omnisharp
332
415
  ```
@@ -339,11 +422,13 @@ The C# language server requires .NET SDK and OmniSharp-Roslyn:
339
422
  3. **Set environment variables**:
340
423
 
341
424
  **Fish shell**:
425
+
342
426
  ```bash
343
427
  set -Ux DOTNET_ROOT ~/.dotnet
344
428
  ```
345
429
 
346
430
  **Bash/Zsh**:
431
+
347
432
  ```bash
348
433
  echo 'export DOTNET_ROOT=~/.dotnet' >> ~/.bashrc # or ~/.zshrc
349
434
  source ~/.bashrc # or ~/.zshrc
@@ -354,6 +439,7 @@ The C# language server requires .NET SDK and OmniSharp-Roslyn:
354
439
  ### Verification
355
440
 
356
441
  Test that OmniSharp works:
442
+
357
443
  ```bash
358
444
  # Verify DOTNET_ROOT is set
359
445
  echo $DOTNET_ROOT
@@ -365,6 +451,7 @@ omnisharp --help
365
451
  ### Project Detection
366
452
 
367
453
  The C# LSP automatically detects C# projects based on these files:
454
+
368
455
  - `*.sln` (Solution files)
369
456
  - `*.csproj` (Project files)
370
457
  - `project.json` (Legacy project files)
@@ -373,6 +460,48 @@ The C# LSP automatically detects C# projects based on these files:
373
460
 
374
461
  For more information, see the [OmniSharp documentation](https://github.com/OmniSharp/omnisharp-roslyn).
375
462
 
463
+ ## Swift Configuration
464
+
465
+ Swift language support is available through SourceKit-LSP, which is included with Xcode Command Line Tools. Support for swift and other LSPs can be added via a config file.
466
+
467
+ ### Prerequisites
468
+
469
+ **macOS (with Xcode Command Line Tools)**:
470
+
471
+ ```bash
472
+ # Check if SourceKit-LSP is available
473
+ xcrun --find sourcekit-lsp
474
+ ```
475
+
476
+ **Alternative toolchains**: If using Swift toolchains from swift.org, SourceKit-LSP is included and can be run with:
477
+
478
+ ```bash
479
+ xcrun --toolchain swift sourcekit-lsp
480
+ ```
481
+
482
+ ### Configuration
483
+
484
+ Create a config file at `~/.config/cli-lsp-client/settings.json`:
485
+
486
+ ```json
487
+ {
488
+ "servers": [
489
+ {
490
+ "id": "sourcekit_lsp",
491
+ "extensions": [".swift"],
492
+ "rootPatterns": ["Package.swift", ".xcodeproj", ".xcworkspace"],
493
+ "command": ["xcrun", "sourcekit-lsp"],
494
+ "env": {}
495
+ }
496
+ ],
497
+ "languageExtensions": {
498
+ ".swift": "swift"
499
+ }
500
+ }
501
+ ```
502
+
503
+ For more information about SourceKit-LSP, see the [official documentation](https://github.com/swiftlang/sourcekit-lsp).
504
+
376
505
  ### Additional Commands
377
506
 
378
507
  ```bash
@@ -382,7 +511,7 @@ npx cli-lsp-client start
382
511
  # Start servers for specific directory
383
512
  npx cli-lsp-client start /path/to/project
384
513
 
385
- # View daemon logs
514
+ # View daemon log file path
386
515
  npx cli-lsp-client logs
387
516
  ```
388
517
 
package/cli-lsp-client CHANGED
Binary file
package/package.json CHANGED
@@ -1,36 +1,11 @@
1
1
  {
2
2
  "name": "cli-lsp-client",
3
- "version": "1.6.0",
4
- "description": "CLI tool for fast LSP diagnostics with background daemon and multi-project support",
5
- "type": "module",
6
- "main": "src/cli.ts",
7
- "license": "MIT",
8
- "bin": {
9
- "cli-lsp-client": "cli-lsp-client"
10
- },
11
- "files": [
12
- "cli-lsp-client"
13
- ],
3
+ "version": "1.7.0",
14
4
  "repository": {
15
5
  "type": "git",
16
6
  "url": "git+https://github.com/eli0shin/cli-lsp-client.git"
17
7
  },
18
- "homepage": "https://github.com/eli0shin/cli-lsp-client#readme",
19
- "bugs": {
20
- "url": "https://github.com/eli0shin/cli-lsp-client/issues"
21
- },
22
- "scripts": {
23
- "build": "bun build src/cli.ts --compile --outfile cli-lsp-client",
24
- "dev": "bun run src/cli.ts",
25
- "typecheck": "bun --bun tsc --noEmit",
26
- "lint": "eslint .",
27
- "lint:fix": "eslint . --fix",
28
- "format": "prettier --check .",
29
- "format:fix": "prettier --write .",
30
- "test": "bun test",
31
- "test:watch": "bun test tests/ --watch",
32
- "prepublish": "bun test && bun run build"
33
- },
8
+ "main": "src/cli.ts",
34
9
  "devDependencies": {
35
10
  "@eslint/js": "^9.33.0",
36
11
  "@types/bun": "latest",
@@ -43,15 +18,35 @@
43
18
  "globals": "^16.3.0",
44
19
  "prettier": "3.6.2",
45
20
  "typescript": "latest",
46
- "typescript-eslint": "^8.39.1"
47
- },
48
- "peerDependencies": {
49
- "typescript": "^5.0.0"
50
- },
51
- "dependencies": {
52
- "pyright": "^1.1.403",
21
+ "typescript-eslint": "^8.39.1",
53
22
  "vscode-jsonrpc": "^8.2.1",
54
23
  "vscode-languageserver-types": "^3.17.5",
55
24
  "zod": "^4.0.17"
56
- }
25
+ },
26
+ "bin": {
27
+ "cli-lsp-client": "cli-lsp-client"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/eli0shin/cli-lsp-client/issues"
31
+ },
32
+ "description": "CLI tool supporting claude code hooks for fast LSP diagnostics with background daemon and multi-project support",
33
+ "files": [
34
+ "cli-lsp-client"
35
+ ],
36
+ "homepage": "https://github.com/eli0shin/cli-lsp-client#readme",
37
+ "license": "MIT",
38
+ "scripts": {
39
+ "build": "bun build src/cli.ts --compile --outfile cli-lsp-client",
40
+ "dev": "bun run src/cli.ts",
41
+ "typecheck": "bun tsc --noEmit",
42
+ "lint": "eslint .",
43
+ "lint:fix": "eslint . --fix",
44
+ "format": "prettier --check .",
45
+ "format:fix": "prettier --write .",
46
+ "test": "bun test",
47
+ "test:watch": "bun test tests/ --watch",
48
+ "prepublishOnly": "bun test && bun run build",
49
+ "postinstall": "node scripts/postinstall.js"
50
+ },
51
+ "type": "module"
57
52
  }
package/src/cli.ts CHANGED
@@ -110,10 +110,46 @@ function showHelp(): void {
110
110
  process.stdout.write(HELP_MESSAGE + '\n');
111
111
  }
112
112
 
113
+ type ParsedArgs = {
114
+ command: string;
115
+ commandArgs: string[];
116
+ configFile?: string;
117
+ };
118
+
119
+ function parseArgs(args: string[]): ParsedArgs {
120
+ let configFile: string | undefined;
121
+ const filteredArgs: string[] = [];
122
+
123
+ for (let i = 0; i < args.length; i++) {
124
+ const arg = args[i];
125
+
126
+ if (arg === '--config-file') {
127
+ if (i + 1 >= args.length) {
128
+ process.stderr.write('Error: --config-file requires a path argument\n');
129
+ process.exit(1);
130
+ }
131
+ configFile = args[i + 1];
132
+ i++; // Skip the next argument since it's the config file path
133
+ } else if (arg.startsWith('--config-file=')) {
134
+ configFile = arg.split('=', 2)[1];
135
+ if (!configFile) {
136
+ process.stderr.write('Error: --config-file= requires a path after the equals sign\n');
137
+ process.exit(1);
138
+ }
139
+ } else {
140
+ filteredArgs.push(arg);
141
+ }
142
+ }
143
+
144
+ const command = filteredArgs[0] || 'status';
145
+ const commandArgs = filteredArgs.slice(1);
146
+
147
+ return { command, commandArgs, configFile };
148
+ }
149
+
113
150
  async function run(): Promise<void> {
114
- const args = process.argv.slice(2);
115
- const command = args[0] || 'status';
116
- const commandArgs = args.slice(1);
151
+ const rawArgs = process.argv.slice(2);
152
+ const { command, commandArgs, configFile } = parseArgs(rawArgs);
117
153
 
118
154
  // Check if we're being invoked to run as daemon
119
155
  if (process.env.LSPCLI_DAEMON_MODE === '1') {
@@ -183,7 +219,7 @@ async function run(): Promise<void> {
183
219
  }
184
220
 
185
221
  // All other user commands are handled by the client (which auto-starts daemon if needed)
186
- await runCommand(command, commandArgs);
222
+ await runCommand(command, commandArgs, configFile);
187
223
  }
188
224
 
189
225
  export { run };