Bläddra i källkod

Add todo list tool enable checkbox to provider advanced settings (#6032)

Co-authored-by: Roo Code <[email protected]>
Co-authored-by: Daniel Riccio <[email protected]>
Co-authored-by: Matt Rubens <[email protected]>
roomote[bot] 5 månader sedan
förälder
incheckning
b1bc085aa6
42 ändrade filer med 402 tillägg och 5 borttagningar
  1. 1 0
      packages/types/src/provider-settings.ts
  2. 21 0
      src/core/config/ProviderSettingsManager.ts
  3. 43 0
      src/core/config/__tests__/ProviderSettingsManager.spec.ts
  4. 2 0
      src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap
  5. 2 0
      src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap
  6. 2 0
      src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap
  7. 2 0
      src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap
  8. 2 0
      src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap
  9. 2 0
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap
  10. 2 0
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap
  11. 2 0
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap
  12. 2 0
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap
  13. 2 0
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap
  14. 2 0
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap
  15. 2 0
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap
  16. 89 1
      src/core/prompts/__tests__/system-prompt.spec.ts
  17. 1 1
      src/core/prompts/sections/custom-instructions.ts
  18. 2 2
      src/core/prompts/system.ts
  19. 5 0
      src/core/prompts/tools/index.ts
  20. 1 1
      src/shared/modes.ts
  21. 5 0
      webview-ui/src/components/settings/ApiOptions.tsx
  22. 35 0
      webview-ui/src/components/settings/TodoListSettingsControl.tsx
  23. 26 0
      webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx
  24. 77 0
      webview-ui/src/components/settings/__tests__/TodoListSettingsControl.spec.tsx
  25. 4 0
      webview-ui/src/i18n/locales/ca/settings.json
  26. 4 0
      webview-ui/src/i18n/locales/de/settings.json
  27. 4 0
      webview-ui/src/i18n/locales/en/settings.json
  28. 4 0
      webview-ui/src/i18n/locales/es/settings.json
  29. 4 0
      webview-ui/src/i18n/locales/fr/settings.json
  30. 4 0
      webview-ui/src/i18n/locales/hi/settings.json
  31. 4 0
      webview-ui/src/i18n/locales/id/settings.json
  32. 4 0
      webview-ui/src/i18n/locales/it/settings.json
  33. 4 0
      webview-ui/src/i18n/locales/ja/settings.json
  34. 4 0
      webview-ui/src/i18n/locales/ko/settings.json
  35. 4 0
      webview-ui/src/i18n/locales/nl/settings.json
  36. 4 0
      webview-ui/src/i18n/locales/pl/settings.json
  37. 4 0
      webview-ui/src/i18n/locales/pt-BR/settings.json
  38. 4 0
      webview-ui/src/i18n/locales/ru/settings.json
  39. 4 0
      webview-ui/src/i18n/locales/tr/settings.json
  40. 4 0
      webview-ui/src/i18n/locales/vi/settings.json
  41. 4 0
      webview-ui/src/i18n/locales/zh-CN/settings.json
  42. 4 0
      webview-ui/src/i18n/locales/zh-TW/settings.json

+ 1 - 0
packages/types/src/provider-settings.ts

@@ -61,6 +61,7 @@ export const DEFAULT_CONSECUTIVE_MISTAKE_LIMIT = 3
 const baseProviderSettingsSchema = z.object({
 	includeMaxTokens: z.boolean().optional(),
 	diffEnabled: z.boolean().optional(),
+	todoListEnabled: z.boolean().optional(),
 	fuzzyMatchThreshold: z.number().optional(),
 	modelTemperature: z.number().nullish(),
 	rateLimitSeconds: z.number().optional(),

+ 21 - 0
src/core/config/ProviderSettingsManager.ts

@@ -28,6 +28,7 @@ export const providerProfilesSchema = z.object({
 			diffSettingsMigrated: z.boolean().optional(),
 			openAiHeadersMigrated: z.boolean().optional(),
 			consecutiveMistakeLimitMigrated: z.boolean().optional(),
+			todoListEnabledMigrated: z.boolean().optional(),
 		})
 		.optional(),
 })
@@ -51,6 +52,7 @@ export class ProviderSettingsManager {
 			diffSettingsMigrated: true, // Mark as migrated on fresh installs
 			openAiHeadersMigrated: true, // Mark as migrated on fresh installs
 			consecutiveMistakeLimitMigrated: true, // Mark as migrated on fresh installs
+			todoListEnabledMigrated: true, // Mark as migrated on fresh installs
 		},
 	}
 
@@ -117,6 +119,7 @@ export class ProviderSettingsManager {
 						diffSettingsMigrated: false,
 						openAiHeadersMigrated: false,
 						consecutiveMistakeLimitMigrated: false,
+						todoListEnabledMigrated: false,
 					} // Initialize with default values
 					isDirty = true
 				}
@@ -145,6 +148,12 @@ export class ProviderSettingsManager {
 					isDirty = true
 				}
 
+				if (!providerProfiles.migrations.todoListEnabledMigrated) {
+					await this.migrateTodoListEnabled(providerProfiles)
+					providerProfiles.migrations.todoListEnabledMigrated = true
+					isDirty = true
+				}
+
 				if (isDirty) {
 					await this.store(providerProfiles)
 				}
@@ -250,6 +259,18 @@ export class ProviderSettingsManager {
 		}
 	}
 
+	private async migrateTodoListEnabled(providerProfiles: ProviderProfiles) {
+		try {
+			for (const [_name, apiConfig] of Object.entries(providerProfiles.apiConfigs)) {
+				if (apiConfig.todoListEnabled === undefined) {
+					apiConfig.todoListEnabled = true
+				}
+			}
+		} catch (error) {
+			console.error(`[MigrateTodoListEnabled] Failed to migrate todo list enabled setting:`, error)
+		}
+	}
+
 	/**
 	 * List all available configs with metadata.
 	 */

+ 43 - 0
src/core/config/__tests__/ProviderSettingsManager.spec.ts

@@ -67,6 +67,7 @@ describe("ProviderSettingsManager", () => {
 						diffSettingsMigrated: true,
 						openAiHeadersMigrated: true,
 						consecutiveMistakeLimitMigrated: true,
+						todoListEnabledMigrated: true,
 					},
 				}),
 			)
@@ -186,6 +187,48 @@ describe("ProviderSettingsManager", () => {
 			expect(storedConfig.migrations.consecutiveMistakeLimitMigrated).toEqual(true)
 		})
 
+		it("should call migrateTodoListEnabled if it has not done so already", async () => {
+			mockSecrets.get.mockResolvedValue(
+				JSON.stringify({
+					currentApiConfigName: "default",
+					apiConfigs: {
+						default: {
+							config: {},
+							id: "default",
+							todoListEnabled: undefined,
+						},
+						test: {
+							apiProvider: "anthropic",
+							todoListEnabled: undefined,
+						},
+						existing: {
+							apiProvider: "anthropic",
+							// this should not really be possible, unless someone has loaded a hand edited config,
+							// but we don't overwrite so we'll check that
+							todoListEnabled: false,
+						},
+					},
+					migrations: {
+						rateLimitSecondsMigrated: true,
+						diffSettingsMigrated: true,
+						openAiHeadersMigrated: true,
+						consecutiveMistakeLimitMigrated: true,
+						todoListEnabledMigrated: false,
+					},
+				}),
+			)
+
+			await providerSettingsManager.initialize()
+
+			// Get the last call to store, which should contain the migrated config
+			const calls = mockSecrets.store.mock.calls
+			const storedConfig = JSON.parse(calls[calls.length - 1][1])
+			expect(storedConfig.apiConfigs.default.todoListEnabled).toEqual(true)
+			expect(storedConfig.apiConfigs.test.todoListEnabled).toEqual(true)
+			expect(storedConfig.apiConfigs.existing.todoListEnabled).toEqual(false)
+			expect(storedConfig.migrations.todoListEnabledMigrated).toEqual(true)
+		})
+
 		it("should throw error if secrets storage fails", async () => {
 			mockSecrets.get.mockRejectedValue(new Error("Storage failed"))
 

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap

@@ -555,6 +555,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap

@@ -555,6 +555,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap

@@ -623,6 +623,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap

@@ -560,6 +560,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap

@@ -555,6 +555,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap

@@ -611,6 +611,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap

@@ -555,6 +555,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap

@@ -643,6 +643,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap

@@ -555,6 +555,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap

@@ -611,6 +611,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap

@@ -623,6 +623,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 2 - 0
src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap

@@ -555,6 +555,8 @@ Mode-specific Instructions:
    - Focused on a single, well-defined outcome
    - Clear enough that another mode could execute it independently
 
+   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.
+
 4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
 5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.

+ 89 - 1
src/core/prompts/__tests__/system-prompt.spec.ts

@@ -79,7 +79,7 @@ __setMockImplementation(
 		globalCustomInstructions: string,
 		cwd: string,
 		mode: string,
-		options?: { language?: string },
+		options?: { language?: string; rooIgnoreInstructions?: string; settings?: Record<string, any> },
 	) => {
 		const sections = []
 
@@ -575,6 +575,94 @@ describe("SYSTEM_PROMPT", () => {
 		expect(prompt.indexOf(modes[0].roleDefinition)).toBeLessThan(prompt.indexOf("TOOL USE"))
 	})
 
+	it("should exclude update_todo_list tool when todoListEnabled is false", async () => {
+		const settings = {
+			todoListEnabled: false,
+		}
+
+		const prompt = await SYSTEM_PROMPT(
+			mockContext,
+			"/test/path",
+			false, // supportsComputerUse
+			undefined, // mcpHub
+			undefined, // diffStrategy
+			undefined, // browserViewportSize
+			defaultModeSlug, // mode
+			undefined, // customModePrompts
+			undefined, // customModes
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			experiments,
+			true, // enableMcpServerCreation
+			undefined, // language
+			undefined, // rooIgnoreInstructions
+			undefined, // partialReadsEnabled
+			settings, // settings
+		)
+
+		// Should not contain the tool description
+		expect(prompt).not.toContain("## update_todo_list")
+		// Mode instructions will still reference the tool with a fallback to markdown
+	})
+
+	it("should include update_todo_list tool when todoListEnabled is true", async () => {
+		const settings = {
+			todoListEnabled: true,
+		}
+
+		const prompt = await SYSTEM_PROMPT(
+			mockContext,
+			"/test/path",
+			false, // supportsComputerUse
+			undefined, // mcpHub
+			undefined, // diffStrategy
+			undefined, // browserViewportSize
+			defaultModeSlug, // mode
+			undefined, // customModePrompts
+			undefined, // customModes
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			experiments,
+			true, // enableMcpServerCreation
+			undefined, // language
+			undefined, // rooIgnoreInstructions
+			undefined, // partialReadsEnabled
+			settings, // settings
+		)
+
+		expect(prompt).toContain("update_todo_list")
+		expect(prompt).toContain("## update_todo_list")
+	})
+
+	it("should include update_todo_list tool when todoListEnabled is undefined", async () => {
+		const settings = {
+			// todoListEnabled not set
+		}
+
+		const prompt = await SYSTEM_PROMPT(
+			mockContext,
+			"/test/path",
+			false, // supportsComputerUse
+			undefined, // mcpHub
+			undefined, // diffStrategy
+			undefined, // browserViewportSize
+			defaultModeSlug, // mode
+			undefined, // customModePrompts
+			undefined, // customModes
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			experiments,
+			true, // enableMcpServerCreation
+			undefined, // language
+			undefined, // rooIgnoreInstructions
+			undefined, // partialReadsEnabled
+			settings, // settings
+		)
+
+		expect(prompt).toContain("update_todo_list")
+		expect(prompt).toContain("## update_todo_list")
+	})
+
 	afterAll(() => {
 		vi.restoreAllMocks()
 	})

+ 1 - 1
src/core/prompts/sections/custom-instructions.ts

@@ -219,7 +219,7 @@ export async function addCustomInstructions(
 	globalCustomInstructions: string,
 	cwd: string,
 	mode: string,
-	options: { language?: string; rooIgnoreInstructions?: string } = {},
+	options: { language?: string; rooIgnoreInstructions?: string; settings?: Record<string, any> } = {},
 ): Promise<string> {
 	const sections = []
 

+ 2 - 2
src/core/prompts/system.ts

@@ -119,7 +119,7 @@ ${getSystemInfoSection(cwd)}
 
 ${getObjectiveSection(codeIndexManager, experiments)}
 
-${await addCustomInstructions(baseInstructions, globalCustomInstructions || "", cwd, mode, { language: language ?? formatLanguage(vscode.env.language), rooIgnoreInstructions })}`
+${await addCustomInstructions(baseInstructions, globalCustomInstructions || "", cwd, mode, { language: language ?? formatLanguage(vscode.env.language), rooIgnoreInstructions, settings })}`
 
 	return basePrompt
 }
@@ -177,7 +177,7 @@ export const SYSTEM_PROMPT = async (
 			globalCustomInstructions || "",
 			cwd,
 			mode,
-			{ language: language ?? formatLanguage(vscode.env.language), rooIgnoreInstructions },
+			{ language: language ?? formatLanguage(vscode.env.language), rooIgnoreInstructions, settings },
 		)
 
 		// For file-based prompts, don't include the tool sections

+ 5 - 0
src/core/prompts/tools/index.ts

@@ -109,6 +109,11 @@ export function getToolDescriptionsForMode(
 		tools.delete("codebase_search")
 	}
 
+	// Conditionally exclude update_todo_list if disabled in settings
+	if (settings?.todoListEnabled === false) {
+		tools.delete("update_todo_list")
+	}
+
 	// Map tool descriptions for allowed tools
 	const descriptions = Array.from(tools).map((toolName) => {
 		const descriptionFn = toolDescriptionMap[toolName]

+ 1 - 1
src/shared/modes.ts

@@ -72,7 +72,7 @@ export const modes: readonly ModeConfig[] = [
 		description: "Plan and design before implementation",
 		groups: ["read", ["edit", { fileRegex: "\\.md$", description: "Markdown files only" }], "browser", "mcp"],
 		customInstructions:
-			"1. Do some information gathering (using provided tools) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:\n   - Specific and actionable\n   - Listed in logical execution order\n   - Focused on a single, well-defined outcome\n   - Clear enough that another mode could execute it independently\n\n4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.\n\n5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.\n\n6. Include Mermaid diagrams if they help clarify complex workflows or system architecture. Please avoid using double quotes (\"\") and parentheses () inside square brackets ([]) in Mermaid diagrams, as this can cause parsing errors.\n\n7. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**",
+			"1. Do some information gathering (using provided tools) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:\n   - Specific and actionable\n   - Listed in logical execution order\n   - Focused on a single, well-defined outcome\n   - Clear enough that another mode could execute it independently\n\n   **Note:** If the `update_todo_list` tool is not available, write the plan to a markdown file (e.g., `plan.md` or `todo.md`) instead.\n\n4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.\n\n5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list.\n\n6. Include Mermaid diagrams if they help clarify complex workflows or system architecture. Please avoid using double quotes (\"\") and parentheses () inside square brackets ([]) in Mermaid diagrams, as this can cause parsing errors.\n\n7. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**",
 	},
 	{
 		slug: "code",

+ 5 - 0
webview-ui/src/components/settings/ApiOptions.tsx

@@ -78,6 +78,7 @@ import { ModelInfoView } from "./ModelInfoView"
 import { ApiErrorMessage } from "./ApiErrorMessage"
 import { ThinkingBudget } from "./ThinkingBudget"
 import { DiffSettingsControl } from "./DiffSettingsControl"
+import { TodoListSettingsControl } from "./TodoListSettingsControl"
 import { TemperatureControl } from "./TemperatureControl"
 import { RateLimitSecondsControl } from "./RateLimitSecondsControl"
 import { ConsecutiveMistakeLimitControl } from "./ConsecutiveMistakeLimitControl"
@@ -564,6 +565,10 @@ const ApiOptions = ({
 						<span className="font-medium">{t("settings:advancedSettings.title")}</span>
 					</CollapsibleTrigger>
 					<CollapsibleContent className="space-y-3">
+						<TodoListSettingsControl
+							todoListEnabled={apiConfiguration.todoListEnabled}
+							onChange={(field, value) => setApiConfigurationField(field, value)}
+						/>
 						<DiffSettingsControl
 							diffEnabled={apiConfiguration.diffEnabled}
 							fuzzyMatchThreshold={apiConfiguration.fuzzyMatchThreshold}

+ 35 - 0
webview-ui/src/components/settings/TodoListSettingsControl.tsx

@@ -0,0 +1,35 @@
+import React, { useCallback } from "react"
+import { useAppTranslation } from "@/i18n/TranslationContext"
+import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
+
+interface TodoListSettingsControlProps {
+	todoListEnabled?: boolean
+	onChange: (field: "todoListEnabled", value: any) => void
+}
+
+export const TodoListSettingsControl: React.FC<TodoListSettingsControlProps> = ({
+	todoListEnabled = true,
+	onChange,
+}) => {
+	const { t } = useAppTranslation()
+
+	const handleTodoListEnabledChange = useCallback(
+		(e: any) => {
+			onChange("todoListEnabled", e.target.checked)
+		},
+		[onChange],
+	)
+
+	return (
+		<div className="flex flex-col gap-1">
+			<div>
+				<VSCodeCheckbox checked={todoListEnabled} onChange={handleTodoListEnabledChange}>
+					<span className="font-medium">{t("settings:advanced.todoList.label")}</span>
+				</VSCodeCheckbox>
+				<div className="text-vscode-descriptionForeground text-sm">
+					{t("settings:advanced.todoList.description")}
+				</div>
+			</div>
+		</div>
+	)
+}

+ 26 - 0
webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx

@@ -21,6 +21,16 @@ vi.mock("@vscode/webview-ui-toolkit/react", () => ({
 	VSCodeRadio: ({ value, checked }: any) => <input type="radio" value={value} checked={checked} />,
 	VSCodeRadioGroup: ({ children }: any) => <div>{children}</div>,
 	VSCodeButton: ({ children }: any) => <div>{children}</div>,
+	VSCodeCheckbox: ({ children, checked, onChange }: any) => (
+		<label>
+			<input
+				type="checkbox"
+				checked={checked}
+				onChange={(e) => onChange && onChange({ target: { checked: e.target.checked } })}
+			/>
+			{children}
+		</label>
+	),
 }))
 
 // Mock other components
@@ -173,6 +183,22 @@ vi.mock("../DiffSettingsControl", () => ({
 	),
 }))
 
+// Mock TodoListSettingsControl for tests
+vi.mock("../TodoListSettingsControl", () => ({
+	TodoListSettingsControl: ({ todoListEnabled, onChange }: any) => (
+		<div data-testid="todo-list-settings-control">
+			<label>
+				Enable todo list tool
+				<input
+					type="checkbox"
+					checked={todoListEnabled}
+					onChange={(e) => onChange("todoListEnabled", e.target.checked)}
+				/>
+			</label>
+		</div>
+	),
+}))
+
 // Mock ThinkingBudget component
 vi.mock("../ThinkingBudget", () => ({
 	ThinkingBudget: ({ modelInfo }: any) => {

+ 77 - 0
webview-ui/src/components/settings/__tests__/TodoListSettingsControl.spec.tsx

@@ -0,0 +1,77 @@
+import React from "react"
+import { render, screen, fireEvent } from "@testing-library/react"
+import { describe, it, expect, vi } from "vitest"
+import { TodoListSettingsControl } from "../TodoListSettingsControl"
+
+// Mock the translation hook
+vi.mock("@/i18n/TranslationContext", () => ({
+	useAppTranslation: () => ({
+		t: (key: string) => {
+			const translations: Record<string, string> = {
+				"settings:advanced.todoList.label": "Enable todo list tool",
+				"settings:advanced.todoList.description":
+					"When enabled, Roo can create and manage todo lists to track task progress. This helps organize complex tasks into manageable steps.",
+			}
+			return translations[key] || key
+		},
+	}),
+}))
+
+// Mock VSCodeCheckbox
+vi.mock("@vscode/webview-ui-toolkit/react", () => ({
+	VSCodeCheckbox: ({ children, onChange, checked, ...props }: any) => (
+		<label>
+			<input
+				type="checkbox"
+				checked={checked}
+				onChange={(e) => onChange({ target: { checked: e.target.checked } })}
+				{...props}
+			/>
+			{children}
+		</label>
+	),
+}))
+
+describe("TodoListSettingsControl", () => {
+	it("renders with default props", () => {
+		const onChange = vi.fn()
+		render(<TodoListSettingsControl onChange={onChange} />)
+
+		const checkbox = screen.getByRole("checkbox")
+		const label = screen.getByText("Enable todo list tool")
+		const description = screen.getByText(/When enabled, Roo can create and manage todo lists/)
+
+		expect(checkbox).toBeInTheDocument()
+		expect(checkbox).toBeChecked() // Default is true
+		expect(label).toBeInTheDocument()
+		expect(description).toBeInTheDocument()
+	})
+
+	it("renders with todoListEnabled set to false", () => {
+		const onChange = vi.fn()
+		render(<TodoListSettingsControl todoListEnabled={false} onChange={onChange} />)
+
+		const checkbox = screen.getByRole("checkbox")
+		expect(checkbox).not.toBeChecked()
+	})
+
+	it("calls onChange when checkbox is clicked", () => {
+		const onChange = vi.fn()
+		render(<TodoListSettingsControl todoListEnabled={true} onChange={onChange} />)
+
+		const checkbox = screen.getByRole("checkbox")
+		fireEvent.click(checkbox)
+
+		expect(onChange).toHaveBeenCalledWith("todoListEnabled", false)
+	})
+
+	it("toggles from unchecked to checked", () => {
+		const onChange = vi.fn()
+		render(<TodoListSettingsControl todoListEnabled={false} onChange={onChange} />)
+
+		const checkbox = screen.getByRole("checkbox")
+		fireEvent.click(checkbox)
+
+		expect(onChange).toHaveBeenCalledWith("todoListEnabled", true)
+	})
+})

+ 4 - 0
webview-ui/src/i18n/locales/ca/settings.json

@@ -577,6 +577,10 @@
 				"label": "Precisió de coincidència",
 				"description": "Aquest control lliscant controla amb quina precisió han de coincidir les seccions de codi en aplicar diffs. Valors més baixos permeten coincidències més flexibles però augmenten el risc de reemplaçaments incorrectes. Utilitzeu valors per sota del 100% amb extrema precaució."
 			}
+		},
+		"todoList": {
+			"label": "Habilitar eina de llista de tasques",
+			"description": "Quan està habilitat, Roo pot crear i gestionar llistes de tasques per fer el seguiment del progrés de les tasques. Això ajuda a organitzar tasques complexes en passos manejables."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/de/settings.json

@@ -577,6 +577,10 @@
 				"label": "Übereinstimmungspräzision",
 				"description": "Dieser Schieberegler steuert, wie genau Codeabschnitte bei der Anwendung von Diffs übereinstimmen müssen. Niedrigere Werte ermöglichen eine flexiblere Übereinstimmung, erhöhen aber das Risiko falscher Ersetzungen. Verwenden Sie Werte unter 100 % mit äußerster Vorsicht."
 			}
+		},
+		"todoList": {
+			"label": "Todo-Listen-Tool aktivieren",
+			"description": "Wenn aktiviert, kann Roo Todo-Listen erstellen und verwalten, um den Aufgabenfortschritt zu verfolgen. Dies hilft, komplexe Aufgaben in überschaubare Schritte zu organisieren."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/en/settings.json

@@ -577,6 +577,10 @@
 				"label": "Match precision",
 				"description": "This slider controls how precisely code sections must match when applying diffs. Lower values allow more flexible matching but increase the risk of incorrect replacements. Use values below 100% with extreme caution."
 			}
+		},
+		"todoList": {
+			"label": "Enable todo list tool",
+			"description": "When enabled, Roo can create and manage todo lists to track task progress. This helps organize complex tasks into manageable steps."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/es/settings.json

@@ -577,6 +577,10 @@
 				"label": "Precisión de coincidencia",
 				"description": "Este control deslizante controla cuán precisamente deben coincidir las secciones de código al aplicar diffs. Valores más bajos permiten coincidencias más flexibles pero aumentan el riesgo de reemplazos incorrectos. Use valores por debajo del 100% con extrema precaución."
 			}
+		},
+		"todoList": {
+			"label": "Habilitar herramienta de lista de tareas",
+			"description": "Cuando está habilitado, Roo puede crear y gestionar listas de tareas para hacer seguimiento del progreso. Esto ayuda a organizar tareas complejas en pasos manejables."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/fr/settings.json

@@ -577,6 +577,10 @@
 				"label": "Précision de correspondance",
 				"description": "Ce curseur contrôle la précision avec laquelle les sections de code doivent correspondre lors de l'application des diffs. Des valeurs plus basses permettent des correspondances plus flexibles mais augmentent le risque de remplacements incorrects. Utilisez des valeurs inférieures à 100 % avec une extrême prudence."
 			}
+		},
+		"todoList": {
+			"label": "Activer l'outil de liste de tâches",
+			"description": "Lorsqu'activé, Roo peut créer et gérer des listes de tâches pour suivre la progression. Cela aide à organiser les tâches complexes en étapes gérables."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/hi/settings.json

@@ -577,6 +577,10 @@
 				"label": "मिलान सटीकता",
 				"description": "यह स्लाइडर नियंत्रित करता है कि diffs लागू करते समय कोड अनुभागों को कितनी सटीकता से मेल खाना चाहिए। निम्न मान अधिक लचीले मिलान की अनुमति देते हैं लेकिन गलत प्रतिस्थापन का जोखिम बढ़ाते हैं। 100% से नीचे के मानों का उपयोग अत्यधिक सावधानी के साथ करें।"
 			}
+		},
+		"todoList": {
+			"label": "टूडू सूची टूल सक्षम करें",
+			"description": "जब सक्षम हो, तो Roo कार्य प्रगति को ट्रैक करने के लिए टूडू सूचियाँ बना और प्रबंधित कर सकता है। यह जटिल कार्यों को प्रबंधनीय चरणों में व्यवस्थित करने में मदद करता है।"
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/id/settings.json

@@ -581,6 +581,10 @@
 				"label": "Presisi pencocokan",
 				"description": "Slider ini mengontrol seberapa tepat bagian kode harus cocok saat menerapkan diff. Nilai yang lebih rendah memungkinkan pencocokan yang lebih fleksibel tetapi meningkatkan risiko penggantian yang salah. Gunakan nilai di bawah 100% dengan sangat hati-hati."
 			}
+		},
+		"todoList": {
+			"label": "Aktifkan alat daftar tugas",
+			"description": "Saat diaktifkan, Roo dapat membuat dan mengelola daftar tugas untuk melacak kemajuan tugas. Ini membantu mengatur tugas kompleks menjadi langkah-langkah yang dapat dikelola."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/it/settings.json

@@ -577,6 +577,10 @@
 				"label": "Precisione corrispondenza",
 				"description": "Questo cursore controlla quanto precisamente le sezioni di codice devono corrispondere quando si applicano i diff. Valori più bassi consentono corrispondenze più flessibili ma aumentano il rischio di sostituzioni errate. Usa valori inferiori al 100% con estrema cautela."
 			}
+		},
+		"todoList": {
+			"label": "Abilita strumento lista di cose da fare",
+			"description": "Quando abilitato, Roo può creare e gestire liste di cose da fare per tracciare il progresso delle attività. Questo aiuta a organizzare attività complesse in passaggi gestibili."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/ja/settings.json

@@ -577,6 +577,10 @@
 				"label": "マッチ精度",
 				"description": "このスライダーは、diffを適用する際にコードセクションがどれだけ正確に一致する必要があるかを制御します。低い値はより柔軟なマッチングを可能にしますが、誤った置換のリスクが高まります。100%未満の値は細心の注意を払って使用してください。"
 			}
+		},
+		"todoList": {
+			"label": "ToDoリストツールを有効にする",
+			"description": "有効にすると、Rooはタスクの進捗を追跡するためのToDoリストを作成・管理できます。これにより、複雑なタスクを管理しやすいステップに整理できます。"
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/ko/settings.json

@@ -577,6 +577,10 @@
 				"label": "일치 정확도",
 				"description": "이 슬라이더는 diff를 적용할 때 코드 섹션이 얼마나 정확하게 일치해야 하는지 제어합니다. 낮은 값은 더 유연한 일치를 허용하지만 잘못된 교체 위험이 증가합니다. 100% 미만의 값은 극도로 주의해서 사용하세요."
 			}
+		},
+		"todoList": {
+			"label": "할 일 목록 도구 활성화",
+			"description": "활성화하면 Roo가 작업 진행 상황을 추적하기 위한 할 일 목록을 만들고 관리할 수 있습니다. 이는 복잡한 작업을 관리 가능한 단계로 구성하는 데 도움이 됩니다."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/nl/settings.json

@@ -577,6 +577,10 @@
 				"label": "Matchnauwkeurigheid",
 				"description": "Deze schuifregelaar bepaalt hoe nauwkeurig codeblokken moeten overeenkomen bij het toepassen van diffs. Lagere waarden laten flexibelere matching toe maar verhogen het risico op verkeerde vervangingen. Gebruik waarden onder 100% met uiterste voorzichtigheid."
 			}
+		},
+		"todoList": {
+			"label": "Takenlijst-tool inschakelen",
+			"description": "Wanneer ingeschakeld, kan Roo takenlijsten maken en beheren om de voortgang van taken bij te houden. Dit helpt complexe taken te organiseren in beheersbare stappen."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/pl/settings.json

@@ -577,6 +577,10 @@
 				"label": "Precyzja dopasowania",
 				"description": "Ten suwak kontroluje, jak dokładnie sekcje kodu muszą pasować podczas stosowania różnic. Niższe wartości umożliwiają bardziej elastyczne dopasowywanie, ale zwiększają ryzyko nieprawidłowych zamian. Używaj wartości poniżej 100% z najwyższą ostrożnością."
 			}
+		},
+		"todoList": {
+			"label": "Włącz narzędzie listy zadań",
+			"description": "Po włączeniu Roo może tworzyć i zarządzać listami zadań do śledzenia postępu zadań. Pomaga to organizować złożone zadania w łatwe do zarządzania kroki."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/pt-BR/settings.json

@@ -577,6 +577,10 @@
 				"label": "Precisão de correspondência",
 				"description": "Este controle deslizante controla quão precisamente as seções de código devem corresponder ao aplicar diffs. Valores mais baixos permitem correspondências mais flexíveis, mas aumentam o risco de substituições incorretas. Use valores abaixo de 100% com extrema cautela."
 			}
+		},
+		"todoList": {
+			"label": "Habilitar ferramenta de lista de tarefas",
+			"description": "Quando habilitado, o Roo pode criar e gerenciar listas de tarefas para acompanhar o progresso das tarefas. Isso ajuda a organizar tarefas complexas em etapas gerenciáveis."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/ru/settings.json

@@ -577,6 +577,10 @@
 				"label": "Точность совпадения",
 				"description": "Этот ползунок управляет точностью совпадения секций кода при применении диффов. Меньшие значения позволяют более гибкое совпадение, но увеличивают риск неверной замены. Используйте значения ниже 100% с осторожностью."
 			}
+		},
+		"todoList": {
+			"label": "Включить инструмент списка задач",
+			"description": "При включении Roo может создавать и управлять списками задач для отслеживания прогресса. Это помогает организовать сложные задачи в управляемые шаги."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/tr/settings.json

@@ -577,6 +577,10 @@
 				"label": "Eşleşme hassasiyeti",
 				"description": "Bu kaydırıcı, diff'ler uygulanırken kod bölümlerinin ne kadar hassas bir şekilde eşleşmesi gerektiğini kontrol eder. Daha düşük değerler daha esnek eşleşmeye izin verir ancak yanlış değiştirme riskini artırır. %100'ün altındaki değerleri son derece dikkatli kullanın."
 			}
+		},
+		"todoList": {
+			"label": "Yapılacaklar listesi aracını etkinleştir",
+			"description": "Etkinleştirildiğinde, Roo görev ilerlemesini takip etmek için yapılacaklar listeleri oluşturabilir ve yönetebilir. Bu, karmaşık görevleri yönetilebilir adımlara organize etmeye yardımcı olur."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/vi/settings.json

@@ -577,6 +577,10 @@
 				"label": "Độ chính xác khớp",
 				"description": "Thanh trượt này kiểm soát mức độ chính xác các phần mã phải khớp khi áp dụng diff. Giá trị thấp hơn cho phép khớp linh hoạt hơn nhưng tăng nguy cơ thay thế không chính xác. Sử dụng giá trị dưới 100% với sự thận trọng cao."
 			}
+		},
+		"todoList": {
+			"label": "Bật công cụ danh sách việc cần làm",
+			"description": "Khi được bật, Roo có thể tạo và quản lý danh sách việc cần làm để theo dõi tiến độ công việc. Điều này giúp tổ chức các tác vụ phức tạp thành các bước có thể quản lý được."
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/zh-CN/settings.json

@@ -577,6 +577,10 @@
 				"label": "匹配精度",
 				"description": "控制代码匹配的精确程度。数值越低匹配越宽松(容错率高但风险大),建议保持100%以确保安全。"
 			}
+		},
+		"todoList": {
+			"label": "启用任务清单工具",
+			"description": "启用后,Roo 可以创建和管理任务清单来跟踪任务进度。这有助于将复杂任务组织成可管理的步骤。"
 		}
 	},
 	"experimental": {

+ 4 - 0
webview-ui/src/i18n/locales/zh-TW/settings.json

@@ -577,6 +577,10 @@
 				"label": "比對精確度",
 				"description": "此滑桿控制套用差異時程式碼區段的比對精確度。較低的數值允許更彈性的比對,但也會增加錯誤取代的風險。使用低於 100% 的數值時請特別謹慎。"
 			}
+		},
+		"todoList": {
+			"label": "啟用待辦事項清單工具",
+			"description": "啟用後,Roo 可以建立和管理待辦事項清單來追蹤任務進度。這有助於將複雜任務組織成可管理的步驟。"
 		}
 	},
 	"experimental": {