Просмотр исходного кода

added task no indicator + improved deleteTask code

ShayBC 10 месяцев назад
Родитель
Сommit
01765995ad

+ 13 - 0
src/core/Cline.ts

@@ -75,6 +75,7 @@ type UserContent = Array<
 
 export class Cline {
 	readonly taskId: string
+	private taskNumber: number
 	// a flag that indicated if this Cline instance is a subtask (on finish return control to parent task)
 	private isSubTask: boolean = false
 	// a flag that indicated if this Cline instance is paused (waiting for provider to resume it after subtask completion)
@@ -139,6 +140,7 @@ export class Cline {
 		}
 
 		this.taskId = crypto.randomUUID()
+		this.taskNumber = -1
 		this.api = buildApiHandler(apiConfiguration)
 		this.terminalManager = new TerminalManager()
 		this.urlContentFetcher = new UrlContentFetcher(provider.context)
@@ -170,6 +172,16 @@ export class Cline {
 		this.isSubTask = true
 	}
 
+	// sets the task number (sequencial number of this task from all the subtask ran from this main task stack)
+	setTaskNumber(taskNumber: number) {
+		this.taskNumber = taskNumber
+	}
+
+	// gets the task number, the sequencial number of this task from all the subtask ran from this main task stack
+	getTaskNumber() {
+		return this.taskNumber
+	}
+
 	// Add method to update diffStrategy
 	async updateDiffStrategy(experimentalDiffStrategy?: boolean) {
 		// If not provided, get from current state
@@ -276,6 +288,7 @@ export class Cline {
 
 			await this.providerRef.deref()?.updateTaskHistory({
 				id: this.taskId,
+				number: this.taskNumber,
 				ts: lastRelevantMessage.ts,
 				task: taskMessage.text ?? "",
 				tokensIn: apiMetrics.totalTokensIn,

+ 1 - 0
src/core/__tests__/Cline.test.ts

@@ -222,6 +222,7 @@ describe("Cline", () => {
 						return [
 							{
 								id: "123",
+								number: 0,
 								ts: Date.now(),
 								task: "historical task",
 								tokensIn: 100,

+ 35 - 37
src/core/webview/ClineProvider.ts

@@ -153,6 +153,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 	private latestAnnouncementId = "jan-21-2025-custom-modes" // update to some unique identifier when we add a new announcement
 	configManager: ConfigManager
 	customModesManager: CustomModesManager
+	private lastTaskNumber = -1
 
 	constructor(
 		readonly context: vscode.ExtensionContext,
@@ -180,6 +181,17 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 	// The instance is pushed to the top of the stack (LIFO order).
 	// When the task is completed, the top instance is removed, reactivating the previous task.
 	addClineToStack(cline: Cline): void {
+		// if cline.getTaskNumber() is -1, it means it is a new task
+		if (cline.getTaskNumber() === -1) {
+			// increase last cline number by 1
+			this.lastTaskNumber = this.lastTaskNumber + 1
+			cline.setTaskNumber(this.lastTaskNumber)
+		}
+		// if cline.getTaskNumber() > lastTaskNumber, set lastTaskNumber to cline.getTaskNumber()
+		else if (cline.getTaskNumber() > this.lastTaskNumber) {
+			this.lastTaskNumber = cline.getTaskNumber()
+		}
+		// push the cline instance to the stack
 		this.clineStack.push(cline)
 	}
 
@@ -192,6 +204,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			// make sure no reference kept, once promises end it will be garbage collected
 			clineToBeRemoved = undefined
 		}
+		// if the stack is empty, reset the last task number
+		if (this.clineStack.length === 0) {
+			this.lastTaskNumber = -1
+		}
 	}
 
 	// remove the cline object with the received clineId, and all the cline objects bove it in the stack
@@ -520,6 +536,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			historyItem,
 			experiments,
 		)
+		// get this cline task number id from the history item and set it to newCline
+		newCline.setTaskNumber(historyItem.number)
 		this.addClineToStack(newCline)
 	}
 
@@ -2384,38 +2402,25 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 		await downloadTask(historyItem.ts, apiConversationHistory)
 	}
 
+	// this function deletes a task from task hidtory, and deletes it's checkpoints and delete the task folder
 	async deleteTaskWithId(id: string) {
+		// get the task directory full path
+		const { taskDirPath } = await this.getTaskWithId(id)
+
+		// remove task from stack if it's the current task
 		if (id === this.getCurrentCline()?.taskId) {
 			await this.removeClineWithIdFromStack(id)
 		}
 
-		const { taskDirPath, apiConversationHistoryFilePath, uiMessagesFilePath } = await this.getTaskWithId(id)
-
+		// delete task from the task history state
 		await this.deleteTaskFromState(id)
 
-		// Delete the task files.
-		const apiConversationHistoryFileExists = await fileExistsAtPath(apiConversationHistoryFilePath)
-
-		if (apiConversationHistoryFileExists) {
-			await fs.unlink(apiConversationHistoryFilePath)
-		}
-
-		const uiMessagesFileExists = await fileExistsAtPath(uiMessagesFilePath)
-
-		if (uiMessagesFileExists) {
-			await fs.unlink(uiMessagesFilePath)
-		}
-
-		const legacyMessagesFilePath = path.join(taskDirPath, "claude_messages.json")
-
-		if (await fileExistsAtPath(legacyMessagesFilePath)) {
-			await fs.unlink(legacyMessagesFilePath)
-		}
-
+		// check if checkpoints are enabled
 		const { checkpointsEnabled } = await this.getState()
+		// get the base directory of the project
 		const baseDir = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0)
 
-		// Delete checkpoints branch.
+		// delete checkpoints branch from project git repo
 		if (checkpointsEnabled && baseDir) {
 			const branchSummary = await simpleGit(baseDir)
 				.branch(["-D", `roo-code-checkpoints-${id}`])
@@ -2426,22 +2431,15 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			}
 		}
 
-		// Delete checkpoints directory
-		const checkpointsDir = path.join(taskDirPath, "checkpoints")
-
-		if (await fileExistsAtPath(checkpointsDir)) {
-			try {
-				await fs.rm(checkpointsDir, { recursive: true, force: true })
-				console.log(`[deleteTaskWithId${id}] removed checkpoints repo`)
-			} catch (error) {
-				console.error(
-					`[deleteTaskWithId${id}] failed to remove checkpoints repo: ${error instanceof Error ? error.message : String(error)}`,
-				)
-			}
+		// delete the entire task directory including checkpoints and all content
+		try {
+			await fs.rm(taskDirPath, { recursive: true, force: true })
+			console.log(`[deleteTaskWithId${id}] removed task directory`)
+		} catch (error) {
+			console.error(
+				`[deleteTaskWithId${id}] failed to remove task directory: ${error instanceof Error ? error.message : String(error)}`,
+			)
 		}
-
-		// Succeeds if the dir is empty.
-		await fs.rmdir(taskDirPath)
 	}
 
 	async deleteTaskFromState(id: string) {

+ 1 - 0
src/shared/HistoryItem.ts

@@ -1,5 +1,6 @@
 export type HistoryItem = {
 	id: string
+	number: number
 	ts: number
 	task: string
 	tokensIn: number

+ 4 - 1
webview-ui/src/components/chat/TaskHeader.tsx

@@ -158,7 +158,10 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
 								flexGrow: 1,
 								minWidth: 0, // This allows the div to shrink below its content size
 							}}>
-							<span style={{ fontWeight: "bold" }}>Task{!isTaskExpanded && ":"}</span>
+							<span style={{ fontWeight: "bold" }}>
+								Task ({currentTaskItem?.number === 0 ? "Main" : currentTaskItem.number})
+								{!isTaskExpanded && ":"}
+							</span>
 							{!isTaskExpanded && (
 								<span style={{ marginLeft: 4 }}>{highlightMentions(task.text, false)}</span>
 							)}

+ 6 - 0
webview-ui/src/components/history/HistoryPreview.tsx

@@ -120,6 +120,12 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => {
 										}}>
 										{formatDate(item.ts)}
 									</span>
+									<span
+										style={{
+											marginLeft: "auto",
+										}}>
+										({item.number === 0 ? "Main" : item.number})
+									</span>
 									<button
 										title="Copy Prompt"
 										aria-label="Copy Prompt"

+ 2 - 0
webview-ui/src/components/history/__tests__/HistoryView.test.tsx

@@ -23,6 +23,7 @@ jest.mock("react-virtuoso", () => ({
 const mockTaskHistory = [
 	{
 		id: "1",
+		number: 0,
 		task: "Test task 1",
 		ts: new Date("2022-02-16T00:00:00").getTime(),
 		tokensIn: 100,
@@ -31,6 +32,7 @@ const mockTaskHistory = [
 	},
 	{
 		id: "2",
+		number: 0,
 		task: "Test task 2",
 		ts: new Date("2022-02-17T00:00:00").getTime(),
 		tokensIn: 200,