diff --git a/packages/opencode/src/lsp/index.ts b/packages/opencode/src/lsp/index.ts index 33fd209cc..793a4475d 100644 --- a/packages/opencode/src/lsp/index.ts +++ b/packages/opencode/src/lsp/index.ts @@ -540,6 +540,8 @@ export namespace LSP { export const outgoingCalls = async (input: LocInput) => runPromise((svc) => svc.outgoingCalls(input)) export namespace Diagnostic { + const MAX_PER_FILE = 20 + export function pretty(diagnostic: LSPClient.Diagnostic) { const severityMap = { 1: "ERROR", @@ -554,5 +556,14 @@ export namespace LSP { return `${severity} [${line}:${col}] ${diagnostic.message}` } + + export function report(file: string, issues: LSPClient.Diagnostic[]) { + const errors = issues.filter((item) => item.severity === 1) + if (errors.length === 0) return "" + const limited = errors.slice(0, MAX_PER_FILE) + const more = errors.length - MAX_PER_FILE + const suffix = more > 0 ? `\n... and ${more} more` : "" + return `\n${limited.map(pretty).join("\n")}${suffix}\n` + } } } diff --git a/packages/opencode/src/tool/apply_patch.ts b/packages/opencode/src/tool/apply_patch.ts index 4b523aeaf..91adc5b92 100644 --- a/packages/opencode/src/tool/apply_patch.ts +++ b/packages/opencode/src/tool/apply_patch.ts @@ -258,20 +258,13 @@ export const ApplyPatchTool = Tool.defineEffect( }) 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 = AppFileSystem.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).replaceAll("\\", "/")}, please fix:\n\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n` - } + const block = LSP.Diagnostic.report(target, diagnostics[AppFileSystem.normalizePath(target)] ?? []) + if (!block) continue + const rel = path.relative(Instance.worktree, target).replaceAll("\\", "/") + output += `\n\nLSP errors detected in ${rel}, please fix:\n${block}` } return { diff --git a/packages/opencode/src/tool/edit.ts b/packages/opencode/src/tool/edit.ts index e0b54bc11..7988ff943 100644 --- a/packages/opencode/src/tool/edit.ts +++ b/packages/opencode/src/tool/edit.ts @@ -20,8 +20,6 @@ import { Instance } from "../project/instance" import { Snapshot } from "@/snapshot" import { assertExternalDirectoryEffect } from "./external-directory" -const MAX_DIAGNOSTICS_PER_FILE = 20 - function normalizeLineEndings(text: string): string { return text.replaceAll("\r\n", "\n") } @@ -166,16 +164,8 @@ export const EditTool = Tool.defineEffect( yield* lsp.touchFile(filePath, true) const diagnostics = yield* lsp.diagnostics() const normalizedFilePath = Filesystem.normalizePath(filePath) - const issues = diagnostics[normalizedFilePath] ?? [] - 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 this file, please fix:\n\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n` - } + const block = LSP.Diagnostic.report(filePath, diagnostics[normalizedFilePath] ?? []) + if (block) output += `\n\nLSP errors detected in this file, please fix:\n${block}` return { metadata: { diff --git a/packages/opencode/src/tool/write.ts b/packages/opencode/src/tool/write.ts index 23a975abc..52e36ffd9 100644 --- a/packages/opencode/src/tool/write.ts +++ b/packages/opencode/src/tool/write.ts @@ -15,7 +15,6 @@ import { Instance } from "../project/instance" import { trimDiff } from "./edit" import { assertExternalDirectoryEffect } from "./external-directory" -const MAX_DIAGNOSTICS_PER_FILE = 20 const MAX_PROJECT_DIAGNOSTICS_FILES = 5 export const WriteTool = Tool.defineEffect( @@ -72,20 +71,16 @@ export const WriteTool = Tool.defineEffect( const normalizedFilepath = AppFileSystem.normalizePath(filepath) let projectDiagnosticsCount = 0 for (const [file, issues] of Object.entries(diagnostics)) { - const errors = issues.filter((item) => item.severity === 1) - if (errors.length === 0) continue - 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` - : "" - if (file === normalizedFilepath) { - output += `\n\nLSP errors detected in this file, please fix:\n\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n` + const current = file === normalizedFilepath + if (!current && projectDiagnosticsCount >= MAX_PROJECT_DIAGNOSTICS_FILES) continue + const block = LSP.Diagnostic.report(current ? filepath : file, issues) + if (!block) continue + if (current) { + output += `\n\nLSP errors detected in this file, please fix:\n${block}` continue } - if (projectDiagnosticsCount >= MAX_PROJECT_DIAGNOSTICS_FILES) continue projectDiagnosticsCount++ - output += `\n\nLSP errors detected in other files:\n\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n` + output += `\n\nLSP errors detected in other files:\n${block}` } return {