fix: address mrubens review on retention types and settings navigation

This commit is contained in:
Hannes Rudolph 2026-01-20 18:58:04 -07:00
parent 56ac6ef9b9
commit 18894daad2
6 changed files with 34 additions and 35 deletions

View file

@ -190,8 +190,7 @@ export const globalSettingsSchema = z.object({
enhancementApiConfigId: z.string().optional(),
includeTaskHistoryInEnhance: z.boolean().optional(),
// Auto-delete task history on extension reload.
// Note: we accept `number` for backwards compatibility with older persisted state.
taskHistoryRetention: z.union([z.enum(TASK_HISTORY_RETENTION_OPTIONS), z.number()]).optional(),
taskHistoryRetention: z.enum(TASK_HISTORY_RETENTION_OPTIONS).optional(),
// Calculated task history storage size info for the Settings > About page
taskHistorySize: z
.object({

View file

@ -105,7 +105,7 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt
return openClineInNewTab({ context, outputChannel })
},
openInNewTab: () => openClineInNewTab({ context, outputChannel }),
settingsButtonClicked: () => {
settingsButtonClicked: (section?: string) => {
const visibleProvider = getVisibleProviderOrLog(outputChannel)
if (!visibleProvider) {
@ -114,7 +114,11 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt
TelemetryService.instance.captureTitleButtonClicked("settings")
visibleProvider.postMessageToWebview({ type: "action", action: "settingsButtonClicked" })
visibleProvider.postMessageToWebview({
type: "action",
action: "settingsButtonClicked",
values: section ? { section } : undefined,
})
// Also explicitly post the visibility message to trigger scroll reliably
visibleProvider.postMessageToWebview({ type: "action", action: "didBecomeVisible" })
},

View file

@ -45,6 +45,7 @@ import {
import { initializeI18n } from "./i18n"
import { flushModels, initializeModelCacheRefresh, refreshModels } from "./api/providers/fetchers/modelCache"
import { startBackgroundRetentionPurge } from "./utils/task-history-retention"
import { TASK_HISTORY_RETENTION_OPTIONS, type TaskHistoryRetentionSetting } from "@roo-code/types"
/**
* Built using https://github.com/microsoft/vscode-webview-ui-toolkit
@ -392,14 +393,11 @@ export async function activate(context: vscode.ExtensionContext) {
// By this point, provider is fully initialized and ready to handle deletions
{
const retentionValue = contextProxy.getValue("taskHistoryRetention")
const retention =
retentionValue === "90" ||
retentionValue === "60" ||
retentionValue === "30" ||
retentionValue === "7" ||
retentionValue === "3"
? retentionValue
: "never"
const retention: TaskHistoryRetentionSetting = TASK_HISTORY_RETENTION_OPTIONS.includes(
retentionValue as TaskHistoryRetentionSetting,
)
? (retentionValue as TaskHistoryRetentionSetting)
: "never"
startBackgroundRetentionPurge({
globalStoragePath: contextProxy.globalStorageUri.fsPath,
log: (m) => outputChannel.appendLine(m),

View file

@ -3,21 +3,13 @@ import * as path from "path"
import * as fs from "fs/promises"
import type { Dirent } from "fs"
import { TASK_HISTORY_RETENTION_OPTIONS, type TaskHistoryRetentionSetting } from "@roo-code/types"
import { getStorageBasePath } from "./storage"
import { GlobalFileNames } from "../shared/globalFileNames"
import { t } from "../i18n"
/**
* Allowed retention day values (as numbers).
*/
export type RetentionDays = 90 | 60 | 30 | 7 | 3
/**
* Supported values for the retention setting.
* - "never" or 0 disables purging
* - "90" | "60" | "30" | "7" | "3" (string) or 90 | 60 | 30 | 7 | 3 (number) specify days
*/
export type RetentionSetting = "never" | "0" | `${RetentionDays}` | RetentionDays | 0
export type RetentionSetting = TaskHistoryRetentionSetting
export type PurgeResult = {
purgedCount: number
@ -280,7 +272,7 @@ export async function purgeOldTasks(
*/
function normalizeDays(value: RetentionSetting): number {
if (value === "never") return 0
const n = typeof value === "number" ? value : parseInt(String(value), 10)
const n = parseInt(value, 10)
return Number.isFinite(n) && n > 0 ? Math.trunc(n) : 0
}
@ -314,11 +306,16 @@ export function startBackgroundRetentionPurge(options: BackgroundPurgeOptions):
void (async () => {
try {
// Skip if retention is disabled
if (retention === "never" || retention === "0" || retention === 0) {
if (retention === "never") {
log("[Retention] Background purge skipped: retention is set to 'never'")
return
}
if (!TASK_HISTORY_RETENTION_OPTIONS.includes(retention)) {
log(`[Retention] Background purge skipped: invalid retention value '${retention}'`)
return
}
log(`[Retention] Starting background purge: setting=${retention}`)
const result = await purgeOldTasks(retention, globalStoragePath, log, false, deleteTaskById)
@ -340,7 +337,7 @@ export function startBackgroundRetentionPurge(options: BackgroundPurgeOptions):
vscode.window.showInformationMessage(message, viewSettingsLabel, dismissLabel).then((action) => {
if (action === viewSettingsLabel) {
// Navigate to Roo Code settings About tab
vscode.commands.executeCommand("roo-cline.settingsButtonClicked")
vscode.commands.executeCommand("roo-cline.settingsButtonClicked", "about")
}
})
}

View file

@ -1,4 +1,4 @@
import { HTMLAttributes, useState, useCallback, useEffect } from "react"
import { HTMLAttributes, useState, useCallback, useEffect, useRef } from "react"
import { useAppTranslation } from "@/i18n/TranslationContext"
import { Trans } from "react-i18next"
import {
@ -58,6 +58,7 @@ export const About = ({
const { t } = useAppTranslation()
const [isRefreshing, setIsRefreshing] = useState(false)
const [cachedSize, setCachedSize] = useState<TaskHistorySize | undefined>(taskHistorySize)
const didRequestInitialSize = useRef(false)
// Update cached size when taskHistorySize changes and reset refreshing state
useEffect(() => {
@ -67,6 +68,13 @@ export const About = ({
}
}, [taskHistorySize])
// Trigger initial task history size calculation when this tab mounts
useEffect(() => {
if (didRequestInitialSize.current) return
didRequestInitialSize.current = true
vscode.postMessage({ type: "refreshTaskHistorySize" })
}, [])
const handleRefreshStorageSize = useCallback(() => {
setIsRefreshing(true)
vscode.postMessage({ type: "refreshTaskHistorySize" })

View file

@ -429,7 +429,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
includeCurrentTime: includeCurrentTime ?? true,
includeCurrentCost: includeCurrentCost ?? true,
maxGitStatusFiles: maxGitStatusFiles ?? 0,
taskHistoryRetention: normalizedTaskHistoryRetention,
taskHistoryRetention: normalizedTaskHistoryRetention,
profileThresholds,
imageGenerationProvider,
openRouterImageApiKey,
@ -566,13 +566,6 @@ taskHistoryRetention: normalizedTaskHistoryRetention,
scrollToActiveTab()
}, [activeTab, scrollToActiveTab])
// Effect to trigger task history size calculation when About tab is opened
useEffect(() => {
if (activeTab === "about") {
vscode.postMessage({ type: "refreshTaskHistorySize" })
}
}, [activeTab])
// Effect to scroll when the webview becomes visible
useLayoutEffect(() => {
const handleMessage = (event: MessageEvent) => {