diff --git a/packages/opencode/src/acp/agent.ts b/packages/opencode/src/acp/agent.ts index 6d8a64b7d02..ebd65bb26da 100644 --- a/packages/opencode/src/acp/agent.ts +++ b/packages/opencode/src/acp/agent.ts @@ -30,6 +30,7 @@ import { Todo } from "@/session/todo" import { z } from "zod" import { LoadAPIKeyError } from "ai" import type { OpencodeClient, SessionMessageResponse } from "@opencode-ai/sdk/v2" +import { applyPatch } from "diff" export namespace ACP { const log = Log.create({ service: "acp-agent" }) @@ -105,6 +106,22 @@ export namespace ACP { }) return } + if (res.outcome.optionId !== "reject" && permission.permission == "edit") { + const metadata = permission.metadata || {} + const filepath = typeof metadata["filepath"] === "string" ? metadata["filepath"] : "" + const diff = typeof metadata["diff"] === "string" ? metadata["diff"] : "" + + const content = await Bun.file(filepath).text() + const newContent = getNewContent(content, diff) + + if (newContent) { + this.connection.writeTextFile({ + sessionId: sessionId, + path: filepath, + content: newContent, + }) + } + } await this.config.sdk.permission.reply({ requestID: permission.id, reply: res.outcome.optionId as "once" | "always" | "reject", @@ -1095,4 +1112,13 @@ export namespace ACP { } } } + + function getNewContent(fileOriginal: string, unifiedDiff: string): string | undefined { + const result = applyPatch(fileOriginal, unifiedDiff) + if (result === false) { + log.error("Failed to apply unified diff (context mismatch)") + return undefined + } + return result + } }