Skip to content

Commit fa0c4e5

Browse files
authored
Add delete all task history button (RooCodeInc#2163)
* Add delete all task history button * Add changeset * Add error message if deleting tasks fails
1 parent 59dc92c commit fa0c4e5

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

.changeset/three-apples-add.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": patch
3+
---
4+
5+
Add delete all tasks button

src/core/webview/ClineProvider.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,12 @@ export class ClineProvider implements vscode.WebviewViewProvider {
915915
await this.postMessageToWebview({ type: "didUpdateSettings" })
916916
break
917917
}
918+
case "clearAllTaskHistory": {
919+
await this.deleteAllTaskHistory()
920+
await this.postStateToWebview()
921+
this.postMessageToWebview({ type: "relinquishControl" })
922+
break
923+
}
918924
// Add more switch case statements here as more webview message commands
919925
// are created within the webview context (i.e. inside media/main.js)
920926
}
@@ -1751,6 +1757,28 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
17511757
await downloadTask(historyItem.ts, apiConversationHistory)
17521758
}
17531759

1760+
async deleteAllTaskHistory() {
1761+
await this.clearTask()
1762+
await this.updateGlobalState("taskHistory", undefined)
1763+
try {
1764+
// Remove all contents of tasks directory
1765+
const taskDirPath = path.join(this.context.globalStorageUri.fsPath, "tasks")
1766+
if (await fileExistsAtPath(taskDirPath)) {
1767+
await fs.rm(taskDirPath, { recursive: true, force: true })
1768+
}
1769+
// Remove checkpoints directory contents
1770+
const checkpointsDirPath = path.join(this.context.globalStorageUri.fsPath, "checkpoints")
1771+
if (await fileExistsAtPath(checkpointsDirPath)) {
1772+
await fs.rm(checkpointsDirPath, { recursive: true, force: true })
1773+
}
1774+
} catch (error) {
1775+
vscode.window.showErrorMessage(
1776+
`Encountered error while deleting task history, there may be some files left behind. Error: ${error instanceof Error ? error.message : String(error)}`,
1777+
)
1778+
}
1779+
// await this.postStateToWebview()
1780+
}
1781+
17541782
async deleteTaskWithId(id: string) {
17551783
console.info("deleteTaskWithId: ", id)
17561784

@@ -1831,7 +1859,10 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
18311859
currentTaskItem: this.cline?.taskId ? (taskHistory || []).find((item) => item.id === this.cline?.taskId) : undefined,
18321860
checkpointTrackerErrorMessage: this.cline?.checkpointTrackerErrorMessage,
18331861
clineMessages: this.cline?.clineMessages || [],
1834-
taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts),
1862+
taskHistory: (taskHistory || [])
1863+
.filter((item) => item.ts && item.task)
1864+
.sort((a, b) => b.ts - a.ts)
1865+
.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?)
18351866
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
18361867
platform: process.platform as Platform,
18371868
autoApprovalSettings,

src/shared/WebviewMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export interface WebviewMessage {
6060
| "checkIsImageUrl"
6161
| "invoke"
6262
| "updateSettings"
63+
| "clearAllTaskHistory"
6364
// | "relaunchChromeDebugMode"
6465
text?: string
6566
disabled?: boolean

webview-ui/src/components/history/HistoryView.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ import { VSCodeButton, VSCodeTextField, VSCodeRadioGroup, VSCodeRadio } from "@v
22
import { useExtensionState } from "../../context/ExtensionStateContext"
33
import { vscode } from "../../utils/vscode"
44
import { Virtuoso } from "react-virtuoso"
5-
import { memo, useMemo, useState, useEffect } from "react"
5+
import { memo, useMemo, useState, useEffect, useCallback } from "react"
66
import Fuse, { FuseResult } from "fuse.js"
77
import { formatLargeNumber } from "../../utils/format"
88
import { formatSize } from "../../utils/size"
9+
import DangerButton from "../common/DangerButton"
10+
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
11+
import { useEvent } from "react-use"
912

1013
type HistoryViewProps = {
1114
onDone: () => void
@@ -18,6 +21,15 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
1821
const [searchQuery, setSearchQuery] = useState("")
1922
const [sortOption, setSortOption] = useState<SortOption>("newest")
2023
const [lastNonRelevantSort, setLastNonRelevantSort] = useState<SortOption | null>("newest")
24+
const [deleteAllDisabled, setDeleteAllDisabled] = useState(false)
25+
26+
const handleMessage = useCallback((event: MessageEvent<ExtensionMessage>) => {
27+
if (event.data.type === "relinquishControl") {
28+
setDeleteAllDisabled(false)
29+
}
30+
}, [])
31+
32+
useEvent("message", handleMessage)
2133

2234
useEffect(() => {
2335
if (searchQuery && sortOption !== "mostRelevant" && !lastNonRelevantSort) {
@@ -447,6 +459,21 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
447459
)}
448460
/>
449461
</div>
462+
<div
463+
style={{
464+
padding: "10px 10px",
465+
borderTop: "1px solid var(--vscode-panel-border)",
466+
}}>
467+
<DangerButton
468+
style={{ width: "100%" }}
469+
disabled={deleteAllDisabled}
470+
onClick={() => {
471+
setDeleteAllDisabled(true)
472+
vscode.postMessage({ type: "clearAllTaskHistory" })
473+
}}>
474+
Delete All History
475+
</DangerButton>
476+
</div>
450477
</div>
451478
</>
452479
)

0 commit comments

Comments
 (0)