diff options
| author | Adam Malczewski <[email protected]> | 2026-06-24 19:24:05 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-24 19:24:05 +0900 |
| commit | d4ff45c8a5c8aa37e824e63037874c46de877309 (patch) | |
| tree | 24f3628da58febbe1520c582d260e06349f47ced | |
| parent | e03a96e539d354345cd6328ddc5c7638398d3e14 (diff) | |
| download | dispatch-d4ff45c8a5c8aa37e824e63037874c46de877309.tar.gz dispatch-d4ff45c8a5c8aa37e824e63037874c46de877309.zip | |
fix(tool-edit-file): lazy LSP service lookup — diagnostics now actually work
The previous fix (e03a96e) wrapped getService in try/catch to prevent the
activation crash, but that wasn't enough: tool-edit-file activates at position
5 in CORE_EXTENSIONS while lsp activates at position 20. So getService ALWAYS
threw at activation time, lspService was ALWAYS undefined, and the diagnostics
hook was NEVER wired — edits succeeded but never showed LSP feedback.
Fix: make the LSP service lookup LAZY — defer it to edit time (when the tool is
actually called), not activation time. By then all extensions have activated.
The diagnostics function tries getService on each edit call; if LSP isn't
loaded, it returns a no-op (graceful degradation).
| -rw-r--r-- | packages/tool-edit-file/src/extension.ts | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/packages/tool-edit-file/src/extension.ts b/packages/tool-edit-file/src/extension.ts index 9be53da..3929634 100644 --- a/packages/tool-edit-file/src/extension.ts +++ b/packages/tool-edit-file/src/extension.ts @@ -14,26 +14,29 @@ export const extension: Extension = { contributes: { tools: ["edit_file"] }, }, activate(host) { - // Optional LSP integration: if the lsp extension is loaded AND has - // activated before us, wire its getDiagnostics service as the post-edit - // diagnostics hook. If absent (not loaded, or activates after us), edits - // proceed without diagnostics (graceful degradation). - let lspService: LspService | undefined; - try { - lspService = host.getService(lspServiceHandle); - } catch { - lspService = undefined; - } - const diagnostics: DiagnosticsHook | undefined = lspService - ? async (opts) => - lspService.getDiagnostics({ - filePath: opts.filePath, - text: opts.text, - cwd: opts.cwd, - timeoutMs: 60_000, - minSeverity: 2, // errors + warnings only - }) - : undefined; + // Lazy LSP lookup: the LSP extension activates AFTER us in the + // CORE_EXTENSIONS array, so host.getService would throw at activation + // time. Instead, defer the lookup to edit time — by then all extensions + // have activated. If LSP isn't loaded, the try/catch returns a no-op + // (graceful degradation: edits proceed without diagnostics). + const diagnostics: DiagnosticsHook = async (opts) => { + let lspService: LspService | undefined; + try { + lspService = host.getService(lspServiceHandle); + } catch { + return { formatted: "", slow: false, timedOut: false }; + } + if (!lspService) { + return { formatted: "", slow: false, timedOut: false }; + } + return lspService.getDiagnostics({ + filePath: opts.filePath, + text: opts.text, + cwd: opts.cwd, + timeoutMs: 60_000, + minSeverity: 2, // errors + warnings only + }); + }; host.defineTool(createEditFileTool(process.cwd(), diagnostics)); }, |
