From 2df9a7a8405f14f0f7b079fdfb93fa6669c7e817 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Mon, 7 Jul 2025 22:22:23 -0400 Subject: [PATCH 1/4] Prevent completion with open todos --- .../__tests__/attemptCompletionTool.spec.ts | 228 ++++++++++++++++++ src/core/tools/attemptCompletionTool.ts | 14 ++ 2 files changed, 242 insertions(+) create mode 100644 src/core/tools/__tests__/attemptCompletionTool.spec.ts diff --git a/src/core/tools/__tests__/attemptCompletionTool.spec.ts b/src/core/tools/__tests__/attemptCompletionTool.spec.ts new file mode 100644 index 0000000000..227055d616 --- /dev/null +++ b/src/core/tools/__tests__/attemptCompletionTool.spec.ts @@ -0,0 +1,228 @@ +import { describe, it, expect, vi, beforeEach } from "vitest" +import { TodoItem } from "@roo-code/types" +import { AttemptCompletionToolUse } from "../../../shared/tools" + +// Mock the formatResponse module before importing the tool +vi.mock("../../prompts/responses", () => ({ + formatResponse: { + toolError: vi.fn((msg: string) => `Error: ${msg}`), + }, +})) + +import { attemptCompletionTool } from "../attemptCompletionTool" +import { Task } from "../../task/Task" + +describe("attemptCompletionTool", () => { + let mockTask: Partial + let mockPushToolResult: ReturnType + let mockAskApproval: ReturnType + let mockHandleError: ReturnType + let mockRemoveClosingTag: ReturnType + let mockToolDescription: ReturnType + let mockAskFinishSubTaskApproval: ReturnType + + beforeEach(() => { + mockPushToolResult = vi.fn() + mockAskApproval = vi.fn() + mockHandleError = vi.fn() + mockRemoveClosingTag = vi.fn() + mockToolDescription = vi.fn() + mockAskFinishSubTaskApproval = vi.fn() + + mockTask = { + consecutiveMistakeCount: 0, + recordToolError: vi.fn(), + todoList: undefined, + } + }) + + describe("todo list validation", () => { + it("should allow completion when there is no todo list", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + mockTask.todoList = undefined + + // Mock the formatResponse to avoid import issues + vi.doMock("../../prompts/responses", () => ({ + formatResponse: { + toolError: vi.fn((msg) => `Error: ${msg}`), + }, + })) + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + // Should not call pushToolResult with an error for empty todo list + expect(mockTask.consecutiveMistakeCount).toBe(0) + expect(mockTask.recordToolError).not.toHaveBeenCalled() + }) + + it("should allow completion when todo list is empty", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + mockTask.todoList = [] + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + expect(mockTask.consecutiveMistakeCount).toBe(0) + expect(mockTask.recordToolError).not.toHaveBeenCalled() + }) + + it("should allow completion when all todos are completed", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + const completedTodos: TodoItem[] = [ + { id: "1", content: "First task", status: "completed" }, + { id: "2", content: "Second task", status: "completed" }, + ] + + mockTask.todoList = completedTodos + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + expect(mockTask.consecutiveMistakeCount).toBe(0) + expect(mockTask.recordToolError).not.toHaveBeenCalled() + }) + + it("should prevent completion when there are pending todos", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + const todosWithPending: TodoItem[] = [ + { id: "1", content: "First task", status: "completed" }, + { id: "2", content: "Second task", status: "pending" }, + ] + + mockTask.todoList = todosWithPending + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + expect(mockTask.consecutiveMistakeCount).toBe(1) + expect(mockTask.recordToolError).toHaveBeenCalledWith("attempt_completion") + expect(mockPushToolResult).toHaveBeenCalledWith( + expect.stringContaining("Cannot complete task while there are incomplete todos"), + ) + }) + + it("should prevent completion when there are in-progress todos", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + const todosWithInProgress: TodoItem[] = [ + { id: "1", content: "First task", status: "completed" }, + { id: "2", content: "Second task", status: "in_progress" }, + ] + + mockTask.todoList = todosWithInProgress + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + expect(mockTask.consecutiveMistakeCount).toBe(1) + expect(mockTask.recordToolError).toHaveBeenCalledWith("attempt_completion") + expect(mockPushToolResult).toHaveBeenCalledWith( + expect.stringContaining("Cannot complete task while there are incomplete todos"), + ) + }) + + it("should prevent completion when there are mixed incomplete todos", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + const mixedTodos: TodoItem[] = [ + { id: "1", content: "First task", status: "completed" }, + { id: "2", content: "Second task", status: "pending" }, + { id: "3", content: "Third task", status: "in_progress" }, + ] + + mockTask.todoList = mixedTodos + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + expect(mockTask.consecutiveMistakeCount).toBe(1) + expect(mockTask.recordToolError).toHaveBeenCalledWith("attempt_completion") + expect(mockPushToolResult).toHaveBeenCalledWith( + expect.stringContaining("Cannot complete task while there are incomplete todos"), + ) + }) + }) +}) diff --git a/src/core/tools/attemptCompletionTool.ts b/src/core/tools/attemptCompletionTool.ts index 57f5870022..b64a1b97d5 100644 --- a/src/core/tools/attemptCompletionTool.ts +++ b/src/core/tools/attemptCompletionTool.ts @@ -28,6 +28,20 @@ export async function attemptCompletionTool( const result: string | undefined = block.params.result const command: string | undefined = block.params.command + // Check if there are incomplete todos + const hasIncompleteTodos = cline.todoList && cline.todoList.some((todo) => todo.status !== "completed") + + if (hasIncompleteTodos) { + cline.consecutiveMistakeCount++ + cline.recordToolError("attempt_completion") + pushToolResult( + formatResponse.toolError( + "Cannot complete task while there are incomplete todos. Please finish all todos before attempting completion.", + ), + ) + return + } + try { const lastMessage = cline.clineMessages.at(-1) From 2dc3b1a52cc75e0fbb633c430217f9349f5afe7c Mon Sep 17 00:00:00 2001 From: Roo Code Date: Fri, 18 Jul 2025 14:51:55 +0000 Subject: [PATCH 2/4] feat: add VSCode setting to control todo completion prevention - Add preventCompletionWithOpenTodos setting (default: false) - Update attemptCompletionTool to check setting before enforcing validation - Add comprehensive tests for setting behavior - Include setting in IPC configuration and global settings schema - Add localization for the new setting --- packages/types/src/global-settings.ts | 2 + .../__tests__/attemptCompletionTool.spec.ts | 161 ++++++++++++++++++ src/core/tools/attemptCompletionTool.ts | 11 +- src/package.json | 5 + src/package.nls.json | 1 + 5 files changed, 178 insertions(+), 2 deletions(-) diff --git a/packages/types/src/global-settings.ts b/packages/types/src/global-settings.ts index cf163e26a6..129ddebdd5 100644 --- a/packages/types/src/global-settings.ts +++ b/packages/types/src/global-settings.ts @@ -51,6 +51,7 @@ export const globalSettingsSchema = z.object({ allowedCommands: z.array(z.string()).optional(), deniedCommands: z.array(z.string()).optional(), commandExecutionTimeout: z.number().optional(), + preventCompletionWithOpenTodos: z.boolean().optional(), allowedMaxRequests: z.number().nullish(), autoCondenseContext: z.boolean().optional(), autoCondenseContextPercent: z.number().optional(), @@ -202,6 +203,7 @@ export const EVALS_SETTINGS: RooCodeSettings = { followupAutoApproveTimeoutMs: 0, allowedCommands: ["*"], commandExecutionTimeout: 30_000, + preventCompletionWithOpenTodos: false, browserToolEnabled: false, browserViewportSize: "900x600", diff --git a/src/core/tools/__tests__/attemptCompletionTool.spec.ts b/src/core/tools/__tests__/attemptCompletionTool.spec.ts index 227055d616..1ff9d36860 100644 --- a/src/core/tools/__tests__/attemptCompletionTool.spec.ts +++ b/src/core/tools/__tests__/attemptCompletionTool.spec.ts @@ -9,8 +9,25 @@ vi.mock("../../prompts/responses", () => ({ }, })) +// Mock vscode module +vi.mock("vscode", () => ({ + workspace: { + getConfiguration: vi.fn(() => ({ + get: vi.fn(), + })), + }, +})) + +// Mock Package module +vi.mock("../../../shared/package", () => ({ + Package: { + name: "roo-cline", + }, +})) + import { attemptCompletionTool } from "../attemptCompletionTool" import { Task } from "../../task/Task" +import * as vscode from "vscode" describe("attemptCompletionTool", () => { let mockTask: Partial @@ -20,6 +37,7 @@ describe("attemptCompletionTool", () => { let mockRemoveClosingTag: ReturnType let mockToolDescription: ReturnType let mockAskFinishSubTaskApproval: ReturnType + let mockGetConfiguration: ReturnType beforeEach(() => { mockPushToolResult = vi.fn() @@ -28,6 +46,17 @@ describe("attemptCompletionTool", () => { mockRemoveClosingTag = vi.fn() mockToolDescription = vi.fn() mockAskFinishSubTaskApproval = vi.fn() + mockGetConfiguration = vi.fn(() => ({ + get: vi.fn((key: string, defaultValue: any) => { + if (key === "preventCompletionWithOpenTodos") { + return defaultValue // Default to false unless overridden in test + } + return defaultValue + }), + })) + + // Setup vscode mock + vi.mocked(vscode.workspace.getConfiguration).mockImplementation(mockGetConfiguration) mockTask = { consecutiveMistakeCount: 0, @@ -224,5 +253,137 @@ describe("attemptCompletionTool", () => { expect.stringContaining("Cannot complete task while there are incomplete todos"), ) }) + + it("should allow completion when setting is disabled even with incomplete todos", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + const todosWithPending: TodoItem[] = [ + { id: "1", content: "First task", status: "completed" }, + { id: "2", content: "Second task", status: "pending" }, + ] + + mockTask.todoList = todosWithPending + + // Ensure the setting is disabled (default behavior) + mockGetConfiguration.mockReturnValue({ + get: vi.fn((key: string, defaultValue: any) => { + if (key === "preventCompletionWithOpenTodos") { + return false // Setting is disabled + } + return defaultValue + }), + }) + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + // Should not prevent completion when setting is disabled + expect(mockTask.consecutiveMistakeCount).toBe(0) + expect(mockTask.recordToolError).not.toHaveBeenCalled() + expect(mockPushToolResult).not.toHaveBeenCalledWith( + expect.stringContaining("Cannot complete task while there are incomplete todos"), + ) + }) + + it("should prevent completion when setting is enabled with incomplete todos", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + const todosWithPending: TodoItem[] = [ + { id: "1", content: "First task", status: "completed" }, + { id: "2", content: "Second task", status: "pending" }, + ] + + mockTask.todoList = todosWithPending + + // Enable the setting + mockGetConfiguration.mockReturnValue({ + get: vi.fn((key: string, defaultValue: any) => { + if (key === "preventCompletionWithOpenTodos") { + return true // Setting is enabled + } + return defaultValue + }), + }) + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + // Should prevent completion when setting is enabled and there are incomplete todos + expect(mockTask.consecutiveMistakeCount).toBe(1) + expect(mockTask.recordToolError).toHaveBeenCalledWith("attempt_completion") + expect(mockPushToolResult).toHaveBeenCalledWith( + expect.stringContaining("Cannot complete task while there are incomplete todos"), + ) + }) + + it("should allow completion when setting is enabled but all todos are completed", async () => { + const block: AttemptCompletionToolUse = { + type: "tool_use", + name: "attempt_completion", + params: { result: "Task completed successfully" }, + partial: false, + } + + const completedTodos: TodoItem[] = [ + { id: "1", content: "First task", status: "completed" }, + { id: "2", content: "Second task", status: "completed" }, + ] + + mockTask.todoList = completedTodos + + // Enable the setting + mockGetConfiguration.mockReturnValue({ + get: vi.fn((key: string, defaultValue: any) => { + if (key === "preventCompletionWithOpenTodos") { + return true // Setting is enabled + } + return defaultValue + }), + }) + + await attemptCompletionTool( + mockTask as Task, + block, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + mockToolDescription, + mockAskFinishSubTaskApproval, + ) + + // Should allow completion when setting is enabled but all todos are completed + expect(mockTask.consecutiveMistakeCount).toBe(0) + expect(mockTask.recordToolError).not.toHaveBeenCalled() + expect(mockPushToolResult).not.toHaveBeenCalledWith( + expect.stringContaining("Cannot complete task while there are incomplete todos"), + ) + }) }) }) diff --git a/src/core/tools/attemptCompletionTool.ts b/src/core/tools/attemptCompletionTool.ts index b64a1b97d5..ef7881854f 100644 --- a/src/core/tools/attemptCompletionTool.ts +++ b/src/core/tools/attemptCompletionTool.ts @@ -1,4 +1,5 @@ import Anthropic from "@anthropic-ai/sdk" +import * as vscode from "vscode" import { TelemetryService } from "@roo-code/telemetry" @@ -14,6 +15,7 @@ import { AskFinishSubTaskApproval, } from "../../shared/tools" import { formatResponse } from "../prompts/responses" +import { Package } from "../../shared/package" export async function attemptCompletionTool( cline: Task, @@ -28,10 +30,15 @@ export async function attemptCompletionTool( const result: string | undefined = block.params.result const command: string | undefined = block.params.command - // Check if there are incomplete todos + // Get the setting for preventing completion with open todos from VSCode configuration + const preventCompletionWithOpenTodos = vscode.workspace + .getConfiguration(Package.name) + .get("preventCompletionWithOpenTodos", false) + + // Check if there are incomplete todos (only if the setting is enabled) const hasIncompleteTodos = cline.todoList && cline.todoList.some((todo) => todo.status !== "completed") - if (hasIncompleteTodos) { + if (preventCompletionWithOpenTodos && hasIncompleteTodos) { cline.consecutiveMistakeCount++ cline.recordToolError("attempt_completion") pushToolResult( diff --git a/src/package.json b/src/package.json index 5cf8727545..448463b750 100644 --- a/src/package.json +++ b/src/package.json @@ -345,6 +345,11 @@ "maximum": 600, "description": "%commands.commandExecutionTimeout.description%" }, + "roo-cline.preventCompletionWithOpenTodos": { + "type": "boolean", + "default": false, + "description": "%commands.preventCompletionWithOpenTodos.description%" + }, "roo-cline.vsCodeLmModelSelector": { "type": "object", "properties": { diff --git a/src/package.nls.json b/src/package.nls.json index c5225c45c8..303f5c3ce1 100644 --- a/src/package.nls.json +++ b/src/package.nls.json @@ -29,6 +29,7 @@ "commands.allowedCommands.description": "Commands that can be auto-executed when 'Always approve execute operations' is enabled", "commands.deniedCommands.description": "Command prefixes that will be automatically denied without asking for approval. In case of conflicts with allowed commands, the longest prefix match takes precedence. Add * to deny all commands.", "commands.commandExecutionTimeout.description": "Maximum time in seconds to wait for command execution to complete before timing out (0 = no timeout, 1-600s, default: 0s)", + "commands.preventCompletionWithOpenTodos.description": "Prevent task completion when there are incomplete todos in the todo list (default: false)", "settings.vsCodeLmModelSelector.description": "Settings for VSCode Language Model API", "settings.vsCodeLmModelSelector.vendor.description": "The vendor of the language model (e.g. copilot)", "settings.vsCodeLmModelSelector.family.description": "The family of the language model (e.g. gpt-4)", From f778acf6f13a55a0d00d1cc112373bc2e38d1b86 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Fri, 18 Jul 2025 11:22:45 -0400 Subject: [PATCH 3/4] PR fixes --- .../__tests__/attemptCompletionTool.spec.ts | 37 +++++++++++++++---- src/i18n/locales/ca/common.json | 5 +++ src/i18n/locales/de/common.json | 5 +++ src/i18n/locales/en/common.json | 5 +++ src/i18n/locales/es/common.json | 5 +++ src/i18n/locales/fr/common.json | 5 +++ src/i18n/locales/hi/common.json | 5 +++ src/i18n/locales/id/common.json | 5 +++ src/i18n/locales/it/common.json | 5 +++ src/i18n/locales/ja/common.json | 5 +++ src/i18n/locales/ko/common.json | 5 +++ src/i18n/locales/nl/common.json | 5 +++ src/i18n/locales/pl/common.json | 5 +++ src/i18n/locales/pt-BR/common.json | 5 +++ src/i18n/locales/ru/common.json | 5 +++ src/i18n/locales/tr/common.json | 5 +++ src/i18n/locales/vi/common.json | 5 +++ src/i18n/locales/zh-CN/common.json | 5 +++ src/i18n/locales/zh-TW/common.json | 5 +++ src/package.nls.json | 2 +- 20 files changed, 121 insertions(+), 8 deletions(-) diff --git a/src/core/tools/__tests__/attemptCompletionTool.spec.ts b/src/core/tools/__tests__/attemptCompletionTool.spec.ts index 1ff9d36860..b39c1acac6 100644 --- a/src/core/tools/__tests__/attemptCompletionTool.spec.ts +++ b/src/core/tools/__tests__/attemptCompletionTool.spec.ts @@ -76,13 +76,6 @@ describe("attemptCompletionTool", () => { mockTask.todoList = undefined - // Mock the formatResponse to avoid import issues - vi.doMock("../../prompts/responses", () => ({ - formatResponse: { - toolError: vi.fn((msg) => `Error: ${msg}`), - }, - })) - await attemptCompletionTool( mockTask as Task, block, @@ -169,6 +162,16 @@ describe("attemptCompletionTool", () => { mockTask.todoList = todosWithPending + // Enable the setting to prevent completion with open todos + mockGetConfiguration.mockReturnValue({ + get: vi.fn((key: string, defaultValue: any) => { + if (key === "preventCompletionWithOpenTodos") { + return true // Setting is enabled + } + return defaultValue + }), + }) + await attemptCompletionTool( mockTask as Task, block, @@ -202,6 +205,16 @@ describe("attemptCompletionTool", () => { mockTask.todoList = todosWithInProgress + // Enable the setting to prevent completion with open todos + mockGetConfiguration.mockReturnValue({ + get: vi.fn((key: string, defaultValue: any) => { + if (key === "preventCompletionWithOpenTodos") { + return true // Setting is enabled + } + return defaultValue + }), + }) + await attemptCompletionTool( mockTask as Task, block, @@ -236,6 +249,16 @@ describe("attemptCompletionTool", () => { mockTask.todoList = mixedTodos + // Enable the setting to prevent completion with open todos + mockGetConfiguration.mockReturnValue({ + get: vi.fn((key: string, defaultValue: any) => { + if (key === "preventCompletionWithOpenTodos") { + return true // Setting is enabled + } + return defaultValue + }), + }) + await attemptCompletionTool( mockTask as Task, block, diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json index 772156286e..633208d4bc 100644 --- a/src/i18n/locales/ca/common.json +++ b/src/i18n/locales/ca/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Esteu segur que voleu suprimir aquest mode personalitzat?", "confirm": "Suprimeix" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Evitar la finalització de tasques quan hi ha todos incomplets a la llista de todos" + } } } diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json index c136fba809..71155b1ebe 100644 --- a/src/i18n/locales/de/common.json +++ b/src/i18n/locales/de/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Bist du sicher, dass du diesen benutzerdefinierten Modus löschen möchtest?", "confirm": "Löschen" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Aufgabenabschluss verhindern, wenn unvollständige Todos in der Todo-Liste vorhanden sind" + } } } diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index b0fdb9d8df..6bab0ab9a9 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -155,5 +155,10 @@ "descriptionNoRules": "Are you sure you want to delete this custom mode?", "confirm": "Delete" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Prevent task completion when there are incomplete todos in the todo list" + } } } diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json index 39cf48383e..d307800c79 100644 --- a/src/i18n/locales/es/common.json +++ b/src/i18n/locales/es/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "¿Estás seguro de que quieres eliminar este modo personalizado?", "confirm": "Eliminar" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Prevenir la finalización de tareas cuando hay todos incompletos en la lista de todos" + } } } diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json index ace5bbe47a..b0571e3714 100644 --- a/src/i18n/locales/fr/common.json +++ b/src/i18n/locales/fr/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Êtes-vous sûr de vouloir supprimer ce mode personnalisé ?", "confirm": "Supprimer" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Empêcher la finalisation des tâches lorsqu'il y a des todos incomplets dans la liste de todos" + } } } diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json index 84dbe9052a..ca4efea535 100644 --- a/src/i18n/locales/hi/common.json +++ b/src/i18n/locales/hi/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "क्या आप वाकई इस कस्टम मोड को हटाना चाहते हैं?", "confirm": "हटाएं" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "जब टूडू सूची में अधूरे टूडू हों तो कार्य पूर्ण होने से रोकें" + } } } diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json index fb2a30994e..46ce587e61 100644 --- a/src/i18n/locales/id/common.json +++ b/src/i18n/locales/id/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Anda yakin ingin menghapus mode kustom ini?", "confirm": "Hapus" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Mencegah penyelesaian tugas ketika ada todo yang belum selesai dalam daftar todo" + } } } diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json index 4681612e9d..11bae26eb3 100644 --- a/src/i18n/locales/it/common.json +++ b/src/i18n/locales/it/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Sei sicuro di voler eliminare questa modalità personalizzata?", "confirm": "Elimina" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Impedire il completamento delle attività quando ci sono todo incompleti nella lista dei todo" + } } } diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index 38fc9d27c5..52ab094633 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "このカスタムモードを削除してもよろしいですか?", "confirm": "削除" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Todoリストに未完了のTodoがある場合、タスクの完了を防ぐ" + } } } diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json index d76a82a7c2..63566f946b 100644 --- a/src/i18n/locales/ko/common.json +++ b/src/i18n/locales/ko/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "이 사용자 정의 모드를 삭제하시겠습니까?", "confirm": "삭제" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "할 일 목록에 미완료된 할 일이 있을 때 작업 완료를 방지" + } } } diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json index 5caa0534ee..fc3c1ce018 100644 --- a/src/i18n/locales/nl/common.json +++ b/src/i18n/locales/nl/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Weet je zeker dat je deze aangepaste modus wilt verwijderen?", "confirm": "Verwijderen" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Voorkom taakafronding wanneer er onvolledige todos in de todolijst staan" + } } } diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json index 77008aa0ab..ef756ec1ce 100644 --- a/src/i18n/locales/pl/common.json +++ b/src/i18n/locales/pl/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Czy na pewno chcesz usunąć ten tryb niestandardowy?", "confirm": "Usuń" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Zapobiegaj ukończeniu zadania gdy na liście zadań są nieukończone zadania" + } } } diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json index 6f63d9d1ed..8856e541be 100644 --- a/src/i18n/locales/pt-BR/common.json +++ b/src/i18n/locales/pt-BR/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Tem certeza de que deseja excluir este modo personalizado?", "confirm": "Excluir" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Impedir a conclusão de tarefas quando há todos incompletos na lista de todos" + } } } diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json index 4e354bcbc5..fd23dffe2a 100644 --- a/src/i18n/locales/ru/common.json +++ b/src/i18n/locales/ru/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Вы уверены, что хотите удалить этот пользовательский режим?", "confirm": "Удалить" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Предотвратить завершение задач при наличии незавершенных дел в списке дел" + } } } diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json index 5de82d00c6..9eeae720ef 100644 --- a/src/i18n/locales/tr/common.json +++ b/src/i18n/locales/tr/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "Bu özel modu silmek istediğinizden emin misiniz?", "confirm": "Sil" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Todo listesinde tamamlanmamış todolar olduğunda görev tamamlanmasını engelle" + } } } diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json index 014bddda58..bd66d623bb 100644 --- a/src/i18n/locales/vi/common.json +++ b/src/i18n/locales/vi/common.json @@ -173,5 +173,10 @@ "descriptionNoRules": "Bạn có chắc chắn muốn xóa chế độ tùy chỉnh này không?", "confirm": "Xóa" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "Ngăn chặn hoàn thành nhiệm vụ khi có các todo chưa hoàn thành trong danh sách todo" + } } } diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json index 268ee5fbb1..515ee7d048 100644 --- a/src/i18n/locales/zh-CN/common.json +++ b/src/i18n/locales/zh-CN/common.json @@ -171,5 +171,10 @@ "descriptionNoRules": "您确定要删除此自定义模式吗?", "confirm": "删除" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "当待办事项列表中有未完成的待办事项时阻止任务完成" + } } } diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json index dec20a1f9a..cceb53e5f3 100644 --- a/src/i18n/locales/zh-TW/common.json +++ b/src/i18n/locales/zh-TW/common.json @@ -166,5 +166,10 @@ "descriptionNoRules": "您確定要刪除此自訂模式嗎?", "confirm": "刪除" } + }, + "commands": { + "preventCompletionWithOpenTodos": { + "description": "當待辦事項清單中有未完成的待辦事項時阻止工作完成" + } } } diff --git a/src/package.nls.json b/src/package.nls.json index 303f5c3ce1..b52f2d11c2 100644 --- a/src/package.nls.json +++ b/src/package.nls.json @@ -29,7 +29,7 @@ "commands.allowedCommands.description": "Commands that can be auto-executed when 'Always approve execute operations' is enabled", "commands.deniedCommands.description": "Command prefixes that will be automatically denied without asking for approval. In case of conflicts with allowed commands, the longest prefix match takes precedence. Add * to deny all commands.", "commands.commandExecutionTimeout.description": "Maximum time in seconds to wait for command execution to complete before timing out (0 = no timeout, 1-600s, default: 0s)", - "commands.preventCompletionWithOpenTodos.description": "Prevent task completion when there are incomplete todos in the todo list (default: false)", + "commands.preventCompletionWithOpenTodos.description": "Prevent task completion when there are incomplete todos in the todo list", "settings.vsCodeLmModelSelector.description": "Settings for VSCode Language Model API", "settings.vsCodeLmModelSelector.vendor.description": "The vendor of the language model (e.g. copilot)", "settings.vsCodeLmModelSelector.family.description": "The family of the language model (e.g. gpt-4)", From 22e9e1031210f7efaed7042fde0d514ebfae9e91 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Fri, 18 Jul 2025 11:30:57 -0400 Subject: [PATCH 4/4] Bump types --- packages/types/npm/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/npm/package.json b/packages/types/npm/package.json index 76bc0eb4e4..924e5251cb 100644 --- a/packages/types/npm/package.json +++ b/packages/types/npm/package.json @@ -1,6 +1,6 @@ { "name": "@roo-code/types", - "version": "1.34.0", + "version": "1.35.0", "description": "TypeScript type definitions for Roo Code.", "publishConfig": { "access": "public",