diff --git a/.changeset/three-apples-add.md b/.changeset/three-apples-add.md new file mode 100644 index 0000000000..cd4ad3a94a --- /dev/null +++ b/.changeset/three-apples-add.md @@ -0,0 +1,5 @@ +--- +"claude-dev": patch +--- + +Add delete all tasks button diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 93c61000ba..dc929436f8 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -915,6 +915,12 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.postMessageToWebview({ type: "didUpdateSettings" }) break } + case "clearAllTaskHistory": { + await this.deleteAllTaskHistory() + await this.postStateToWebview() + this.postMessageToWebview({ type: "relinquishControl" }) + break + } // Add more switch case statements here as more webview message commands // are created within the webview context (i.e. inside media/main.js) } @@ -1751,6 +1757,28 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont await downloadTask(historyItem.ts, apiConversationHistory) } + async deleteAllTaskHistory() { + await this.clearTask() + await this.updateGlobalState("taskHistory", undefined) + try { + // Remove all contents of tasks directory + const taskDirPath = path.join(this.context.globalStorageUri.fsPath, "tasks") + if (await fileExistsAtPath(taskDirPath)) { + await fs.rm(taskDirPath, { recursive: true, force: true }) + } + // Remove checkpoints directory contents + const checkpointsDirPath = path.join(this.context.globalStorageUri.fsPath, "checkpoints") + if (await fileExistsAtPath(checkpointsDirPath)) { + await fs.rm(checkpointsDirPath, { recursive: true, force: true }) + } + } catch (error) { + vscode.window.showErrorMessage( + `Encountered error while deleting task history, there may be some files left behind. Error: ${error instanceof Error ? error.message : String(error)}`, + ) + } + // await this.postStateToWebview() + } + async deleteTaskWithId(id: string) { console.info("deleteTaskWithId: ", id) @@ -1831,7 +1859,10 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont currentTaskItem: this.cline?.taskId ? (taskHistory || []).find((item) => item.id === this.cline?.taskId) : undefined, checkpointTrackerErrorMessage: this.cline?.checkpointTrackerErrorMessage, clineMessages: this.cline?.clineMessages || [], - taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts), + taskHistory: (taskHistory || []) + .filter((item) => item.ts && item.task) + .sort((a, b) => b.ts - a.ts) + .slice(0, 100), // for now we're only getting the latest 100 tasks, but a better solution here is to only pass in 3 for recent task history, and then get the full task history on demand when going to the task history view (maybe with pagination?) shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId, platform: process.platform as Platform, autoApprovalSettings, diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index caf488f243..09192120ae 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -60,6 +60,7 @@ export interface WebviewMessage { | "checkIsImageUrl" | "invoke" | "updateSettings" + | "clearAllTaskHistory" // | "relaunchChromeDebugMode" text?: string disabled?: boolean diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index d50b4b39db..709e5d42a6 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -2,10 +2,13 @@ import { VSCodeButton, VSCodeTextField, VSCodeRadioGroup, VSCodeRadio } from "@v import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import { Virtuoso } from "react-virtuoso" -import { memo, useMemo, useState, useEffect } from "react" +import { memo, useMemo, useState, useEffect, useCallback } from "react" import Fuse, { FuseResult } from "fuse.js" import { formatLargeNumber } from "../../utils/format" import { formatSize } from "../../utils/size" +import DangerButton from "../common/DangerButton" +import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" +import { useEvent } from "react-use" type HistoryViewProps = { onDone: () => void @@ -18,6 +21,15 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { const [searchQuery, setSearchQuery] = useState("") const [sortOption, setSortOption] = useState("newest") const [lastNonRelevantSort, setLastNonRelevantSort] = useState("newest") + const [deleteAllDisabled, setDeleteAllDisabled] = useState(false) + + const handleMessage = useCallback((event: MessageEvent) => { + if (event.data.type === "relinquishControl") { + setDeleteAllDisabled(false) + } + }, []) + + useEvent("message", handleMessage) useEffect(() => { if (searchQuery && sortOption !== "mostRelevant" && !lastNonRelevantSort) { @@ -447,6 +459,21 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { )} /> +
+ { + setDeleteAllDisabled(true) + vscode.postMessage({ type: "clearAllTaskHistory" }) + }}> + Delete All History + +
)