|
|
@@ -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<diagnostics file="${target}">\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n</diagnostics>`
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// 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,
|
|
|
}
|
|
|
},
|
|
|
})
|