Skip to content

Commit 69a23ed

Browse files
authored
Merge pull request #42 from narumiruna/feat/pi-lsp-extension
feat: add shared pi lsp extension
2 parents 0c811ea + dfdad59 commit 69a23ed

20 files changed

Lines changed: 1857 additions & 4 deletions

AGENTS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,10 @@ Run commands from the repository root unless noted otherwise.
4343
- Recent history uses Conventional Commits such as `feat: ...`, `fix: ...`, and `chore(release): ...`; keep commit messages grounded in the actual diff.
4444
- Stage only intended paths. Do not use blanket staging for unrelated local changes.
4545
- For PRs or handoff notes, include the commands run and any publish/visibility checks performed.
46+
47+
## MEMORY.md
48+
49+
- `MEMORY.md` is not auto-loaded. Check it before non-trivial debugging or design work when prior project context may matter.
50+
- Keep entries short and reusable.
51+
- `MEMORY.md` must use `## GOTCHA` and `## TASTE` sections.
52+
- After a non-trivial error or discovery, add one concise entry if it will help future work.

MEMORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
- Codex usage can be queried without Codex CLI by sending Pi's `openai-codex` bearer token to `https://chatgpt.com/backend-api/wham/usage`; response uses Codex `RateLimitStatusPayload` snake_case fields.
1515
- `pi-codex-usage` statusline must select a rate-limit bucket by current model id/name; `gpt-5.3-codex-spark` can use its own returned bucket instead of primary `codex`.
1616
- `node-domexception` deprecation comes via `@google/genai -> google-auth-library -> gaxios -> node-fetch -> fetch-blob`; use the root npm override to `npm:@profoundlogic/node-domexception`.
17+
- New filesystem-writing Pi tools need a pre-review edge-case pass: workspace containment, absolute/`..` paths, symlink loops/escapes, duplicate paths, cancellation, process errors, protocol errors, and edit ordering.
18+
- When PR comments expose one class of bug, stop patching comment-by-comment and do a holistic pass over adjacent Modules before pushing again.
1719

1820
## TASTE
1921

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![npm scope](https://img.shields.io/badge/npm-@narumitw-blue)](https://www.npmjs.com/org/narumitw) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
44

5-
Production-ready, independently installable [Pi](https://pi.dev) extension packages for the Pi coding agent. This monorepo provides native Pi tools and commands for Biome LSP diagnostics, Chrome DevTools automation, Codex usage status, Firecrawl web scraping, Python LSP diagnostics with ty and Ruff, goal-driven task completion, retry handling, terminal statuslines, and keep-awake automation.
5+
Production-ready, independently installable [Pi](https://pi.dev) extension packages for the Pi coding agent. This monorepo provides native Pi tools and commands for shared LSP diagnostics and edits, Biome LSP diagnostics, Chrome DevTools automation, Codex usage status, Firecrawl web scraping, Python LSP diagnostics with ty and Ruff, goal-driven task completion, retry handling, terminal statuslines, and keep-awake automation.
66

77
## 📦 Pi extension packages
88

@@ -17,6 +17,7 @@ Install only the Pi extensions you need. Each package is published under the `@n
1717
| [`@narumitw/pi-codex-usage`](./extensions/pi-codex-usage) | 📊 `/codex-status` command and automatic statusline item for ChatGPT Codex subscription usage, using Pi auth first and Codex CLI only as fallback. | `pi install npm:@narumitw/pi-codex-usage` |
1818
| [`@narumitw/pi-firecrawl`](./extensions/pi-firecrawl) | 🔥 Firecrawl-powered web scraping, crawling, URL discovery, and web search tools for research workflows. | `pi install npm:@narumitw/pi-firecrawl` |
1919
| [`@narumitw/pi-goal`](./extensions/pi-goal) | 🎯 `/goal` mode that keeps the agent working until a verifiable task is complete. | `pi install npm:@narumitw/pi-goal` |
20+
| [`@narumitw/pi-lsp`](./extensions/pi-lsp) | 🧠 Shared language-server tools for Biome diagnostics/edits, ty diagnostics, and Ruff diagnostics/edits. | `pi install npm:@narumitw/pi-lsp` |
2021
| [`@narumitw/pi-python-lsp`](./extensions/pi-python-lsp) | 🐍 Python language-server tools for ty type diagnostics and Ruff linting, formatting, and fixes. | `pi install npm:@narumitw/pi-python-lsp` |
2122
| [`@narumitw/pi-retry`](./extensions/pi-retry) | 🔁 Retry support for provider responses that fail with `Unknown error (no error details in response)`. | `pi install npm:@narumitw/pi-retry` |
2223
| [`@narumitw/pi-statusline`](./extensions/pi-statusline) | ✨ A rich Pi terminal statusline with model, tools, git branch, context usage, token totals, cost, and time. | `pi install npm:@narumitw/pi-statusline` |
@@ -39,11 +40,15 @@ pi -e npm:@narumitw/pi-statusline
3940
Use multiple Pi extensions together:
4041

4142
```bash
42-
pi -e npm:@narumitw/pi-goal -e npm:@narumitw/pi-statusline -e npm:@narumitw/pi-python-lsp -e npm:@narumitw/pi-biome-lsp
43+
pi -e npm:@narumitw/pi-goal -e npm:@narumitw/pi-statusline -e npm:@narumitw/pi-lsp
4344
```
4445

4546
## 🛠️ Extension use cases
4647

48+
### 🧠 Shared language-server workflows
49+
50+
Use [`@narumitw/pi-lsp`](./extensions/pi-lsp) to let Pi run Biome, ty, and Ruff language-server tools through one shared LSP runner. It covers Biome diagnostics and edits, ty type diagnostics, and Ruff lint diagnostics, formatting, import organization, and source fixes. The older [`@narumitw/pi-biome-lsp`](./extensions/pi-biome-lsp) and [`@narumitw/pi-python-lsp`](./extensions/pi-python-lsp) packages remain available and are not deprecated yet.
51+
4752
### 🧬 JavaScript and TypeScript coding with Biome
4853

4954
Use [`@narumitw/pi-biome-lsp`](./extensions/pi-biome-lsp) to let Pi run Biome diagnostics through `biome lsp-proxy`, format supported files, organize imports, and apply safe Biome source fixes.
@@ -100,6 +105,7 @@ pi -e ./extensions/pi-chrome-devtools
100105
pi -e ./extensions/pi-codex-usage
101106
pi -e ./extensions/pi-firecrawl
102107
pi -e ./extensions/pi-goal
108+
pi -e ./extensions/pi-lsp
103109
pi -e ./extensions/pi-python-lsp
104110
pi -e ./extensions/pi-retry
105111
pi -e ./extensions/pi-statusline
@@ -116,6 +122,7 @@ npm run pack:chrome-devtools
116122
npm run pack:codex-usage
117123
npm run pack:firecrawl
118124
npm run pack:goal
125+
npm run pack:lsp
119126
npm run pack:python-lsp
120127
npm run pack:retry
121128
npm run pack:statusline
@@ -142,6 +149,7 @@ extensions/
142149
├── pi-codex-usage/
143150
├── pi-firecrawl/
144151
├── pi-goal/
152+
├── pi-lsp/
145153
├── pi-python-lsp/
146154
├── pi-retry/
147155
├── pi-statusline/
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# pi-lsp parity checklist
2+
3+
`@narumitw/pi-lsp` keeps the existing public tool Interface from `@narumitw/pi-biome-lsp` and `@narumitw/pi-python-lsp` while moving common LSP behavior into a shared runner Module.
4+
5+
## Tool names and parameters
6+
7+
- [x] `biome_lsp_diagnostics`: `paths?`, `root?`, `limit?`.
8+
- [x] `biome_lsp_format`: `path`, `root?`, `write?`.
9+
- [x] `biome_lsp_fix`: `path`, `root?`, `kind?`, `write?`; default kind `source.fixAll.biome`.
10+
- [x] `ty_lsp_diagnostics`: `paths?`, `root?`, `limit?`.
11+
- [x] `ruff_lsp_diagnostics`: `paths?`, `root?`, `limit?`.
12+
- [x] `ruff_lsp_format`: `path`, `root?`, `write?`.
13+
- [x] `ruff_lsp_fix`: `path`, `root?`, `kind?`, `write?`; default kind `source.fixAll.ruff`.
14+
15+
## Server commands and environment variables
16+
17+
- [x] Biome defaults to `biome lsp-proxy`, supports `PI_BIOME_LSP_COMMAND`, and uses `PI_BIOME_LSP_TIMEOUT_MS`.
18+
- [x] ty defaults to `ty server`, supports `PI_TY_LSP_COMMAND`, and uses `PI_TY_LSP_TIMEOUT_MS`.
19+
- [x] Ruff defaults to `ruff server`, supports `PI_RUFF_LSP_COMMAND`, and uses `PI_RUFF_LSP_TIMEOUT_MS`.
20+
- [x] Command splitting preserves the old quoted-command support but intentionally preserves normal backslashes so Windows command paths such as `C:\\Tools\\ruff.exe` remain valid.
21+
- [x] Command probing validates runnable files, rejects directories/non-executable POSIX files, and resolves relative command paths against the LSP workspace root used as the server `cwd`.
22+
23+
## File discovery
24+
25+
- [x] Biome file extensions match `pi-biome-lsp`: `.astro`, `.css`, `.cts`, `.cjs`, `.graphql`, `.gql`, `.html`, `.js`, `.json`, `.jsonc`, `.jsx`, `.mjs`, `.mts`, `.svelte`, `.ts`, `.tsx`, `.vue`.
26+
- [x] Biome skips `.git`, `.hg`, `.next`, `.nuxt`, `.output`, `.svelte-kit`, `coverage`, `dist`, `node_modules`, and `out`.
27+
- [x] Python files match `pi-python-lsp`: `.py` and `.pyi`.
28+
- [x] Python skips `.git`, `.hg`, `.mypy_cache`, `.ruff_cache`, `.tox`, `.venv`, `__pycache__`, `node_modules`, and `venv`.
29+
30+
## LSP behavior
31+
32+
- [x] Shared runner owns JSON-RPC framing, subprocess lifecycle, initialize/shutdown, file open/close, diagnostics, formatting, code actions, action resolution, and workspace edit application.
33+
- [x] Biome Adapter keeps dynamic registration capabilities, publish-diagnostics fallback, workspace-folder request handling, tab size 2, and tabs.
34+
- [x] ty Adapter keeps diagnostic requests without code actions, tab size 4, and spaces.
35+
- [x] Ruff Adapter keeps diagnostic requests, code actions, tab size 4, and spaces.
36+
37+
## Result shapes and messages
38+
39+
- [x] Tool results still return `{ content: [{ type: "text", text }], details }`.
40+
- [x] Diagnostics details include `root`, `command`, `files`, and `summary`.
41+
- [x] Format/fix details include `path`, `uri`, `changed`, `write`, `edits`, and preview `text` when `write` is false.
42+
- [x] Fix details include `kind` and resolved `actions`.
43+
- [x] Missing-command errors preserve server-specific install guidance.
44+
45+
## Documentation and compatibility
46+
47+
- [x] `extensions/pi-lsp/README.md` documents tool-name compatibility, environment variables, and no-deprecation status for the old packages.
48+
- [x] Root `README.md`, `package.json`, and `justfile` include `pi-lsp` integration.
49+
- [x] `pi-biome-lsp` and `pi-python-lsp` package metadata and READMEs are unchanged in this phase.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
## Goal
2+
3+
Create a new `@narumitw/pi-lsp` Pi extension that provides one deep LSP runner Module for diagnostics, formatting, source fixes, and import organization across multiple language-server Adapters. The initial success condition is that the new package covers the current `pi-biome-lsp` and `pi-python-lsp` behavior without deprecating those packages yet.
4+
5+
## Context
6+
7+
`extensions/pi-biome-lsp/src/biome-lsp.ts` and `extensions/pi-python-lsp/src/python-lsp.ts` duplicate most of their LSP JSON-RPC, subprocess lifecycle, file collection, workspace edit, and result formatting Implementation. The intended deepening is to move that behavior behind a smaller `pi-lsp` Interface, while keeping Biome, ty, and Ruff as concrete Adapters.
8+
9+
## Architecture
10+
11+
- The external Pi tool Interface remains familiar to existing users: diagnostics, format, and fix tools for Biome, ty, and Ruff.
12+
- The new package contains an internal LSP runner Module with one Seam for server-specific Adapters.
13+
- Each Adapter describes server command resolution, supported file discovery, language id, initialization options/capabilities, formatting options, code-action kind defaults, and missing-command guidance.
14+
- `pi-biome-lsp` and `pi-python-lsp` remain unchanged until a later deprecation decision.
15+
16+
## Non-Goals
17+
18+
- Do not deprecate or remove `@narumitw/pi-biome-lsp` or `@narumitw/pi-python-lsp` in this phase.
19+
- Do not publish the new npm package in this phase unless explicitly requested after local verification.
20+
- Do not add a separate shared workspace package unless the new `pi-lsp` package proves that reuse outside the package is needed.
21+
22+
## Assumptions
23+
24+
- The new package can initially copy behavior from the existing LSP extensions, then consolidate it behind deeper internal Modules.
25+
- Tool names may stay compatible with the existing names at first, even if users should avoid installing old and new LSP packages together because duplicate tool names can conflict.
26+
- The package should follow current monorepo conventions: `extensions/pi-lsp`, package-local `README.md`, `LICENSE`, `tsconfig.json`, `src/*.ts`, root scripts, and just recipes.
27+
28+
## Unknowns
29+
30+
- Resolved: duplicate tool names are documented as an installation caveat in `extensions/pi-lsp/README.md`; side-by-side installs are not recommended until a later Pi-version-specific decision.
31+
- Resolved: generic configurable LSP tools are deferred; this phase ships built-in Biome, ty, and Ruff Adapters only.
32+
33+
## Plan
34+
35+
- [x] Inventory current LSP behavior in `extensions/pi-biome-lsp/src/biome-lsp.ts`, `extensions/pi-python-lsp/src/python-lsp.ts`, and their READMEs to produce a parity checklist of tool names, parameters, environment variables, command defaults, supported file extensions, result details, and error messages; verified by `docs/implementation-notes/pi-lsp-parity-checklist.md`.
36+
- [x] Create `extensions/pi-lsp/` with `package.json`, `README.md`, `LICENSE`, `tsconfig.json`, and `src/` following existing package conventions; verified with `npm --workspace @narumitw/pi-lsp run typecheck`.
37+
- [x] Add root workspace integration for the new package in `package.json`, `justfile`, and root `README.md` without changing old LSP packages; verified with `just --list | rg '(^|-)lsp|pack-lsp|try-lsp|install-lsp|publish-lsp'` and `just pack lsp`.
38+
- [x] Implement an internal LSP runner Module in `extensions/pi-lsp/src/` that owns JSON-RPC framing, process lifecycle, initialize/shutdown, file open/close, diagnostics collection, formatting requests, code-action requests, and workspace edit application; verified with `npm --workspace @narumitw/pi-lsp run typecheck`, `npm run biome:check`, and the parity checklist.
39+
- [x] Implement Biome, ty, and Ruff Adapters for the runner Module, each with command resolution, file support, language id, capabilities/options, and missing-command guidance matching existing packages; verified by `docs/implementation-notes/pi-lsp-parity-checklist.md`.
40+
- [x] Register Pi tools in `extensions/pi-lsp/src/pi-lsp.ts` for existing Biome, ty, and Ruff diagnostics/format/fix workflows; verified with `npm --workspace @narumitw/pi-lsp run typecheck` and `npm run biome:check`.
41+
- [x] Add package documentation that explains what `@narumitw/pi-lsp` replaces, the current no-deprecation status of old packages, tool-name conflict guidance, environment variables, and local try instructions; verified by `extensions/pi-lsp/README.md` and root `README.md`.
42+
- [x] Run local package verification with `npm run check` and `just pack lsp`; verified both commands passed and the dry-run tarball listed only `LICENSE`, `README.md`, `package.json`, and `src/*.ts`.
43+
- [x] Try the extension locally with `pi -e ./extensions/pi-lsp` on at least one TypeScript/JSON file and one Python file, using available Biome/Ruff/ty commands when installed; verified by `pi -e ./extensions/pi-lsp --version`, compiled local harness execution of `biome_lsp_diagnostics`, `biome_lsp_format`, `biome_lsp_fix`, `ty_lsp_diagnostics`, `ruff_lsp_diagnostics`, `ruff_lsp_format`, and `ruff_lsp_fix` against `/tmp/pi-lsp-runtime` sample JSON/Python files.
44+
- [x] Decide whether old packages should enter a later deprecation plan only after `@narumitw/pi-lsp` passes local verification; verified by leaving `pi-biome-lsp` and `pi-python-lsp` package metadata and READMEs unchanged in this phase.
45+
46+
## Risks
47+
48+
- Mitigated: duplicate tool names may confuse users if `pi-lsp` is installed with the old packages; documented in `extensions/pi-lsp/README.md` and old packages were not deprecated.
49+
- Mitigated: consolidation can accidentally change result shapes or error wording; `docs/implementation-notes/pi-lsp-parity-checklist.md` records parity checks.
50+
- Mitigated: LSP server behavior differs subtly between Biome, ty, and Ruff; server-specific behavior is kept in `extensions/pi-lsp/src/adapters.ts`.
51+
52+
## Rollback / Recovery
53+
54+
- If the new package fails later verification, remove `extensions/pi-lsp/` and root references in one rollback commit; old LSP packages remain available because this phase does not modify or deprecate them.
55+
- If a specific Adapter is unstable after wider use, keep the package unpublished and document the failing Adapter while preserving the runner Module work for follow-up.
56+
57+
## Completion Checklist
58+
59+
- [x] `@narumitw/pi-lsp` package exists with package metadata, README, LICENSE, tsconfig, and source files verified by repository paths under `extensions/pi-lsp/`.
60+
- [x] Biome, ty, and Ruff tool parity is verified by `docs/implementation-notes/pi-lsp-parity-checklist.md` against the old LSP packages.
61+
- [x] Repository integration is verified by root scripts/just recipes and root README entries for the new package, plus `just --list | rg '(^|-)lsp|pack-lsp|try-lsp|install-lsp|publish-lsp'`.
62+
- [x] Static verification is complete with passing `npm run check`.
63+
- [x] Package contents are verified with passing `just pack lsp` dry-run output listing 11 expected files.
64+
- [x] Runtime behavior is verified with `pi -e ./extensions/pi-lsp --version` and recorded diagnostics/format/fix harness results for Biome JSON and Python ty/Ruff workflows.
65+
- [x] `pi-biome-lsp` and `pi-python-lsp` are not deprecated, removed, or behavior-changed in this phase, verified by no diffs under `extensions/pi-biome-lsp/` or `extensions/pi-python-lsp/`.

extensions/pi-lsp/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 narumiruna
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)