specweave 1.0.186 → 1.0.187

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/CLAUDE.md CHANGED
@@ -1,4 +1,4 @@
1
- <!-- SW:META template="claude" version="1.0.184" sections="header,start,autodetect,metarule,rules,workflow,reflect,context,structure,taskformat,secrets,syncing,testing,tdd,api,limits,troubleshooting,lazyloading,principles,linking,mcp,auto,docs" -->
1
+ <!-- SW:META template="claude" version="1.0.186" sections="header,start,autodetect,metarule,rules,workflow,reflect,context,structure,taskformat,secrets,syncing,testing,tdd,api,limits,troubleshooting,lazyloading,principles,linking,mcp,auto,docs" -->
2
2
 
3
3
  <!-- SW:SECTION:hook-priority version="1.0.171" -->
4
4
  ## ⛔ ABSOLUTE PRIORITY: Hook Instructions Are Mandatory
@@ -53,7 +53,7 @@ Hooks exist to enforce workflow discipline. If you ignore them:
53
53
  **This is non-negotiable. No exceptions. No "just this once".**
54
54
  <!-- SW:END:hook-priority -->
55
55
 
56
- <!-- SW:SECTION:header version="1.0.184" -->
56
+ <!-- SW:SECTION:header version="1.0.186" -->
57
57
  **Framework**: SpecWeave | **Truth**: `spec.md` + `tasks.md`
58
58
  <!-- SW:END:header -->
59
59
 
@@ -244,7 +244,7 @@ The official `typescript-lsp@claude-plugins-official` and similar plugins:
244
244
 
245
245
  Use `boostvolt/claude-code-lsps` until official plugins are fixed.
246
246
 
247
- <!-- SW:SECTION:start version="1.0.184" -->
247
+ <!-- SW:SECTION:start version="1.0.186" -->
248
248
  ## Getting Started
249
249
 
250
250
  **Initial increment**: `0001-project-setup` (auto-created by `specweave init`)
@@ -254,7 +254,7 @@ Use `boostvolt/claude-code-lsps` until official plugins are fixed.
254
254
  2. **Customize**: Edit spec.md and use for setup tasks
255
255
  <!-- SW:END:start -->
256
256
 
257
- <!-- SW:SECTION:autodetect version="1.0.184" -->
257
+ <!-- SW:SECTION:autodetect version="1.0.186" -->
258
258
  ## Auto-Detection
259
259
 
260
260
  SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
@@ -264,7 +264,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
264
264
  **Opt-out phrases**: "Just brainstorm first" | "Don't plan yet" | "Quick discussion" | "Let's explore ideas"
265
265
  <!-- SW:END:autodetect -->
266
266
 
267
- <!-- SW:SECTION:metarule version="1.0.184" -->
267
+ <!-- SW:SECTION:metarule version="1.0.186" -->
268
268
  ## Meta-Rule: Think-Before-Act
269
269
 
270
270
  **Satisfy dependencies BEFORE dependent operations.**
@@ -275,7 +275,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
275
275
  ```
276
276
  <!-- SW:END:metarule -->
277
277
 
278
- <!-- SW:SECTION:rules version="1.0.184" -->
278
+ <!-- SW:SECTION:rules version="1.0.186" -->
279
279
  ## Rules
280
280
 
281
281
  1. **Files** → `.specweave/increments/####-name/` (see Structure section for details)
@@ -286,7 +286,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
286
286
  6. **⛔ Marketplace refresh**: Use `specweave refresh-marketplace` CLI (not `scripts/refresh-marketplace.sh`)
287
287
  <!-- SW:END:rules -->
288
288
 
289
- <!-- SW:SECTION:workflow version="1.0.184" -->
289
+ <!-- SW:SECTION:workflow version="1.0.186" -->
290
290
  ## Workflow
291
291
 
292
292
  `/sw:increment "X"` → `/sw:do` → `/sw:progress` → `/sw:done 0001`
@@ -306,7 +306,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
306
306
  **Natural language**: "Let's build X" → `/sw:increment` | "What's status?" → `/sw:progress` | "We're done" → `/sw:done` | "Ship while sleeping" → `/sw:auto`
307
307
  <!-- SW:END:workflow -->
308
308
 
309
- <!-- SW:SECTION:reflect version="1.0.184" -->
309
+ <!-- SW:SECTION:reflect version="1.0.186" -->
310
310
  ## Skill Memories
311
311
 
312
312
  SpecWeave learns from corrections. Learnings saved here automatically. Edit or delete as needed.
@@ -329,7 +329,7 @@ SpecWeave learns from corrections. Learnings saved here automatically. Edit or d
329
329
  - **2026-01-29**: in this codebase. Then use goToDefinition to show me where it's defined.
330
330
  - **2026-01-29**: ✗→✓ Find All References of handleAutoCommand using LSP The user wants me to find all references to handl
331
331
 
332
- <!-- SW:SECTION:context version="1.0.184" -->
332
+ <!-- SW:SECTION:context version="1.0.186" -->
333
333
  ## Context
334
334
 
335
335
  **Before implementing**: Check ADRs at `.specweave/docs/internal/architecture/adr/`
@@ -337,7 +337,7 @@ SpecWeave learns from corrections. Learnings saved here automatically. Edit or d
337
337
  **Load context**: `/sw:context <topic>` loads relevant living docs into conversation
338
338
  <!-- SW:END:context -->
339
339
 
340
- <!-- SW:SECTION:structure version="1.0.184" -->
340
+ <!-- SW:SECTION:structure version="1.0.186" -->
341
341
  ## Structure
342
342
 
343
343
  ```
@@ -352,7 +352,7 @@ SpecWeave learns from corrections. Learnings saved here automatically. Edit or d
352
352
  **Everything else → subfolders**: `reports/` | `logs/` | `scripts/` | `backups/`
353
353
  <!-- SW:END:structure -->
354
354
 
355
- <!-- SW:SECTION:taskformat version="1.0.184" -->
355
+ <!-- SW:SECTION:taskformat version="1.0.186" -->
356
356
  ## Task Format
357
357
 
358
358
  ```markdown
@@ -362,7 +362,7 @@ SpecWeave learns from corrections. Learnings saved here automatically. Edit or d
362
362
  ```
363
363
  <!-- SW:END:taskformat -->
364
364
 
365
- <!-- SW:SECTION:secrets version="1.0.184" -->
365
+ <!-- SW:SECTION:secrets version="1.0.186" -->
366
366
  ## Secrets Check
367
367
 
368
368
  **BEFORE CLI tools**: Check existing config first!
@@ -376,7 +376,7 @@ gh auth status
376
376
  **SECURITY**: NEVER use `grep TOKEN .env` without `-q` flag - it exposes credentials in terminal!
377
377
  <!-- SW:END:secrets -->
378
378
 
379
- <!-- SW:SECTION:syncing version="1.0.184" -->
379
+ <!-- SW:SECTION:syncing version="1.0.186" -->
380
380
  ## External Sync (GitHub/JIRA/ADO)
381
381
 
382
382
  **Commands**: `/sw-github:sync {id}` (issues) | `/sw:sync-specs` (living docs only)
@@ -386,7 +386,7 @@ gh auth status
386
386
  **Config**: Set `sync.github.enabled: true` + `canUpdateExternalItems: true` in config.json
387
387
  <!-- SW:END:syncing -->
388
388
 
389
- <!-- SW:SECTION:testing version="1.0.184" -->
389
+ <!-- SW:SECTION:testing version="1.0.186" -->
390
390
  ## Testing
391
391
 
392
392
  BDD in tasks.md | Unit >80% | `.test.ts` (Vitest)
@@ -398,7 +398,7 @@ vi.mock('./module', () => ({ func: mockFn }));
398
398
  ```
399
399
  <!-- SW:END:testing -->
400
400
 
401
- <!-- SW:SECTION:tdd version="1.0.184" -->
401
+ <!-- SW:SECTION:tdd version="1.0.186" -->
402
402
  ## TDD Mode (Test-Driven Development)
403
403
 
404
404
  **When `testing.defaultTestMode: "TDD"` is configured**, follow RED-GREEN-REFACTOR discipline:
@@ -459,7 +459,7 @@ When TDD is enabled, tasks include phase markers:
459
459
  **Rule**: Complete dependencies BEFORE dependent tasks (RED before GREEN).
460
460
  <!-- SW:END:tdd -->
461
461
 
462
- <!-- SW:SECTION:api version="1.0.184" -->
462
+ <!-- SW:SECTION:api version="1.0.186" -->
463
463
  ## API Development (OpenAPI-First)
464
464
 
465
465
  **For API projects only.** Commands: `/sw:api-docs --all` | `--openapi` | `--postman` | `--validate`
@@ -467,13 +467,13 @@ When TDD is enabled, tasks include phase markers:
467
467
  Enable in config: `{"apiDocs":{"enabled":true,"openApiPath":"openapi.yaml"}}`
468
468
  <!-- SW:END:api -->
469
469
 
470
- <!-- SW:SECTION:limits version="1.0.184" -->
470
+ <!-- SW:SECTION:limits version="1.0.186" -->
471
471
  ## Limits
472
472
 
473
473
  **Max 1500 lines/file** — extract before adding
474
474
  <!-- SW:END:limits -->
475
475
 
476
- <!-- SW:SECTION:troubleshooting version="1.0.184" -->
476
+ <!-- SW:SECTION:troubleshooting version="1.0.186" -->
477
477
  ## Troubleshooting
478
478
 
479
479
  | Issue | Fix |
@@ -489,7 +489,7 @@ Enable in config: `{"apiDocs":{"enabled":true,"openApiPath":"openapi.yaml"}}`
489
489
  | Marketplace shows 0 | Normal with auto-load; `/plugin list` shows actual |
490
490
  <!-- SW:END:troubleshooting -->
491
491
 
492
- <!-- SW:SECTION:lazyloading version="1.0.184" -->
492
+ <!-- SW:SECTION:lazyloading version="1.0.186" -->
493
493
  ## Plugin Auto-Loading
494
494
 
495
495
  Plugins load automatically based on project type and keywords. Manual install if needed:
@@ -503,7 +503,7 @@ export SPECWEAVE_DISABLE_AUTO_LOAD=1 # Disable auto-load
503
503
  **Token savings**: Core ~3-5K tokens vs all plugins ~60K+
504
504
  <!-- SW:END:lazyloading -->
505
505
 
506
- <!-- SW:SECTION:principles version="1.0.184" -->
506
+ <!-- SW:SECTION:principles version="1.0.186" -->
507
507
  ## Principles
508
508
 
509
509
  1. **Spec-first**: `/sw:increment` before coding
@@ -512,7 +512,7 @@ export SPECWEAVE_DISABLE_AUTO_LOAD=1 # Disable auto-load
512
512
  4. **Traceable**: All work → specs → ACs
513
513
  <!-- SW:END:principles -->
514
514
 
515
- <!-- SW:SECTION:linking version="1.0.184" -->
515
+ <!-- SW:SECTION:linking version="1.0.186" -->
516
516
  ## Bidirectional Linking
517
517
 
518
518
  Tasks ↔ User Stories auto-linked via AC-IDs: `AC-US1-01` → `US-001`
@@ -520,7 +520,7 @@ Tasks ↔ User Stories auto-linked via AC-IDs: `AC-US1-01` → `US-001`
520
520
  Task format: `**AC**: AC-US1-01, AC-US1-02` (CRITICAL for linking)
521
521
  <!-- SW:END:linking -->
522
522
 
523
- <!-- SW:SECTION:mcp version="1.0.184" -->
523
+ <!-- SW:SECTION:mcp version="1.0.186" -->
524
524
  ## External Services
525
525
 
526
526
  **Priority**: CLI tools first (simpler) → MCP for complex integrations
@@ -542,7 +542,7 @@ claude mcp add --transport stdio postgres -- npx -y @modelcontextprotocol/server
542
542
  MCP supports lazy-loading (auto mode) - tools load on-demand when >10% context.
543
543
  <!-- SW:END:mcp -->
544
544
 
545
- <!-- SW:SECTION:auto version="1.0.184" -->
545
+ <!-- SW:SECTION:auto version="1.0.186" -->
546
546
  ## Auto Mode
547
547
 
548
548
  **Commands**: `/sw:auto` (start) | `/sw:auto-status` (check) | `/sw:cancel-auto` (emergency only)
@@ -559,7 +559,7 @@ MCP supports lazy-loading (auto mode) - tools load on-demand when >10% context.
559
559
  **STOP & ASK** if: Spec conflicts | Task unnecessary | Requirement ambiguous
560
560
  <!-- SW:END:auto -->
561
561
 
562
- <!-- SW:SECTION:docs version="1.0.184" -->
562
+ <!-- SW:SECTION:docs version="1.0.186" -->
563
563
  ## Docs
564
564
 
565
565
  [spec-weave.com](https://spec-weave.com)
package/bin/specweave.js CHANGED
@@ -649,6 +649,51 @@ program
649
649
  await cacheCommand(options);
650
650
  });
651
651
 
652
+ // LSP command - Code intelligence operations
653
+ const lspCmd = program
654
+ .command('lsp')
655
+ .description('LSP code intelligence (refs, def, hover, symbols, search)');
656
+
657
+ lspCmd
658
+ .command('refs <file> <symbol>')
659
+ .description('Find all references to a symbol')
660
+ .action(async (file, symbol) => {
661
+ const { handleLspRefs } = await import('../dist/src/cli/commands/lsp.js');
662
+ await handleLspRefs(process.cwd(), file, symbol);
663
+ });
664
+
665
+ lspCmd
666
+ .command('def <file> <symbol>')
667
+ .description('Go to definition of a symbol')
668
+ .action(async (file, symbol) => {
669
+ const { handleLspDef } = await import('../dist/src/cli/commands/lsp.js');
670
+ await handleLspDef(process.cwd(), file, symbol);
671
+ });
672
+
673
+ lspCmd
674
+ .command('hover <file> <symbol>')
675
+ .description('Get type information for a symbol')
676
+ .action(async (file, symbol) => {
677
+ const { handleLspHover } = await import('../dist/src/cli/commands/lsp.js');
678
+ await handleLspHover(process.cwd(), file, symbol);
679
+ });
680
+
681
+ lspCmd
682
+ .command('symbols <file>')
683
+ .description('List all symbols in a file')
684
+ .action(async (file) => {
685
+ const { handleLspSymbols } = await import('../dist/src/cli/commands/lsp.js');
686
+ await handleLspSymbols(process.cwd(), file);
687
+ });
688
+
689
+ lspCmd
690
+ .command('search <query>')
691
+ .description('Search for symbols in workspace')
692
+ .action(async (query) => {
693
+ const { handleLspSearch } = await import('../dist/src/cli/commands/lsp.js');
694
+ await handleLspSearch(process.cwd(), query);
695
+ });
696
+
652
697
  // Commits command - Display last 2 git commits
653
698
  program
654
699
  .command('commits')
@@ -0,0 +1,50 @@
1
+ /**
2
+ * LSP CLI Commands
3
+ *
4
+ * Provides CLI interface to LSP operations: refs, def, hover, symbols, search.
5
+ * Accepts symbol NAME (not line:char) for ease of use.
6
+ *
7
+ * @module cli/commands/lsp
8
+ */
9
+ import { Command } from 'commander';
10
+ /**
11
+ * Position in a file (0-indexed)
12
+ */
13
+ export interface SymbolPosition {
14
+ line: number;
15
+ character: number;
16
+ }
17
+ /**
18
+ * Find the position of a symbol in a file by name.
19
+ * Uses regex with word boundaries to find the symbol declaration.
20
+ *
21
+ * @param filePath - Path to the file
22
+ * @param symbolName - Name of the symbol to find
23
+ * @returns Position (0-indexed) or null if not found
24
+ */
25
+ export declare function findSymbolPosition(filePath: string, symbolName: string): SymbolPosition | null;
26
+ /**
27
+ * Find all references to a symbol
28
+ */
29
+ export declare function handleLspRefs(projectRoot: string, filePath: string, symbolName: string): Promise<void>;
30
+ /**
31
+ * Go to definition of a symbol
32
+ */
33
+ export declare function handleLspDef(projectRoot: string, filePath: string, symbolName: string): Promise<void>;
34
+ /**
35
+ * Get hover/type information for a symbol
36
+ */
37
+ export declare function handleLspHover(projectRoot: string, filePath: string, symbolName: string): Promise<void>;
38
+ /**
39
+ * List all symbols in a file
40
+ */
41
+ export declare function handleLspSymbols(projectRoot: string, filePath: string): Promise<void>;
42
+ /**
43
+ * Search for symbols in workspace
44
+ */
45
+ export declare function handleLspSearch(projectRoot: string, query: string): Promise<void>;
46
+ /**
47
+ * Create the LSP command for Commander.js
48
+ */
49
+ export declare function createLspCommand(): Command;
50
+ //# sourceMappingURL=lsp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/lsp.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAiD9F;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAiCf;AA+BD;;GAEG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AA+BD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B3F;AAsCD;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BvF;AAyED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAiD1C"}
@@ -0,0 +1,410 @@
1
+ /**
2
+ * LSP CLI Commands
3
+ *
4
+ * Provides CLI interface to LSP operations: refs, def, hover, symbols, search.
5
+ * Accepts symbol NAME (not line:char) for ease of use.
6
+ *
7
+ * @module cli/commands/lsp
8
+ */
9
+ import fs from 'fs';
10
+ import path from 'path';
11
+ import { Command } from 'commander';
12
+ import { getGlobalLSPManager, shutdownGlobalLSPManager } from '../../core/lsp/lsp-manager.js';
13
+ /**
14
+ * Find the position of a symbol in a file by name.
15
+ * Uses regex with word boundaries to find the symbol declaration.
16
+ *
17
+ * @param filePath - Path to the file
18
+ * @param symbolName - Name of the symbol to find
19
+ * @returns Position (0-indexed) or null if not found
20
+ */
21
+ export function findSymbolPosition(filePath, symbolName) {
22
+ const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);
23
+ if (!fs.existsSync(resolvedPath)) {
24
+ return null;
25
+ }
26
+ const content = fs.readFileSync(resolvedPath, 'utf-8');
27
+ const lines = content.split('\n');
28
+ // Patterns to match symbol declarations (in order of specificity)
29
+ const patterns = [
30
+ // Function/method declaration: function name(, async function name(, name(
31
+ new RegExp(`\\b(?:export\\s+)?(?:async\\s+)?function\\s+(${symbolName})\\s*\\(`),
32
+ // Class declaration
33
+ new RegExp(`\\b(?:export\\s+)?class\\s+(${symbolName})\\b`),
34
+ // Interface declaration
35
+ new RegExp(`\\b(?:export\\s+)?interface\\s+(${symbolName})\\b`),
36
+ // Type declaration
37
+ new RegExp(`\\b(?:export\\s+)?type\\s+(${symbolName})\\b`),
38
+ // Const/let/var declaration
39
+ new RegExp(`\\b(?:export\\s+)?(?:const|let|var)\\s+(${symbolName})\\b`),
40
+ // Method in class (indented)
41
+ new RegExp(`^\\s+(?:async\\s+)?(${symbolName})\\s*\\(`),
42
+ // Property assignment in object/class
43
+ new RegExp(`\\b(${symbolName})\\s*[:=]`),
44
+ // Generic word boundary match (fallback)
45
+ new RegExp(`\\b(${symbolName})\\b`),
46
+ ];
47
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
48
+ const line = lines[lineIndex];
49
+ for (const pattern of patterns) {
50
+ const match = pattern.exec(line);
51
+ if (match) {
52
+ // Find the position of the captured group (the symbol name)
53
+ const symbolStartIndex = line.indexOf(match[1], match.index);
54
+ if (symbolStartIndex !== -1) {
55
+ return {
56
+ line: lineIndex,
57
+ character: symbolStartIndex,
58
+ };
59
+ }
60
+ }
61
+ }
62
+ }
63
+ return null;
64
+ }
65
+ /**
66
+ * Find all references to a symbol
67
+ */
68
+ export async function handleLspRefs(projectRoot, filePath, symbolName) {
69
+ const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);
70
+ // Find symbol position
71
+ const position = findSymbolPosition(resolvedPath, symbolName);
72
+ if (!position) {
73
+ console.error(`Symbol '${symbolName}' not found in ${filePath}`);
74
+ return;
75
+ }
76
+ try {
77
+ const lspManager = getGlobalLSPManager(projectRoot);
78
+ await lspManager.initialize();
79
+ const result = await lspManager.findReferences(resolvedPath, position.line, position.character);
80
+ if (result && result.success && result.locations.length > 0) {
81
+ console.log(`References to '${symbolName}':\n`);
82
+ for (const loc of result.locations) {
83
+ const relPath = path.relative(projectRoot, loc.uri.replace('file://', ''));
84
+ console.log(` ${relPath}:${loc.range.start.line + 1}:${loc.range.start.character + 1}`);
85
+ }
86
+ console.log(`\nTotal: ${result.locations.length} references`);
87
+ }
88
+ else {
89
+ // Fall back to grep-based search
90
+ await grepFallbackRefs(projectRoot, symbolName);
91
+ }
92
+ await shutdownGlobalLSPManager();
93
+ }
94
+ catch {
95
+ // LSP failed, fall back to grep
96
+ await grepFallbackRefs(projectRoot, symbolName);
97
+ }
98
+ }
99
+ /**
100
+ * Grep fallback for finding references
101
+ */
102
+ async function grepFallbackRefs(projectRoot, symbolName) {
103
+ console.log(`References to '${symbolName}' (grep fallback):\n`);
104
+ const { execSync } = await import('child_process');
105
+ try {
106
+ const result = execSync(`grep -rn --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" "\\b${symbolName}\\b" .`, { cwd: projectRoot, encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 });
107
+ const lines = result.trim().split('\n').filter(Boolean);
108
+ for (const line of lines) {
109
+ console.log(` ${line}`);
110
+ }
111
+ console.log(`\nTotal: ${lines.length} matches (grep)`);
112
+ }
113
+ catch (error) {
114
+ const exitCode = error.status;
115
+ if (exitCode === 1) {
116
+ console.log(' No references found');
117
+ }
118
+ else {
119
+ console.error('Grep search failed');
120
+ }
121
+ }
122
+ }
123
+ /**
124
+ * Go to definition of a symbol
125
+ */
126
+ export async function handleLspDef(projectRoot, filePath, symbolName) {
127
+ const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);
128
+ const position = findSymbolPosition(resolvedPath, symbolName);
129
+ if (!position) {
130
+ console.error(`Symbol '${symbolName}' not found in ${filePath}`);
131
+ return;
132
+ }
133
+ try {
134
+ const lspManager = getGlobalLSPManager(projectRoot);
135
+ await lspManager.initialize();
136
+ const result = await lspManager.goToDefinition(resolvedPath, position.line, position.character);
137
+ if (result && result.success && result.location) {
138
+ const loc = result.location;
139
+ const relPath = path.relative(projectRoot, loc.uri.replace('file://', ''));
140
+ console.log(`Definition of '${symbolName}':\n`);
141
+ console.log(` ${relPath}:${loc.range.start.line + 1}:${loc.range.start.character + 1}`);
142
+ }
143
+ else {
144
+ // Symbol is likely defined at the position we found
145
+ const relPath = path.relative(projectRoot, resolvedPath);
146
+ console.log(`Definition of '${symbolName}':\n`);
147
+ console.log(` ${relPath}:${position.line + 1}:${position.character + 1}`);
148
+ }
149
+ await shutdownGlobalLSPManager();
150
+ }
151
+ catch {
152
+ // Fall back to showing found position
153
+ const relPath = path.relative(projectRoot, resolvedPath);
154
+ console.log(`Definition of '${symbolName}' (fallback):\n`);
155
+ console.log(` ${relPath}:${position.line + 1}:${position.character + 1}`);
156
+ }
157
+ }
158
+ /**
159
+ * Get hover/type information for a symbol
160
+ */
161
+ export async function handleLspHover(projectRoot, filePath, symbolName) {
162
+ const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);
163
+ const position = findSymbolPosition(resolvedPath, symbolName);
164
+ if (!position) {
165
+ console.error(`Symbol '${symbolName}' not found in ${filePath}`);
166
+ return;
167
+ }
168
+ try {
169
+ const lspManager = getGlobalLSPManager(projectRoot);
170
+ await lspManager.initialize();
171
+ const result = await lspManager.hover(resolvedPath, position.line, position.character);
172
+ if (result && result.success && result.contents) {
173
+ console.log(`Type info for '${symbolName}':\n`);
174
+ console.log(result.contents);
175
+ }
176
+ else {
177
+ // Fall back to showing the line content
178
+ await hoverFallback(resolvedPath, symbolName, position);
179
+ }
180
+ await shutdownGlobalLSPManager();
181
+ }
182
+ catch {
183
+ await hoverFallback(resolvedPath, symbolName, position);
184
+ }
185
+ }
186
+ /**
187
+ * Fallback hover showing line content
188
+ */
189
+ async function hoverFallback(filePath, symbolName, position) {
190
+ const content = fs.readFileSync(filePath, 'utf-8');
191
+ const lines = content.split('\n');
192
+ const line = lines[position.line];
193
+ console.log(`Type info for '${symbolName}' (from source):\n`);
194
+ console.log(` ${line.trim()}`);
195
+ // Try to infer type from declaration
196
+ if (line.includes('function')) {
197
+ console.log(`\n Kind: function`);
198
+ }
199
+ else if (line.includes('class')) {
200
+ console.log(`\n Kind: class`);
201
+ }
202
+ else if (line.includes('interface')) {
203
+ console.log(`\n Kind: interface`);
204
+ }
205
+ else if (line.includes('type')) {
206
+ console.log(`\n Kind: type alias`);
207
+ }
208
+ else if (line.includes('const') || line.includes('let') || line.includes('var')) {
209
+ console.log(`\n Kind: variable`);
210
+ }
211
+ }
212
+ /**
213
+ * List all symbols in a file
214
+ */
215
+ export async function handleLspSymbols(projectRoot, filePath) {
216
+ const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);
217
+ if (!fs.existsSync(resolvedPath)) {
218
+ console.error(`File not found: ${filePath}`);
219
+ return;
220
+ }
221
+ try {
222
+ const lspManager = getGlobalLSPManager(projectRoot);
223
+ await lspManager.initialize();
224
+ const result = await lspManager.documentSymbols(resolvedPath);
225
+ if (result && result.success && result.symbols.length > 0) {
226
+ console.log(`Symbols in ${path.basename(filePath)}:\n`);
227
+ for (const sym of result.symbols) {
228
+ const kind = getSymbolKindName(sym.kind);
229
+ const line = sym.location?.range?.start?.line ?? 0;
230
+ console.log(` ${kind.padEnd(12)} ${sym.name} (line ${line + 1})`);
231
+ }
232
+ console.log(`\nTotal: ${result.symbols.length} symbols`);
233
+ }
234
+ else {
235
+ await symbolsFallback(resolvedPath);
236
+ }
237
+ await shutdownGlobalLSPManager();
238
+ }
239
+ catch {
240
+ await symbolsFallback(resolvedPath);
241
+ }
242
+ }
243
+ /**
244
+ * Fallback symbol extraction using regex
245
+ */
246
+ async function symbolsFallback(filePath) {
247
+ const content = fs.readFileSync(filePath, 'utf-8');
248
+ const lines = content.split('\n');
249
+ console.log(`Symbols in ${path.basename(filePath)} (regex fallback):\n`);
250
+ const symbols = [];
251
+ const patterns = [
252
+ { kind: 'function', regex: /(?:export\s+)?(?:async\s+)?function\s+(\w+)/ },
253
+ { kind: 'class', regex: /(?:export\s+)?class\s+(\w+)/ },
254
+ { kind: 'interface', regex: /(?:export\s+)?interface\s+(\w+)/ },
255
+ { kind: 'type', regex: /(?:export\s+)?type\s+(\w+)/ },
256
+ { kind: 'const', regex: /(?:export\s+)?const\s+(\w+)\s*[:=]/ },
257
+ ];
258
+ for (let i = 0; i < lines.length; i++) {
259
+ const line = lines[i];
260
+ for (const { kind, regex } of patterns) {
261
+ const match = regex.exec(line);
262
+ if (match) {
263
+ symbols.push({ kind, name: match[1], line: i + 1 });
264
+ }
265
+ }
266
+ }
267
+ for (const sym of symbols) {
268
+ console.log(` ${sym.kind.padEnd(12)} ${sym.name} (line ${sym.line})`);
269
+ }
270
+ console.log(`\nTotal: ${symbols.length} symbols`);
271
+ }
272
+ /**
273
+ * Search for symbols in workspace
274
+ */
275
+ export async function handleLspSearch(projectRoot, query) {
276
+ try {
277
+ const lspManager = getGlobalLSPManager(projectRoot);
278
+ await lspManager.initialize();
279
+ const result = await lspManager.workspaceSymbols(query);
280
+ if (result && result.success && result.symbols.length > 0) {
281
+ console.log(`Workspace symbols matching '${query}':\n`);
282
+ for (const sym of result.symbols) {
283
+ const kind = getSymbolKindName(sym.kind);
284
+ const relPath = sym.location?.uri
285
+ ? path.relative(projectRoot, sym.location.uri.replace('file://', ''))
286
+ : 'unknown';
287
+ const line = sym.location?.range?.start?.line ?? 0;
288
+ console.log(` ${kind.padEnd(12)} ${sym.name} (${relPath}:${line + 1})`);
289
+ }
290
+ console.log(`\nTotal: ${result.symbols.length} symbols`);
291
+ }
292
+ else {
293
+ await searchFallback(projectRoot, query);
294
+ }
295
+ await shutdownGlobalLSPManager();
296
+ }
297
+ catch {
298
+ await searchFallback(projectRoot, query);
299
+ }
300
+ }
301
+ /**
302
+ * Fallback workspace search using grep
303
+ */
304
+ async function searchFallback(projectRoot, query) {
305
+ console.log(`Workspace symbols matching '${query}' (grep fallback):\n`);
306
+ const { execSync } = await import('child_process');
307
+ try {
308
+ // Search for declarations matching the query
309
+ const patterns = [
310
+ `function\\s+\\w*${query}\\w*`,
311
+ `class\\s+\\w*${query}\\w*`,
312
+ `interface\\s+\\w*${query}\\w*`,
313
+ `type\\s+\\w*${query}\\w*`,
314
+ ];
315
+ const combinedPattern = patterns.join('|');
316
+ const result = execSync(`grep -rn --include="*.ts" --include="*.tsx" -E "${combinedPattern}" .`, { cwd: projectRoot, encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 });
317
+ const lines = result.trim().split('\n').filter(Boolean);
318
+ for (const line of lines.slice(0, 20)) {
319
+ // Limit to 20 results
320
+ console.log(` ${line}`);
321
+ }
322
+ if (lines.length > 20) {
323
+ console.log(` ... and ${lines.length - 20} more`);
324
+ }
325
+ console.log(`\nTotal: ${lines.length} matches`);
326
+ }
327
+ catch (error) {
328
+ const exitCode = error.status;
329
+ if (exitCode === 1) {
330
+ console.log(' No symbols found matching query');
331
+ }
332
+ else {
333
+ console.error('Search failed');
334
+ }
335
+ }
336
+ }
337
+ /**
338
+ * Convert LSP symbol kind number to name
339
+ */
340
+ function getSymbolKindName(kind) {
341
+ const kinds = {
342
+ 1: 'File',
343
+ 2: 'Module',
344
+ 3: 'Namespace',
345
+ 4: 'Package',
346
+ 5: 'Class',
347
+ 6: 'Method',
348
+ 7: 'Property',
349
+ 8: 'Field',
350
+ 9: 'Constructor',
351
+ 10: 'Enum',
352
+ 11: 'Interface',
353
+ 12: 'Function',
354
+ 13: 'Variable',
355
+ 14: 'Constant',
356
+ 15: 'String',
357
+ 16: 'Number',
358
+ 17: 'Boolean',
359
+ 18: 'Array',
360
+ };
361
+ return kinds[kind] || 'Unknown';
362
+ }
363
+ /**
364
+ * Create the LSP command for Commander.js
365
+ */
366
+ export function createLspCommand() {
367
+ const lsp = new Command('lsp').description('LSP code intelligence operations');
368
+ // specweave lsp refs <file> <symbol>
369
+ lsp
370
+ .command('refs <file> <symbol>')
371
+ .description('Find all references to a symbol')
372
+ .action(async (file, symbol) => {
373
+ const projectRoot = process.cwd();
374
+ await handleLspRefs(projectRoot, file, symbol);
375
+ });
376
+ // specweave lsp def <file> <symbol>
377
+ lsp
378
+ .command('def <file> <symbol>')
379
+ .description('Go to definition of a symbol')
380
+ .action(async (file, symbol) => {
381
+ const projectRoot = process.cwd();
382
+ await handleLspDef(projectRoot, file, symbol);
383
+ });
384
+ // specweave lsp hover <file> <symbol>
385
+ lsp
386
+ .command('hover <file> <symbol>')
387
+ .description('Get type information for a symbol')
388
+ .action(async (file, symbol) => {
389
+ const projectRoot = process.cwd();
390
+ await handleLspHover(projectRoot, file, symbol);
391
+ });
392
+ // specweave lsp symbols <file>
393
+ lsp
394
+ .command('symbols <file>')
395
+ .description('List all symbols in a file')
396
+ .action(async (file) => {
397
+ const projectRoot = process.cwd();
398
+ await handleLspSymbols(projectRoot, file);
399
+ });
400
+ // specweave lsp search <query>
401
+ lsp
402
+ .command('search <query>')
403
+ .description('Search for symbols in workspace')
404
+ .action(async (query) => {
405
+ const projectRoot = process.cwd();
406
+ await handleLspSearch(projectRoot, query);
407
+ });
408
+ return lsp;
409
+ }
410
+ //# sourceMappingURL=lsp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.js","sourceRoot":"","sources":["../../../../src/cli/commands/lsp.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specweave",
3
- "version": "1.0.186",
3
+ "version": "1.0.187",
4
4
  "description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,180 +1,141 @@
1
1
  ---
2
2
  name: lsp
3
- description: Direct LSP (Language Server Protocol) code intelligence for any language. Use for findReferences, goToDefinition, hover, and symbol search. Works with TypeScript, Python, C#, Go, Rust. Bypasses Claude Code's built-in LSP (which has known bugs).
3
+ description: >
4
+ Code intelligence via LSP - find references, go to definition, hover type info, list symbols.
5
+ Activates on: "find all references", "go to definition", "where is X defined",
6
+ "show type of", "list symbols", "search symbols", "what uses", "who calls".
7
+ Works with TypeScript, Python, C#, Go, Rust. Falls back to grep if LSP unavailable.
4
8
  ---
5
9
 
6
- # SpecWeave LSP Skill
10
+ # LSP Code Intelligence
7
11
 
8
- Direct access to Language Server Protocol features for code intelligence.
12
+ Use SpecWeave's LSP CLI for semantic code navigation and analysis.
9
13
 
10
- ## When to Use This Skill
14
+ ## How to Use (IMPORTANT)
11
15
 
12
- Use this skill when the user asks for:
13
- - "Find all references to X"
14
- - "Go to definition of X"
15
- - "Where is X defined?"
16
- - "Show me the type of X"
17
- - "List symbols in file X"
18
- - "Search for symbol X in workspace"
16
+ **Use Bash tool with `specweave lsp` commands:**
19
17
 
20
- ## Implementation
18
+ ```bash
19
+ # Find all references to a symbol
20
+ specweave lsp refs <file> <symbol>
21
+
22
+ # Go to definition
23
+ specweave lsp def <file> <symbol>
24
+
25
+ # Get type information (hover)
26
+ specweave lsp hover <file> <symbol>
21
27
 
22
- This skill uses the existing SpecWeave LSP infrastructure:
23
- - `src/core/lsp/lsp-client.ts` - Low-level JSON-RPC client
24
- - `src/core/lsp/lsp-manager.ts` - Multi-language manager
28
+ # List all symbols in a file
29
+ specweave lsp symbols <file>
30
+
31
+ # Search workspace for symbols
32
+ specweave lsp search <query>
33
+ ```
25
34
 
26
- ### Usage Pattern
35
+ ## Command Reference
27
36
 
28
- ```typescript
29
- import { getGlobalLSPManager, shutdownGlobalLSPManager } from 'src/core/lsp/lsp-manager.js';
37
+ | Command | Purpose | Example |
38
+ |---------|---------|---------|
39
+ | `lsp refs` | Find all usages of a symbol | `specweave lsp refs src/api.ts handleRequest` |
40
+ | `lsp def` | Navigate to symbol definition | `specweave lsp def src/utils.ts formatDate` |
41
+ | `lsp hover` | Get type signature and docs | `specweave lsp hover src/models.ts User` |
42
+ | `lsp symbols` | List all symbols in file | `specweave lsp symbols src/index.ts` |
43
+ | `lsp search` | Find symbols across workspace | `specweave lsp search Controller` |
30
44
 
31
- // Get the LSP manager (auto-initializes)
32
- const lspManager = getGlobalLSPManager(projectRoot);
45
+ ## When to Use LSP vs Grep
33
46
 
34
- // Find references
35
- const refs = await lspManager.findReferences('src/file.ts', line, character);
47
+ | Task | Use LSP | Use Grep |
48
+ |------|---------|----------|
49
+ | Find function usages | ✅ `lsp refs` | ❌ |
50
+ | Navigate to definition | ✅ `lsp def` | ❌ |
51
+ | Get type information | ✅ `lsp hover` | ❌ |
52
+ | Search text patterns | ❌ | ✅ `Grep tool` |
53
+ | Find in comments | ❌ | ✅ `Grep tool` |
54
+ | Case-insensitive search | ❌ | ✅ `Grep -i` |
36
55
 
37
- // Go to definition
38
- const def = await lspManager.goToDefinition('src/file.ts', line, character);
56
+ **Rule of thumb**: Use LSP for symbols, Grep for text patterns.
39
57
 
40
- // Get hover info (types, docs)
41
- const hover = await lspManager.hover('src/file.ts', line, character);
58
+ ## Examples
42
59
 
43
- // List symbols in file
44
- const symbols = await lspManager.documentSymbols('src/file.ts');
60
+ ### Example 1: Find All References Before Refactoring
45
61
 
46
- // Search workspace for symbol
47
- const wsSymbols = await lspManager.workspaceSymbols('MyClass');
62
+ User: "Find all references to handleAutoCommand"
48
63
 
49
- // Cleanup when done
50
- await shutdownGlobalLSPManager();
64
+ ```bash
65
+ specweave lsp refs src/cli/commands/auto.ts handleAutoCommand
51
66
  ```
52
67
 
53
- ## Supported Languages
68
+ Output:
69
+ ```
70
+ References to 'handleAutoCommand':
54
71
 
55
- | Language | Server | Detection |
56
- |----------|--------|-----------|
57
- | TypeScript/JavaScript | `typescript-language-server` | `tsconfig.json`, `package.json` |
58
- | Python | `pyright-langserver` or `pylsp` | `requirements.txt`, `pyproject.toml` |
59
- | C#/.NET | `csharp-ls` | `*.csproj`, `*.sln` |
60
- | Go | `gopls` | `go.mod` |
61
- | Rust | `rust-analyzer` | `Cargo.toml` |
72
+ bin/specweave.js:473:1
73
+ bin/specweave.js:474:1
74
+ src/cli/commands/auto.ts:82:5
75
+ src/cli/commands/auto.ts:96:24
62
76
 
63
- ## Position Calculation
64
-
65
- LSP positions are 0-indexed:
66
- - `line`: 0-based line number (first line = 0)
67
- - `character`: 0-based character offset
68
-
69
- To find a symbol position:
70
- 1. Read the file
71
- 2. Count lines (0-indexed)
72
- 3. Find character offset within the line (0-indexed)
73
-
74
- ## Response Formats
75
-
76
- ### findReferences
77
-
78
- ```typescript
79
- {
80
- locations: [
81
- {
82
- uri: 'file:///path/to/file.ts',
83
- range: {
84
- start: { line: 10, character: 5 },
85
- end: { line: 10, character: 15 }
86
- }
87
- }
88
- ],
89
- success: true
90
- }
77
+ Total: 4 references
91
78
  ```
92
79
 
93
- ### goToDefinition
94
-
95
- ```typescript
96
- {
97
- location: {
98
- uri: 'file:///path/to/definition.ts',
99
- range: {
100
- start: { line: 5, character: 0 },
101
- end: { line: 5, character: 20 }
102
- }
103
- },
104
- success: true
105
- }
80
+ ### Example 2: Go to Definition
81
+
82
+ User: "Where is processArgs defined?"
83
+
84
+ ```bash
85
+ specweave lsp def src/cli/commands/auto.ts processArgs
106
86
  ```
107
87
 
108
- ### hover
88
+ ### Example 3: Get Type Information
89
+
90
+ User: "What's the type signature of handleAutoCommand?"
109
91
 
110
- ```typescript
111
- {
112
- contents: '(method) MyClass.myMethod(): void',
113
- range: { start: {...}, end: {...} },
114
- success: true
115
- }
92
+ ```bash
93
+ specweave lsp hover src/cli/commands/auto.ts handleAutoCommand
116
94
  ```
117
95
 
118
- ### documentSymbols
119
-
120
- ```typescript
121
- {
122
- symbols: [
123
- {
124
- name: 'MyClass',
125
- kind: 5, // Class
126
- location: {...},
127
- containerName: undefined
128
- },
129
- {
130
- name: 'myMethod',
131
- kind: 6, // Method
132
- location: {...},
133
- containerName: 'MyClass'
134
- }
135
- ],
136
- success: true
137
- }
96
+ ### Example 4: List All Exports
97
+
98
+ User: "What functions are exported from lsp.ts?"
99
+
100
+ ```bash
101
+ specweave lsp symbols src/cli/commands/lsp.ts
138
102
  ```
139
103
 
140
- ## Symbol Kinds
141
-
142
- | Kind | Name |
143
- |------|------|
144
- | 1 | File |
145
- | 2 | Module |
146
- | 3 | Namespace |
147
- | 4 | Package |
148
- | 5 | Class |
149
- | 6 | Method |
150
- | 7 | Property |
151
- | 8 | Field |
152
- | 9 | Constructor |
153
- | 10 | Enum |
154
- | 11 | Interface |
155
- | 12 | Function |
156
- | 13 | Variable |
157
- | 14 | Constant |
158
- | 15 | String |
159
- | 16 | Number |
160
- | 17 | Boolean |
161
- | 18 | Array |
104
+ ### Example 5: Search Workspace
105
+
106
+ User: "Find all Command classes"
107
+
108
+ ```bash
109
+ specweave lsp search Command
110
+ ```
111
+
112
+ ## Supported Languages
113
+
114
+ | Language | Server Required | Auto-detected by |
115
+ |----------|-----------------|------------------|
116
+ | TypeScript/JS | `typescript-language-server` | `tsconfig.json`, `package.json` |
117
+ | Python | `pyright` or `pylsp` | `requirements.txt`, `pyproject.toml` |
118
+ | C#/.NET | `csharp-ls` | `*.csproj`, `*.sln` |
119
+ | Go | `gopls` | `go.mod` |
120
+ | Rust | `rust-analyzer` | `Cargo.toml` |
121
+
122
+ ## Fallback Behavior
123
+
124
+ If LSP is unavailable (server not installed, timeout, etc.):
125
+ 1. Commands automatically fall back to grep-based search
126
+ 2. Results show "(grep fallback)" in output
127
+ 3. Still functional, but less precise for symbol resolution
162
128
 
163
129
  ## Requirements
164
130
 
165
131
  Language servers must be installed globally:
166
132
 
167
133
  ```bash
168
- # TypeScript
134
+ # TypeScript (most common)
169
135
  npm install -g typescript-language-server typescript
170
136
 
171
137
  # Python
172
138
  pip install pyright
173
- # or
174
- pip install python-lsp-server
175
-
176
- # C#
177
- dotnet tool install -g csharp-ls
178
139
 
179
140
  # Go
180
141
  go install golang.org/x/tools/gopls@latest
@@ -183,23 +144,32 @@ go install golang.org/x/tools/gopls@latest
183
144
  rustup component add rust-analyzer
184
145
  ```
185
146
 
186
- ## Fallback Behavior
187
-
188
- If LSP is not available for a file type:
189
- 1. The manager returns `null`
190
- 2. Fall back to grep-based search
191
- 3. Results are less precise but still useful
147
+ ## Decision Tree for Claude
192
148
 
193
- ## Example: Find All References
194
-
195
- User: "Find all references to handleAutoCommand in src/cli/commands/auto.ts"
196
-
197
- Steps:
198
- 1. Identify file: `src/cli/commands/auto.ts`
199
- 2. Find symbol position (read file, locate `handleAutoCommand`)
200
- 3. Call `lspManager.findReferences('src/cli/commands/auto.ts', line, char)`
201
- 4. Format and display results
149
+ ```
150
+ User asks about code navigation?
151
+
152
+ ├─ "Find references to X" or "What uses X" or "Who calls X"
153
+ │ └─ Use: specweave lsp refs <file> <symbol>
154
+
155
+ ├─ "Go to definition" or "Where is X defined"
156
+ │ └─ Use: specweave lsp def <file> <symbol>
157
+
158
+ ├─ "What type is X" or "Show signature of X"
159
+ │ └─ Use: specweave lsp hover <file> <symbol>
160
+
161
+ ├─ "List symbols in file" or "What's exported"
162
+ │ └─ Use: specweave lsp symbols <file>
163
+
164
+ ├─ "Find symbol X in workspace" or "Search for X"
165
+ │ └─ Use: specweave lsp search <query>
166
+
167
+ └─ Text search, patterns, comments
168
+ └─ Use: Grep tool (not LSP)
169
+ ```
202
170
 
203
- ## Why This Skill Exists
171
+ ## Why This Exists
204
172
 
205
- Claude Code's built-in LSP has known bugs (GitHub Issues #15148, #16291, #20050). This skill provides direct access to language servers via JSON-RPC, bypassing Claude Code's broken infrastructure.
173
+ Claude Code's built-in LSP has known bugs (GitHub Issues #15148, #16291, #20050).
174
+ This skill provides direct access to language servers via SpecWeave's CLI,
175
+ bypassing the broken infrastructure.