@@ -14,6 +14,7 @@ import { AppFileSystem } from "@opencode-ai/shared/filesystem"
1414import DESCRIPTION from "./apply_patch.txt"
1515import { File } from "../file"
1616import { Format } from "../format"
17+ import * as Bom from "@/util/bom"
1718
1819const PatchParams = z . object ( {
1920 patchText : z . string ( ) . describe ( "The full patch text that describes all changes to be made" ) ,
@@ -59,6 +60,7 @@ export const ApplyPatchTool = Tool.define(
5960 diff : string
6061 additions : number
6162 deletions : number
63+ bom : boolean
6264 } > = [ ]
6365
6466 let totalDiff = ""
@@ -72,23 +74,25 @@ export const ApplyPatchTool = Tool.define(
7274 const oldContent = ""
7375 const newContent =
7476 hunk . contents . length === 0 || hunk . contents . endsWith ( "\n" ) ? hunk . contents : `${ hunk . contents } \n`
75- const diff = trimDiff ( createTwoFilesPatch ( filePath , filePath , oldContent , newContent ) )
77+ const next = Bom . split ( newContent )
78+ const diff = trimDiff ( createTwoFilesPatch ( filePath , filePath , oldContent , next . text ) )
7679
7780 let additions = 0
7881 let deletions = 0
79- for ( const change of diffLines ( oldContent , newContent ) ) {
82+ for ( const change of diffLines ( oldContent , next . text ) ) {
8083 if ( change . added ) additions += change . count || 0
8184 if ( change . removed ) deletions += change . count || 0
8285 }
8386
8487 fileChanges . push ( {
8588 filePath,
8689 oldContent,
87- newContent,
90+ newContent : next . text ,
8891 type : "add" ,
8992 diff,
9093 additions,
9194 deletions,
95+ bom : next . bom ,
9296 } )
9397
9498 totalDiff += diff + "\n"
@@ -104,13 +108,16 @@ export const ApplyPatchTool = Tool.define(
104108 )
105109 }
106110
107- const oldContent = yield * afs . readFileString ( filePath )
111+ const source = yield * Bom . readFile ( afs , filePath )
112+ const oldContent = source . text
108113 let newContent = oldContent
114+ let bom = source . bom
109115
110116 // Apply the update chunks to get new content
111117 try {
112118 const fileUpdate = Patch . deriveNewContentsFromChunks ( filePath , hunk . chunks )
113119 newContent = fileUpdate . content
120+ bom = fileUpdate . bom
114121 } catch ( error ) {
115122 return yield * Effect . fail ( new Error ( `apply_patch verification failed: ${ error } ` ) )
116123 }
@@ -136,15 +143,16 @@ export const ApplyPatchTool = Tool.define(
136143 diff,
137144 additions,
138145 deletions,
146+ bom,
139147 } )
140148
141149 totalDiff += diff + "\n"
142150 break
143151 }
144152
145153 case "delete" : {
146- const contentToDelete = yield * afs
147- . readFileString ( filePath )
154+ const source = yield * Bom
155+ . readFile ( afs , filePath )
148156 . pipe (
149157 Effect . catch ( ( error ) =>
150158 Effect . fail (
@@ -154,6 +162,7 @@ export const ApplyPatchTool = Tool.define(
154162 ) ,
155163 ) ,
156164 )
165+ const contentToDelete = source . text
157166 const deleteDiff = trimDiff ( createTwoFilesPatch ( filePath , filePath , contentToDelete , "" ) )
158167
159168 const deletions = contentToDelete . split ( "\n" ) . length
@@ -166,6 +175,7 @@ export const ApplyPatchTool = Tool.define(
166175 diff : deleteDiff ,
167176 additions : 0 ,
168177 deletions,
178+ bom : source . bom ,
169179 } )
170180
171181 totalDiff += deleteDiff + "\n"
@@ -207,20 +217,20 @@ export const ApplyPatchTool = Tool.define(
207217 case "add" :
208218 // Create parent directories (recursive: true is safe on existing/root dirs)
209219
210- yield * afs . writeWithDirs ( change . filePath , change . newContent )
220+ yield * afs . writeWithDirs ( change . filePath , Bom . join ( change . newContent , change . bom ) )
211221 updates . push ( { file : change . filePath , event : "add" } )
212222 break
213223
214224 case "update" :
215- yield * afs . writeWithDirs ( change . filePath , change . newContent )
225+ yield * afs . writeWithDirs ( change . filePath , Bom . join ( change . newContent , change . bom ) )
216226 updates . push ( { file : change . filePath , event : "change" } )
217227 break
218228
219229 case "move" :
220230 if ( change . movePath ) {
221231 // Create parent directories (recursive: true is safe on existing/root dirs)
222232
223- yield * afs . writeWithDirs ( change . movePath ! , change . newContent )
233+ yield * afs . writeWithDirs ( change . movePath ! , Bom . join ( change . newContent , change . bom ) )
224234 yield * afs . remove ( change . filePath )
225235 updates . push ( { file : change . filePath , event : "unlink" } )
226236 updates . push ( { file : change . movePath , event : "add" } )
@@ -234,7 +244,9 @@ export const ApplyPatchTool = Tool.define(
234244 }
235245
236246 if ( edited ) {
237- yield * format . file ( edited )
247+ if ( yield * format . file ( edited ) ) {
248+ yield * Bom . syncFile ( afs , edited , change . bom )
249+ }
238250 yield * bus . publish ( File . Event . Edited , { file : edited } )
239251 }
240252 }
0 commit comments