@@ -16,18 +16,29 @@ import { DIFF_VIEW_URI_SCHEME } from "../../integrations/editor/DiffViewProvider
1616
1717import { CheckpointServiceOptions , RepoPerTaskCheckpointService } from "../../services/checkpoints"
1818
19- export function getCheckpointService ( cline : Task ) {
19+ export async function getCheckpointService (
20+ cline : Task ,
21+ { interval = 250 , timeout = 15_000 } : { interval ?: number ; timeout ?: number } = { } ,
22+ ) {
2023 if ( ! cline . enableCheckpoints ) {
2124 return undefined
2225 }
2326
2427 if ( cline . checkpointService ) {
25- return cline . checkpointService
26- }
27-
28- if ( cline . checkpointServiceInitializing ) {
29- console . log ( "[Task#getCheckpointService] checkpoint service is still initializing" )
30- return undefined
28+ if ( cline . checkpointServiceInitializing ) {
29+ console . log ( "[Task#getCheckpointService] checkpoint service is still initializing" )
30+ const service = cline . checkpointService
31+ await pWaitFor (
32+ ( ) => {
33+ console . log ( "[Task#getCheckpointService] waiting for service to initialize" )
34+ return service . isInitialized
35+ } ,
36+ { interval, timeout } ,
37+ )
38+ return service . isInitialized ? cline . checkpointService : undefined
39+ } else {
40+ return cline . checkpointService
41+ }
3142 }
3243
3344 const provider = cline . providerRef . deref ( )
@@ -69,15 +80,20 @@ export function getCheckpointService(cline: Task) {
6980 }
7081
7182 const service = RepoPerTaskCheckpointService . create ( options )
72-
7383 cline . checkpointServiceInitializing = true
7484
7585 // Check if Git is installed before initializing the service
76- // Note: This is intentionally fire-and-forget to match the original IIFE pattern
77- // The service is returned immediately while Git check happens asynchronously
78- checkGitInstallation ( cline , service , log , provider )
79-
80- return service
86+ // Only assign the service after successful initialization
87+ try {
88+ await checkGitInstallation ( cline , service , log , provider )
89+ cline . checkpointService = service
90+ return service
91+ } catch ( err ) {
92+ // Clean up on failure
93+ cline . checkpointServiceInitializing = false
94+ cline . enableCheckpoints = false
95+ throw err
96+ }
8197 } catch ( err ) {
8298 log ( `[Task#getCheckpointService] ${ err . message } ` )
8399 cline . enableCheckpoints = false
@@ -115,22 +131,7 @@ async function checkGitInstallation(
115131 // Git is installed, proceed with initialization
116132 service . on ( "initialize" , ( ) => {
117133 log ( "[Task#getCheckpointService] service initialized" )
118-
119- try {
120- const isCheckpointNeeded =
121- typeof cline . clineMessages . find ( ( { say } ) => say === "checkpoint_saved" ) === "undefined"
122-
123- cline . checkpointService = service
124- cline . checkpointServiceInitializing = false
125-
126- if ( isCheckpointNeeded ) {
127- log ( "[Task#getCheckpointService] no checkpoints found, saving initial checkpoint" )
128- checkpointSave ( cline )
129- }
130- } catch ( err ) {
131- log ( "[Task#getCheckpointService] caught error in on('initialize'), disabling checkpoints" )
132- cline . enableCheckpoints = false
133- }
134+ cline . checkpointServiceInitializing = false
134135 } )
135136
136137 service . on ( "checkpoint" , ( { isFirst, fromHash : from , toHash : to } ) => {
@@ -153,11 +154,12 @@ async function checkGitInstallation(
153154 } )
154155
155156 log ( "[Task#getCheckpointService] initializing shadow git" )
156-
157- service . initShadowGit ( ) . catch ( ( err ) => {
157+ try {
158+ await service . initShadowGit ( )
159+ } catch ( err ) {
158160 log ( `[Task#getCheckpointService] initShadowGit -> ${ err . message } ` )
159161 cline . enableCheckpoints = false
160- } )
162+ }
161163 } catch ( err ) {
162164 log ( `[Task#getCheckpointService] Unexpected error during Git check: ${ err . message } ` )
163165 console . error ( "Git check error:" , err )
@@ -166,33 +168,8 @@ async function checkGitInstallation(
166168 }
167169}
168170
169- async function getInitializedCheckpointService (
170- cline : Task ,
171- { interval = 250 , timeout = 15_000 } : { interval ?: number ; timeout ?: number } = { } ,
172- ) {
173- const service = getCheckpointService ( cline )
174-
175- if ( ! service || service . isInitialized ) {
176- return service
177- }
178-
179- try {
180- await pWaitFor (
181- ( ) => {
182- console . log ( "[Task#getCheckpointService] waiting for service to initialize" )
183- return service . isInitialized
184- } ,
185- { interval, timeout } ,
186- )
187-
188- return service
189- } catch ( err ) {
190- return undefined
191- }
192- }
193-
194171export async function checkpointSave ( cline : Task , force = false ) {
195- const service = getCheckpointService ( cline )
172+ const service = await getCheckpointService ( cline )
196173
197174 if ( ! service ) {
198175 return
@@ -221,7 +198,7 @@ export type CheckpointRestoreOptions = {
221198}
222199
223200export async function checkpointRestore ( cline : Task , { ts, commitHash, mode } : CheckpointRestoreOptions ) {
224- const service = await getInitializedCheckpointService ( cline )
201+ const service = await getCheckpointService ( cline )
225202
226203 if ( ! service ) {
227204 return
@@ -289,25 +266,27 @@ export type CheckpointDiffOptions = {
289266}
290267
291268export async function checkpointDiff ( cline : Task , { ts, previousCommitHash, commitHash, mode } : CheckpointDiffOptions ) {
292- const service = await getInitializedCheckpointService ( cline )
269+ const service = await getCheckpointService ( cline )
293270
294271 if ( ! service ) {
295272 return
296273 }
297274
298275 TelemetryService . instance . captureCheckpointDiffed ( cline . taskId )
299276
300- if ( ! previousCommitHash && mode === "checkpoint" ) {
301- const previousCheckpoint = cline . clineMessages
302- . filter ( ( { say } ) => say === "checkpoint_saved" )
303- . sort ( ( a , b ) => b . ts - a . ts )
304- . find ( ( message ) => message . ts < ts )
277+ let prevHash = commitHash
278+ let nextHash : string | undefined
305279
306- previousCommitHash = previousCheckpoint ?. text
280+ const checkpoints = typeof service . getCheckpoints === "function" ? service . getCheckpoints ( ) : [ ]
281+ const idx = checkpoints . indexOf ( commitHash )
282+ if ( idx !== - 1 && idx < checkpoints . length - 1 ) {
283+ nextHash = checkpoints [ idx + 1 ]
284+ } else {
285+ nextHash = undefined
307286 }
308287
309288 try {
310- const changes = await service . getDiff ( { from : previousCommitHash , to : commitHash } )
289+ const changes = await service . getDiff ( { from : prevHash , to : nextHash } )
311290
312291 if ( ! changes ?. length ) {
313292 vscode . window . showInformationMessage ( "No changes found." )
0 commit comments