@@ -7,21 +7,19 @@ import { WorkspaceProvider } from '@/context/providers/workspace-provider'
77import { Logger } from '@shared/utils/logger'
88import { dictionary } from '@shared/constants/dictionary'
99
10- const build_changes_xml = (
10+ const build_changes_markdown = (
1111 diff : string ,
1212 cwd : string ,
13- workspace_provider : WorkspaceProvider ,
14- is_no_context_web_mode ?: boolean
13+ diff_base : string ,
14+ branch_name : string
1515) : string => {
1616 // Split diff into per-file sections. Each section starts with 'diff --git '.
1717 const file_diffs = diff . split ( / ^ d i f f - - g i t / m) . filter ( ( d ) => d . trim ( ) != '' )
18-
1918 if ( file_diffs . length == 0 ) {
2019 return ''
2120 }
2221
2322 let changes_content = ''
24- const checked_files = new Set ( workspace_provider . get_checked_files ( ) )
2523
2624 for ( const file_diff_content of file_diffs ) {
2725 const full_file_diff = 'diff --git ' + file_diff_content
@@ -49,52 +47,37 @@ const build_changes_xml = (
4947 }
5048
5149 if ( file_path ) {
52- changes_content += `<change path="${ file_path } ">\n`
53- changes_content += `<diff>\n<![CDATA[\n${ full_file_diff } \n]]>\n</diff>\n`
54-
55- const absolute_path = path . join ( cwd , file_path )
56- if ( ! is_no_context_web_mode && checked_files . has ( absolute_path ) ) {
57- const workspace_root =
58- workspace_provider . get_workspace_root_for_file ( absolute_path )
59- let display_path : string
60- if ( workspace_root ) {
61- const relative_path = path
62- . relative ( workspace_root , absolute_path )
63- . replace ( / \\ / g, '/' )
64- if ( workspace_provider . getWorkspaceRoots ( ) . length > 1 ) {
65- const workspace_name =
66- workspace_provider . get_workspace_name ( workspace_root )
67- display_path = `${ workspace_name } /${ relative_path } `
68- } else {
69- display_path = relative_path
70- }
71- } else {
72- display_path = file_path . replace ( / \\ / g, '/' )
73- }
74- changes_content += `<file path="${ display_path } " />\n`
75- } else {
76- let file_content = ''
50+ changes_content += `\n\n### File: \`${ file_path } \`\n\n`
51+
52+ let file_content = ''
53+ try {
54+ // Get the file content from the git revision we're diffing against.
55+ file_content = execSync ( `git show ${ diff_base } :"./${ file_path } "` , {
56+ cwd,
57+ encoding : 'utf-8' ,
58+ stdio : [ 'pipe' , 'pipe' , 'ignore' ] // Prevent git errors from crashing (e.g., file not on branch)
59+ } )
60+ } catch ( e ) {
61+ // File likely did not exist on the branch (i.e., it's a new file).
62+ // In this case, the original content is correctly an empty string.
7763 if ( ! is_deleted ) {
78- try {
79- file_content = fs . readFileSync ( absolute_path , 'utf-8' )
80- } catch ( e ) {
81- if ( ( e as NodeJS . ErrnoException ) . code !== 'ENOENT' ) {
82- Logger . error ( {
83- function_name : 'build_changes_xml' ,
84- message : `Could not read file for diff: ${ absolute_path } ` ,
85- data : e
86- } )
87- }
88- }
64+ Logger . warn ( {
65+ function_name : 'build_changes_markdown' ,
66+ message : `Could not get file content from git base ${ diff_base } for path ${ file_path } . Assuming it's a new file.` ,
67+ data : e
68+ } )
8969 }
90- changes_content += `<file>\n<![CDATA[\n${ file_content } \n]]>\n</file>\n`
9170 }
92- changes_content += `</change>\n`
71+ if ( file_content ) {
72+ const lang = path . extname ( file_path ) . slice ( 1 )
73+ changes_content += `The original state of the file for reference:\n\n\`\`\`${ lang } \n${ file_content } \n\`\`\`\n\n`
74+ }
75+ changes_content += `**New changes:**\n\n\`\`\`diff\n${ full_file_diff } \`\`\`\n`
9376 }
9477 }
9578
9679 if ( changes_content ) {
97- return `\n<changes>\n ${ changes_content } </changes> \n`
80+ return `\n\n# Changes against ${ branch_name } branch ${ changes_content } \n---\n \n`
9881 }
9982 return ''
10083}
@@ -115,9 +98,16 @@ export const replace_changes_symbol = async (params: {
11598 const branch_spec = matches [ 1 ]
11699
117100 if ( params . after_context ) {
101+ let branch_name = branch_spec
102+ const multi_root_match = branch_spec . match ( / ^ ( [ ^ / ] + ) \/ ( .+ ) $ / )
103+
104+ if ( multi_root_match ) {
105+ branch_name = multi_root_match [ 2 ]
106+ }
107+
118108 return params . instruction . replace (
119109 new RegExp ( `#Changes:${ branch_spec } ` , 'g' ) ,
120- '<changes/>'
110+ `(Changes against ${ branch_name } branch)`
121111 )
122112 }
123113
@@ -151,18 +141,24 @@ export const replace_changes_symbol = async (params: {
151141 }
152142
153143 try {
154- // Get current branch name
155144 const current_branch = execSync ( 'git rev-parse --abbrev-ref HEAD' , {
156145 cwd : target_folder . uri . fsPath
157146 } )
158147 . toString ( )
159148 . trim ( )
160149
161- // If comparing to same branch, use merge-base to show changes since branch point
162- const diff_command =
163- current_branch == branch_name
164- ? `git diff $(git merge-base HEAD origin/${ branch_name } )`
165- : `git diff ${ branch_name } `
150+ let diff_base : string
151+ if ( current_branch == branch_name ) {
152+ // If comparing to same branch, use merge-base to show changes since branch point
153+ diff_base = execSync ( `git merge-base HEAD origin/${ branch_name } ` , {
154+ cwd : target_folder . uri . fsPath
155+ } )
156+ . toString ( )
157+ . trim ( )
158+ } else {
159+ diff_base = branch_name
160+ }
161+ const diff_command = `git diff ${ diff_base } `
166162 const diff = execSync ( diff_command , {
167163 cwd : target_folder . uri . fsPath
168164 } ) . toString ( )
@@ -180,14 +176,14 @@ export const replace_changes_symbol = async (params: {
180176 )
181177 }
182178
183- const replacement_text = build_changes_xml (
179+ const replacement_text = build_changes_markdown (
184180 diff ,
185181 target_folder . uri . fsPath ,
186- params . workspace_provider ,
187- params . is_no_context_web_mode
182+ diff_base ,
183+ branch_name
188184 )
189185 return params . instruction . replace (
190- new RegExp ( `#Changes:${ branch_spec } ` , 'g' ) ,
186+ new RegExp ( `\\s* #Changes:${ branch_spec } \\s* ` , 'g' ) ,
191187 replacement_text
192188 )
193189 } catch ( error ) {
@@ -221,18 +217,24 @@ export const replace_changes_symbol = async (params: {
221217 }
222218
223219 try {
224- // Get current branch name
225220 const current_branch = execSync ( 'git rev-parse --abbrev-ref HEAD' , {
226221 cwd : repository . rootUri . fsPath
227222 } )
228223 . toString ( )
229224 . trim ( )
230225
231- // If comparing to same branch, use merge-base to show changes since branch point
232- const diff_command =
233- current_branch == branch_name
234- ? `git diff $(git merge-base HEAD origin/${ branch_name } )`
235- : `git diff ${ branch_name } `
226+ let diff_base : string
227+ if ( current_branch == branch_name ) {
228+ // If comparing to same branch, use merge-base to show changes since branch point
229+ diff_base = execSync ( `git merge-base HEAD origin/${ branch_name } ` , {
230+ cwd : repository . rootUri . fsPath
231+ } )
232+ . toString ( )
233+ . trim ( )
234+ } else {
235+ diff_base = branch_name
236+ }
237+ const diff_command = `git diff ${ diff_base } `
236238 const diff = execSync ( diff_command , {
237239 cwd : repository . rootUri . fsPath
238240 } ) . toString ( )
@@ -249,14 +251,14 @@ export const replace_changes_symbol = async (params: {
249251 )
250252 }
251253
252- const replacement_text = build_changes_xml (
254+ const replacement_text = build_changes_markdown (
253255 diff ,
254256 repository . rootUri . fsPath ,
255- params . workspace_provider ,
256- params . is_no_context_web_mode
257+ diff_base ,
258+ branch_name
257259 )
258260 return params . instruction . replace (
259- new RegExp ( `#Changes:${ branch_name } ` , 'g' ) ,
261+ new RegExp ( `\\s* #Changes:${ branch_name } \\s* ` , 'g' ) ,
260262 replacement_text
261263 )
262264 } catch ( error ) {
@@ -276,7 +278,7 @@ export const replace_changes_symbol = async (params: {
276278 }
277279}
278280
279- const build_commit_changes_xml = (
281+ const build_commit_changes_markdown = (
280282 diff : string ,
281283 cwd : string ,
282284 commit_hash : string ,
@@ -325,25 +327,27 @@ const build_commit_changes_xml = (
325327 } )
326328 } catch ( e ) {
327329 Logger . error ( {
328- function_name : 'build_commit_changes_xml ' ,
330+ function_name : 'build_commit_changes_markdown ' ,
329331 message : `Could not read file for diff from commit: ${ file_path } ` ,
330332 data : e
331333 } )
332334 }
333335 }
334336
335- changes_content += `<change path="${ file_path } ">\n`
336- changes_content += `<diff>\n<![CDATA[\n${ full_file_diff } \n]]>\n</diff>\n`
337- changes_content += `<file>\n<![CDATA[\n${ file_content } \n]]>\n</file>\n`
338- changes_content += `</change>\n`
337+ changes_content += `### File: \`${ file_path } \`\n\n`
338+ changes_content += `**Changes:**\n\n\`\`\`diff\n${ full_file_diff } \`\`\`\n`
339+ if ( file_content ) {
340+ const lang = path . extname ( file_path ) . slice ( 1 )
341+ changes_content += `\nFull file for reference:\n\n\`\`\`${ lang } \n${ file_content } \n\`\`\`\n`
342+ }
339343 }
340344 }
341345
342346 if ( changes_content ) {
343- const message_attribute = commit_message
344- ? ` message=" ${ commit_message . replace ( / " / g , '"' ) } " `
347+ const message_section = commit_message
348+ ? `**Message:** ${ commit_message } \n\n `
345349 : ''
346- return `\n<commit ${ message_attribute } >\n<changes>\n ${ changes_content } </changes>\n</commit> \n`
350+ return `\n\n# Commit\n\n ${ message_section } ${ changes_content } \n---\n \n`
347351 }
348352 return ''
349353}
@@ -356,11 +360,9 @@ export const replace_commit_symbol = async (params: {
356360 if ( params . after_context ) {
357361 return params . instruction . replace (
358362 regex ,
359- ( _match , _folder , _hash , message ) => {
360- const message_attr = message
361- ? ` message="${ message . replace ( / " / g, '"' ) } "`
362- : ''
363- return `<commit${ message_attr } />`
363+ ( _match , _folder_name , _commit_hash , commit_message ) => {
364+ if ( commit_message ) return `(Commit: ${ commit_message } )`
365+ return '(Commit)'
364366 }
365367 )
366368 }
@@ -404,14 +406,16 @@ export const replace_commit_symbol = async (params: {
404406 continue
405407 }
406408
407- const replacement_text = build_commit_changes_xml (
409+ const replacement_text = build_commit_changes_markdown (
408410 diff ,
409411 target_folder . uri . fsPath ,
410412 commit_hash ,
411413 commit_message
412414 )
413415 result_instruction = result_instruction . replace (
414- full_match ,
416+ new RegExp (
417+ `\\s*${ full_match . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) } \\s*`
418+ ) ,
415419 replacement_text
416420 )
417421 } catch ( error ) {
0 commit comments