@signalridge/pi-lsp
Pi extension that exposes configurable, language-agnostic LSP tools through a shared runner.
Package details
Install @signalridge/pi-lsp from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@signalridge/pi-lsp- Package
@signalridge/pi-lsp- Version
1.3.2- Published
- Nov 7, 2026
- Downloads
- 1,323/mo · 451/wk
- Author
- signalridge
- License
- MIT
- Types
- extension
- Size
- 181.1 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-lsp — configurable language server tools for Pi
@signalridge/pi-lsp is a native Pi coding agent extension that exposes diagnostics, source fixes, code navigation, and semantic rename through configurable Language Server Protocol routes.
The extension is language-agnostic: servers are selected by config and file extension instead of hard-coded language families.
Install
pi install npm:@signalridge/pi-lsp
Try without installing permanently:
pi -e npm:@signalridge/pi-lsp
Try this package locally from the repository root:
pi -e ./packages/pi-lsp
Quick start
- Install the server commands you need on PATH; pi-lsp never downloads them.
- Run
/lspto see configured commands and availability. - Navigate with definition/references/hover/symbols; request diagnostics when useful. Preview fixes/renames, then opt into writing only after review.
- Run the repository's authoritative formatter/lint/typecheck/build/tests before completion. LSP speed/success benefits have not been benchmarked.
Every call cold-starts and stops its servers. Project-aware indexing may return incomplete references/symbols just after startup. No editor-like incremental pool or automatic diagnostics injection is provided.
Writes bypass edit/write tool gates. lsp_fix(write: true) and lsp_rename(apply: true) mutate files themselves. Freshness/containment checks are not filesystem locks; multi-file rename can partially write and has no rollback. Reread changed files. Mutation and cleanup contract.
Configuration
No config uses the built-in server catalog. Custom JSON replaces that map, including operation splits. Trusted project <workspace>/.pi/pi-lsp.json wins over user ~/.pi/agent/pi-lsp.json, then built-ins. A tool's root selects files/cwd, not settings authority. Example:
{
"timeout": 30000,
"servers": {
"ruff": { "command": ["uv", "run", "--no-sync", "ruff", "server"], "extensions": [".py", ".pyi"] }
}
}
Global timeout defaults to 20000 ms. Commands are argv arrays; child environment is inherited then servers[].env overrides it (including PATH resolution). Canonical/legacy migration, all timing options, install examples and capability routing: configuration reference.
Pi tools
| Tool | Action / main inputs |
|---|---|
lsp_diagnostics |
paths?, root?, limit?, server?; all matching servers by default |
lsp_fix |
path, root?, kind? (source.fixAll), write? (false), server? |
lsp_definition, lsp_references, lsp_hover |
path, line, symbol or column, root?, server? |
lsp_symbols |
path, root?, server?, query? for workspace search |
lsp_rename |
position plus newName, apply? (false, preview) |
Lines/columns are 1-based; columns use UTF-16. Symbol matching is exact at identifier boundaries; value#2 selects its second occurrence. Navigation/rename requires advertised server capability. Rename accepts text edits only, no file operations; targets beyond the 10,000-path baseline fail even in preview. Output caps at 2,000 lines/50 KiB; overflow goes to a unique private temporary file. lsp_format is retired; use project formatters, not source actions as a formatting substitute. All parameters, output and containment rules.
Cancellation is cooperative; synchronous writes cannot be interrupted or rolled back. Unconfirmed process close retains a runner lease and blocks equivalent calls until confirmed, not arbitrary server descendants. Cancellation/shutdown.
Provenance
The equivalent-file-URI diagnostic keys selectively adapt narumiruna/pi-extensions c23e6047759f6eb628eccf7395cac97a1fa4d47e. The whole-invocation session cancellation selectively adapts 756e1e2939eaf149fb4568a505117c3a8fbdf707. These are bounded adaptations, not wholesale replacements: file keys normalize drive letters independently of the host OS while preserving escaped filename characters and non-file URI identity; lifecycle handling retains this package's client leases, bounded close confirmation, mutation queue/freshness checks, concurrent status ownership, and output limits.
From the same upstream, literal code-action support adapts
246a2cb9dd63362506cc92b38c72b5dca0b10c84
and cda5d36e0ea70abd7c5be3194d123326867a196f,
keeping the first commit's full LSP 3.17 kind set rather than the second's three source kinds. Windows
launcher preference and cmd.exe quoting adapt
90bafa069a387306ebdddfb43ee8254a2c1ddf1e
without a new dependency; unlike upstream, a dotted name whose suffix is not .exe, .cmd, or .bat
still gets Windows suffixes.
The navigation and rename tools adapt ideas from the MIT-licensed LSP integration of
can1357/oh-my-pi (packages/coding-agent/src/lsp, commit
1f23be9b8986237afb78aa15e91bbb57d98ce784): addressing a position by line plus an identifier with an
optional #N occurrence, refusing an implicit column, showing the source line of each location, and
the typescript-language-server --stdio default. The local version is an independent implementation
on this package's per-call runner: it routes by advertised capabilities, previews renames unless
apply: true (oh-my-pi applies by default), rejects resource operations instead of applying them,
matches identifiers exactly without a case-insensitive fallback, and keeps servers per call rather
than in a persistent pool.
License
MIT. See LICENSE.
Reference
Source entrypoint: src/index.ts. Detailed contracts and legacy section links: