diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx
index 2169b1d96e..1dd9301585 100644
--- a/webview-ui/src/components/history/HistoryPreview.tsx
+++ b/webview-ui/src/components/history/HistoryPreview.tsx
@@ -2,6 +2,7 @@ import { memo } from "react"
import { vscode } from "@src/utils/vscode"
import { useAppTranslation } from "@src/i18n/TranslationContext"
+import { useExtensionState } from "@src/context/ExtensionStateContext"
import { useTaskSearch } from "./useTaskSearch"
import TaskItem from "./TaskItem"
@@ -9,11 +10,17 @@ import TaskItem from "./TaskItem"
const HistoryPreview = () => {
const { tasks } = useTaskSearch()
const { t } = useAppTranslation()
+ const { maxTasksHomeScreen } = useExtensionState()
const handleViewAllHistory = () => {
vscode.postMessage({ type: "switchTab", tab: "history" })
}
+ // If maxTasksHomeScreen is 0, don't render anything
+ if (maxTasksHomeScreen === 0) {
+ return null
+ }
+
return (
@@ -27,7 +34,7 @@ const HistoryPreview = () => {
{tasks.length !== 0 && (
<>
- {tasks.slice(0, 4).map((item) => (
+ {tasks.slice(0, maxTasksHomeScreen).map((item) => (
))}
>
diff --git a/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx b/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx
index da344970a8..427f73de6a 100644
--- a/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx
+++ b/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx
@@ -3,8 +3,10 @@ import { render, screen } from "@/utils/test-utils"
import type { HistoryItem } from "@roo-code/types"
import HistoryPreview from "../HistoryPreview"
+import { useExtensionState } from "@/context/ExtensionStateContext"
vi.mock("../useTaskSearch")
+vi.mock("@/context/ExtensionStateContext")
vi.mock("../TaskItem", () => {
return {
@@ -20,6 +22,7 @@ import { useTaskSearch } from "../useTaskSearch"
import TaskItem from "../TaskItem"
const mockUseTaskSearch = useTaskSearch as any
+const mockUseExtensionState = useExtensionState as any
const mockTaskItem = TaskItem as any
const mockTasks: HistoryItem[] = [
@@ -82,6 +85,32 @@ const mockTasks: HistoryItem[] = [
describe("HistoryPreview", () => {
beforeEach(() => {
vi.clearAllMocks()
+ // Default mock for useExtensionState
+ mockUseExtensionState.mockReturnValue({
+ maxTasksHomeScreen: 4,
+ })
+ })
+
+ it("renders nothing when maxTasksHomeScreen is 0", () => {
+ mockUseExtensionState.mockReturnValue({
+ maxTasksHomeScreen: 0,
+ })
+ mockUseTaskSearch.mockReturnValue({
+ tasks: mockTasks,
+ searchQuery: "",
+ setSearchQuery: vi.fn(),
+ sortOption: "newest",
+ setSortOption: vi.fn(),
+ lastNonRelevantSort: null,
+ setLastNonRelevantSort: vi.fn(),
+ showAllWorkspaces: false,
+ setShowAllWorkspaces: vi.fn(),
+ })
+
+ const { container } = render(
)
+
+ // Should render nothing when maxTasksHomeScreen is 0
+ expect(container.firstChild).toBeNull()
})
it("renders nothing when no tasks are available", () => {
@@ -228,4 +257,29 @@ describe("HistoryPreview", () => {
expect(container.firstChild).toHaveClass("flex", "flex-col", "gap-1")
})
+
+ it("respects maxTasksHomeScreen setting", () => {
+ mockUseExtensionState.mockReturnValue({
+ maxTasksHomeScreen: 2,
+ })
+ mockUseTaskSearch.mockReturnValue({
+ tasks: mockTasks,
+ searchQuery: "",
+ setSearchQuery: vi.fn(),
+ sortOption: "newest",
+ setSortOption: vi.fn(),
+ lastNonRelevantSort: null,
+ setLastNonRelevantSort: vi.fn(),
+ showAllWorkspaces: false,
+ setShowAllWorkspaces: vi.fn(),
+ })
+
+ render(
)
+
+ // Should render only the first 2 tasks
+ expect(screen.getByTestId("task-item-task-1")).toBeInTheDocument()
+ expect(screen.getByTestId("task-item-task-2")).toBeInTheDocument()
+ expect(screen.queryByTestId("task-item-task-3")).not.toBeInTheDocument()
+ expect(screen.queryByTestId("task-item-task-4")).not.toBeInTheDocument()
+ })
})
diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx
index 3a9cb539a8..1f8ed5ff0f 100644
--- a/webview-ui/src/components/settings/SettingsView.tsx
+++ b/webview-ui/src/components/settings/SettingsView.tsx
@@ -201,6 +201,7 @@ const SettingsView = forwardRef
(({ onDone, t
openRouterImageApiKey,
openRouterImageGenerationSelectedModel,
reasoningBlockCollapsed,
+ maxTasksHomeScreen,
includeCurrentTime,
includeCurrentCost,
} = cachedState
@@ -393,6 +394,7 @@ const SettingsView = forwardRef(({ onDone, t
condensingApiConfigId: condensingApiConfigId || "",
includeTaskHistoryInEnhance: includeTaskHistoryInEnhance ?? true,
reasoningBlockCollapsed: reasoningBlockCollapsed ?? true,
+ maxTasksHomeScreen: maxTasksHomeScreen ?? 4,
includeCurrentTime: includeCurrentTime ?? true,
includeCurrentCost: includeCurrentCost ?? true,
profileThresholds,
@@ -802,6 +804,7 @@ const SettingsView = forwardRef(({ onDone, t
{activeTab === "ui" && (
)}
diff --git a/webview-ui/src/components/settings/UISettings.tsx b/webview-ui/src/components/settings/UISettings.tsx
index 2de16e6882..1cb3b592a6 100644
--- a/webview-ui/src/components/settings/UISettings.tsx
+++ b/webview-ui/src/components/settings/UISettings.tsx
@@ -1,6 +1,6 @@
import { HTMLAttributes } from "react"
import { useAppTranslation } from "@/i18n/TranslationContext"
-import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
+import { VSCodeCheckbox, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { Glasses } from "lucide-react"
import { telemetryClient } from "@/utils/TelemetryClient"
@@ -11,10 +11,16 @@ import { ExtensionStateContextType } from "@/context/ExtensionStateContext"
interface UISettingsProps extends HTMLAttributes {
reasoningBlockCollapsed: boolean
+ maxTasksHomeScreen: number
setCachedStateField: SetCachedStateField
}
-export const UISettings = ({ reasoningBlockCollapsed, setCachedStateField, ...props }: UISettingsProps) => {
+export const UISettings = ({
+ reasoningBlockCollapsed,
+ maxTasksHomeScreen,
+ setCachedStateField,
+ ...props
+}: UISettingsProps) => {
const { t } = useAppTranslation()
const handleReasoningBlockCollapsedChange = (value: boolean) => {
@@ -26,6 +32,18 @@ export const UISettings = ({ reasoningBlockCollapsed, setCachedStateField, ...pr
})
}
+ const handleMaxTasksHomeScreenChange = (value: string) => {
+ const numValue = parseInt(value, 10)
+ if (!isNaN(numValue) && numValue >= 0 && numValue <= 20) {
+ setCachedStateField("maxTasksHomeScreen", numValue)
+
+ // Track telemetry event
+ telemetryClient.capture("ui_settings_max_tasks_home_screen_changed", {
+ value: numValue,
+ })
+ }
+ }
+
return (
@@ -49,6 +67,26 @@ export const UISettings = ({ reasoningBlockCollapsed, setCachedStateField, ...pr
{t("settings:ui.collapseThinking.description")}
+
+ {/* Maximum Tasks in Home Screen Setting */}
+