MCPcopy Create free account
hub / github.com/Zoo-Code-Org/Zoo-Code / computeReplacements

Function computeReplacements

src/core/tools/apply-patch/apply.ts:38–95  ·  view source on GitHub ↗

* Compute the replacements needed to transform originalLines into the new lines. * Each replacement is [startIndex, oldLength, newLines].

(
	originalLines: string[],
	filePath: string,
	chunks: UpdateFileChunk[],
)

Source from the content-addressed store, hash-verified

36 * Each replacement is [startIndex, oldLength, newLines].
37 */
38function computeReplacements(
39 originalLines: string[],
40 filePath: string,
41 chunks: UpdateFileChunk[],
42): Array<[number, number, string[]]> {
43 const replacements: Array<[number, number, string[]]> = []
44 let lineIndex = 0
45
46 for (const chunk of chunks) {
47 // If a chunk has a change_context, find it first
48 if (chunk.changeContext !== null) {
49 const idx = seekSequence(originalLines, [chunk.changeContext], lineIndex, false)
50 if (idx === null) {
51 throw new ApplyPatchError(`Failed to find context '${chunk.changeContext}' in ${filePath}`)
52 }
53 lineIndex = idx + 1
54 }
55
56 if (chunk.oldLines.length === 0) {
57 // Pure addition (no old lines). Add at the end or before final empty line.
58 const insertionIdx =
59 originalLines.length > 0 && originalLines[originalLines.length - 1] === ""
60 ? originalLines.length - 1
61 : originalLines.length
62 replacements.push([insertionIdx, 0, chunk.newLines])
63 continue
64 }
65
66 // Try to find the old_lines in the file
67 let pattern = chunk.oldLines
68 let newSlice = chunk.newLines
69 let found = seekSequence(originalLines, pattern, lineIndex, chunk.isEndOfFile)
70
71 // If not found and pattern ends with empty string (trailing newline),
72 // retry without it
73 if (found === null && pattern.length > 0 && pattern[pattern.length - 1] === "") {
74 pattern = pattern.slice(0, -1)
75 if (newSlice.length > 0 && newSlice[newSlice.length - 1] === "") {
76 newSlice = newSlice.slice(0, -1)
77 }
78 found = seekSequence(originalLines, pattern, lineIndex, chunk.isEndOfFile)
79 }
80
81 if (found !== null) {
82 replacements.push([found, pattern.length, newSlice])
83 lineIndex = found + pattern.length
84 } else {
85 throw new ApplyPatchError(
86 `Failed to find expected lines in ${filePath}:\n${chunk.oldLines.join("\n").substring(0, 200)}${chunk.oldLines.join("\n").length > 200 ? "..." : ""}`,
87 )
88 }
89 }
90
91 // Sort replacements by start index
92 replacements.sort((a, b) => a[0] - b[0])
93
94 return replacements
95}

Callers 1

applyChunksToContentFunction · 0.85

Calls 1

seekSequenceFunction · 0.90

Tested by

no test coverage detected