Standalone pi extension that adds a code_symbols tool backed by project-configured Language Server Protocol processes.
Current implementation:
- Spawns and manages one LSP subprocess per
(server id, workspace root)pair - Supports multiple configured servers in the same workspace
- Routes requests by
serverId,language, andfilePath - Cleans up all spawned processes on pi shutdown and extension reload
- Exposes
search,definitions, andreferencesthrough thecode_symbolstool - Returns optional source snippets using the LSP-reported range
Not implemented yet:
- Tree-sitter-based expansion from a symbol range to the enclosing syntax node
- Automatic installation or discovery of language servers
- Rich disambiguation UI when multiple document symbols match the same pattern
cd /path/to/pi-lsp
bun installLoad it in pi:
pi --extension /path/to/pi-lsp/src/index.tsOr point pi at the package directory if you use it as a project extension source.
Create .pi/lsp.json in the target workspace:
{
"defaultLimit": 25,
"maxLimit": 100,
"servers": [
{
"id": "ts",
"name": "TypeScript",
"languages": ["typescript", "javascript"],
"fileGlobs": ["src/*.ts", "src/*.tsx", "test/*.ts"],
"rootMarkers": ["package.json", "tsconfig.json"],
"command": {
"command": "vtsls",
"args": ["--stdio"]
}
},
{
"id": "py",
"name": "ty",
"languages": ["python"],
"fileGlobs": ["pkg/*.py", "tests/*.py"],
"rootMarkers": ["pyproject.toml", "setup.py"],
"command": {
"command": "ty",
"args": ["--stdio"]
}
},
{
"id": "rust",
"name": "rust-analyzer",
"languages": ["rust"],
"fileGlobs": ["src/*.rs", "tests/*.rs", "examples/*.rs"],
"rootMarkers": ["Cargo.toml"],
"command": {
"command": "rust-analyzer"
}
}
]
}servers: required, non-empty arrayid: stable server identifierlanguages: optional language filter used during routingfileGlobs: optional minimatch globs evaluated relative to the workspace cwdrootMarkers: optional files/directories used to compute the server rootcommand.command: executable to spawncommand.args: optional argument arraycommand.env: optional environment variablesinitializationOptions: optional LSP initialization payloadtrace: optional LSP trace leveltreeSitterLanguage: reserved for upcoming tree-sitter source expansion
The extension registers one tool:
code_symbols
Parameters:
action:"search" | "definitions" | "references"name: symbol name or wildcard patternfilePath: optional forsearch, required fordefinitionsandreferenceslanguage: optional language overrideserverId: optional explicit server overrideincludeSource: include source snippets in resultslimit: result cap
Examples:
Use code_symbols to search for "run*"
Use code_symbols to find definitions of "runTask" in src/app.ts
Use code_symbols to find references of "make_widget" in pkg/tool.py
bun run check
bun testThe tests use a fake stdio LSP server and verify:
- server routing across multiple configured servers
- workspace symbol search
- document symbol + definition flow
- references flow
- shutdown cleanup