diff --git a/packages/app/src/context/file.tsx b/packages/app/src/context/file.tsx index 306bce922..805936cd8 100644 --- a/packages/app/src/context/file.tsx +++ b/packages/app/src/context/file.tsx @@ -571,6 +571,18 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({ } const kind = event.properties.event + if (kind === "change") { + const dir = (() => { + if (path === "") return "" + const node = tree.node[path] + if (node?.type !== "directory") return + return path + })() + if (dir === undefined) return + if (!tree.dir[dir]?.loaded) return + listDir(dir, { force: true }) + return + } if (kind !== "add" && kind !== "unlink") return const parent = path.split("/").slice(0, -1).join("/") diff --git a/packages/opencode/src/tool/apply_patch.ts b/packages/opencode/src/tool/apply_patch.ts index 8028ee8de..1344467c7 100644 --- a/packages/opencode/src/tool/apply_patch.ts +++ b/packages/opencode/src/tool/apply_patch.ts @@ -185,7 +185,7 @@ export const ApplyPatchTool = Tool.define("apply_patch", { }) // Apply the changes - const changedFiles: string[] = [] + const updates: Array<{ file: string; event: "add" | "change" | "unlink" }> = [] for (const change of fileChanges) { const edited = change.type === "delete" ? undefined : (change.movePath ?? change.filePath) @@ -194,12 +194,12 @@ export const ApplyPatchTool = Tool.define("apply_patch", { // Create parent directories (recursive: true is safe on existing/root dirs) await fs.mkdir(path.dirname(change.filePath), { recursive: true }) await fs.writeFile(change.filePath, change.newContent, "utf-8") - changedFiles.push(change.filePath) + updates.push({ file: change.filePath, event: "add" }) break case "update": await fs.writeFile(change.filePath, change.newContent, "utf-8") - changedFiles.push(change.filePath) + updates.push({ file: change.filePath, event: "change" }) break case "move": @@ -208,13 +208,14 @@ export const ApplyPatchTool = Tool.define("apply_patch", { await fs.mkdir(path.dirname(change.movePath), { recursive: true }) await fs.writeFile(change.movePath, change.newContent, "utf-8") await fs.unlink(change.filePath) - changedFiles.push(change.movePath) + updates.push({ file: change.filePath, event: "unlink" }) + updates.push({ file: change.movePath, event: "add" }) } break case "delete": await fs.unlink(change.filePath) - changedFiles.push(change.filePath) + updates.push({ file: change.filePath, event: "unlink" }) break } @@ -226,8 +227,8 @@ export const ApplyPatchTool = Tool.define("apply_patch", { } // Publish file change events - for (const filePath of changedFiles) { - await Bus.publish(FileWatcher.Event.Updated, { file: filePath, event: "change" }) + for (const update of updates) { + await Bus.publish(FileWatcher.Event.Updated, update) } // Notify LSP of file changes and collect diagnostics diff --git a/packages/opencode/src/tool/edit.ts b/packages/opencode/src/tool/edit.ts index 26db5b228..0bf1d6792 100644 --- a/packages/opencode/src/tool/edit.ts +++ b/packages/opencode/src/tool/edit.ts @@ -10,6 +10,7 @@ import { LSP } from "../lsp" import { createTwoFilesPatch, diffLines } from "diff" import DESCRIPTION from "./edit.txt" import { File } from "../file" +import { FileWatcher } from "../file/watcher" import { Bus } from "../bus" import { FileTime } from "../file/time" import { Filesystem } from "../util/filesystem" @@ -48,6 +49,7 @@ export const EditTool = Tool.define("edit", { let contentNew = "" await FileTime.withLock(filePath, async () => { if (params.oldString === "") { + const existed = await Bun.file(filePath).exists() contentNew = params.newString diff = trimDiff(createTwoFilesPatch(filePath, filePath, contentOld, contentNew)) await ctx.ask({ @@ -63,6 +65,10 @@ export const EditTool = Tool.define("edit", { await Bus.publish(File.Event.Edited, { file: filePath, }) + await Bus.publish(FileWatcher.Event.Updated, { + file: filePath, + event: existed ? "change" : "add", + }) FileTime.read(ctx.sessionID, filePath) return } @@ -92,6 +98,10 @@ export const EditTool = Tool.define("edit", { await Bus.publish(File.Event.Edited, { file: filePath, }) + await Bus.publish(FileWatcher.Event.Updated, { + file: filePath, + event: "change", + }) contentNew = await file.text() diff = trimDiff( createTwoFilesPatch(filePath, filePath, normalizeLineEndings(contentOld), normalizeLineEndings(contentNew)), diff --git a/packages/opencode/src/tool/write.ts b/packages/opencode/src/tool/write.ts index cfcf6a0da..eca64d303 100644 --- a/packages/opencode/src/tool/write.ts +++ b/packages/opencode/src/tool/write.ts @@ -6,6 +6,7 @@ import { createTwoFilesPatch } from "diff" import DESCRIPTION from "./write.txt" import { Bus } from "../bus" import { File } from "../file" +import { FileWatcher } from "../file/watcher" import { FileTime } from "../file/time" import { Filesystem } from "../util/filesystem" import { Instance } from "../project/instance" @@ -45,6 +46,10 @@ export const WriteTool = Tool.define("write", { await Bus.publish(File.Event.Edited, { file: filepath, }) + await Bus.publish(FileWatcher.Event.Updated, { + file: filepath, + event: exists ? "change" : "add", + }) FileTime.read(ctx.sessionID, filepath) let output = "Wrote file successfully."