@@ -221,29 +221,80 @@ async function checkGitInstallation(
221221 try {
222222 const checkpointFileChangeManager = provider ?. getFileChangeManager ( )
223223 if ( checkpointFileChangeManager ) {
224- // Get the initial baseline (preserve for cumulative diff tracking)
225- const initialBaseline = checkpointFileChangeManager . getChanges ( ) . baseCheckpoint
224+ // Get the current baseline for cumulative tracking
225+ let currentBaseline = checkpointFileChangeManager . getChanges ( ) . baseCheckpoint
226+
227+ // For cumulative tracking, we want to calculate from baseline to new checkpoint
228+ // But if this is the first time or baseline is invalid, update it to fromHash
229+ try {
230+ await service . getDiff ( { from : currentBaseline , to : currentBaseline } )
231+ log (
232+ `[Task#checkpointCreated] Using existing baseline ${ currentBaseline } for cumulative tracking` ,
233+ )
234+ } catch ( baselineValidationError ) {
235+ // Baseline is invalid, use fromHash as the new baseline for cumulative tracking
236+ log (
237+ `[Task#checkpointCreated] Baseline validation failed for ${ currentBaseline } : ${ baselineValidationError instanceof Error ? baselineValidationError . message : String ( baselineValidationError ) } ` ,
238+ )
239+ log ( `[Task#checkpointCreated] Updating baseline to fromHash: ${ fromHash } ` )
240+ currentBaseline = fromHash
241+ // Update FileChangeManager baseline to match
242+ try {
243+ await checkpointFileChangeManager . updateBaseline ( currentBaseline )
244+ log ( `[Task#checkpointCreated] Successfully updated baseline to ${ currentBaseline } ` )
245+ } catch ( updateError ) {
246+ log (
247+ `[Task#checkpointCreated] Failed to update baseline: ${ updateError instanceof Error ? updateError . message : String ( updateError ) } ` ,
248+ )
249+ throw updateError
250+ }
251+ }
252+
226253 log (
227- `[Task#checkpointCreated] Calculating cumulative changes from initial baseline ${ initialBaseline } to ${ toHash } ` ,
254+ `[Task#checkpointCreated] Calculating cumulative changes from baseline ${ currentBaseline } to ${ toHash } ` ,
228255 )
229256
230- // Calculate cumulative diff from initial baseline to new checkpoint using checkpoint service
231- const changes = await service . getDiff ( { from : initialBaseline , to : toHash } )
257+ // Calculate cumulative diff from baseline to new checkpoint using checkpoint service
258+ const changes = await service . getDiff ( { from : currentBaseline , to : toHash } )
232259
233260 if ( changes && changes . length > 0 ) {
234261 // Convert to FileChange format with correct checkpoint references
235- const fileChanges = changes . map ( ( change : any ) => ( {
236- uri : change . paths . relative ,
237- type : ( change . paths . newFile
238- ? "create"
239- : change . paths . deletedFile
240- ? "delete"
241- : "edit" ) as FileChangeType ,
242- fromCheckpoint : initialBaseline , // Always reference initial baseline for cumulative view
243- toCheckpoint : toHash , // Current checkpoint for comparison
244- linesAdded : change . content . after ? change . content . after . split ( "\n" ) . length : 0 ,
245- linesRemoved : change . content . before ? change . content . before . split ( "\n" ) . length : 0 ,
246- } ) )
262+ const fileChanges = changes . map ( ( change : any ) => {
263+ const type = (
264+ change . paths . newFile ? "create" : change . paths . deletedFile ? "delete" : "edit"
265+ ) as FileChangeType
266+
267+ // Calculate actual line differences for the change
268+ let linesAdded = 0
269+ let linesRemoved = 0
270+
271+ if ( type === "create" ) {
272+ // New file: all lines are added
273+ linesAdded = change . content . after ? change . content . after . split ( "\n" ) . length : 0
274+ linesRemoved = 0
275+ } else if ( type === "delete" ) {
276+ // Deleted file: all lines are removed
277+ linesAdded = 0
278+ linesRemoved = change . content . before ? change . content . before . split ( "\n" ) . length : 0
279+ } else {
280+ // Modified file: use FileChangeManager's improved calculation method
281+ const lineDifferences = FileChangeManager . calculateLineDifferences (
282+ change . content . before || "" ,
283+ change . content . after || "" ,
284+ )
285+ linesAdded = lineDifferences . linesAdded
286+ linesRemoved = lineDifferences . linesRemoved
287+ }
288+
289+ return {
290+ uri : change . paths . relative ,
291+ type,
292+ fromCheckpoint : currentBaseline , // Reference current baseline for cumulative view
293+ toCheckpoint : toHash , // Current checkpoint for comparison
294+ linesAdded,
295+ linesRemoved,
296+ }
297+ } )
247298
248299 log ( `[Task#checkpointCreated] Found ${ fileChanges . length } cumulative file changes` )
249300
@@ -253,13 +304,13 @@ async function checkGitInstallation(
253304 // DON'T clear accepted/rejected state here - preserve user's accept/reject decisions
254305 // The state should only be cleared on baseline changes (checkpoint restore) or task restart
255306
256- // Get filtered changeset that excludes already accepted/rejected files and only shows LLM-modified files
307+ // Get changeset that excludes already accepted/rejected files and only shows LLM-modified files
257308 const filteredChangeset = await checkpointFileChangeManager . getLLMOnlyChanges (
258309 task . taskId ,
259310 task . fileContextTracker ,
260311 )
261312
262- // Create changeset and send to webview (only LLM-modified, unaccepted files)
313+ // Create changeset and send to webview (unaccepted files)
263314 const serializableChangeset = {
264315 baseCheckpoint : filteredChangeset . baseCheckpoint ,
265316 files : filteredChangeset . files ,
@@ -274,13 +325,13 @@ async function checkGitInstallation(
274325 filesChanged : serializableChangeset ,
275326 } )
276327 } else {
277- log ( `[Task#checkpointCreated] No changes found between ${ initialBaseline } and ${ toHash } ` )
328+ log ( `[Task#checkpointCreated] No changes found between ${ currentBaseline } and ${ toHash } ` )
278329 }
279330
280- // DON'T update the baseline - keep it at initial baseline for cumulative tracking
331+ // DON'T update the baseline - keep it at current baseline for cumulative tracking
281332 // The baseline should only change when explicitly requested (e.g., checkpoint restore)
282333 log (
283- `[Task#checkpointCreated] Keeping FileChangeManager baseline at ${ initialBaseline } for cumulative tracking` ,
334+ `[Task#checkpointCreated] Keeping FileChangeManager baseline at ${ currentBaseline } for cumulative tracking` ,
284335 )
285336 }
286337 } catch ( error ) {
@@ -457,12 +508,14 @@ export async function checkpointRestore(
457508 provider ?. log ( `[checkpointRestore] Cleared accept/reject state for fresh start` )
458509 }
459510
460- // Calculate and send current changes (should be empty immediately after restore)
461- const changes = fileChangeManager . getChanges ( )
462- provider ?. postMessageToWebview ( {
463- type : "filesChanged" ,
464- filesChanged : changes . files . length > 0 ? changes : undefined ,
465- } )
511+ // Calculate and send current changes with LLM-only filtering (should be empty immediately after restore)
512+ if ( cline . taskId && cline . fileContextTracker ) {
513+ const changes = await fileChangeManager . getLLMOnlyChanges ( cline . taskId , cline . fileContextTracker )
514+ provider ?. postMessageToWebview ( {
515+ type : "filesChanged" ,
516+ filesChanged : changes . files . length > 0 ? changes : undefined ,
517+ } )
518+ }
466519 }
467520 } catch ( error ) {
468521 provider ?. log ( `[checkpointRestore] Failed to update FileChangeManager baseline: ${ error } ` )
0 commit comments