@@ -2208,33 +2208,51 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
22082208 } > {
22092209 const history = ( ( await this . getGlobalState ( "taskHistory" ) ) as HistoryItem [ ] | undefined ) || [ ]
22102210 const historyItem = history . find ( ( item ) => item . id === id )
2211- if ( historyItem ) {
2212- const taskDirPath = path . join ( this . contextProxy . globalStorageUri . fsPath , "tasks" , id )
2213- const apiConversationHistoryFilePath = path . join ( taskDirPath , GlobalFileNames . apiConversationHistory )
2214- const uiMessagesFilePath = path . join ( taskDirPath , GlobalFileNames . uiMessages )
2215- const fileExists = await fileExistsAtPath ( apiConversationHistoryFilePath )
2216- if ( fileExists ) {
2217- const apiConversationHistory = JSON . parse ( await fs . readFile ( apiConversationHistoryFilePath , "utf8" ) )
2218- return {
2219- historyItem,
2220- taskDirPath,
2221- apiConversationHistoryFilePath,
2222- uiMessagesFilePath,
2223- apiConversationHistory,
2224- }
2225- }
2211+ if ( ! historyItem ) {
2212+ throw new Error ( "Task not found in history" )
2213+ }
2214+
2215+ const taskDirPath = path . join ( this . contextProxy . globalStorageUri . fsPath , "tasks" , id )
2216+ const apiConversationHistoryFilePath = path . join ( taskDirPath , GlobalFileNames . apiConversationHistory )
2217+ const uiMessagesFilePath = path . join ( taskDirPath , GlobalFileNames . uiMessages )
2218+
2219+ const fileExists = await fileExistsAtPath ( apiConversationHistoryFilePath )
2220+ if ( ! fileExists ) {
2221+ // Instead of silently deleting, throw a specific error
2222+ throw new Error ( "TASK_FILES_MISSING" )
2223+ }
2224+
2225+ const apiConversationHistory = JSON . parse ( await fs . readFile ( apiConversationHistoryFilePath , "utf8" ) )
2226+ return {
2227+ historyItem,
2228+ taskDirPath,
2229+ apiConversationHistoryFilePath,
2230+ uiMessagesFilePath,
2231+ apiConversationHistory,
22262232 }
2227- // if we tried to get a task that doesn't exist, remove it from state
2228- // FIXME: this seems to happen sometimes when the json file doesnt save to disk for some reason
2229- await this . deleteTaskFromState ( id )
2230- throw new Error ( "Task not found" )
22312233 }
22322234
22332235 async showTaskWithId ( id : string ) {
22342236 if ( id !== this . getCurrentCline ( ) ?. taskId ) {
2235- // Non-current task.
2236- const { historyItem } = await this . getTaskWithId ( id )
2237- await this . initClineWithHistoryItem ( historyItem ) // Clears existing task.
2237+ try {
2238+ const { historyItem } = await this . getTaskWithId ( id )
2239+ await this . initClineWithHistoryItem ( historyItem )
2240+ } catch ( error ) {
2241+ if ( error . message === "TASK_FILES_MISSING" ) {
2242+ const response = await vscode . window . showWarningMessage (
2243+ "This task's files are missing. Would you like to remove it from the task list?" ,
2244+ "Remove" ,
2245+ "Keep" ,
2246+ )
2247+
2248+ if ( response === "Remove" ) {
2249+ await this . deleteTaskFromState ( id )
2250+ await this . postStateToWebview ( )
2251+ }
2252+ return
2253+ }
2254+ throw error
2255+ }
22382256 }
22392257
22402258 await this . postMessageToWebview ( { type : "action" , action : "chatButtonClicked" } )
@@ -2702,4 +2720,30 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
27022720
27032721 return properties
27042722 }
2723+
2724+ async validateTaskHistory ( ) {
2725+ const history = ( ( await this . getGlobalState ( "taskHistory" ) ) as HistoryItem [ ] | undefined ) || [ ]
2726+ const validTasks : HistoryItem [ ] = [ ]
2727+
2728+ for ( const item of history ) {
2729+ const taskDirPath = path . join ( this . contextProxy . globalStorageUri . fsPath , "tasks" , item . id )
2730+ const apiConversationHistoryFilePath = path . join ( taskDirPath , GlobalFileNames . apiConversationHistory )
2731+
2732+ if ( await fileExistsAtPath ( apiConversationHistoryFilePath ) ) {
2733+ validTasks . push ( item )
2734+ }
2735+ }
2736+
2737+ if ( validTasks . length !== history . length ) {
2738+ await this . updateGlobalState ( "taskHistory" , validTasks )
2739+ await this . postStateToWebview ( )
2740+
2741+ const removedCount = history . length - validTasks . length
2742+ if ( removedCount > 0 ) {
2743+ await vscode . window . showInformationMessage (
2744+ `Cleaned up ${ removedCount } task(s) with missing files from history.` ,
2745+ )
2746+ }
2747+ }
2748+ }
27052749}
0 commit comments