diff --git a/packages/types/src/message.ts b/packages/types/src/message.ts index b6eb67e171..b3a1cd8111 100644 --- a/packages/types/src/message.ts +++ b/packages/types/src/message.ts @@ -224,6 +224,7 @@ export const clineMessageSchema = z.object({ reasoning_summary: z.string().optional(), }) .optional(), + title: z.string().optional(), // Custom title for error messages }) .optional(), }) diff --git a/src/core/assistant-message/presentAssistantMessage.ts b/src/core/assistant-message/presentAssistantMessage.ts index 689675999f..d4fee5d0a1 100644 --- a/src/core/assistant-message/presentAssistantMessage.ts +++ b/src/core/assistant-message/presentAssistantMessage.ts @@ -317,12 +317,15 @@ export async function presentAssistantMessage(cline: Task) { return await askApproval("tool", toolMessage) } - const handleError = async (action: string, error: Error) => { + const handleError = async (action: string, error: Error, title?: string) => { const errorString = `Error ${action}: ${JSON.stringify(serializeError(error))}` await cline.say( "error", `Error ${action}:\n${error.message ?? JSON.stringify(serializeError(error), null, 2)}`, + undefined, + undefined, + title ? { title } : undefined, ) pushToolResult(formatResponse.toolError(errorString)) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index c5be865731..636ee1d133 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1164,15 +1164,41 @@ export class Task extends EventEmitter implements TaskLike { } async sayAndCreateMissingParamError(toolName: ToolName, paramName: string, relPath?: string) { + const relPathFormatted = relPath ? ` for '${relPath.toPosix()}'` : "" await this.say( "error", - `Roo tried to use ${toolName}${ - relPath ? ` for '${relPath.toPosix()}'` : "" - } without value for required parameter '${paramName}'. Retrying...`, + t("tools:common.errors.missingParameterMessage", { + toolName, + relPath: relPathFormatted, + paramName, + }), + undefined, + undefined, + undefined, + undefined, + { + metadata: { + title: t("tools:common.errors.missingParameter"), + }, + }, ) return formatResponse.toolError(formatResponse.missingToolParameterError(paramName)) } + /** + * Helper method to say an error with a custom title + * @param title - The title to display for the error + * @param text - The error message text + * @param images - Optional images to include + */ + async sayError(title: string, text: string, images?: string[]) { + await this.say("error", text, images, undefined, undefined, undefined, { + metadata: { + title, + }, + }) + } + // Lifecycle // Start / Resume / Abort / Dispose diff --git a/src/core/tools/__tests__/generateImageTool.test.ts b/src/core/tools/__tests__/generateImageTool.test.ts index 0a12bebbe2..9084dbdbed 100644 --- a/src/core/tools/__tests__/generateImageTool.test.ts +++ b/src/core/tools/__tests__/generateImageTool.test.ts @@ -277,7 +277,17 @@ describe("generateImageTool", () => { mockRemoveClosingTag, ) - expect(mockCline.say).toHaveBeenCalledWith("error", expect.stringContaining("Input image not found")) + expect(mockCline.say).toHaveBeenCalledWith( + "error", + expect.stringContaining("Input image not found"), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Input Image Not Found" }, + }, + ) expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Input image not found")) }) @@ -302,7 +312,17 @@ describe("generateImageTool", () => { mockRemoveClosingTag, ) - expect(mockCline.say).toHaveBeenCalledWith("error", expect.stringContaining("Unsupported image format")) + expect(mockCline.say).toHaveBeenCalledWith( + "error", + expect.stringContaining("Unsupported image format"), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Unsupported Image Format" }, + }, + ) expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Unsupported image format")) }) }) diff --git a/src/core/tools/__tests__/insertContentTool.spec.ts b/src/core/tools/__tests__/insertContentTool.spec.ts index 5f055fb29a..b73caff303 100644 --- a/src/core/tools/__tests__/insertContentTool.spec.ts +++ b/src/core/tools/__tests__/insertContentTool.spec.ts @@ -46,6 +46,22 @@ vi.mock("../../ignore/RooIgnoreController", () => ({ }, })) +vi.mock("../../../i18n", () => ({ + t: vi.fn((key: string, params?: any) => { + // Return the key without the namespace prefix for testing + const keyWithoutNamespace = key.replace(/^[^:]+:/, "") + if (params) { + // Simple parameter replacement for testing + let result = keyWithoutNamespace + Object.entries(params).forEach(([key, value]) => { + result = result.replace(`{{${key}}}`, String(value)) + }) + return result + } + return keyWithoutNamespace + }), +})) + describe("insertContentTool", () => { const testFilePath = "test/file.txt" // Use a consistent mock absolute path for testing @@ -226,7 +242,19 @@ describe("insertContentTool", () => { expect(mockedFsReadFile).not.toHaveBeenCalled() expect(mockCline.consecutiveMistakeCount).toBe(1) expect(mockCline.recordToolError).toHaveBeenCalledWith("insert_content") - expect(mockCline.say).toHaveBeenCalledWith("error", expect.stringContaining("non-existent file")) + expect(mockCline.say).toHaveBeenCalledWith( + "error", + "insertContent.errors.cannotInsertIntoNonExistent", + undefined, + undefined, + undefined, + undefined, + expect.objectContaining({ + metadata: expect.objectContaining({ + title: "insertContent.errors.invalidLineNumber", + }), + }), + ) expect(mockCline.diffViewProvider.update).not.toHaveBeenCalled() expect(mockCline.diffViewProvider.pushToolWriteResult).not.toHaveBeenCalled() }) diff --git a/src/core/tools/__tests__/useMcpToolTool.spec.ts b/src/core/tools/__tests__/useMcpToolTool.spec.ts index 8738e059e5..e964c921ae 100644 --- a/src/core/tools/__tests__/useMcpToolTool.spec.ts +++ b/src/core/tools/__tests__/useMcpToolTool.spec.ts @@ -151,7 +151,17 @@ describe("useMcpToolTool", () => { expect(mockTask.consecutiveMistakeCount).toBe(1) expect(mockTask.recordToolError).toHaveBeenCalledWith("use_mcp_tool") - expect(mockTask.say).toHaveBeenCalledWith("error", expect.stringContaining("invalid JSON argument")) + expect(mockTask.say).toHaveBeenCalledWith( + "error", + expect.stringContaining("invalid JSON argument"), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Invalid JSON Arguments" }, + }, + ) expect(mockPushToolResult).toHaveBeenCalledWith("Tool error: Invalid args for test_server:test_tool") }) }) @@ -343,7 +353,17 @@ describe("useMcpToolTool", () => { expect(mockTask.consecutiveMistakeCount).toBe(1) expect(mockTask.recordToolError).toHaveBeenCalledWith("use_mcp_tool") - expect(mockTask.say).toHaveBeenCalledWith("error", expect.stringContaining("does not exist")) + expect(mockTask.say).toHaveBeenCalledWith( + "error", + expect.stringContaining("does not exist"), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "MCP Tool Not Found" }, + }, + ) // Check that the error message contains available tools expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("existing-tool-1")) expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("existing-tool-2")) @@ -390,7 +410,17 @@ describe("useMcpToolTool", () => { expect(mockTask.consecutiveMistakeCount).toBe(1) expect(mockTask.recordToolError).toHaveBeenCalledWith("use_mcp_tool") - expect(mockTask.say).toHaveBeenCalledWith("error", expect.stringContaining("does not exist")) + expect(mockTask.say).toHaveBeenCalledWith( + "error", + expect.stringContaining("does not exist"), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "MCP Tool Not Found" }, + }, + ) expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("No tools available")) }) @@ -484,7 +514,17 @@ describe("useMcpToolTool", () => { // Assert expect(mockTask.consecutiveMistakeCount).toBe(1) expect(mockTask.recordToolError).toHaveBeenCalledWith("use_mcp_tool") - expect(mockTask.say).toHaveBeenCalledWith("error", expect.stringContaining("not configured")) + expect(mockTask.say).toHaveBeenCalledWith( + "error", + expect.stringContaining("not configured"), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "MCP Server Not Found" }, + }, + ) expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("s1")) expect(callToolMock).not.toHaveBeenCalled() expect(mockAskApproval).not.toHaveBeenCalled() @@ -527,7 +567,17 @@ describe("useMcpToolTool", () => { // Assert expect(mockTask.consecutiveMistakeCount).toBe(1) expect(mockTask.recordToolError).toHaveBeenCalledWith("use_mcp_tool") - expect(mockTask.say).toHaveBeenCalledWith("error", expect.stringContaining("not configured")) + expect(mockTask.say).toHaveBeenCalledWith( + "error", + expect.stringContaining("not configured"), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "MCP Server Not Found" }, + }, + ) expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("No servers available")) expect(callToolMock).not.toHaveBeenCalled() expect(mockAskApproval).not.toHaveBeenCalled() diff --git a/src/core/tools/__tests__/writeToFileTool.spec.ts b/src/core/tools/__tests__/writeToFileTool.spec.ts index 78e60cbaa5..9ce6cb2683 100644 --- a/src/core/tools/__tests__/writeToFileTool.spec.ts +++ b/src/core/tools/__tests__/writeToFileTool.spec.ts @@ -403,7 +403,11 @@ describe("writeToFileTool", () => { await executeWriteFileTool({}) - expect(mockHandleError).toHaveBeenCalledWith("writing file", expect.any(Error)) + expect(mockHandleError).toHaveBeenCalledWith( + "writing file", + expect.any(Error), + "writeToFile.errors.writeFileError", + ) expect(mockCline.diffViewProvider.reset).toHaveBeenCalled() }) @@ -412,7 +416,11 @@ describe("writeToFileTool", () => { await executeWriteFileTool({}, { isPartial: true }) - expect(mockHandleError).toHaveBeenCalledWith("writing file", expect.any(Error)) + expect(mockHandleError).toHaveBeenCalledWith( + "writing file", + expect.any(Error), + "writeToFile.errors.writeFileError", + ) expect(mockCline.diffViewProvider.reset).toHaveBeenCalled() }) }) diff --git a/src/core/tools/applyDiffTool.ts b/src/core/tools/applyDiffTool.ts index 903e3c846e..58652588d1 100644 --- a/src/core/tools/applyDiffTool.ts +++ b/src/core/tools/applyDiffTool.ts @@ -13,6 +13,7 @@ import { fileExistsAtPath } from "../../utils/fs" import { RecordSource } from "../context-tracking/FileContextTrackerTypes" import { unescapeHtmlEntities } from "../../utils/text-normalization" import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" +import { t } from "../../i18n" export async function applyDiffToolLegacy( cline: Task, @@ -82,8 +83,10 @@ export async function applyDiffToolLegacy( if (!fileExists) { cline.consecutiveMistakeCount++ cline.recordToolError("apply_diff") - const formattedError = `File does not exist at path: ${absolutePath}\n\n\nThe specified file could not be found. Please verify the file path and try again.\n` - await cline.say("error", formattedError) + const formattedError = `${t("tools:applyDiff.errors.fileDoesNotExist", { path: absolutePath })}\n\n\n${t("tools:applyDiff.errors.fileDoesNotExistDetails")}\n` + await cline.say("error", formattedError, undefined, undefined, undefined, undefined, { + metadata: { title: t("tools:applyDiff.errors.fileNotFound") }, + }) pushToolResult(formattedError) return } @@ -248,7 +251,7 @@ export async function applyDiffToolLegacy( return } } catch (error) { - await handleError("applying diff", error) + await handleError("applying diff", error, t("tools:applyDiff.errors.applyDiffError")) await cline.diffViewProvider.reset() return } diff --git a/src/core/tools/askFollowupQuestionTool.ts b/src/core/tools/askFollowupQuestionTool.ts index e736936887..a48f5b4c2c 100644 --- a/src/core/tools/askFollowupQuestionTool.ts +++ b/src/core/tools/askFollowupQuestionTool.ts @@ -2,6 +2,7 @@ import { Task } from "../task/Task" import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools" import { formatResponse } from "../prompts/responses" import { parseXml } from "../../utils/xml" +import { t } from "../../i18n" export async function askFollowupQuestionTool( cline: Task, @@ -48,7 +49,17 @@ export async function askFollowupQuestionTool( } catch (error) { cline.consecutiveMistakeCount++ cline.recordToolError("ask_followup_question") - await cline.say("error", `Failed to parse operations: ${error.message}`) + await cline.say( + "error", + `Failed to parse operations: ${error.message}`, + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "XML Parse Error" }, + }, + ) pushToolResult(formatResponse.toolError("Invalid operations xml format")) return } @@ -83,7 +94,7 @@ export async function askFollowupQuestionTool( return } } catch (error) { - await handleError("asking question", error) + await handleError("asking question", error, t("tools:askFollowupQuestion.errors.askError")) return } } diff --git a/src/core/tools/executeCommandTool.ts b/src/core/tools/executeCommandTool.ts index 2c7ce0d023..5bc32634e2 100644 --- a/src/core/tools/executeCommandTool.ts +++ b/src/core/tools/executeCommandTool.ts @@ -128,7 +128,7 @@ export async function executeCommandTool( return } } catch (error) { - await handleError("executing command", error) + await handleError("executing command", error, t("tools:executeCommand.errors.executeError")) return } } @@ -271,7 +271,17 @@ export async function executeCommand( if (isTimedOut) { const status: CommandExecutionStatus = { executionId, status: "timeout" } provider?.postMessageToWebview({ type: "commandExecutionStatus", text: JSON.stringify(status) }) - await task.say("error", t("common:errors:command_timeout", { seconds: commandExecutionTimeoutSeconds })) + await task.say( + "error", + t("common:errors:command_timeout", { seconds: commandExecutionTimeoutSeconds }), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Command Timeout" }, + }, + ) task.terminalProcess = undefined return [ diff --git a/src/core/tools/fetchInstructionsTool.ts b/src/core/tools/fetchInstructionsTool.ts index 5325f98fbf..999aa16e0a 100644 --- a/src/core/tools/fetchInstructionsTool.ts +++ b/src/core/tools/fetchInstructionsTool.ts @@ -3,6 +3,7 @@ import { fetchInstructions } from "../prompts/instructions/instructions" import { ClineSayTool } from "../../shared/ExtensionMessage" import { formatResponse } from "../prompts/responses" import { ToolUse, AskApproval, HandleError, PushToolResult } from "../../shared/tools" +import { t } from "../../i18n" export async function fetchInstructionsTool( cline: Task, @@ -58,6 +59,6 @@ export async function fetchInstructionsTool( return } } catch (error) { - await handleError("fetch instructions", error) + await handleError("fetch instructions", error, t("tools:fetchInstructions.errors.fetchError")) } } diff --git a/src/core/tools/generateImageTool.ts b/src/core/tools/generateImageTool.ts index 749e7cff9a..4ca9888ce7 100644 --- a/src/core/tools/generateImageTool.ts +++ b/src/core/tools/generateImageTool.ts @@ -73,7 +73,17 @@ export async function generateImageTool( // Check if input image exists const inputImageExists = await fileExistsAtPath(inputImageFullPath) if (!inputImageExists) { - await cline.say("error", `Input image not found: ${getReadablePath(cline.cwd, inputImagePath)}`) + await cline.say( + "error", + `Input image not found: ${getReadablePath(cline.cwd, inputImagePath)}`, + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Input Image Not Found" }, + }, + ) pushToolResult( formatResponse.toolError(`Input image not found: ${getReadablePath(cline.cwd, inputImagePath)}`), ) @@ -99,6 +109,13 @@ export async function generateImageTool( await cline.say( "error", `Unsupported image format: ${imageExtension}. Supported formats: ${supportedFormats.join(", ")}`, + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Unsupported Image Format" }, + }, ) pushToolResult( formatResponse.toolError( @@ -115,6 +132,13 @@ export async function generateImageTool( await cline.say( "error", `Failed to read input image: ${error instanceof Error ? error.message : "Unknown error"}`, + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Failed to Read Input Image" }, + }, ) pushToolResult( formatResponse.toolError( @@ -135,6 +159,13 @@ export async function generateImageTool( await cline.say( "error", "OpenRouter API key is required for image generation. Please configure it in the Image Generation experimental settings.", + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Missing API Key" }, + }, ) pushToolResult( formatResponse.toolError( @@ -188,14 +219,26 @@ export async function generateImageTool( ) if (!result.success) { - await cline.say("error", result.error || "Failed to generate image") + await cline.say( + "error", + result.error || "Failed to generate image", + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Image Generation Failed" }, + }, + ) pushToolResult(formatResponse.toolError(result.error || "Failed to generate image")) return } if (!result.imageData) { const errorMessage = "No image data received" - await cline.say("error", errorMessage) + await cline.say("error", errorMessage, undefined, undefined, undefined, undefined, { + metadata: { title: "No Image Data" }, + }) pushToolResult(formatResponse.toolError(errorMessage)) return } @@ -204,7 +247,9 @@ export async function generateImageTool( const base64Match = result.imageData.match(/^data:image\/(png|jpeg|jpg);base64,(.+)$/) if (!base64Match) { const errorMessage = "Invalid image format received" - await cline.say("error", errorMessage) + await cline.say("error", errorMessage, undefined, undefined, undefined, undefined, { + metadata: { title: "Invalid Image Format" }, + }) pushToolResult(formatResponse.toolError(errorMessage)) return } diff --git a/src/core/tools/insertContentTool.ts b/src/core/tools/insertContentTool.ts index e22a368167..d4485d0052 100644 --- a/src/core/tools/insertContentTool.ts +++ b/src/core/tools/insertContentTool.ts @@ -12,6 +12,7 @@ import { fileExistsAtPath } from "../../utils/fs" import { insertGroups } from "../diff/insert-groups" import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" +import { t } from "../../i18n" export async function insertContentTool( cline: Task, @@ -86,8 +87,10 @@ export async function insertContentTool( if (lineNumber > 1) { cline.consecutiveMistakeCount++ cline.recordToolError("insert_content") - const formattedError = `Cannot insert content at line ${lineNumber} into a non-existent file. For new files, 'line' must be 0 (to append) or 1 (to insert at the beginning).` - await cline.say("error", formattedError) + const formattedError = t("tools:insertContent.errors.cannotInsertIntoNonExistent", { lineNumber }) + await cline.say("error", formattedError, undefined, undefined, undefined, undefined, { + metadata: { title: t("tools:insertContent.errors.invalidLineNumber") }, + }) pushToolResult(formattedError) return } @@ -188,7 +191,7 @@ export async function insertContentTool( await cline.diffViewProvider.reset() } catch (error) { - handleError("insert content", error) + handleError("insert content", error, t("tools:insertContent.errors.insertContentError")) await cline.diffViewProvider.reset() } } diff --git a/src/core/tools/listCodeDefinitionNamesTool.ts b/src/core/tools/listCodeDefinitionNamesTool.ts index 6ceec0a725..9d12214cd9 100644 --- a/src/core/tools/listCodeDefinitionNamesTool.ts +++ b/src/core/tools/listCodeDefinitionNamesTool.ts @@ -8,6 +8,7 @@ import { getReadablePath } from "../../utils/path" import { isPathOutsideWorkspace } from "../../utils/pathUtils" import { parseSourceCodeForDefinitionsTopLevel, parseSourceCodeDefinitionsForFile } from "../../services/tree-sitter" import { RecordSource } from "../context-tracking/FileContextTrackerTypes" +import { t } from "../../i18n" export async function listCodeDefinitionNamesTool( cline: Task, @@ -76,7 +77,11 @@ export async function listCodeDefinitionNamesTool( return } } catch (error) { - await handleError("parsing source code definitions", error) + await handleError( + "parsing source code definitions", + error, + t("tools:listCodeDefinitionNames.errors.parseError"), + ) return } } diff --git a/src/core/tools/listFilesTool.ts b/src/core/tools/listFilesTool.ts index e51453c5d9..aee3cda592 100644 --- a/src/core/tools/listFilesTool.ts +++ b/src/core/tools/listFilesTool.ts @@ -7,6 +7,7 @@ import { listFiles } from "../../services/glob/list-files" import { getReadablePath } from "../../utils/path" import { isPathOutsideWorkspace } from "../../utils/pathUtils" import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools" +import { t } from "../../i18n" /** * Implements the list_files tool. @@ -82,6 +83,6 @@ export async function listFilesTool( pushToolResult(result) } } catch (error) { - await handleError("listing files", error) + await handleError("listing files", error, t("tools:listFiles.errors.listFilesError")) } } diff --git a/src/core/tools/multiApplyDiffTool.ts b/src/core/tools/multiApplyDiffTool.ts index 50695b1da7..d141fee20c 100644 --- a/src/core/tools/multiApplyDiffTool.ts +++ b/src/core/tools/multiApplyDiffTool.ts @@ -3,6 +3,7 @@ import fs from "fs/promises" import { TelemetryService } from "@roo-code/telemetry" import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" +import { t } from "../../i18n" import { ClineSayTool } from "../../shared/ExtensionMessage" import { getReadablePath } from "../../utils/path" @@ -677,7 +678,7 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""} pushToolResult(results.join("\n\n") + singleBlockNotice) return } catch (error) { - await handleError("applying diff", error) + await handleError("applying diff", error, t("tools:applyDiff.errors.applyDiffError")) await cline.diffViewProvider.reset() return } diff --git a/src/core/tools/readFileTool.ts b/src/core/tools/readFileTool.ts index 01427f4d9d..6ab5906458 100644 --- a/src/core/tools/readFileTool.ts +++ b/src/core/tools/readFileTool.ts @@ -155,7 +155,7 @@ export async function readFileTool( } } catch (error) { const errorMessage = `Failed to parse read_file XML args: ${error instanceof Error ? error.message : String(error)}` - await handleError("parsing read_file args", new Error(errorMessage)) + await handleError("parsing read_file args", new Error(errorMessage), t("tools:readFile.errors.parseError")) pushToolResult(`${errorMessage}`) return } @@ -226,7 +226,11 @@ export async function readFileTool( error: errorMsg, xmlContent: `${relPath}Error reading file: ${errorMsg}`, }) - await handleError(`reading file ${relPath}`, new Error(errorMsg)) + await handleError( + `reading file ${relPath}`, + new Error(errorMsg), + t("tools:readFile.errors.invalidLineRange"), + ) hasRangeError = true break } @@ -237,7 +241,11 @@ export async function readFileTool( error: errorMsg, xmlContent: `${relPath}Error reading file: ${errorMsg}`, }) - await handleError(`reading file ${relPath}`, new Error(errorMsg)) + await handleError( + `reading file ${relPath}`, + new Error(errorMsg), + t("tools:readFile.errors.invalidLineRange"), + ) hasRangeError = true break } @@ -508,6 +516,7 @@ export async function readFileTool( await handleError( `reading image file ${relPath}`, error instanceof Error ? error : new Error(errorMsg), + t("tools:readFile.errors.imageReadError"), ) continue } @@ -616,7 +625,11 @@ export async function readFileTool( error: `Error reading file: ${errorMsg}`, xmlContent: `${relPath}Error reading file: ${errorMsg}`, }) - await handleError(`reading file ${relPath}`, error instanceof Error ? error : new Error(errorMsg)) + await handleError( + `reading file ${relPath}`, + error instanceof Error ? error : new Error(errorMsg), + t("tools:readFile.errors.fileReadError"), + ) } } @@ -704,8 +717,11 @@ export async function readFileTool( xmlContent: `${relPath}Error reading file: ${errorMsg}`, }) } - - await handleError(`reading file ${relPath}`, error instanceof Error ? error : new Error(errorMsg)) + await handleError( + `reading file ${relPath}`, + error instanceof Error ? error : new Error(errorMsg), + t("tools:readFile.errors.fileReadError"), + ) // Generate final XML result from all file results const xmlResults = fileResults.filter((result) => result.xmlContent).map((result) => result.xmlContent) diff --git a/src/core/tools/searchAndReplaceTool.ts b/src/core/tools/searchAndReplaceTool.ts index 4912934415..ca71c27ae0 100644 --- a/src/core/tools/searchAndReplaceTool.ts +++ b/src/core/tools/searchAndReplaceTool.ts @@ -13,6 +13,7 @@ import { fileExistsAtPath } from "../../utils/fs" import { RecordSource } from "../context-tracking/FileContextTrackerTypes" import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" +import { t } from "../../i18n" /** * Tool for performing search and replace operations on files @@ -137,7 +138,9 @@ export async function searchAndReplaceTool( const formattedError = formatResponse.toolError( `File does not exist at path: ${absolutePath}\nThe specified file could not be found. Please verify the file path and try again.`, ) - await cline.say("error", formattedError) + await cline.say("error", formattedError, undefined, undefined, undefined, undefined, { + metadata: { title: "File Not Found" }, + }) pushToolResult(formattedError) return } @@ -156,7 +159,9 @@ export async function searchAndReplaceTool( error instanceof Error ? error.message : String(error) }\nPlease verify file permissions and try again.` const formattedError = formatResponse.toolError(errorMessage) - await cline.say("error", formattedError) + await cline.say("error", formattedError, undefined, undefined, undefined, undefined, { + metadata: { title: "File Read Error" }, + }) pushToolResult(formattedError) return } @@ -264,7 +269,7 @@ export async function searchAndReplaceTool( cline.recordToolUsage("search_and_replace") await cline.diffViewProvider.reset() } catch (error) { - handleError("search and replace", error) + handleError("search and replace", error, t("tools:searchAndReplace.errors.searchAndReplaceError")) await cline.diffViewProvider.reset() } } diff --git a/src/core/tools/searchFilesTool.ts b/src/core/tools/searchFilesTool.ts index b6ee97f874..b5fd9c8e33 100644 --- a/src/core/tools/searchFilesTool.ts +++ b/src/core/tools/searchFilesTool.ts @@ -6,6 +6,7 @@ import { ClineSayTool } from "../../shared/ExtensionMessage" import { getReadablePath } from "../../utils/path" import { isPathOutsideWorkspace } from "../../utils/pathUtils" import { regexSearchFiles } from "../../services/ripgrep" +import { t } from "../../i18n" export async function searchFilesTool( cline: Task, @@ -72,7 +73,7 @@ export async function searchFilesTool( return } } catch (error) { - await handleError("searching files", error) + await handleError("searching files", error, t("tools:searchFiles.errors.searchFilesError")) return } } diff --git a/src/core/tools/simpleReadFileTool.ts b/src/core/tools/simpleReadFileTool.ts index ee6656c5c8..791ed721b4 100644 --- a/src/core/tools/simpleReadFileTool.ts +++ b/src/core/tools/simpleReadFileTool.ts @@ -180,6 +180,7 @@ export async function simpleReadFileTool( await handleError( `reading image file ${relPath}`, error instanceof Error ? error : new Error(errorMsg), + t("tools:readFile.errors.imageReadError"), ) return } @@ -268,7 +269,11 @@ export async function simpleReadFileTool( } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error) pushToolResult(`${relPath}Error reading file: ${errorMsg}`) - await handleError(`reading file ${relPath}`, error instanceof Error ? error : new Error(errorMsg)) + await handleError( + `reading file ${relPath}`, + error instanceof Error ? error : new Error(errorMsg), + t("tools:simpleReadFile.errors.readError"), + ) } } diff --git a/src/core/tools/switchModeTool.ts b/src/core/tools/switchModeTool.ts index 8ce906b41f..819190b540 100644 --- a/src/core/tools/switchModeTool.ts +++ b/src/core/tools/switchModeTool.ts @@ -4,6 +4,7 @@ import { Task } from "../task/Task" import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools" import { formatResponse } from "../prompts/responses" import { defaultModeSlug, getModeBySlug } from "../../shared/modes" +import { t } from "../../i18n" export async function switchModeTool( cline: Task, @@ -75,7 +76,7 @@ export async function switchModeTool( return } } catch (error) { - await handleError("switching mode", error) + await handleError("switching mode", error, t("tools:switchMode.errors.switchError")) return } } diff --git a/src/core/tools/updateTodoListTool.ts b/src/core/tools/updateTodoListTool.ts index de96c3cc76..d80a04c4b5 100644 --- a/src/core/tools/updateTodoListTool.ts +++ b/src/core/tools/updateTodoListTool.ts @@ -6,6 +6,7 @@ import cloneDeep from "clone-deep" import crypto from "crypto" import { TodoItem, TodoStatus, todoStatusSchema } from "@roo-code/types" import { getLatestTodo } from "../../shared/todo" +import { t } from "../../i18n" let approvedTodoList: TodoItem[] | undefined = undefined @@ -231,6 +232,6 @@ export async function updateTodoListTool( pushToolResult(formatResponse.toolResult("Todo list updated successfully.")) } } catch (error) { - await handleError("update todo list", error) + await handleError("update todo list", error, t("tools:updateTodoList.errors.updateError")) } } diff --git a/src/core/tools/useMcpToolTool.ts b/src/core/tools/useMcpToolTool.ts index 41697ab979..8801a487d6 100644 --- a/src/core/tools/useMcpToolTool.ts +++ b/src/core/tools/useMcpToolTool.ts @@ -62,7 +62,17 @@ async function validateParams( } catch (error) { cline.consecutiveMistakeCount++ cline.recordToolError("use_mcp_tool") - await cline.say("error", t("mcp:errors.invalidJsonArgument", { toolName: params.tool_name })) + await cline.say( + "error", + t("mcp:errors.invalidJsonArgument", { toolName: params.tool_name }), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "Invalid JSON Arguments" }, + }, + ) pushToolResult( formatResponse.toolError( @@ -109,7 +119,17 @@ async function validateToolExists( cline.consecutiveMistakeCount++ cline.recordToolError("use_mcp_tool") - await cline.say("error", t("mcp:errors.serverNotFound", { serverName, availableServers })) + await cline.say( + "error", + t("mcp:errors.serverNotFound", { serverName, availableServers }), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "MCP Server Not Found" }, + }, + ) pushToolResult(formatResponse.unknownMcpServerError(serverName, availableServersArray)) return { isValid: false, availableTools: [] } @@ -127,6 +147,13 @@ async function validateToolExists( serverName, availableTools: "No tools available", }), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "MCP Tool Not Found" }, + }, ) pushToolResult(formatResponse.unknownMcpToolError(serverName, toolName, [])) @@ -149,6 +176,13 @@ async function validateToolExists( serverName, availableTools: availableToolNames.join(", "), }), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "MCP Tool Not Found" }, + }, ) pushToolResult(formatResponse.unknownMcpToolError(serverName, toolName, availableToolNames)) @@ -171,6 +205,13 @@ async function validateToolExists( availableTools: enabledToolNames.length > 0 ? enabledToolNames.join(", ") : "No enabled tools available", }), + undefined, + undefined, + undefined, + undefined, + { + metadata: { title: "MCP Tool Disabled" }, + }, ) pushToolResult(formatResponse.unknownMcpToolError(serverName, toolName, enabledToolNames)) diff --git a/src/core/tools/writeToFileTool.ts b/src/core/tools/writeToFileTool.ts index e82eab92bc..090f2d5182 100644 --- a/src/core/tools/writeToFileTool.ts +++ b/src/core/tools/writeToFileTool.ts @@ -16,6 +16,7 @@ import { detectCodeOmission } from "../../integrations/editor/detect-omission" import { unescapeHtmlEntities } from "../../utils/text-normalization" import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" +import { t } from "../../i18n" export async function writeToFileTool( cline: Task, @@ -311,7 +312,7 @@ export async function writeToFileTool( return } } catch (error) { - await handleError("writing file", error) + await handleError("writing file", error, t("tools:writeToFile.errors.writeFileError")) await cline.diffViewProvider.reset() return } diff --git a/src/i18n/locales/ca/tools.json b/src/i18n/locales/ca/tools.json index 0f10b6fc2a..b24489371e 100644 --- a/src/i18n/locales/ca/tools.json +++ b/src/i18n/locales/ca/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (només definicions)", "maxLines": " (màxim {{max}} línies)", "imageTooLarge": "El fitxer d'imatge és massa gran ({{size}} MB). La mida màxima permesa és {{max}} MB.", - "imageWithSize": "Fitxer d'imatge ({{size}} KB)" + "imageWithSize": "Fitxer d'imatge ({{size}} KB)", + "errors": { + "parseError": "Error d'Anàlisi del Fitxer", + "invalidLineRange": "Rang de Línies Invàlid", + "imageReadError": "Error de Lectura d'Imatge", + "fileReadError": "Error de Lectura del Fitxer" + } }, "toolRepetitionLimitReached": "Roo sembla estar atrapat en un bucle, intentant la mateixa acció ({{toolName}}) repetidament. Això podria indicar un problema amb la seva estratègia actual. Considera reformular la tasca, proporcionar instruccions més específiques o guiar-lo cap a un enfocament diferent.", "codebaseSearch": { - "approval": "Cercant '{{query}}' a la base de codi..." + "approval": "Cercant '{{query}}' a la base de codi...", + "errors": { + "searchError": "Error de cerca de codi" + } }, "newTask": { "errors": { "policy_restriction": "No s'ha pogut crear una nova tasca a causa de restriccions de política." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Fitxer no trobat", + "fileDoesNotExist": "El fitxer no existeix al camí: {{path}}", + "fileDoesNotExistDetails": "No s'ha pogut trobar el fitxer especificat. Si us plau, verifica el camí del fitxer i torna-ho a provar.", + "applyDiffError": "Error d'Aplicació de Diff" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Número de línia invàlid", + "cannotInsertIntoNonExistent": "No es pot inserir contingut a la línia {{lineNumber}} d'un fitxer inexistent. Per a fitxers nous, 'line' ha de ser 0 (per afegir al final) o 1 (per inserir al principi).", + "insertContentError": "Error d'Inserció de Contingut" + } + }, + "common": { + "errors": { + "missingParameter": "Paràmetre que falta", + "missingParameterMessage": "Roo ha intentat utilitzar {{toolName}}{{relPath}} sense valor per al paràmetre requerit '{{paramName}}'. Tornant a intentar..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Error d'Escriptura del Fitxer" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Error de Cerca i Substitució" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Error en llistar fitxers" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Error en cercar fitxers" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Error en analitzar definicions de codi" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Error en obtenir instruccions" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Error en actualitzar la llista de tasques" + } + }, + "executeCommand": { + "errors": { + "executeError": "Error en executar l'ordre" + } + }, + "browserAction": { + "errors": { + "browserError": "Error d'acció del navegador" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Error en fer la pregunta" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Error en inspeccionar el lloc" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Error en executar l'ordre slash" + } + }, + "generateImage": { + "errors": { + "generateError": "Error en generar la imatge" + } + }, + "newTaskTool": { + "errors": { + "createError": "Error en crear una nova tasca" + } + }, + "switchMode": { + "errors": { + "switchError": "Error en canviar de mode" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Error en accedir al recurs MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Error en executar l'eina MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Error en llegir el fitxer" + } } } diff --git a/src/i18n/locales/de/tools.json b/src/i18n/locales/de/tools.json index ecf372a50b..c75a45c74b 100644 --- a/src/i18n/locales/de/tools.json +++ b/src/i18n/locales/de/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (nur Definitionen)", "maxLines": " (maximal {{max}} Zeilen)", "imageTooLarge": "Die Bilddatei ist zu groß ({{size}} MB). Die maximal erlaubte Größe beträgt {{max}} MB.", - "imageWithSize": "Bilddatei ({{size}} KB)" + "imageWithSize": "Bilddatei ({{size}} KB)", + "errors": { + "parseError": "Datei-Parse-Fehler", + "invalidLineRange": "Ungültiger Zeilenbereich", + "imageReadError": "Bildlesefehler", + "fileReadError": "Dateilesefehler" + } }, "toolRepetitionLimitReached": "Roo scheint in einer Schleife festzustecken und versucht wiederholt dieselbe Aktion ({{toolName}}). Dies könnte auf ein Problem mit der aktuellen Strategie hindeuten. Überlege dir, die Aufgabe umzuformulieren, genauere Anweisungen zu geben oder Roo zu einem anderen Ansatz zu führen.", "codebaseSearch": { - "approval": "Suche nach '{{query}}' im Codebase..." + "approval": "Suche nach '{{query}}' im Codebase...", + "errors": { + "searchError": "Codebase-Suchfehler" + } }, "newTask": { "errors": { "policy_restriction": "Neue Aufgabe konnte aufgrund von Richtlinienbeschränkungen nicht erstellt werden." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Datei nicht gefunden", + "fileDoesNotExist": "Datei existiert nicht unter dem Pfad: {{path}}", + "fileDoesNotExistDetails": "Die angegebene Datei konnte nicht gefunden werden. Bitte überprüfe den Dateipfad und versuche es erneut.", + "applyDiffError": "Diff-Anwendungsfehler" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Ungültige Zeilennummer", + "cannotInsertIntoNonExistent": "Inhalt kann nicht in Zeile {{lineNumber}} einer nicht existierenden Datei eingefügt werden. Für neue Dateien muss 'line' 0 (zum Anhängen) oder 1 (zum Einfügen am Anfang) sein.", + "insertContentError": "Inhaltseinfügefehler" + } + }, + "common": { + "errors": { + "missingParameter": "Fehlender Parameter", + "missingParameterMessage": "Roo hat versucht, {{toolName}}{{relPath}} ohne Wert für den erforderlichen Parameter '{{paramName}}' zu verwenden. Versuche erneut..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Dateischreibfehler" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Suchen und Ersetzen Fehler" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Dateilistenfehler" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Dateisuchfehler" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Code-Definitionen-Analysefehler" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Anweisungsabruffehler" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Todo-Listen-Aktualisierungsfehler" + } + }, + "executeCommand": { + "errors": { + "executeError": "Befehlsausführungsfehler" + } + }, + "browserAction": { + "errors": { + "browserError": "Browser-Aktionsfehler" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Fragefehler" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Website-Inspektionsfehler" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Slash-Befehlsfehler" + } + }, + "generateImage": { + "errors": { + "generateError": "Bilderzeugungsfehler" + } + }, + "newTaskTool": { + "errors": { + "createError": "Neue Aufgabe Erstellungsfehler" + } + }, + "switchMode": { + "errors": { + "switchError": "Moduswechselfehler" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "MCP-Ressourcenzugriffsfehler" + } + }, + "useMcpTool": { + "errors": { + "executeError": "MCP-Tool-Ausführungsfehler" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Dateilesefehler" + } } } diff --git a/src/i18n/locales/en/tools.json b/src/i18n/locales/en/tools.json index 5b88affae6..81a10df8e0 100644 --- a/src/i18n/locales/en/tools.json +++ b/src/i18n/locales/en/tools.json @@ -4,7 +4,13 @@ "definitionsOnly": " (definitions only)", "maxLines": " (max {{max}} lines)", "imageTooLarge": "Image file is too large ({{size}} MB). The maximum allowed size is {{max}} MB.", - "imageWithSize": "Image file ({{size}} KB)" + "imageWithSize": "Image file ({{size}} KB)", + "errors": { + "parseError": "Read File Parse Error", + "invalidLineRange": "Invalid Line Range", + "imageReadError": "Image Read Error", + "fileReadError": "File Read Error" + } }, "toolRepetitionLimitReached": "Roo appears to be stuck in a loop, attempting the same action ({{toolName}}) repeatedly. This might indicate a problem with its current strategy. Consider rephrasing the task, providing more specific instructions, or guiding it towards a different approach.", "codebaseSearch": { @@ -14,5 +20,121 @@ "errors": { "policy_restriction": "Failed to create new task due to policy restrictions." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "File Not Found", + "fileDoesNotExist": "File does not exist at path: {{path}}", + "fileDoesNotExistDetails": "The specified file could not be found. Please verify the file path and try again.", + "applyDiffError": "Apply Diff Error" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Invalid Line Number", + "cannotInsertIntoNonExistent": "Cannot insert content at line {{lineNumber}} into a non-existent file. For new files, 'line' must be 0 (to append) or 1 (to insert at the beginning).", + "insertContentError": "Insert Content Error" + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Write File Error" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Search and Replace Error" + } + }, + "listFiles": { + "errors": { + "listFilesError": "List Files Error" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Search Files Error" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Parse Code Definitions Error" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Fetch Instructions Error" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Update Todo List Error" + } + }, + "executeCommand": { + "errors": { + "executeError": "Execute Command Error" + } + }, + "browserAction": { + "errors": { + "browserError": "Browser Action Error" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Ask Question Error" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Inspect Site Error" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Run Slash Command Error" + } + }, + "generateImage": { + "errors": { + "generateError": "Generate Image Error" + } + }, + "newTaskTool": { + "errors": { + "createError": "Create New Task Error" + } + }, + "codebaseSearch": { + "errors": { + "searchError": "Codebase Search Error" + } + }, + "switchMode": { + "errors": { + "switchError": "Switch Mode Error" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Access MCP Resource Error" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Execute MCP Tool Error" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Read File Error" + } + }, + "common": { + "errors": { + "missingParameter": "Missing Parameter Error", + "missingParameterMessage": "Roo tried to use {{toolName}}{{relPath}} without value for required parameter '{{paramName}}'. Retrying..." + } } } diff --git a/src/i18n/locales/es/tools.json b/src/i18n/locales/es/tools.json index 6fd1cc2122..f8600113e2 100644 --- a/src/i18n/locales/es/tools.json +++ b/src/i18n/locales/es/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (solo definiciones)", "maxLines": " (máximo {{max}} líneas)", "imageTooLarge": "El archivo de imagen es demasiado grande ({{size}} MB). El tamaño máximo permitido es {{max}} MB.", - "imageWithSize": "Archivo de imagen ({{size}} KB)" + "imageWithSize": "Archivo de imagen ({{size}} KB)", + "errors": { + "parseError": "Error de Análisis de Archivo", + "invalidLineRange": "Rango de Líneas Inválido", + "imageReadError": "Error de Lectura de Imagen", + "fileReadError": "Error de Lectura de Archivo" + } }, "toolRepetitionLimitReached": "Roo parece estar atrapado en un bucle, intentando la misma acción ({{toolName}}) repetidamente. Esto podría indicar un problema con su estrategia actual. Considera reformular la tarea, proporcionar instrucciones más específicas o guiarlo hacia un enfoque diferente.", "codebaseSearch": { - "approval": "Buscando '{{query}}' en la base de código..." + "approval": "Buscando '{{query}}' en la base de código...", + "errors": { + "searchError": "Error de búsqueda de código" + } }, "newTask": { "errors": { "policy_restriction": "No se pudo crear una nueva tarea debido a restricciones de política." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Archivo no encontrado", + "fileDoesNotExist": "El archivo no existe en la ruta: {{path}}", + "fileDoesNotExistDetails": "No se pudo encontrar el archivo especificado. Por favor, verifica la ruta del archivo e intenta de nuevo.", + "applyDiffError": "Error al Aplicar Diff" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Número de línea inválido", + "cannotInsertIntoNonExistent": "No se puede insertar contenido en la línea {{lineNumber}} de un archivo inexistente. Para archivos nuevos, 'line' debe ser 0 (para añadir al final) o 1 (para insertar al principio).", + "insertContentError": "Error al Insertar Contenido" + } + }, + "common": { + "errors": { + "missingParameter": "Parámetro faltante", + "missingParameterMessage": "Roo intentó usar {{toolName}}{{relPath}} sin valor para el parámetro requerido '{{paramName}}'. Reintentando..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Error de Escritura de Archivo" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Error de Búsqueda y Reemplazo" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Error al listar archivos" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Error al buscar archivos" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Error al analizar definiciones de código" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Error al obtener instrucciones" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Error al actualizar lista de tareas" + } + }, + "executeCommand": { + "errors": { + "executeError": "Error al ejecutar comando" + } + }, + "browserAction": { + "errors": { + "browserError": "Error de acción del navegador" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Error al hacer pregunta" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Error al inspeccionar sitio" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Error al ejecutar comando slash" + } + }, + "generateImage": { + "errors": { + "generateError": "Error al generar imagen" + } + }, + "newTaskTool": { + "errors": { + "createError": "Error al crear nueva tarea" + } + }, + "switchMode": { + "errors": { + "switchError": "Error al cambiar modo" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Error al acceder recurso MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Error al ejecutar herramienta MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Error al leer archivo" + } } } diff --git a/src/i18n/locales/fr/tools.json b/src/i18n/locales/fr/tools.json index b6d7accebb..91ba148e20 100644 --- a/src/i18n/locales/fr/tools.json +++ b/src/i18n/locales/fr/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (définitions uniquement)", "maxLines": " (max {{max}} lignes)", "imageTooLarge": "Le fichier image est trop volumineux ({{size}} MB). La taille maximale autorisée est {{max}} MB.", - "imageWithSize": "Fichier image ({{size}} Ko)" + "imageWithSize": "Fichier image ({{size}} Ko)", + "errors": { + "parseError": "Erreur d'Analyse du Fichier", + "invalidLineRange": "Plage de Lignes Invalide", + "imageReadError": "Erreur de Lecture d'Image", + "fileReadError": "Erreur de Lecture du Fichier" + } }, "toolRepetitionLimitReached": "Roo semble être bloqué dans une boucle, tentant la même action ({{toolName}}) de façon répétée. Cela pourrait indiquer un problème avec sa stratégie actuelle. Envisage de reformuler la tâche, de fournir des instructions plus spécifiques ou de le guider vers une approche différente.", "codebaseSearch": { - "approval": "Recherche de '{{query}}' dans la base de code..." + "approval": "Recherche de '{{query}}' dans la base de code...", + "errors": { + "searchError": "Erreur de recherche de code" + } }, "newTask": { "errors": { "policy_restriction": "Impossible de créer une nouvelle tâche en raison de restrictions de politique." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Fichier introuvable", + "fileDoesNotExist": "Le fichier n'existe pas au chemin : {{path}}", + "fileDoesNotExistDetails": "Le fichier spécifié n'a pas pu être trouvé. Veuillez vérifier le chemin du fichier et réessayer.", + "applyDiffError": "Erreur d'Application de Diff" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Numéro de ligne invalide", + "cannotInsertIntoNonExistent": "Impossible d'insérer du contenu à la ligne {{lineNumber}} dans un fichier inexistant. Pour les nouveaux fichiers, 'line' doit être 0 (pour ajouter à la fin) ou 1 (pour insérer au début).", + "insertContentError": "Erreur d'Insertion de Contenu" + } + }, + "common": { + "errors": { + "missingParameter": "Paramètre manquant", + "missingParameterMessage": "Roo a essayé d'utiliser {{toolName}}{{relPath}} sans valeur pour le paramètre requis '{{paramName}}'. Nouvelle tentative..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Erreur d'Écriture du Fichier" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Erreur de Recherche et Remplacement" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Erreur de liste de fichiers" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Erreur de recherche de fichiers" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Erreur d'analyse des définitions de code" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Erreur de récupération des instructions" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Erreur de mise à jour de la liste de tâches" + } + }, + "executeCommand": { + "errors": { + "executeError": "Erreur d'exécution de commande" + } + }, + "browserAction": { + "errors": { + "browserError": "Erreur d'action du navigateur" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Erreur de question" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Erreur d'inspection du site" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Erreur d'exécution de commande slash" + } + }, + "generateImage": { + "errors": { + "generateError": "Erreur de génération d'image" + } + }, + "newTaskTool": { + "errors": { + "createError": "Erreur de création de nouvelle tâche" + } + }, + "switchMode": { + "errors": { + "switchError": "Erreur de changement de mode" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Erreur d'accès à la ressource MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Erreur d'exécution de l'outil MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Erreur de lecture de fichier" + } } } diff --git a/src/i18n/locales/hi/tools.json b/src/i18n/locales/hi/tools.json index cbfbd7aef7..fc11440b83 100644 --- a/src/i18n/locales/hi/tools.json +++ b/src/i18n/locales/hi/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (केवल परिभाषाएँ)", "maxLines": " (अधिकतम {{max}} पंक्तियाँ)", "imageTooLarge": "छवि फ़ाइल बहुत बड़ी है ({{size}} MB)। अधिकतम अनुमतित आकार {{max}} MB है।", - "imageWithSize": "छवि फ़ाइल ({{size}} KB)" + "imageWithSize": "छवि फ़ाइल ({{size}} KB)", + "errors": { + "parseError": "फ़ाइल पार्स त्रुटि", + "invalidLineRange": "अमान्य लाइन रेंज", + "imageReadError": "छवि पढ़ने में त्रुटि", + "fileReadError": "फ़ाइल पढ़ने में त्रुटि" + } }, "toolRepetitionLimitReached": "Roo एक लूप में फंसा हुआ लगता है, बार-बार एक ही क्रिया ({{toolName}}) को दोहरा रहा है। यह उसकी वर्तमान रणनीति में किसी समस्या का संकेत हो सकता है। कार्य को पुनः परिभाषित करने, अधिक विशिष्ट निर्देश देने, या उसे एक अलग दृष्टिकोण की ओर मार्गदर्शित करने पर विचार करें।", "codebaseSearch": { - "approval": "कोडबेस में '{{query}}' खोज रहा है..." + "approval": "कोडबेस में '{{query}}' खोज रहा है...", + "errors": { + "searchError": "कोडबेस खोज त्रुटि" + } }, "newTask": { "errors": { "policy_restriction": "नीति प्रतिबंधों के कारण नया कार्य बनाने में विफल।" } + }, + "applyDiff": { + "errors": { + "fileNotFound": "फ़ाइल नहीं मिली", + "fileDoesNotExist": "फ़ाइल पथ पर मौजूद नहीं है: {{path}}", + "fileDoesNotExistDetails": "निर्दिष्ट फ़ाइल नहीं मिल सकी। कृपया फ़ाइल पथ सत्यापित करें और पुनः प्रयास करें।", + "applyDiffError": "डिफ लागू करने में त्रुटि" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "अमान्य लाइन नंबर", + "cannotInsertIntoNonExistent": "गैर-मौजूद फ़ाइल की लाइन {{lineNumber}} में सामग्री नहीं डाली जा सकती। नई फ़ाइलों के लिए, 'line' 0 (अंत में जोड़ने के लिए) या 1 (शुरुआत में डालने के लिए) होनी चाहिए।", + "insertContentError": "सामग्री डालने में त्रुटि" + } + }, + "common": { + "errors": { + "missingParameter": "गुम पैरामीटर", + "missingParameterMessage": "Roo ने आवश्यक पैरामीटर '{{paramName}}' के लिए मान के बिना {{toolName}}{{relPath}} का उपयोग करने का प्रयास किया। पुनः प्रयास कर रहा है..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "फ़ाइल लिखने में त्रुटि" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "खोज और बदलाव त्रुटि" + } + }, + "listFiles": { + "errors": { + "listFilesError": "फ़ाइल सूची त्रुटि" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "फ़ाइल खोज त्रुटि" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "कोड परिभाषा पार्स त्रुटि" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "निर्देश प्राप्त करने में त्रुटि" + } + }, + "updateTodoList": { + "errors": { + "updateError": "टूडू सूची अपडेट त्रुटि" + } + }, + "executeCommand": { + "errors": { + "executeError": "कमांड निष्पादन त्रुटि" + } + }, + "browserAction": { + "errors": { + "browserError": "ब्राउज़र क्रिया त्रुटि" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "प्रश्न पूछने में त्रुटि" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "साइट निरीक्षण त्रुटि" + } + }, + "runSlashCommand": { + "errors": { + "runError": "स्लैश कमांड त्रुटि" + } + }, + "generateImage": { + "errors": { + "generateError": "छवि जनरेट त्रुटि" + } + }, + "newTaskTool": { + "errors": { + "createError": "नया कार्य बनाने में त्रुटि" + } + }, + "switchMode": { + "errors": { + "switchError": "मोड स्विच त्रुटि" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "MCP संसाधन पहुंच त्रुटि" + } + }, + "useMcpTool": { + "errors": { + "executeError": "MCP टूल निष्पादन त्रुटि" + } + }, + "simpleReadFile": { + "errors": { + "readError": "फ़ाइल पढ़ने में त्रुटि" + } } } diff --git a/src/i18n/locales/id/tools.json b/src/i18n/locales/id/tools.json index 3eb8854eff..b65c2d4961 100644 --- a/src/i18n/locales/id/tools.json +++ b/src/i18n/locales/id/tools.json @@ -4,18 +4,136 @@ "definitionsOnly": " (hanya definisi)", "maxLines": " (maks {{max}} baris)", "imageTooLarge": "File gambar terlalu besar ({{size}} MB). Ukuran maksimum yang diizinkan adalah {{max}} MB.", - "imageWithSize": "File gambar ({{size}} KB)" + "imageWithSize": "File gambar ({{size}} KB)", + "errors": { + "parseError": "Kesalahan Parse File", + "invalidLineRange": "Rentang Baris Tidak Valid", + "imageReadError": "Kesalahan Membaca Gambar", + "fileReadError": "Kesalahan Membaca File" + } }, "toolRepetitionLimitReached": "Roo tampaknya terjebak dalam loop, mencoba aksi yang sama ({{toolName}}) berulang kali. Ini mungkin menunjukkan masalah dengan strategi saat ini. Pertimbangkan untuk mengubah frasa tugas, memberikan instruksi yang lebih spesifik, atau mengarahkannya ke pendekatan yang berbeda.", "codebaseSearch": { - "approval": "Mencari '{{query}}' di codebase..." + "approval": "Mencari '{{query}}' di codebase...", + "errors": { + "searchError": "Kesalahan Pencarian Kode" + } }, "searchFiles": { - "workspaceBoundaryError": "Tidak dapat mencari di luar workspace. Path '{{path}}' berada di luar workspace saat ini." + "workspaceBoundaryError": "Tidak dapat mencari di luar workspace. Path '{{path}}' berada di luar workspace saat ini.", + "errors": { + "searchFilesError": "Kesalahan Pencarian File" + } }, "newTask": { "errors": { "policy_restriction": "Gagal membuat tugas baru karena pembatasan kebijakan." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "File Tidak Ditemukan", + "fileDoesNotExist": "File tidak ada di path: {{path}}", + "fileDoesNotExistDetails": "File yang ditentukan tidak dapat ditemukan. Silakan verifikasi path file dan coba lagi.", + "applyDiffError": "Kesalahan Menerapkan Diff" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Nomor Baris Tidak Valid", + "cannotInsertIntoNonExistent": "Tidak dapat menyisipkan konten di baris {{lineNumber}} ke file yang tidak ada. Untuk file baru, 'line' harus 0 (untuk menambahkan di akhir) atau 1 (untuk menyisipkan di awal).", + "insertContentError": "Kesalahan Menyisipkan Konten" + } + }, + "common": { + "errors": { + "missingParameter": "Parameter Hilang", + "missingParameterMessage": "Roo mencoba menggunakan {{toolName}}{{relPath}} tanpa nilai untuk parameter yang diperlukan '{{paramName}}'. Mencoba lagi..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Kesalahan Menulis File" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Kesalahan Cari dan Ganti" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Kesalahan Daftar File" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Kesalahan Parse Definisi Kode" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Kesalahan Mengambil Instruksi" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Kesalahan Pembaruan Daftar Todo" + } + }, + "executeCommand": { + "errors": { + "executeError": "Kesalahan Eksekusi Perintah" + } + }, + "browserAction": { + "errors": { + "browserError": "Kesalahan Aksi Browser" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Kesalahan Mengajukan Pertanyaan" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Kesalahan Inspeksi Situs" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Kesalahan Menjalankan Perintah Slash" + } + }, + "generateImage": { + "errors": { + "generateError": "Kesalahan Menghasilkan Gambar" + } + }, + "newTaskTool": { + "errors": { + "createError": "Kesalahan Membuat Tugas Baru" + } + }, + "switchMode": { + "errors": { + "switchError": "Kesalahan Beralih Mode" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Kesalahan Akses Sumber Daya MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Kesalahan Eksekusi Alat MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Kesalahan Membaca File" + } } } diff --git a/src/i18n/locales/it/tools.json b/src/i18n/locales/it/tools.json index 35b114a719..fb127f1d9b 100644 --- a/src/i18n/locales/it/tools.json +++ b/src/i18n/locales/it/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (solo definizioni)", "maxLines": " (max {{max}} righe)", "imageTooLarge": "Il file immagine è troppo grande ({{size}} MB). La dimensione massima consentita è {{max}} MB.", - "imageWithSize": "File immagine ({{size}} KB)" + "imageWithSize": "File immagine ({{size}} KB)", + "errors": { + "parseError": "Errore di Analisi del File", + "invalidLineRange": "Intervallo di Righe Non Valido", + "imageReadError": "Errore di Lettura Immagine", + "fileReadError": "Errore di Lettura del File" + } }, "toolRepetitionLimitReached": "Roo sembra essere bloccato in un ciclo, tentando ripetutamente la stessa azione ({{toolName}}). Questo potrebbe indicare un problema con la sua strategia attuale. Considera di riformulare l'attività, fornire istruzioni più specifiche o guidarlo verso un approccio diverso.", "codebaseSearch": { - "approval": "Ricerca di '{{query}}' nella base di codice..." + "approval": "Ricerca di '{{query}}' nella base di codice...", + "errors": { + "searchError": "Errore ricerca codice" + } }, "newTask": { "errors": { "policy_restriction": "Impossibile creare una nuova attività a causa di restrizioni di policy." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "File non trovato", + "fileDoesNotExist": "Il file non esiste nel percorso: {{path}}", + "fileDoesNotExistDetails": "Il file specificato non è stato trovato. Verifica il percorso del file e riprova.", + "applyDiffError": "Errore nell'Applicazione del Diff" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Numero di riga non valido", + "cannotInsertIntoNonExistent": "Impossibile inserire contenuto alla riga {{lineNumber}} in un file inesistente. Per i nuovi file, 'line' deve essere 0 (per aggiungere alla fine) o 1 (per inserire all'inizio).", + "insertContentError": "Errore nell'Inserimento del Contenuto" + } + }, + "common": { + "errors": { + "missingParameter": "Parametro mancante", + "missingParameterMessage": "Roo ha tentato di usare {{toolName}}{{relPath}} senza valore per il parametro richiesto '{{paramName}}'. Nuovo tentativo..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Errore di Scrittura del File" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Errore di Ricerca e Sostituzione" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Errore elenco file" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Errore ricerca file" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Errore analisi definizioni codice" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Errore recupero istruzioni" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Errore aggiornamento lista todo" + } + }, + "executeCommand": { + "errors": { + "executeError": "Errore esecuzione comando" + } + }, + "browserAction": { + "errors": { + "browserError": "Errore azione browser" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Errore domanda" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Errore ispezione sito" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Errore esecuzione comando slash" + } + }, + "generateImage": { + "errors": { + "generateError": "Errore generazione immagine" + } + }, + "newTaskTool": { + "errors": { + "createError": "Errore creazione nuova attività" + } + }, + "switchMode": { + "errors": { + "switchError": "Errore cambio modalità" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Errore accesso risorsa MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Errore esecuzione strumento MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Errore lettura file" + } } } diff --git a/src/i18n/locales/ja/tools.json b/src/i18n/locales/ja/tools.json index 257d5aa201..1a10902bed 100644 --- a/src/i18n/locales/ja/tools.json +++ b/src/i18n/locales/ja/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (定義のみ)", "maxLines": " (最大{{max}}行)", "imageTooLarge": "画像ファイルが大きすぎます({{size}} MB)。最大許可サイズは {{max}} MB です。", - "imageWithSize": "画像ファイル({{size}} KB)" + "imageWithSize": "画像ファイル({{size}} KB)", + "errors": { + "parseError": "ファイル解析エラー", + "invalidLineRange": "無効な行範囲", + "imageReadError": "画像読み取りエラー", + "fileReadError": "ファイル読み取りエラー" + } }, "toolRepetitionLimitReached": "Rooが同じ操作({{toolName}})を繰り返し試みるループに陥っているようです。これは現在の方法に問題がある可能性を示しています。タスクの言い換え、より具体的な指示の提供、または別のアプローチへの誘導を検討してください。", "codebaseSearch": { - "approval": "コードベースで '{{query}}' を検索中..." + "approval": "コードベースで '{{query}}' を検索中...", + "errors": { + "searchError": "コードベース検索エラー" + } }, "newTask": { "errors": { "policy_restriction": "ポリシー制限により新しいタスクを作成できませんでした。" } + }, + "applyDiff": { + "errors": { + "fileNotFound": "ファイルが見つかりません", + "fileDoesNotExist": "ファイルがパスに存在しません: {{path}}", + "fileDoesNotExistDetails": "指定されたファイルが見つかりませんでした。ファイルパスを確認して、もう一度お試しください。", + "applyDiffError": "差分適用エラー" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "無効な行番号", + "cannotInsertIntoNonExistent": "存在しないファイルの{{lineNumber}}行目にコンテンツを挿入できません。新しいファイルの場合、'line'は0(末尾に追加)または1(先頭に挿入)である必要があります。", + "insertContentError": "コンテンツ挿入エラー" + } + }, + "common": { + "errors": { + "missingParameter": "パラメータ不足", + "missingParameterMessage": "Rooは必須パラメータ'{{paramName}}'の値なしで{{toolName}}{{relPath}}を使用しようとしました。再試行中..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "ファイル書き込みエラー" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "検索と置換エラー" + } + }, + "listFiles": { + "errors": { + "listFilesError": "ファイル一覧エラー" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "ファイル検索エラー" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "コード定義解析エラー" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "指示取得エラー" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Todoリスト更新エラー" + } + }, + "executeCommand": { + "errors": { + "executeError": "コマンド実行エラー" + } + }, + "browserAction": { + "errors": { + "browserError": "ブラウザアクションエラー" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "質問エラー" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "サイト検査エラー" + } + }, + "runSlashCommand": { + "errors": { + "runError": "スラッシュコマンド実行エラー" + } + }, + "generateImage": { + "errors": { + "generateError": "画像生成エラー" + } + }, + "newTaskTool": { + "errors": { + "createError": "新規タスク作成エラー" + } + }, + "switchMode": { + "errors": { + "switchError": "モード切替エラー" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "MCPリソースアクセスエラー" + } + }, + "useMcpTool": { + "errors": { + "executeError": "MCPツール実行エラー" + } + }, + "simpleReadFile": { + "errors": { + "readError": "ファイル読み取りエラー" + } } } diff --git a/src/i18n/locales/ko/tools.json b/src/i18n/locales/ko/tools.json index 94b6d8c377..f15af486d6 100644 --- a/src/i18n/locales/ko/tools.json +++ b/src/i18n/locales/ko/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (정의만)", "maxLines": " (최대 {{max}}행)", "imageTooLarge": "이미지 파일이 너무 큽니다 ({{size}} MB). 최대 허용 크기는 {{max}} MB입니다.", - "imageWithSize": "이미지 파일 ({{size}} KB)" + "imageWithSize": "이미지 파일 ({{size}} KB)", + "errors": { + "parseError": "파일 구문 분석 오류", + "invalidLineRange": "잘못된 줄 범위", + "imageReadError": "이미지 읽기 오류", + "fileReadError": "파일 읽기 오류" + } }, "toolRepetitionLimitReached": "Roo가 같은 동작({{toolName}})을 반복적으로 시도하면서 루프에 갇힌 것 같습니다. 이는 현재 전략에 문제가 있을 수 있음을 나타냅니다. 작업을 다시 표현하거나, 더 구체적인 지침을 제공하거나, 다른 접근 방식으로 안내해 보세요.", "codebaseSearch": { - "approval": "코드베이스에서 '{{query}}' 검색 중..." + "approval": "코드베이스에서 '{{query}}' 검색 중...", + "errors": { + "searchError": "코드베이스 검색 오류" + } }, "newTask": { "errors": { "policy_restriction": "정책 제한으로 인해 새 작업을 생성하지 못했습니다." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "파일을 찾을 수 없음", + "fileDoesNotExist": "파일이 경로에 존재하지 않습니다: {{path}}", + "fileDoesNotExistDetails": "지정된 파일을 찾을 수 없습니다. 파일 경로를 확인하고 다시 시도해 주세요.", + "applyDiffError": "차이점 적용 오류" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "잘못된 줄 번호", + "cannotInsertIntoNonExistent": "존재하지 않는 파일의 {{lineNumber}}번째 줄에 내용을 삽입할 수 없습니다. 새 파일의 경우 'line'은 0(끝에 추가) 또는 1(시작 부분에 삽입)이어야 합니다.", + "insertContentError": "콘텐츠 삽입 오류" + } + }, + "common": { + "errors": { + "missingParameter": "누락된 매개변수", + "missingParameterMessage": "Roo가 필수 매개변수 '{{paramName}}'의 값 없이 {{toolName}}{{relPath}}를 사용하려고 했습니다. 다시 시도 중..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "파일 쓰기 오류" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "검색 및 바꾸기 오류" + } + }, + "listFiles": { + "errors": { + "listFilesError": "파일 목록 오류" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "파일 검색 오류" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "코드 정의 구문 분석 오류" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "지침 가져오기 오류" + } + }, + "updateTodoList": { + "errors": { + "updateError": "할 일 목록 업데이트 오류" + } + }, + "executeCommand": { + "errors": { + "executeError": "명령 실행 오류" + } + }, + "browserAction": { + "errors": { + "browserError": "브라우저 작업 오류" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "질문 오류" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "사이트 검사 오류" + } + }, + "runSlashCommand": { + "errors": { + "runError": "슬래시 명령 실행 오류" + } + }, + "generateImage": { + "errors": { + "generateError": "이미지 생성 오류" + } + }, + "newTaskTool": { + "errors": { + "createError": "새 작업 생성 오류" + } + }, + "switchMode": { + "errors": { + "switchError": "모드 전환 오류" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "MCP 리소스 액세스 오류" + } + }, + "useMcpTool": { + "errors": { + "executeError": "MCP 도구 실행 오류" + } + }, + "simpleReadFile": { + "errors": { + "readError": "파일 읽기 오류" + } } } diff --git a/src/i18n/locales/nl/tools.json b/src/i18n/locales/nl/tools.json index 449cd54583..5171416ffd 100644 --- a/src/i18n/locales/nl/tools.json +++ b/src/i18n/locales/nl/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (alleen definities)", "maxLines": " (max {{max}} regels)", "imageTooLarge": "Afbeeldingsbestand is te groot ({{size}} MB). De maximaal toegestane grootte is {{max}} MB.", - "imageWithSize": "Afbeeldingsbestand ({{size}} KB)" + "imageWithSize": "Afbeeldingsbestand ({{size}} KB)", + "errors": { + "parseError": "Bestand Parse Fout", + "invalidLineRange": "Ongeldig Regelbereik", + "imageReadError": "Afbeelding Leesfout", + "fileReadError": "Bestand Leesfout" + } }, "toolRepetitionLimitReached": "Roo lijkt vast te zitten in een lus, waarbij hij herhaaldelijk dezelfde actie ({{toolName}}) probeert. Dit kan duiden op een probleem met de huidige strategie. Overweeg de taak te herformuleren, specifiekere instructies te geven of Roo naar een andere aanpak te leiden.", "codebaseSearch": { - "approval": "Zoeken naar '{{query}}' in codebase..." + "approval": "Zoeken naar '{{query}}' in codebase...", + "errors": { + "searchError": "Codebase zoekfout" + } }, "newTask": { "errors": { "policy_restriction": "Kan geen nieuwe taak aanmaken vanwege beleidsbeperkingen." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Bestand niet gevonden", + "fileDoesNotExist": "Bestand bestaat niet op pad: {{path}}", + "fileDoesNotExistDetails": "Het opgegeven bestand kon niet worden gevonden. Controleer het bestandspad en probeer het opnieuw.", + "applyDiffError": "Diff Toepassingsfout" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Ongeldig regelnummer", + "cannotInsertIntoNonExistent": "Kan geen inhoud invoegen op regel {{lineNumber}} in een niet-bestaand bestand. Voor nieuwe bestanden moet 'line' 0 zijn (om toe te voegen aan het einde) of 1 (om in te voegen aan het begin).", + "insertContentError": "Inhoud Invoegfout" + } + }, + "common": { + "errors": { + "missingParameter": "Ontbrekende parameter", + "missingParameterMessage": "Roo probeerde {{toolName}}{{relPath}} te gebruiken zonder waarde voor de vereiste parameter '{{paramName}}'. Opnieuw proberen..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Bestand Schrijffout" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Zoek en Vervang Fout" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Bestandslijstfout" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Bestandszoekfout" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Code-definitie parseerfout" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Instructies ophalfout" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Todo-lijst updatefout" + } + }, + "executeCommand": { + "errors": { + "executeError": "Opdracht uitvoerfout" + } + }, + "browserAction": { + "errors": { + "browserError": "Browser-actiefout" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Vraagfout" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Site-inspectiefout" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Slash-opdracht uitvoerfout" + } + }, + "generateImage": { + "errors": { + "generateError": "Afbeelding generatiefout" + } + }, + "newTaskTool": { + "errors": { + "createError": "Nieuwe taak aanmaakfout" + } + }, + "switchMode": { + "errors": { + "switchError": "Modus wisselfout" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "MCP-bron toegangsfout" + } + }, + "useMcpTool": { + "errors": { + "executeError": "MCP-tool uitvoerfout" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Bestand leesfout" + } } } diff --git a/src/i18n/locales/pl/tools.json b/src/i18n/locales/pl/tools.json index 979b2f54ae..d679783019 100644 --- a/src/i18n/locales/pl/tools.json +++ b/src/i18n/locales/pl/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (tylko definicje)", "maxLines": " (maks. {{max}} linii)", "imageTooLarge": "Plik obrazu jest zbyt duży ({{size}} MB). Maksymalny dozwolony rozmiar to {{max}} MB.", - "imageWithSize": "Plik obrazu ({{size}} KB)" + "imageWithSize": "Plik obrazu ({{size}} KB)", + "errors": { + "parseError": "Błąd Parsowania Pliku", + "invalidLineRange": "Nieprawidłowy Zakres Linii", + "imageReadError": "Błąd Odczytu Obrazu", + "fileReadError": "Błąd Odczytu Pliku" + } }, "toolRepetitionLimitReached": "Wygląda na to, że Roo utknął w pętli, wielokrotnie próbując wykonać tę samą akcję ({{toolName}}). Może to wskazywać na problem z jego obecną strategią. Rozważ przeformułowanie zadania, podanie bardziej szczegółowych instrukcji lub nakierowanie go na inne podejście.", "codebaseSearch": { - "approval": "Wyszukiwanie '{{query}}' w bazie kodu..." + "approval": "Wyszukiwanie '{{query}}' w bazie kodu...", + "errors": { + "searchError": "Błąd wyszukiwania kodu" + } }, "newTask": { "errors": { "policy_restriction": "Nie udało się utworzyć nowego zadania z powodu ograniczeń polityki." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Plik nie został znaleziony", + "fileDoesNotExist": "Plik nie istnieje w ścieżce: {{path}}", + "fileDoesNotExistDetails": "Nie można znaleźć określonego pliku. Sprawdź ścieżkę pliku i spróbuj ponownie.", + "applyDiffError": "Błąd Stosowania Różnic" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Nieprawidłowy numer linii", + "cannotInsertIntoNonExistent": "Nie można wstawić treści w linii {{lineNumber}} do nieistniejącego pliku. Dla nowych plików 'line' musi być 0 (aby dodać na końcu) lub 1 (aby wstawić na początku).", + "insertContentError": "Błąd Wstawiania Treści" + } + }, + "common": { + "errors": { + "missingParameter": "Brakujący parametr", + "missingParameterMessage": "Roo próbował użyć {{toolName}}{{relPath}} bez wartości dla wymaganego parametru '{{paramName}}'. Ponawiam próbę..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Błąd Zapisu Pliku" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Błąd Wyszukiwania i Zamiany" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Błąd listy plików" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Błąd wyszukiwania plików" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Błąd analizy definicji kodu" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Błąd pobierania instrukcji" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Błąd aktualizacji listy zadań" + } + }, + "executeCommand": { + "errors": { + "executeError": "Błąd wykonywania polecenia" + } + }, + "browserAction": { + "errors": { + "browserError": "Błąd akcji przeglądarki" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Błąd zadawania pytania" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Błąd inspekcji strony" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Błąd wykonywania polecenia slash" + } + }, + "generateImage": { + "errors": { + "generateError": "Błąd generowania obrazu" + } + }, + "newTaskTool": { + "errors": { + "createError": "Błąd tworzenia nowego zadania" + } + }, + "switchMode": { + "errors": { + "switchError": "Błąd przełączania trybu" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Błąd dostępu do zasobu MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Błąd wykonywania narzędzia MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Błąd odczytu pliku" + } } } diff --git a/src/i18n/locales/pt-BR/tools.json b/src/i18n/locales/pt-BR/tools.json index 4e3296fd4a..2425b8d4aa 100644 --- a/src/i18n/locales/pt-BR/tools.json +++ b/src/i18n/locales/pt-BR/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (apenas definições)", "maxLines": " (máx. {{max}} linhas)", "imageTooLarge": "Arquivo de imagem é muito grande ({{size}} MB). O tamanho máximo permitido é {{max}} MB.", - "imageWithSize": "Arquivo de imagem ({{size}} KB)" + "imageWithSize": "Arquivo de imagem ({{size}} KB)", + "errors": { + "parseError": "Erro de Análise do Arquivo", + "invalidLineRange": "Intervalo de Linhas Inválido", + "imageReadError": "Erro de Leitura de Imagem", + "fileReadError": "Erro de Leitura do Arquivo" + } }, "toolRepetitionLimitReached": "Roo parece estar preso em um loop, tentando a mesma ação ({{toolName}}) repetidamente. Isso pode indicar um problema com sua estratégia atual. Considere reformular a tarefa, fornecer instruções mais específicas ou guiá-lo para uma abordagem diferente.", "codebaseSearch": { - "approval": "Pesquisando '{{query}}' na base de código..." + "approval": "Pesquisando '{{query}}' na base de código...", + "errors": { + "searchError": "Erro de Pesquisa de Código" + } }, "newTask": { "errors": { "policy_restriction": "Falha ao criar nova tarefa devido a restrições de política." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Arquivo não encontrado", + "fileDoesNotExist": "O arquivo não existe no caminho: {{path}}", + "fileDoesNotExistDetails": "O arquivo especificado não pôde ser encontrado. Por favor, verifique o caminho do arquivo e tente novamente.", + "applyDiffError": "Erro ao Aplicar Diff" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Número de linha inválido", + "cannotInsertIntoNonExistent": "Não é possível inserir conteúdo na linha {{lineNumber}} em um arquivo inexistente. Para novos arquivos, 'line' deve ser 0 (para adicionar ao final) ou 1 (para inserir no início).", + "insertContentError": "Erro ao Inserir Conteúdo" + } + }, + "common": { + "errors": { + "missingParameter": "Parâmetro ausente", + "missingParameterMessage": "Roo tentou usar {{toolName}}{{relPath}} sem valor para o parâmetro obrigatório '{{paramName}}'. Tentando novamente..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Erro de Escrita do Arquivo" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Erro de Busca e Substituição" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Erro ao Listar Arquivos" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Erro ao Pesquisar Arquivos" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Erro ao Analisar Definições de Código" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Erro ao Buscar Instruções" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Erro ao Atualizar Lista de Tarefas" + } + }, + "executeCommand": { + "errors": { + "executeError": "Erro ao Executar Comando" + } + }, + "browserAction": { + "errors": { + "browserError": "Erro de Ação do Navegador" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Erro ao Fazer Pergunta" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Erro ao Inspecionar Site" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Erro ao Executar Comando Slash" + } + }, + "generateImage": { + "errors": { + "generateError": "Erro ao Gerar Imagem" + } + }, + "newTaskTool": { + "errors": { + "createError": "Erro ao Criar Nova Tarefa" + } + }, + "switchMode": { + "errors": { + "switchError": "Erro ao Alternar Modo" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Erro ao Acessar Recurso MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Erro ao Executar Ferramenta MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Erro ao Ler Arquivo" + } } } diff --git a/src/i18n/locales/ru/tools.json b/src/i18n/locales/ru/tools.json index d74918f058..59ae5b02a5 100644 --- a/src/i18n/locales/ru/tools.json +++ b/src/i18n/locales/ru/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (только определения)", "maxLines": " (макс. {{max}} строк)", "imageTooLarge": "Файл изображения слишком большой ({{size}} МБ). Максимально допустимый размер {{max}} МБ.", - "imageWithSize": "Файл изображения ({{size}} КБ)" + "imageWithSize": "Файл изображения ({{size}} КБ)", + "errors": { + "parseError": "Ошибка Разбора Файла", + "invalidLineRange": "Недопустимый Диапазон Строк", + "imageReadError": "Ошибка Чтения Изображения", + "fileReadError": "Ошибка Чтения Файла" + } }, "toolRepetitionLimitReached": "Похоже, что Roo застрял в цикле, многократно пытаясь выполнить одно и то же действие ({{toolName}}). Это может указывать на проблему с его текущей стратегией. Попробуйте переформулировать задачу, предоставить более конкретные инструкции или направить его к другому подходу.", "codebaseSearch": { - "approval": "Поиск '{{query}}' в кодовой базе..." + "approval": "Поиск '{{query}}' в кодовой базе...", + "errors": { + "searchError": "Ошибка поиска кода" + } }, "newTask": { "errors": { "policy_restriction": "Не удалось создать новую задачу из-за ограничений политики." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Файл не найден", + "fileDoesNotExist": "Файл не существует по пути: {{path}}", + "fileDoesNotExistDetails": "Указанный файл не найден. Пожалуйста, проверьте путь к файлу и попробуйте снова.", + "applyDiffError": "Ошибка Применения Различий" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Недопустимый номер строки", + "cannotInsertIntoNonExistent": "Невозможно вставить содержимое в строку {{lineNumber}} несуществующего файла. Для новых файлов 'line' должна быть 0 (для добавления в конец) или 1 (для вставки в начало).", + "insertContentError": "Ошибка Вставки Содержимого" + } + }, + "common": { + "errors": { + "missingParameter": "Отсутствующий параметр", + "missingParameterMessage": "Roo попытался использовать {{toolName}}{{relPath}} без значения для обязательного параметра '{{paramName}}'. Повторная попытка..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Ошибка Записи Файла" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Ошибка Поиска и Замены" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Ошибка списка файлов" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Ошибка поиска файлов" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Ошибка анализа определений кода" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Ошибка получения инструкций" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Ошибка обновления списка задач" + } + }, + "executeCommand": { + "errors": { + "executeError": "Ошибка выполнения команды" + } + }, + "browserAction": { + "errors": { + "browserError": "Ошибка действия браузера" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Ошибка вопроса" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Ошибка проверки сайта" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Ошибка выполнения slash-команды" + } + }, + "generateImage": { + "errors": { + "generateError": "Ошибка генерации изображения" + } + }, + "newTaskTool": { + "errors": { + "createError": "Ошибка создания новой задачи" + } + }, + "switchMode": { + "errors": { + "switchError": "Ошибка переключения режима" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Ошибка доступа к ресурсу MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Ошибка выполнения инструмента MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Ошибка чтения файла" + } } } diff --git a/src/i18n/locales/tr/tools.json b/src/i18n/locales/tr/tools.json index 5341a23cb1..773d07013c 100644 --- a/src/i18n/locales/tr/tools.json +++ b/src/i18n/locales/tr/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (sadece tanımlar)", "maxLines": " (maks. {{max}} satır)", "imageTooLarge": "Görüntü dosyası çok büyük ({{size}} MB). İzin verilen maksimum boyut {{max}} MB.", - "imageWithSize": "Görüntü dosyası ({{size}} KB)" + "imageWithSize": "Görüntü dosyası ({{size}} KB)", + "errors": { + "parseError": "Dosya Ayrıştırma Hatası", + "invalidLineRange": "Geçersiz Satır Aralığı", + "imageReadError": "Görüntü Okuma Hatası", + "fileReadError": "Dosya Okuma Hatası" + } }, "toolRepetitionLimitReached": "Roo bir döngüye takılmış gibi görünüyor, aynı eylemi ({{toolName}}) tekrar tekrar deniyor. Bu, mevcut stratejisinde bir sorun olduğunu gösterebilir. Görevi yeniden ifade etmeyi, daha spesifik talimatlar vermeyi veya onu farklı bir yaklaşıma yönlendirmeyi düşünün.", "codebaseSearch": { - "approval": "Kod tabanında '{{query}}' aranıyor..." + "approval": "Kod tabanında '{{query}}' aranıyor...", + "errors": { + "searchError": "Kod Tabanı Arama Hatası" + } }, "newTask": { "errors": { "policy_restriction": "Politika kısıtlamaları nedeniyle yeni görev oluşturulamadı." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Dosya Bulunamadı", + "fileDoesNotExist": "Dosya şu yolda mevcut değil: {{path}}", + "fileDoesNotExistDetails": "Belirtilen dosya bulunamadı. Lütfen dosya yolunu doğrulayın ve tekrar deneyin.", + "applyDiffError": "Fark Uygulama Hatası" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Geçersiz Satır Numarası", + "cannotInsertIntoNonExistent": "Var olmayan bir dosyanın {{lineNumber}}. satırına içerik eklenemez. Yeni dosyalar için 'line' 0 (sona eklemek için) veya 1 (başa eklemek için) olmalıdır.", + "insertContentError": "İçerik Ekleme Hatası" + } + }, + "common": { + "errors": { + "missingParameter": "Eksik Parametre", + "missingParameterMessage": "Roo, gerekli '{{paramName}}' parametresi için değer olmadan {{toolName}}{{relPath}} kullanmaya çalıştı. Yeniden deneniyor..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Dosya Yazma Hatası" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Ara ve Değiştir Hatası" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Dosya Listeleme Hatası" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Dosya Arama Hatası" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Kod Tanımları Ayrıştırma Hatası" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Talimat Getirme Hatası" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Yapılacaklar Listesi Güncelleme Hatası" + } + }, + "executeCommand": { + "errors": { + "executeError": "Komut Yürütme Hatası" + } + }, + "browserAction": { + "errors": { + "browserError": "Tarayıcı Eylem Hatası" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Soru Sorma Hatası" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Site İnceleme Hatası" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Slash Komutu Çalıştırma Hatası" + } + }, + "generateImage": { + "errors": { + "generateError": "Görüntü Oluşturma Hatası" + } + }, + "newTaskTool": { + "errors": { + "createError": "Yeni Görev Oluşturma Hatası" + } + }, + "switchMode": { + "errors": { + "switchError": "Mod Değiştirme Hatası" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "MCP Kaynağı Erişim Hatası" + } + }, + "useMcpTool": { + "errors": { + "executeError": "MCP Aracı Yürütme Hatası" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Dosya Okuma Hatası" + } } } diff --git a/src/i18n/locales/vi/tools.json b/src/i18n/locales/vi/tools.json index 4c5080a146..820b97ab88 100644 --- a/src/i18n/locales/vi/tools.json +++ b/src/i18n/locales/vi/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (chỉ định nghĩa)", "maxLines": " (tối đa {{max}} dòng)", "imageTooLarge": "Tệp hình ảnh quá lớn ({{size}} MB). Kích thước tối đa cho phép là {{max}} MB.", - "imageWithSize": "Tệp hình ảnh ({{size}} KB)" + "imageWithSize": "Tệp hình ảnh ({{size}} KB)", + "errors": { + "parseError": "Lỗi Phân Tích Tệp", + "invalidLineRange": "Phạm Vi Dòng Không Hợp Lệ", + "imageReadError": "Lỗi Đọc Hình Ảnh", + "fileReadError": "Lỗi Đọc Tệp" + } }, "toolRepetitionLimitReached": "Roo dường như đang bị mắc kẹt trong một vòng lặp, liên tục cố gắng thực hiện cùng một hành động ({{toolName}}). Điều này có thể cho thấy vấn đề với chiến lược hiện tại. Hãy cân nhắc việc diễn đạt lại nhiệm vụ, cung cấp hướng dẫn cụ thể hơn, hoặc hướng Roo theo một cách tiếp cận khác.", "codebaseSearch": { - "approval": "Đang tìm kiếm '{{query}}' trong cơ sở mã..." + "approval": "Đang tìm kiếm '{{query}}' trong cơ sở mã...", + "errors": { + "searchError": "Lỗi Tìm Kiếm Mã" + } }, "newTask": { "errors": { "policy_restriction": "Không thể tạo nhiệm vụ mới do hạn chế chính sách." } + }, + "applyDiff": { + "errors": { + "fileNotFound": "Không tìm thấy tệp", + "fileDoesNotExist": "Tệp không tồn tại tại đường dẫn: {{path}}", + "fileDoesNotExistDetails": "Không thể tìm thấy tệp được chỉ định. Vui lòng xác minh đường dẫn tệp và thử lại.", + "applyDiffError": "Lỗi Áp Dụng Diff" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "Số dòng không hợp lệ", + "cannotInsertIntoNonExistent": "Không thể chèn nội dung vào dòng {{lineNumber}} của tệp không tồn tại. Đối với tệp mới, 'line' phải là 0 (để thêm vào cuối) hoặc 1 (để chèn vào đầu).", + "insertContentError": "Lỗi Chèn Nội Dung" + } + }, + "common": { + "errors": { + "missingParameter": "Thiếu tham số", + "missingParameterMessage": "Roo đã cố gắng sử dụng {{toolName}}{{relPath}} mà không có giá trị cho tham số bắt buộc '{{paramName}}'. Đang thử lại..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "Lỗi Ghi Tệp" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "Lỗi Tìm và Thay Thế" + } + }, + "listFiles": { + "errors": { + "listFilesError": "Lỗi Danh Sách Tệp" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "Lỗi Tìm Kiếm Tệp" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "Lỗi Phân Tích Định Nghĩa Mã" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "Lỗi Lấy Hướng Dẫn" + } + }, + "updateTodoList": { + "errors": { + "updateError": "Lỗi Cập Nhật Danh Sách Việc Cần Làm" + } + }, + "executeCommand": { + "errors": { + "executeError": "Lỗi Thực Thi Lệnh" + } + }, + "browserAction": { + "errors": { + "browserError": "Lỗi Hành Động Trình Duyệt" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "Lỗi Đặt Câu Hỏi" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "Lỗi Kiểm Tra Trang Web" + } + }, + "runSlashCommand": { + "errors": { + "runError": "Lỗi Chạy Lệnh Slash" + } + }, + "generateImage": { + "errors": { + "generateError": "Lỗi Tạo Hình Ảnh" + } + }, + "newTaskTool": { + "errors": { + "createError": "Lỗi Tạo Tác Vụ Mới" + } + }, + "switchMode": { + "errors": { + "switchError": "Lỗi Chuyển Chế Độ" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "Lỗi Truy Cập Tài Nguyên MCP" + } + }, + "useMcpTool": { + "errors": { + "executeError": "Lỗi Thực Thi Công Cụ MCP" + } + }, + "simpleReadFile": { + "errors": { + "readError": "Lỗi Đọc Tệp" + } } } diff --git a/src/i18n/locales/zh-CN/tools.json b/src/i18n/locales/zh-CN/tools.json index c0c93d8436..af8d2b95d1 100644 --- a/src/i18n/locales/zh-CN/tools.json +++ b/src/i18n/locales/zh-CN/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (仅定义)", "maxLines": " (最多 {{max}} 行)", "imageTooLarge": "图片文件过大 ({{size}} MB)。允许的最大大小为 {{max}} MB。", - "imageWithSize": "图片文件 ({{size}} KB)" + "imageWithSize": "图片文件 ({{size}} KB)", + "errors": { + "parseError": "文件解析错误", + "invalidLineRange": "无效的行范围", + "imageReadError": "图像读取错误", + "fileReadError": "文件读取错误" + } }, "toolRepetitionLimitReached": "Roo 似乎陷入循环,反复尝试同一操作 ({{toolName}})。这可能表明当前策略存在问题。请考虑重新描述任务、提供更具体的指示或引导其尝试不同的方法。", "codebaseSearch": { - "approval": "正在搜索代码库中的 '{{query}}'..." + "approval": "正在搜索代码库中的 '{{query}}'...", + "errors": { + "searchError": "代码库搜索错误" + } }, "newTask": { "errors": { "policy_restriction": "由于策略限制,无法创建新任务。" } + }, + "applyDiff": { + "errors": { + "fileNotFound": "文件未找到", + "fileDoesNotExist": "文件不存在于路径:{{path}}", + "fileDoesNotExistDetails": "找不到指定的文件。请验证文件路径并重试。", + "applyDiffError": "应用差异错误" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "无效的行号", + "cannotInsertIntoNonExistent": "无法在不存在的文件的第 {{lineNumber}} 行插入内容。对于新文件,'line' 必须为 0(追加到末尾)或 1(插入到开头)。", + "insertContentError": "插入内容错误" + } + }, + "common": { + "errors": { + "missingParameter": "缺少参数", + "missingParameterMessage": "Roo 尝试使用 {{toolName}}{{relPath}} 但缺少必需参数 '{{paramName}}' 的值。正在重试..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "文件写入错误" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "搜索和替换错误" + } + }, + "listFiles": { + "errors": { + "listFilesError": "文件列表错误" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "文件搜索错误" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "代码定义解析错误" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "获取指令错误" + } + }, + "updateTodoList": { + "errors": { + "updateError": "更新待办事项列表错误" + } + }, + "executeCommand": { + "errors": { + "executeError": "执行命令错误" + } + }, + "browserAction": { + "errors": { + "browserError": "浏览器操作错误" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "提问错误" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "检查站点错误" + } + }, + "runSlashCommand": { + "errors": { + "runError": "运行斜杠命令错误" + } + }, + "generateImage": { + "errors": { + "generateError": "生成图像错误" + } + }, + "newTaskTool": { + "errors": { + "createError": "创建新任务错误" + } + }, + "switchMode": { + "errors": { + "switchError": "切换模式错误" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "访问MCP资源错误" + } + }, + "useMcpTool": { + "errors": { + "executeError": "执行MCP工具错误" + } + }, + "simpleReadFile": { + "errors": { + "readError": "读取文件错误" + } } } diff --git a/src/i18n/locales/zh-TW/tools.json b/src/i18n/locales/zh-TW/tools.json index b736448c20..5809cbaee7 100644 --- a/src/i18n/locales/zh-TW/tools.json +++ b/src/i18n/locales/zh-TW/tools.json @@ -4,15 +4,135 @@ "definitionsOnly": " (僅定義)", "maxLines": " (最多 {{max}} 行)", "imageTooLarge": "圖片檔案過大 ({{size}} MB)。允許的最大大小為 {{max}} MB。", - "imageWithSize": "圖片檔案 ({{size}} KB)" + "imageWithSize": "圖片檔案 ({{size}} KB)", + "errors": { + "parseError": "檔案解析錯誤", + "invalidLineRange": "無效的行範圍", + "imageReadError": "圖像讀取錯誤", + "fileReadError": "檔案讀取錯誤" + } }, "toolRepetitionLimitReached": "Roo 似乎陷入循環,反覆嘗試同一操作 ({{toolName}})。這可能表明目前策略存在問題。請考慮重新描述工作、提供更具體的指示或引導其嘗試不同的方法。", "codebaseSearch": { - "approval": "正在搜尋程式碼庫中的「{{query}}」..." + "approval": "正在搜尋程式碼庫中的「{{query}}」...", + "errors": { + "searchError": "程式碼庫搜尋錯誤" + } }, "newTask": { "errors": { "policy_restriction": "由於政策限制,無法建立新工作。" } + }, + "applyDiff": { + "errors": { + "fileNotFound": "找不到檔案", + "fileDoesNotExist": "檔案不存在於路徑:{{path}}", + "fileDoesNotExistDetails": "找不到指定的檔案。請驗證檔案路徑並重試。", + "applyDiffError": "應用差異錯誤" + } + }, + "insertContent": { + "errors": { + "invalidLineNumber": "無效的行號", + "cannotInsertIntoNonExistent": "無法在不存在的檔案的第 {{lineNumber}} 行插入內容。對於新檔案,'line' 必須為 0(附加到結尾)或 1(插入到開頭)。", + "insertContentError": "插入內容錯誤" + } + }, + "common": { + "errors": { + "missingParameter": "缺少參數", + "missingParameterMessage": "Roo 嘗試使用 {{toolName}}{{relPath}} 但缺少必要參數 '{{paramName}}' 的值。正在重試..." + } + }, + "writeToFile": { + "errors": { + "writeFileError": "檔案寫入錯誤" + } + }, + "searchAndReplace": { + "errors": { + "searchAndReplaceError": "搜尋和替換錯誤" + } + }, + "listFiles": { + "errors": { + "listFilesError": "檔案列表錯誤" + } + }, + "searchFiles": { + "errors": { + "searchFilesError": "檔案搜尋錯誤" + } + }, + "listCodeDefinitionNames": { + "errors": { + "parseError": "程式碼定義解析錯誤" + } + }, + "fetchInstructions": { + "errors": { + "fetchError": "取得指令錯誤" + } + }, + "updateTodoList": { + "errors": { + "updateError": "更新待辦事項清單錯誤" + } + }, + "executeCommand": { + "errors": { + "executeError": "執行命令錯誤" + } + }, + "browserAction": { + "errors": { + "browserError": "瀏覽器操作錯誤" + } + }, + "askFollowupQuestion": { + "errors": { + "askError": "提問錯誤" + } + }, + "attemptCompletion": { + "errors": { + "inspectError": "檢查網站錯誤" + } + }, + "runSlashCommand": { + "errors": { + "runError": "執行斜線命令錯誤" + } + }, + "generateImage": { + "errors": { + "generateError": "生成圖片錯誤" + } + }, + "newTaskTool": { + "errors": { + "createError": "建立新任務錯誤" + } + }, + "switchMode": { + "errors": { + "switchError": "切換模式錯誤" + } + }, + "accessMcpResource": { + "errors": { + "accessError": "存取MCP資源錯誤" + } + }, + "useMcpTool": { + "errors": { + "executeError": "執行MCP工具錯誤" + } + }, + "simpleReadFile": { + "errors": { + "readError": "讀取檔案錯誤" + } } } diff --git a/src/shared/tools.ts b/src/shared/tools.ts index 608b50752e..fedc300e77 100644 --- a/src/shared/tools.ts +++ b/src/shared/tools.ts @@ -11,7 +11,7 @@ export type AskApproval = ( forceApproval?: boolean, ) => Promise -export type HandleError = (action: string, error: Error) => Promise +export type HandleError = (action: string, error: Error, title?: string) => Promise export type PushToolResult = (content: ToolResponse) => void diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 7b3107a2be..d96168b533 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -120,7 +120,9 @@ export const ChatRowContent = ({ const { info: model } = useSelectedModel(apiConfiguration) const [reasoningCollapsed, setReasoningCollapsed] = useState(true) const [isDiffErrorExpanded, setIsDiffErrorExpanded] = useState(false) + const [isErrorExpanded, setIsErrorExpanded] = useState(false) const [showCopySuccess, setShowCopySuccess] = useState(false) + const [showErrorCopySuccess, setShowErrorCopySuccess] = useState(false) const [isEditing, setIsEditing] = useState(false) const [editedContent, setEditedContent] = useState("") const [editMode, setEditMode] = useState(mode || "code") @@ -1243,16 +1245,99 @@ export const ChatRowContent = ({ ) case "error": + // Extract custom title from metadata if available + const errorTitle = (message as any).metadata?.title || t("chat:error") + return ( - <> - {title && ( -
- {icon} - {title} +
+
+
setIsErrorExpanded(!isErrorExpanded)}> +
+ + + {errorTitle} + +
+
+ { + e.stopPropagation() + + // Call copyWithFeedback and handle the Promise + copyWithFeedback(message.text || "").then((success) => { + if (success) { + // Show checkmark + setShowErrorCopySuccess(true) + + // Reset after a brief delay + setTimeout(() => { + setShowErrorCopySuccess(false) + }, 1000) + } + }) + }}> + + + +
- )} -

{message.text}

- + {isErrorExpanded && ( +
+

+ {message.text} +

+
+ )} +
+
) case "completion_result": return (