From 4173ee0e0bb90609b796feb873f001caa2ad35eb Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Sat, 17 Jan 2026 22:47:26 -0600 Subject: [PATCH] add lsp diagnostics to apply patch --- packages/opencode/src/tool/apply_patch.ts | 35 +++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/tool/apply_patch.ts b/packages/opencode/src/tool/apply_patch.ts index 4809c5be0e..d070eaefa9 100644 --- a/packages/opencode/src/tool/apply_patch.ts +++ b/packages/opencode/src/tool/apply_patch.ts @@ -10,6 +10,8 @@ import { Patch } from "../patch" import { createTwoFilesPatch, diffLines } from "diff" import { assertExternalDirectory } from "./external-directory" import { trimDiff } from "./edit" +import { LSP } from "../lsp" +import { Filesystem } from "../util/filesystem" const PatchParams = z.object({ patchText: z.string().describe("The full patch text that describes all changes to be made"), @@ -212,6 +214,14 @@ export const ApplyPatchTool = Tool.define("apply_patch", { await Bus.publish(FileWatcher.Event.Updated, { file: filePath, event: "change" }) } + // Notify LSP of file changes and collect diagnostics + for (const change of fileChanges) { + if (change.type === "delete") continue + const target = change.movePath ?? change.filePath + await LSP.touchFile(target, true) + } + const diagnostics = await LSP.diagnostics() + // Generate output summary const summaryLines = fileChanges.map((change) => { if (change.type === "add") { @@ -223,7 +233,23 @@ export const ApplyPatchTool = Tool.define("apply_patch", { const target = change.movePath ?? change.filePath return `M ${path.relative(Instance.worktree, target)}` }) - const summary = `Success. Updated the following files:\n${summaryLines.join("\n")}` + let output = `Success. Updated the following files:\n${summaryLines.join("\n")}` + + // Report LSP errors for changed files + const MAX_DIAGNOSTICS_PER_FILE = 20 + for (const change of fileChanges) { + if (change.type === "delete") continue + const target = change.movePath ?? change.filePath + const normalized = Filesystem.normalizePath(target) + const issues = diagnostics[normalized] ?? [] + const errors = issues.filter((item) => item.severity === 1) + if (errors.length > 0) { + const limited = errors.slice(0, MAX_DIAGNOSTICS_PER_FILE) + const suffix = + errors.length > MAX_DIAGNOSTICS_PER_FILE ? `\n... and ${errors.length - MAX_DIAGNOSTICS_PER_FILE} more` : "" + output += `\n\nLSP errors detected in ${path.relative(Instance.worktree, target)}, please fix:\n\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n` + } + } // Build per-file metadata for UI rendering const files = fileChanges.map((change) => ({ @@ -231,18 +257,21 @@ export const ApplyPatchTool = Tool.define("apply_patch", { relativePath: path.relative(Instance.worktree, change.movePath ?? change.filePath), type: change.type, diff: change.diff, + before: change.oldContent, + after: change.newContent, additions: change.additions, deletions: change.deletions, movePath: change.movePath, })) return { - title: summary, + title: output, metadata: { diff: totalDiff, files, + diagnostics, }, - output: summary, + output, } }, })