LSP servers maintain their own workspace index built at initialize time and rely on the client to push file-system events. Previously the daemon only synced the single file being queried, so externally created/changed files (codegen, build scripts, git checkout, the agent's own writes from the perspective of other open files) left the server's index stale until manual /lsp-destroy. Each ClientEntry now lazily owns a WorkspaceWatcher (chokidar + picomatch) that translates FS events into workspace/didChangeWatchedFiles batches. Patterns come from the server via client/registerCapability (no speculative watching). Ignores layer a tiny baseline (.git, .DS_Store) over the repo's root .gitignore, with a fallback list for non-git workspaces. Events debounce 50ms quiet / 500ms max wait. Notable: gopls registers absolute-path globs (/abs/root/**/*.go) rather than relative ones, so compileWatchers() matches each event against both relative and absolute path forms. Caught by the integration test; unit regression test added. Rollback: PI_LSP_DISABLE_WATCHERS=1 disables all watcher creation. - src/client.ts: honor register/unregisterCapability for workspace/didChangeWatchedFiles; advertise dynamicRegistration; expose getFileWatchers/onWatchersChanged/sendNotification - src/watcher.ts: new WorkspaceWatcher with layered ignores, debounce+batch, Created+Deleted coalescing, dual-form glob matching - src/daemon.ts: per-entry watcher lifecycle, PI_LSP_DISABLE_WATCHERS, LSP_DEBUG-gated pattern/event logging - test/unit/watcher.test.ts: 11 tests against real chokidar + temp dir - test/integration/watcher-gopls.test.ts: end-to-end against gopls - AGENTS.md: new "Workspace File Watching" section - flake.nix: add go (required by gopls integration test)
40 lines
1.1 KiB
JSON
40 lines
1.1 KiB
JSON
{
|
|
"name": "@evan/pi-lsp",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"description": "LSP tools for pi: hover, definition, references, completions, symbols, diagnostics.",
|
|
"pi": {
|
|
"extensions": [
|
|
"./index.ts"
|
|
]
|
|
},
|
|
"type": "module",
|
|
"bin": {
|
|
"pi-lsp": "./cli.ts"
|
|
},
|
|
"scripts": {
|
|
"lsp": "tsx ./cli.ts",
|
|
"typecheck": "tsc --noEmit",
|
|
"lint": "oxlint . --ignore-pattern=.direnv/**",
|
|
"test": "NODE_OPTIONS='--import=tsx' node --test test/unit/**/*.ts test/integration/**/*.ts",
|
|
"test:unit": "NODE_OPTIONS='--import=tsx' node --test test/unit/**/*.ts",
|
|
"test:integration": "NODE_OPTIONS='--import=tsx' node --test test/integration/**/*.ts"
|
|
},
|
|
"dependencies": {
|
|
"chokidar": "^5.0.0",
|
|
"ignore": "^7.0.5",
|
|
"picomatch": "^4.0.4",
|
|
"vscode-jsonrpc": "^8.2.1",
|
|
"vscode-languageserver-protocol": "^3.17.5"
|
|
},
|
|
"devDependencies": {
|
|
"@mariozechner/pi-coding-agent": "^0.72.0",
|
|
"@types/node": "^22.10.0",
|
|
"@types/picomatch": "^4.0.3",
|
|
"oxlint": "^1.62.0",
|
|
"tsx": "^4.19.2",
|
|
"typebox": "^1.1.37",
|
|
"typescript": "^6.0.3"
|
|
}
|
|
}
|