@@ -160,44 +160,80 @@ export function getCheckpointService(cline: Task) {
160160 try {
161161 const checkpointFileChangeManager = provider ?. getFileChangeManager ( )
162162 if ( checkpointFileChangeManager ) {
163- // Get the initial baseline (preserve for cumulative diff tracking)
164- let initialBaseline = checkpointFileChangeManager . getChanges ( ) . baseCheckpoint
163+ // Get the current baseline for cumulative tracking
164+ let currentBaseline = checkpointFileChangeManager . getChanges ( ) . baseCheckpoint
165165
166- // Validate that the baseline exists in the shadow repository before attempting diff
167- // If the baseline doesn't exist (e.g., from a previous task session), fall back to shadow repo base
166+ // For cumulative tracking, we want to calculate from baseline to new checkpoint
167+ // But if this is the first time or baseline is invalid, update it to fromHash
168168 try {
169- await service . getDiff ( { from : initialBaseline , to : initialBaseline } )
169+ await service . getDiff ( { from : currentBaseline , to : currentBaseline } )
170+ log (
171+ `[Task#checkpointCreated] Using existing baseline ${ currentBaseline } for cumulative tracking` ,
172+ )
170173 } catch ( baselineValidationError ) {
171- const shadowBase = service . baseHash || toHash
174+ // Baseline is invalid, use fromHash as the new baseline for cumulative tracking
172175 log (
173- `[Task#checkpointCreated] Initial baseline ${ initialBaseline } not found in shadow repo, falling back to shadow base ${ shadowBase } ` ,
176+ `[Task#checkpointCreated] Baseline validation failed for ${ currentBaseline } : ${ baselineValidationError instanceof Error ? baselineValidationError . message : String ( baselineValidationError ) } ` ,
174177 )
175- initialBaseline = shadowBase
176- // Update FileChangeManager baseline to match shadow repository
177- await checkpointFileChangeManager . updateBaseline ( initialBaseline )
178+ log ( `[Task#checkpointCreated] Updating baseline to fromHash: ${ fromHash } ` )
179+ currentBaseline = fromHash
180+ // Update FileChangeManager baseline to match
181+ try {
182+ await checkpointFileChangeManager . updateBaseline ( currentBaseline )
183+ log ( `[Task#checkpointCreated] Successfully updated baseline to ${ currentBaseline } ` )
184+ } catch ( updateError ) {
185+ log (
186+ `[Task#checkpointCreated] Failed to update baseline: ${ updateError instanceof Error ? updateError . message : String ( updateError ) } ` ,
187+ )
188+ throw updateError
189+ }
178190 }
179191
180192 log (
181- `[Task#checkpointCreated] Calculating cumulative changes from validated baseline ${ initialBaseline } to ${ toHash } ` ,
193+ `[Task#checkpointCreated] Calculating cumulative changes from baseline ${ currentBaseline } to ${ toHash } ` ,
182194 )
183195
184- // Calculate cumulative diff from validated baseline to new checkpoint using checkpoint service
185- const changes = await service . getDiff ( { from : initialBaseline , to : toHash } )
196+ // Calculate cumulative diff from baseline to new checkpoint using checkpoint service
197+ const changes = await service . getDiff ( { from : currentBaseline , to : toHash } )
186198
187199 if ( changes && changes . length > 0 ) {
188200 // Convert to FileChange format with correct checkpoint references
189- const fileChanges = changes . map ( ( change : any ) => ( {
190- uri : change . paths . relative ,
191- type : ( change . paths . newFile
192- ? "create"
193- : change . paths . deletedFile
194- ? "delete"
195- : "edit" ) as FileChangeType ,
196- fromCheckpoint : initialBaseline , // Always reference initial baseline for cumulative view
197- toCheckpoint : toHash , // Current checkpoint for comparison
198- linesAdded : change . content . after ? change . content . after . split ( "\n" ) . length : 0 ,
199- linesRemoved : change . content . before ? change . content . before . split ( "\n" ) . length : 0 ,
200- } ) )
201+ const fileChanges = changes . map ( ( change : any ) => {
202+ const type = (
203+ change . paths . newFile ? "create" : change . paths . deletedFile ? "delete" : "edit"
204+ ) as FileChangeType
205+
206+ // Calculate actual line differences for the change
207+ let linesAdded = 0
208+ let linesRemoved = 0
209+
210+ if ( type === "create" ) {
211+ // New file: all lines are added
212+ linesAdded = change . content . after ? change . content . after . split ( "\n" ) . length : 0
213+ linesRemoved = 0
214+ } else if ( type === "delete" ) {
215+ // Deleted file: all lines are removed
216+ linesAdded = 0
217+ linesRemoved = change . content . before ? change . content . before . split ( "\n" ) . length : 0
218+ } else {
219+ // Modified file: use FileChangeManager's improved calculation method
220+ const lineDifferences = FileChangeManager . calculateLineDifferences (
221+ change . content . before || "" ,
222+ change . content . after || "" ,
223+ )
224+ linesAdded = lineDifferences . linesAdded
225+ linesRemoved = lineDifferences . linesRemoved
226+ }
227+
228+ return {
229+ uri : change . paths . relative ,
230+ type,
231+ fromCheckpoint : currentBaseline , // Reference current baseline for cumulative view
232+ toCheckpoint : toHash , // Current checkpoint for comparison
233+ linesAdded,
234+ linesRemoved,
235+ }
236+ } )
201237
202238 log ( `[Task#checkpointCreated] Found ${ fileChanges . length } cumulative file changes` )
203239
@@ -228,13 +264,13 @@ export function getCheckpointService(cline: Task) {
228264 filesChanged : serializableChangeset ,
229265 } )
230266 } else {
231- log ( `[Task#checkpointCreated] No changes found between ${ initialBaseline } and ${ toHash } ` )
267+ log ( `[Task#checkpointCreated] No changes found between ${ currentBaseline } and ${ toHash } ` )
232268 }
233269
234- // DON'T update the baseline - keep it at initial baseline for cumulative tracking
270+ // DON'T update the baseline - keep it at current baseline for cumulative tracking
235271 // The baseline should only change when explicitly requested (e.g., checkpoint restore)
236272 log (
237- `[Task#checkpointCreated] Keeping FileChangeManager baseline at ${ initialBaseline } for cumulative tracking` ,
273+ `[Task#checkpointCreated] Keeping FileChangeManager baseline at ${ currentBaseline } for cumulative tracking` ,
238274 )
239275 }
240276 } catch ( error ) {
@@ -419,12 +455,14 @@ export async function checkpointRestore(cline: Task, { ts, commitHash, mode }: C
419455 provider ?. log ( `[checkpointRestore] Cleared accept/reject state for fresh start` )
420456 }
421457
422- // Calculate and send current changes (should be empty immediately after restore)
423- const changes = fileChangeManager . getChanges ( )
424- provider ?. postMessageToWebview ( {
425- type : "filesChanged" ,
426- filesChanged : changes . files . length > 0 ? changes : undefined ,
427- } )
458+ // Calculate and send current changes with LLM-only filtering (should be empty immediately after restore)
459+ if ( cline . taskId && cline . fileContextTracker ) {
460+ const changes = await fileChangeManager . getLLMOnlyChanges ( cline . taskId , cline . fileContextTracker )
461+ provider ?. postMessageToWebview ( {
462+ type : "filesChanged" ,
463+ filesChanged : changes . files . length > 0 ? changes : undefined ,
464+ } )
465+ }
428466 }
429467 } catch ( error ) {
430468 provider ?. log ( `[checkpointRestore] Failed to update FileChangeManager baseline: ${ error } ` )
0 commit comments