Skip to content

Commit a041bb8

Browse files
committed
tool: trim persisted LSP diagnostics
1 parent 2685de2 commit a041bb8

File tree

3 files changed

+105
-6
lines changed

3 files changed

+105
-6
lines changed

packages/opencode/src/tool/edit.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ export const EditTool = Tool.define("edit", {
131131

132132
let output = ""
133133
await LSP.touchFile(filePath, true)
134-
const diagnostics = await LSP.diagnostics()
134+
const allDiagnostics = await LSP.diagnostics()
135135
const normalizedFilePath = Filesystem.normalizePath(filePath)
136-
const issues = diagnostics[normalizedFilePath] ?? []
136+
const issues = allDiagnostics[normalizedFilePath] ?? []
137137
const errors = issues.filter((item) => item.severity === 1)
138138
if (errors.length > 0) {
139139
const limited = errors.slice(0, MAX_DIAGNOSTICS_PER_FILE)
@@ -144,7 +144,9 @@ export const EditTool = Tool.define("edit", {
144144

145145
return {
146146
metadata: {
147-
diagnostics,
147+
diagnostics: {
148+
[normalizedFilePath]: issues,
149+
},
148150
diff,
149151
filediff,
150152
},

packages/opencode/src/tool/write.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ export const WriteTool = Tool.define("write", {
5353

5454
let output = ""
5555
await LSP.touchFile(filepath, true)
56-
const diagnostics = await LSP.diagnostics()
56+
const allDiagnostics = await LSP.diagnostics()
5757
const normalizedFilepath = Filesystem.normalizePath(filepath)
5858
let projectDiagnosticsCount = 0
59-
for (const [file, issues] of Object.entries(diagnostics)) {
59+
for (const [file, issues] of Object.entries(allDiagnostics)) {
6060
const errors = issues.filter((item) => item.severity === 1)
6161
if (errors.length === 0) continue
6262
const limited = errors.slice(0, MAX_DIAGNOSTICS_PER_FILE)
@@ -74,7 +74,9 @@ export const WriteTool = Tool.define("write", {
7474
return {
7575
title: path.relative(Instance.worktree, filepath),
7676
metadata: {
77-
diagnostics,
77+
diagnostics: {
78+
[normalizedFilepath]: allDiagnostics[normalizedFilepath] ?? [],
79+
},
7880
filepath,
7981
exists: exists,
8082
},
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { describe, expect, mock, test } from "bun:test"
2+
import path from "path"
3+
import { Instance } from "../../src/project/instance"
4+
import { Filesystem } from "../../src/util/filesystem"
5+
import { FileTime } from "../../src/file/time"
6+
import { tmpdir } from "../fixture/fixture"
7+
8+
const state = {
9+
diagnostics: {} as Record<string, Array<{ severity: number }>>,
10+
}
11+
12+
mock.module("../../src/lsp", () => ({
13+
LSP: {
14+
touchFile: () => Promise.resolve(),
15+
diagnostics: () => Promise.resolve(state.diagnostics),
16+
Diagnostic: {
17+
pretty: () => "",
18+
},
19+
},
20+
}))
21+
22+
const { EditTool } = await import("../../src/tool/edit")
23+
const { WriteTool } = await import("../../src/tool/write")
24+
25+
const ctx = {
26+
sessionID: "test",
27+
messageID: "",
28+
callID: "",
29+
agent: "build",
30+
abort: AbortSignal.any([]),
31+
metadata: () => {},
32+
ask: async () => {},
33+
}
34+
35+
describe("tool diagnostics metadata", () => {
36+
test("write stores only touched file diagnostics", async () => {
37+
await using tmp = await tmpdir({ git: true })
38+
await Instance.provide({
39+
directory: tmp.path,
40+
fn: async () => {
41+
const filePath = path.join(tmp.path, "a.lua")
42+
const normalizedFilepath = Filesystem.normalizePath(filePath)
43+
const otherPath = Filesystem.normalizePath(path.join(tmp.path, "b.lua"))
44+
state.diagnostics = {
45+
[normalizedFilepath]: [{ severity: 1 }, { severity: 1 }],
46+
[otherPath]: Array.from({ length: 250 }, () => ({ severity: 1 })),
47+
}
48+
49+
const tool = await WriteTool.init()
50+
const result = await tool.execute(
51+
{
52+
filePath,
53+
content: "print('hi')",
54+
},
55+
ctx,
56+
)
57+
58+
expect(Object.keys(result.metadata.diagnostics)).toEqual([normalizedFilepath])
59+
expect(result.metadata.diagnostics[normalizedFilepath]?.length).toBe(2)
60+
},
61+
})
62+
})
63+
64+
test("edit stores only touched file diagnostics", async () => {
65+
await using tmp = await tmpdir({ git: true })
66+
await Instance.provide({
67+
directory: tmp.path,
68+
fn: async () => {
69+
const filePath = path.join(tmp.path, "a.lua")
70+
await Bun.write(filePath, "hello\n")
71+
FileTime.read(ctx.sessionID, filePath)
72+
73+
const normalizedFilepath = Filesystem.normalizePath(filePath)
74+
const otherPath = Filesystem.normalizePath(path.join(tmp.path, "b.lua"))
75+
state.diagnostics = {
76+
[normalizedFilepath]: [{ severity: 1 }],
77+
[otherPath]: Array.from({ length: 250 }, () => ({ severity: 1 })),
78+
}
79+
80+
const tool = await EditTool.init()
81+
const result = await tool.execute(
82+
{
83+
filePath,
84+
oldString: "hello",
85+
newString: "world",
86+
},
87+
ctx,
88+
)
89+
90+
expect(Object.keys(result.metadata.diagnostics)).toEqual([normalizedFilepath])
91+
expect(result.metadata.diagnostics[normalizedFilepath]?.length).toBe(1)
92+
},
93+
})
94+
})
95+
})

0 commit comments

Comments
 (0)