@@ -30,7 +30,12 @@ export async function applyDiffTool(
3030 removeClosingTag : RemoveClosingTag ,
3131) {
3232 const argsXmlTag : string | undefined = block . params . args
33+ const legacyPath : string | undefined = block . params . path
34+ const legacyDiffContent : string | undefined = block . params . diff
35+ const legacyStartLineStr : string | undefined = block . params . start_line
36+
3337 let operationsMap : Record < string , DiffOperation > = { }
38+ let usingLegacyParams = false
3439
3540 // Handle partial message first
3641 if ( block . partial ) {
@@ -40,6 +45,9 @@ export async function applyDiffTool(
4045 if ( match ) {
4146 filePath = match [ 1 ]
4247 }
48+ } else if ( legacyPath ) {
49+ // Use legacy path if argsXmlTag is not present for partial messages
50+ filePath = legacyPath
4351 }
4452
4553 const sharedMessageProps : ClineSayTool = {
@@ -51,51 +59,67 @@ export async function applyDiffTool(
5159 return
5260 }
5361
54- if ( ! argsXmlTag ) {
55- cline . consecutiveMistakeCount ++
56- cline . recordToolError ( "apply_diff" )
57- const errorMsg = await cline . sayAndCreateMissingParamError ( "apply_diff" , "args" )
58- pushToolResult ( errorMsg )
59- return
60- }
61-
62- // Parse file entries from XML
63- try {
64- const parsed = parseXml ( argsXmlTag , [ "file.diff.content" ] ) as any
65- const files = Array . isArray ( parsed . file ) ? parsed . file : [ parsed . file ] . filter ( Boolean )
62+ if ( argsXmlTag ) {
63+ // Parse file entries from XML (new way)
64+ try {
65+ const parsed = parseXml ( argsXmlTag , [ "file.diff.content" ] ) as any
66+ const files = Array . isArray ( parsed . file ) ? parsed . file : [ parsed . file ] . filter ( Boolean )
6667
67- for ( const file of files ) {
68- if ( ! file . path || ! file . diff ) continue
68+ for ( const file of files ) {
69+ if ( ! file . path || ! file . diff ) continue
6970
70- const filePath = file . path
71+ const filePath = file . path
7172
72- // Initialize the operation in the map if it doesn't exist
73- if ( ! operationsMap [ filePath ] ) {
74- operationsMap [ filePath ] = {
75- path : filePath ,
76- diff : [ ] ,
73+ // Initialize the operation in the map if it doesn't exist
74+ if ( ! operationsMap [ filePath ] ) {
75+ operationsMap [ filePath ] = {
76+ path : filePath ,
77+ diff : [ ] ,
78+ }
7779 }
78- }
7980
80- // Handle diff as either array or single element
81- const diffs = Array . isArray ( file . diff ) ? file . diff : [ file . diff ]
81+ // Handle diff as either array or single element
82+ const diffs = Array . isArray ( file . diff ) ? file . diff : [ file . diff ]
8283
83- for ( let i = 0 ; i < diffs . length ; i ++ ) {
84- const diff = diffs [ i ]
85- let diffContent : string
86- let startLine : number | undefined
84+ for ( let i = 0 ; i < diffs . length ; i ++ ) {
85+ const diff = diffs [ i ]
86+ let diffContent : string
87+ let startLine : number | undefined
8788
88- diffContent = diff . content
89- startLine = diff . start_line ? parseInt ( diff . start_line ) : undefined
89+ diffContent = diff . content
90+ startLine = diff . start_line ? parseInt ( diff . start_line ) : undefined
9091
91- operationsMap [ filePath ] . diff . push ( {
92- content : diffContent ,
93- startLine,
94- } )
92+ operationsMap [ filePath ] . diff . push ( {
93+ content : diffContent ,
94+ startLine,
95+ } )
96+ }
9597 }
98+ } catch ( error ) {
99+ throw new Error ( `Failed to parse apply_diff XML: ${ error instanceof Error ? error . message : String ( error ) } ` )
96100 }
97- } catch ( error ) {
98- throw new Error ( `Failed to parse apply_diff XML: ${ error instanceof Error ? error . message : String ( error ) } ` )
101+ } else if ( legacyPath && typeof legacyDiffContent === "string" ) {
102+ // Handle legacy parameters (old way)
103+ usingLegacyParams = true
104+ operationsMap [ legacyPath ] = {
105+ path : legacyPath ,
106+ diff : [
107+ {
108+ content : legacyDiffContent , // Unescaping will be handled later like new diffs
109+ startLine : legacyStartLineStr ? parseInt ( legacyStartLineStr ) : undefined ,
110+ } ,
111+ ] ,
112+ }
113+ } else {
114+ // Neither new XML args nor old path/diff params are sufficient
115+ cline . consecutiveMistakeCount ++
116+ cline . recordToolError ( "apply_diff" )
117+ const errorMsg = await cline . sayAndCreateMissingParamError (
118+ "apply_diff" ,
119+ "args (or legacy 'path' and 'diff' parameters)" ,
120+ )
121+ pushToolResult ( errorMsg )
122+ return
99123 }
100124
101125 // If no operations were extracted, bail out
@@ -105,7 +129,9 @@ export async function applyDiffTool(
105129 pushToolResult (
106130 await cline . sayAndCreateMissingParamError (
107131 "apply_diff" ,
108- "args (must contain at least one valid file element)" ,
132+ usingLegacyParams
133+ ? "legacy 'path' and 'diff' (must be valid and non-empty)"
134+ : "args (must contain at least one valid file element)" ,
109135 ) ,
110136 )
111137 return
0 commit comments