Add pi-tool-display (compact tool rendering, adaptive diffs) + pi-lsp-extension (LSP diagnostics/hover/definitions) — vendored from npm 0.5.0 / 1.3.0
This commit is contained in:
192
extensions/pi-lsp-extension/README.md
Normal file
192
extensions/pi-lsp-extension/README.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# pi-lsp-extension
|
||||
|
||||
A [pi](https://github.com/mariozechner/pi-mono) coding agent extension that integrates Language Server Protocol (LSP) servers, giving the LLM access to the same language intelligence that powers your IDE.
|
||||
|
||||
## Tools
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `lsp_diagnostics` | Compilation errors and warnings for a file |
|
||||
| `lsp_hover` | Type information and documentation at a position |
|
||||
| `lsp_definition` | Go to definition of a symbol |
|
||||
| `lsp_references` | Find all references to a symbol |
|
||||
| `lsp_symbols` | List file symbols or search workspace symbols |
|
||||
| `lsp_rename` | Preview rename refactoring (returns planned edits) |
|
||||
| `lsp_completions` | Code completion suggestions at a position |
|
||||
| `code_overview` | Project structure, key files, and symbols (tree-sitter) |
|
||||
| `code_search` | Find code by AST structure with metavariables |
|
||||
| `code_rewrite` | Transform code matching structural patterns |
|
||||
|
||||
LSP servers start lazily — they only spin up when a tool is first used on a file of that language. For slow servers (e.g. jdtls), you can [auto-start them on session launch](#project-config).
|
||||
|
||||
## Auto-diagnostics
|
||||
|
||||
After a successful `write` or `edit`, if an LSP server is already running for that file type, the extension automatically appends compilation errors to the tool result. This gives the LLM immediate feedback without requiring a separate `lsp_diagnostics` call.
|
||||
|
||||
- Scoped to the single changed file (no workspace-wide noise)
|
||||
- Only errors, max 10 lines — keeps context lean
|
||||
- Only fires when a server is already running (no lazy startup)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
git clone https://github.com/samfoy/pi-lsp-extension.git
|
||||
cd pi-lsp-extension
|
||||
npm install
|
||||
```
|
||||
|
||||
Add to your pi `settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"extensions": ["/path/to/pi-lsp-extension/src/index.ts"]
|
||||
}
|
||||
```
|
||||
|
||||
Or run directly:
|
||||
|
||||
```bash
|
||||
pi -e /path/to/pi-lsp-extension/src/index.ts
|
||||
```
|
||||
|
||||
## Supported Languages
|
||||
|
||||
Install the language server you need, then it works automatically:
|
||||
|
||||
| Language | Server | Install |
|
||||
|----------|--------|---------|
|
||||
| TypeScript/JavaScript | `typescript-language-server` | `npm i -g typescript-language-server typescript` |
|
||||
| Python | `pyright-langserver` | `pip install pyright` |
|
||||
| Rust | `rust-analyzer` | [rustup](https://rustup.rs/) |
|
||||
| Go | `gopls` | `go install golang.org/x/tools/gopls@latest` |
|
||||
| Java | `jdtls` | [Eclipse JDT.LS](https://github.com/eclipse-jdtls/eclipse.jdt.ls) |
|
||||
|
||||
Add more at runtime:
|
||||
|
||||
```
|
||||
/lsp-config ruby solargraph stdio
|
||||
/lsp-config lua lua-language-server
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/lsp` | Show status of running LSP servers |
|
||||
| `/lsp-restart <lang>` | Restart an LSP server (kills daemon, re-initializes) |
|
||||
| `/lsp-config <lang> <cmd> [args]` | Configure a language server |
|
||||
| `/lsp-lombok [path]` | Set Lombok jar path for Java (or show current) |
|
||||
| `/bemol [run\|watch\|stop\|status]` | Manage bemol (Brazil workspaces) |
|
||||
|
||||
## How it Works
|
||||
|
||||
1. **Lazy startup** — servers start on first tool use for a file type (or eagerly via [`.pi-lsp.json`](#project-config))
|
||||
2. **Tree-sitter fallback** — when no LSP server is running, tools like `lsp_diagnostics`, `lsp_hover`, `lsp_definition`, and `lsp_symbols` fall back to tree-sitter for syntax errors, signatures, and symbol extraction
|
||||
3. **File sync** — pi's `read`/`write`/`edit` operations are automatically synced to the LSP via `didOpen`/`didChange`, with LRU eviction (`didClose`) after 100 tracked files
|
||||
4. **Diagnostics cache** — the server pushes diagnostics asynchronously; tools read from a local cache
|
||||
5. **Auto-diagnostics** — errors are appended to write/edit results when a server is running
|
||||
6. **Shared daemons** — in supported workspaces, LSP servers run as background daemons shared across pi sessions
|
||||
|
||||
## Lombok Support (Java)
|
||||
|
||||
If your Java project uses [Lombok](https://projectlombok.org/), jdtls needs the Lombok agent jar to understand generated code. The extension resolves the jar in this order:
|
||||
|
||||
1. **`/lsp-lombok` command** — set the path at runtime:
|
||||
```
|
||||
/lsp-lombok /path/to/lombok.jar
|
||||
```
|
||||
|
||||
2. **`LOMBOK_JAR` environment variable** — set before starting pi:
|
||||
```bash
|
||||
export LOMBOK_JAR=/path/to/lombok.jar
|
||||
pi
|
||||
```
|
||||
|
||||
3. **Auto-detection** — in Brazil workspaces, the extension searches `env/Lombok-*/runtime/lib/` and `env/gradle-cache-2/` automatically.
|
||||
|
||||
Run `/lsp-lombok` with no arguments to see which jar is currently configured.
|
||||
|
||||
## Project Config
|
||||
|
||||
Create a `.pi-lsp.json` file in your project root to configure LSP behavior per-project:
|
||||
|
||||
```json
|
||||
{
|
||||
"autoStart": ["java", "typescript"],
|
||||
"lombokJar": "auto",
|
||||
"autoInjectDiagnostics": ["typescript"],
|
||||
"servers": {
|
||||
"python": { "command": "pylsp", "args": [] }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `autoStart` | Array of language IDs to start eagerly on session launch. Servers begin initializing in the background immediately — no need to wait for the first tool call. Ideal for slow servers like `jdtls`. |
|
||||
| `lombokJar` | Path to a Lombok jar (absolute or relative to project root), or `"auto"` to auto-detect in Brazil workspaces. Applied before auto-start so jdtls launches with the correct `-javaagent` flag. |
|
||||
| `autoInjectDiagnostics` | Controls whether LSP errors are auto-appended to `write`/`edit` tool results. `true` (default) enables for all languages, `false` disables entirely, or pass an array of language IDs (e.g. `["typescript"]`) to enable selectively. Disable for Java/Brazil workspaces where Lombok and dependency-chain false positives create noise. |
|
||||
| `servers` | Custom server configs keyed by language ID. Overrides the built-in defaults. Each entry has `command`, optional `args` (string array), and optional `env` (key-value pairs). |
|
||||
|
||||
The config file is loaded once at session start. Changes require restarting the pi session.
|
||||
|
||||
**Example for a Java Brazil workspace:**
|
||||
```json
|
||||
{
|
||||
"autoStart": ["java"],
|
||||
"lombokJar": "auto"
|
||||
}
|
||||
```
|
||||
|
||||
This triggers bemol + jdtls startup as soon as the session begins, so by the time you need `lsp_diagnostics` or `lsp_hover`, the server is already warm.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
src/
|
||||
├── index.ts # Extension entry point, .pi-lsp.json config loader
|
||||
├── lsp-client.ts # JSON-RPC client (stdio + socket modes)
|
||||
├── lsp-manager.ts # Server lifecycle, per-language instances
|
||||
├── file-sync.ts # didOpen/didChange tracking
|
||||
├── lsp-daemon.ts # Background daemon for shared servers
|
||||
├── lsp-daemon-launcher.cjs
|
||||
├── bemol.ts # Brazil workspace support
|
||||
├── locks.ts # File-based locking for daemon coordination
|
||||
├── resolve-provider.ts # LSP vs tree-sitter provider selection
|
||||
├── shared/
|
||||
│ ├── constants.ts # Skip dirs, file size limits
|
||||
│ ├── debug.ts # Debug logger (PI_LSP_DEBUG=1)
|
||||
│ ├── format.ts # Location formatting utilities
|
||||
│ ├── language-map.ts # File extension → language ID mapping
|
||||
│ └── timing.ts # Timing constants
|
||||
├── tree-sitter/
|
||||
│ ├── parser-manager.ts # WASM parser loading and caching
|
||||
│ ├── pattern-compiler.ts # Metavariable pattern → AST matcher
|
||||
│ ├── search-engine.ts # Structural search over files
|
||||
│ ├── rewrite-engine.ts # Structural find-and-replace
|
||||
│ ├── symbol-extractor.ts # Per-language symbol extraction
|
||||
│ └── workspace-index.ts # Project-wide symbol index
|
||||
└── tools/
|
||||
├── diagnostics.ts
|
||||
├── hover.ts
|
||||
├── definition.ts
|
||||
├── references.ts
|
||||
├── symbols.ts
|
||||
├── rename.ts
|
||||
├── completions.ts
|
||||
├── code-overview.ts
|
||||
├── code-search.ts
|
||||
└── code-rewrite.ts
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Position parameters are 1-indexed (line 1, column 1 = first character)
|
||||
- `lsp_rename` returns a preview — the LLM uses `edit`/`write` to apply changes
|
||||
- Use `/lsp-restart java` after changing Lombok config — jdtls needs a full restart to pick up `-javaagent` changes
|
||||
- Set `PI_LSP_DEBUG=1` to enable debug logging for troubleshooting
|
||||
- The extension adds a system prompt guideline nudging the LLM to check diagnostics after edits
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user