| name | lsp |
| description | Query language servers (pyright, typescript-language-server) for code intelligence — symbols, definitions, references, hover info, diagnostics, and impact analysis. Use for exploring codebases, planning code changes, and reviewing change impact across Python and TypeScript projects. |
| allowed-tools | ["Read","Grep","Glob","Bash(.claude/skills/lsp/scripts/lsp_explorer.sh *)"] |
| user-invokable | true |
LSP Explorer
Query language servers for code intelligence from the command line.
Quick Start
.claude/skills/lsp/scripts/lsp_explorer.sh symbols src/main.py
.claude/skills/lsp/scripts/lsp_explorer.sh definition src/main.py 10 5
.claude/skills/lsp/scripts/lsp_explorer.sh references src/main.py 10 5
.claude/skills/lsp/scripts/lsp_explorer.sh hover src/main.py 10 5
.claude/skills/lsp/scripts/lsp_explorer.sh diagnostics src/main.py
.claude/skills/lsp/scripts/lsp_explorer.sh explore src/main.py
.claude/skills/lsp/scripts/lsp_explorer.sh impact src/main.py 10 5 --depth 2
.claude/skills/lsp/scripts/lsp_explorer.sh index --root .
.claude/skills/lsp/scripts/lsp_explorer.sh lookup MyClass --pretty
.claude/skills/lsp/scripts/lsp_explorer.sh dead --file-type source --exclude-private --pretty
.claude/skills/lsp/scripts/lsp_explorer.sh trace src/main.py 10 5 --depth 3 --pretty
Output Format
All output is compact JSON optimized for token efficiency. Use --pretty or pipe to jq for human-readable output.
Key Mapping
| Key | Meaning |
|---|
n | name |
k | kind (class, method, function, variable, etc.) |
r | range [start_line, end_line] (1-indexed) |
ch | children (nested symbols) |
f | file (relative path) |
l | line (1-indexed) |
c | column (1-indexed) |
s | severity (1=error, 2=warning, 3=info, 4=hint) |
d | detail (type annotation) |
sym | symbol name |
refs | references |
msg | message |
src | source (which LSP server) |
doc | documentation string |
type | type signature |
Example Outputs
symbols:
[{"n":"MyClass","k":"class","r":[1,25],"ch":[{"n":"__init__","k":"method","r":[3,6]},{"n":"process","k":"method","r":[8,25]}]},{"n":"main","k":"function","r":[28,35]}]
references:
{"refs":{"src/main.py":[12,28,33],"src/utils.py":[7,45]},"total":5}
definition:
[{"f":"src/models.py","l":15,"c":4,"preview":" def process(self, data: list[str]) -> Result:"}]
hover:
{"type":"(self, data: list[str]) -> Result","doc":"Process input data and return result."}
diagnostics:
[{"f":"src/main.py","l":12,"c":1,"s":1,"msg":"Argument missing for parameter \"name\"","src":"pyright"}]
Symbol Index (SQLite Cache)
Pre-compute all definitions and references across a project into a SQLite cache, then query instantly without spinning up LSP servers.
.claude/skills/lsp/scripts/lsp_explorer.sh index --root .
.claude/skills/lsp/scripts/lsp_explorer.sh index --root . --cache-incremental
.claude/skills/lsp/scripts/lsp_explorer.sh index-status --pretty
.claude/skills/lsp/scripts/lsp_explorer.sh index-clear
.claude/skills/lsp/scripts/lsp_explorer.sh lookup MyClass --kind class --file-type source --pretty
.claude/skills/lsp/scripts/lsp_explorer.sh dead --file-type source --exclude-private --pretty
.claude/skills/lsp/scripts/lsp_explorer.sh trace src/main.py 10 5 --depth 3 --pretty
.claude/skills/lsp/scripts/lsp_explorer.sh files --language python --file-type source --pretty
Cache Control Flags
| Flag | Description |
|---|
--cache-rebuild | Wipe and rebuild entire index (default) |
--cache-incremental | Only index files with newer mtime |
--cache-frozen | Skip indexing, use existing cache as-is |
Index Commands
| Command | Purpose | Requires LSP? |
|---|
index | Build symbol index | Yes |
index-status | Show index stats | No |
index-clear | Wipe all index data | No |
lookup NAME | Find definitions by name | No |
dead | Find unreferenced definitions | No |
trace FILE LINE COL | Impact analysis from cache | No |
files | List indexed files | No |
How It Works
The index uses two LSP calls per file (O(N) total):
documentSymbol — hierarchical definitions with scope ranges
semanticTokens/full — all token positions in a single pass
References = tokens that are NOT definitions (a SQL VIEW). Definition scope ranges are stored in an R-Tree for O(log N) containment queries. A materialized edge list enables recursive CTE graph traversal for impact analysis.
Cache Schema
erDiagram
cache_metadata {
TEXT key PK
TEXT value
}
source_files {
INTEGER id PK
TEXT filepath UK "absolute path"
TEXT relative_path "git-relative"
REAL mtime
INTEGER size_bytes
TEXT indexed_at
TEXT language "python typescript javascript"
TEXT lsp_server
TEXT file_type "source or test"
}
symbols {
INTEGER id PK
INTEGER source_file_id FK
TEXT name
TEXT kind "class function variable etc"
INTEGER line "1-indexed"
INTEGER col "1-indexed"
INTEGER end_line
INTEGER end_col
TEXT detail "nullable"
BOOLEAN is_definition "0 = reference 1 = definition"
INTEGER scope_start_line "definitions only"
INTEGER scope_end_line "definitions only"
}
definition_ranges {
INTEGER id PK "matches symbols.id"
INTEGER min_line "scope_start_line"
INTEGER max_line "scope_end_line"
INTEGER min_file_id "source_file_id"
INTEGER max_file_id "source_file_id"
}
symbol_containments {
INTEGER inner_symbol_id FK "contained symbol"
INTEGER outer_symbol_id FK "enclosing definition"
}
source_files ||--o{ symbols : "contains"
symbols ||--o| definition_ranges : "R-Tree scope index"
symbols ||--o{ symbol_containments : "contained in"
SQL Views (no separate tables):
definitions — SELECT * FROM symbols WHERE is_definition = 1
references — SELECT * FROM symbols WHERE is_definition = 0
Global Options
These flags are shared across all subcommands. Place them after the subcommand name.
| Flag | Description |
|---|
-v | Verbose logging (debug output) |
--pretty | Pretty-print JSON (indent=2) |
--root PATH | Override project root directory |
--timeout N | Timeout in seconds (default: 30) |
Supported Languages
| Language | Server | Install |
|---|
| Python | pyright-langserver | pip install pyright |
| TypeScript/TSX | typescript-language-server | npm install -g typescript-language-server typescript |
| JavaScript/JSX | typescript-language-server | npm install -g typescript-language-server typescript |
Architecture
CLI (argparse) <- User/Claude invokes commands
| \
CodeExplorer IndexCacheManager <- High-level: explore/impact | index/dead/trace
| |
LspSession SQLite (R-Tree) <- Protocol: textDocument/* | Cached symbols
|
JsonRpcClient <- Wire: Content-Length framing
|
subprocess (stdin/stdout) <- pyright-langserver or typescript-language-server
Positions are 1-indexed at the CLI (matching editors and grep output), converted to 0-indexed internally for LSP protocol compliance.
Use Cases
- Planning code changes — understand symbols, types, and definitions before modifying code
- Reviewing change impact — find all references to a symbol, trace what a change would affect
- Exploring new codebases — get high-level symbol overviews of files and directories
- Dead code detection — find unreferenced definitions across the entire project (cached)
- Impact analysis — trace how a change propagates through the call graph (cached)
- Symbol lookup — instantly find any definition by name without spinning up LSP servers