From 1c37b77e9d47917c26ac0924c8c385ca9bc9984f Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Thu, 26 Jun 2025 15:19:58 -0400 Subject: [PATCH 01/70] Track mode selector opened in telemetry (#5150) --- packages/types/src/telemetry.ts | 2 ++ webview-ui/src/components/chat/ModeSelector.tsx | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/packages/types/src/telemetry.ts b/packages/types/src/telemetry.ts index 0f9ddfa122..6ad2eb3a7a 100644 --- a/packages/types/src/telemetry.ts +++ b/packages/types/src/telemetry.ts @@ -25,6 +25,7 @@ export enum TelemetryEventName { TASK_CONVERSATION_MESSAGE = "Conversation Message", LLM_COMPLETION = "LLM Completion", MODE_SWITCH = "Mode Switched", + MODE_SELECTOR_OPENED = "Mode Selector Opened", TOOL_USED = "Tool Used", CHECKPOINT_CREATED = "Checkpoint Created", @@ -126,6 +127,7 @@ export const rooCodeTelemetryEventSchema = z.discriminatedUnion("type", [ TelemetryEventName.TASK_COMPLETED, TelemetryEventName.TASK_CONVERSATION_MESSAGE, TelemetryEventName.MODE_SWITCH, + TelemetryEventName.MODE_SELECTOR_OPENED, TelemetryEventName.TOOL_USED, TelemetryEventName.CHECKPOINT_CREATED, TelemetryEventName.CHECKPOINT_RESTORED, diff --git a/webview-ui/src/components/chat/ModeSelector.tsx b/webview-ui/src/components/chat/ModeSelector.tsx index f066dabfa6..927c8be0d2 100644 --- a/webview-ui/src/components/chat/ModeSelector.tsx +++ b/webview-ui/src/components/chat/ModeSelector.tsx @@ -9,6 +9,8 @@ import { useExtensionState } from "@/context/ExtensionStateContext" import { useAppTranslation } from "@/i18n/TranslationContext" import { Mode, getAllModes } from "@roo/modes" import { ModeConfig, CustomModePrompts } from "@roo-code/types" +import { telemetryClient } from "@/utils/TelemetryClient" +import { TelemetryEventName } from "@roo-code/types" interface ModeSelectorProps { value: Mode @@ -37,6 +39,10 @@ export const ModeSelector = ({ const { t } = useAppTranslation() const trackModeSelectorOpened = () => { + // Track telemetry every time the mode selector is opened + telemetryClient.capture(TelemetryEventName.MODE_SELECTOR_OPENED) + + // Track first-time usage for UI purposes if (!hasOpenedModeSelector) { setHasOpenedModeSelector(true) vscode.postMessage({ type: "hasOpenedModeSelector", bool: true }) From c797c9a1d1e631540f574460552ae1badc1d9a4f Mon Sep 17 00:00:00 2001 From: KanTakahiro <64513424+KanTakahiro@users.noreply.github.com> Date: Fri, 27 Jun 2025 04:39:43 +0900 Subject: [PATCH 02/70] update maxTokens value for qwen/qwen3-32b model on Groq (#5138) Co-authored-by: Kan Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com> --- packages/types/src/providers/groq.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/providers/groq.ts b/packages/types/src/providers/groq.ts index 1782a6a72a..49667e357e 100644 --- a/packages/types/src/providers/groq.ts +++ b/packages/types/src/providers/groq.ts @@ -70,7 +70,7 @@ export const groqModels = { description: "Alibaba Qwen QwQ 32B model, 128K context.", }, "qwen/qwen3-32b": { - maxTokens: 131072, + maxTokens: 40960, contextWindow: 131072, supportsImages: false, supportsPromptCache: false, From 3318366b668197d1f992e13866bbbd659b28a7ef Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Thu, 26 Jun 2025 13:41:32 -0600 Subject: [PATCH 03/70] fix: standardize tooltip delays to 300ms (#5090) (#5098) Co-authored-by: Daniel Riccio --- webview-ui/src/App.tsx | 6 +- webview-ui/src/__tests__/App.spec.tsx | 2 +- .../__tests__/ContextWindowProgress.spec.tsx | 28 ++- .../account/__tests__/AccountView.spec.tsx | 2 +- .../src/components/chat/ChatTextArea.tsx | 39 +-- webview-ui/src/components/chat/ChatView.tsx | 66 ++--- .../components/chat/CodebaseSearchResult.tsx | 26 +- .../components/chat/ContextWindowProgress.tsx | 109 +++++---- .../src/components/chat/FollowUpSuggest.tsx | 27 +- webview-ui/src/components/chat/IconButton.tsx | 6 +- webview-ui/src/components/chat/Markdown.tsx | 48 ++-- .../src/components/chat/ModeSelector.tsx | 43 ++-- .../src/components/chat/ShareButton.tsx | 39 +-- webview-ui/src/components/chat/TaskHeader.tsx | 30 ++- .../chat/__tests__/Announcement.spec.tsx | 2 +- .../__tests__/BatchFilePermission.spec.tsx | 2 +- .../chat/__tests__/ChatTextArea.spec.tsx | 4 +- .../__tests__/ChatView.auto-approve.spec.tsx | 2 +- .../chat/__tests__/ChatView.spec.tsx | 2 +- .../__tests__/IndexingStatusBadge.spec.tsx | 2 +- .../chat/__tests__/ModeSelector.spec.tsx | 2 +- .../chat/__tests__/ShareButton.spec.tsx | 2 +- .../chat/__tests__/TaskActions.spec.tsx | 85 +++++-- .../chat/__tests__/TaskHeader.spec.tsx | 23 +- .../chat/checkpoints/CheckpointMenu.tsx | 22 +- .../src/components/common/CodeBlock.tsx | 84 ++++--- .../src/components/common/IconButton.tsx | 14 +- .../common/MermaidActionButtons.tsx | 69 +++--- .../src/components/common/MermaidButton.tsx | 38 +-- .../src/components/common/ZoomControls.tsx | 35 +-- .../common/__tests__/CodeBlock.spec.tsx | 16 +- .../common/__tests__/MarkdownBlock.spec.tsx | 2 +- .../src/components/history/CopyButton.tsx | 21 +- .../src/components/history/DeleteButton.tsx | 21 +- .../src/components/history/ExportButton.tsx | 21 +- .../src/components/history/HistoryView.tsx | 33 ++- .../__tests__/BatchDeleteTaskDialog.spec.tsx | 2 +- .../history/__tests__/CopyButton.spec.tsx | 2 +- .../history/__tests__/DeleteButton.spec.tsx | 2 +- .../__tests__/DeleteTaskDialog.spec.tsx | 2 +- .../history/__tests__/ExportButton.spec.tsx | 2 +- .../history/__tests__/HistoryPreview.spec.tsx | 2 +- .../history/__tests__/HistoryView.spec.tsx | 2 +- .../history/__tests__/TaskItem.spec.tsx | 2 +- .../history/__tests__/TaskItemFooter.spec.tsx | 2 +- .../history/__tests__/TaskItemHeader.spec.tsx | 2 +- .../history/__tests__/useTaskSearch.spec.tsx | 2 +- .../marketplace/MarketplaceView.tsx | 2 +- .../__tests__/MarketplaceListView.spec.tsx | 4 +- .../__tests__/MarketplaceView.spec.tsx | 2 +- .../components/MarketplaceItemCard.tsx | 90 ++++--- ...placeInstallModal-optional-params.spec.tsx | 2 +- .../MarketplaceInstallModal.spec.tsx | 2 +- .../__tests__/MarketplaceItemCard.spec.tsx | 4 +- webview-ui/src/components/mcp/McpToolRow.tsx | 44 ++-- .../mcp/__tests__/McpToolRow.spec.tsx | 2 +- webview-ui/src/components/modes/ModesView.tsx | 230 +++++++++--------- .../modes/__tests__/ModesView.spec.tsx | 2 +- .../components/settings/ApiConfigManager.tsx | 107 ++++---- .../components/settings/AutoApproveToggle.tsx | 30 +-- .../components/settings/PromptsSettings.tsx | 23 +- .../src/components/settings/SettingsView.tsx | 36 +-- .../__tests__/ApiConfigManager.spec.tsx | 3 +- .../settings/__tests__/ApiOptions.spec.tsx | 3 +- .../__tests__/AutoApproveToggle.spec.tsx | 2 +- .../__tests__/CodeIndexSettings.spec.tsx | 2 +- .../ContextManagementSettings.spec.tsx | 2 +- .../settings/__tests__/ModelPicker.spec.tsx | 2 +- .../settings/__tests__/SettingsView.spec.tsx | 3 +- .../__tests__/TemperatureControl.spec.tsx | 2 +- .../__tests__/ThinkingBudget.spec.tsx | 2 +- .../components/settings/providers/Bedrock.tsx | 13 +- .../settings/providers/OpenAICompatible.tsx | 102 ++++---- .../providers/__tests__/Bedrock.spec.tsx | 2 +- .../__tests__/OpenAICompatible.spec.tsx | 3 +- .../ui/__tests__/select-dropdown.spec.tsx | 2 +- .../components/ui/__tests__/tooltip.spec.tsx | 182 ++++++++++++++ webview-ui/src/components/ui/index.ts | 1 + .../src/components/ui/select-dropdown.tsx | 38 +-- .../src/components/ui/standard-tooltip.tsx | 69 ++++++ webview-ui/src/components/ui/tooltip.tsx | 5 +- .../welcome/__tests__/RooTips.spec.tsx | 2 +- .../__tests__/ExtensionStateContext.spec.tsx | 2 +- .../__tests__/TranslationContext.spec.tsx | 2 +- webview-ui/src/utils/test-utils.tsx | 21 ++ 85 files changed, 1242 insertions(+), 798 deletions(-) create mode 100644 webview-ui/src/components/ui/__tests__/tooltip.spec.tsx create mode 100644 webview-ui/src/components/ui/standard-tooltip.tsx create mode 100644 webview-ui/src/utils/test-utils.tsx diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index 6b33a9b7f7..332ef18511 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -20,6 +20,8 @@ import ModesView from "./components/modes/ModesView" import { HumanRelayDialog } from "./components/human-relay/HumanRelayDialog" import { AccountView } from "./components/account/AccountView" import { useAddNonInteractiveClickListener } from "./components/ui/hooks/useNonInteractiveClick" +import { TooltipProvider } from "./components/ui/tooltip" +import { STANDARD_TOOLTIP_DELAY } from "./components/ui/standard-tooltip" type Tab = "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account" @@ -215,7 +217,9 @@ const AppWithProviders = () => ( - + + + diff --git a/webview-ui/src/__tests__/App.spec.tsx b/webview-ui/src/__tests__/App.spec.tsx index d4e8b26818..2c55d1cf07 100644 --- a/webview-ui/src/__tests__/App.spec.tsx +++ b/webview-ui/src/__tests__/App.spec.tsx @@ -1,7 +1,7 @@ // npx vitest run src/__tests__/App.spec.tsx import React from "react" -import { render, screen, act, cleanup } from "@testing-library/react" +import { render, screen, act, cleanup } from "@/utils/test-utils" import AppWithProviders from "../App" diff --git a/webview-ui/src/__tests__/ContextWindowProgress.spec.tsx b/webview-ui/src/__tests__/ContextWindowProgress.spec.tsx index 6b989a4e74..0e5d0d6193 100644 --- a/webview-ui/src/__tests__/ContextWindowProgress.spec.tsx +++ b/webview-ui/src/__tests__/ContextWindowProgress.spec.tsx @@ -1,6 +1,6 @@ // npm run test ContextWindowProgress.spec.tsx -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import TaskHeader from "@src/components/chat/TaskHeader" @@ -102,18 +102,22 @@ describe("ContextWindowProgress", () => { it("calculates percentages correctly", () => { renderComponent({ contextTokens: 1000, contextWindow: 4000 }) - // Instead of checking the title attribute, verify the data-test-id - // which identifies the element containing info about the percentage of tokens used - const tokenUsageDiv = screen.getByTestId("context-tokens-used") - expect(tokenUsageDiv).toBeInTheDocument() + // Verify that the token count and window size are displayed correctly + const tokenCount = screen.getByTestId("context-tokens-count") + const windowSize = screen.getByTestId("context-window-size") - // Just verify that the element has a title attribute (the actual text is translated and may vary) - expect(tokenUsageDiv).toHaveAttribute("title") + expect(tokenCount).toBeInTheDocument() + expect(tokenCount).toHaveTextContent("1000") - // We can't reliably test computed styles in JSDOM, so we'll just check - // that the component appears to be working correctly by checking for expected elements - // The context-window-label is not part of the ContextWindowProgress component - expect(screen.getByTestId("context-tokens-count")).toBeInTheDocument() - expect(screen.getByTestId("context-tokens-count")).toHaveTextContent("1000") + expect(windowSize).toBeInTheDocument() + expect(windowSize).toHaveTextContent("4000") + + // The progress bar is now wrapped in tooltips, but we can verify the structure exists + // by checking for the progress bar container + const progressBarContainer = screen.getByTestId("context-tokens-count").parentElement + expect(progressBarContainer).toBeInTheDocument() + + // Verify the flex container has the expected structure + expect(progressBarContainer?.querySelector(".flex-1.relative")).toBeInTheDocument() }) }) diff --git a/webview-ui/src/components/account/__tests__/AccountView.spec.tsx b/webview-ui/src/components/account/__tests__/AccountView.spec.tsx index 53b7c0a4ce..d6fd3013e6 100644 --- a/webview-ui/src/components/account/__tests__/AccountView.spec.tsx +++ b/webview-ui/src/components/account/__tests__/AccountView.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import { describe, it, expect, vi } from "vitest" import { AccountView } from "../AccountView" diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 910b671725..dc07764077 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -19,7 +19,7 @@ import { SearchResult, } from "@src/utils/context-mentions" import { convertToMentionPath } from "@/utils/path-mentions" -import { SelectDropdown, DropdownOptionType, Button } from "@/components/ui" +import { SelectDropdown, DropdownOptionType, Button, StandardTooltip } from "@/components/ui" import Thumbnails from "../common/Thumbnails" import ModeSelector from "./ModeSelector" @@ -1094,8 +1094,7 @@ const ChatTextArea = forwardRef(
+ })}> {label}
@@ -1106,21 +1105,25 @@ const ChatTextArea = forwardRef( })}>
- + + + ) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 5456c5b698..a4f18c870c 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -30,6 +30,7 @@ import { useExtensionState } from "@src/context/ExtensionStateContext" import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel" import RooHero from "@src/components/welcome/RooHero" import RooTips from "@src/components/welcome/RooTips" +import { StandardTooltip } from "@src/components/ui" import TelemetryBanner from "../common/TelemetryBanner" import { useTaskSearch } from "../history/useTaskSearch" @@ -730,7 +731,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction { @@ -1095,8 +1096,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction { return () => { - if (scrollToBottomSmooth && typeof (scrollToBottomSmooth as any).cancel === 'function') { - (scrollToBottomSmooth as any).cancel() + if (scrollToBottomSmooth && typeof (scrollToBottomSmooth as any).cancel === "function") { + ;(scrollToBottomSmooth as any).cancel() } } }, [scrollToBottomSmooth]) @@ -1476,15 +1477,16 @@ const ChatViewComponent: React.ForwardRefRenderFunction {showScrollToBottom ? (
-
{ - scrollToBottomSmooth() - disableAutoScrollRef.current = false - }} - title={t("chat:scrollToBottom")}> - -
+ +
{ + scrollToBottomSmooth() + disableAutoScrollRef.current = false + }}> + +
+
) : (
{primaryButtonText && !isStreaming && ( - handlePrimaryButtonClick(inputValue, selectedImages)}> - {primaryButtonText} - + }> + handlePrimaryButtonClick(inputValue, selectedImages)}> + {primaryButtonText} + + )} {(secondaryButtonText || isStreaming) && ( - handleSecondaryButtonClick(inputValue, selectedImages)}> - {isStreaming ? t("chat:cancel.title") : secondaryButtonText} - + }> + handleSecondaryButtonClick(inputValue, selectedImages)}> + {isStreaming ? t("chat:cancel.title") : secondaryButtonText} + + )}
)} diff --git a/webview-ui/src/components/chat/CodebaseSearchResult.tsx b/webview-ui/src/components/chat/CodebaseSearchResult.tsx index d5a8e6407f..4a2ced6178 100644 --- a/webview-ui/src/components/chat/CodebaseSearchResult.tsx +++ b/webview-ui/src/components/chat/CodebaseSearchResult.tsx @@ -1,5 +1,6 @@ import React from "react" import { vscode } from "@src/utils/vscode" +import { StandardTooltip } from "@/components/ui" interface CodebaseSearchResultProps { filePath: string @@ -23,19 +24,20 @@ const CodebaseSearchResult: React.FC = ({ filePath, s } return ( -
-
- - {filePath.split("/").at(-1)}:{startLine}-{endLine} - - - {filePath.split("/").slice(0, -1).join("/")} - + +
+
+ + {filePath.split("/").at(-1)}:{startLine}-{endLine} + + + {filePath.split("/").slice(0, -1).join("/")} + +
-
+ ) } diff --git a/webview-ui/src/components/chat/ContextWindowProgress.tsx b/webview-ui/src/components/chat/ContextWindowProgress.tsx index a5490d9d4f..1ae80bb3db 100644 --- a/webview-ui/src/components/chat/ContextWindowProgress.tsx +++ b/webview-ui/src/components/chat/ContextWindowProgress.tsx @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next" import { formatLargeNumber } from "@/utils/format" import { calculateTokenDistribution } from "@/utils/model-utils" +import { StandardTooltip } from "@/components/ui" interface ContextWindowProgressProps { contextWindow: number @@ -26,64 +27,70 @@ export const ContextWindowProgress = ({ contextWindow, contextTokens, maxTokens const safeContextWindow = Math.max(0, contextWindow) const safeContextTokens = Math.max(0, contextTokens) + // Combine all tooltip content into a single tooltip + const tooltipContent = ( +
+
+ {t("chat:tokenProgress.tokensUsed", { + used: formatLargeNumber(safeContextTokens), + total: formatLargeNumber(safeContextWindow), + })} +
+ {reservedForOutput > 0 && ( +
+ {t("chat:tokenProgress.reservedForResponse", { + amount: formatLargeNumber(reservedForOutput), + })} +
+ )} + {availableSize > 0 && ( +
+ {t("chat:tokenProgress.availableSpace", { + amount: formatLargeNumber(availableSize), + })} +
+ )} +
+ ) + return ( <>
{formatLargeNumber(safeContextTokens)}
-
- {/* Invisible overlay for hover area */} -
- - {/* Main progress bar container */} -
- {/* Current tokens container */} -
- {/* Invisible overlay for current tokens section */} + +
+ {/* Main progress bar container */} +
+ {/* Current tokens container */}
- {/* Current tokens used - darkest */} -
-
- - {/* Container for reserved tokens */} -
- {/* Invisible overlay for reserved section */} -
- {/* Reserved for output section - medium gray */} -
-
- - {/* Empty section (if any) */} - {availablePercent > 0 && ( -
- {/* Invisible overlay for available space */} -
+ className="relative h-full" + style={{ width: `${currentPercent}%` }} + data-testid="context-tokens-used"> + {/* Current tokens used - darkest */} +
- )} + + {/* Container for reserved tokens */} +
+ {/* Reserved for output section - medium gray */} +
+
+ + {/* Empty section (if any) */} + {availablePercent > 0 && ( +
+ {/* Available space - transparent */} +
+ )} +
-
+
{formatLargeNumber(safeContextWindow)}
diff --git a/webview-ui/src/components/chat/FollowUpSuggest.tsx b/webview-ui/src/components/chat/FollowUpSuggest.tsx index 44a30ca803..9f4c017e74 100644 --- a/webview-ui/src/components/chat/FollowUpSuggest.tsx +++ b/webview-ui/src/components/chat/FollowUpSuggest.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { Edit } from "lucide-react" -import { Button } from "@/components/ui" +import { Button, StandardTooltip } from "@/components/ui" import { useAppTranslation } from "@src/i18n/TranslationContext" @@ -36,18 +36,19 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }: aria-label={suggestion}>
{suggestion}
-
{ - e.stopPropagation() - // Simulate shift-click by directly calling the handler with shiftKey=true. - onSuggestionClick?.(suggestion, { ...e, shiftKey: true }) - }} - title={t("chat:followUpSuggest.copyToInput")}> - -
+ +
{ + e.stopPropagation() + // Simulate shift-click by directly calling the handler with shiftKey=true. + onSuggestionClick?.(suggestion, { ...e, shiftKey: true }) + }}> + +
+
))}
diff --git a/webview-ui/src/components/chat/IconButton.tsx b/webview-ui/src/components/chat/IconButton.tsx index 34311b22c6..75d8bc4b0b 100644 --- a/webview-ui/src/components/chat/IconButton.tsx +++ b/webview-ui/src/components/chat/IconButton.tsx @@ -1,4 +1,5 @@ import { cn } from "@/lib/utils" +import { StandardTooltip } from "@/components/ui" interface IconButtonProps extends React.ButtonHTMLAttributes { iconClass: string @@ -35,10 +36,9 @@ export const IconButton: React.FC = ({ const iconClasses = cn("codicon", iconClass, isLoading && "codicon-modifier-spin") - return ( + const button = ( ) + + return {button} } diff --git a/webview-ui/src/components/chat/Markdown.tsx b/webview-ui/src/components/chat/Markdown.tsx index a209ce8723..ba838284d7 100644 --- a/webview-ui/src/components/chat/Markdown.tsx +++ b/webview-ui/src/components/chat/Markdown.tsx @@ -2,6 +2,7 @@ import { memo, useState } from "react" import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" import { useCopyToClipboard } from "@src/utils/clipboard" +import { StandardTooltip } from "@src/components/ui" import MarkdownBlock from "../common/MarkdownBlock" @@ -34,30 +35,31 @@ export const Markdown = memo(({ markdown, partial }: { markdown?: string; partia borderRadius: "4px", }}> - { - const success = await copyWithFeedback(markdown) - if (success) { - const button = document.activeElement as HTMLElement - if (button) { - button.style.background = "var(--vscode-button-background)" - setTimeout(() => { - button.style.background = "" - }, 200) + + { + const success = await copyWithFeedback(markdown) + if (success) { + const button = document.activeElement as HTMLElement + if (button) { + button.style.background = "var(--vscode-button-background)" + setTimeout(() => { + button.style.background = "" + }, 200) + } } - } - }} - title="Copy as markdown"> - - + }}> + + +
)}
diff --git a/webview-ui/src/components/chat/ModeSelector.tsx b/webview-ui/src/components/chat/ModeSelector.tsx index 927c8be0d2..336e9f8357 100644 --- a/webview-ui/src/components/chat/ModeSelector.tsx +++ b/webview-ui/src/components/chat/ModeSelector.tsx @@ -2,7 +2,7 @@ import React from "react" import { ChevronUp, Check } from "lucide-react" import { cn } from "@/lib/utils" import { useRooPortal } from "@/components/ui/hooks/useRooPortal" -import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui" +import { Popover, PopoverContent, PopoverTrigger, StandardTooltip } from "@/components/ui" import { IconButton } from "./IconButton" import { vscode } from "@/utils/vscode" import { useExtensionState } from "@/context/ExtensionStateContext" @@ -61,6 +61,27 @@ export const ModeSelector = ({ // Find the selected mode const selectedMode = React.useMemo(() => modes.find((mode) => mode.slug === value), [modes, value]) + const trigger = ( + + + {selectedMode?.name || ""} + + ) + return ( - - - {selectedMode?.name || ""} - + {title ? {trigger} : trigger} { {shareButtonState.showPopover ? ( - + + + {shareSuccess ? ( @@ -205,15 +207,16 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => { ) : ( - + + + )} {/* Connect to Cloud Modal */} diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 6198b12a03..0d75f8f250 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -10,7 +10,7 @@ import { getModelMaxOutputTokens } from "@roo/api" import { formatLargeNumber } from "@src/utils/format" import { cn } from "@src/lib/utils" -import { Button } from "@src/components/ui" +import { Button, StandardTooltip } from "@src/components/ui" import { useExtensionState } from "@src/context/ExtensionStateContext" import { useSelectedModel } from "@/components/ui/hooks/useSelectedModel" @@ -58,13 +58,14 @@ const TaskHeader = ({ const { width: windowWidth } = useWindowSize() const condenseButton = ( - + + + ) return ( @@ -95,14 +96,11 @@ const TaskHeader = ({ )}
- + + +
{/* Collapsed state: Track context and cost if we have any */} {!isTaskExpanded && contextWindow > 0 && ( diff --git a/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx index 7048022440..42c2d6ff50 100644 --- a/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import { Package } from "@roo/package" diff --git a/webview-ui/src/components/chat/__tests__/BatchFilePermission.spec.tsx b/webview-ui/src/components/chat/__tests__/BatchFilePermission.spec.tsx index 7aef88d0de..6b2a290c63 100644 --- a/webview-ui/src/components/chat/__tests__/BatchFilePermission.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/BatchFilePermission.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { TranslationProvider } from "@/i18n/__mocks__/TranslationContext" diff --git a/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx b/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx index e31803b99e..63112d12c0 100644 --- a/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx @@ -1,4 +1,4 @@ -import { render, fireEvent, screen } from "@testing-library/react" +import { render, fireEvent, screen } from "@/utils/test-utils" import { defaultModeSlug } from "@roo/modes" @@ -761,7 +761,7 @@ describe("ChatTextArea", () => { describe("selectApiConfig", () => { // Helper function to get the API config dropdown const getApiConfigDropdown = () => { - return screen.getByTitle("chat:selectApiConfig") + return screen.getByTestId("dropdown-trigger") } it("should be enabled independently of sendingDisabled", () => { render() diff --git a/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.spec.tsx b/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.spec.tsx index 3e819904fe..15405396f7 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.spec.tsx @@ -1,6 +1,6 @@ // npx vitest run src/components/chat/__tests__/ChatView.auto-approve.spec.tsx -import { render, waitFor } from "@testing-library/react" +import { render, waitFor } from "@/utils/test-utils" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import { ExtensionStateContextProvider } from "@src/context/ExtensionStateContext" diff --git a/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx b/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx index f6ecbaf0e4..5a21b6c14c 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx @@ -1,7 +1,7 @@ // npx vitest run src/components/chat/__tests__/ChatView.spec.tsx import React from "react" -import { render, waitFor, act } from "@testing-library/react" +import { render, waitFor, act } from "@/utils/test-utils" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import { ExtensionStateContextProvider } from "@src/context/ExtensionStateContext" diff --git a/webview-ui/src/components/chat/__tests__/IndexingStatusBadge.spec.tsx b/webview-ui/src/components/chat/__tests__/IndexingStatusBadge.spec.tsx index e75b16606a..4ef3764841 100644 --- a/webview-ui/src/components/chat/__tests__/IndexingStatusBadge.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/IndexingStatusBadge.spec.tsx @@ -1,5 +1,5 @@ import React from "react" -import { render, screen, fireEvent, waitFor, act } from "@testing-library/react" +import { render, screen, fireEvent, waitFor, act } from "@/utils/test-utils" import { vscode } from "@src/utils/vscode" diff --git a/webview-ui/src/components/chat/__tests__/ModeSelector.spec.tsx b/webview-ui/src/components/chat/__tests__/ModeSelector.spec.tsx index 4d07a6de46..d6fc81368d 100644 --- a/webview-ui/src/components/chat/__tests__/ModeSelector.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/ModeSelector.spec.tsx @@ -1,5 +1,5 @@ import React from "react" -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import { describe, test, expect, vi } from "vitest" import ModeSelector from "../ModeSelector" import { Mode } from "@roo/modes" diff --git a/webview-ui/src/components/chat/__tests__/ShareButton.spec.tsx b/webview-ui/src/components/chat/__tests__/ShareButton.spec.tsx index f6102dc616..cbe5620264 100644 --- a/webview-ui/src/components/chat/__tests__/ShareButton.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/ShareButton.spec.tsx @@ -1,5 +1,5 @@ import { describe, test, expect, vi, beforeEach } from "vitest" -import { render, screen, fireEvent, waitFor } from "@testing-library/react" +import { render, screen, fireEvent, waitFor } from "@/utils/test-utils" import { ShareButton } from "../ShareButton" import { useTranslation } from "react-i18next" import { vscode } from "@/utils/vscode" diff --git a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx index c21c5b9331..2d9ea0cac1 100644 --- a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { vi, describe, it, expect, beforeEach } from "vitest" import { TaskActions } from "../TaskActions" import type { HistoryItem } from "@roo-code/types" @@ -89,15 +89,19 @@ describe("TaskActions", () => { it("renders share button when item has id", () => { render() - const shareButton = screen.getByTitle("Share task") + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) expect(shareButton).toBeInTheDocument() }) it("does not render share button when item has no id", () => { render() - const shareButton = screen.queryByTitle("Share task") - expect(shareButton).not.toBeInTheDocument() + // Find button by its icon class + const buttons = screen.queryAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).not.toBeDefined() }) it("renders share button even when not authenticated", () => { @@ -108,7 +112,9 @@ describe("TaskActions", () => { render() - const shareButton = screen.getByTitle("Share task") + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) expect(shareButton).toBeInTheDocument() }) }) @@ -117,8 +123,11 @@ describe("TaskActions", () => { it("shows organization and public share options when authenticated and sharing enabled", () => { render() - const shareButton = screen.getByTitle("Share task") - fireEvent.click(shareButton) + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) expect(screen.getByText("Share with Organization")).toBeInTheDocument() expect(screen.getByText("Share Publicly")).toBeInTheDocument() @@ -127,8 +136,11 @@ describe("TaskActions", () => { it("sends shareCurrentTask message when organization option is selected", () => { render() - const shareButton = screen.getByTitle("Share task") - fireEvent.click(shareButton) + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) const orgOption = screen.getByText("Share with Organization") fireEvent.click(orgOption) @@ -142,8 +154,11 @@ describe("TaskActions", () => { it("sends shareCurrentTask message when public option is selected", () => { render() - const shareButton = screen.getByTitle("Share task") - fireEvent.click(shareButton) + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) const publicOption = screen.getByText("Share Publicly") fireEvent.click(publicOption) @@ -165,8 +180,11 @@ describe("TaskActions", () => { render() - const shareButton = screen.getByTitle("Share task") - fireEvent.click(shareButton) + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument() expect(screen.getByText("Share Publicly")).toBeInTheDocument() @@ -184,8 +202,11 @@ describe("TaskActions", () => { it("shows connect to cloud option when not authenticated", () => { render() - const shareButton = screen.getByTitle("Share task") - fireEvent.click(shareButton) + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) expect(screen.getByText("Connect to Roo Code Cloud")).toBeInTheDocument() expect(screen.getByText("Sign in to Roo Code Cloud to share tasks")).toBeInTheDocument() @@ -195,8 +216,11 @@ describe("TaskActions", () => { it("does not show organization and public options when not authenticated", () => { render() - const shareButton = screen.getByTitle("Share task") - fireEvent.click(shareButton) + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument() expect(screen.queryByText("Share Publicly")).not.toBeInTheDocument() @@ -205,8 +229,11 @@ describe("TaskActions", () => { it("sends rooCloudSignIn message when connect to cloud is selected", () => { render() - const shareButton = screen.getByTitle("Share task") - fireEvent.click(shareButton) + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) const connectOption = screen.getByText("Connect") fireEvent.click(connectOption) @@ -226,12 +253,14 @@ describe("TaskActions", () => { render() - const shareButton = screen.getByTitle("Sharing disabled by organization") + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) expect(shareButton).toBeInTheDocument() expect(shareButton).toBeDisabled() // Should not have a popover when sharing is disabled - fireEvent.click(shareButton) + fireEvent.click(shareButton!) expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument() expect(screen.queryByText("Connect to Cloud")).not.toBeInTheDocument() }) @@ -269,14 +298,14 @@ describe("TaskActions", () => { it("renders export button", () => { render() - const exportButton = screen.getByTitle("Export task history") + const exportButton = screen.getByLabelText("Export task history") expect(exportButton).toBeInTheDocument() }) it("sends exportCurrentTask message when export button is clicked", () => { render() - const exportButton = screen.getByTitle("Export task history") + const exportButton = screen.getByLabelText("Export task history") fireEvent.click(exportButton) expect(mockPostMessage).toHaveBeenCalledWith({ @@ -287,7 +316,7 @@ describe("TaskActions", () => { it("renders delete button and file size when item has size", () => { render() - const deleteButton = screen.getByTitle("Delete Task (Shift + Click to skip confirmation)") + const deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)") expect(deleteButton).toBeInTheDocument() expect(screen.getByText("1024 B")).toBeInTheDocument() }) @@ -296,7 +325,7 @@ describe("TaskActions", () => { const itemWithoutSize = { ...mockItem, size: 0 } render() - const deleteButton = screen.queryByTitle("Delete Task (Shift + Click to skip confirmation)") + const deleteButton = screen.queryByLabelText("Delete Task (Shift + Click to skip confirmation)") expect(deleteButton).not.toBeInTheDocument() }) }) @@ -305,8 +334,10 @@ describe("TaskActions", () => { it("disables buttons when buttonsDisabled is true", () => { render() - const shareButton = screen.getByTitle("Share task") - const exportButton = screen.getByTitle("Export task history") + // Find button by its icon class + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + const exportButton = screen.getByLabelText("Export task history") expect(shareButton).toBeDisabled() expect(exportButton).toBeDisabled() diff --git a/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx index 9acd0ad5ce..c04f7e45e5 100644 --- a/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx @@ -1,7 +1,7 @@ // npx vitest src/components/chat/__tests__/TaskHeader.spec.tsx import React from "react" -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import type { ProviderSettings } from "@roo-code/types" @@ -93,22 +93,33 @@ describe("TaskHeader", () => { it("should render the condense context button", () => { renderTaskHeader() - expect(screen.getByTitle("chat:task.condenseContext")).toBeInTheDocument() + // Find the button that contains the FoldVertical icon + const buttons = screen.getAllByRole("button") + const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-fold-vertical")) + expect(condenseButton).toBeDefined() + expect(condenseButton?.querySelector("svg")).toBeInTheDocument() }) it("should call handleCondenseContext when condense context button is clicked", () => { const handleCondenseContext = vi.fn() renderTaskHeader({ handleCondenseContext }) - const condenseButton = screen.getByTitle("chat:task.condenseContext") - fireEvent.click(condenseButton) + // Find the button that contains the FoldVertical icon + const buttons = screen.getAllByRole("button") + const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-fold-vertical")) + expect(condenseButton).toBeDefined() + fireEvent.click(condenseButton!) expect(handleCondenseContext).toHaveBeenCalledWith("test-task-id") }) it("should disable the condense context button when buttonsDisabled is true", () => { const handleCondenseContext = vi.fn() renderTaskHeader({ buttonsDisabled: true, handleCondenseContext }) - const condenseButton = screen.getByTitle("chat:task.condenseContext") - fireEvent.click(condenseButton) + // Find the button that contains the FoldVertical icon + const buttons = screen.getAllByRole("button") + const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-fold-vertical")) + expect(condenseButton).toBeDefined() + expect(condenseButton).toBeDisabled() + fireEvent.click(condenseButton!) expect(handleCondenseContext).not.toHaveBeenCalled() }) }) diff --git a/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx b/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx index 348e230619..6b632a4548 100644 --- a/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx +++ b/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx @@ -2,7 +2,7 @@ import { useState, useCallback } from "react" import { CheckIcon, Cross2Icon } from "@radix-ui/react-icons" import { useTranslation } from "react-i18next" -import { Button, Popover, PopoverContent, PopoverTrigger } from "@/components/ui" +import { Button, Popover, PopoverContent, PopoverTrigger, StandardTooltip } from "@/components/ui" import { useRooPortal } from "@/components/ui/hooks" import { vscode } from "@src/utils/vscode" @@ -48,13 +48,11 @@ export const CheckpointMenu = ({ ts, commitHash, currentHash, checkpoint }: Chec return (
{isDiffAvailable && ( - + + + )} {isRestoreAvailable && ( - + + +
diff --git a/webview-ui/src/components/common/CodeBlock.tsx b/webview-ui/src/components/common/CodeBlock.tsx index 06f929b830..2cf8fcc82e 100644 --- a/webview-ui/src/components/common/CodeBlock.tsx +++ b/webview-ui/src/components/common/CodeBlock.tsx @@ -6,6 +6,7 @@ import { bundledLanguages } from "shiki" import type { ShikiTransformer } from "shiki" import { ChevronDown, ChevronUp, WrapText, AlignJustify, Copy, Check } from "lucide-react" import { useAppTranslation } from "@src/i18n/TranslationContext" +import { StandardTooltip } from "@/components/ui" export const CODE_BLOCK_BG_COLOR = "var(--vscode-editor-background, --vscode-sideBar-background, rgb(30 30 30))" export const WRAPPER_ALPHA = "cc" // 80% opacity @@ -725,48 +726,55 @@ const CodeBlock = memo( } {showCollapseButton && ( - { - // Get the current code block element - const codeBlock = codeBlockRef.current // Capture ref early - // Toggle window shade state - setWindowShade(!windowShade) + + { + // Get the current code block element + const codeBlock = codeBlockRef.current // Capture ref early + // Toggle window shade state + setWindowShade(!windowShade) - // Clear any previous timeouts - if (collapseTimeout1Ref.current) clearTimeout(collapseTimeout1Ref.current) - if (collapseTimeout2Ref.current) clearTimeout(collapseTimeout2Ref.current) + // Clear any previous timeouts + if (collapseTimeout1Ref.current) clearTimeout(collapseTimeout1Ref.current) + if (collapseTimeout2Ref.current) clearTimeout(collapseTimeout2Ref.current) - // After UI updates, ensure code block is visible and update button position - collapseTimeout1Ref.current = setTimeout( - () => { - if (codeBlock) { - // Check if codeBlock element still exists - codeBlock.scrollIntoView({ behavior: "smooth", block: "nearest" }) + // After UI updates, ensure code block is visible and update button position + collapseTimeout1Ref.current = setTimeout( + () => { + if (codeBlock) { + // Check if codeBlock element still exists + codeBlock.scrollIntoView({ behavior: "smooth", block: "nearest" }) - // Wait for scroll to complete before updating button position - collapseTimeout2Ref.current = setTimeout(() => { - // updateCodeBlockButtonPosition itself should also check for refs if needed - updateCodeBlockButtonPosition() - collapseTimeout2Ref.current = null - }, 50) - } - collapseTimeout1Ref.current = null - }, - WINDOW_SHADE_SETTINGS.transitionDelayS * 1000 + 50, - ) - }} - title={t(`chat:codeblock.tooltips.${windowShade ? "expand" : "collapse"}`)}> - {windowShade ? : } - + // Wait for scroll to complete before updating button position + collapseTimeout2Ref.current = setTimeout(() => { + // updateCodeBlockButtonPosition itself should also check for refs if needed + updateCodeBlockButtonPosition() + collapseTimeout2Ref.current = null + }, 50) + } + collapseTimeout1Ref.current = null + }, + WINDOW_SHADE_SETTINGS.transitionDelayS * 1000 + 50, + ) + }}> + {windowShade ? : } + + )} - setWordWrap(!wordWrap)} - title={t(`chat:codeblock.tooltips.${wordWrap ? "disable_wrap" : "enable_wrap"}`)}> - {wordWrap ? : } - - - {showCopyFeedback ? : } - + + setWordWrap(!wordWrap)}> + {wordWrap ? : } + + + + + {showCopyFeedback ? : } + + )} diff --git a/webview-ui/src/components/common/IconButton.tsx b/webview-ui/src/components/common/IconButton.tsx index 70a66ba9f1..ac8b7ca1e2 100644 --- a/webview-ui/src/components/common/IconButton.tsx +++ b/webview-ui/src/components/common/IconButton.tsx @@ -1,3 +1,5 @@ +import { StandardTooltip } from "@/components/ui" + interface IconButtonProps { icon: string onClick?: (e: React.MouseEvent) => void @@ -31,15 +33,21 @@ export function IconButton({ const handleClick = onClick || ((_event: React.MouseEvent) => {}) - return ( + const button = ( ) + + if (title) { + return {button} + } + + return button } diff --git a/webview-ui/src/components/common/MermaidActionButtons.tsx b/webview-ui/src/components/common/MermaidActionButtons.tsx index 46ded57644..79558b9b03 100644 --- a/webview-ui/src/components/common/MermaidActionButtons.tsx +++ b/webview-ui/src/components/common/MermaidActionButtons.tsx @@ -2,6 +2,7 @@ import React from "react" import { useAppTranslation } from "@src/i18n/TranslationContext" import { IconButton } from "./IconButton" import { ZoomControls } from "./ZoomControls" +import { StandardTooltip } from "@/components/ui" interface MermaidActionButtonsProps { onZoom?: (e: React.MouseEvent) => void @@ -40,41 +41,51 @@ export const MermaidActionButtons: React.FC = ({ zoomInTitle={t("common:mermaid.buttons.zoomIn")} zoomOutTitle={t("common:mermaid.buttons.zoomOut")} /> - { - e.stopPropagation() - onViewCode() - }} - title={t("common:mermaid.buttons.viewCode")} - /> - + + { + e.stopPropagation() + onViewCode() + }} + /> + + + + ) } return ( <> - {onZoom && } - { - e.stopPropagation() - onViewCode() - }} - title={t("common:mermaid.buttons.viewCode")} - /> - - {onSave && } - {onClose && } + {onZoom && ( + + + + )} + + { + e.stopPropagation() + onViewCode() + }} + /> + + + + + {onSave && ( + + + + )} + {onClose && ( + + + + )} ) } diff --git a/webview-ui/src/components/common/MermaidButton.tsx b/webview-ui/src/components/common/MermaidButton.tsx index 57d4c26b0a..ede4d0f35e 100644 --- a/webview-ui/src/components/common/MermaidButton.tsx +++ b/webview-ui/src/components/common/MermaidButton.tsx @@ -7,6 +7,7 @@ import { Modal } from "./Modal" import { TabButton } from "./TabButton" import { IconButton } from "./IconButton" import { ZoomControls } from "./ZoomControls" +import { StandardTooltip } from "@/components/ui" const MIN_ZOOM = 0.5 const MAX_ZOOM = 20 @@ -160,11 +161,9 @@ export function MermaidButton({ containerRef, code, isLoading, svgToPng, childre
- setShowModal(false)} - title={t("common:mermaid.buttons.close")} - /> + + setShowModal(false)} /> +
- - + + + + + + ) : ( - { - e.stopPropagation() - copyWithFeedback(code, e) - }} - title={t("common:mermaid.buttons.copy")} - /> + + { + e.stopPropagation() + copyWithFeedback(code, e) + }} + /> + )}
diff --git a/webview-ui/src/components/common/ZoomControls.tsx b/webview-ui/src/components/common/ZoomControls.tsx index 47093ec59f..427a17c7fd 100644 --- a/webview-ui/src/components/common/ZoomControls.tsx +++ b/webview-ui/src/components/common/ZoomControls.tsx @@ -1,5 +1,6 @@ import { IconButton } from "./IconButton" import { useRef, useEffect } from "react" +import { StandardTooltip } from "@/components/ui" interface ZoomControlsProps { zoomLevel: number @@ -67,25 +68,27 @@ export function ZoomControls({ return (
- adjustZoom?.(zoomOutStep)) : undefined} - onMouseDown={useContinuousZoom && adjustZoom ? () => startContinuousZoom(zoomOutStep) : undefined} - onMouseUp={useContinuousZoom && adjustZoom ? stopContinuousZoom : undefined} - onMouseLeave={useContinuousZoom && adjustZoom ? stopContinuousZoom : undefined} - /> + + adjustZoom?.(zoomOutStep)) : undefined} + onMouseDown={useContinuousZoom && adjustZoom ? () => startContinuousZoom(zoomOutStep) : undefined} + onMouseUp={useContinuousZoom && adjustZoom ? stopContinuousZoom : undefined} + onMouseLeave={useContinuousZoom && adjustZoom ? stopContinuousZoom : undefined} + /> +
{Math.round(zoomLevel * 100)}%
- adjustZoom?.(zoomInStep)) : undefined} - onMouseDown={useContinuousZoom && adjustZoom ? () => startContinuousZoom(zoomInStep) : undefined} - onMouseUp={useContinuousZoom && adjustZoom ? stopContinuousZoom : undefined} - onMouseLeave={useContinuousZoom && adjustZoom ? stopContinuousZoom : undefined} - /> + + adjustZoom?.(zoomInStep)) : undefined} + onMouseDown={useContinuousZoom && adjustZoom ? () => startContinuousZoom(zoomInStep) : undefined} + onMouseUp={useContinuousZoom && adjustZoom ? stopContinuousZoom : undefined} + onMouseLeave={useContinuousZoom && adjustZoom ? stopContinuousZoom : undefined} + /> +
) } diff --git a/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx b/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx index a1d3849744..f5278d5cdf 100644 --- a/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx +++ b/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx @@ -1,6 +1,6 @@ // npx vitest run src/components/common/__tests__/CodeBlock.spec.tsx -import { render, screen, fireEvent, act } from "@testing-library/react" +import { render, screen, fireEvent, act } from "@/utils/test-utils" import CodeBlock from "../CodeBlock" @@ -170,9 +170,15 @@ describe("CodeBlock", () => { codeBlock.setAttribute("data-partially-visible", "true") } - const copyButton = screen.getByTitle("Copy code") - await act(async () => { - fireEvent.click(copyButton) - }) + // Find the copy button by looking for the button containing the Copy icon + const buttons = screen.getAllByRole("button") + const copyButton = buttons.find((btn) => btn.querySelector("svg.lucide-copy")) + + expect(copyButton).toBeTruthy() + if (copyButton) { + await act(async () => { + fireEvent.click(copyButton) + }) + } }) }) diff --git a/webview-ui/src/components/common/__tests__/MarkdownBlock.spec.tsx b/webview-ui/src/components/common/__tests__/MarkdownBlock.spec.tsx index 5190f7fe82..ec97e4e667 100644 --- a/webview-ui/src/components/common/__tests__/MarkdownBlock.spec.tsx +++ b/webview-ui/src/components/common/__tests__/MarkdownBlock.spec.tsx @@ -1,5 +1,5 @@ import React from "react" -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import MarkdownBlock from "../MarkdownBlock" import { vi } from "vitest" diff --git a/webview-ui/src/components/history/CopyButton.tsx b/webview-ui/src/components/history/CopyButton.tsx index 743b150aae..4243ff8d5a 100644 --- a/webview-ui/src/components/history/CopyButton.tsx +++ b/webview-ui/src/components/history/CopyButton.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react" import { useClipboard } from "@/components/ui/hooks" -import { Button } from "@/components/ui" +import { Button, StandardTooltip } from "@/components/ui" import { useAppTranslation } from "@/i18n/TranslationContext" import { cn } from "@/lib/utils" @@ -25,14 +25,15 @@ export const CopyButton = ({ itemTask }: CopyButtonProps) => { ) return ( - + + + ) } diff --git a/webview-ui/src/components/history/DeleteButton.tsx b/webview-ui/src/components/history/DeleteButton.tsx index b91f13bd50..3e99027546 100644 --- a/webview-ui/src/components/history/DeleteButton.tsx +++ b/webview-ui/src/components/history/DeleteButton.tsx @@ -1,6 +1,6 @@ import { useCallback } from "react" -import { Button } from "@/components/ui" +import { Button, StandardTooltip } from "@/components/ui" import { useAppTranslation } from "@/i18n/TranslationContext" import { vscode } from "@/utils/vscode" @@ -25,14 +25,15 @@ export const DeleteButton = ({ itemId, onDelete }: DeleteButtonProps) => { ) return ( - + + + ) } diff --git a/webview-ui/src/components/history/ExportButton.tsx b/webview-ui/src/components/history/ExportButton.tsx index eeba0ccaf4..fabc8d3d15 100644 --- a/webview-ui/src/components/history/ExportButton.tsx +++ b/webview-ui/src/components/history/ExportButton.tsx @@ -1,5 +1,5 @@ import { vscode } from "@/utils/vscode" -import { Button } from "@/components/ui" +import { Button, StandardTooltip } from "@/components/ui" import { useAppTranslation } from "@/i18n/TranslationContext" import { useCallback } from "react" @@ -15,14 +15,15 @@ export const ExportButton = ({ itemId }: { itemId: string }) => { ) return ( - + + + ) } diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index 2d6ee5fa3d..2f156d0418 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -5,7 +5,16 @@ import { Virtuoso } from "react-virtuoso" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { Button, Checkbox, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui" +import { + Button, + Checkbox, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, + StandardTooltip, +} from "@/components/ui" import { useAppTranslation } from "@/i18n/TranslationContext" import { Tab, TabContent, TabHeader } from "../common/Tab" @@ -75,20 +84,22 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {

{t("history:history")}

- + +
diff --git a/webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.spec.tsx b/webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.spec.tsx index 9fe49663d1..bdcff23cdd 100644 --- a/webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.spec.tsx +++ b/webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { vscode } from "@/utils/vscode" diff --git a/webview-ui/src/components/history/__tests__/CopyButton.spec.tsx b/webview-ui/src/components/history/__tests__/CopyButton.spec.tsx index 0ba1b27a1f..ac1b39859d 100644 --- a/webview-ui/src/components/history/__tests__/CopyButton.spec.tsx +++ b/webview-ui/src/components/history/__tests__/CopyButton.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { useClipboard } from "@/components/ui/hooks" diff --git a/webview-ui/src/components/history/__tests__/DeleteButton.spec.tsx b/webview-ui/src/components/history/__tests__/DeleteButton.spec.tsx index 42c17f5335..19b333ab44 100644 --- a/webview-ui/src/components/history/__tests__/DeleteButton.spec.tsx +++ b/webview-ui/src/components/history/__tests__/DeleteButton.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { DeleteButton } from "../DeleteButton" diff --git a/webview-ui/src/components/history/__tests__/DeleteTaskDialog.spec.tsx b/webview-ui/src/components/history/__tests__/DeleteTaskDialog.spec.tsx index e78101f37d..f8e244e9bf 100644 --- a/webview-ui/src/components/history/__tests__/DeleteTaskDialog.spec.tsx +++ b/webview-ui/src/components/history/__tests__/DeleteTaskDialog.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { vscode } from "@/utils/vscode" diff --git a/webview-ui/src/components/history/__tests__/ExportButton.spec.tsx b/webview-ui/src/components/history/__tests__/ExportButton.spec.tsx index 68f4407400..1dda83305c 100644 --- a/webview-ui/src/components/history/__tests__/ExportButton.spec.tsx +++ b/webview-ui/src/components/history/__tests__/ExportButton.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { vscode } from "@src/utils/vscode" diff --git a/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx b/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx index 179c51b1c0..6118509702 100644 --- a/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx +++ b/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import type { HistoryItem } from "@roo-code/types" diff --git a/webview-ui/src/components/history/__tests__/HistoryView.spec.tsx b/webview-ui/src/components/history/__tests__/HistoryView.spec.tsx index 030c36f503..3079844aad 100644 --- a/webview-ui/src/components/history/__tests__/HistoryView.spec.tsx +++ b/webview-ui/src/components/history/__tests__/HistoryView.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { useExtensionState } from "@src/context/ExtensionStateContext" diff --git a/webview-ui/src/components/history/__tests__/TaskItem.spec.tsx b/webview-ui/src/components/history/__tests__/TaskItem.spec.tsx index 9fcc11e572..9d4a939a1e 100644 --- a/webview-ui/src/components/history/__tests__/TaskItem.spec.tsx +++ b/webview-ui/src/components/history/__tests__/TaskItem.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import TaskItem from "../TaskItem" diff --git a/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx b/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx index f1390b7d55..661cecf122 100644 --- a/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx +++ b/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import TaskItemFooter from "../TaskItemFooter" diff --git a/webview-ui/src/components/history/__tests__/TaskItemHeader.spec.tsx b/webview-ui/src/components/history/__tests__/TaskItemHeader.spec.tsx index 02f554d697..090bf2521f 100644 --- a/webview-ui/src/components/history/__tests__/TaskItemHeader.spec.tsx +++ b/webview-ui/src/components/history/__tests__/TaskItemHeader.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import TaskItemHeader from "../TaskItemHeader" diff --git a/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx b/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx index e047a81cf3..bea79814fa 100644 --- a/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx +++ b/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx @@ -1,4 +1,4 @@ -import { renderHook, act } from "@testing-library/react" +import { renderHook, act } from "@/utils/test-utils" import type { HistoryItem } from "@roo-code/types" diff --git a/webview-ui/src/components/marketplace/MarketplaceView.tsx b/webview-ui/src/components/marketplace/MarketplaceView.tsx index b469e886ea..b47e1aa875 100644 --- a/webview-ui/src/components/marketplace/MarketplaceView.tsx +++ b/webview-ui/src/components/marketplace/MarketplaceView.tsx @@ -81,7 +81,7 @@ export function MarketplaceView({ stateManager, onDone, targetTab }: Marketplace const filteredTags = useMemo(() => allTags, [allTags]) return ( - +
diff --git a/webview-ui/src/components/marketplace/__tests__/MarketplaceListView.spec.tsx b/webview-ui/src/components/marketplace/__tests__/MarketplaceListView.spec.tsx index 8e62af73c9..06078d638c 100644 --- a/webview-ui/src/components/marketplace/__tests__/MarketplaceListView.spec.tsx +++ b/webview-ui/src/components/marketplace/__tests__/MarketplaceListView.spec.tsx @@ -1,6 +1,6 @@ // npx vitest run src/components/marketplace/__tests__/MarketplaceListView.spec.tsx -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import userEvent from "@testing-library/user-event" import { TooltipProvider } from "@/components/ui/tooltip" @@ -49,7 +49,7 @@ describe("MarketplaceListView", () => { const renderWithProviders = (props = {}) => render( - + , diff --git a/webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx b/webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx index 10290b70b3..95b2dea54b 100644 --- a/webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx +++ b/webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import userEvent from "@testing-library/user-event" import { MarketplaceView } from "../MarketplaceView" diff --git a/webview-ui/src/components/marketplace/components/MarketplaceItemCard.tsx b/webview-ui/src/components/marketplace/components/MarketplaceItemCard.tsx index b59291a35b..defc138581 100644 --- a/webview-ui/src/components/marketplace/components/MarketplaceItemCard.tsx +++ b/webview-ui/src/components/marketplace/components/MarketplaceItemCard.tsx @@ -7,7 +7,7 @@ import { useAppTranslation } from "@/i18n/TranslationContext" import { isValidUrl } from "../../../utils/url" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" +import { StandardTooltip } from "@/components/ui" import { MarketplaceInstallModal } from "./MarketplaceInstallModal" import { useExtensionState } from "@/context/ExtensionStateContext" @@ -79,37 +79,33 @@ export const MarketplaceItemCard: React.FC = ({ item,
{isInstalled ? ( /* Single Remove button when installed */ - - - - - - - - {isInstalledInProject + - + : t("marketplace:items.card.removeGlobalTooltip") + }> + + ) : ( /* Single Install button when not installed */ + + ))}
)} diff --git a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.spec.tsx b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.spec.tsx index 8ffb15abd4..29af469f80 100644 --- a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.spec.tsx +++ b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent, waitFor } from "@testing-library/react" +import { render, screen, fireEvent, waitFor } from "@/utils/test-utils" import { MarketplaceItem } from "@roo-code/types" diff --git a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.spec.tsx b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.spec.tsx index 6bc9453cd9..e586fbb9e1 100644 --- a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.spec.tsx +++ b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent, waitFor } from "@testing-library/react" +import { render, screen, fireEvent, waitFor } from "@/utils/test-utils" import { MarketplaceItem } from "@roo-code/types" diff --git a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.spec.tsx b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.spec.tsx index bd88de7229..1f1ed9030b 100644 --- a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.spec.tsx +++ b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen } from "@testing-library/react" +import { render, screen } from "@/utils/test-utils" import userEvent from "@testing-library/user-event" import { MarketplaceItem } from "@roo-code/types" @@ -57,7 +57,7 @@ vi.mock("@/i18n/TranslationContext", () => ({ })) const renderWithProviders = (ui: React.ReactElement) => { - return render({ui}) + return render({ui}) } describe("MarketplaceItemCard", () => { diff --git a/webview-ui/src/components/mcp/McpToolRow.tsx b/webview-ui/src/components/mcp/McpToolRow.tsx index 892304d1c6..58b938f9f1 100644 --- a/webview-ui/src/components/mcp/McpToolRow.tsx +++ b/webview-ui/src/components/mcp/McpToolRow.tsx @@ -4,6 +4,7 @@ import { McpTool } from "@roo/mcp" import { useAppTranslation } from "@src/i18n/TranslationContext" import { vscode } from "@src/utils/vscode" +import { StandardTooltip } from "@/components/ui" type McpToolRowProps = { tool: McpTool @@ -46,9 +47,9 @@ const McpToolRow = ({ tool, serverName, serverSource, alwaysAllowMcp, isInChatCo {/* Tool name section */}
- - {tool.name} - + + {tool.name} +
{/* Controls section */} @@ -69,24 +70,25 @@ const McpToolRow = ({ tool, serverName, serverSource, alwaysAllowMcp, isInChatCo {/* Enabled eye button - only show in settings context */} {!isInChatContext && ( - + + + )}
)} diff --git a/webview-ui/src/components/mcp/__tests__/McpToolRow.spec.tsx b/webview-ui/src/components/mcp/__tests__/McpToolRow.spec.tsx index a3ccd6a990..2bfe3b1338 100644 --- a/webview-ui/src/components/mcp/__tests__/McpToolRow.spec.tsx +++ b/webview-ui/src/components/mcp/__tests__/McpToolRow.spec.tsx @@ -1,5 +1,5 @@ import React from "react" -import { render, fireEvent, screen } from "@testing-library/react" +import { render, fireEvent, screen } from "@/utils/test-utils" import { vscode } from "@src/utils/vscode" diff --git a/webview-ui/src/components/modes/ModesView.tsx b/webview-ui/src/components/modes/ModesView.tsx index 42069de8f8..2dd6c6dc76 100644 --- a/webview-ui/src/components/modes/ModesView.tsx +++ b/webview-ui/src/components/modes/ModesView.tsx @@ -45,6 +45,7 @@ import { CommandItem, CommandGroup, Input, + StandardTooltip, } from "@src/components/ui" // Get all available groups that should show in prompts view @@ -431,30 +432,29 @@ const ModesView = ({ onDone }: ModesViewProps) => {
e.stopPropagation()} className="flex justify-between items-center mb-3">

{t("prompts:modes.title")}

- -
- + +
+ + + {showConfigMenu && (
e.stopPropagation()} @@ -652,18 +652,19 @@ const ModesView = ({ onDone }: ModesViewProps) => { }} className="w-full" /> - + + +
@@ -674,19 +675,20 @@ const ModesView = ({ onDone }: ModesViewProps) => {
{t("prompts:roleDefinition.title")}
{!findModeBySlug(visualMode, customModes) && ( - + + + )}
@@ -733,19 +735,20 @@ const ModesView = ({ onDone }: ModesViewProps) => {
{t("prompts:description.title")}
{!findModeBySlug(visualMode, customModes) && ( - + + + )}
@@ -786,19 +789,20 @@ const ModesView = ({ onDone }: ModesViewProps) => {
{t("prompts:whenToUse.title")}
{!findModeBySlug(visualMode, customModes) && ( - + + + )}
@@ -843,18 +847,20 @@ const ModesView = ({ onDone }: ModesViewProps) => {
{t("prompts:tools.title")}
{findModeBySlug(visualMode, customModes) && ( - + + )}
{!findModeBySlug(visualMode, customModes) && ( @@ -936,19 +942,20 @@ const ModesView = ({ onDone }: ModesViewProps) => {
{t("prompts:customInstructions.title")}
{!findModeBySlug(visualMode, customModes) && ( - + + + )}
@@ -1041,22 +1048,23 @@ const ModesView = ({ onDone }: ModesViewProps) => { data-testid="preview-prompt-button"> {t("prompts:systemPrompt.preview")} - + + +
{/* Custom System Prompt Disclosure */} diff --git a/webview-ui/src/components/modes/__tests__/ModesView.spec.tsx b/webview-ui/src/components/modes/__tests__/ModesView.spec.tsx index 4ff7f4cf87..e202114bbb 100644 --- a/webview-ui/src/components/modes/__tests__/ModesView.spec.tsx +++ b/webview-ui/src/components/modes/__tests__/ModesView.spec.tsx @@ -1,6 +1,6 @@ // npx vitest src/components/modes/__tests__/ModesView.spec.tsx -import { render, screen, fireEvent, waitFor } from "@testing-library/react" +import { render, screen, fireEvent, waitFor } from "@/utils/test-utils" import ModesView from "../ModesView" import { ExtensionStateContext } from "@src/context/ExtensionStateContext" import { vscode } from "@src/utils/vscode" diff --git a/webview-ui/src/components/settings/ApiConfigManager.tsx b/webview-ui/src/components/settings/ApiConfigManager.tsx index d0a0a6aa44..edd0a5fe07 100644 --- a/webview-ui/src/components/settings/ApiConfigManager.tsx +++ b/webview-ui/src/components/settings/ApiConfigManager.tsx @@ -21,6 +21,7 @@ import { Popover, PopoverContent, PopoverTrigger, + StandardTooltip, } from "@/components/ui" interface ApiConfigManagerProps { @@ -248,23 +249,25 @@ const ApiConfigManager = ({ }} className="grow" /> - - + + + + + +
{error && (
@@ -334,13 +337,17 @@ const ApiConfigManager = ({ className={!valid ? "text-vscode-errorForeground" : ""}>
{!valid && ( - - - + + + + + )} {config.name}
@@ -360,37 +367,37 @@ const ApiConfigManager = ({ - + + + {currentApiConfigName && ( <> - - + + - - + }> + + )}
diff --git a/webview-ui/src/components/settings/AutoApproveToggle.tsx b/webview-ui/src/components/settings/AutoApproveToggle.tsx index ffad47e2ac..d2b6694f75 100644 --- a/webview-ui/src/components/settings/AutoApproveToggle.tsx +++ b/webview-ui/src/components/settings/AutoApproveToggle.tsx @@ -2,7 +2,7 @@ import type { GlobalSettings } from "@roo-code/types" import { useAppTranslation } from "@/i18n/TranslationContext" import { cn } from "@/lib/utils" -import { Button } from "@/components/ui" +import { Button, StandardTooltip } from "@/components/ui" type AutoApproveToggles = Pick< GlobalSettings, @@ -100,20 +100,20 @@ export const AutoApproveToggle = ({ onToggle, ...props }: AutoApproveToggleProps "[@media(min-width:800px)]:max-w-[800px]", )}> {Object.values(autoApproveSettingsConfig).map(({ key, descriptionKey, labelKey, icon, testId }) => ( - + + + ))}
) diff --git a/webview-ui/src/components/settings/PromptsSettings.tsx b/webview-ui/src/components/settings/PromptsSettings.tsx index 568b8eeee1..160f79dc84 100644 --- a/webview-ui/src/components/settings/PromptsSettings.tsx +++ b/webview-ui/src/components/settings/PromptsSettings.tsx @@ -6,7 +6,15 @@ import { supportPrompt, SupportPromptType } from "@roo/support-prompt" import { vscode } from "@src/utils/vscode" import { useAppTranslation } from "@src/i18n/TranslationContext" import { useExtensionState } from "@src/context/ExtensionStateContext" -import { Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@src/components/ui" +import { + Button, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, + StandardTooltip, +} from "@src/components/ui" import { SectionHeader } from "./SectionHeader" import { Section } from "./Section" import { MessageSquare } from "lucide-react" @@ -97,15 +105,14 @@ const PromptsSettings = ({ customSupportPrompts, setCustomSupportPrompts }: Prom
- + +
(({ onDone, t

{t("settings:header.title")}

- - + }> + + + + +
@@ -510,7 +512,7 @@ const SettingsView = forwardRef(({ onDone, t if (isCompactMode) { // Wrap in Tooltip and manually add onClick to the trigger return ( - + {/* Clone to avoid ref issues if triggerComponent itself had a key */} diff --git a/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx b/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx index 553f60c79e..194f0ff31e 100644 --- a/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx @@ -1,6 +1,6 @@ // npx vitest src/components/settings/__tests__/ApiConfigManager.spec.tsx -import { render, screen, fireEvent, within } from "@testing-library/react" +import { render, screen, fireEvent, within } from "@/utils/test-utils" import ApiConfigManager from "../ApiConfigManager" @@ -41,6 +41,7 @@ vitest.mock("@/components/ui", () => ({ data-testid={dataTestId} /> ), + StandardTooltip: ({ children, content }: any) =>
{children}
, // New components for searchable dropdown Popover: ({ children, open }: any) => (
diff --git a/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx b/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx index 31cc2ec82f..1e13323f36 100644 --- a/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx @@ -1,6 +1,6 @@ // npx vitest src/components/settings/__tests__/ApiOptions.spec.tsx -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import { type ModelInfo, type ProviderSettings, openAiModelInfoSaneDefaults } from "@roo-code/types" @@ -61,6 +61,7 @@ vi.mock("@/components/ui", () => ({ {children} ), + StandardTooltip: ({ children, content }: any) =>
{children}
, // Add missing components used by ModelPicker Command: ({ children }: any) =>
{children}
, CommandEmpty: ({ children }: any) =>
{children}
, diff --git a/webview-ui/src/components/settings/__tests__/AutoApproveToggle.spec.tsx b/webview-ui/src/components/settings/__tests__/AutoApproveToggle.spec.tsx index 4442cb9abb..97e5dcc96b 100644 --- a/webview-ui/src/components/settings/__tests__/AutoApproveToggle.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/AutoApproveToggle.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { TranslationProvider } from "@/i18n/__mocks__/TranslationContext" diff --git a/webview-ui/src/components/settings/__tests__/CodeIndexSettings.spec.tsx b/webview-ui/src/components/settings/__tests__/CodeIndexSettings.spec.tsx index 7e591114a8..3c3dae7956 100644 --- a/webview-ui/src/components/settings/__tests__/CodeIndexSettings.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/CodeIndexSettings.spec.tsx @@ -1,6 +1,6 @@ // npx vitest src/components/settings/__tests__/CodeIndexSettings.spec.tsx -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import userEvent from "@testing-library/user-event" import { CodeIndexSettings } from "../CodeIndexSettings" diff --git a/webview-ui/src/components/settings/__tests__/ContextManagementSettings.spec.tsx b/webview-ui/src/components/settings/__tests__/ContextManagementSettings.spec.tsx index 9a7d451d1d..e467ab51d6 100644 --- a/webview-ui/src/components/settings/__tests__/ContextManagementSettings.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ContextManagementSettings.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { ContextManagementSettings } from "@src/components/settings/ContextManagementSettings" diff --git a/webview-ui/src/components/settings/__tests__/ModelPicker.spec.tsx b/webview-ui/src/components/settings/__tests__/ModelPicker.spec.tsx index 38237dc0e3..82c6da2a3f 100644 --- a/webview-ui/src/components/settings/__tests__/ModelPicker.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ModelPicker.spec.tsx @@ -1,6 +1,6 @@ // npx vitest src/components/settings/__tests__/ModelPicker.spec.tsx -import { screen, fireEvent, render } from "@testing-library/react" +import { screen, fireEvent, render } from "@/utils/test-utils" import { act } from "react" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import { vi } from "vitest" diff --git a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx index 8d79b998a1..0a76e54ffe 100644 --- a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import { vscode } from "@/utils/vscode" @@ -115,6 +115,7 @@ vi.mock("@/components/ui", () => ({ {children} ), + StandardTooltip: ({ children, content }: any) =>
{children}
, Input: ({ value, onChange, placeholder, "data-testid": dataTestId }: any) => ( ), diff --git a/webview-ui/src/components/settings/__tests__/TemperatureControl.spec.tsx b/webview-ui/src/components/settings/__tests__/TemperatureControl.spec.tsx index ad4e352126..f9eba66c8f 100644 --- a/webview-ui/src/components/settings/__tests__/TemperatureControl.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/TemperatureControl.spec.tsx @@ -1,6 +1,6 @@ // npx vitest src/components/settings/__tests__/TemperatureControl.spec.tsx -import { render, screen, fireEvent, waitFor } from "@testing-library/react" +import { render, screen, fireEvent, waitFor } from "@/utils/test-utils" import { TemperatureControl } from "../TemperatureControl" diff --git a/webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx b/webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx index f5d1cf29dd..5ca51b4528 100644 --- a/webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx @@ -1,6 +1,6 @@ // npx vitest src/components/settings/__tests__/ThinkingBudget.spec.tsx -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import type { ModelInfo } from "@roo-code/types" diff --git a/webview-ui/src/components/settings/providers/Bedrock.tsx b/webview-ui/src/components/settings/providers/Bedrock.tsx index a0ebafd88e..1839298f9b 100644 --- a/webview-ui/src/components/settings/providers/Bedrock.tsx +++ b/webview-ui/src/components/settings/providers/Bedrock.tsx @@ -5,7 +5,7 @@ import { VSCodeTextField, VSCodeRadio, VSCodeRadioGroup } from "@vscode/webview- import { type ProviderSettings, type ModelInfo, BEDROCK_REGIONS } from "@roo-code/types" import { useAppTranslation } from "@src/i18n/TranslationContext" -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@src/components/ui" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StandardTooltip } from "@src/components/ui" import { inputEventTransform, noTransform } from "../transforms" @@ -114,11 +114,12 @@ export const Bedrock = ({ apiConfiguration, setApiConfigurationField, selectedMo onChange={handleInputChange("awsUsePromptCache", noTransform)}>
{t("settings:providers.enablePromptCaching")} - + + +
diff --git a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx index b5f7abc7d4..736b0253c4 100644 --- a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx +++ b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx @@ -15,7 +15,7 @@ import { import { ExtensionMessage } from "@roo/ExtensionMessage" import { useAppTranslation } from "@src/i18n/TranslationContext" -import { Button } from "@src/components/ui" +import { Button, StandardTooltip } from "@src/components/ui" import { convertHeadersToObject } from "../utils/headers" import { inputEventTransform, noTransform } from "../transforms" @@ -208,9 +208,11 @@ export const OpenAICompatible = ({
- - - + + + + +
{!customHeaders.length ? (
@@ -231,12 +233,11 @@ export const OpenAICompatible = ({ placeholder={t("settings:providers.headerValue")} onInput={(e: any) => handleUpdateHeaderValue(index, e.target.value)} /> - handleRemoveCustomHeader(index)}> - - + + handleRemoveCustomHeader(index)}> + + +
)) )} @@ -305,7 +306,6 @@ export const OpenAICompatible = ({ return value > 0 ? "var(--vscode-charts-green)" : "var(--vscode-errorForeground)" })(), }} - title={t("settings:providers.customModel.maxTokens.description")} onInput={handleInputChange("openAiCustomModelInfo", (e) => { const value = parseInt((e.target as HTMLInputElement).value) @@ -344,7 +344,6 @@ export const OpenAICompatible = ({ return value > 0 ? "var(--vscode-charts-green)" : "var(--vscode-errorForeground)" })(), }} - title={t("settings:providers.customModel.contextWindow.description")} onInput={handleInputChange("openAiCustomModelInfo", (e) => { const value = (e.target as HTMLInputElement).value const parsed = parseInt(value) @@ -382,11 +381,12 @@ export const OpenAICompatible = ({ {t("settings:providers.customModel.imageSupport.label")} - + + +
{t("settings:providers.customModel.imageSupport.description")} @@ -405,11 +405,12 @@ export const OpenAICompatible = ({ })}> {t("settings:providers.customModel.computerUse.label")} - + + +
{t("settings:providers.customModel.computerUse.description")} @@ -428,11 +429,12 @@ export const OpenAICompatible = ({ })}> {t("settings:providers.customModel.promptCache.label")} - + + +
{t("settings:providers.customModel.promptCache.description")} @@ -473,11 +475,12 @@ export const OpenAICompatible = ({ - + + +
@@ -516,11 +519,12 @@ export const OpenAICompatible = ({ - + + +
@@ -559,11 +563,13 @@ export const OpenAICompatible = ({ {t("settings:providers.customModel.pricing.cacheReads.label")} - + + +
@@ -599,11 +605,13 @@ export const OpenAICompatible = ({ - + + +
diff --git a/webview-ui/src/components/settings/providers/__tests__/Bedrock.spec.tsx b/webview-ui/src/components/settings/providers/__tests__/Bedrock.spec.tsx index ac99a12c6c..b5bb16e975 100644 --- a/webview-ui/src/components/settings/providers/__tests__/Bedrock.spec.tsx +++ b/webview-ui/src/components/settings/providers/__tests__/Bedrock.spec.tsx @@ -1,5 +1,5 @@ import React from "react" -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { Bedrock } from "../Bedrock" import { ProviderSettings } from "@roo-code/types" diff --git a/webview-ui/src/components/settings/providers/__tests__/OpenAICompatible.spec.tsx b/webview-ui/src/components/settings/providers/__tests__/OpenAICompatible.spec.tsx index c96de176e6..aba81ec219 100644 --- a/webview-ui/src/components/settings/providers/__tests__/OpenAICompatible.spec.tsx +++ b/webview-ui/src/components/settings/providers/__tests__/OpenAICompatible.spec.tsx @@ -1,5 +1,5 @@ import React from "react" -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { OpenAICompatible } from "../OpenAICompatible" import { ProviderSettings } from "@roo-code/types" @@ -64,6 +64,7 @@ vi.mock("@src/i18n/TranslationContext", () => ({ // Mock the UI components vi.mock("@src/components/ui", () => ({ Button: ({ children, onClick }: any) => , + StandardTooltip: ({ children, content }: any) =>
{children}
, })) // Mock other components diff --git a/webview-ui/src/components/ui/__tests__/select-dropdown.spec.tsx b/webview-ui/src/components/ui/__tests__/select-dropdown.spec.tsx index d4ed834654..2262adb872 100644 --- a/webview-ui/src/components/ui/__tests__/select-dropdown.spec.tsx +++ b/webview-ui/src/components/ui/__tests__/select-dropdown.spec.tsx @@ -1,7 +1,7 @@ // npx vitest run src/components/ui/__tests__/select-dropdown.spec.tsx import { ReactNode } from "react" -import { render, screen, fireEvent } from "@testing-library/react" +import { render, screen, fireEvent } from "@/utils/test-utils" import { SelectDropdown, DropdownOptionType } from "../select-dropdown" diff --git a/webview-ui/src/components/ui/__tests__/tooltip.spec.tsx b/webview-ui/src/components/ui/__tests__/tooltip.spec.tsx new file mode 100644 index 0000000000..e1cb619545 --- /dev/null +++ b/webview-ui/src/components/ui/__tests__/tooltip.spec.tsx @@ -0,0 +1,182 @@ +import { render, screen, waitFor } from "@testing-library/react" +import userEvent from "@testing-library/user-event" +import { describe, it, expect } from "vitest" +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../tooltip" +import { StandardTooltip } from "../standard-tooltip" + +describe("Tooltip", () => { + it("should render tooltip content on hover", async () => { + const user = userEvent.setup() + + render( + + + Hover me + Tooltip text + + , + ) + + const trigger = screen.getByText("Hover me") + await user.hover(trigger) + + await waitFor( + () => { + const tooltips = screen.getAllByText("Tooltip text") + expect(tooltips.length).toBeGreaterThan(0) + }, + { timeout: 1000 }, + ) + }) + + it("should apply text wrapping classes", async () => { + const user = userEvent.setup() + + render( + + + Hover me + + This is a very long tooltip text that should wrap when it reaches the maximum width + + + , + ) + + const trigger = screen.getByText("Hover me") + await user.hover(trigger) + + await waitFor( + () => { + const tooltips = screen.getAllByText(/This is a very long tooltip text/) + const visibleTooltip = tooltips.find((el) => el.getAttribute("role") !== "tooltip") + expect(visibleTooltip).toHaveClass("max-w-[300px]", "break-words") + }, + { timeout: 1000 }, + ) + }) + + it("should not have overflow-hidden class", async () => { + const user = userEvent.setup() + + render( + + + Hover me + Tooltip text + + , + ) + + const trigger = screen.getByText("Hover me") + await user.hover(trigger) + + await waitFor( + () => { + const tooltips = screen.getAllByText("Tooltip text") + const visibleTooltip = tooltips.find((el) => el.getAttribute("role") !== "tooltip") + expect(visibleTooltip).not.toHaveClass("overflow-hidden") + }, + { timeout: 1000 }, + ) + }) +}) + +describe("StandardTooltip", () => { + it("should render with default delay", async () => { + const user = userEvent.setup() + + render( + + + + + , + ) + + const trigger = screen.getByText("Hover me") + await user.hover(trigger) + + await waitFor( + () => { + const tooltips = screen.getAllByText("Tooltip text") + expect(tooltips.length).toBeGreaterThan(0) + }, + { timeout: 1000 }, + ) + }) + + it("should apply custom maxWidth", async () => { + const user = userEvent.setup() + + render( + + + + + , + ) + + const trigger = screen.getByText("Hover me") + await user.hover(trigger) + + await waitFor( + () => { + const tooltips = screen.getAllByText("Long tooltip text") + const visibleTooltip = tooltips.find((el) => el.getAttribute("role") !== "tooltip") + expect(visibleTooltip).toHaveStyle({ maxWidth: "200px" }) + }, + { timeout: 1000 }, + ) + }) + + it("should apply custom maxWidth as string", async () => { + const user = userEvent.setup() + + render( + + + + + , + ) + + const trigger = screen.getByText("Hover me") + await user.hover(trigger) + + await waitFor( + () => { + const tooltips = screen.getAllByText("Long tooltip text") + const visibleTooltip = tooltips.find((el) => el.getAttribute("role") !== "tooltip") + expect(visibleTooltip).toHaveStyle({ maxWidth: "15rem" }) + }, + { timeout: 1000 }, + ) + }) + + it("should handle long content with text wrapping", async () => { + const user = userEvent.setup() + const longContent = + "This is a very long tooltip content that should definitely wrap when displayed because it exceeds the maximum width constraint" + + render( + + + + + , + ) + + const trigger = screen.getByText("Hover me") + await user.hover(trigger) + + await waitFor( + () => { + const tooltips = screen.getAllByText(longContent) + const visibleTooltip = tooltips.find((el) => el.getAttribute("role") !== "tooltip") + expect(visibleTooltip).toHaveClass("max-w-[300px]", "break-words") + }, + { timeout: 1000 }, + ) + }) +}) diff --git a/webview-ui/src/components/ui/index.ts b/webview-ui/src/components/ui/index.ts index 69d9c093e0..5bd6b62ee8 100644 --- a/webview-ui/src/components/ui/index.ts +++ b/webview-ui/src/components/ui/index.ts @@ -16,3 +16,4 @@ export * from "./select-dropdown" export * from "./select" export * from "./textarea" export * from "./tooltip" +export * from "./standard-tooltip" diff --git a/webview-ui/src/components/ui/select-dropdown.tsx b/webview-ui/src/components/ui/select-dropdown.tsx index 7fcc6884b7..d9ee99ebbb 100644 --- a/webview-ui/src/components/ui/select-dropdown.tsx +++ b/webview-ui/src/components/ui/select-dropdown.tsx @@ -7,6 +7,7 @@ import { useTranslation } from "react-i18next" import { cn } from "@/lib/utils" import { useRooPortal } from "./hooks/useRooPortal" import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui" +import { StandardTooltip } from "@/components/ui" export enum DropdownOptionType { ITEM = "item", @@ -185,25 +186,28 @@ export const SelectDropdown = React.memo( [onChange, options], ) + const triggerContent = ( + + + {displayText} + + ) + return ( - - - {displayText} - + {title ? {triggerContent} : triggerContent} + * + * + * + * // With custom positioning + * + * + * + * + * @note This replaces native HTML title attributes for consistent timing. + * @note Requires a TooltipProvider to be present in the component tree (typically at the app root). + * @note Do not nest StandardTooltip components as this can cause UI issues. + */ +export function StandardTooltip({ + children, + content, + side = "top", + align = "center", + sideOffset = 4, + className, + asChild = true, + maxWidth, +}: StandardTooltipProps) { + // Don't render tooltip if content is empty or only whitespace + if (!content || (typeof content === "string" && !content.trim())) { + return <>{children} + } + + const style = maxWidth ? { maxWidth: typeof maxWidth === "number" ? `${maxWidth}px` : maxWidth } : undefined + + return ( + + {children} + + {content} + + + ) +} diff --git a/webview-ui/src/components/ui/tooltip.tsx b/webview-ui/src/components/ui/tooltip.tsx index 7818d9b125..d09d8cec9d 100644 --- a/webview-ui/src/components/ui/tooltip.tsx +++ b/webview-ui/src/components/ui/tooltip.tsx @@ -17,8 +17,11 @@ const TooltipContent = React.forwardRef< { + return {children} +} + +const customRender = (ui: React.ReactElement, options?: Omit) => + render(ui, { wrapper: AllTheProviders, ...options }) + +// re-export everything +export * from "@testing-library/react" + +// override render method +export { customRender as render } From 992997c02f5ce286f2ec5975d3de95bf46e45359 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Thu, 26 Jun 2025 14:03:18 -0600 Subject: [PATCH 04/70] feat: add Gemini CLI provider for free access to Gemini models (#5134) (#5137) Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> Co-authored-by: Matt Rubens Co-authored-by: Daniel Riccio Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com> --- packages/types/src/provider-settings.ts | 8 + packages/types/src/providers/gemini-cli.ts | 110 +++++ packages/types/src/providers/index.ts | 1 + src/api/index.ts | 3 + .../providers/__tests__/gemini-cli.spec.ts | 329 ++++++++++++++ src/api/providers/gemini-cli.ts | 419 ++++++++++++++++++ src/api/providers/index.ts | 1 + src/i18n/locales/ca/common.json | 10 + src/i18n/locales/de/common.json | 10 + src/i18n/locales/en/common.json | 10 + src/i18n/locales/es/common.json | 10 + src/i18n/locales/fr/common.json | 10 + src/i18n/locales/hi/common.json | 10 + src/i18n/locales/id/common.json | 10 + src/i18n/locales/it/common.json | 10 + src/i18n/locales/ja/common.json | 10 + src/i18n/locales/ko/common.json | 10 + src/i18n/locales/nl/common.json | 10 + src/i18n/locales/pl/common.json | 10 + src/i18n/locales/pt-BR/common.json | 10 + src/i18n/locales/ru/common.json | 10 + src/i18n/locales/tr/common.json | 10 + src/i18n/locales/vi/common.json | 10 + src/i18n/locales/zh-CN/common.json | 10 + src/i18n/locales/zh-TW/common.json | 10 + src/shared/checkExistApiConfig.ts | 4 +- .../src/components/settings/ApiOptions.tsx | 7 + .../src/components/settings/constants.ts | 3 + .../settings/providers/GeminiCli.tsx | 81 ++++ .../providers/__tests__/GeminiCli.spec.tsx | 169 +++++++ .../components/settings/providers/index.ts | 1 + .../components/ui/hooks/useSelectedModel.ts | 7 + webview-ui/src/i18n/locales/ca/settings.json | 15 + webview-ui/src/i18n/locales/de/settings.json | 15 + webview-ui/src/i18n/locales/en/settings.json | 15 + webview-ui/src/i18n/locales/es/settings.json | 15 + webview-ui/src/i18n/locales/fr/settings.json | 15 + webview-ui/src/i18n/locales/hi/settings.json | 15 + webview-ui/src/i18n/locales/id/settings.json | 15 + webview-ui/src/i18n/locales/it/settings.json | 15 + webview-ui/src/i18n/locales/ja/settings.json | 15 + webview-ui/src/i18n/locales/ko/settings.json | 15 + webview-ui/src/i18n/locales/nl/settings.json | 15 + webview-ui/src/i18n/locales/pl/settings.json | 15 + .../src/i18n/locales/pt-BR/settings.json | 15 + webview-ui/src/i18n/locales/ru/settings.json | 15 + webview-ui/src/i18n/locales/tr/settings.json | 15 + webview-ui/src/i18n/locales/vi/settings.json | 15 + .../src/i18n/locales/zh-CN/settings.json | 15 + .../src/i18n/locales/zh-TW/settings.json | 15 + webview-ui/src/utils/validate.ts | 3 + 51 files changed, 1594 insertions(+), 2 deletions(-) create mode 100644 packages/types/src/providers/gemini-cli.ts create mode 100644 src/api/providers/__tests__/gemini-cli.spec.ts create mode 100644 src/api/providers/gemini-cli.ts create mode 100644 webview-ui/src/components/settings/providers/GeminiCli.tsx create mode 100644 webview-ui/src/components/settings/providers/__tests__/GeminiCli.spec.tsx diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 609d0fefbf..e940ececd1 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -19,6 +19,7 @@ export const providerNames = [ "vscode-lm", "lmstudio", "gemini", + "gemini-cli", "openai-native", "mistral", "deepseek", @@ -158,6 +159,11 @@ const geminiSchema = apiModelIdProviderModelSchema.extend({ googleGeminiBaseUrl: z.string().optional(), }) +const geminiCliSchema = apiModelIdProviderModelSchema.extend({ + geminiCliOAuthPath: z.string().optional(), + geminiCliProjectId: z.string().optional(), +}) + const openAiNativeSchema = apiModelIdProviderModelSchema.extend({ openAiNativeApiKey: z.string().optional(), openAiNativeBaseUrl: z.string().optional(), @@ -223,6 +229,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv vsCodeLmSchema.merge(z.object({ apiProvider: z.literal("vscode-lm") })), lmStudioSchema.merge(z.object({ apiProvider: z.literal("lmstudio") })), geminiSchema.merge(z.object({ apiProvider: z.literal("gemini") })), + geminiCliSchema.merge(z.object({ apiProvider: z.literal("gemini-cli") })), openAiNativeSchema.merge(z.object({ apiProvider: z.literal("openai-native") })), mistralSchema.merge(z.object({ apiProvider: z.literal("mistral") })), deepSeekSchema.merge(z.object({ apiProvider: z.literal("deepseek") })), @@ -250,6 +257,7 @@ export const providerSettingsSchema = z.object({ ...vsCodeLmSchema.shape, ...lmStudioSchema.shape, ...geminiSchema.shape, + ...geminiCliSchema.shape, ...openAiNativeSchema.shape, ...mistralSchema.shape, ...deepSeekSchema.shape, diff --git a/packages/types/src/providers/gemini-cli.ts b/packages/types/src/providers/gemini-cli.ts new file mode 100644 index 0000000000..4ef498220e --- /dev/null +++ b/packages/types/src/providers/gemini-cli.ts @@ -0,0 +1,110 @@ +import type { ModelInfo } from "../model.js" + +// Gemini CLI models with free tier pricing (all $0) +export type GeminiCliModelId = keyof typeof geminiCliModels + +export const geminiCliDefaultModelId: GeminiCliModelId = "gemini-2.0-flash-001" + +export const geminiCliModels = { + "gemini-2.0-flash-001": { + maxTokens: 8192, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-2.0-flash-thinking-exp-01-21": { + maxTokens: 65_536, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-2.0-flash-thinking-exp-1219": { + maxTokens: 8192, + contextWindow: 32_767, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-2.0-flash-exp": { + maxTokens: 8192, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-1.5-flash-002": { + maxTokens: 8192, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-1.5-flash-exp-0827": { + maxTokens: 8192, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-1.5-flash-8b-exp-0827": { + maxTokens: 8192, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-1.5-pro-002": { + maxTokens: 8192, + contextWindow: 2_097_152, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-1.5-pro-exp-0827": { + maxTokens: 8192, + contextWindow: 2_097_152, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-exp-1206": { + maxTokens: 8192, + contextWindow: 2_097_152, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, + "gemini-2.5-flash": { + maxTokens: 64_000, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + maxThinkingTokens: 24_576, + supportsReasoningBudget: true, + }, + "gemini-2.5-pro": { + maxTokens: 64_000, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + maxThinkingTokens: 32_768, + supportsReasoningBudget: true, + requiredReasoningBudget: true, + }, +} as const satisfies Record diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index 267401bd91..0f3e96fdcb 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -4,6 +4,7 @@ export * from "./chutes.js" export * from "./claude-code.js" export * from "./deepseek.js" export * from "./gemini.js" +export * from "./gemini-cli.js" export * from "./glama.js" export * from "./groq.js" export * from "./lite-llm.js" diff --git a/src/api/index.ts b/src/api/index.ts index 960209f714..b70f7dcd45 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -15,6 +15,7 @@ import { OllamaHandler, LmStudioHandler, GeminiHandler, + GeminiCliHandler, OpenAiNativeHandler, DeepSeekHandler, MistralHandler, @@ -85,6 +86,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler { return new LmStudioHandler(options) case "gemini": return new GeminiHandler(options) + case "gemini-cli": + return new GeminiCliHandler(options) case "openai-native": return new OpenAiNativeHandler(options) case "deepseek": diff --git a/src/api/providers/__tests__/gemini-cli.spec.ts b/src/api/providers/__tests__/gemini-cli.spec.ts new file mode 100644 index 0000000000..a84e940e96 --- /dev/null +++ b/src/api/providers/__tests__/gemini-cli.spec.ts @@ -0,0 +1,329 @@ +import { describe, it, expect, vi, beforeEach } from "vitest" +import { GeminiCliHandler } from "../gemini-cli" +import { geminiCliDefaultModelId, geminiCliModels } from "@roo-code/types" +import * as fs from "fs/promises" +import axios from "axios" + +vi.mock("fs/promises") +vi.mock("axios") +vi.mock("google-auth-library", () => ({ + OAuth2Client: vi.fn().mockImplementation(() => ({ + setCredentials: vi.fn(), + refreshAccessToken: vi.fn().mockResolvedValue({ + credentials: { + access_token: "refreshed-token", + refresh_token: "refresh-token", + token_type: "Bearer", + expiry_date: Date.now() + 3600 * 1000, + }, + }), + request: vi.fn(), + })), +})) + +describe("GeminiCliHandler", () => { + let handler: GeminiCliHandler + const mockCredentials = { + access_token: "test-access-token", + refresh_token: "test-refresh-token", + token_type: "Bearer", + expiry_date: Date.now() + 3600 * 1000, + } + + beforeEach(() => { + vi.clearAllMocks() + ;(fs.readFile as any).mockResolvedValue(JSON.stringify(mockCredentials)) + ;(fs.writeFile as any).mockResolvedValue(undefined) + + // Set up default mock + ;(axios.post as any).mockResolvedValue({ + data: {}, + }) + + handler = new GeminiCliHandler({ + apiModelId: geminiCliDefaultModelId, + }) + + // Set up default mock for OAuth2Client request + handler["authClient"].request = vi.fn().mockResolvedValue({ + data: {}, + }) + + // Mock the discoverProjectId to avoid real API calls in tests + handler["projectId"] = "test-project-123" + vi.spyOn(handler as any, "discoverProjectId").mockResolvedValue("test-project-123") + }) + + describe("constructor", () => { + it("should initialize with provided config", () => { + expect(handler["options"].apiModelId).toBe(geminiCliDefaultModelId) + }) + }) + + describe("getModel", () => { + it("should return correct model info", () => { + const modelInfo = handler.getModel() + expect(modelInfo.id).toBe(geminiCliDefaultModelId) + expect(modelInfo.info).toBeDefined() + expect(modelInfo.info.inputPrice).toBe(0) + expect(modelInfo.info.outputPrice).toBe(0) + }) + + it("should return default model if invalid model specified", () => { + const invalidHandler = new GeminiCliHandler({ + apiModelId: "invalid-model", + }) + const modelInfo = invalidHandler.getModel() + expect(modelInfo.id).toBe(geminiCliDefaultModelId) + }) + + it("should handle :thinking suffix", () => { + const thinkingHandler = new GeminiCliHandler({ + apiModelId: "gemini-2.5-pro:thinking", + }) + const modelInfo = thinkingHandler.getModel() + // The :thinking suffix should be removed from the ID + expect(modelInfo.id).toBe("gemini-2.5-pro") + // But the model should still have reasoning support + expect(modelInfo.info.supportsReasoningBudget).toBe(true) + expect(modelInfo.info.requiredReasoningBudget).toBe(true) + }) + }) + + describe("OAuth authentication", () => { + it("should load OAuth credentials from default path", async () => { + await handler["loadOAuthCredentials"]() + expect(fs.readFile).toHaveBeenCalledWith(expect.stringMatching(/\.gemini[/\\]oauth_creds\.json$/), "utf-8") + }) + + it("should load OAuth credentials from custom path", async () => { + const customHandler = new GeminiCliHandler({ + apiModelId: geminiCliDefaultModelId, + geminiCliOAuthPath: "/custom/path/oauth.json", + }) + await customHandler["loadOAuthCredentials"]() + expect(fs.readFile).toHaveBeenCalledWith("/custom/path/oauth.json", "utf-8") + }) + + it("should refresh expired tokens", async () => { + const expiredCredentials = { + ...mockCredentials, + expiry_date: Date.now() - 1000, // Expired + } + ;(fs.readFile as any).mockResolvedValueOnce(JSON.stringify(expiredCredentials)) + + await handler["ensureAuthenticated"]() + + expect(handler["authClient"].refreshAccessToken).toHaveBeenCalled() + expect(fs.writeFile).toHaveBeenCalledWith( + expect.stringMatching(/\.gemini[/\\]oauth_creds\.json$/), + expect.stringContaining("refreshed-token"), + ) + }) + + it("should throw error if credentials file not found", async () => { + ;(fs.readFile as any).mockRejectedValueOnce(new Error("ENOENT")) + + await expect(handler["loadOAuthCredentials"]()).rejects.toThrow("errors.geminiCli.oauthLoadFailed") + }) + }) + + describe("project ID discovery", () => { + it("should use provided project ID", async () => { + const customHandler = new GeminiCliHandler({ + apiModelId: geminiCliDefaultModelId, + geminiCliProjectId: "custom-project", + }) + + const projectId = await customHandler["discoverProjectId"]() + expect(projectId).toBe("custom-project") + expect(customHandler["projectId"]).toBe("custom-project") + }) + + it("should discover project ID through API", async () => { + // Create a new handler without the mocked discoverProjectId + const testHandler = new GeminiCliHandler({ + apiModelId: geminiCliDefaultModelId, + }) + testHandler["authClient"].request = vi.fn().mockResolvedValue({ + data: {}, + }) + + // Mock the callEndpoint method + testHandler["callEndpoint"] = vi.fn().mockResolvedValueOnce({ + cloudaicompanionProject: "discovered-project-123", + }) + + const projectId = await testHandler["discoverProjectId"]() + expect(projectId).toBe("discovered-project-123") + expect(testHandler["projectId"]).toBe("discovered-project-123") + }) + + it("should onboard user if no existing project", async () => { + // Create a new handler without the mocked discoverProjectId + const testHandler = new GeminiCliHandler({ + apiModelId: geminiCliDefaultModelId, + }) + testHandler["authClient"].request = vi.fn().mockResolvedValue({ + data: {}, + }) + + // Mock the callEndpoint method + testHandler["callEndpoint"] = vi + .fn() + .mockResolvedValueOnce({ + allowedTiers: [{ id: "free-tier", isDefault: true }], + }) + .mockResolvedValueOnce({ + done: false, + }) + .mockResolvedValueOnce({ + done: true, + response: { + cloudaicompanionProject: { + id: "onboarded-project-456", + }, + }, + }) + + const projectId = await testHandler["discoverProjectId"]() + expect(projectId).toBe("onboarded-project-456") + expect(testHandler["projectId"]).toBe("onboarded-project-456") + expect(testHandler["callEndpoint"]).toHaveBeenCalledTimes(3) + }) + }) + + describe("completePrompt", () => { + it("should complete prompt successfully", async () => { + handler["authClient"].request = vi.fn().mockResolvedValue({ + data: { + candidates: [ + { + content: { + parts: [{ text: "Test response" }], + }, + }, + ], + }, + }) + + const result = await handler.completePrompt("Test prompt") + expect(result).toBe("Test response") + }) + + it("should handle empty response", async () => { + handler["authClient"].request = vi.fn().mockResolvedValue({ + data: { + candidates: [], + }, + }) + + const result = await handler.completePrompt("Test prompt") + expect(result).toBe("") + }) + + it("should filter out thinking parts", async () => { + handler["authClient"].request = vi.fn().mockResolvedValue({ + data: { + candidates: [ + { + content: { + parts: [{ text: "Thinking...", thought: true }, { text: "Actual response" }], + }, + }, + ], + }, + }) + + const result = await handler.completePrompt("Test prompt") + expect(result).toBe("Actual response") + }) + + it("should handle API errors", async () => { + handler["authClient"].request = vi.fn().mockRejectedValue(new Error("API Error")) + + await expect(handler.completePrompt("Test prompt")).rejects.toThrow("errors.geminiCli.completionError") + }) + }) + + describe("createMessage streaming", () => { + it("should handle streaming response with reasoning", async () => { + // Create a mock Node.js readable stream + const { Readable } = require("stream") + const mockStream = new Readable({ + read() { + this.push('data: {"candidates":[{"content":{"parts":[{"text":"Hello"}]}}]}\n\n') + this.push( + 'data: {"candidates":[{"content":{"parts":[{"thought":true,"text":"thinking..."}]}}]}\n\n', + ) + this.push( + 'data: {"candidates":[{"content":{"parts":[{"text":" world"}]}}],"usageMetadata":{"promptTokenCount":10,"candidatesTokenCount":5}}\n\n', + ) + this.push("data: [DONE]\n\n") + this.push(null) // End the stream + }, + }) + + handler["authClient"].request = vi.fn().mockResolvedValue({ + data: mockStream, + }) + + const stream = handler.createMessage("System", []) + const chunks: any[] = [] + + for await (const chunk of stream) { + chunks.push(chunk) + } + + // Check we got the expected chunks + expect(chunks).toHaveLength(4) // 2 text chunks, 1 reasoning chunk, 1 usage chunk + + // Filter out only text chunks (not reasoning chunks) + const textChunks = chunks.filter((c) => c.type === "text").map((c) => c.text) + expect(textChunks).toEqual(["Hello", " world"]) + + // Check reasoning chunk + const reasoningChunks = chunks.filter((c) => c.type === "reasoning") + expect(reasoningChunks).toHaveLength(1) + expect(reasoningChunks[0].text).toBe("thinking...") + + // Check usage chunk + const usageChunks = chunks.filter((c) => c.type === "usage") + expect(usageChunks).toHaveLength(1) + expect(usageChunks[0]).toMatchObject({ + type: "usage", + inputTokens: 10, + outputTokens: 5, + totalCost: 0, + }) + }) + + it("should handle rate limit errors", async () => { + handler["authClient"].request = vi.fn().mockRejectedValue({ + response: { + status: 429, + data: { error: { message: "Rate limit exceeded" } }, + }, + }) + + const stream = handler.createMessage("System", []) + + await expect(async () => { + for await (const _chunk of stream) { + // Should throw before yielding + } + }).rejects.toThrow("errors.geminiCli.rateLimitExceeded") + }) + }) + + describe("countTokens", () => { + it("should fall back to base provider implementation", async () => { + const content = [{ type: "text" as const, text: "Hello world" }] + const tokenCount = await handler.countTokens(content) + + // Should return a number (tiktoken fallback) + expect(typeof tokenCount).toBe("number") + expect(tokenCount).toBeGreaterThan(0) + }) + }) +}) diff --git a/src/api/providers/gemini-cli.ts b/src/api/providers/gemini-cli.ts new file mode 100644 index 0000000000..6e265511e4 --- /dev/null +++ b/src/api/providers/gemini-cli.ts @@ -0,0 +1,419 @@ +import type { Anthropic } from "@anthropic-ai/sdk" +import { OAuth2Client } from "google-auth-library" +import * as fs from "fs/promises" +import * as path from "path" +import * as os from "os" +import axios from "axios" + +import { type ModelInfo, type GeminiCliModelId, geminiCliDefaultModelId, geminiCliModels } from "@roo-code/types" + +import type { ApiHandlerOptions } from "../../shared/api" +import { t } from "../../i18n" + +import { convertAnthropicContentToGemini, convertAnthropicMessageToGemini } from "../transform/gemini-format" +import type { ApiStream } from "../transform/stream" +import { getModelParams } from "../transform/model-params" + +import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index" +import { BaseProvider } from "./base-provider" + +// OAuth2 Configuration (from Cline implementation) +const OAUTH_CLIENT_ID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com" +const OAUTH_CLIENT_SECRET = "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" +const OAUTH_REDIRECT_URI = "http://localhost:45289" + +// Code Assist API Configuration +const CODE_ASSIST_ENDPOINT = "https://cloudcode-pa.googleapis.com" +const CODE_ASSIST_API_VERSION = "v1internal" + +interface OAuthCredentials { + access_token: string + refresh_token: string + token_type: string + expiry_date: number +} + +export class GeminiCliHandler extends BaseProvider implements SingleCompletionHandler { + protected options: ApiHandlerOptions + private authClient: OAuth2Client + private projectId: string | null = null + private credentials: OAuthCredentials | null = null + + constructor(options: ApiHandlerOptions) { + super() + this.options = options + + // Initialize OAuth2 client + this.authClient = new OAuth2Client(OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_REDIRECT_URI) + } + + private async loadOAuthCredentials(): Promise { + try { + const credPath = this.options.geminiCliOAuthPath || path.join(os.homedir(), ".gemini", "oauth_creds.json") + const credData = await fs.readFile(credPath, "utf-8") + this.credentials = JSON.parse(credData) + + // Set credentials on the OAuth2 client + if (this.credentials) { + this.authClient.setCredentials({ + access_token: this.credentials.access_token, + refresh_token: this.credentials.refresh_token, + expiry_date: this.credentials.expiry_date, + }) + } + } catch (error) { + throw new Error(t("common:errors.geminiCli.oauthLoadFailed", { error })) + } + } + + private async ensureAuthenticated(): Promise { + if (!this.credentials) { + await this.loadOAuthCredentials() + } + + // Check if token needs refresh + if (this.credentials && this.credentials.expiry_date < Date.now()) { + try { + const { credentials } = await this.authClient.refreshAccessToken() + if (credentials.access_token) { + this.credentials = { + access_token: credentials.access_token!, + refresh_token: credentials.refresh_token || this.credentials.refresh_token, + token_type: credentials.token_type || "Bearer", + expiry_date: credentials.expiry_date || Date.now() + 3600 * 1000, + } + // Optionally save refreshed credentials back to file + const credPath = + this.options.geminiCliOAuthPath || path.join(os.homedir(), ".gemini", "oauth_creds.json") + await fs.writeFile(credPath, JSON.stringify(this.credentials, null, 2)) + } + } catch (error) { + throw new Error(t("common:errors.geminiCli.tokenRefreshFailed", { error })) + } + } + } + + /** + * Call a Code Assist API endpoint + */ + private async callEndpoint(method: string, body: any, retryAuth: boolean = true): Promise { + try { + const res = await this.authClient.request({ + url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:${method}`, + method: "POST", + headers: { + "Content-Type": "application/json", + }, + responseType: "json", + data: JSON.stringify(body), + }) + return res.data + } catch (error: any) { + console.error(`[GeminiCLI] Error calling ${method}:`, error) + console.error(`[GeminiCLI] Error response:`, error.response?.data) + console.error(`[GeminiCLI] Error status:`, error.response?.status) + console.error(`[GeminiCLI] Error message:`, error.message) + + // If we get a 401 and haven't retried yet, try refreshing auth + if (error.response?.status === 401 && retryAuth) { + await this.ensureAuthenticated() // This will refresh the token + return this.callEndpoint(method, body, false) // Retry without further auth retries + } + + throw error + } + } + + /** + * Discover or retrieve the project ID + */ + private async discoverProjectId(): Promise { + // If we already have a project ID, use it + if (this.options.geminiCliProjectId) { + this.projectId = this.options.geminiCliProjectId + return this.projectId + } + + // If we've already discovered it, return it + if (this.projectId) { + return this.projectId + } + + // Start with a default project ID (can be anything for personal OAuth) + const initialProjectId = "default" + + // Prepare client metadata + const clientMetadata = { + ideType: "IDE_UNSPECIFIED", + platform: "PLATFORM_UNSPECIFIED", + pluginType: "GEMINI", + duetProject: initialProjectId, + } + + try { + // Call loadCodeAssist to discover the actual project ID + const loadRequest = { + cloudaicompanionProject: initialProjectId, + metadata: clientMetadata, + } + + const loadResponse = await this.callEndpoint("loadCodeAssist", loadRequest) + + // Check if we already have a project ID from the response + if (loadResponse.cloudaicompanionProject) { + this.projectId = loadResponse.cloudaicompanionProject + return this.projectId as string + } + + // If no existing project, we need to onboard + const defaultTier = loadResponse.allowedTiers?.find((tier: any) => tier.isDefault) + const tierId = defaultTier?.id || "free-tier" + + const onboardRequest = { + tierId: tierId, + cloudaicompanionProject: initialProjectId, + metadata: clientMetadata, + } + + let lroResponse = await this.callEndpoint("onboardUser", onboardRequest) + + // Poll until operation is complete with timeout protection + const MAX_RETRIES = 30 // Maximum number of retries (60 seconds total) + let retryCount = 0 + + while (!lroResponse.done && retryCount < MAX_RETRIES) { + await new Promise((resolve) => setTimeout(resolve, 2000)) + lroResponse = await this.callEndpoint("onboardUser", onboardRequest) + retryCount++ + } + + if (!lroResponse.done) { + throw new Error(t("common:errors.geminiCli.onboardingTimeout")) + } + + const discoveredProjectId = lroResponse.response?.cloudaicompanionProject?.id || initialProjectId + this.projectId = discoveredProjectId + return this.projectId as string + } catch (error: any) { + console.error("Failed to discover project ID:", error.response?.data || error.message) + throw new Error(t("common:errors.geminiCli.projectDiscoveryFailed")) + } + } + + /** + * Parse Server-Sent Events from a stream + */ + private async *parseSSEStream(stream: NodeJS.ReadableStream): AsyncGenerator { + let buffer = "" + + for await (const chunk of stream) { + buffer += chunk.toString() + const lines = buffer.split("\n") + buffer = lines.pop() || "" + + for (const line of lines) { + if (line.startsWith("data: ")) { + const data = line.slice(6).trim() + if (data === "[DONE]") continue + + try { + const parsed = JSON.parse(data) + yield parsed + } catch (e) { + console.error("Error parsing SSE data:", e) + } + } + } + } + } + + async *createMessage( + systemInstruction: string, + messages: Anthropic.Messages.MessageParam[], + metadata?: ApiHandlerCreateMessageMetadata, + ): ApiStream { + await this.ensureAuthenticated() + const projectId = await this.discoverProjectId() + + const { id: model, info, reasoning: thinkingConfig, maxTokens } = this.getModel() + + // Convert messages to Gemini format + const contents = messages.map(convertAnthropicMessageToGemini) + + // Prepare request body for Code Assist API - matching Cline's structure + const requestBody: any = { + model: model, + project: projectId, + request: { + contents: [ + { + role: "user", + parts: [{ text: systemInstruction }], + }, + ...contents, + ], + generationConfig: { + temperature: this.options.modelTemperature ?? 0.7, + maxOutputTokens: this.options.modelMaxTokens ?? maxTokens ?? 8192, + }, + }, + } + + // Add thinking config if applicable + if (thinkingConfig) { + requestBody.request.generationConfig.thinkingConfig = thinkingConfig + } + + try { + // Call Code Assist streaming endpoint using OAuth2Client + const response = await this.authClient.request({ + url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:streamGenerateContent`, + method: "POST", + params: { alt: "sse" }, + headers: { + "Content-Type": "application/json", + }, + responseType: "stream", + data: JSON.stringify(requestBody), + }) + + // Process the SSE stream + let lastUsageMetadata: any = undefined + + for await (const jsonData of this.parseSSEStream(response.data as NodeJS.ReadableStream)) { + // Extract content from the response + const responseData = jsonData.response || jsonData + const candidate = responseData.candidates?.[0] + + if (candidate?.content?.parts) { + for (const part of candidate.content.parts) { + if (part.text) { + // Check if this is a thinking/reasoning part + if (part.thought === true) { + yield { + type: "reasoning", + text: part.text, + } + } else { + yield { + type: "text", + text: part.text, + } + } + } + } + } + + // Store usage metadata for final reporting + if (responseData.usageMetadata) { + lastUsageMetadata = responseData.usageMetadata + } + + // Check if this is the final chunk + if (candidate?.finishReason) { + break + } + } + + // Yield final usage information + if (lastUsageMetadata) { + const inputTokens = lastUsageMetadata.promptTokenCount ?? 0 + const outputTokens = lastUsageMetadata.candidatesTokenCount ?? 0 + const cacheReadTokens = lastUsageMetadata.cachedContentTokenCount + const reasoningTokens = lastUsageMetadata.thoughtsTokenCount + + yield { + type: "usage", + inputTokens, + outputTokens, + cacheReadTokens, + reasoningTokens, + totalCost: 0, // Free tier - all costs are 0 + } + } + } catch (error: any) { + console.error("[GeminiCLI] API Error:", error.response?.status, error.response?.statusText) + console.error("[GeminiCLI] Error Response:", error.response?.data) + + if (error.response?.status === 429) { + throw new Error(t("common:errors.geminiCli.rateLimitExceeded")) + } + if (error.response?.status === 400) { + throw new Error( + t("common:errors.geminiCli.badRequest", { + details: JSON.stringify(error.response?.data) || error.message, + }), + ) + } + throw new Error(t("common:errors.geminiCli.apiError", { error: error.message })) + } + } + + override getModel() { + const modelId = this.options.apiModelId + // Handle :thinking suffix before checking if model exists + const baseModelId = modelId?.endsWith(":thinking") ? modelId.replace(":thinking", "") : modelId + let id = + baseModelId && baseModelId in geminiCliModels ? (baseModelId as GeminiCliModelId) : geminiCliDefaultModelId + const info: ModelInfo = geminiCliModels[id] + const params = getModelParams({ format: "gemini", modelId: id, model: info, settings: this.options }) + + // Return the cleaned model ID + return { id, info, ...params } + } + + async completePrompt(prompt: string): Promise { + await this.ensureAuthenticated() + const projectId = await this.discoverProjectId() + + try { + const { id: model } = this.getModel() + + const requestBody = { + model: model, + project: projectId, + request: { + contents: [{ role: "user", parts: [{ text: prompt }] }], + generationConfig: { + temperature: this.options.modelTemperature ?? 0.7, + }, + }, + } + + const response = await this.authClient.request({ + url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:generateContent`, + method: "POST", + headers: { + "Content-Type": "application/json", + }, + data: JSON.stringify(requestBody), + }) + + // Extract text from response + const responseData = response.data as any + if (responseData.candidates && responseData.candidates.length > 0) { + const candidate = responseData.candidates[0] + if (candidate.content && candidate.content.parts) { + const textParts = candidate.content.parts + .filter((part: any) => part.text && !part.thought) + .map((part: any) => part.text) + .join("") + return textParts + } + } + + return "" + } catch (error) { + if (error instanceof Error) { + throw new Error(t("common:errors.geminiCli.completionError", { error: error.message })) + } + throw error + } + } + + override async countTokens(content: Array): Promise { + // For OAuth/free tier, we can't use the token counting API + // Fall back to the base provider's tiktoken implementation + return super.countTokens(content) + } +} diff --git a/src/api/providers/index.ts b/src/api/providers/index.ts index 93df5c58ff..5bad9482a0 100644 --- a/src/api/providers/index.ts +++ b/src/api/providers/index.ts @@ -6,6 +6,7 @@ export { ClaudeCodeHandler } from "./claude-code" export { DeepSeekHandler } from "./deepseek" export { FakeAIHandler } from "./fake-ai" export { GeminiHandler } from "./gemini" +export { GeminiCliHandler } from "./gemini-cli" export { GlamaHandler } from "./glama" export { GroqHandler } from "./groq" export { HumanRelayHandler } from "./human-relay" diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json index 8e9f07c100..f23ee831aa 100644 --- a/src/i18n/locales/ca/common.json +++ b/src/i18n/locales/ca/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "La teva organitzaciรณ requereix autenticaciรณ de Roo Code Cloud. Si us plau, inicia sessiรณ per continuar.", "organization_mismatch": "Has d'estar autenticat amb el compte de Roo Code Cloud de la teva organitzaciรณ.", "verification_failed": "No s'ha pogut verificar l'autenticaciรณ de l'organitzaciรณ." + }, + "geminiCli": { + "oauthLoadFailed": "No s'han pogut carregar les credencials OAuth. Si us plau, autentica't primer: {{error}}", + "tokenRefreshFailed": "No s'ha pogut actualitzar el token OAuth: {{error}}", + "onboardingTimeout": "L'operaciรณ d'onboarding ha esgotat el temps desprรฉs de 60 segons. Si us plau, torna-ho a provar mรฉs tard.", + "projectDiscoveryFailed": "No s'ha pogut descobrir l'ID del projecte. Assegura't d'estar autenticat amb 'gemini auth'.", + "rateLimitExceeded": "S'ha superat el lรญmit de velocitat. S'han assolit els lรญmits del nivell gratuรฏt.", + "badRequest": "Solยทlicitud incorrecta: {{details}}", + "apiError": "Error de l'API Gemini CLI: {{error}}", + "completionError": "Error de compleciรณ de Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json index fc4ce25de1..a09813d284 100644 --- a/src/i18n/locales/de/common.json +++ b/src/i18n/locales/de/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "Deine Organisation erfordert eine Roo Code Cloud-Authentifizierung. Bitte melde dich an, um fortzufahren.", "organization_mismatch": "Du musst mit dem Roo Code Cloud-Konto deiner Organisation authentifiziert sein.", "verification_failed": "Die Organisationsauthentifizierung konnte nicht verifiziert werden." + }, + "geminiCli": { + "oauthLoadFailed": "Fehler beim Laden der OAuth-Anmeldedaten. Bitte authentifiziere dich zuerst: {{error}}", + "tokenRefreshFailed": "Fehler beim Aktualisieren des OAuth-Tokens: {{error}}", + "onboardingTimeout": "Onboarding-Vorgang nach 60 Sekunden abgebrochen. Bitte versuche es spรคter erneut.", + "projectDiscoveryFailed": "Projekt-ID konnte nicht ermittelt werden. Stelle sicher, dass du mit 'gemini auth' authentifiziert bist.", + "rateLimitExceeded": "Anfragenlimit รผberschritten. Die Limits des kostenlosen Tarifs wurden erreicht.", + "badRequest": "Ungรผltige Anfrage: {{details}}", + "apiError": "Gemini CLI API-Fehler: {{error}}", + "completionError": "Gemini CLI Vervollstรคndigungsfehler: {{error}}" } } } diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index 3f19a1dd50..b8b370d132 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -128,6 +128,16 @@ "cloud_auth_required": "Your organization requires Roo Code Cloud authentication. Please sign in to continue.", "organization_mismatch": "You must be authenticated with your organization's Roo Code Cloud account.", "verification_failed": "Unable to verify organization authentication." + }, + "geminiCli": { + "oauthLoadFailed": "Failed to load OAuth credentials. Please authenticate first: {{error}}", + "tokenRefreshFailed": "Failed to refresh OAuth token: {{error}}", + "onboardingTimeout": "Onboarding operation timed out after 60 seconds. Please try again later.", + "projectDiscoveryFailed": "Could not discover project ID. Make sure you're authenticated with 'gemini auth'.", + "rateLimitExceeded": "Rate limit exceeded. Free tier limits have been reached.", + "badRequest": "Bad request: {{details}}", + "apiError": "Gemini CLI API error: {{error}}", + "completionError": "Gemini CLI completion error: {{error}}" } } } diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json index 4b3177619e..090faffad1 100644 --- a/src/i18n/locales/es/common.json +++ b/src/i18n/locales/es/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "Tu organizaciรณn requiere autenticaciรณn de Roo Code Cloud. Por favor, inicia sesiรณn para continuar.", "organization_mismatch": "Debes estar autenticado con la cuenta de Roo Code Cloud de tu organizaciรณn.", "verification_failed": "No se pudo verificar la autenticaciรณn de la organizaciรณn." + }, + "geminiCli": { + "oauthLoadFailed": "Error al cargar credenciales OAuth. Por favor autentรญcate primero: {{error}}", + "tokenRefreshFailed": "Error al actualizar token OAuth: {{error}}", + "onboardingTimeout": "La operaciรณn de incorporaciรณn expirรณ despuรฉs de 60 segundos. Intรฉntalo de nuevo mรกs tarde.", + "projectDiscoveryFailed": "No se pudo descubrir el ID del proyecto. Asegรบrate de estar autenticado con 'gemini auth'.", + "rateLimitExceeded": "Lรญmite de velocidad excedido. Se han alcanzado los lรญmites del nivel gratuito.", + "badRequest": "Solicitud incorrecta: {{details}}", + "apiError": "Error de API de Gemini CLI: {{error}}", + "completionError": "Error de completado de Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json index 93cd67ca15..a9215a81ec 100644 --- a/src/i18n/locales/fr/common.json +++ b/src/i18n/locales/fr/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "Votre organisation nรฉcessite une authentification Roo Code Cloud. Veuillez vous connecter pour continuer.", "organization_mismatch": "Vous devez รชtre authentifiรฉ avec le compte Roo Code Cloud de votre organisation.", "verification_failed": "Impossible de vรฉrifier l'authentification de l'organisation." + }, + "geminiCli": { + "oauthLoadFailed": "ร‰chec du chargement des identifiants OAuth. Veuillez vous authentifier d'abord : {{error}}", + "tokenRefreshFailed": "ร‰chec du renouvellement du token OAuth : {{error}}", + "onboardingTimeout": "L'opรฉration d'intรฉgration a expirรฉ aprรจs 60 secondes. Veuillez rรฉessayer plus tard.", + "projectDiscoveryFailed": "Impossible de dรฉcouvrir l'ID du projet. Assurez-vous d'รชtre authentifiรฉ avec 'gemini auth'.", + "rateLimitExceeded": "Limite de dรฉbit dรฉpassรฉe. Les limites du niveau gratuit ont รฉtรฉ atteintes.", + "badRequest": "Requรชte incorrecte : {{details}}", + "apiError": "Erreur API Gemini CLI : {{error}}", + "completionError": "Erreur de complรฉtion Gemini CLI : {{error}}" } } } diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json index 68788beacc..65e6561835 100644 --- a/src/i18n/locales/hi/common.json +++ b/src/i18n/locales/hi/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "เค†เคชเค•เฅ‡ เคธเค‚เค—เค เคจ เค•เฅ‹ Roo Code Cloud เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เคนเฅˆเฅค เค•เฅƒเคชเคฏเคพ เคœเคพเคฐเฅ€ เคฐเค–เคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เคธเคพเค‡เคจ เค‡เคจ เค•เคฐเฅ‡เค‚เฅค", "organization_mismatch": "เค†เคชเค•เฅ‹ เค…เคชเคจเฅ‡ เคธเค‚เค—เค เคจ เค•เฅ‡ Roo Code Cloud เค–เคพเคคเฅ‡ เคธเฅ‡ เคชเฅเคฐเคฎเคพเคฃเคฟเคค เคนเฅ‹เคจเคพ เคนเฅ‹เค—เคพเฅค", "verification_failed": "เคธเค‚เค—เค เคจ เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เคธเคคเฅเคฏเคพเคชเคฟเคค เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เค…เคธเคฎเคฐเฅเคฅเฅค" + }, + "geminiCli": { + "oauthLoadFailed": "OAuth เค•เฅเคฐเฅ‡เคกเฅ‡เค‚เคถเคฟเคฏเคฒ เคฒเฅ‹เคก เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒเฅค เค•เฅƒเคชเคฏเคพ เคชเคนเคฒเฅ‡ เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เคฐเฅ‡เค‚: {{error}}", + "tokenRefreshFailed": "OAuth เคŸเฅ‹เค•เคจ เคฐเฅ€เคซเฅเคฐเฅ‡เคถ เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒ: {{error}}", + "onboardingTimeout": "เค‘เคจเคฌเฅ‹เคฐเฅเคกเคฟเค‚เค— เค‘เคชเคฐเฅ‡เคถเคจ 60 เคธเฅ‡เค•เค‚เคก เคฌเคพเคฆ เคŸเคพเค‡เคฎเค†เค‰เคŸ เคนเฅ‹ เค—เคฏเคพเฅค เค•เฅƒเคชเคฏเคพ เคฌเคพเคฆ เคฎเฅ‡เค‚ เคชเฅเคจเคƒ เคชเฅเคฐเคฏเคพเคธ เค•เคฐเฅ‡เค‚เฅค", + "projectDiscoveryFailed": "เคชเฅเคฐเฅ‹เคœเฅ‡เค•เฅเคŸ ID เค–เฅ‹เคœเคจเฅ‡ เคฎเฅ‡เค‚ เค…เคธเคฎเคฐเฅเคฅเฅค เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เค•เคฐเฅ‡เค‚ เค•เคฟ เค†เคช 'gemini auth' เค•เฅ‡ เคธเคพเคฅ เคชเฅเคฐเคฎเคพเคฃเคฟเคค เคนเฅˆเค‚เฅค", + "rateLimitExceeded": "เคฆเคฐ เคธเฅ€เคฎเคพ เคชเคพเคฐ เคนเฅ‹ เค—เคˆเฅค เคฎเฅเคซเฅเคค เคŸเคฟเคฏเคฐ เค•เฅ€ เคธเฅ€เคฎเคพ เคชเคนเฅเค‚เคš เค—เคˆ เคนเฅˆเฅค", + "badRequest": "เค—เคฒเคค เค…เคจเฅเคฐเฅ‹เคง: {{details}}", + "apiError": "Gemini CLI API เคคเฅเคฐเฅเคŸเคฟ: {{error}}", + "completionError": "Gemini CLI เคชเฅ‚เคฐเฅเคฃเคคเคพ เคคเฅเคฐเฅเคŸเคฟ: {{error}}" } } } diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json index d6bb2ffa98..e7901d28bf 100644 --- a/src/i18n/locales/id/common.json +++ b/src/i18n/locales/id/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "Organisasi kamu memerlukan autentikasi Roo Code Cloud. Silakan masuk untuk melanjutkan.", "organization_mismatch": "Kamu harus diautentikasi dengan akun Roo Code Cloud organisasi kamu.", "verification_failed": "Tidak dapat memverifikasi autentikasi organisasi." + }, + "geminiCli": { + "oauthLoadFailed": "Gagal memuat kredensial OAuth. Silakan autentikasi terlebih dahulu: {{error}}", + "tokenRefreshFailed": "Gagal memperbarui token OAuth: {{error}}", + "onboardingTimeout": "Operasi onboarding timeout setelah 60 detik. Silakan coba lagi nanti.", + "projectDiscoveryFailed": "Tidak dapat menemukan ID proyek. Pastikan Anda sudah terautentikasi dengan 'gemini auth'.", + "rateLimitExceeded": "Batas kecepatan terlampaui. Batas tier gratis telah tercapai.", + "badRequest": "Permintaan tidak valid: {{details}}", + "apiError": "Error API Gemini CLI: {{error}}", + "completionError": "Error penyelesaian Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json index 0ef6ee5b54..6329185e25 100644 --- a/src/i18n/locales/it/common.json +++ b/src/i18n/locales/it/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "La tua organizzazione richiede l'autenticazione Roo Code Cloud. Accedi per continuare.", "organization_mismatch": "Devi essere autenticato con l'account Roo Code Cloud della tua organizzazione.", "verification_failed": "Impossibile verificare l'autenticazione dell'organizzazione." + }, + "geminiCli": { + "oauthLoadFailed": "Impossibile caricare le credenziali OAuth. Autenticati prima: {{error}}", + "tokenRefreshFailed": "Impossibile aggiornare il token OAuth: {{error}}", + "onboardingTimeout": "L'operazione di onboarding รจ scaduta dopo 60 secondi. Riprova piรน tardi.", + "projectDiscoveryFailed": "Impossibile scoprire l'ID del progetto. Assicurati di essere autenticato con 'gemini auth'.", + "rateLimitExceeded": "Limite di velocitร  superato. I limiti del livello gratuito sono stati raggiunti.", + "badRequest": "Richiesta non valida: {{details}}", + "apiError": "Errore API Gemini CLI: {{error}}", + "completionError": "Errore di completamento Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index b132470eac..72b5f6f878 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "ใ‚ใชใŸใฎ็ต„็น”ใงใฏ Roo Code Cloud ่ช่จผใŒๅฟ…่ฆใงใ™ใ€‚็ถš่กŒใ™ใ‚‹ใซใฏใ‚ตใ‚คใƒณใ‚คใƒณใ—ใฆใใ ใ•ใ„ใ€‚", "organization_mismatch": "็ต„็น”ใฎ Roo Code Cloud ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใง่ช่จผใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚", "verification_failed": "็ต„็น”่ช่จผใฎ็ขบ่ชใŒใงใใพใ›ใ‚“ใงใ—ใŸใ€‚" + }, + "geminiCli": { + "oauthLoadFailed": "OAuth่ช่จผๆƒ…ๅ ฑใฎ่ชญใฟ่พผใฟใซๅคฑๆ•—ใ—ใพใ—ใŸใ€‚ใพใš่ช่จผใ—ใฆใใ ใ•ใ„: {{error}}", + "tokenRefreshFailed": "OAuthใƒˆใƒผใ‚ฏใƒณใฎๆ›ดๆ–ฐใซๅคฑๆ•—ใ—ใพใ—ใŸ: {{error}}", + "onboardingTimeout": "ใ‚ชใƒณใƒœใƒผใƒ‡ใ‚ฃใƒณใ‚ฐๆ“ไฝœใŒ60็ง’ใงใ‚ฟใ‚คใƒ ใ‚ขใ‚ฆใƒˆใ—ใพใ—ใŸใ€‚ๅพŒใงใ‚‚ใ†ไธ€ๅบฆใŠ่ฉฆใ—ใใ ใ•ใ„ใ€‚", + "projectDiscoveryFailed": "ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆIDใ‚’็™บ่ฆ‹ใงใใพใ›ใ‚“ใงใ—ใŸใ€‚'gemini auth'ใง่ช่จผใ•ใ‚Œใฆใ„ใ‚‹ใ“ใจใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚", + "rateLimitExceeded": "ใƒฌใƒผใƒˆๅˆถ้™ใ‚’่ถ…้Žใ—ใพใ—ใŸใ€‚็„กๆ–™ใƒ—ใƒฉใƒณใฎๅˆถ้™ใซ้”ใ—ใฆใ„ใพใ™ใ€‚", + "badRequest": "ไธๆญฃใชใƒชใ‚ฏใ‚จใ‚นใƒˆ: {{details}}", + "apiError": "Gemini CLI APIใ‚จใƒฉใƒผ: {{error}}", + "completionError": "Gemini CLI่ฃœๅฎŒใ‚จใƒฉใƒผ: {{error}}" } } } diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json index 079bb56a48..d70be5cf3d 100644 --- a/src/i18n/locales/ko/common.json +++ b/src/i18n/locales/ko/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "์กฐ์ง์—์„œ Roo Code Cloud ์ธ์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์†ํ•˜๋ ค๋ฉด ๋กœ๊ทธ์ธํ•˜์„ธ์š”.", "organization_mismatch": "์กฐ์ง์˜ Roo Code Cloud ๊ณ„์ •์œผ๋กœ ์ธ์ฆํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.", "verification_failed": "์กฐ์ง ์ธ์ฆ์„ ํ™•์ธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." + }, + "geminiCli": { + "oauthLoadFailed": "OAuth ์ž๊ฒฉ ์ฆ๋ช…์„ ๋กœ๋“œํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ธ์ฆํ•˜์„ธ์š”: {{error}}", + "tokenRefreshFailed": "OAuth ํ† ํฐ ์ƒˆ๋กœ ๊ณ ์นจ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค: {{error}}", + "onboardingTimeout": "์˜จ๋ณด๋”ฉ ์ž‘์—…์ด 60์ดˆ ํ›„ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋‹ค์‹œ ์‹œ๋„ํ•˜์„ธ์š”.", + "projectDiscoveryFailed": "ํ”„๋กœ์ ํŠธ ID๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. 'gemini auth'๋กœ ์ธ์ฆ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.", + "rateLimitExceeded": "์†๋„ ์ œํ•œ์„ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌด๋ฃŒ ๊ณ„์ธต ์ œํ•œ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.", + "badRequest": "์ž˜๋ชป๋œ ์š”์ฒญ: {{details}}", + "apiError": "Gemini CLI API ์˜ค๋ฅ˜: {{error}}", + "completionError": "Gemini CLI ์™„์„ฑ ์˜ค๋ฅ˜: {{error}}" } } } diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json index ef27bef3d8..70f5d42dd8 100644 --- a/src/i18n/locales/nl/common.json +++ b/src/i18n/locales/nl/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "Je organisatie vereist Roo Code Cloud-authenticatie. Log in om door te gaan.", "organization_mismatch": "Je moet geauthenticeerd zijn met het Roo Code Cloud-account van je organisatie.", "verification_failed": "Kan organisatie-authenticatie niet verifiรซren." + }, + "geminiCli": { + "oauthLoadFailed": "Kan OAuth-referenties niet laden. Authenticeer eerst: {{error}}", + "tokenRefreshFailed": "Kan OAuth-token niet vernieuwen: {{error}}", + "onboardingTimeout": "Onboarding-operatie is na 60 seconden verlopen. Probeer het later opnieuw.", + "projectDiscoveryFailed": "Kan project-ID niet ontdekken. Zorg ervoor dat je geauthenticeerd bent met 'gemini auth'.", + "rateLimitExceeded": "Snelheidslimiet overschreden. Gratis tier limieten zijn bereikt.", + "badRequest": "Ongeldig verzoek: {{details}}", + "apiError": "Gemini CLI API-fout: {{error}}", + "completionError": "Gemini CLI voltooiingsfout: {{error}}" } } } diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json index 777bbd82b7..98350a70d8 100644 --- a/src/i18n/locales/pl/common.json +++ b/src/i18n/locales/pl/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "Twoja organizacja wymaga uwierzytelnienia Roo Code Cloud. Zaloguj siฤ™, aby kontynuowaฤ‡.", "organization_mismatch": "Musisz byฤ‡ uwierzytelniony kontem Roo Code Cloud swojej organizacji.", "verification_failed": "Nie moลผna zweryfikowaฤ‡ uwierzytelnienia organizacji." + }, + "geminiCli": { + "oauthLoadFailed": "Nie udaล‚o siฤ™ zaล‚adowaฤ‡ danych uwierzytelniajฤ…cych OAuth. Najpierw siฤ™ uwierzytelnij: {{error}}", + "tokenRefreshFailed": "Nie udaล‚o siฤ™ odล›wieลผyฤ‡ tokenu OAuth: {{error}}", + "onboardingTimeout": "Operacja wdraลผania przekroczyล‚a limit czasu po 60 sekundach. Sprรณbuj ponownie pรณลบniej.", + "projectDiscoveryFailed": "Nie moลผna odkryฤ‡ ID projektu. Upewnij siฤ™, ลผe jesteล› uwierzytelniony za pomocฤ… 'gemini auth'.", + "rateLimitExceeded": "Przekroczono limit szybkoล›ci. Osiฤ…gniฤ™to limity darmowego poziomu.", + "badRequest": "Nieprawidล‚owe ลผฤ…danie: {{details}}", + "apiError": "Bล‚ฤ…d API Gemini CLI: {{error}}", + "completionError": "Bล‚ฤ…d uzupeล‚niania Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json index 18695588c8..b8acb6b3c6 100644 --- a/src/i18n/locales/pt-BR/common.json +++ b/src/i18n/locales/pt-BR/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "Sua organizaรงรฃo requer autenticaรงรฃo do Roo Code Cloud. Faรงa login para continuar.", "organization_mismatch": "Vocรช deve estar autenticado com a conta Roo Code Cloud da sua organizaรงรฃo.", "verification_failed": "Nรฃo foi possรญvel verificar a autenticaรงรฃo da organizaรงรฃo." + }, + "geminiCli": { + "oauthLoadFailed": "Falha ao carregar credenciais OAuth. Por favor, autentique-se primeiro: {{error}}", + "tokenRefreshFailed": "Falha ao atualizar token OAuth: {{error}}", + "onboardingTimeout": "A operaรงรฃo de integraรงรฃo expirou apรณs 60 segundos. Tente novamente mais tarde.", + "projectDiscoveryFailed": "Nรฃo foi possรญvel descobrir o ID do projeto. Certifique-se de estar autenticado com 'gemini auth'.", + "rateLimitExceeded": "Limite de taxa excedido. Os limites do nรญvel gratuito foram atingidos.", + "badRequest": "Solicitaรงรฃo invรกlida: {{details}}", + "apiError": "Erro da API Gemini CLI: {{error}}", + "completionError": "Erro de conclusรฃo do Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json index b0e4f58ceb..1b8f35fcbf 100644 --- a/src/i18n/locales/ru/common.json +++ b/src/i18n/locales/ru/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "ะ’ะฐัˆะฐ ะพั€ะณะฐะฝะธะทะฐั†ะธั ั‚ั€ะตะฑัƒะตั‚ ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธะธ Roo Code Cloud. ะ’ะพะนะดะธั‚ะต ะฒ ัะธัั‚ะตะผัƒ, ั‡ั‚ะพะฑั‹ ะฟั€ะพะดะพะปะถะธั‚ัŒ.", "organization_mismatch": "ะ’ั‹ ะดะพะปะถะฝั‹ ะฑั‹ั‚ัŒ ะฐัƒั‚ะตะฝั‚ะธั„ะธั†ะธั€ะพะฒะฐะฝั‹ ั ัƒั‡ะตั‚ะฝะพะน ะทะฐะฟะธััŒัŽ Roo Code Cloud ะฒะฐัˆะตะน ะพั€ะณะฐะฝะธะทะฐั†ะธะธ.", "verification_failed": "ะะต ัƒะดะฐะตั‚ัั ะฟั€ะพะฒะตั€ะธั‚ัŒ ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ ะพั€ะณะฐะฝะธะทะฐั†ะธะธ." + }, + "geminiCli": { + "oauthLoadFailed": "ะะต ัƒะดะฐะปะพััŒ ะทะฐะณั€ัƒะทะธั‚ัŒ ัƒั‡ะตั‚ะฝั‹ะต ะดะฐะฝะฝั‹ะต OAuth. ะกะฝะฐั‡ะฐะปะฐ ะฒั‹ะฟะพะปะฝะธั‚ะต ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ: {{error}}", + "tokenRefreshFailed": "ะะต ัƒะดะฐะปะพััŒ ะพะฑะฝะพะฒะธั‚ัŒ ั‚ะพะบะตะฝ OAuth: {{error}}", + "onboardingTimeout": "ะžะฟะตั€ะฐั†ะธั ะฐะดะฐะฟั‚ะฐั†ะธะธ ะธัั‚ะตะบะปะฐ ั‡ะตั€ะตะท 60 ัะตะบัƒะฝะด. ะŸะพะฟั€ะพะฑัƒะนั‚ะต ะฟะพะทะถะต.", + "projectDiscoveryFailed": "ะะต ัƒะดะฐะปะพััŒ ะพะฑะฝะฐั€ัƒะถะธั‚ัŒ ID ะฟั€ะพะตะบั‚ะฐ. ะฃะฑะตะดะธั‚ะตััŒ, ั‡ั‚ะพ ะฒั‹ ะฐัƒั‚ะตะฝั‚ะธั„ะธั†ะธั€ะพะฒะฐะฝั‹ ั ะฟะพะผะพั‰ัŒัŽ 'gemini auth'.", + "rateLimitExceeded": "ะŸั€ะตะฒั‹ัˆะตะฝ ะปะธะผะธั‚ ัะบะพั€ะพัั‚ะธ. ะ”ะพัั‚ะธะณะฝัƒั‚ั‹ ะพะณั€ะฐะฝะธั‡ะตะฝะธั ะฑะตัะฟะปะฐั‚ะฝะพะณะพ ัƒั€ะพะฒะฝั.", + "badRequest": "ะะตะฒะตั€ะฝั‹ะน ะทะฐะฟั€ะพั: {{details}}", + "apiError": "ะžัˆะธะฑะบะฐ API Gemini CLI: {{error}}", + "completionError": "ะžัˆะธะฑะบะฐ ะทะฐะฒะตั€ัˆะตะฝะธั Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json index 9663cac808..f07ee9cc80 100644 --- a/src/i18n/locales/tr/common.json +++ b/src/i18n/locales/tr/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "KuruluลŸunuz Roo Code Cloud kimlik doฤŸrulamasฤฑ gerektiriyor. Devam etmek iรงin giriลŸ yapฤฑn.", "organization_mismatch": "KuruluลŸunuzun Roo Code Cloud hesabฤฑyla kimlik doฤŸrulamasฤฑ yapmalฤฑsฤฑnฤฑz.", "verification_failed": "KuruluลŸ kimlik doฤŸrulamasฤฑ doฤŸrulanamฤฑyor." + }, + "geminiCli": { + "oauthLoadFailed": "OAuth kimlik bilgileri yรผklenemedi. Lรผtfen รถnce kimlik doฤŸrulamasฤฑ yapฤฑn: {{error}}", + "tokenRefreshFailed": "OAuth token yenilenemedi: {{error}}", + "onboardingTimeout": "Onboarding iลŸlemi 60 saniye sonra zaman aลŸฤฑmฤฑna uฤŸradฤฑ. Lรผtfen daha sonra tekrar deneyin.", + "projectDiscoveryFailed": "Proje ID'si keลŸfedilemedi. 'gemini auth' ile kimlik doฤŸrulamasฤฑ yaptฤฑฤŸฤฑnฤฑzdan emin olun.", + "rateLimitExceeded": "Hฤฑz sฤฑnฤฑrฤฑ aลŸฤฑldฤฑ. รœcretsiz seviye sฤฑnฤฑrlarฤฑna ulaลŸฤฑldฤฑ.", + "badRequest": "Geรงersiz istek: {{details}}", + "apiError": "Gemini CLI API hatasฤฑ: {{error}}", + "completionError": "Gemini CLI tamamlama hatasฤฑ: {{error}}" } } } diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json index 5a9d0983f8..49db186e93 100644 --- a/src/i18n/locales/vi/common.json +++ b/src/i18n/locales/vi/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "Tแป• chแปฉc cแปงa bแบกn yรชu cแบงu xรกc thแปฑc Roo Code Cloud. Vui lรฒng ฤ‘ฤƒng nhแบญp ฤ‘แปƒ tiแบฟp tแปฅc.", "organization_mismatch": "Bแบกn phแบฃi ฤ‘ฦฐแปฃc xรกc thแปฑc bแบฑng tร i khoแบฃn Roo Code Cloud cแปงa tแป• chแปฉc.", "verification_failed": "Khรดng thแปƒ xรกc minh xรกc thแปฑc tแป• chแปฉc." + }, + "geminiCli": { + "oauthLoadFailed": "Khรดng thแปƒ tแบฃi thรดng tin xรกc thแปฑc OAuth. Vui lรฒng xรกc thแปฑc trฦฐแป›c: {{error}}", + "tokenRefreshFailed": "Khรดng thแปƒ lร m mแป›i token OAuth: {{error}}", + "onboardingTimeout": "Thao tรกc onboarding ฤ‘รฃ hแบฟt thแปi gian chแป sau 60 giรขy. Vui lรฒng thแปญ lแบกi sau.", + "projectDiscoveryFailed": "Khรดng thแปƒ khรกm phรก ID dแปฑ รกn. ฤแบฃm bแบฃo bแบกn ฤ‘รฃ xรกc thแปฑc bแบฑng 'gemini auth'.", + "rateLimitExceeded": "ฤรฃ vฦฐแปฃt quรก giแป›i hแบกn tแป‘c ฤ‘แป™. ฤรฃ ฤ‘แบกt ฤ‘แบฟn giแป›i hแบกn cแปงa gรณi miแป…n phรญ.", + "badRequest": "Yรชu cแบงu khรดng hแปฃp lแป‡: {{details}}", + "apiError": "Lแป—i API Gemini CLI: {{error}}", + "completionError": "Lแป—i hoร n thร nh Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json index b355c2ec35..a5e355e27f 100644 --- a/src/i18n/locales/zh-CN/common.json +++ b/src/i18n/locales/zh-CN/common.json @@ -144,6 +144,16 @@ "cloud_auth_required": "ๆ‚จ็š„็ป„็ป‡้œ€่ฆ Roo Code Cloud ่บซไปฝ้ชŒ่ฏใ€‚่ฏท็™ปๅฝ•ไปฅ็ปง็ปญใ€‚", "organization_mismatch": "ๆ‚จๅฟ…้กปไฝฟ็”จ็ป„็ป‡็š„ Roo Code Cloud ่ดฆๆˆท่ฟ›่กŒ่บซไปฝ้ชŒ่ฏใ€‚", "verification_failed": "ๆ— ๆณ•้ชŒ่ฏ็ป„็ป‡่บซไปฝ้ชŒ่ฏใ€‚" + }, + "geminiCli": { + "oauthLoadFailed": "ๅŠ ่ฝฝ OAuth ๅ‡ญๆฎๅคฑ่ดฅใ€‚่ฏทๅ…ˆ่ฟ›่กŒ่บซไปฝ้ชŒ่ฏ๏ผš{{error}}", + "tokenRefreshFailed": "ๅˆทๆ–ฐ OAuth Token ๅคฑ่ดฅ๏ผš{{error}}", + "onboardingTimeout": "ๅ…ฅ้—จๆ“ไฝœๅœจ 60 ็ง’ๅŽ่ถ…ๆ—ถใ€‚่ฏท็จๅŽ้‡่ฏ•ใ€‚", + "projectDiscoveryFailed": "ๆ— ๆณ•ๅ‘็Žฐ้กน็›ฎ IDใ€‚่ฏท็กฎไฟๅทฒไฝฟ็”จ 'gemini auth' ่ฟ›่กŒ่บซไปฝ้ชŒ่ฏใ€‚", + "rateLimitExceeded": "API ่ฏทๆฑ‚้ข‘็އ้™ๅˆถๅทฒ่ถ…ๅ‡บใ€‚ๅ…่ดนๅฑ‚็บง้™ๅˆถๅทฒ่พพๅˆฐใ€‚", + "badRequest": "่ฏทๆฑ‚้”™่ฏฏ๏ผš{{details}}", + "apiError": "Gemini CLI API ้”™่ฏฏ๏ผš{{error}}", + "completionError": "Gemini CLI ่กฅๅ…จ้”™่ฏฏ๏ผš{{error}}" } } } diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json index 6c1c9747aa..09b26377ec 100644 --- a/src/i18n/locales/zh-TW/common.json +++ b/src/i18n/locales/zh-TW/common.json @@ -139,6 +139,16 @@ "cloud_auth_required": "ๆ‚จ็š„็ต„็น”้œ€่ฆ Roo Code Cloud ่บซไปฝ้ฉ—่ญ‰ใ€‚่ซ‹็™ปๅ…ฅไปฅ็นผ็บŒใ€‚", "organization_mismatch": "ๆ‚จๅฟ…้ ˆไฝฟ็”จ็ต„็น”็š„ Roo Code Cloud ๅธณๆˆถ้€ฒ่กŒ่บซไปฝ้ฉ—่ญ‰ใ€‚", "verification_failed": "็„กๆณ•้ฉ—่ญ‰็ต„็น”่บซไปฝ้ฉ—่ญ‰ใ€‚" + }, + "geminiCli": { + "oauthLoadFailed": "่ผ‰ๅ…ฅ OAuth ๆ†‘่ญ‰ๅคฑๆ•—ใ€‚่ซ‹ๅ…ˆ้€ฒ่กŒ่บซไปฝ้ฉ—่ญ‰๏ผš{{error}}", + "tokenRefreshFailed": "้‡ๆ–ฐๆ•ด็† OAuth Token ๅคฑๆ•—๏ผš{{error}}", + "onboardingTimeout": "ๅ…ฅ้–€ๆ“ไฝœๅœจ 60 ็ง’ๅพŒ้€พๆ™‚ใ€‚่ซ‹็จๅพŒ้‡่ฉฆใ€‚", + "projectDiscoveryFailed": "็„กๆณ•็™ผ็พๅฐˆๆกˆ IDใ€‚่ซ‹็ขบไฟๅทฒไฝฟ็”จ 'gemini auth' ้€ฒ่กŒ่บซไปฝ้ฉ—่ญ‰ใ€‚", + "rateLimitExceeded": "้€Ÿ็އ้™ๅˆถๅทฒ่ถ…ๅ‡บใ€‚ๅ…่ฒปๅฑค็ดš้™ๅˆถๅทฒ้”ๅˆฐใ€‚", + "badRequest": "่ซ‹ๆฑ‚้Œฏ่ชค๏ผš{{details}}", + "apiError": "Gemini CLI API ้Œฏ่ชค๏ผš{{error}}", + "completionError": "Gemini CLI ๅฎŒๆˆ้Œฏ่ชค๏ผš{{error}}" } } } diff --git a/src/shared/checkExistApiConfig.ts b/src/shared/checkExistApiConfig.ts index eca2dd4fe0..d54e98ec8e 100644 --- a/src/shared/checkExistApiConfig.ts +++ b/src/shared/checkExistApiConfig.ts @@ -5,8 +5,8 @@ export function checkExistKey(config: ProviderSettings | undefined) { return false } - // Special case for human-relay, fake-ai, and claude-code providers which don't need any configuration. - if (config.apiProvider && ["human-relay", "fake-ai", "claude-code"].includes(config.apiProvider)) { + // Special case for human-relay, fake-ai, claude-code, and gemini-cli providers which don't need any configuration. + if (config.apiProvider && ["human-relay", "fake-ai", "claude-code", "gemini-cli"].includes(config.apiProvider)) { return true } diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 8f6050f4f2..ca96502e82 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -15,6 +15,7 @@ import { anthropicDefaultModelId, claudeCodeDefaultModelId, geminiDefaultModelId, + geminiCliDefaultModelId, deepSeekDefaultModelId, mistralDefaultModelId, xaiDefaultModelId, @@ -40,6 +41,7 @@ import { ClaudeCode, DeepSeek, Gemini, + GeminiCli, Glama, Groq, LMStudio, @@ -259,6 +261,7 @@ const ApiOptions = ({ "claude-code": { field: "apiModelId", default: claudeCodeDefaultModelId }, "openai-native": { field: "apiModelId", default: openAiNativeDefaultModelId }, gemini: { field: "apiModelId", default: geminiDefaultModelId }, + "gemini-cli": { field: "apiModelId", default: geminiCliDefaultModelId }, deepseek: { field: "apiModelId", default: deepSeekDefaultModelId }, mistral: { field: "apiModelId", default: mistralDefaultModelId }, xai: { field: "apiModelId", default: xaiDefaultModelId }, @@ -414,6 +417,10 @@ const ApiOptions = ({ )} + {selectedProvider === "gemini-cli" && ( + + )} + {selectedProvider === "openai" && ( void +} + +export const GeminiCli = ({ apiConfiguration, setApiConfigurationField }: GeminiCliProps) => { + const { t } = useAppTranslation() + + const handleInputChange = useCallback( + ( + field: K, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, + ) => + (event: E | Event) => { + setApiConfigurationField(field, transform(event as E)) + }, + [setApiConfigurationField], + ) + + return ( + <> + + + +
+ {t("settings:providers.geminiCli.oauthPathDescription")} +
+ +
+ {t("settings:providers.geminiCli.description")} +
+ +
+ {t("settings:providers.geminiCli.instructions")}{" "} + gemini{" "} + {t("settings:providers.geminiCli.instructionsContinued")} +
+ + + {t("settings:providers.geminiCli.setupLink")} + + +
+
+ + {t("settings:providers.geminiCli.requirementsTitle")} +
+
    +
  • {t("settings:providers.geminiCli.requirement1")}
  • +
  • {t("settings:providers.geminiCli.requirement2")}
  • +
  • {t("settings:providers.geminiCli.requirement3")}
  • +
  • {t("settings:providers.geminiCli.requirement4")}
  • +
  • {t("settings:providers.geminiCli.requirement5")}
  • +
+
+ +
+ + + {t("settings:providers.geminiCli.freeAccess")} + +
+ + ) +} diff --git a/webview-ui/src/components/settings/providers/__tests__/GeminiCli.spec.tsx b/webview-ui/src/components/settings/providers/__tests__/GeminiCli.spec.tsx new file mode 100644 index 0000000000..dc9c82f200 --- /dev/null +++ b/webview-ui/src/components/settings/providers/__tests__/GeminiCli.spec.tsx @@ -0,0 +1,169 @@ +import { render, screen, fireEvent } from "@testing-library/react" +import { describe, it, expect, vi } from "vitest" + +import type { ProviderSettings } from "@roo-code/types" + +import { GeminiCli } from "../GeminiCli" + +// Mock the translation hook +vi.mock("@src/i18n/TranslationContext", () => ({ + useAppTranslation: () => ({ + t: (key: string) => key, + }), +})) + +// Mock VSCodeLink to render as a regular anchor tag +vi.mock("@vscode/webview-ui-toolkit/react", async () => { + const actual = await vi.importActual("@vscode/webview-ui-toolkit/react") + return { + ...actual, + VSCodeLink: ({ children, href, ...props }: any) => ( + + {children} + + ), + } +}) + +describe("GeminiCli", () => { + const mockSetApiConfigurationField = vi.fn() + const defaultProps = { + apiConfiguration: {} as ProviderSettings, + setApiConfigurationField: mockSetApiConfigurationField, + } + + beforeEach(() => { + vi.clearAllMocks() + }) + + it("renders all required elements", () => { + render() + + // Check for OAuth path input + expect(screen.getByText("settings:providers.geminiCli.oauthPath")).toBeInTheDocument() + expect(screen.getByPlaceholderText("~/.gemini/oauth_creds.json")).toBeInTheDocument() + + // Check for description text + expect(screen.getByText("settings:providers.geminiCli.description")).toBeInTheDocument() + + // Check for instructions - they're in the same div but broken up by the code element + // Find all elements that contain the instruction parts + const instructionsDivs = screen.getAllByText((_content, element) => { + // Check if this element contains all the expected text parts + const fullText = element?.textContent || "" + return ( + fullText.includes("settings:providers.geminiCli.instructions") && + fullText.includes("gemini") && + fullText.includes("settings:providers.geminiCli.instructionsContinued") + ) + }) + // Find the div with the correct classes + const instructionsDiv = instructionsDivs.find( + (div) => + div.classList.contains("text-sm") && + div.classList.contains("text-vscode-descriptionForeground") && + div.classList.contains("mt-2"), + ) + expect(instructionsDiv).toBeDefined() + expect(instructionsDiv).toBeInTheDocument() + + // Also verify the code element exists + const codeElement = screen.getByText("gemini") + expect(codeElement).toBeInTheDocument() + expect(codeElement.tagName).toBe("CODE") + + // Check for setup link + expect(screen.getByText("settings:providers.geminiCli.setupLink")).toBeInTheDocument() + + // Check for requirements + expect(screen.getByText("settings:providers.geminiCli.requirementsTitle")).toBeInTheDocument() + expect(screen.getByText("settings:providers.geminiCli.requirement1")).toBeInTheDocument() + expect(screen.getByText("settings:providers.geminiCli.requirement2")).toBeInTheDocument() + expect(screen.getByText("settings:providers.geminiCli.requirement3")).toBeInTheDocument() + expect(screen.getByText("settings:providers.geminiCli.requirement4")).toBeInTheDocument() + expect(screen.getByText("settings:providers.geminiCli.requirement5")).toBeInTheDocument() + + // Check for free access note + expect(screen.getByText("settings:providers.geminiCli.freeAccess")).toBeInTheDocument() + }) + + it("displays OAuth path from configuration", () => { + const apiConfiguration: ProviderSettings = { + geminiCliOAuthPath: "/custom/path/oauth.json", + } + + render() + + const oauthInput = screen.getByDisplayValue("/custom/path/oauth.json") + expect(oauthInput).toBeInTheDocument() + }) + + it("calls setApiConfigurationField when OAuth path is changed", () => { + render() + + const oauthInput = screen.getByPlaceholderText("~/.gemini/oauth_creds.json") + + // Simulate input event with VSCodeTextField + fireEvent.input(oauthInput, { target: { value: "/new/path.json" } }) + + // Check that setApiConfigurationField was called + expect(mockSetApiConfigurationField).toHaveBeenCalledWith("geminiCliOAuthPath", "/new/path.json") + }) + + it("renders setup link with correct href", () => { + render() + + const setupLink = screen.getByText("settings:providers.geminiCli.setupLink") + expect(setupLink).toHaveAttribute( + "href", + "https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quickstart", + ) + }) + + it("shows OAuth path description", () => { + render() + + expect(screen.getByText("settings:providers.geminiCli.oauthPathDescription")).toBeInTheDocument() + }) + + it("renders all requirements in a list", () => { + render() + + const listItems = screen.getAllByRole("listitem") + expect(listItems).toHaveLength(5) + expect(listItems[0]).toHaveTextContent("settings:providers.geminiCli.requirement1") + expect(listItems[1]).toHaveTextContent("settings:providers.geminiCli.requirement2") + expect(listItems[2]).toHaveTextContent("settings:providers.geminiCli.requirement3") + expect(listItems[3]).toHaveTextContent("settings:providers.geminiCli.requirement4") + expect(listItems[4]).toHaveTextContent("settings:providers.geminiCli.requirement5") + }) + + it("applies correct styling classes", () => { + render() + + // Check for styled warning box + const warningBox = screen.getByText("settings:providers.geminiCli.requirementsTitle").closest("div.mt-3") + expect(warningBox).toHaveClass("bg-vscode-editorWidget-background") + expect(warningBox).toHaveClass("border-vscode-editorWidget-border") + expect(warningBox).toHaveClass("rounded") + expect(warningBox).toHaveClass("p-3") + + // Check for warning icon + const warningIcon = screen.getByText("settings:providers.geminiCli.requirementsTitle").previousElementSibling + expect(warningIcon).toHaveClass("codicon-warning") + expect(warningIcon).toHaveClass("text-vscode-notificationsWarningIcon-foreground") + + // Check for check icon + const checkIcon = screen.getByText("settings:providers.geminiCli.freeAccess").previousElementSibling + expect(checkIcon).toHaveClass("codicon-check") + expect(checkIcon).toHaveClass("text-vscode-notificationsInfoIcon-foreground") + }) + + it("renders instructions with code element", () => { + render() + + const codeElement = screen.getByText("gemini") + expect(codeElement.tagName).toBe("CODE") + expect(codeElement).toHaveClass("text-vscode-textPreformat-foreground") + }) +}) diff --git a/webview-ui/src/components/settings/providers/index.ts b/webview-ui/src/components/settings/providers/index.ts index b195607430..4c7b3c9f0b 100644 --- a/webview-ui/src/components/settings/providers/index.ts +++ b/webview-ui/src/components/settings/providers/index.ts @@ -4,6 +4,7 @@ export { Chutes } from "./Chutes" export { ClaudeCode } from "./ClaudeCode" export { DeepSeek } from "./DeepSeek" export { Gemini } from "./Gemini" +export { GeminiCli } from "./GeminiCli" export { Glama } from "./Glama" export { Groq } from "./Groq" export { LMStudio } from "./LMStudio" diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 40c1ff2431..35ed30fb3f 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -10,6 +10,8 @@ import { deepSeekModels, geminiDefaultModelId, geminiModels, + geminiCliDefaultModelId, + geminiCliModels, mistralDefaultModelId, mistralModels, openAiModelInfoSaneDefaults, @@ -157,6 +159,11 @@ function getSelectedModel({ const info = geminiModels[id as keyof typeof geminiModels] return { id, info } } + case "gemini-cli": { + const id = apiConfiguration.apiModelId ?? geminiCliDefaultModelId + const info = geminiCliModels[id as keyof typeof geminiCliModels] + return { id, info } + } case "deepseek": { const id = apiConfiguration.apiModelId ?? deepSeekDefaultModelId const info = deepSeekModels[id as keyof typeof deepSeekModels] diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index ea4f974149..b3906fb50e 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Ruta del Codi Claude", "description": "Ruta opcional al teu CLI de Claude Code. Per defecte, 'claude' si no s'estableix.", "placeholder": "Per defecte: claude" + }, + "geminiCli": { + "description": "Aquest proveรฏdor utilitza l'autenticaciรณ OAuth de l'eina Gemini CLI i no requereix claus d'API.", + "oauthPath": "Ruta de Credencials OAuth (opcional)", + "oauthPathDescription": "Ruta al fitxer de credencials OAuth. Deixa buit per utilitzar la ubicaciรณ per defecte (~/.gemini/oauth_creds.json).", + "instructions": "Si encara no t'has autenticat, executa", + "instructionsContinued": "al teu terminal primer.", + "setupLink": "Instruccions de Configuraciรณ de Gemini CLI", + "requirementsTitle": "Requisits Importants", + "requirement1": "Primer, necessites instalยทlar l'eina Gemini CLI", + "requirement2": "Desprรฉs, executa gemini al teu terminal i assegura't d'iniciar sessiรณ amb Google", + "requirement3": "Nomรฉs funciona amb comptes personals de Google (no comptes de Google Workspace)", + "requirement4": "No utilitza claus d'API - l'autenticaciรณ es gestiona via OAuth", + "requirement5": "Requereix que l'eina Gemini CLI estigui instalยทlada i autenticada primer", + "freeAccess": "Accรฉs gratuรฏt via autenticaciรณ OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index c5e161bafe..ad78931d81 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Claude-Code-Pfad", "description": "Optionaler Pfad zu Ihrer Claude Code CLI. Standard ist 'claude', wenn nicht festgelegt.", "placeholder": "Standard: claude" + }, + "geminiCli": { + "description": "Dieser Anbieter verwendet OAuth-Authentifizierung vom Gemini CLI-Tool und benรถtigt keine API-Schlรผssel.", + "oauthPath": "OAuth-Anmeldedaten-Pfad (optional)", + "oauthPathDescription": "Pfad zur OAuth-Anmeldedaten-Datei. Leer lassen, um den Standardort zu verwenden (~/.gemini/oauth_creds.json).", + "instructions": "Falls du dich noch nicht authentifiziert hast, fรผhre bitte", + "instructionsContinued": "in deinem Terminal zuerst aus.", + "setupLink": "Gemini CLI Setup-Anweisungen", + "requirementsTitle": "Wichtige Anforderungen", + "requirement1": "Zuerst musst du das Gemini CLI-Tool installieren", + "requirement2": "Dann fรผhre gemini in deinem Terminal aus und stelle sicher, dass du dich mit Google anmeldest", + "requirement3": "Funktioniert nur mit persรถnlichen Google-Konten (nicht mit Google Workspace-Konten)", + "requirement4": "Verwendet keine API-Schlรผssel - Authentifizierung wird รผber OAuth abgewickelt", + "requirement5": "Erfordert, dass das Gemini CLI-Tool zuerst installiert und authentifiziert wird", + "freeAccess": "Kostenloser Zugang รผber OAuth-Authentifizierung" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 14981ea499..9083d4a204 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Claude Code Path", "description": "Optional path to your Claude Code CLI. Defaults to 'claude' if not set.", "placeholder": "Default: claude" + }, + "geminiCli": { + "description": "This provider uses OAuth authentication from the Gemini CLI tool and does not require API keys.", + "oauthPath": "OAuth Credentials Path (optional)", + "oauthPathDescription": "Path to the OAuth credentials file. Leave empty to use the default location (~/.gemini/oauth_creds.json).", + "instructions": "If you haven't authenticated yet, please run", + "instructionsContinued": "in your terminal first.", + "setupLink": "Gemini CLI Setup Instructions", + "requirementsTitle": "Important Requirements", + "requirement1": "First, you need to install the Gemini CLI tool", + "requirement2": "Then, run gemini in your terminal and make sure you Log in with Google", + "requirement3": "Only works with personal Google accounts (not Google Workspace accounts)", + "requirement4": "Does not use API keys - authentication is handled via OAuth", + "requirement5": "Requires the Gemini CLI tool to be installed and authenticated first", + "freeAccess": "Free tier access via OAuth authentication" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 3e3d20cce1..c83237d4f3 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Ruta de Claude Code", "description": "Ruta opcional a su CLI de Claude Code. Por defecto, es 'claude' si no se establece.", "placeholder": "Por defecto: claude" + }, + "geminiCli": { + "description": "Este proveedor usa autenticaciรณn OAuth de la herramienta Gemini CLI y no requiere claves API.", + "oauthPath": "Ruta de Credenciales OAuth (opcional)", + "oauthPathDescription": "Ruta al archivo de credenciales OAuth. Deja vacรญo para usar la ubicaciรณn predeterminada (~/.gemini/oauth_creds.json).", + "instructions": "Si aรบn no te has autenticado, por favor ejecuta", + "instructionsContinued": "en tu terminal primero.", + "setupLink": "Instrucciones de Configuraciรณn de Gemini CLI", + "requirementsTitle": "Requisitos Importantes", + "requirement1": "Primero, necesitas instalar la herramienta Gemini CLI", + "requirement2": "Luego, ejecuta gemini en tu terminal y asegรบrate de iniciar sesiรณn con Google", + "requirement3": "Solo funciona con cuentas personales de Google (no cuentas de Google Workspace)", + "requirement4": "No usa claves API - la autenticaciรณn se maneja vรญa OAuth", + "requirement5": "Requiere que la herramienta Gemini CLI estรฉ instalada y autenticada primero", + "freeAccess": "Acceso gratuito vรญa autenticaciรณn OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 5635251876..681d95be98 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Chemin du code Claude", "description": "Chemin facultatif vers votre CLI Claude Code. La valeur par dรฉfaut est 'claude' si non dรฉfini.", "placeholder": "Dรฉfaut : claude" + }, + "geminiCli": { + "description": "Ce fournisseur utilise l'authentification OAuth de l'outil Gemini CLI et ne nรฉcessite pas de clรฉs API.", + "oauthPath": "Chemin des Identifiants OAuth (optionnel)", + "oauthPathDescription": "Chemin vers le fichier d'identifiants OAuth. Laissez vide pour utiliser l'emplacement par dรฉfaut (~/.gemini/oauth_creds.json).", + "instructions": "Si vous ne vous รชtes pas encore authentifiรฉ, veuillez exรฉcuter", + "instructionsContinued": "dans votre terminal d'abord.", + "setupLink": "Instructions de Configuration Gemini CLI", + "requirementsTitle": "Exigences Importantes", + "requirement1": "D'abord, vous devez installer l'outil Gemini CLI", + "requirement2": "Ensuite, exรฉcutez gemini dans votre terminal et assurez-vous de vous connecter avec Google", + "requirement3": "Fonctionne uniquement avec les comptes Google personnels (pas les comptes Google Workspace)", + "requirement4": "N'utilise pas de clรฉs API - l'authentification est gรฉrรฉe via OAuth", + "requirement5": "Nรฉcessite que l'outil Gemini CLI soit installรฉ et authentifiรฉ d'abord", + "freeAccess": "Accรจs gratuit via l'authentification OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 8de5bd1a19..9d8bef3711 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -308,6 +308,21 @@ "pathLabel": "เค•เฅเคฒเคพเค‰เคก เค•เฅ‹เคก เคชเคฅ", "description": "เค†เคชเค•เฅ‡ เค•เฅเคฒเคพเค‰เคก เค•เฅ‹เคก เคธเฅ€เคเคฒเค†เคˆ เค•เคพ เคตเฅˆเค•เคฒเฅเคชเคฟเค• เคชเคฅเฅค เคฏเคฆเคฟ เคธเฅ‡เคŸ เคจเคนเฅ€เค‚ เคนเฅˆ เคคเฅ‹ เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ 'claude' เคนเฅˆเฅค", "placeholder": "เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ: claude" + }, + "geminiCli": { + "description": "เคฏเคน เคชเฅเคฐเคฆเคพเคคเคพ Gemini CLI เคŸเฅ‚เคฒ เคธเฅ‡ OAuth เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เคพ เค‰เคชเคฏเฅ‹เค— เค•เคฐเคคเคพ เคนเฅˆ เค”เคฐ API เค•เฅเค‚เคœเคฟเคฏเฅ‹เค‚ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เคจเคนเฅ€เค‚ เคนเฅˆเฅค", + "oauthPath": "OAuth เค•เฅเคฐเฅ‡เคกเฅ‡เค‚เคถเคฟเคฏเคฒ เคชเคฅ (เคตเฅˆเค•เคฒเฅเคชเคฟเค•)", + "oauthPathDescription": "OAuth เค•เฅเคฐเฅ‡เคกเฅ‡เค‚เคถเคฟเคฏเคฒ เคซเคผเคพเค‡เคฒ เค•เคพ เคชเคฅเฅค เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ เคธเฅเคฅเคพเคจ (~/.gemini/oauth_creds.json) เค•เคพ เค‰เคชเคฏเฅ‹เค— เค•เคฐเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค–เคพเคฒเฅ€ เค›เฅ‹เคกเคผเฅ‡เค‚เฅค", + "instructions": "เคฏเคฆเคฟ เค†เคชเคจเฅ‡ เค…เคญเฅ€ เคคเค• เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เคจเคนเฅ€เค‚ เค•เคฟเคฏเคพ เคนเฅˆ, เคคเฅ‹ เค•เฅƒเคชเคฏเคพ เคชเคนเคฒเฅ‡", + "instructionsContinued": "เค•เฅ‹ เค…เคชเคจเฅ‡ เคŸเคฐเฅเคฎเคฟเคจเคฒ เคฎเฅ‡เค‚ เคšเคฒเคพเคเค‚เฅค", + "setupLink": "Gemini CLI เคธเฅ‡เคŸเค…เคช เคจเคฟเคฐเฅเคฆเฅ‡เคถ", + "requirementsTitle": "เคฎเคนเคคเฅเคตเคชเฅ‚เคฐเฅเคฃ เค†เคตเคถเฅเคฏเค•เคคเคพเคเค‚", + "requirement1": "เคชเคนเคฒเฅ‡, เค†เคชเค•เฅ‹ Gemini CLI เคŸเฅ‚เคฒ เค‡เค‚เคธเฅเคŸเฅ‰เคฒ เค•เคฐเคจเคพ เคนเฅ‹เค—เคพ", + "requirement2": "เคซเคฟเคฐ, เค…เคชเคจเฅ‡ เคŸเคฐเฅเคฎเคฟเคจเคฒ เคฎเฅ‡เค‚ gemini เคšเคฒเคพเคเค‚ เค”เคฐ เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เค•เคฐเฅ‡เค‚ เค•เคฟ เค†เคช Google เคธเฅ‡ เคฒเฅ‰เค— เค‡เคจ เค•เคฐเฅ‡เค‚", + "requirement3": "เค•เฅ‡เคตเคฒ เคตเฅเคฏเค•เฅเคคเคฟเค—เคค Google เค–เคพเคคเฅ‹เค‚ เค•เฅ‡ เคธเคพเคฅ เค•เคพเคฎ เค•เคฐเคคเคพ เคนเฅˆ (Google Workspace เค–เคพเคคเฅ‡ เคจเคนเฅ€เค‚)", + "requirement4": "API เค•เฅเค‚เคœเคฟเคฏเฅ‹เค‚ เค•เคพ เค‰เคชเคฏเฅ‹เค— เคจเคนเฅ€เค‚ เค•เคฐเคคเคพ - เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ OAuth เค•เฅ‡ เคฎเคพเคงเฅเคฏเคฎ เคธเฅ‡ เคธเค‚เคญเคพเคฒเคพ เคœเคพเคคเคพ เคนเฅˆ", + "requirement5": "Gemini CLI เคŸเฅ‚เคฒ เค•เฅ‹ เคชเคนเคฒเฅ‡ เค‡เค‚เคธเฅเคŸเฅ‰เคฒ เค”เคฐ เคชเฅเคฐเคฎเคพเคฃเคฟเคค เค•เคฐเคจเฅ‡ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เคนเฅˆ", + "freeAccess": "OAuth เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เฅ‡ เคฎเคพเคงเฅเคฏเคฎ เคธเฅ‡ เคฎเฅเคซเฅเคค เคชเคนเฅเค‚เคš" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 8def303c05..c5e3abf45c 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -312,6 +312,21 @@ "pathLabel": "Jalur Kode Claude", "description": "Jalur opsional ke Claude Code CLI Anda. Defaultnya adalah 'claude' jika tidak diatur.", "placeholder": "Default: claude" + }, + "geminiCli": { + "description": "Penyedia ini menggunakan autentikasi OAuth dari alat Gemini CLI dan tidak memerlukan kunci API.", + "oauthPath": "Jalur Kredensial OAuth (opsional)", + "oauthPathDescription": "Jalur ke file kredensial OAuth. Biarkan kosong untuk menggunakan lokasi default (~/.gemini/oauth_creds.json).", + "instructions": "Jika Anda belum melakukan autentikasi, jalankan", + "instructionsContinued": "di terminal Anda terlebih dahulu.", + "setupLink": "Petunjuk Pengaturan Gemini CLI", + "requirementsTitle": "Persyaratan Penting", + "requirement1": "Pertama, Anda perlu menginstal alat Gemini CLI", + "requirement2": "Kemudian, jalankan gemini di terminal Anda dan pastikan Anda masuk dengan Google", + "requirement3": "Hanya berfungsi dengan akun Google pribadi (bukan akun Google Workspace)", + "requirement4": "Tidak menggunakan kunci API - autentikasi ditangani melalui OAuth", + "requirement5": "Memerlukan alat Gemini CLI diinstal dan diautentikasi terlebih dahulu", + "freeAccess": "Akses gratis melalui autentikasi OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 572f99cbb0..fefdcd2ca2 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Percorso Claude Code", "description": "Percorso facoltativo per la tua CLI Claude Code. Predefinito 'claude' se non impostato.", "placeholder": "Predefinito: claude" + }, + "geminiCli": { + "description": "Questo provider utilizza l'autenticazione OAuth dallo strumento Gemini CLI e non richiede chiavi API.", + "oauthPath": "Percorso Credenziali OAuth (opzionale)", + "oauthPathDescription": "Percorso al file delle credenziali OAuth. Lascia vuoto per utilizzare la posizione predefinita (~/.gemini/oauth_creds.json).", + "instructions": "Se non ti sei ancora autenticato, esegui", + "instructionsContinued": "nel tuo terminale prima.", + "setupLink": "Istruzioni di Configurazione Gemini CLI", + "requirementsTitle": "Requisiti Importanti", + "requirement1": "Prima, devi installare lo strumento Gemini CLI", + "requirement2": "Poi, esegui gemini nel tuo terminale e assicurati di accedere con Google", + "requirement3": "Funziona solo con account Google personali (non account Google Workspace)", + "requirement4": "Non utilizza chiavi API - l'autenticazione รจ gestita tramite OAuth", + "requirement5": "Richiede che lo strumento Gemini CLI sia installato e autenticato prima", + "freeAccess": "Accesso gratuito tramite autenticazione OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index c6a681e549..f5d198a8d4 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -308,6 +308,21 @@ "pathLabel": "ใ‚ฏใƒญใƒผใƒ‰ใ‚ณใƒผใƒ‰ใƒ‘ใ‚น", "description": "Claude Code CLIใธใฎใ‚ชใƒ—ใ‚ทใƒงใƒณใƒ‘ใ‚นใ€‚่จญๅฎšใ•ใ‚Œใฆใ„ใชใ„ๅ ดๅˆใ€ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฏใ€Œclaudeใ€ใงใ™ใ€‚", "placeholder": "ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆ๏ผšclaude" + }, + "geminiCli": { + "description": "ใ“ใฎใƒ—ใƒญใƒใ‚คใƒ€ใƒผใฏGemini CLIใƒ„ใƒผใƒซใ‹ใ‚‰ใฎOAuth่ช่จผใ‚’ไฝฟ็”จใ—ใ€APIใ‚ญใƒผใฏๅฟ…่ฆใ‚ใ‚Šใพใ›ใ‚“ใ€‚", + "oauthPath": "OAuth่ช่จผๆƒ…ๅ ฑใƒ‘ใ‚น๏ผˆใ‚ชใƒ—ใ‚ทใƒงใƒณ๏ผ‰", + "oauthPathDescription": "OAuth่ช่จผๆƒ…ๅ ฑใƒ•ใ‚กใ‚คใƒซใธใฎใƒ‘ใ‚นใ€‚ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎๅ ดๆ‰€๏ผˆ~/.gemini/oauth_creds.json๏ผ‰ใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆใฏ็ฉบใฎใพใพใซใ—ใฆใใ ใ•ใ„ใ€‚", + "instructions": "ใพใ ่ช่จผใ—ใฆใ„ใชใ„ๅ ดๅˆใฏใ€ใพใš", + "instructionsContinued": "ใ‚’ใ‚ฟใƒผใƒŸใƒŠใƒซใงๅฎŸ่กŒใ—ใฆใใ ใ•ใ„ใ€‚", + "setupLink": "Gemini CLI ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ๆ‰‹้ †", + "requirementsTitle": "้‡่ฆใช่ฆไปถ", + "requirement1": "ใพใšใ€Gemini CLIใƒ„ใƒผใƒซใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™", + "requirement2": "ๆฌกใซใ€ใ‚ฟใƒผใƒŸใƒŠใƒซใงgeminiใ‚’ๅฎŸ่กŒใ—ใ€Googleใงใƒญใ‚ฐใ‚คใƒณใ™ใ‚‹ใ“ใจใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„", + "requirement3": "ๅ€‹ไบบใฎGoogleใ‚ขใ‚ซใ‚ฆใƒณใƒˆใงใฎใฟๅ‹•ไฝœใ—ใพใ™๏ผˆGoogle Workspaceใ‚ขใ‚ซใ‚ฆใƒณใƒˆใฏไธๅฏ๏ผ‰", + "requirement4": "APIใ‚ญใƒผใฏไฝฟ็”จใ—ใพใ›ใ‚“ - ่ช่จผใฏOAuthใงๅ‡ฆ็†ใ•ใ‚Œใพใ™", + "requirement5": "Gemini CLIใƒ„ใƒผใƒซใŒๆœ€ๅˆใซใ‚คใƒณใ‚นใƒˆใƒผใƒซใ•ใ‚Œใ€่ช่จผใ•ใ‚Œใฆใ„ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™", + "freeAccess": "OAuth่ช่จผใซใ‚ˆใ‚‹็„กๆ–™ใ‚ขใ‚ฏใ‚ปใ‚น" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 6ae68428bd..5476b044bf 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -308,6 +308,21 @@ "pathLabel": "ํด๋กœ๋“œ ์ฝ”๋“œ ๊ฒฝ๋กœ", "description": "Claude Code CLI์˜ ์„ ํƒ์  ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด 'claude'๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ž…๋‹ˆ๋‹ค.", "placeholder": "๊ธฐ๋ณธ๊ฐ’: claude" + }, + "geminiCli": { + "description": "์ด ๊ณต๊ธ‰์ž๋Š” Gemini CLI ๋„๊ตฌ์˜ OAuth ์ธ์ฆ์„ ์‚ฌ์šฉํ•˜๋ฉฐ API ํ‚ค๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.", + "oauthPath": "OAuth ์ž๊ฒฉ ์ฆ๋ช… ๊ฒฝ๋กœ (์„ ํƒ์‚ฌํ•ญ)", + "oauthPathDescription": "OAuth ์ž๊ฒฉ ์ฆ๋ช… ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์œ„์น˜(~/.gemini/oauth_creds.json)๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋น„์›Œ๋‘์„ธ์š”.", + "instructions": "์•„์ง ์ธ์ฆํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด", + "instructionsContinued": "๋ฅผ ํ„ฐ๋ฏธ๋„์—์„œ ๋จผ์ € ์‹คํ–‰ํ•˜์„ธ์š”.", + "setupLink": "Gemini CLI ์„ค์ • ์ง€์นจ", + "requirementsTitle": "์ค‘์š”ํ•œ ์š”๊ตฌ์‚ฌํ•ญ", + "requirement1": "๋จผ์ € Gemini CLI ๋„๊ตฌ๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค", + "requirement2": "๊ทธ ๋‹ค์Œ ํ„ฐ๋ฏธ๋„์—์„œ gemini๋ฅผ ์‹คํ–‰ํ•˜๊ณ  Google๋กœ ๋กœ๊ทธ์ธํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”", + "requirement3": "๊ฐœ์ธ Google ๊ณ„์ •์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค (Google Workspace ๊ณ„์ • ๋ถˆ๊ฐ€)", + "requirement4": "API ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค - ์ธ์ฆ์€ OAuth๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค", + "requirement5": "Gemini CLI ๋„๊ตฌ๊ฐ€ ๋จผ์ € ์„ค์น˜๋˜๊ณ  ์ธ์ฆ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค", + "freeAccess": "OAuth ์ธ์ฆ์„ ํ†ตํ•œ ๋ฌด๋ฃŒ ์•ก์„ธ์Šค" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index c6d1bb7992..88a66c0d5f 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Claude Code Pad", "description": "Optioneel pad naar uw Claude Code CLI. Standaard 'claude' als niet ingesteld.", "placeholder": "Standaard: claude" + }, + "geminiCli": { + "description": "Deze provider gebruikt OAuth-authenticatie van de Gemini CLI-tool en vereist geen API-sleutels.", + "oauthPath": "OAuth-referentiepad (optioneel)", + "oauthPathDescription": "Pad naar het OAuth-referentiebestand. Laat leeg om de standaardlocatie te gebruiken (~/.gemini/oauth_creds.json).", + "instructions": "Als je nog niet bent geauthenticeerd, voer dan eerst", + "instructionsContinued": "uit in je terminal.", + "setupLink": "Gemini CLI Setup-instructies", + "requirementsTitle": "Belangrijke vereisten", + "requirement1": "Eerst moet je de Gemini CLI-tool installeren", + "requirement2": "Voer vervolgens gemini uit in je terminal en zorg ervoor dat je inlogt met Google", + "requirement3": "Werkt alleen met persoonlijke Google-accounts (geen Google Workspace-accounts)", + "requirement4": "Gebruikt geen API-sleutels - authenticatie wordt afgehandeld via OAuth", + "requirement5": "Vereist dat de Gemini CLI-tool eerst wordt geรฏnstalleerd en geauthenticeerd", + "freeAccess": "Gratis toegang via OAuth-authenticatie" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index b702d7b5a5..4a446f7095 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -308,6 +308,21 @@ "pathLabel": "ลšcieลผka Claude Code", "description": "Opcjonalna ล›cieลผka do Twojego CLI Claude Code. Domyล›lnie 'claude', jeล›li nie ustawiono.", "placeholder": "Domyล›lnie: claude" + }, + "geminiCli": { + "description": "Ten dostawca uลผywa uwierzytelniania OAuth z narzฤ™dzia Gemini CLI i nie wymaga kluczy API.", + "oauthPath": "ลšcieลผka danych uwierzytelniajฤ…cych OAuth (opcjonalne)", + "oauthPathDescription": "ลšcieลผka do pliku danych uwierzytelniajฤ…cych OAuth. Pozostaw puste, aby uลผyฤ‡ domyล›lnej lokalizacji (~/.gemini/oauth_creds.json).", + "instructions": "Jeล›li jeszcze siฤ™ nie uwierzytelniล‚eล›, uruchom najpierw", + "instructionsContinued": "w swoim terminalu.", + "setupLink": "Instrukcje konfiguracji Gemini CLI", + "requirementsTitle": "Waลผne wymagania", + "requirement1": "Najpierw musisz zainstalowaฤ‡ narzฤ™dzie Gemini CLI", + "requirement2": "Nastฤ™pnie uruchom gemini w swoim terminalu i upewnij siฤ™, ลผe logujesz siฤ™ przez Google", + "requirement3": "Dziaล‚a tylko z osobistymi kontami Google (nie z kontami Google Workspace)", + "requirement4": "Nie uลผywa kluczy API - uwierzytelnianie jest obsล‚ugiwane przez OAuth", + "requirement5": "Wymaga, aby narzฤ™dzie Gemini CLI byล‚o najpierw zainstalowane i uwierzytelnione", + "freeAccess": "Darmowy dostฤ™p przez uwierzytelnianie OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index be7bfe2d0d..b4ae11c2ac 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Caminho do Claude Code", "description": "Caminho opcional para o seu Claude Code CLI. O padrรฃo รฉ 'claude' se nรฃo for definido.", "placeholder": "Padrรฃo: claude" + }, + "geminiCli": { + "description": "Este provedor usa autenticaรงรฃo OAuth da ferramenta Gemini CLI e nรฃo requer chaves de API.", + "oauthPath": "Caminho das Credenciais OAuth (opcional)", + "oauthPathDescription": "Caminho para o arquivo de credenciais OAuth. Deixe vazio para usar o local padrรฃo (~/.gemini/oauth_creds.json).", + "instructions": "Se vocรช ainda nรฃo se autenticou, execute", + "instructionsContinued": "no seu terminal primeiro.", + "setupLink": "Instruรงรตes de Configuraรงรฃo do Gemini CLI", + "requirementsTitle": "Requisitos Importantes", + "requirement1": "Primeiro, vocรช precisa instalar a ferramenta Gemini CLI", + "requirement2": "Em seguida, execute gemini no seu terminal e certifique-se de fazer login com o Google", + "requirement3": "Funciona apenas com contas pessoais do Google (nรฃo contas do Google Workspace)", + "requirement4": "Nรฃo usa chaves de API - a autenticaรงรฃo รฉ tratada via OAuth", + "requirement5": "Requer que a ferramenta Gemini CLI seja instalada e autenticada primeiro", + "freeAccess": "Acesso gratuito via autenticaรงรฃo OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index b0693f4532..79c13741da 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -308,6 +308,21 @@ "pathLabel": "ะŸัƒั‚ัŒ ะบ Claude Code", "description": "ะะตะพะฑัะทะฐั‚ะตะปัŒะฝั‹ะน ะฟัƒั‚ัŒ ะบ ะฒะฐัˆะตะผัƒ Claude Code CLI. ะŸะพ ัƒะผะพะปั‡ะฐะฝะธัŽ ะธัะฟะพะปัŒะทัƒะตั‚ัั 'claude', ะตัะปะธ ะฝะต ัƒัั‚ะฐะฝะพะฒะปะตะฝะพ.", "placeholder": "ะŸะพ ัƒะผะพะปั‡ะฐะฝะธัŽ: claude" + }, + "geminiCli": { + "description": "ะญั‚ะพั‚ ะฟั€ะพะฒะฐะนะดะตั€ ะธัะฟะพะปัŒะทัƒะตั‚ OAuth-ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ ะธะท ะธะฝัั‚ั€ัƒะผะตะฝั‚ะฐ Gemini CLI ะธ ะฝะต ั‚ั€ะตะฑัƒะตั‚ API-ะบะปัŽั‡ะตะน.", + "oauthPath": "ะŸัƒั‚ัŒ ะบ ัƒั‡ะตั‚ะฝั‹ะผ ะดะฐะฝะฝั‹ะผ OAuth (ะฝะตะพะฑัะทะฐั‚ะตะปัŒะฝะพ)", + "oauthPathDescription": "ะŸัƒั‚ัŒ ะบ ั„ะฐะนะปัƒ ัƒั‡ะตั‚ะฝั‹ั… ะดะฐะฝะฝั‹ั… OAuth. ะžัั‚ะฐะฒัŒั‚ะต ะฟัƒัั‚ั‹ะผ ะดะปั ะธัะฟะพะปัŒะทะพะฒะฐะฝะธั ะผะตัั‚ะพะฟะพะปะพะถะตะฝะธั ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ (~/.gemini/oauth_creds.json).", + "instructions": "ะ•ัะปะธ ะฒั‹ ะตั‰ะต ะฝะต ะฟั€ะพัˆะปะธ ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ, ะฒั‹ะฟะพะปะฝะธั‚ะต", + "instructionsContinued": "ะฒ ะฒะฐัˆะตะผ ั‚ะตั€ะผะธะฝะฐะปะต ัะฝะฐั‡ะฐะปะฐ.", + "setupLink": "ะ˜ะฝัั‚ั€ัƒะบั†ะธะธ ะฟะพ ะฝะฐัั‚ั€ะพะนะบะต Gemini CLI", + "requirementsTitle": "ะ’ะฐะถะฝั‹ะต ั‚ั€ะตะฑะพะฒะฐะฝะธั", + "requirement1": "ะกะฝะฐั‡ะฐะปะฐ ะฒะฐะผ ะฝัƒะถะฝะพ ัƒัั‚ะฐะฝะพะฒะธั‚ัŒ ะธะฝัั‚ั€ัƒะผะตะฝั‚ Gemini CLI", + "requirement2": "ะ—ะฐั‚ะตะผ ะทะฐะฟัƒัั‚ะธั‚ะต gemini ะฒ ะฒะฐัˆะตะผ ั‚ะตั€ะผะธะฝะฐะปะต ะธ ัƒะฑะตะดะธั‚ะตััŒ, ั‡ั‚ะพ ะฒั‹ ะฒะพัˆะปะธ ะฒ Google", + "requirement3": "ะ ะฐะฑะพั‚ะฐะตั‚ ั‚ะพะปัŒะบะพ ั ะปะธั‡ะฝั‹ะผะธ ะฐะบะบะฐัƒะฝั‚ะฐะผะธ Google (ะฝะต ั ะฐะบะบะฐัƒะฝั‚ะฐะผะธ Google Workspace)", + "requirement4": "ะะต ะธัะฟะพะปัŒะทัƒะตั‚ API-ะบะปัŽั‡ะธ - ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธั ะพะฑั€ะฐะฑะฐั‚ั‹ะฒะฐะตั‚ัั ั‡ะตั€ะตะท OAuth", + "requirement5": "ะขั€ะตะฑัƒะตั‚, ั‡ั‚ะพะฑั‹ ะธะฝัั‚ั€ัƒะผะตะฝั‚ Gemini CLI ะฑั‹ะป ัะฝะฐั‡ะฐะปะฐ ัƒัั‚ะฐะฝะพะฒะปะตะฝ ะธ ะฐัƒั‚ะตะฝั‚ะธั„ะธั†ะธั€ะพะฒะฐะฝ", + "freeAccess": "ะ‘ะตัะฟะปะฐั‚ะฝั‹ะน ะดะพัั‚ัƒะฟ ั‡ะตั€ะตะท OAuth-ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 06bd626406..e6335c6dad 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Claude Code Yolu", "description": "Claude Code CLI'nize isteฤŸe baฤŸlฤฑ yol. Ayarlanmazsa varsayฤฑlan olarak 'claude' kullanฤฑlฤฑr.", "placeholder": "Varsayฤฑlan: claude" + }, + "geminiCli": { + "description": "Bu saฤŸlayฤฑcฤฑ Gemini CLI aracฤฑndan OAuth kimlik doฤŸrulamasฤฑ kullanฤฑr ve API anahtarlarฤฑ gerektirmez.", + "oauthPath": "OAuth Kimlik Bilgileri Yolu (isteฤŸe baฤŸlฤฑ)", + "oauthPathDescription": "OAuth kimlik bilgileri dosyasฤฑnฤฑn yolu. Varsayฤฑlan konumu kullanmak iรงin boลŸ bฤฑrakฤฑn (~/.gemini/oauth_creds.json).", + "instructions": "Henรผz kimlik doฤŸrulamasฤฑ yapmadฤฑysanฤฑz, รถnce", + "instructionsContinued": "komutunu terminalinizde รงalฤฑลŸtฤฑrฤฑn.", + "setupLink": "Gemini CLI Kurulum Talimatlarฤฑ", + "requirementsTitle": "ร–nemli Gereksinimler", + "requirement1": "ร–nce Gemini CLI aracฤฑnฤฑ yรผklemeniz gerekir", + "requirement2": "Sonra terminalinizde gemini รงalฤฑลŸtฤฑrฤฑn ve Google ile giriลŸ yaptฤฑฤŸฤฑnฤฑzdan emin olun", + "requirement3": "Sadece kiลŸisel Google hesaplarฤฑyla รงalฤฑลŸฤฑr (Google Workspace hesaplarฤฑ deฤŸil)", + "requirement4": "API anahtarlarฤฑ kullanmaz - kimlik doฤŸrulama OAuth ile yapฤฑlฤฑr", + "requirement5": "Gemini CLI aracฤฑnฤฑn รถnce yรผklenmesi ve kimlik doฤŸrulamasฤฑ yapฤฑlmasฤฑ gerekir", + "freeAccess": "OAuth kimlik doฤŸrulamasฤฑ ile รผcretsiz eriลŸim" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index c434276b3b..f860292e02 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -308,6 +308,21 @@ "pathLabel": "ฤฦฐแปng dแบซn Claude Code", "description": "ฤฦฐแปng dแบซn tรนy chแปn ฤ‘แบฟn Claude Code CLI cแปงa bแบกn. Mแบทc ฤ‘แป‹nh lร  'claude' nแบฟu khรดng ฤ‘ฦฐแปฃc ฤ‘แบทt.", "placeholder": "Mแบทc ฤ‘แป‹nh: claude" + }, + "geminiCli": { + "description": "Nhร  cung cแบฅp nร y sแปญ dแปฅng xรกc thแปฑc OAuth tแปซ cรดng cแปฅ Gemini CLI vร  khรดng yรชu cแบงu khรณa API.", + "oauthPath": "ฤฦฐแปng dแบซn Thรดng tin xรกc thแปฑc OAuth (tรนy chแปn)", + "oauthPathDescription": "ฤฦฐแปng dแบซn ฤ‘แบฟn tแป‡p thรดng tin xรกc thแปฑc OAuth. ฤแปƒ trแป‘ng ฤ‘แปƒ sแปญ dแปฅng vแป‹ trรญ mแบทc ฤ‘แป‹nh (~/.gemini/oauth_creds.json).", + "instructions": "Nแบฟu bแบกn chฦฐa xรกc thแปฑc, vui lรฒng chแบกy", + "instructionsContinued": "trong terminal cแปงa bแบกn trฦฐแป›c.", + "setupLink": "Hฦฐแป›ng dแบซn Thiแบฟt lแบญp Gemini CLI", + "requirementsTitle": "Yรชu cแบงu Quan trแปng", + "requirement1": "Trฦฐแป›c tiรชn, bแบกn cแบงn cร i ฤ‘แบทt cรดng cแปฅ Gemini CLI", + "requirement2": "Sau ฤ‘รณ, chแบกy gemini trong terminal cแปงa bแบกn vร  ฤ‘แบฃm bแบฃo bแบกn ฤ‘ฤƒng nhแบญp bแบฑng Google", + "requirement3": "Chแป‰ hoแบกt ฤ‘แป™ng vแป›i tร i khoแบฃn Google cรก nhรขn (khรดng phแบฃi tร i khoแบฃn Google Workspace)", + "requirement4": "Khรดng sแปญ dแปฅng khรณa API - xรกc thแปฑc ฤ‘ฦฐแปฃc xแปญ lรฝ qua OAuth", + "requirement5": "Yรชu cแบงu cรดng cแปฅ Gemini CLI ฤ‘ฦฐแปฃc cร i ฤ‘แบทt vร  xรกc thแปฑc trฦฐแป›c", + "freeAccess": "Truy cแบญp miแป…n phรญ qua xรกc thแปฑc OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 80bcab26eb..f2e80cee7f 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Claude Code ่ทฏๅพ„", "description": "ๆ‚จ็š„ Claude Code CLI ็š„ๅฏ้€‰่ทฏๅพ„ใ€‚ๅฆ‚ๆžœๆœช่ฎพ็ฝฎ๏ผŒๅˆ™้ป˜่ฎคไธบ โ€œclaudeโ€ใ€‚", "placeholder": "้ป˜่ฎค๏ผšclaude" + }, + "geminiCli": { + "description": "ๆญคๆไพ›ๅ•†ไฝฟ็”จ Gemini CLI ๅทฅๅ…ท็š„ OAuth ่บซไปฝ้ชŒ่ฏ๏ผŒไธ้œ€่ฆ API ๅฏ†้’ฅใ€‚", + "oauthPath": "OAuth ๅ‡ญๆฎ่ทฏๅพ„๏ผˆๅฏ้€‰๏ผ‰", + "oauthPathDescription": "OAuth ๅ‡ญๆฎๆ–‡ไปถ็š„่ทฏๅพ„ใ€‚็•™็ฉบไปฅไฝฟ็”จ้ป˜่ฎคไฝ็ฝฎ๏ผˆ~/.gemini/oauth_creds.json๏ผ‰ใ€‚", + "instructions": "ๅฆ‚ๆžœๆ‚จๅฐšๆœช่ฟ›่กŒ่บซไปฝ้ชŒ่ฏ๏ผŒ่ฏทๅ…ˆ่ฟ่กŒ", + "instructionsContinued": "ๅœจๆ‚จ็š„็ปˆ็ซฏไธญใ€‚", + "setupLink": "Gemini CLI ่ฎพ็ฝฎ่ฏดๆ˜Ž", + "requirementsTitle": "้‡่ฆ่ฆๆฑ‚", + "requirement1": "้ฆ–ๅ…ˆ๏ผŒๆ‚จ้œ€่ฆๅฎ‰่ฃ… Gemini CLI ๅทฅๅ…ท", + "requirement2": "็„ถๅŽ๏ผŒๅœจ็ปˆ็ซฏไธญ่ฟ่กŒ gemini ๅนถ็กฎไฟไฝฟ็”จ Google ็™ปๅฝ•", + "requirement3": "ไป…้€‚็”จไบŽไธชไบบ Google ่ดฆๆˆท๏ผˆไธๆ”ฏๆŒ Google Workspace ่ดฆๆˆท๏ผ‰", + "requirement4": "ไธไฝฟ็”จ API ๅฏ†้’ฅ - ่บซไปฝ้ชŒ่ฏ้€š่ฟ‡ OAuth ๅค„็†", + "requirement5": "้œ€่ฆๅ…ˆๅฎ‰่ฃ…ๅนถ้ชŒ่ฏ Gemini CLI ๅทฅๅ…ท", + "freeAccess": "้€š่ฟ‡ OAuth ่บซไปฝ้ชŒ่ฏๅ…่ดน่ฎฟ้—ฎ" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 033230ebb4..874fbe7a37 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -308,6 +308,21 @@ "pathLabel": "Claude Code ่ทฏๅพ‘", "description": "ๅฏ้ธ็š„ Claude Code CLI ่ทฏๅพ‘ใ€‚ๅฆ‚ๆžœๆœช่จญๅฎš๏ผŒๅ‰‡้ ่จญ็‚บ 'claude'ใ€‚", "placeholder": "้ ่จญ๏ผšclaude" + }, + "geminiCli": { + "description": "ๆญคๆไพ›ๅ•†ไฝฟ็”จ Gemini CLI ๅทฅๅ…ท็š„ OAuth ่บซไปฝ้ฉ—่ญ‰๏ผŒไธ้œ€่ฆ API ้‡‘้‘ฐใ€‚", + "oauthPath": "OAuth ๆ†‘่ญ‰่ทฏๅพ‘๏ผˆๅฏ้ธ๏ผ‰", + "oauthPathDescription": "OAuth ๆ†‘่ญ‰ๆช”ๆกˆ็š„่ทฏๅพ‘ใ€‚็•™็ฉบไปฅไฝฟ็”จ้ ่จญไฝ็ฝฎ๏ผˆ~/.gemini/oauth_creds.json๏ผ‰ใ€‚", + "instructions": "ๅฆ‚ๆžœๆ‚จๅฐšๆœช้€ฒ่กŒ่บซไปฝ้ฉ—่ญ‰๏ผŒ่ซ‹ๅ…ˆๅŸท่กŒ", + "instructionsContinued": "ๅœจๆ‚จ็š„็ต‚็ซฏๆฉŸไธญใ€‚", + "setupLink": "Gemini CLI ่จญๅฎš่ชชๆ˜Ž", + "requirementsTitle": "้‡่ฆ่ฆๆฑ‚", + "requirement1": "้ฆ–ๅ…ˆ๏ผŒๆ‚จ้œ€่ฆๅฎ‰่ฃ Gemini CLI ๅทฅๅ…ท", + "requirement2": "็„ถๅพŒ๏ผŒๅœจ็ต‚็ซฏๆฉŸไธญๅŸท่กŒ gemini ไธฆ็ขบไฟไฝฟ็”จ Google ็™ปๅ…ฅ", + "requirement3": "ๅƒ…้ฉ็”จๆ–ผๅ€‹ไบบ Google ๅธณๆˆถ๏ผˆไธๆ”ฏๆด Google Workspace ๅธณๆˆถ๏ผ‰", + "requirement4": "ไธไฝฟ็”จ API ้‡‘้‘ฐ - ่บซไปฝ้ฉ—่ญ‰้€้Ž OAuth ่™•็†", + "requirement5": "้œ€่ฆๅ…ˆๅฎ‰่ฃไธฆ้ฉ—่ญ‰ Gemini CLI ๅทฅๅ…ท", + "freeAccess": "้€้Ž OAuth ่บซไปฝ้ฉ—่ญ‰ๅ…่ฒปๅญ˜ๅ–" } }, "browser": { diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index 1040b60c2d..d902195d5c 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -72,6 +72,9 @@ function validateModelsAndKeysProvided(apiConfiguration: ProviderSettings): stri return i18next.t("settings:validation.apiKey") } break + case "gemini-cli": + // OAuth-based provider, no API key validation needed + break case "openai-native": if (!apiConfiguration.openAiNativeApiKey) { return i18next.t("settings:validation.apiKey") From 2f52058def8416d508c69c07e54cd7310f04e357 Mon Sep 17 00:00:00 2001 From: roomote Date: Thu, 26 Jun 2025 17:16:00 -0700 Subject: [PATCH 05/70] chore: add changeset for v3.22.1 patch release (#5164) Co-authored-by: Matt Rubens --- .changeset/v3.22.1.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/v3.22.1.md diff --git a/.changeset/v3.22.1.md b/.changeset/v3.22.1.md new file mode 100644 index 0000000000..4cdcfed8cd --- /dev/null +++ b/.changeset/v3.22.1.md @@ -0,0 +1,9 @@ +--- +"roo-cline": patch +--- + +- Add Gemini CLI provider for free access to Gemini models (thanks Cline!) +- Fix undefined mcp command (thanks @qdaxb!) +- Use upstream_inference_cost for OpenRouter BYOK cost calculation and show cached token count (thanks @chrarnoldus!) +- Update maxTokens value for qwen/qwen3-32b model on Groq (thanks @KanTakahiro!) +- Standardize tooltip delays to 300ms From 43357967f000e171b37c514dbda35ae4b334369c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 20:19:18 -0400 Subject: [PATCH 06/70] Changeset version bump (#5166) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Matt Rubens --- .changeset/v3.22.1.md | 9 --------- CHANGELOG.md | 8 ++++++++ src/package.json | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 .changeset/v3.22.1.md diff --git a/.changeset/v3.22.1.md b/.changeset/v3.22.1.md deleted file mode 100644 index 4cdcfed8cd..0000000000 --- a/.changeset/v3.22.1.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"roo-cline": patch ---- - -- Add Gemini CLI provider for free access to Gemini models (thanks Cline!) -- Fix undefined mcp command (thanks @qdaxb!) -- Use upstream_inference_cost for OpenRouter BYOK cost calculation and show cached token count (thanks @chrarnoldus!) -- Update maxTokens value for qwen/qwen3-32b model on Groq (thanks @KanTakahiro!) -- Standardize tooltip delays to 300ms diff --git a/CHANGELOG.md b/CHANGELOG.md index 6099da527f..56555351bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Roo Code Changelog +## [3.22.1] - 2025-06-26 + +- Add Gemini CLI provider (thanks Cline!) +- Fix undefined mcp command (thanks @qdaxb!) +- Use upstream_inference_cost for OpenRouter BYOK cost calculation and show cached token count (thanks @chrarnoldus!) +- Update maxTokens value for qwen/qwen3-32b model on Groq (thanks @KanTakahiro!) +- Standardize tooltip delays to 300ms + ## [3.22.0] - 2025-06-25 - Add 1-click task sharing diff --git a/src/package.json b/src/package.json index df40fe3586..40e40ac914 100644 --- a/src/package.json +++ b/src/package.json @@ -3,7 +3,7 @@ "displayName": "%extension.displayName%", "description": "%extension.description%", "publisher": "RooVeterinaryInc", - "version": "3.22.0", + "version": "3.22.1", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 9bf31d3ff7103bdf009e7337f5ac1ec5a1da31c0 Mon Sep 17 00:00:00 2001 From: Murilo Pires <50873657+MuriloFP@users.noreply.github.com> Date: Thu, 26 Jun 2025 21:34:14 -0300 Subject: [PATCH 07/70] fix terminal keyboard shortcut error when adding content to context (#5161) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Fix terminal keyboard shortcut error when adding content to context **Fixes:** [#2276](https://github.com/RooCodeInc/Roo-Code/issues/2276) **Problem:** - Using keyboard shortcuts to add terminal content to context threw error: "Cannot read properties of undefined (reading 'selection')" - Context menu worked correctly, but keyboard shortcuts failed **Root Cause:** - Command handler accessed `args.selection` without null checking - When triggered via keyboard shortcut, VS Code passes `undefined` for `args` parameter - When triggered via context menu, VS Code passes an object with `selection` property **Solution:** - Changed `args.selection` to `args?.selection` using optional chaining - Maintains existing fallback behavior when no selection is available - Preserves backward compatibility with context menu functionality **Files Modified:** - `src/activate/registerTerminalActions.ts` - Added null safety for args parameter **Testing:** - โœ… Keyboard shortcuts now work without errors - โœ… Context menu functionality preserved - โœ… Fallback to `Terminal.getTerminalContents()` works in both scenarios --- src/activate/registerTerminalActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/activate/registerTerminalActions.ts b/src/activate/registerTerminalActions.ts index eb494d66da..9773d01d38 100644 --- a/src/activate/registerTerminalActions.ts +++ b/src/activate/registerTerminalActions.ts @@ -20,7 +20,7 @@ const registerTerminalAction = ( ) => { context.subscriptions.push( vscode.commands.registerCommand(getTerminalCommand(command), async (args: any) => { - let content = args.selection + let content = args?.selection if (!content || content === "") { content = await Terminal.getTerminalContents(promptType === "TERMINAL_ADD_TO_CONTEXT" ? -1 : 1) From 426518bccdb0bd900e5f00470606bff79ca0cca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Fri, 27 Jun 2025 11:20:38 -0300 Subject: [PATCH 08/70] Code Index (Qdrant) recreate services when change configurations (#5152) --- .../code-index/__tests__/manager.spec.ts | 4 +- src/services/code-index/manager.ts | 109 ++++++++++-------- 2 files changed, 62 insertions(+), 51 deletions(-) diff --git a/src/services/code-index/__tests__/manager.spec.ts b/src/services/code-index/__tests__/manager.spec.ts index 12583291eb..2aaeb1d374 100644 --- a/src/services/code-index/__tests__/manager.spec.ts +++ b/src/services/code-index/__tests__/manager.spec.ts @@ -89,7 +89,7 @@ describe("CodeIndexManager - handleExternalSettingsChange regression", () => { expect(manager.isInitialized).toBe(true) // Mock the methods that would be called during restart - const stopWatcherSpy = vitest.spyOn(manager, "stopWatcher").mockImplementation(() => {}) + const recreateServicesSpy = vitest.spyOn(manager as any, "_recreateServices").mockImplementation(() => {}) const startIndexingSpy = vitest.spyOn(manager, "startIndexing").mockResolvedValue() // Mock the feature state @@ -100,7 +100,7 @@ describe("CodeIndexManager - handleExternalSettingsChange regression", () => { // Verify that the restart sequence was called expect(mockConfigManager.loadConfiguration).toHaveBeenCalled() - expect(stopWatcherSpy).toHaveBeenCalled() + expect(recreateServicesSpy).toHaveBeenCalled() expect(startIndexingSpy).toHaveBeenCalled() }) diff --git a/src/services/code-index/manager.ts b/src/services/code-index/manager.ts index 465fa95d0c..735bcee670 100644 --- a/src/services/code-index/manager.ts +++ b/src/services/code-index/manager.ts @@ -123,54 +123,7 @@ export class CodeIndexManager { const needsServiceRecreation = !this._serviceFactory || requiresRestart if (needsServiceRecreation) { - // Stop watcher if it exists - if (this._orchestrator) { - this.stopWatcher() - } - - // (Re)Initialize service factory - this._serviceFactory = new CodeIndexServiceFactory( - this._configManager, - this.workspacePath, - this._cacheManager, - ) - - const ignoreInstance = ignore() - const ignorePath = path.join(getWorkspacePath(), ".gitignore") - try { - const content = await fs.readFile(ignorePath, "utf8") - ignoreInstance.add(content) - ignoreInstance.add(".gitignore") - } catch (error) { - // Should never happen: reading file failed even though it exists - console.error("Unexpected error loading .gitignore:", error) - } - - // (Re)Create shared service instances - const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices( - this.context, - this._cacheManager, - ignoreInstance, - ) - - // (Re)Initialize orchestrator - this._orchestrator = new CodeIndexOrchestrator( - this._configManager, - this._stateManager, - this.workspacePath, - this._cacheManager, - vectorStore, - scanner, - fileWatcher, - ) - - // (Re)Initialize search service - this._searchService = new CodeIndexSearchService( - this._configManager, - this._stateManager, - embedder, - vectorStore, - ) + await this._recreateServices() } // 5. Handle Indexing Start/Restart @@ -248,6 +201,61 @@ export class CodeIndexManager { return this._searchService!.searchIndex(query, directoryPrefix) } + /** + * Private helper method to recreate services with current configuration. + * Used by both initialize() and handleExternalSettingsChange(). + */ + private async _recreateServices(): Promise { + // Stop watcher if it exists + if (this._orchestrator) { + this.stopWatcher() + } + + // (Re)Initialize service factory + this._serviceFactory = new CodeIndexServiceFactory( + this._configManager!, + this.workspacePath, + this._cacheManager!, + ) + + const ignoreInstance = ignore() + const ignorePath = path.join(getWorkspacePath(), ".gitignore") + try { + const content = await fs.readFile(ignorePath, "utf8") + ignoreInstance.add(content) + ignoreInstance.add(".gitignore") + } catch (error) { + // Should never happen: reading file failed even though it exists + console.error("Unexpected error loading .gitignore:", error) + } + + // (Re)Create shared service instances + const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices( + this.context, + this._cacheManager!, + ignoreInstance, + ) + + // (Re)Initialize orchestrator + this._orchestrator = new CodeIndexOrchestrator( + this._configManager!, + this._stateManager, + this.workspacePath, + this._cacheManager!, + vectorStore, + scanner, + fileWatcher, + ) + + // (Re)Initialize search service + this._searchService = new CodeIndexSearchService( + this._configManager!, + this._stateManager, + embedder, + vectorStore, + ) + } + /** * Handles external settings changes by reloading configuration. * This method should be called when API provider settings are updated @@ -263,7 +271,10 @@ export class CodeIndexManager { // If configuration changes require a restart and the manager is initialized, restart the service if (requiresRestart && isFeatureEnabled && isFeatureConfigured && this.isInitialized) { - this.stopWatcher() + // Recreate services with new configuration + await this._recreateServices() + + // Start indexing with new services await this.startIndexing() } } From c58b9638c5eb546a226a060d48d8fb53ee27c51a Mon Sep 17 00:00:00 2001 From: KJ7LNW <93454819+KJ7LNW@users.noreply.github.com> Date: Fri, 27 Jun 2025 07:20:59 -0700 Subject: [PATCH 09/70] fix: eliminate XSS vulnerability in CodeBlock component (#5157) Co-authored-by: Eric Wheeler Co-authored-by: Daniel Riccio --- pnpm-lock.yaml | 3 ++ webview-ui/package.json | 1 + .../src/components/common/CodeBlock.tsx | 40 +++++++++++++++---- .../common/__tests__/CodeBlock.spec.tsx | 37 +++++++++++++++++ 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e6406db240..5030055fea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -958,6 +958,9 @@ importers: fzf: specifier: ^0.5.2 version: 0.5.2 + hast-util-to-jsx-runtime: + specifier: ^2.3.6 + version: 2.3.6 i18next: specifier: ^25.0.0 version: 25.2.1(typescript@5.8.3) diff --git a/webview-ui/package.json b/webview-ui/package.json index 4d5e5cc821..4c6edc7a2b 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -42,6 +42,7 @@ "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", "fzf": "^0.5.2", + "hast-util-to-jsx-runtime": "^2.3.6", "i18next": "^25.0.0", "i18next-http-backend": "^3.0.2", "katex": "^0.16.11", diff --git a/webview-ui/src/components/common/CodeBlock.tsx b/webview-ui/src/components/common/CodeBlock.tsx index 2cf8fcc82e..28492acd8b 100644 --- a/webview-ui/src/components/common/CodeBlock.tsx +++ b/webview-ui/src/components/common/CodeBlock.tsx @@ -4,6 +4,8 @@ import { useCopyToClipboard } from "@src/utils/clipboard" import { getHighlighter, isLanguageLoaded, normalizeLanguage, ExtendedLanguage } from "@src/utils/highlighter" import { bundledLanguages } from "shiki" import type { ShikiTransformer } from "shiki" +import { toJsxRuntime } from "hast-util-to-jsx-runtime" +import { Fragment, jsx, jsxs } from "react/jsx-runtime" import { ChevronDown, ChevronUp, WrapText, AlignJustify, Copy, Check } from "lucide-react" import { useAppTranslation } from "@src/i18n/TranslationContext" import { StandardTooltip } from "@/components/ui" @@ -226,7 +228,7 @@ const CodeBlock = memo( const [windowShade, setWindowShade] = useState(initialWindowShade) const [currentLanguage, setCurrentLanguage] = useState(() => normalizeLanguage(language)) const userChangedLanguageRef = useRef(false) - const [highlightedCode, setHighlightedCode] = useState("") + const [highlightedCode, setHighlightedCode] = useState(null) const [showCollapseButton, setShowCollapseButton] = useState(true) const codeBlockRef = useRef(null) const preRef = useRef(null) @@ -253,7 +255,12 @@ const CodeBlock = memo( // Set mounted state at the beginning of this effect isMountedRef.current = true - const fallback = `
${source || ""}
` + // Create a safe fallback using React elements instead of HTML string + const fallback = ( +
+					{source || ""}
+				
+ ) const highlight = async () => { // Show plain text if language needs to be loaded. @@ -266,7 +273,7 @@ const CodeBlock = memo( const highlighter = await getHighlighter(currentLanguage) if (!isMountedRef.current) return - const html = await highlighter.codeToHtml(source || "", { + const hast = await highlighter.codeToHast(source || "", { lang: currentLanguage || "txt", theme: document.body.className.toLowerCase().includes("light") ? "github-light" : "github-dark", transformers: [ @@ -290,8 +297,25 @@ const CodeBlock = memo( }) if (!isMountedRef.current) return - if (isMountedRef.current) { - setHighlightedCode(html) + // Convert HAST to React elements using hast-util-to-jsx-runtime + // This approach eliminates XSS vulnerabilities by avoiding dangerouslySetInnerHTML + // while maintaining the exact same visual output and syntax highlighting + try { + const reactElement = toJsxRuntime(hast, { + Fragment, + jsx, + jsxs, + // Don't override components - let them render as-is to maintain exact output + }) + + if (isMountedRef.current) { + setHighlightedCode(reactElement) + } + } catch (error) { + console.error("[CodeBlock] Error converting HAST to JSX:", error) + if (isMountedRef.current) { + setHighlightedCode(fallback) + } } } @@ -783,7 +807,7 @@ const CodeBlock = memo( ) // Memoized content component to prevent unnecessary re-renders of highlighted code -const MemoizedCodeContent = memo(({ html }: { html: string }) =>
) +const MemoizedCodeContent = memo(({ children }: { children: React.ReactNode }) => <>{children}) // Memoized StyledPre component const MemoizedStyledPre = memo( @@ -801,7 +825,7 @@ const MemoizedStyledPre = memo( wordWrap: boolean windowShade: boolean collapsedHeight?: number - highlightedCode: string + highlightedCode: React.ReactNode updateCodeBlockButtonPosition: (forceHide?: boolean) => void }) => ( updateCodeBlockButtonPosition(true)} onMouseUp={() => updateCodeBlockButtonPosition(false)}> - + {highlightedCode} ), ) diff --git a/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx b/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx index f5278d5cdf..f413745b61 100644 --- a/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx +++ b/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx @@ -37,6 +37,43 @@ vi.mock("../../../utils/highlighter", () => { const theme = options.theme === "github-light" ? "light" : "dark" return `
${code} [${theme}-theme]
` }), + codeToHast: vi.fn().mockImplementation((code, options) => { + const theme = options.theme === "github-light" ? "light" : "dark" + // Return a comprehensive HAST node structure that matches Shiki's output + // Apply transformers if provided + const preNode = { + type: "element", + tagName: "pre", + properties: {}, + children: [ + { + type: "element", + tagName: "code", + properties: { className: [`hljs`, `language-${options.lang}`] }, + children: [ + { + type: "text", + value: `${code} [${theme}-theme]`, + }, + ], + }, + ], + } + + // Apply transformers if they exist + if (options.transformers) { + for (const transformer of options.transformers) { + if (transformer.pre) { + transformer.pre(preNode) + } + if (transformer.code && preNode.children[0]) { + transformer.code(preNode.children[0]) + } + } + } + + return preNode + }), } return { From b0190387ce12998e7365411fc680e4dd14a8b274 Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 27 Jun 2025 10:22:32 -0500 Subject: [PATCH 10/70] Fix checkpoint popover not opening due to StandardTooltip wrapper conflict (#5192) --- .../src/components/chat/checkpoints/CheckpointMenu.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx b/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx index 6b632a4548..21b4f486c7 100644 --- a/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx +++ b/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx @@ -61,13 +61,13 @@ export const CheckpointMenu = ({ ts, commitHash, currentHash, checkpoint }: Chec setIsOpen(open) setIsConfirming(false) }}> - - + + - - + +
{!isCurrent && ( From 0ddd21e8fbcbe11590022386aa5c4e09df00cfa3 Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 27 Jun 2025 11:23:21 -0500 Subject: [PATCH 11/70] fix(i18n): correct gemini cli error translation paths (#5194) --- src/i18n/locales/ca/common.json | 20 ++++++++++---------- src/i18n/locales/de/common.json | 20 ++++++++++---------- src/i18n/locales/en/common.json | 20 ++++++++++---------- src/i18n/locales/es/common.json | 20 ++++++++++---------- src/i18n/locales/fr/common.json | 20 ++++++++++---------- src/i18n/locales/hi/common.json | 20 ++++++++++---------- src/i18n/locales/id/common.json | 20 ++++++++++---------- src/i18n/locales/it/common.json | 20 ++++++++++---------- src/i18n/locales/ja/common.json | 20 ++++++++++---------- src/i18n/locales/ko/common.json | 20 ++++++++++---------- src/i18n/locales/nl/common.json | 20 ++++++++++---------- src/i18n/locales/pl/common.json | 20 ++++++++++---------- src/i18n/locales/pt-BR/common.json | 20 ++++++++++---------- src/i18n/locales/ru/common.json | 20 ++++++++++---------- src/i18n/locales/tr/common.json | 20 ++++++++++---------- src/i18n/locales/vi/common.json | 20 ++++++++++---------- src/i18n/locales/zh-CN/common.json | 20 ++++++++++---------- src/i18n/locales/zh-TW/common.json | 20 ++++++++++---------- 18 files changed, 180 insertions(+), 180 deletions(-) diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json index f23ee831aa..eb90a77179 100644 --- a/src/i18n/locales/ca/common.json +++ b/src/i18n/locales/ca/common.json @@ -73,6 +73,16 @@ "processExitedWithError": "El procรฉs Claude Code ha sortit amb codi {{exitCode}}. Sortida d'error: {{output}}", "stoppedWithReason": "Claude Code s'ha aturat per la raรณ: {{reason}}", "apiKeyModelPlanMismatch": "Les claus API i els plans de subscripciรณ permeten models diferents. Assegura't que el model seleccionat estigui inclรฒs al teu pla." + }, + "geminiCli": { + "oauthLoadFailed": "No s'han pogut carregar les credencials OAuth. Si us plau, autentica't primer: {{error}}", + "tokenRefreshFailed": "No s'ha pogut actualitzar el token OAuth: {{error}}", + "onboardingTimeout": "L'operaciรณ d'onboarding ha esgotat el temps desprรฉs de 60 segons. Si us plau, torna-ho a provar mรฉs tard.", + "projectDiscoveryFailed": "No s'ha pogut descobrir l'ID del projecte. Assegura't d'estar autenticat amb 'gemini auth'.", + "rateLimitExceeded": "S'ha superat el lรญmit de velocitat. S'han assolit els lรญmits del nivell gratuรฏt.", + "badRequest": "Solยทlicitud incorrecta: {{details}}", + "apiError": "Error de l'API Gemini CLI: {{error}}", + "completionError": "Error de compleciรณ de Gemini CLI: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "La teva organitzaciรณ requereix autenticaciรณ de Roo Code Cloud. Si us plau, inicia sessiรณ per continuar.", "organization_mismatch": "Has d'estar autenticat amb el compte de Roo Code Cloud de la teva organitzaciรณ.", "verification_failed": "No s'ha pogut verificar l'autenticaciรณ de l'organitzaciรณ." - }, - "geminiCli": { - "oauthLoadFailed": "No s'han pogut carregar les credencials OAuth. Si us plau, autentica't primer: {{error}}", - "tokenRefreshFailed": "No s'ha pogut actualitzar el token OAuth: {{error}}", - "onboardingTimeout": "L'operaciรณ d'onboarding ha esgotat el temps desprรฉs de 60 segons. Si us plau, torna-ho a provar mรฉs tard.", - "projectDiscoveryFailed": "No s'ha pogut descobrir l'ID del projecte. Assegura't d'estar autenticat amb 'gemini auth'.", - "rateLimitExceeded": "S'ha superat el lรญmit de velocitat. S'han assolit els lรญmits del nivell gratuรฏt.", - "badRequest": "Solยทlicitud incorrecta: {{details}}", - "apiError": "Error de l'API Gemini CLI: {{error}}", - "completionError": "Error de compleciรณ de Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json index a09813d284..48e34db479 100644 --- a/src/i18n/locales/de/common.json +++ b/src/i18n/locales/de/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Claude Code Prozess wurde mit Code {{exitCode}} beendet. Fehlerausgabe: {{output}}", "stoppedWithReason": "Claude Code wurde mit Grund gestoppt: {{reason}}", "apiKeyModelPlanMismatch": "API-Schlรผssel und Abonnement-Plรคne erlauben verschiedene Modelle. Stelle sicher, dass das ausgewรคhlte Modell in deinem Plan enthalten ist." + }, + "geminiCli": { + "oauthLoadFailed": "Fehler beim Laden der OAuth-Anmeldedaten. Bitte authentifiziere dich zuerst: {{error}}", + "tokenRefreshFailed": "Fehler beim Aktualisieren des OAuth-Tokens: {{error}}", + "onboardingTimeout": "Onboarding-Vorgang nach 60 Sekunden abgebrochen. Bitte versuche es spรคter erneut.", + "projectDiscoveryFailed": "Projekt-ID konnte nicht ermittelt werden. Stelle sicher, dass du mit 'gemini auth' authentifiziert bist.", + "rateLimitExceeded": "Anfragenlimit รผberschritten. Die Limits des kostenlosen Tarifs wurden erreicht.", + "badRequest": "Ungรผltige Anfrage: {{details}}", + "apiError": "Gemini CLI API-Fehler: {{error}}", + "completionError": "Gemini CLI Vervollstรคndigungsfehler: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "Deine Organisation erfordert eine Roo Code Cloud-Authentifizierung. Bitte melde dich an, um fortzufahren.", "organization_mismatch": "Du musst mit dem Roo Code Cloud-Konto deiner Organisation authentifiziert sein.", "verification_failed": "Die Organisationsauthentifizierung konnte nicht verifiziert werden." - }, - "geminiCli": { - "oauthLoadFailed": "Fehler beim Laden der OAuth-Anmeldedaten. Bitte authentifiziere dich zuerst: {{error}}", - "tokenRefreshFailed": "Fehler beim Aktualisieren des OAuth-Tokens: {{error}}", - "onboardingTimeout": "Onboarding-Vorgang nach 60 Sekunden abgebrochen. Bitte versuche es spรคter erneut.", - "projectDiscoveryFailed": "Projekt-ID konnte nicht ermittelt werden. Stelle sicher, dass du mit 'gemini auth' authentifiziert bist.", - "rateLimitExceeded": "Anfragenlimit รผberschritten. Die Limits des kostenlosen Tarifs wurden erreicht.", - "badRequest": "Ungรผltige Anfrage: {{details}}", - "apiError": "Gemini CLI API-Fehler: {{error}}", - "completionError": "Gemini CLI Vervollstรคndigungsfehler: {{error}}" } } } diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index b8b370d132..855a69c23b 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Claude Code process exited with code {{exitCode}}. Error output: {{output}}", "stoppedWithReason": "Claude Code stopped with reason: {{reason}}", "apiKeyModelPlanMismatch": "API keys and subscription plans allow different models. Make sure the selected model is included in your plan." + }, + "geminiCli": { + "oauthLoadFailed": "Failed to load OAuth credentials. Please authenticate first: {{error}}", + "tokenRefreshFailed": "Failed to refresh OAuth token: {{error}}", + "onboardingTimeout": "Onboarding operation timed out after 60 seconds. Please try again later.", + "projectDiscoveryFailed": "Could not discover project ID. Make sure you're authenticated with 'gemini auth'.", + "rateLimitExceeded": "Rate limit exceeded. Free tier limits have been reached.", + "badRequest": "Bad request: {{details}}", + "apiError": "Gemini CLI API error: {{error}}", + "completionError": "Gemini CLI completion error: {{error}}" } }, "warnings": { @@ -128,16 +138,6 @@ "cloud_auth_required": "Your organization requires Roo Code Cloud authentication. Please sign in to continue.", "organization_mismatch": "You must be authenticated with your organization's Roo Code Cloud account.", "verification_failed": "Unable to verify organization authentication." - }, - "geminiCli": { - "oauthLoadFailed": "Failed to load OAuth credentials. Please authenticate first: {{error}}", - "tokenRefreshFailed": "Failed to refresh OAuth token: {{error}}", - "onboardingTimeout": "Onboarding operation timed out after 60 seconds. Please try again later.", - "projectDiscoveryFailed": "Could not discover project ID. Make sure you're authenticated with 'gemini auth'.", - "rateLimitExceeded": "Rate limit exceeded. Free tier limits have been reached.", - "badRequest": "Bad request: {{details}}", - "apiError": "Gemini CLI API error: {{error}}", - "completionError": "Gemini CLI completion error: {{error}}" } } } diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json index 090faffad1..0de842ee44 100644 --- a/src/i18n/locales/es/common.json +++ b/src/i18n/locales/es/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "El proceso de Claude Code terminรณ con cรณdigo {{exitCode}}. Salida de error: {{output}}", "stoppedWithReason": "Claude Code se detuvo por la razรณn: {{reason}}", "apiKeyModelPlanMismatch": "Las claves API y los planes de suscripciรณn permiten diferentes modelos. Asegรบrate de que el modelo seleccionado estรฉ incluido en tu plan." + }, + "geminiCli": { + "oauthLoadFailed": "Error al cargar credenciales OAuth. Por favor autentรญcate primero: {{error}}", + "tokenRefreshFailed": "Error al actualizar token OAuth: {{error}}", + "onboardingTimeout": "La operaciรณn de incorporaciรณn expirรณ despuรฉs de 60 segundos. Intรฉntalo de nuevo mรกs tarde.", + "projectDiscoveryFailed": "No se pudo descubrir el ID del proyecto. Asegรบrate de estar autenticado con 'gemini auth'.", + "rateLimitExceeded": "Lรญmite de velocidad excedido. Se han alcanzado los lรญmites del nivel gratuito.", + "badRequest": "Solicitud incorrecta: {{details}}", + "apiError": "Error de API de Gemini CLI: {{error}}", + "completionError": "Error de completado de Gemini CLI: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "Tu organizaciรณn requiere autenticaciรณn de Roo Code Cloud. Por favor, inicia sesiรณn para continuar.", "organization_mismatch": "Debes estar autenticado con la cuenta de Roo Code Cloud de tu organizaciรณn.", "verification_failed": "No se pudo verificar la autenticaciรณn de la organizaciรณn." - }, - "geminiCli": { - "oauthLoadFailed": "Error al cargar credenciales OAuth. Por favor autentรญcate primero: {{error}}", - "tokenRefreshFailed": "Error al actualizar token OAuth: {{error}}", - "onboardingTimeout": "La operaciรณn de incorporaciรณn expirรณ despuรฉs de 60 segundos. Intรฉntalo de nuevo mรกs tarde.", - "projectDiscoveryFailed": "No se pudo descubrir el ID del proyecto. Asegรบrate de estar autenticado con 'gemini auth'.", - "rateLimitExceeded": "Lรญmite de velocidad excedido. Se han alcanzado los lรญmites del nivel gratuito.", - "badRequest": "Solicitud incorrecta: {{details}}", - "apiError": "Error de API de Gemini CLI: {{error}}", - "completionError": "Error de completado de Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json index a9215a81ec..2fcef289f4 100644 --- a/src/i18n/locales/fr/common.json +++ b/src/i18n/locales/fr/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Le processus Claude Code s'est terminรฉ avec le code {{exitCode}}. Sortie d'erreur : {{output}}", "stoppedWithReason": "Claude Code s'est arrรชtรฉ pour la raison : {{reason}}", "apiKeyModelPlanMismatch": "Les clรฉs API et les plans d'abonnement permettent diffรฉrents modรจles. Assurez-vous que le modรจle sรฉlectionnรฉ est inclus dans votre plan." + }, + "geminiCli": { + "oauthLoadFailed": "ร‰chec du chargement des identifiants OAuth. Veuillez vous authentifier d'abord : {{error}}", + "tokenRefreshFailed": "ร‰chec du renouvellement du token OAuth : {{error}}", + "onboardingTimeout": "L'opรฉration d'intรฉgration a expirรฉ aprรจs 60 secondes. Veuillez rรฉessayer plus tard.", + "projectDiscoveryFailed": "Impossible de dรฉcouvrir l'ID du projet. Assurez-vous d'รชtre authentifiรฉ avec 'gemini auth'.", + "rateLimitExceeded": "Limite de dรฉbit dรฉpassรฉe. Les limites du niveau gratuit ont รฉtรฉ atteintes.", + "badRequest": "Requรชte incorrecte : {{details}}", + "apiError": "Erreur API Gemini CLI : {{error}}", + "completionError": "Erreur de complรฉtion Gemini CLI : {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "Votre organisation nรฉcessite une authentification Roo Code Cloud. Veuillez vous connecter pour continuer.", "organization_mismatch": "Vous devez รชtre authentifiรฉ avec le compte Roo Code Cloud de votre organisation.", "verification_failed": "Impossible de vรฉrifier l'authentification de l'organisation." - }, - "geminiCli": { - "oauthLoadFailed": "ร‰chec du chargement des identifiants OAuth. Veuillez vous authentifier d'abord : {{error}}", - "tokenRefreshFailed": "ร‰chec du renouvellement du token OAuth : {{error}}", - "onboardingTimeout": "L'opรฉration d'intรฉgration a expirรฉ aprรจs 60 secondes. Veuillez rรฉessayer plus tard.", - "projectDiscoveryFailed": "Impossible de dรฉcouvrir l'ID du projet. Assurez-vous d'รชtre authentifiรฉ avec 'gemini auth'.", - "rateLimitExceeded": "Limite de dรฉbit dรฉpassรฉe. Les limites du niveau gratuit ont รฉtรฉ atteintes.", - "badRequest": "Requรชte incorrecte : {{details}}", - "apiError": "Erreur API Gemini CLI : {{error}}", - "completionError": "Erreur de complรฉtion Gemini CLI : {{error}}" } } } diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json index 65e6561835..b799cc03b7 100644 --- a/src/i18n/locales/hi/common.json +++ b/src/i18n/locales/hi/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Claude Code เคชเฅเคฐเค•เฅเคฐเคฟเคฏเคพ เค•เฅ‹เคก {{exitCode}} เค•เฅ‡ เคธเคพเคฅ เคธเคฎเคพเคชเฅเคค เคนเฅเคˆเฅค เคคเฅเคฐเฅเคŸเคฟ เค†เค‰เคŸเคชเฅเคŸ: {{output}}", "stoppedWithReason": "Claude Code เค‡เคธ เค•เคพเคฐเคฃ เคธเฅ‡ เคฐเฅเค•เคพ: {{reason}}", "apiKeyModelPlanMismatch": "API เค•เฅเค‚เคœเฅ€ เค”เคฐ เคธเคฌเฅเคธเค•เฅเคฐเคฟเคชเฅเคถเคจ เคชเฅเคฒเคพเคจ เค…เคฒเค—-เค…เคฒเค— เคฎเฅ‰เคกเคฒ เค•เฅ€ เค…เคจเฅเคฎเคคเคฟ เคฆเฅ‡เคคเฅ‡ เคนเฅˆเค‚เฅค เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เค•เคฐเฅ‡เค‚ เค•เคฟ เคšเคฏเคจเคฟเคค เคฎเฅ‰เคกเคฒ เค†เคชเค•เฅ€ เคฏเฅ‹เคœเคจเคพ เคฎเฅ‡เค‚ เคถเคพเคฎเคฟเคฒ เคนเฅˆเฅค" + }, + "geminiCli": { + "oauthLoadFailed": "OAuth เค•เฅเคฐเฅ‡เคกเฅ‡เค‚เคถเคฟเคฏเคฒ เคฒเฅ‹เคก เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒเฅค เค•เฅƒเคชเคฏเคพ เคชเคนเคฒเฅ‡ เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เคฐเฅ‡เค‚: {{error}}", + "tokenRefreshFailed": "OAuth เคŸเฅ‹เค•เคจ เคฐเฅ€เคซเฅเคฐเฅ‡เคถ เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒ: {{error}}", + "onboardingTimeout": "เค‘เคจเคฌเฅ‹เคฐเฅเคกเคฟเค‚เค— เค‘เคชเคฐเฅ‡เคถเคจ 60 เคธเฅ‡เค•เค‚เคก เคฌเคพเคฆ เคŸเคพเค‡เคฎเค†เค‰เคŸ เคนเฅ‹ เค—เคฏเคพเฅค เค•เฅƒเคชเคฏเคพ เคฌเคพเคฆ เคฎเฅ‡เค‚ เคชเฅเคจเคƒ เคชเฅเคฐเคฏเคพเคธ เค•เคฐเฅ‡เค‚เฅค", + "projectDiscoveryFailed": "เคชเฅเคฐเฅ‹เคœเฅ‡เค•เฅเคŸ ID เค–เฅ‹เคœเคจเฅ‡ เคฎเฅ‡เค‚ เค…เคธเคฎเคฐเฅเคฅเฅค เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เค•เคฐเฅ‡เค‚ เค•เคฟ เค†เคช 'gemini auth' เค•เฅ‡ เคธเคพเคฅ เคชเฅเคฐเคฎเคพเคฃเคฟเคค เคนเฅˆเค‚เฅค", + "rateLimitExceeded": "เคฆเคฐ เคธเฅ€เคฎเคพ เคชเคพเคฐ เคนเฅ‹ เค—เคˆเฅค เคฎเฅเคซเฅเคค เคŸเคฟเคฏเคฐ เค•เฅ€ เคธเฅ€เคฎเคพ เคชเคนเฅเค‚เคš เค—เคˆ เคนเฅˆเฅค", + "badRequest": "เค—เคฒเคค เค…เคจเฅเคฐเฅ‹เคง: {{details}}", + "apiError": "Gemini CLI API เคคเฅเคฐเฅเคŸเคฟ: {{error}}", + "completionError": "Gemini CLI เคชเฅ‚เคฐเฅเคฃเคคเคพ เคคเฅเคฐเฅเคŸเคฟ: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "เค†เคชเค•เฅ‡ เคธเค‚เค—เค เคจ เค•เฅ‹ Roo Code Cloud เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เคนเฅˆเฅค เค•เฅƒเคชเคฏเคพ เคœเคพเคฐเฅ€ เคฐเค–เคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เคธเคพเค‡เคจ เค‡เคจ เค•เคฐเฅ‡เค‚เฅค", "organization_mismatch": "เค†เคชเค•เฅ‹ เค…เคชเคจเฅ‡ เคธเค‚เค—เค เคจ เค•เฅ‡ Roo Code Cloud เค–เคพเคคเฅ‡ เคธเฅ‡ เคชเฅเคฐเคฎเคพเคฃเคฟเคค เคนเฅ‹เคจเคพ เคนเฅ‹เค—เคพเฅค", "verification_failed": "เคธเค‚เค—เค เคจ เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เคธเคคเฅเคฏเคพเคชเคฟเคค เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เค…เคธเคฎเคฐเฅเคฅเฅค" - }, - "geminiCli": { - "oauthLoadFailed": "OAuth เค•เฅเคฐเฅ‡เคกเฅ‡เค‚เคถเคฟเคฏเคฒ เคฒเฅ‹เคก เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒเฅค เค•เฅƒเคชเคฏเคพ เคชเคนเคฒเฅ‡ เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เคฐเฅ‡เค‚: {{error}}", - "tokenRefreshFailed": "OAuth เคŸเฅ‹เค•เคจ เคฐเฅ€เคซเฅเคฐเฅ‡เคถ เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒ: {{error}}", - "onboardingTimeout": "เค‘เคจเคฌเฅ‹เคฐเฅเคกเคฟเค‚เค— เค‘เคชเคฐเฅ‡เคถเคจ 60 เคธเฅ‡เค•เค‚เคก เคฌเคพเคฆ เคŸเคพเค‡เคฎเค†เค‰เคŸ เคนเฅ‹ เค—เคฏเคพเฅค เค•เฅƒเคชเคฏเคพ เคฌเคพเคฆ เคฎเฅ‡เค‚ เคชเฅเคจเคƒ เคชเฅเคฐเคฏเคพเคธ เค•เคฐเฅ‡เค‚เฅค", - "projectDiscoveryFailed": "เคชเฅเคฐเฅ‹เคœเฅ‡เค•เฅเคŸ ID เค–เฅ‹เคœเคจเฅ‡ เคฎเฅ‡เค‚ เค…เคธเคฎเคฐเฅเคฅเฅค เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เค•เคฐเฅ‡เค‚ เค•เคฟ เค†เคช 'gemini auth' เค•เฅ‡ เคธเคพเคฅ เคชเฅเคฐเคฎเคพเคฃเคฟเคค เคนเฅˆเค‚เฅค", - "rateLimitExceeded": "เคฆเคฐ เคธเฅ€เคฎเคพ เคชเคพเคฐ เคนเฅ‹ เค—เคˆเฅค เคฎเฅเคซเฅเคค เคŸเคฟเคฏเคฐ เค•เฅ€ เคธเฅ€เคฎเคพ เคชเคนเฅเค‚เคš เค—เคˆ เคนเฅˆเฅค", - "badRequest": "เค—เคฒเคค เค…เคจเฅเคฐเฅ‹เคง: {{details}}", - "apiError": "Gemini CLI API เคคเฅเคฐเฅเคŸเคฟ: {{error}}", - "completionError": "Gemini CLI เคชเฅ‚เคฐเฅเคฃเคคเคพ เคคเฅเคฐเฅเคŸเคฟ: {{error}}" } } } diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json index e7901d28bf..9ddd5ca2de 100644 --- a/src/i18n/locales/id/common.json +++ b/src/i18n/locales/id/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Proses Claude Code keluar dengan kode {{exitCode}}. Output error: {{output}}", "stoppedWithReason": "Claude Code berhenti karena alasan: {{reason}}", "apiKeyModelPlanMismatch": "Kunci API dan paket berlangganan memungkinkan model yang berbeda. Pastikan model yang dipilih termasuk dalam paket Anda." + }, + "geminiCli": { + "oauthLoadFailed": "Gagal memuat kredensial OAuth. Silakan autentikasi terlebih dahulu: {{error}}", + "tokenRefreshFailed": "Gagal memperbarui token OAuth: {{error}}", + "onboardingTimeout": "Operasi onboarding habis waktu setelah 60 detik. Silakan coba lagi nanti.", + "projectDiscoveryFailed": "Tidak dapat menemukan ID proyek. Pastikan Anda terautentikasi dengan 'gemini auth'.", + "rateLimitExceeded": "Batas kecepatan terlampaui. Batas tingkat gratis telah tercapai.", + "badRequest": "Permintaan tidak valid: {{details}}", + "apiError": "Kesalahan API Gemini CLI: {{error}}", + "completionError": "Kesalahan penyelesaian Gemini CLI: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "Organisasi kamu memerlukan autentikasi Roo Code Cloud. Silakan masuk untuk melanjutkan.", "organization_mismatch": "Kamu harus diautentikasi dengan akun Roo Code Cloud organisasi kamu.", "verification_failed": "Tidak dapat memverifikasi autentikasi organisasi." - }, - "geminiCli": { - "oauthLoadFailed": "Gagal memuat kredensial OAuth. Silakan autentikasi terlebih dahulu: {{error}}", - "tokenRefreshFailed": "Gagal memperbarui token OAuth: {{error}}", - "onboardingTimeout": "Operasi onboarding timeout setelah 60 detik. Silakan coba lagi nanti.", - "projectDiscoveryFailed": "Tidak dapat menemukan ID proyek. Pastikan Anda sudah terautentikasi dengan 'gemini auth'.", - "rateLimitExceeded": "Batas kecepatan terlampaui. Batas tier gratis telah tercapai.", - "badRequest": "Permintaan tidak valid: {{details}}", - "apiError": "Error API Gemini CLI: {{error}}", - "completionError": "Error penyelesaian Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json index 6329185e25..d34a14d840 100644 --- a/src/i18n/locales/it/common.json +++ b/src/i18n/locales/it/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Il processo Claude Code รจ terminato con codice {{exitCode}}. Output di errore: {{output}}", "stoppedWithReason": "Claude Code si รจ fermato per il motivo: {{reason}}", "apiKeyModelPlanMismatch": "Le chiavi API e i piani di abbonamento consentono modelli diversi. Assicurati che il modello selezionato sia incluso nel tuo piano." + }, + "geminiCli": { + "oauthLoadFailed": "Impossibile caricare le credenziali OAuth. Autenticati prima: {{error}}", + "tokenRefreshFailed": "Impossibile aggiornare il token OAuth: {{error}}", + "onboardingTimeout": "L'operazione di onboarding รจ scaduta dopo 60 secondi. Riprova piรน tardi.", + "projectDiscoveryFailed": "Impossibile scoprire l'ID del progetto. Assicurati di essere autenticato con 'gemini auth'.", + "rateLimitExceeded": "Limite di velocitร  superato. I limiti del livello gratuito sono stati raggiunti.", + "badRequest": "Richiesta non valida: {{details}}", + "apiError": "Errore API Gemini CLI: {{error}}", + "completionError": "Errore di completamento Gemini CLI: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "La tua organizzazione richiede l'autenticazione Roo Code Cloud. Accedi per continuare.", "organization_mismatch": "Devi essere autenticato con l'account Roo Code Cloud della tua organizzazione.", "verification_failed": "Impossibile verificare l'autenticazione dell'organizzazione." - }, - "geminiCli": { - "oauthLoadFailed": "Impossibile caricare le credenziali OAuth. Autenticati prima: {{error}}", - "tokenRefreshFailed": "Impossibile aggiornare il token OAuth: {{error}}", - "onboardingTimeout": "L'operazione di onboarding รจ scaduta dopo 60 secondi. Riprova piรน tardi.", - "projectDiscoveryFailed": "Impossibile scoprire l'ID del progetto. Assicurati di essere autenticato con 'gemini auth'.", - "rateLimitExceeded": "Limite di velocitร  superato. I limiti del livello gratuito sono stati raggiunti.", - "badRequest": "Richiesta non valida: {{details}}", - "apiError": "Errore API Gemini CLI: {{error}}", - "completionError": "Errore di completamento Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index 72b5f6f878..0e6afe18cf 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Claude Code ใƒ—ใƒญใ‚ปใ‚นใŒใ‚ณใƒผใƒ‰ {{exitCode}} ใง็ต‚ไบ†ใ—ใพใ—ใŸใ€‚ใ‚จใƒฉใƒผๅ‡บๅŠ›๏ผš{{output}}", "stoppedWithReason": "Claude Code ใŒ็†็”ฑใซใ‚ˆใ‚Šๅœๆญขใ—ใพใ—ใŸ๏ผš{{reason}}", "apiKeyModelPlanMismatch": "API ใ‚ญใƒผใจใ‚ตใƒ–ใ‚นใ‚ฏใƒชใƒ—ใ‚ทใƒงใƒณใƒ—ใƒฉใƒณใงใฏ็•ฐใชใ‚‹ใƒขใƒ‡ใƒซใŒๅˆฉ็”จๅฏ่ƒฝใงใ™ใ€‚้ธๆŠžใ—ใŸใƒขใƒ‡ใƒซใŒใƒ—ใƒฉใƒณใซๅซใพใ‚Œใฆใ„ใ‚‹ใ“ใจใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚" + }, + "geminiCli": { + "oauthLoadFailed": "OAuth่ช่จผๆƒ…ๅ ฑใฎ่ชญใฟ่พผใฟใซๅคฑๆ•—ใ—ใพใ—ใŸใ€‚ใพใš่ช่จผใ—ใฆใใ ใ•ใ„: {{error}}", + "tokenRefreshFailed": "OAuthใƒˆใƒผใ‚ฏใƒณใฎๆ›ดๆ–ฐใซๅคฑๆ•—ใ—ใพใ—ใŸ: {{error}}", + "onboardingTimeout": "ใ‚ชใƒณใƒœใƒผใƒ‡ใ‚ฃใƒณใ‚ฐๆ“ไฝœใŒ60็ง’ใงใ‚ฟใ‚คใƒ ใ‚ขใ‚ฆใƒˆใ—ใพใ—ใŸใ€‚ๅพŒใงใ‚‚ใ†ไธ€ๅบฆใŠ่ฉฆใ—ใใ ใ•ใ„ใ€‚", + "projectDiscoveryFailed": "ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆIDใ‚’็™บ่ฆ‹ใงใใพใ›ใ‚“ใงใ—ใŸใ€‚'gemini auth'ใง่ช่จผใ•ใ‚Œใฆใ„ใ‚‹ใ“ใจใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚", + "rateLimitExceeded": "ใƒฌใƒผใƒˆๅˆถ้™ใ‚’่ถ…้Žใ—ใพใ—ใŸใ€‚็„กๆ–™ใƒ—ใƒฉใƒณใฎๅˆถ้™ใซ้”ใ—ใฆใ„ใพใ™ใ€‚", + "badRequest": "ไธๆญฃใชใƒชใ‚ฏใ‚จใ‚นใƒˆ: {{details}}", + "apiError": "Gemini CLI APIใ‚จใƒฉใƒผ: {{error}}", + "completionError": "Gemini CLI่ฃœๅฎŒใ‚จใƒฉใƒผ: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "ใ‚ใชใŸใฎ็ต„็น”ใงใฏ Roo Code Cloud ่ช่จผใŒๅฟ…่ฆใงใ™ใ€‚็ถš่กŒใ™ใ‚‹ใซใฏใ‚ตใ‚คใƒณใ‚คใƒณใ—ใฆใใ ใ•ใ„ใ€‚", "organization_mismatch": "็ต„็น”ใฎ Roo Code Cloud ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใง่ช่จผใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚", "verification_failed": "็ต„็น”่ช่จผใฎ็ขบ่ชใŒใงใใพใ›ใ‚“ใงใ—ใŸใ€‚" - }, - "geminiCli": { - "oauthLoadFailed": "OAuth่ช่จผๆƒ…ๅ ฑใฎ่ชญใฟ่พผใฟใซๅคฑๆ•—ใ—ใพใ—ใŸใ€‚ใพใš่ช่จผใ—ใฆใใ ใ•ใ„: {{error}}", - "tokenRefreshFailed": "OAuthใƒˆใƒผใ‚ฏใƒณใฎๆ›ดๆ–ฐใซๅคฑๆ•—ใ—ใพใ—ใŸ: {{error}}", - "onboardingTimeout": "ใ‚ชใƒณใƒœใƒผใƒ‡ใ‚ฃใƒณใ‚ฐๆ“ไฝœใŒ60็ง’ใงใ‚ฟใ‚คใƒ ใ‚ขใ‚ฆใƒˆใ—ใพใ—ใŸใ€‚ๅพŒใงใ‚‚ใ†ไธ€ๅบฆใŠ่ฉฆใ—ใใ ใ•ใ„ใ€‚", - "projectDiscoveryFailed": "ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆIDใ‚’็™บ่ฆ‹ใงใใพใ›ใ‚“ใงใ—ใŸใ€‚'gemini auth'ใง่ช่จผใ•ใ‚Œใฆใ„ใ‚‹ใ“ใจใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚", - "rateLimitExceeded": "ใƒฌใƒผใƒˆๅˆถ้™ใ‚’่ถ…้Žใ—ใพใ—ใŸใ€‚็„กๆ–™ใƒ—ใƒฉใƒณใฎๅˆถ้™ใซ้”ใ—ใฆใ„ใพใ™ใ€‚", - "badRequest": "ไธๆญฃใชใƒชใ‚ฏใ‚จใ‚นใƒˆ: {{details}}", - "apiError": "Gemini CLI APIใ‚จใƒฉใƒผ: {{error}}", - "completionError": "Gemini CLI่ฃœๅฎŒใ‚จใƒฉใƒผ: {{error}}" } } } diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json index d70be5cf3d..affba735ab 100644 --- a/src/i18n/locales/ko/common.json +++ b/src/i18n/locales/ko/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Claude Code ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ฝ”๋“œ {{exitCode}}๋กœ ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ์ถœ๋ ฅ: {{output}}", "stoppedWithReason": "Claude Code๊ฐ€ ๋‹ค์Œ ์ด์œ ๋กœ ์ค‘์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค: {{reason}}", "apiKeyModelPlanMismatch": "API ํ‚ค์™€ ๊ตฌ๋… ํ”Œ๋žœ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋ธ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒํ•œ ๋ชจ๋ธ์ด ํ”Œ๋žœ์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”." + }, + "geminiCli": { + "oauthLoadFailed": "OAuth ์ž๊ฒฉ ์ฆ๋ช…์„ ๋กœ๋“œํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ธ์ฆํ•˜์„ธ์š”: {{error}}", + "tokenRefreshFailed": "OAuth ํ† ํฐ์„ ์ƒˆ๋กœ ๊ณ ์น˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค: {{error}}", + "onboardingTimeout": "์˜จ๋ณด๋”ฉ ์ž‘์—…์ด 60์ดˆ ํ›„ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋‹ค์‹œ ์‹œ๋„ํ•˜์„ธ์š”.", + "projectDiscoveryFailed": "ํ”„๋กœ์ ํŠธ ID๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. 'gemini auth'๋กœ ์ธ์ฆ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.", + "rateLimitExceeded": "์†๋„ ์ œํ•œ์„ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌด๋ฃŒ ๋“ฑ๊ธ‰ ์ œํ•œ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.", + "badRequest": "์ž˜๋ชป๋œ ์š”์ฒญ: {{details}}", + "apiError": "Gemini CLI API ์˜ค๋ฅ˜: {{error}}", + "completionError": "Gemini CLI ์™„์„ฑ ์˜ค๋ฅ˜: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "์กฐ์ง์—์„œ Roo Code Cloud ์ธ์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์†ํ•˜๋ ค๋ฉด ๋กœ๊ทธ์ธํ•˜์„ธ์š”.", "organization_mismatch": "์กฐ์ง์˜ Roo Code Cloud ๊ณ„์ •์œผ๋กœ ์ธ์ฆํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.", "verification_failed": "์กฐ์ง ์ธ์ฆ์„ ํ™•์ธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." - }, - "geminiCli": { - "oauthLoadFailed": "OAuth ์ž๊ฒฉ ์ฆ๋ช…์„ ๋กœ๋“œํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ธ์ฆํ•˜์„ธ์š”: {{error}}", - "tokenRefreshFailed": "OAuth ํ† ํฐ ์ƒˆ๋กœ ๊ณ ์นจ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค: {{error}}", - "onboardingTimeout": "์˜จ๋ณด๋”ฉ ์ž‘์—…์ด 60์ดˆ ํ›„ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋‹ค์‹œ ์‹œ๋„ํ•˜์„ธ์š”.", - "projectDiscoveryFailed": "ํ”„๋กœ์ ํŠธ ID๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. 'gemini auth'๋กœ ์ธ์ฆ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.", - "rateLimitExceeded": "์†๋„ ์ œํ•œ์„ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌด๋ฃŒ ๊ณ„์ธต ์ œํ•œ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.", - "badRequest": "์ž˜๋ชป๋œ ์š”์ฒญ: {{details}}", - "apiError": "Gemini CLI API ์˜ค๋ฅ˜: {{error}}", - "completionError": "Gemini CLI ์™„์„ฑ ์˜ค๋ฅ˜: {{error}}" } } } diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json index 70f5d42dd8..b0748a5aa6 100644 --- a/src/i18n/locales/nl/common.json +++ b/src/i18n/locales/nl/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Claude Code proces beรซindigd met code {{exitCode}}. Foutuitvoer: {{output}}", "stoppedWithReason": "Claude Code gestopt om reden: {{reason}}", "apiKeyModelPlanMismatch": "API-sleutels en abonnementsplannen staan verschillende modellen toe. Zorg ervoor dat het geselecteerde model is opgenomen in je plan." + }, + "geminiCli": { + "oauthLoadFailed": "Kan OAuth-referenties niet laden. Authenticeer eerst: {{error}}", + "tokenRefreshFailed": "Kan OAuth-token niet vernieuwen: {{error}}", + "onboardingTimeout": "Onboarding-operatie is na 60 seconden verlopen. Probeer het later opnieuw.", + "projectDiscoveryFailed": "Kan project-ID niet ontdekken. Zorg ervoor dat je geauthenticeerd bent met 'gemini auth'.", + "rateLimitExceeded": "Snelheidslimiet overschreden. Gratis tier limieten zijn bereikt.", + "badRequest": "Ongeldig verzoek: {{details}}", + "apiError": "Gemini CLI API-fout: {{error}}", + "completionError": "Gemini CLI voltooiingsfout: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "Je organisatie vereist Roo Code Cloud-authenticatie. Log in om door te gaan.", "organization_mismatch": "Je moet geauthenticeerd zijn met het Roo Code Cloud-account van je organisatie.", "verification_failed": "Kan organisatie-authenticatie niet verifiรซren." - }, - "geminiCli": { - "oauthLoadFailed": "Kan OAuth-referenties niet laden. Authenticeer eerst: {{error}}", - "tokenRefreshFailed": "Kan OAuth-token niet vernieuwen: {{error}}", - "onboardingTimeout": "Onboarding-operatie is na 60 seconden verlopen. Probeer het later opnieuw.", - "projectDiscoveryFailed": "Kan project-ID niet ontdekken. Zorg ervoor dat je geauthenticeerd bent met 'gemini auth'.", - "rateLimitExceeded": "Snelheidslimiet overschreden. Gratis tier limieten zijn bereikt.", - "badRequest": "Ongeldig verzoek: {{details}}", - "apiError": "Gemini CLI API-fout: {{error}}", - "completionError": "Gemini CLI voltooiingsfout: {{error}}" } } } diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json index 98350a70d8..b8cd29976f 100644 --- a/src/i18n/locales/pl/common.json +++ b/src/i18n/locales/pl/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Proces Claude Code zakoล„czyล‚ siฤ™ kodem {{exitCode}}. Wyjล›cie bล‚ฤ™du: {{output}}", "stoppedWithReason": "Claude Code zatrzymaล‚ siฤ™ z powodu: {{reason}}", "apiKeyModelPlanMismatch": "Klucze API i plany subskrypcji pozwalajฤ… na rรณลผne modele. Upewnij siฤ™, ลผe wybrany model jest zawarty w twoim planie." + }, + "geminiCli": { + "oauthLoadFailed": "Nie udaล‚o siฤ™ zaล‚adowaฤ‡ danych uwierzytelniajฤ…cych OAuth. Najpierw siฤ™ uwierzytelnij: {{error}}", + "tokenRefreshFailed": "Nie udaล‚o siฤ™ odล›wieลผyฤ‡ tokenu OAuth: {{error}}", + "onboardingTimeout": "Operacja wdraลผania przekroczyล‚a limit czasu po 60 sekundach. Sprรณbuj ponownie pรณลบniej.", + "projectDiscoveryFailed": "Nie moลผna odkryฤ‡ ID projektu. Upewnij siฤ™, ลผe jesteล› uwierzytelniony za pomocฤ… 'gemini auth'.", + "rateLimitExceeded": "Przekroczono limit szybkoล›ci. Osiฤ…gniฤ™to limity darmowego poziomu.", + "badRequest": "Nieprawidล‚owe ลผฤ…danie: {{details}}", + "apiError": "Bล‚ฤ…d API Gemini CLI: {{error}}", + "completionError": "Bล‚ฤ…d uzupeล‚niania Gemini CLI: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "Twoja organizacja wymaga uwierzytelnienia Roo Code Cloud. Zaloguj siฤ™, aby kontynuowaฤ‡.", "organization_mismatch": "Musisz byฤ‡ uwierzytelniony kontem Roo Code Cloud swojej organizacji.", "verification_failed": "Nie moลผna zweryfikowaฤ‡ uwierzytelnienia organizacji." - }, - "geminiCli": { - "oauthLoadFailed": "Nie udaล‚o siฤ™ zaล‚adowaฤ‡ danych uwierzytelniajฤ…cych OAuth. Najpierw siฤ™ uwierzytelnij: {{error}}", - "tokenRefreshFailed": "Nie udaล‚o siฤ™ odล›wieลผyฤ‡ tokenu OAuth: {{error}}", - "onboardingTimeout": "Operacja wdraลผania przekroczyล‚a limit czasu po 60 sekundach. Sprรณbuj ponownie pรณลบniej.", - "projectDiscoveryFailed": "Nie moลผna odkryฤ‡ ID projektu. Upewnij siฤ™, ลผe jesteล› uwierzytelniony za pomocฤ… 'gemini auth'.", - "rateLimitExceeded": "Przekroczono limit szybkoล›ci. Osiฤ…gniฤ™to limity darmowego poziomu.", - "badRequest": "Nieprawidล‚owe ลผฤ…danie: {{details}}", - "apiError": "Bล‚ฤ…d API Gemini CLI: {{error}}", - "completionError": "Bล‚ฤ…d uzupeล‚niania Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json index b8acb6b3c6..25779949d2 100644 --- a/src/i18n/locales/pt-BR/common.json +++ b/src/i18n/locales/pt-BR/common.json @@ -73,6 +73,16 @@ "processExitedWithError": "O processo Claude Code saiu com cรณdigo {{exitCode}}. Saรญda de erro: {{output}}", "stoppedWithReason": "Claude Code parou pela razรฃo: {{reason}}", "apiKeyModelPlanMismatch": "Chaves de API e planos de assinatura permitem modelos diferentes. Certifique-se de que o modelo selecionado esteja incluรญdo no seu plano." + }, + "geminiCli": { + "oauthLoadFailed": "Falha ao carregar credenciais OAuth. Por favor, autentique-se primeiro: {{error}}", + "tokenRefreshFailed": "Falha ao atualizar token OAuth: {{error}}", + "onboardingTimeout": "A operaรงรฃo de integraรงรฃo expirou apรณs 60 segundos. Por favor, tente novamente mais tarde.", + "projectDiscoveryFailed": "Nรฃo foi possรญvel descobrir o ID do projeto. Certifique-se de estar autenticado com 'gemini auth'.", + "rateLimitExceeded": "Limite de taxa excedido. Os limites do nรญvel gratuito foram atingidos.", + "badRequest": "Solicitaรงรฃo invรกlida: {{details}}", + "apiError": "Erro da API Gemini CLI: {{error}}", + "completionError": "Erro de conclusรฃo do Gemini CLI: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "Sua organizaรงรฃo requer autenticaรงรฃo do Roo Code Cloud. Faรงa login para continuar.", "organization_mismatch": "Vocรช deve estar autenticado com a conta Roo Code Cloud da sua organizaรงรฃo.", "verification_failed": "Nรฃo foi possรญvel verificar a autenticaรงรฃo da organizaรงรฃo." - }, - "geminiCli": { - "oauthLoadFailed": "Falha ao carregar credenciais OAuth. Por favor, autentique-se primeiro: {{error}}", - "tokenRefreshFailed": "Falha ao atualizar token OAuth: {{error}}", - "onboardingTimeout": "A operaรงรฃo de integraรงรฃo expirou apรณs 60 segundos. Tente novamente mais tarde.", - "projectDiscoveryFailed": "Nรฃo foi possรญvel descobrir o ID do projeto. Certifique-se de estar autenticado com 'gemini auth'.", - "rateLimitExceeded": "Limite de taxa excedido. Os limites do nรญvel gratuito foram atingidos.", - "badRequest": "Solicitaรงรฃo invรกlida: {{details}}", - "apiError": "Erro da API Gemini CLI: {{error}}", - "completionError": "Erro de conclusรฃo do Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json index 1b8f35fcbf..006b7af222 100644 --- a/src/i18n/locales/ru/common.json +++ b/src/i18n/locales/ru/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "ะŸั€ะพั†ะตัั Claude Code ะทะฐะฒะตั€ัˆะธะปัั ั ะบะพะดะพะผ {{exitCode}}. ะ’ั‹ะฒะพะด ะพัˆะธะฑะบะธ: {{output}}", "stoppedWithReason": "Claude Code ะพัั‚ะฐะฝะพะฒะธะปัั ะฟะพ ะฟั€ะธั‡ะธะฝะต: {{reason}}", "apiKeyModelPlanMismatch": "API-ะบะปัŽั‡ะธ ะธ ะฟะปะฐะฝั‹ ะฟะพะดะฟะธัะบะธ ะฟะพะทะฒะพะปััŽั‚ ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ ั€ะฐะทะฝั‹ะต ะผะพะดะตะปะธ. ะฃะฑะตะดะธั‚ะตััŒ, ั‡ั‚ะพ ะฒั‹ะฑั€ะฐะฝะฝะฐั ะผะพะดะตะปัŒ ะฒะบะปัŽั‡ะตะฝะฐ ะฒ ะฒะฐัˆ ะฟะปะฐะฝ." + }, + "geminiCli": { + "oauthLoadFailed": "ะะต ัƒะดะฐะปะพััŒ ะทะฐะณั€ัƒะทะธั‚ัŒ ัƒั‡ะตั‚ะฝั‹ะต ะดะฐะฝะฝั‹ะต OAuth. ะกะฝะฐั‡ะฐะปะฐ ะฒั‹ะฟะพะปะฝะธั‚ะต ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ: {{error}}", + "tokenRefreshFailed": "ะะต ัƒะดะฐะปะพััŒ ะพะฑะฝะพะฒะธั‚ัŒ ั‚ะพะบะตะฝ OAuth: {{error}}", + "onboardingTimeout": "ะžะฟะตั€ะฐั†ะธั ะฟะพะดะบะปัŽั‡ะตะฝะธั ะธัั‚ะตะบะปะฐ ั‡ะตั€ะตะท 60 ัะตะบัƒะฝะด. ะŸะพะถะฐะปัƒะนัั‚ะฐ, ะฟะพะฟั€ะพะฑัƒะนั‚ะต ะฟะพะทะถะต.", + "projectDiscoveryFailed": "ะะต ัƒะดะฐะปะพััŒ ะพะฑะฝะฐั€ัƒะถะธั‚ัŒ ะธะดะตะฝั‚ะธั„ะธะบะฐั‚ะพั€ ะฟั€ะพะตะบั‚ะฐ. ะฃะฑะตะดะธั‚ะตััŒ, ั‡ั‚ะพ ะฒั‹ ะฐัƒั‚ะตะฝั‚ะธั„ะธั†ะธั€ะพะฒะฐะฝั‹ ั ะฟะพะผะพั‰ัŒัŽ 'gemini auth'.", + "rateLimitExceeded": "ะŸั€ะตะฒั‹ัˆะตะฝ ะปะธะผะธั‚ ัะบะพั€ะพัั‚ะธ. ะ”ะพัั‚ะธะณะฝัƒั‚ั‹ ะปะธะผะธั‚ั‹ ะฑะตัะฟะปะฐั‚ะฝะพะณะพ ัƒั€ะพะฒะฝั.", + "badRequest": "ะะตะฒะตั€ะฝั‹ะน ะทะฐะฟั€ะพั: {{details}}", + "apiError": "ะžัˆะธะฑะบะฐ API Gemini CLI: {{error}}", + "completionError": "ะžัˆะธะฑะบะฐ ะทะฐะฒะตั€ัˆะตะฝะธั Gemini CLI: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "ะ’ะฐัˆะฐ ะพั€ะณะฐะฝะธะทะฐั†ะธั ั‚ั€ะตะฑัƒะตั‚ ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธะธ Roo Code Cloud. ะ’ะพะนะดะธั‚ะต ะฒ ัะธัั‚ะตะผัƒ, ั‡ั‚ะพะฑั‹ ะฟั€ะพะดะพะปะถะธั‚ัŒ.", "organization_mismatch": "ะ’ั‹ ะดะพะปะถะฝั‹ ะฑั‹ั‚ัŒ ะฐัƒั‚ะตะฝั‚ะธั„ะธั†ะธั€ะพะฒะฐะฝั‹ ั ัƒั‡ะตั‚ะฝะพะน ะทะฐะฟะธััŒัŽ Roo Code Cloud ะฒะฐัˆะตะน ะพั€ะณะฐะฝะธะทะฐั†ะธะธ.", "verification_failed": "ะะต ัƒะดะฐะตั‚ัั ะฟั€ะพะฒะตั€ะธั‚ัŒ ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ ะพั€ะณะฐะฝะธะทะฐั†ะธะธ." - }, - "geminiCli": { - "oauthLoadFailed": "ะะต ัƒะดะฐะปะพััŒ ะทะฐะณั€ัƒะทะธั‚ัŒ ัƒั‡ะตั‚ะฝั‹ะต ะดะฐะฝะฝั‹ะต OAuth. ะกะฝะฐั‡ะฐะปะฐ ะฒั‹ะฟะพะปะฝะธั‚ะต ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ: {{error}}", - "tokenRefreshFailed": "ะะต ัƒะดะฐะปะพััŒ ะพะฑะฝะพะฒะธั‚ัŒ ั‚ะพะบะตะฝ OAuth: {{error}}", - "onboardingTimeout": "ะžะฟะตั€ะฐั†ะธั ะฐะดะฐะฟั‚ะฐั†ะธะธ ะธัั‚ะตะบะปะฐ ั‡ะตั€ะตะท 60 ัะตะบัƒะฝะด. ะŸะพะฟั€ะพะฑัƒะนั‚ะต ะฟะพะทะถะต.", - "projectDiscoveryFailed": "ะะต ัƒะดะฐะปะพััŒ ะพะฑะฝะฐั€ัƒะถะธั‚ัŒ ID ะฟั€ะพะตะบั‚ะฐ. ะฃะฑะตะดะธั‚ะตััŒ, ั‡ั‚ะพ ะฒั‹ ะฐัƒั‚ะตะฝั‚ะธั„ะธั†ะธั€ะพะฒะฐะฝั‹ ั ะฟะพะผะพั‰ัŒัŽ 'gemini auth'.", - "rateLimitExceeded": "ะŸั€ะตะฒั‹ัˆะตะฝ ะปะธะผะธั‚ ัะบะพั€ะพัั‚ะธ. ะ”ะพัั‚ะธะณะฝัƒั‚ั‹ ะพะณั€ะฐะฝะธั‡ะตะฝะธั ะฑะตัะฟะปะฐั‚ะฝะพะณะพ ัƒั€ะพะฒะฝั.", - "badRequest": "ะะตะฒะตั€ะฝั‹ะน ะทะฐะฟั€ะพั: {{details}}", - "apiError": "ะžัˆะธะฑะบะฐ API Gemini CLI: {{error}}", - "completionError": "ะžัˆะธะฑะบะฐ ะทะฐะฒะตั€ัˆะตะฝะธั Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json index f07ee9cc80..87635c61ef 100644 --- a/src/i18n/locales/tr/common.json +++ b/src/i18n/locales/tr/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Claude Code iลŸlemi {{exitCode}} koduyla รงฤฑktฤฑ. Hata รงฤฑktฤฑsฤฑ: {{output}}", "stoppedWithReason": "Claude Code ลŸu nedenle durdu: {{reason}}", "apiKeyModelPlanMismatch": "API anahtarlarฤฑ ve abonelik planlarฤฑ farklฤฑ modellere izin verir. Seรงilen modelin planฤฑnฤฑza dahil olduฤŸundan emin olun." + }, + "geminiCli": { + "oauthLoadFailed": "OAuth kimlik bilgileri yรผklenemedi. Lรผtfen รถnce kimlik doฤŸrulamasฤฑ yapฤฑn: {{error}}", + "tokenRefreshFailed": "OAuth token yenilenemedi: {{error}}", + "onboardingTimeout": "Onboarding iลŸlemi 60 saniye sonra zaman aลŸฤฑmฤฑna uฤŸradฤฑ. Lรผtfen daha sonra tekrar deneyin.", + "projectDiscoveryFailed": "Proje ID'si keลŸfedilemedi. 'gemini auth' ile kimlik doฤŸrulamasฤฑ yaptฤฑฤŸฤฑnฤฑzdan emin olun.", + "rateLimitExceeded": "Hฤฑz sฤฑnฤฑrฤฑ aลŸฤฑldฤฑ. รœcretsiz seviye sฤฑnฤฑrlarฤฑna ulaลŸฤฑldฤฑ.", + "badRequest": "Geรงersiz istek: {{details}}", + "apiError": "Gemini CLI API hatasฤฑ: {{error}}", + "completionError": "Gemini CLI tamamlama hatasฤฑ: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "KuruluลŸunuz Roo Code Cloud kimlik doฤŸrulamasฤฑ gerektiriyor. Devam etmek iรงin giriลŸ yapฤฑn.", "organization_mismatch": "KuruluลŸunuzun Roo Code Cloud hesabฤฑyla kimlik doฤŸrulamasฤฑ yapmalฤฑsฤฑnฤฑz.", "verification_failed": "KuruluลŸ kimlik doฤŸrulamasฤฑ doฤŸrulanamฤฑyor." - }, - "geminiCli": { - "oauthLoadFailed": "OAuth kimlik bilgileri yรผklenemedi. Lรผtfen รถnce kimlik doฤŸrulamasฤฑ yapฤฑn: {{error}}", - "tokenRefreshFailed": "OAuth token yenilenemedi: {{error}}", - "onboardingTimeout": "Onboarding iลŸlemi 60 saniye sonra zaman aลŸฤฑmฤฑna uฤŸradฤฑ. Lรผtfen daha sonra tekrar deneyin.", - "projectDiscoveryFailed": "Proje ID'si keลŸfedilemedi. 'gemini auth' ile kimlik doฤŸrulamasฤฑ yaptฤฑฤŸฤฑnฤฑzdan emin olun.", - "rateLimitExceeded": "Hฤฑz sฤฑnฤฑrฤฑ aลŸฤฑldฤฑ. รœcretsiz seviye sฤฑnฤฑrlarฤฑna ulaลŸฤฑldฤฑ.", - "badRequest": "Geรงersiz istek: {{details}}", - "apiError": "Gemini CLI API hatasฤฑ: {{error}}", - "completionError": "Gemini CLI tamamlama hatasฤฑ: {{error}}" } } } diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json index 49db186e93..7321b3e8a6 100644 --- a/src/i18n/locales/vi/common.json +++ b/src/i18n/locales/vi/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Tiแบฟn trรฌnh Claude Code thoรกt vแป›i mรฃ {{exitCode}}. ฤแบงu ra lแป—i: {{output}}", "stoppedWithReason": "Claude Code dแปซng lแบกi vรฌ lรฝ do: {{reason}}", "apiKeyModelPlanMismatch": "Khรณa API vร  gรณi ฤ‘ฤƒng kรฝ cho phรฉp cรกc mรด hรฌnh khรกc nhau. ฤแบฃm bแบฃo rแบฑng mรด hรฌnh ฤ‘รฃ chแปn ฤ‘ฦฐแปฃc bao gแป“m trong gรณi cแปงa bแบกn." + }, + "geminiCli": { + "oauthLoadFailed": "Khรดng thแปƒ tแบฃi thรดng tin xรกc thแปฑc OAuth. Vui lรฒng xรกc thแปฑc trฦฐแป›c: {{error}}", + "tokenRefreshFailed": "Khรดng thแปƒ lร m mแป›i token OAuth: {{error}}", + "onboardingTimeout": "Thao tรกc onboarding ฤ‘รฃ hแบฟt thแปi gian chแป sau 60 giรขy. Vui lรฒng thแปญ lแบกi sau.", + "projectDiscoveryFailed": "Khรดng thแปƒ khรกm phรก ID dแปฑ รกn. ฤแบฃm bแบฃo bแบกn ฤ‘รฃ xรกc thแปฑc bแบฑng 'gemini auth'.", + "rateLimitExceeded": "ฤรฃ vฦฐแปฃt quรก giแป›i hแบกn tแป‘c ฤ‘แป™. ฤรฃ ฤ‘แบกt ฤ‘แบฟn giแป›i hแบกn cแปงa gรณi miแป…n phรญ.", + "badRequest": "Yรชu cแบงu khรดng hแปฃp lแป‡: {{details}}", + "apiError": "Lแป—i API Gemini CLI: {{error}}", + "completionError": "Lแป—i hoร n thร nh Gemini CLI: {{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "Tแป• chแปฉc cแปงa bแบกn yรชu cแบงu xรกc thแปฑc Roo Code Cloud. Vui lรฒng ฤ‘ฤƒng nhแบญp ฤ‘แปƒ tiแบฟp tแปฅc.", "organization_mismatch": "Bแบกn phแบฃi ฤ‘ฦฐแปฃc xรกc thแปฑc bแบฑng tร i khoแบฃn Roo Code Cloud cแปงa tแป• chแปฉc.", "verification_failed": "Khรดng thแปƒ xรกc minh xรกc thแปฑc tแป• chแปฉc." - }, - "geminiCli": { - "oauthLoadFailed": "Khรดng thแปƒ tแบฃi thรดng tin xรกc thแปฑc OAuth. Vui lรฒng xรกc thแปฑc trฦฐแป›c: {{error}}", - "tokenRefreshFailed": "Khรดng thแปƒ lร m mแป›i token OAuth: {{error}}", - "onboardingTimeout": "Thao tรกc onboarding ฤ‘รฃ hแบฟt thแปi gian chแป sau 60 giรขy. Vui lรฒng thแปญ lแบกi sau.", - "projectDiscoveryFailed": "Khรดng thแปƒ khรกm phรก ID dแปฑ รกn. ฤแบฃm bแบฃo bแบกn ฤ‘รฃ xรกc thแปฑc bแบฑng 'gemini auth'.", - "rateLimitExceeded": "ฤรฃ vฦฐแปฃt quรก giแป›i hแบกn tแป‘c ฤ‘แป™. ฤรฃ ฤ‘แบกt ฤ‘แบฟn giแป›i hแบกn cแปงa gรณi miแป…n phรญ.", - "badRequest": "Yรชu cแบงu khรดng hแปฃp lแป‡: {{details}}", - "apiError": "Lแป—i API Gemini CLI: {{error}}", - "completionError": "Lแป—i hoร n thร nh Gemini CLI: {{error}}" } } } diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json index a5e355e27f..9ebdd04b95 100644 --- a/src/i18n/locales/zh-CN/common.json +++ b/src/i18n/locales/zh-CN/common.json @@ -74,6 +74,16 @@ "processExitedWithError": "Claude Code ่ฟ›็จ‹้€€ๅ‡บ๏ผŒ้€€ๅ‡บ็ ๏ผš{{exitCode}}ใ€‚้”™่ฏฏ่พ“ๅ‡บ๏ผš{{output}}", "stoppedWithReason": "Claude Code ๅœๆญข๏ผŒๅŽŸๅ› ๏ผš{{reason}}", "apiKeyModelPlanMismatch": "API ๅฏ†้’ฅๅ’Œ่ฎข้˜…่ฎกๅˆ’ๆ”ฏๆŒไธๅŒ็š„ๆจกๅž‹ใ€‚่ฏท็กฎไฟๆ‰€้€‰ๆจกๅž‹ๅŒ…ๅซๅœจๆ‚จ็š„่ฎกๅˆ’ไธญใ€‚" + }, + "geminiCli": { + "oauthLoadFailed": "ๅŠ ่ฝฝ OAuth ๅ‡ญๆฎๅคฑ่ดฅใ€‚่ฏทๅ…ˆ่ฟ›่กŒ่บซไปฝ้ชŒ่ฏ๏ผš{{error}}", + "tokenRefreshFailed": "ๅˆทๆ–ฐ OAuth Token ๅคฑ่ดฅ๏ผš{{error}}", + "onboardingTimeout": "ๅ…ฅ้—จๆ“ไฝœๅœจ 60 ็ง’ๅŽ่ถ…ๆ—ถใ€‚่ฏท็จๅŽ้‡่ฏ•ใ€‚", + "projectDiscoveryFailed": "ๆ— ๆณ•ๅ‘็Žฐ้กน็›ฎ IDใ€‚่ฏท็กฎไฟๅทฒไฝฟ็”จ 'gemini auth' ่ฟ›่กŒ่บซไปฝ้ชŒ่ฏใ€‚", + "rateLimitExceeded": "API ่ฏทๆฑ‚้ข‘็އ้™ๅˆถๅทฒ่ถ…ๅ‡บใ€‚ๅ…่ดนๅฑ‚็บง้™ๅˆถๅทฒ่พพๅˆฐใ€‚", + "badRequest": "่ฏทๆฑ‚้”™่ฏฏ๏ผš{{details}}", + "apiError": "Gemini CLI API ้”™่ฏฏ๏ผš{{error}}", + "completionError": "Gemini CLI ่กฅๅ…จ้”™่ฏฏ๏ผš{{error}}" } }, "warnings": { @@ -144,16 +154,6 @@ "cloud_auth_required": "ๆ‚จ็š„็ป„็ป‡้œ€่ฆ Roo Code Cloud ่บซไปฝ้ชŒ่ฏใ€‚่ฏท็™ปๅฝ•ไปฅ็ปง็ปญใ€‚", "organization_mismatch": "ๆ‚จๅฟ…้กปไฝฟ็”จ็ป„็ป‡็š„ Roo Code Cloud ่ดฆๆˆท่ฟ›่กŒ่บซไปฝ้ชŒ่ฏใ€‚", "verification_failed": "ๆ— ๆณ•้ชŒ่ฏ็ป„็ป‡่บซไปฝ้ชŒ่ฏใ€‚" - }, - "geminiCli": { - "oauthLoadFailed": "ๅŠ ่ฝฝ OAuth ๅ‡ญๆฎๅคฑ่ดฅใ€‚่ฏทๅ…ˆ่ฟ›่กŒ่บซไปฝ้ชŒ่ฏ๏ผš{{error}}", - "tokenRefreshFailed": "ๅˆทๆ–ฐ OAuth Token ๅคฑ่ดฅ๏ผš{{error}}", - "onboardingTimeout": "ๅ…ฅ้—จๆ“ไฝœๅœจ 60 ็ง’ๅŽ่ถ…ๆ—ถใ€‚่ฏท็จๅŽ้‡่ฏ•ใ€‚", - "projectDiscoveryFailed": "ๆ— ๆณ•ๅ‘็Žฐ้กน็›ฎ IDใ€‚่ฏท็กฎไฟๅทฒไฝฟ็”จ 'gemini auth' ่ฟ›่กŒ่บซไปฝ้ชŒ่ฏใ€‚", - "rateLimitExceeded": "API ่ฏทๆฑ‚้ข‘็އ้™ๅˆถๅทฒ่ถ…ๅ‡บใ€‚ๅ…่ดนๅฑ‚็บง้™ๅˆถๅทฒ่พพๅˆฐใ€‚", - "badRequest": "่ฏทๆฑ‚้”™่ฏฏ๏ผš{{details}}", - "apiError": "Gemini CLI API ้”™่ฏฏ๏ผš{{error}}", - "completionError": "Gemini CLI ่กฅๅ…จ้”™่ฏฏ๏ผš{{error}}" } } } diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json index 09b26377ec..a63e87f61a 100644 --- a/src/i18n/locales/zh-TW/common.json +++ b/src/i18n/locales/zh-TW/common.json @@ -69,6 +69,16 @@ "processExitedWithError": "Claude Code ็จ‹ๅบ้€€ๅ‡บ๏ผŒ้€€ๅ‡บ็ขผ๏ผš{{exitCode}}ใ€‚้Œฏ่ชค่ผธๅ‡บ๏ผš{{output}}", "stoppedWithReason": "Claude Code ๅœๆญข๏ผŒๅŽŸๅ› ๏ผš{{reason}}", "apiKeyModelPlanMismatch": "API ้‡‘้‘ฐๅ’Œ่จ‚้–ฑๆ–นๆกˆๅ…่จฑไธๅŒ็š„ๆจกๅž‹ใ€‚่ซ‹็ขบไฟๆ‰€้ธๆจกๅž‹ๅŒ…ๅซๅœจๆ‚จ็š„ๆ–นๆกˆไธญใ€‚" + }, + "geminiCli": { + "oauthLoadFailed": "็„กๆณ•่ผ‰ๅ…ฅ OAuth ๆ†‘่ญ‰ใ€‚่ซ‹ๅ…ˆ้€ฒ่กŒ้ฉ—่ญ‰๏ผš{{error}}", + "tokenRefreshFailed": "็„กๆณ•้‡ๆ–ฐๆ•ด็† OAuth ๆฌŠๆ–๏ผš{{error}}", + "onboardingTimeout": "ๆ–ฐๆ‰‹ๅฐŽๅผ•ๆ“ไฝœๅœจ 60 ็ง’ๅพŒ้€พๆ™‚ใ€‚่ซ‹็จๅพŒๅ†่ฉฆใ€‚", + "projectDiscoveryFailed": "็„กๆณ•็™ผ็พๅฐˆๆกˆ IDใ€‚่ซ‹็ขบไฟๆ‚จๅทฒไฝฟ็”จ 'gemini auth' ้€ฒ่กŒ้ฉ—่ญ‰ใ€‚", + "rateLimitExceeded": "่ถ…้Ž้€Ÿ็އ้™ๅˆถใ€‚ๅทฒ้”ๅˆฐๅ…่ฒปๅฑค็ดš้™ๅˆถใ€‚", + "badRequest": "้Œฏ่ชค็š„่ซ‹ๆฑ‚๏ผš{{details}}", + "apiError": "Gemini CLI API ้Œฏ่ชค๏ผš{{error}}", + "completionError": "Gemini CLI ๅฎŒๆˆ้Œฏ่ชค๏ผš{{error}}" } }, "warnings": { @@ -139,16 +149,6 @@ "cloud_auth_required": "ๆ‚จ็š„็ต„็น”้œ€่ฆ Roo Code Cloud ่บซไปฝ้ฉ—่ญ‰ใ€‚่ซ‹็™ปๅ…ฅไปฅ็นผ็บŒใ€‚", "organization_mismatch": "ๆ‚จๅฟ…้ ˆไฝฟ็”จ็ต„็น”็š„ Roo Code Cloud ๅธณๆˆถ้€ฒ่กŒ่บซไปฝ้ฉ—่ญ‰ใ€‚", "verification_failed": "็„กๆณ•้ฉ—่ญ‰็ต„็น”่บซไปฝ้ฉ—่ญ‰ใ€‚" - }, - "geminiCli": { - "oauthLoadFailed": "่ผ‰ๅ…ฅ OAuth ๆ†‘่ญ‰ๅคฑๆ•—ใ€‚่ซ‹ๅ…ˆ้€ฒ่กŒ่บซไปฝ้ฉ—่ญ‰๏ผš{{error}}", - "tokenRefreshFailed": "้‡ๆ–ฐๆ•ด็† OAuth Token ๅคฑๆ•—๏ผš{{error}}", - "onboardingTimeout": "ๅ…ฅ้–€ๆ“ไฝœๅœจ 60 ็ง’ๅพŒ้€พๆ™‚ใ€‚่ซ‹็จๅพŒ้‡่ฉฆใ€‚", - "projectDiscoveryFailed": "็„กๆณ•็™ผ็พๅฐˆๆกˆ IDใ€‚่ซ‹็ขบไฟๅทฒไฝฟ็”จ 'gemini auth' ้€ฒ่กŒ่บซไปฝ้ฉ—่ญ‰ใ€‚", - "rateLimitExceeded": "้€Ÿ็އ้™ๅˆถๅทฒ่ถ…ๅ‡บใ€‚ๅ…่ฒปๅฑค็ดš้™ๅˆถๅทฒ้”ๅˆฐใ€‚", - "badRequest": "่ซ‹ๆฑ‚้Œฏ่ชค๏ผš{{details}}", - "apiError": "Gemini CLI API ้Œฏ่ชค๏ผš{{error}}", - "completionError": "Gemini CLI ๅฎŒๆˆ้Œฏ่ชค๏ผš{{error}}" } } } From 11ed27a925fcec4dc0abeabc63ca9d2d71cba2c6 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Fri, 27 Jun 2025 12:53:06 -0400 Subject: [PATCH 12/70] v3.22.2 (#5195) --- .changeset/v3.22.2.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/v3.22.2.md diff --git a/.changeset/v3.22.2.md b/.changeset/v3.22.2.md new file mode 100644 index 0000000000..178cf1a5de --- /dev/null +++ b/.changeset/v3.22.2.md @@ -0,0 +1,9 @@ +--- +"roo-cline": patch +--- + +- Fix: eliminate XSS vulnerability in CodeBlock component (thanks @KJ7LNW!) +- Fix terminal keyboard shortcut error when adding content to context (thanks @MuriloFP!) +- Fix checkpoint popover not opening due to StandardTooltip wrapper conflict (thanks @daniel-lxs!) +- Fix(i18n): correct gemini cli error translation paths (thanks @daniel-lxs!) +- Code Index (Qdrant) recreate services when change configurations (thanks @catrielmuller!) From f1feccc6bf3e8c2dc1ef416da1918ea9d9cf3b0b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 12:58:44 -0400 Subject: [PATCH 13/70] Changeset version bump (#5167) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Matt Rubens --- .changeset/v3.22.2.md | 9 --------- CHANGELOG.md | 8 ++++++++ src/package.json | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 .changeset/v3.22.2.md diff --git a/.changeset/v3.22.2.md b/.changeset/v3.22.2.md deleted file mode 100644 index 178cf1a5de..0000000000 --- a/.changeset/v3.22.2.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"roo-cline": patch ---- - -- Fix: eliminate XSS vulnerability in CodeBlock component (thanks @KJ7LNW!) -- Fix terminal keyboard shortcut error when adding content to context (thanks @MuriloFP!) -- Fix checkpoint popover not opening due to StandardTooltip wrapper conflict (thanks @daniel-lxs!) -- Fix(i18n): correct gemini cli error translation paths (thanks @daniel-lxs!) -- Code Index (Qdrant) recreate services when change configurations (thanks @catrielmuller!) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56555351bc..47f37b7bbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Roo Code Changelog +## [3.22.2] - 2025-06-27 + +- Fix: eliminate XSS vulnerability in CodeBlock component (thanks @KJ7LNW!) +- Fix terminal keyboard shortcut error when adding content to context (thanks @MuriloFP!) +- Fix checkpoint popover not opening due to StandardTooltip wrapper conflict (thanks @daniel-lxs!) +- Fix(i18n): correct gemini cli error translation paths (thanks @daniel-lxs!) +- Code Index (Qdrant) recreate services when change configurations (thanks @catrielmuller!) + ## [3.22.1] - 2025-06-26 - Add Gemini CLI provider (thanks Cline!) diff --git a/src/package.json b/src/package.json index 40e40ac914..81bd4f6aab 100644 --- a/src/package.json +++ b/src/package.json @@ -3,7 +3,7 @@ "displayName": "%extension.displayName%", "description": "%extension.description%", "publisher": "RooVeterinaryInc", - "version": "3.22.1", + "version": "3.22.2", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From d397d131b944dd2d7301018baaec96c2cab4ae39 Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 27 Jun 2025 14:04:17 -0500 Subject: [PATCH 14/70] fix: restore JSON backwards compatibility for .roomodes files (#5199) --- src/core/config/CustomModesManager.ts | 45 +++++++++++---------- src/services/marketplace/SimpleInstaller.ts | 8 +--- src/utils/migrateSettings.ts | 2 +- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts index 5ce94b0e38..b96293ee49 100644 --- a/src/core/config/CustomModesManager.ts +++ b/src/core/config/CustomModesManager.ts @@ -123,18 +123,29 @@ export class CustomModesManager { try { return yaml.parse(cleanedContent) - } catch (error) { - const errorMsg = error instanceof Error ? error.message : String(error) - console.error(`[CustomModesManager] Failed to parse YAML from ${filePath}:`, errorMsg) - - // Show user-friendly error message for .roomodes files + } catch (yamlError) { + // For .roomodes files, try JSON as fallback if (filePath.endsWith(ROOMODES_FILENAME)) { - const lineMatch = errorMsg.match(/at line (\d+)/) - const line = lineMatch ? lineMatch[1] : "unknown" - vscode.window.showErrorMessage(t("common:customModes.errors.yamlParseError", { line })) + try { + // Try parsing the original content as JSON (not the cleaned content) + return JSON.parse(content) + } catch (jsonError) { + // JSON also failed, show the original YAML error + const errorMsg = yamlError instanceof Error ? yamlError.message : String(yamlError) + console.error(`[CustomModesManager] Failed to parse YAML from ${filePath}:`, errorMsg) + + const lineMatch = errorMsg.match(/at line (\d+)/) + const line = lineMatch ? lineMatch[1] : "unknown" + vscode.window.showErrorMessage(t("common:customModes.errors.yamlParseError", { line })) + + // Return empty object to prevent duplicate error handling + return {} + } } - // Return empty object to prevent duplicate error handling + // For non-.roomodes files, just log and return empty object + const errorMsg = yamlError instanceof Error ? yamlError.message : String(yamlError) + console.error(`[CustomModesManager] Failed to parse YAML from ${filePath}:`, errorMsg) return {} } } @@ -205,12 +216,7 @@ export class CustomModesManager { const fileExists = await fileExistsAtPath(filePath) if (!fileExists) { - await this.queueWrite(() => - fs.writeFile( - filePath, - yaml.stringify({ customModes: [] }, { lineWidth: 0, defaultStringType: "PLAIN" }), - ), - ) + await this.queueWrite(() => fs.writeFile(filePath, yaml.stringify({ customModes: [] }, { lineWidth: 0 }))) } return filePath @@ -414,7 +420,7 @@ export class CustomModesManager { content = await fs.readFile(filePath, "utf-8") } catch (error) { // File might not exist yet. - content = yaml.stringify({ customModes: [] }, { lineWidth: 0, defaultStringType: "PLAIN" }) + content = yaml.stringify({ customModes: [] }, { lineWidth: 0 }) } let settings @@ -427,7 +433,7 @@ export class CustomModesManager { } settings.customModes = operation(settings.customModes || []) - await fs.writeFile(filePath, yaml.stringify(settings, { lineWidth: 0, defaultStringType: "PLAIN" }), "utf-8") + await fs.writeFile(filePath, yaml.stringify(settings, { lineWidth: 0 }), "utf-8") } private async refreshMergedState(): Promise { @@ -485,10 +491,7 @@ export class CustomModesManager { public async resetCustomModes(): Promise { try { const filePath = await this.getCustomModesFilePath() - await fs.writeFile( - filePath, - yaml.stringify({ customModes: [] }, { lineWidth: 0, defaultStringType: "PLAIN" }), - ) + await fs.writeFile(filePath, yaml.stringify({ customModes: [] }, { lineWidth: 0 })) await this.context.globalState.update("customModes", []) this.clearCache() await this.onUpdate() diff --git a/src/services/marketplace/SimpleInstaller.ts b/src/services/marketplace/SimpleInstaller.ts index 7ead5e2442..91f5bcad26 100644 --- a/src/services/marketplace/SimpleInstaller.ts +++ b/src/services/marketplace/SimpleInstaller.ts @@ -84,7 +84,7 @@ export class SimpleInstaller { // Write back to file await fs.mkdir(path.dirname(filePath), { recursive: true }) - const yamlContent = yaml.stringify(existingData, { lineWidth: 0, defaultStringType: "PLAIN" }) + const yamlContent = yaml.stringify(existingData, { lineWidth: 0 }) await fs.writeFile(filePath, yamlContent, "utf-8") // Calculate approximate line number where the new mode was added @@ -282,11 +282,7 @@ export class SimpleInstaller { existingData.customModes = existingData.customModes.filter((mode: any) => mode.slug !== modeData.slug) // Always write back the file, even if empty - await fs.writeFile( - filePath, - yaml.stringify(existingData, { lineWidth: 0, defaultStringType: "PLAIN" }), - "utf-8", - ) + await fs.writeFile(filePath, yaml.stringify(existingData, { lineWidth: 0 }), "utf-8") } } catch (error: any) { if (error.code === "ENOENT") { diff --git a/src/utils/migrateSettings.ts b/src/utils/migrateSettings.ts index 3007a6bcfb..43b1d7291f 100644 --- a/src/utils/migrateSettings.ts +++ b/src/utils/migrateSettings.ts @@ -93,7 +93,7 @@ async function migrateCustomModesToYaml(settingsDir: string, outputChannel: vsco const customModesData = yaml.parse(jsonContent) // Convert to YAML with no line width limit to prevent line breaks - const yamlContent = yaml.stringify(customModesData, { lineWidth: 0, defaultStringType: "PLAIN" }) + const yamlContent = yaml.stringify(customModesData, { lineWidth: 0 }) // Write YAML file await fs.writeFile(newYamlPath, yamlContent, "utf-8") From e64db9ad0bdaee85d6731178cec40f953ff6ab8f Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Fri, 27 Jun 2025 15:40:33 -0400 Subject: [PATCH 15/70] v3.22.3 (#5201) --- .changeset/v3.22.3.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/v3.22.3.md diff --git a/.changeset/v3.22.3.md b/.changeset/v3.22.3.md new file mode 100644 index 0000000000..4fce8a1bcd --- /dev/null +++ b/.changeset/v3.22.3.md @@ -0,0 +1,5 @@ +--- +"roo-cline": patch +--- + +- Fix restore JSON backwards compatibility for .roomodes files (thanks @daniel-lxs!) From 3a8ba276156f32284df25a6ca098671d8df9d56c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 15:45:28 -0400 Subject: [PATCH 16/70] Changeset version bump (#5196) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Matt Rubens --- .changeset/v3.22.3.md | 5 ----- CHANGELOG.md | 4 ++++ src/package.json | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 .changeset/v3.22.3.md diff --git a/.changeset/v3.22.3.md b/.changeset/v3.22.3.md deleted file mode 100644 index 4fce8a1bcd..0000000000 --- a/.changeset/v3.22.3.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"roo-cline": patch ---- - -- Fix restore JSON backwards compatibility for .roomodes files (thanks @daniel-lxs!) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47f37b7bbf..693b40db92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Roo Code Changelog +## [3.22.3] - 2025-06-27 + +- Restore JSON backwards compatibility for .roomodes files (thanks @daniel-lxs!) + ## [3.22.2] - 2025-06-27 - Fix: eliminate XSS vulnerability in CodeBlock component (thanks @KJ7LNW!) diff --git a/src/package.json b/src/package.json index 81bd4f6aab..6412b4b858 100644 --- a/src/package.json +++ b/src/package.json @@ -3,7 +3,7 @@ "displayName": "%extension.displayName%", "description": "%extension.description%", "publisher": "RooVeterinaryInc", - "version": "3.22.2", + "version": "3.22.3", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 719d661478388590ebb7f93e2a3a68022dbd1d48 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Fri, 27 Jun 2025 16:26:17 -0400 Subject: [PATCH 17/70] Add optional mode suggestions to follow-up questions (#5200) --- .../architect-mode-prompt.snap | 15 +++ .../ask-mode-prompt.snap | 15 +++ .../mcp-server-creation-disabled.snap | 15 +++ .../mcp-server-creation-enabled.snap | 15 +++ .../partial-reads-enabled.snap | 15 +++ .../consistent-system-prompt.snap | 15 +++ .../with-computer-use-support.snap | 15 +++ .../with-diff-enabled-false.snap | 15 +++ .../system-prompt/with-diff-enabled-true.snap | 15 +++ .../with-diff-enabled-undefined.snap | 15 +++ .../with-different-viewport-size.snap | 15 +++ .../system-prompt/with-mcp-hub-provided.snap | 15 +++ .../system-prompt/with-undefined-mcp-hub.snap | 15 +++ .../prompts/tools/ask-followup-question.ts | 15 +++ .../__tests__/askFollowupQuestionTool.spec.ts | 108 ++++++++++++++++++ src/core/tools/askFollowupQuestionTool.ts | 30 ++++- .../src/components/chat/FollowUpSuggest.tsx | 82 ++++++++----- 17 files changed, 398 insertions(+), 32 deletions(-) create mode 100644 src/core/tools/__tests__/askFollowupQuestionTool.spec.ts diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap index dd621b34b8..98ef98fcad 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap @@ -277,6 +277,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -284,6 +286,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -297,6 +302,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/ask-mode-prompt.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/ask-mode-prompt.snap index 3b8f357e8c..e665309432 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/ask-mode-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/ask-mode-prompt.snap @@ -174,6 +174,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -181,6 +183,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -194,6 +199,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap index 719e7f0ea7..bf9a0ef02f 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap @@ -348,6 +348,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -355,6 +357,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -368,6 +373,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap index 9f3ad102e8..7b3e18690c 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap @@ -348,6 +348,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -355,6 +357,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -368,6 +373,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap index 2c7e9ec165..b77b77e1e2 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap @@ -304,6 +304,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -311,6 +313,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -324,6 +329,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap index b4220ce2e8..2f2a41916d 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap @@ -299,6 +299,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -306,6 +308,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -319,6 +324,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap index 6248770325..1cf0529e19 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap @@ -352,6 +352,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -359,6 +361,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -372,6 +377,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap index b4220ce2e8..2f2a41916d 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap @@ -299,6 +299,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -306,6 +308,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -319,6 +324,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap index 1fce8bf785..6612df745e 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap @@ -387,6 +387,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -394,6 +396,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -407,6 +412,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap index b4220ce2e8..2f2a41916d 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap @@ -299,6 +299,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -306,6 +308,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -319,6 +324,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap index d07dc1d874..28b31eefcf 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap @@ -352,6 +352,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -359,6 +361,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -372,6 +377,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap index 9f3ad102e8..7b3e18690c 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap @@ -348,6 +348,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -355,6 +357,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -368,6 +373,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap index b4220ce2e8..2f2a41916d 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap @@ -299,6 +299,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -306,6 +308,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -319,6 +324,16 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + + + ## attempt_completion Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. diff --git a/src/core/prompts/tools/ask-followup-question.ts b/src/core/prompts/tools/ask-followup-question.ts index 7ece1e311d..c69e5a697f 100644 --- a/src/core/prompts/tools/ask-followup-question.ts +++ b/src/core/prompts/tools/ask-followup-question.ts @@ -7,6 +7,8 @@ Parameters: 1. Be provided in its own tag 2. Be specific, actionable, and directly related to the completed task 3. Be a complete answer to the question - the user should not need to provide additional information or fill in any missing details. DO NOT include placeholders with brackets or parentheses. + 4. Optionally include a mode attribute to switch to a specific mode when the suggestion is selected: suggestion text + - When using the mode attribute, focus the suggestion text on the action to be taken rather than mentioning the mode switch, as the mode change is handled automatically and indicated by a visual badge Usage: Your question here @@ -14,6 +16,9 @@ Usage: Your suggested answer here + +Implement the solution + @@ -25,5 +30,15 @@ Example: Requesting to ask the user for the path to the frontend-config.json fil ./config/frontend-config.json ./frontend-config.json + + +Example: Asking a question with mode switching options + +How would you like to proceed with this task? + +Start implementing the solution +Plan the architecture first +Continue with more details + ` } diff --git a/src/core/tools/__tests__/askFollowupQuestionTool.spec.ts b/src/core/tools/__tests__/askFollowupQuestionTool.spec.ts new file mode 100644 index 0000000000..fbb9ef9eb3 --- /dev/null +++ b/src/core/tools/__tests__/askFollowupQuestionTool.spec.ts @@ -0,0 +1,108 @@ +import { describe, it, expect, vi } from "vitest" +import { askFollowupQuestionTool } from "../askFollowupQuestionTool" +import { ToolUse } from "../../../shared/tools" + +describe("askFollowupQuestionTool", () => { + let mockCline: any + let mockPushToolResult: any + let toolResult: any + + beforeEach(() => { + vi.clearAllMocks() + + mockCline = { + ask: vi.fn().mockResolvedValue({ text: "Test response" }), + say: vi.fn().mockResolvedValue(undefined), + consecutiveMistakeCount: 0, + } + + mockPushToolResult = vi.fn((result) => { + toolResult = result + }) + }) + + it("should parse suggestions without mode attributes", async () => { + const block: ToolUse = { + type: "tool_use", + name: "ask_followup_question", + params: { + question: "What would you like to do?", + follow_up: "Option 1Option 2", + }, + partial: false, + } + + await askFollowupQuestionTool( + mockCline, + block, + vi.fn(), + vi.fn(), + mockPushToolResult, + vi.fn((tag, content) => content), + ) + + expect(mockCline.ask).toHaveBeenCalledWith( + "followup", + expect.stringContaining('"suggest":[{"answer":"Option 1"},{"answer":"Option 2"}]'), + false, + ) + }) + + it("should parse suggestions with mode attributes", async () => { + const block: ToolUse = { + type: "tool_use", + name: "ask_followup_question", + params: { + question: "What would you like to do?", + follow_up: 'Write codeDebug issue', + }, + partial: false, + } + + await askFollowupQuestionTool( + mockCline, + block, + vi.fn(), + vi.fn(), + mockPushToolResult, + vi.fn((tag, content) => content), + ) + + expect(mockCline.ask).toHaveBeenCalledWith( + "followup", + expect.stringContaining( + '"suggest":[{"answer":"Write code","mode":"code"},{"answer":"Debug issue","mode":"debug"}]', + ), + false, + ) + }) + + it("should handle mixed suggestions with and without mode attributes", async () => { + const block: ToolUse = { + type: "tool_use", + name: "ask_followup_question", + params: { + question: "What would you like to do?", + follow_up: 'Regular optionPlan architecture', + }, + partial: false, + } + + await askFollowupQuestionTool( + mockCline, + block, + vi.fn(), + vi.fn(), + mockPushToolResult, + vi.fn((tag, content) => content), + ) + + expect(mockCline.ask).toHaveBeenCalledWith( + "followup", + expect.stringContaining( + '"suggest":[{"answer":"Regular option"},{"answer":"Plan architecture","mode":"architect"}]', + ), + false, + ) + }) +}) diff --git a/src/core/tools/askFollowupQuestionTool.ts b/src/core/tools/askFollowupQuestionTool.ts index d5adf6d4cd..e736936887 100644 --- a/src/core/tools/askFollowupQuestionTool.ts +++ b/src/core/tools/askFollowupQuestionTool.ts @@ -26,7 +26,7 @@ export async function askFollowupQuestionTool( return } - type Suggest = { answer: string } + type Suggest = { answer: string; mode?: string } let follow_up_json = { question, @@ -34,12 +34,17 @@ export async function askFollowupQuestionTool( } if (follow_up) { + // Define the actual structure returned by the XML parser + type ParsedSuggestion = string | { "#text": string; "@_mode"?: string } + let parsedSuggest: { - suggest: Suggest[] | Suggest + suggest: ParsedSuggestion[] | ParsedSuggestion } try { - parsedSuggest = parseXml(follow_up, ["suggest"]) as { suggest: Suggest[] | Suggest } + parsedSuggest = parseXml(follow_up, ["suggest"]) as { + suggest: ParsedSuggestion[] | ParsedSuggestion + } } catch (error) { cline.consecutiveMistakeCount++ cline.recordToolError("ask_followup_question") @@ -48,9 +53,24 @@ export async function askFollowupQuestionTool( return } - const normalizedSuggest = Array.isArray(parsedSuggest?.suggest) + const rawSuggestions = Array.isArray(parsedSuggest?.suggest) ? parsedSuggest.suggest - : [parsedSuggest?.suggest].filter((sug): sug is Suggest => sug !== undefined) + : [parsedSuggest?.suggest].filter((sug): sug is ParsedSuggestion => sug !== undefined) + + // Transform parsed XML to our Suggest format + const normalizedSuggest: Suggest[] = rawSuggestions.map((sug) => { + if (typeof sug === "string") { + // Simple string suggestion (no mode attribute) + return { answer: sug } + } else { + // XML object with text content and optional mode attribute + const result: Suggest = { answer: sug["#text"] } + if (sug["@_mode"]) { + result.mode = sug["@_mode"] + } + return result + } + }) follow_up_json.suggest = normalizedSuggest } diff --git a/webview-ui/src/components/chat/FollowUpSuggest.tsx b/webview-ui/src/components/chat/FollowUpSuggest.tsx index 9f4c017e74..6e1ec58814 100644 --- a/webview-ui/src/components/chat/FollowUpSuggest.tsx +++ b/webview-ui/src/components/chat/FollowUpSuggest.tsx @@ -2,11 +2,17 @@ import { useCallback } from "react" import { Edit } from "lucide-react" import { Button, StandardTooltip } from "@/components/ui" +import { vscode } from "@/utils/vscode" import { useAppTranslation } from "@src/i18n/TranslationContext" +interface SuggestionItem { + answer: string + mode?: string +} + interface FollowUpSuggestProps { - suggestions?: string[] + suggestions?: (string | SuggestionItem)[] onSuggestionClick?: (answer: string, event?: React.MouseEvent) => void ts: number } @@ -14,8 +20,19 @@ interface FollowUpSuggestProps { export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }: FollowUpSuggestProps) => { const { t } = useAppTranslation() const handleSuggestionClick = useCallback( - (suggestion: string, event: React.MouseEvent) => { - onSuggestionClick?.(suggestion, event) + (suggestion: string | SuggestionItem, event: React.MouseEvent) => { + const suggestionText = typeof suggestion === "string" ? suggestion : suggestion.answer + const mode = typeof suggestion === "object" ? suggestion.mode : undefined + + // If there's a mode switch and it's not a shift-click (which just copies to input), switch modes first + if (mode && !event.shiftKey) { + vscode.postMessage({ + type: "mode", + text: mode, + }) + } + + onSuggestionClick?.(suggestionText, event) }, [onSuggestionClick], ) @@ -27,30 +44,41 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }: return (
- {suggestions.map((suggestion) => ( -
- - -
{ - e.stopPropagation() - // Simulate shift-click by directly calling the handler with shiftKey=true. - onSuggestionClick?.(suggestion, { ...e, shiftKey: true }) - }}> - -
-
-
- ))} + {suggestions.map((suggestion) => { + const suggestionText = typeof suggestion === "string" ? suggestion : suggestion.answer + const mode = typeof suggestion === "object" ? suggestion.mode : undefined + + return ( +
+ + {mode && ( +
+ + {mode} +
+ )} + +
{ + e.stopPropagation() + // Simulate shift-click by directly calling the handler with shiftKey=true. + onSuggestionClick?.(suggestionText, { ...e, shiftKey: true }) + }}> + +
+
+
+ ) + })}
) } From de99e348df22349b856f369735d57a275f27c183 Mon Sep 17 00:00:00 2001 From: Johannes <38868829+Fovty@users.noreply.github.com> Date: Sat, 28 Jun 2025 02:07:04 +0200 Subject: [PATCH 18/70] fix: resolve E2BIG error by passing large prompts via stdin to Claude CLI (#5186) * fix: resolve E2BIG error by passing large prompts via stdin to Claude CLI - Pass messages via stdin instead of command line arguments to avoid Linux argument length limits - Add --input-format text flag to claude CLI command - Update execa configuration to use stdin pipe - Fix corresponding unit tests with proper async iterator mocking - Resolves spawn E2BIG errors when using very large conversation histories * fix: address race condition and improve error handling - Use setImmediate to ensure process is spawned before writing to stdin - Add proper error handling for stdin write operations - Add tests for error scenarios - Update existing tests to handle async behavior properly * fix: remove --input-format text flag to prevent CLI parsing errors The --input-format text flag was causing the Claude CLI to misinterpret the JSON content passed via stdin, leading to errors like 'unknown option -------' when the system prompt contained dashes. Removing this flag allows the CLI to properly handle the JSON input via stdin. --------- Co-authored-by: Daniel Riccio --- .../claude-code/__tests__/run.spec.ts | 253 ++++++++++++++++++ src/integrations/claude-code/run.ts | 29 +- 2 files changed, 279 insertions(+), 3 deletions(-) diff --git a/src/integrations/claude-code/__tests__/run.spec.ts b/src/integrations/claude-code/__tests__/run.spec.ts index aa8d9fe8d2..d2fda08fc0 100644 --- a/src/integrations/claude-code/__tests__/run.spec.ts +++ b/src/integrations/claude-code/__tests__/run.spec.ts @@ -13,9 +13,92 @@ vi.mock("vscode", () => ({ }, })) +// Mock execa to test stdin behavior +const mockExeca = vi.fn() +const mockStdin = { + write: vi.fn((data, encoding, callback) => { + // Simulate successful write + if (callback) callback(null) + }), + end: vi.fn(), +} + +// Mock process that simulates successful execution +const createMockProcess = () => { + let resolveProcess: (value: { exitCode: number }) => void + const processPromise = new Promise<{ exitCode: number }>((resolve) => { + resolveProcess = resolve + }) + + const mockProcess = { + stdin: mockStdin, + stdout: { + on: vi.fn(), + }, + stderr: { + on: vi.fn((event, callback) => { + // Don't emit any stderr data in tests + }), + }, + on: vi.fn((event, callback) => { + if (event === "close") { + // Simulate successful process completion after a short delay + setTimeout(() => { + callback(0) + resolveProcess({ exitCode: 0 }) + }, 10) + } + if (event === "error") { + // Don't emit any errors in tests + } + }), + killed: false, + kill: vi.fn(), + then: processPromise.then.bind(processPromise), + catch: processPromise.catch.bind(processPromise), + finally: processPromise.finally.bind(processPromise), + } + return mockProcess +} + +vi.mock("execa", () => ({ + execa: mockExeca, +})) + +// Mock readline with proper interface simulation +let mockReadlineInterface: any = null + +vi.mock("readline", () => ({ + default: { + createInterface: vi.fn(() => { + mockReadlineInterface = { + async *[Symbol.asyncIterator]() { + // Simulate Claude CLI JSON output + yield '{"type":"text","text":"Hello"}' + yield '{"type":"text","text":" world"}' + // Simulate end of stream - must return to terminate the iterator + return + }, + close: vi.fn(), + } + return mockReadlineInterface + }), + }, +})) + describe("runClaudeCode", () => { beforeEach(() => { vi.clearAllMocks() + mockExeca.mockReturnValue(createMockProcess()) + // Mock setImmediate to run synchronously in tests + vi.spyOn(global, "setImmediate").mockImplementation((callback: any) => { + callback() + return {} as any + }) + }) + + afterEach(() => { + vi.restoreAllMocks() }) test("should export runClaudeCode function", async () => { @@ -34,4 +117,174 @@ describe("runClaudeCode", () => { expect(Symbol.asyncIterator in result).toBe(true) expect(typeof result[Symbol.asyncIterator]).toBe("function") }) + + test("should use stdin instead of command line arguments for messages", async () => { + const { runClaudeCode } = await import("../run") + const messages = [{ role: "user" as const, content: "Hello world!" }] + const options = { + systemPrompt: "You are a helpful assistant", + messages, + } + + const generator = runClaudeCode(options) + + // Consume the generator to completion + const results = [] + for await (const chunk of generator) { + results.push(chunk) + } + + // Verify execa was called with correct arguments (no JSON.stringify(messages) in args) + expect(mockExeca).toHaveBeenCalledWith( + "claude", + expect.arrayContaining([ + "-p", + "--system-prompt", + "You are a helpful assistant", + "--verbose", + "--output-format", + "stream-json", + "--disallowedTools", + expect.any(String), + "--max-turns", + "1", + ]), + expect.objectContaining({ + stdin: "pipe", + stdout: "pipe", + stderr: "pipe", + }), + ) + + // Verify the arguments do NOT contain the stringified messages + const [, args] = mockExeca.mock.calls[0] + expect(args).not.toContain(JSON.stringify(messages)) + + // Verify messages were written to stdin with callback + expect(mockStdin.write).toHaveBeenCalledWith(JSON.stringify(messages), "utf8", expect.any(Function)) + expect(mockStdin.end).toHaveBeenCalled() + + // Verify we got the expected mock output + expect(results).toHaveLength(2) + expect(results[0]).toEqual({ type: "text", text: "Hello" }) + expect(results[1]).toEqual({ type: "text", text: " world" }) + }) + + test("should include model parameter when provided", async () => { + const { runClaudeCode } = await import("../run") + const options = { + systemPrompt: "You are a helpful assistant", + messages: [{ role: "user" as const, content: "Hello" }], + modelId: "claude-3-5-sonnet-20241022", + } + + const generator = runClaudeCode(options) + + // Consume at least one item to trigger process spawn + await generator.next() + + // Clean up the generator + await generator.return(undefined) + + const [, args] = mockExeca.mock.calls[0] + expect(args).toContain("--model") + expect(args).toContain("claude-3-5-sonnet-20241022") + }) + + test("should use custom claude path when provided", async () => { + const { runClaudeCode } = await import("../run") + const options = { + systemPrompt: "You are a helpful assistant", + messages: [{ role: "user" as const, content: "Hello" }], + path: "/custom/path/to/claude", + } + + const generator = runClaudeCode(options) + + // Consume at least one item to trigger process spawn + await generator.next() + + // Clean up the generator + await generator.return(undefined) + + const [claudePath] = mockExeca.mock.calls[0] + expect(claudePath).toBe("/custom/path/to/claude") + }) + + test("should handle stdin write errors gracefully", async () => { + const { runClaudeCode } = await import("../run") + + // Create a mock process with stdin that fails + const mockProcessWithError = createMockProcess() + mockProcessWithError.stdin.write = vi.fn((data, encoding, callback) => { + // Simulate write error + if (callback) callback(new Error("EPIPE: broken pipe")) + }) + + // Mock console.error to verify error logging + const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}) + + mockExeca.mockReturnValueOnce(mockProcessWithError) + + const options = { + systemPrompt: "You are a helpful assistant", + messages: [{ role: "user" as const, content: "Hello" }], + } + + const generator = runClaudeCode(options) + + // Try to consume the generator + try { + await generator.next() + } catch (error) { + // Expected to fail + } + + // Verify error was logged + expect(consoleErrorSpy).toHaveBeenCalledWith("Error writing to Claude Code stdin:", expect.any(Error)) + + // Verify process was killed + expect(mockProcessWithError.kill).toHaveBeenCalled() + + // Clean up + consoleErrorSpy.mockRestore() + await generator.return(undefined) + }) + + test("should handle stdin access errors gracefully", async () => { + const { runClaudeCode } = await import("../run") + + // Create a mock process without stdin + const mockProcessWithoutStdin = createMockProcess() + mockProcessWithoutStdin.stdin = null as any + + // Mock console.error to verify error logging + const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}) + + mockExeca.mockReturnValueOnce(mockProcessWithoutStdin) + + const options = { + systemPrompt: "You are a helpful assistant", + messages: [{ role: "user" as const, content: "Hello" }], + } + + const generator = runClaudeCode(options) + + // Try to consume the generator + try { + await generator.next() + } catch (error) { + // Expected to fail + } + + // Verify error was logged + expect(consoleErrorSpy).toHaveBeenCalledWith("Error accessing Claude Code stdin:", expect.any(Error)) + + // Verify process was killed + expect(mockProcessWithoutStdin.kill).toHaveBeenCalled() + + // Clean up + consoleErrorSpy.mockRestore() + await generator.return(undefined) + }) }) diff --git a/src/integrations/claude-code/run.ts b/src/integrations/claude-code/run.ts index 84f1fe0902..8e37d0f303 100644 --- a/src/integrations/claude-code/run.ts +++ b/src/integrations/claude-code/run.ts @@ -112,7 +112,6 @@ function runProcess({ systemPrompt, messages, path, modelId }: ClaudeCodeOptions const args = [ "-p", - JSON.stringify(messages), "--system-prompt", systemPrompt, "--verbose", @@ -129,8 +128,8 @@ function runProcess({ systemPrompt, messages, path, modelId }: ClaudeCodeOptions args.push("--model", modelId) } - return execa(claudePath, args, { - stdin: "ignore", + const child = execa(claudePath, args, { + stdin: "pipe", stdout: "pipe", stderr: "pipe", env: { @@ -142,6 +141,30 @@ function runProcess({ systemPrompt, messages, path, modelId }: ClaudeCodeOptions maxBuffer: 1024 * 1024 * 1000, timeout: CLAUDE_CODE_TIMEOUT, }) + + // Write messages to stdin after process is spawned + // This avoids the E2BIG error on Linux when passing large messages as command line arguments + // Linux has a per-argument limit of ~128KiB for execve() system calls + const messagesJson = JSON.stringify(messages) + + // Use setImmediate to ensure the process has been spawned before writing to stdin + // This prevents potential race conditions where stdin might not be ready + setImmediate(() => { + try { + child.stdin.write(messagesJson, "utf8", (error) => { + if (error) { + console.error("Error writing to Claude Code stdin:", error) + child.kill() + } + }) + child.stdin.end() + } catch (error) { + console.error("Error accessing Claude Code stdin:", error) + child.kill() + } + }) + + return child } function parseChunk(data: string, processState: ProcessState) { From 867eaf4d708263f3a954dd91ce7a14cb57b8c7d9 Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 27 Jun 2025 19:13:46 -0500 Subject: [PATCH 19/70] fix: move StandardTooltip inside PopoverTrigger in ShareButton (#5203) --- webview-ui/src/components/chat/ShareButton.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webview-ui/src/components/chat/ShareButton.tsx b/webview-ui/src/components/chat/ShareButton.tsx index 874d640e70..20442ba76b 100644 --- a/webview-ui/src/components/chat/ShareButton.tsx +++ b/webview-ui/src/components/chat/ShareButton.tsx @@ -144,8 +144,8 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => { <> {shareButtonState.showPopover ? ( - - + + - - + + {shareSuccess ? (
From 53cf9010da2c13b7dd41176e7f44181e2c55e3c7 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Fri, 27 Jun 2025 20:16:12 -0400 Subject: [PATCH 20/70] chore: add changeset for v3.22.4 patch release (#5204) --- .changeset/v3.22.4.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/v3.22.4.md diff --git a/.changeset/v3.22.4.md b/.changeset/v3.22.4.md new file mode 100644 index 0000000000..a93bdfc488 --- /dev/null +++ b/.changeset/v3.22.4.md @@ -0,0 +1,7 @@ +--- +"roo-cline": patch +--- + +- Fix: resolve E2BIG error by passing large prompts via stdin to Claude CLI (thanks @Fovty!) +- Add optional mode suggestions to follow-up questions (thanks @mrubens!) +- Fix: move StandardTooltip inside PopoverTrigger in ShareButton (thanks @daniel-lxs!) From ad89e832807d8f1bb3ec6c6d533aae991a09f5ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 20:17:16 -0400 Subject: [PATCH 21/70] Update contributors list (#5129) Co-authored-by: mrubens <2600+mrubens@users.noreply.github.com> --- README.md | 69 +++++++++++++++++++++-------------------- locales/ca/README.md | 61 ++++++++++++++++++------------------ locales/de/README.md | 61 ++++++++++++++++++------------------ locales/es/README.md | 61 ++++++++++++++++++------------------ locales/fr/README.md | 61 ++++++++++++++++++------------------ locales/hi/README.md | 61 ++++++++++++++++++------------------ locales/id/README.md | 61 ++++++++++++++++++------------------ locales/it/README.md | 61 ++++++++++++++++++------------------ locales/ja/README.md | 61 ++++++++++++++++++------------------ locales/ko/README.md | 61 ++++++++++++++++++------------------ locales/nl/README.md | 61 ++++++++++++++++++------------------ locales/pl/README.md | 61 ++++++++++++++++++------------------ locales/pt-BR/README.md | 61 ++++++++++++++++++------------------ locales/ru/README.md | 61 ++++++++++++++++++------------------ locales/tr/README.md | 61 ++++++++++++++++++------------------ locales/vi/README.md | 61 ++++++++++++++++++------------------ locales/zh-CN/README.md | 61 ++++++++++++++++++------------------ locales/zh-TW/README.md | 61 ++++++++++++++++++------------------ 18 files changed, 562 insertions(+), 544 deletions(-) diff --git a/README.md b/README.md index af209a1429..48055236e6 100644 --- a/README.md +++ b/README.md @@ -176,40 +176,41 @@ Thanks to all our contributors who have helped make Roo Code better! -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jquanton
jquanton
| nissa-seru
nissa-seru
| jr
jr
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| sachasayan
sachasayan
| -| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| cannuri
cannuri
| feifei325
feifei325
| zhangtony239
zhangtony239
| qdaxb
qdaxb
| -| shariqriazz
shariqriazz
| pugazhendhi-m
pugazhendhi-m
| dtrugman
dtrugman
| lloydchang
lloydchang
| vigneshsubbiah16
vigneshsubbiah16
| Szpadel
Szpadel
| -| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| diarmidmackenzie
diarmidmackenzie
| -| chrarnoldus
chrarnoldus
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| afshawnlotfi
afshawnlotfi
| RaySinner
RaySinner
| nbihan-mediware
nbihan-mediware
| -| ChuKhaLi
ChuKhaLi
| hassoncs
hassoncs
| emshvac
emshvac
| kyle-apex
kyle-apex
| noritaka1166
noritaka1166
| pdecat
pdecat
| -| SannidhyaSah
SannidhyaSah
| StevenTCramer
StevenTCramer
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| benzntech
benzntech
| mr-ryan-james
mr-ryan-james
| -| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| kcwhite
kcwhite
| -| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| ashktn
ashktn
| -| franekp
franekp
| yt3trees
yt3trees
| axkirillov
axkirillov
| anton-otee
anton-otee
| bramburn
bramburn
| olearycrew
olearycrew
| -| brunobergher
brunobergher
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| -| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| ross
ross
| philfung
philfung
| dairui1
dairui1
| -| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| -| shoopapa
shoopapa
| jwcraig
jwcraig
| nevermorec
nevermorec
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| -| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| -| Githubguy132010
Githubguy132010
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| -| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| -| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| -| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| -| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| kinandan
kinandan
| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| -| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| dleen
dleen
| devxpain
devxpain
| -| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| Atlogit
Atlogit
| -| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| HadesArchitect
HadesArchitect
| alarno
alarno
| -| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| -| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| -| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| markijbema
markijbema
| -| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| KanTakahiro
KanTakahiro
| -| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| celestial-vault
celestial-vault
| +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | diff --git a/locales/ca/README.md b/locales/ca/README.md index bf342dda2c..d774b94a61 100644 --- a/locales/ca/README.md +++ b/locales/ca/README.md @@ -184,37 +184,38 @@ Grร cies a tots els nostres colยทlaboradors que han ajudat a millorar Roo Code! |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Llicรจncia diff --git a/locales/de/README.md b/locales/de/README.md index 1c1eb41f19..05fb7d3bd3 100644 --- a/locales/de/README.md +++ b/locales/de/README.md @@ -184,37 +184,38 @@ Danke an alle unsere Mitwirkenden, die geholfen haben, Roo Code zu verbessern! |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Lizenz diff --git a/locales/es/README.md b/locales/es/README.md index aa15874979..cd652e745a 100644 --- a/locales/es/README.md +++ b/locales/es/README.md @@ -184,37 +184,38 @@ Usamos [changesets](https://github.com/changesets/changesets) para versionar y p |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Licencia diff --git a/locales/fr/README.md b/locales/fr/README.md index a7100ba924..9c093562e2 100644 --- a/locales/fr/README.md +++ b/locales/fr/README.md @@ -184,37 +184,38 @@ Merci ร  tous nos contributeurs qui ont aidรฉ ร  amรฉliorer Roo Code ! |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Licence diff --git a/locales/hi/README.md b/locales/hi/README.md index 0184824533..d05baccf48 100644 --- a/locales/hi/README.md +++ b/locales/hi/README.md @@ -184,37 +184,38 @@ Roo Code เค•เฅ‹ เคฌเฅ‡เคนเคคเคฐ เคฌเคจเคพเคจเฅ‡ เคฎเฅ‡เค‚ เคฎเคฆเคฆ เค•เคฐเคจเฅ‡ |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## เคฒเคพเค‡เคธเฅ‡เค‚เคธ diff --git a/locales/id/README.md b/locales/id/README.md index 06f88d3b30..0903a209a5 100644 --- a/locales/id/README.md +++ b/locales/id/README.md @@ -178,37 +178,38 @@ Terima kasih kepada semua kontributor kami yang telah membantu membuat Roo Code |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## License diff --git a/locales/it/README.md b/locales/it/README.md index 7d96654b89..5de5eb9937 100644 --- a/locales/it/README.md +++ b/locales/it/README.md @@ -184,37 +184,38 @@ Grazie a tutti i nostri contributori che hanno aiutato a migliorare Roo Code! |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Licenza diff --git a/locales/ja/README.md b/locales/ja/README.md index d91743b525..1d31dc9da7 100644 --- a/locales/ja/README.md +++ b/locales/ja/README.md @@ -184,37 +184,38 @@ Roo Codeใฎๆ”นๅ–„ใซ่ฒข็Œฎใ—ใฆใใ‚ŒใŸใ™ในใฆใฎ่ฒข็Œฎ่€…ใซๆ„Ÿ่ฌใ—ใพใ™ |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## ใƒฉใ‚คใ‚ปใƒณใ‚น diff --git a/locales/ko/README.md b/locales/ko/README.md index d994aa3e11..d03fd157b3 100644 --- a/locales/ko/README.md +++ b/locales/ko/README.md @@ -184,37 +184,38 @@ Roo Code๋ฅผ ๋” ์ข‹๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ ๋„์›€์„ ์ค€ ๋ชจ๋“  ๊ธฐ์—ฌ์ž์—๊ฒŒ ๊ฐ์‚ฌ |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## ๋ผ์ด์„ ์Šค diff --git a/locales/nl/README.md b/locales/nl/README.md index b3094153e1..218c12b725 100644 --- a/locales/nl/README.md +++ b/locales/nl/README.md @@ -184,37 +184,38 @@ Dank aan alle bijdragers die Roo Code beter hebben gemaakt! |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Licentie diff --git a/locales/pl/README.md b/locales/pl/README.md index 687a5721b4..023f27cb15 100644 --- a/locales/pl/README.md +++ b/locales/pl/README.md @@ -184,37 +184,38 @@ Dziฤ™kujemy wszystkim naszym wspรณล‚twรณrcom, ktรณrzy pomogli ulepszyฤ‡ Roo Code |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Licencja diff --git a/locales/pt-BR/README.md b/locales/pt-BR/README.md index 8a03cc7703..74d4d36a43 100644 --- a/locales/pt-BR/README.md +++ b/locales/pt-BR/README.md @@ -184,37 +184,38 @@ Obrigado a todos os nossos contribuidores que ajudaram a tornar o Roo Code melho |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Licenรงa diff --git a/locales/ru/README.md b/locales/ru/README.md index 96db7bdb3f..3e9133cb97 100644 --- a/locales/ru/README.md +++ b/locales/ru/README.md @@ -184,37 +184,38 @@ code --install-extension bin/roo-cline-.vsix |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## ะ›ะธั†ะตะฝะทะธั diff --git a/locales/tr/README.md b/locales/tr/README.md index 6ff6f24c76..cc26916c32 100644 --- a/locales/tr/README.md +++ b/locales/tr/README.md @@ -184,37 +184,38 @@ Roo Code'u daha iyi hale getirmeye yardฤฑmcฤฑ olan tรผm katkฤฑda bulunanlara te |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Lisans diff --git a/locales/vi/README.md b/locales/vi/README.md index 56d286cd98..3f21cb2729 100644 --- a/locales/vi/README.md +++ b/locales/vi/README.md @@ -184,37 +184,38 @@ Cแบฃm ฦกn tแบฅt cแบฃ nhแปฏng ngฦฐแปi ฤ‘รณng gรณp ฤ‘รฃ giรบp cแบฃi thiแป‡n Roo C |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## Giแบฅy Phรฉp diff --git a/locales/zh-CN/README.md b/locales/zh-CN/README.md index ad89772d36..b6eb4e8ab5 100644 --- a/locales/zh-CN/README.md +++ b/locales/zh-CN/README.md @@ -184,37 +184,38 @@ code --install-extension bin/roo-cline-.vsix |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## ่ฎธๅฏ่ฏ diff --git a/locales/zh-TW/README.md b/locales/zh-TW/README.md index 245c66205a..cc4c2f67c7 100644 --- a/locales/zh-TW/README.md +++ b/locales/zh-TW/README.md @@ -185,37 +185,38 @@ code --install-extension bin/roo-cline-.vsix |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jquanton
jquanton
|nissa-seru
nissa-seru
|jr
jr
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|sachasayan
sachasayan
| -|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|cannuri
cannuri
|feifei325
feifei325
|zhangtony239
zhangtony239
|qdaxb
qdaxb
| -|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|dtrugman
dtrugman
|lloydchang
lloydchang
|vigneshsubbiah16
vigneshsubbiah16
|Szpadel
Szpadel
| -|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
|diarmidmackenzie
diarmidmackenzie
| -|chrarnoldus
chrarnoldus
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|afshawnlotfi
afshawnlotfi
|RaySinner
RaySinner
|nbihan-mediware
nbihan-mediware
| -|ChuKhaLi
ChuKhaLi
|hassoncs
hassoncs
|emshvac
emshvac
|kyle-apex
kyle-apex
|noritaka1166
noritaka1166
|pdecat
pdecat
| -|SannidhyaSah
SannidhyaSah
|StevenTCramer
StevenTCramer
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| +|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| +|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| +|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| +|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| +|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| |dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|benzntech
benzntech
|mr-ryan-james
mr-ryan-james
| -|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
|kcwhite
kcwhite
| -|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
|ashktn
ashktn
| -|franekp
franekp
|yt3trees
yt3trees
|axkirillov
axkirillov
|anton-otee
anton-otee
|bramburn
bramburn
|olearycrew
olearycrew
| -|brunobergher
brunobergher
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
| -|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
|ross
ross
|philfung
philfung
|dairui1
dairui1
| -|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
| -|shoopapa
shoopapa
|jwcraig
jwcraig
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
| -|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
| -|Githubguy132010
Githubguy132010
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
| -|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
| -|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
| -|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
| -|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|kinandan
kinandan
|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
| -|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
|devxpain
devxpain
| -|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| -|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
|alarno
alarno
| -|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
| -|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| -|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
|markijbema
markijbema
| -|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
|KanTakahiro
KanTakahiro
| -|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
|celestial-vault
celestial-vault
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| +|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| +|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| +|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| +|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| +|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| +|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| +|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| +|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| +|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| +|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| +|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| +|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| +|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| +|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| +|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| +|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| +|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| +|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| +|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| +|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| +|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | ## ๆŽˆๆฌŠ From fa693e1f06d846931eaa1232c53a4bfc326d74f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 20:20:03 -0400 Subject: [PATCH 22/70] Changeset version bump (#5205) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Matt Rubens --- .changeset/v3.22.4.md | 7 ------- CHANGELOG.md | 6 ++++++ src/package.json | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 .changeset/v3.22.4.md diff --git a/.changeset/v3.22.4.md b/.changeset/v3.22.4.md deleted file mode 100644 index a93bdfc488..0000000000 --- a/.changeset/v3.22.4.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"roo-cline": patch ---- - -- Fix: resolve E2BIG error by passing large prompts via stdin to Claude CLI (thanks @Fovty!) -- Add optional mode suggestions to follow-up questions (thanks @mrubens!) -- Fix: move StandardTooltip inside PopoverTrigger in ShareButton (thanks @daniel-lxs!) diff --git a/CHANGELOG.md b/CHANGELOG.md index 693b40db92..367671f56d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Roo Code Changelog +## [3.22.4] - 2025-06-27 + +- Fix: resolve E2BIG error by passing large prompts via stdin to Claude CLI (thanks @Fovty!) +- Add optional mode suggestions to follow-up questions +- Fix: move StandardTooltip inside PopoverTrigger in ShareButton (thanks @daniel-lxs!) + ## [3.22.3] - 2025-06-27 - Restore JSON backwards compatibility for .roomodes files (thanks @daniel-lxs!) diff --git a/src/package.json b/src/package.json index 6412b4b858..71085517db 100644 --- a/src/package.json +++ b/src/package.json @@ -3,7 +3,7 @@ "displayName": "%extension.displayName%", "description": "%extension.description%", "publisher": "RooVeterinaryInc", - "version": "3.22.3", + "version": "3.22.4", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 8bb7ef083f371f996ad56c35aa1e0e3a561e7b8b Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Sat, 28 Jun 2025 00:49:01 -0400 Subject: [PATCH 23/70] Stop double-capturing cloud telemetry (#5211) --- src/core/task/Task.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 46da7485ed..4af3372941 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -375,13 +375,18 @@ export class Task extends EventEmitter { await provider?.postMessageToWebview({ type: "messageUpdated", clineMessage: message }) this.emit("message", { action: "updated", message }) - const shouldCaptureMessage = message.partial !== true && CloudService.isEnabled() + // Only check for telemetry if the message is complete and CloudService is enabled + if (message.partial !== true && CloudService.isEnabled()) { + // Now check if this message was already captured + const previousMessage = this.clineMessages.find((m) => m.ts === message.ts) + const wasAlreadyCaptured = previousMessage && previousMessage.partial !== true - if (shouldCaptureMessage) { - CloudService.instance.captureEvent({ - event: TelemetryEventName.TASK_MESSAGE, - properties: { taskId: this.taskId, message }, - }) + if (!wasAlreadyCaptured) { + CloudService.instance.captureEvent({ + event: TelemetryEventName.TASK_MESSAGE, + properties: { taskId: this.taskId, message }, + }) + } } } From dc44e7a40b035e833881b662356fdc41c34b40f8 Mon Sep 17 00:00:00 2001 From: Will Li Date: Sat, 28 Jun 2025 06:32:27 -0700 Subject: [PATCH 24/70] Git Repo URL telemetry link fix: only Https (#5202) * https parsing in URL sanatizing for git repo * fix: remove duplicate JSDoc and add SSH to HTTPS conversion test - Remove duplicate JSDoc comment from convertGitUrlToHttps function - Add test case to verify getGitRepositoryInfo converts SSH URLs to HTTPS format --------- Co-authored-by: Daniel Riccio --- src/utils/__tests__/git.spec.ts | 84 +++++++++++++++++++++++++++++++++ src/utils/git.ts | 41 +++++++++++++++- 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/src/utils/__tests__/git.spec.ts b/src/utils/__tests__/git.spec.ts index 3dc0f6fe24..3ab306feec 100644 --- a/src/utils/__tests__/git.spec.ts +++ b/src/utils/__tests__/git.spec.ts @@ -12,6 +12,7 @@ import { extractRepositoryName, getWorkspaceGitInfo, GitRepositoryInfo, + convertGitUrlToHttps, } from "../git" import { truncateOutput } from "../../integrations/misc/extract-text" @@ -560,6 +561,89 @@ describe("getGitRepositoryInfo", () => { repositoryName: "RooCodeInc/Roo-Code", }) }) + + it("should convert SSH URLs to HTTPS format", async () => { + // Clear previous mocks + vitest.clearAllMocks() + + // Create a spy to track the implementation + const gitSpy = vitest.spyOn(fs.promises, "readFile") + + // Mock successful access to .git directory + vitest.mocked(fs.promises.access).mockResolvedValue(undefined) + + // Mock git config file with SSH URL + const mockConfig = ` +[core] + repositoryformatversion = 0 + filemode = true + bare = false +[remote "origin"] + url = git@github.com:RooCodeInc/Roo-Code.git + fetch = +refs/heads/*:refs/remotes/origin/* +[branch "main"] + remote = origin + merge = refs/heads/main +` + // Mock HEAD file content + const mockHead = "ref: refs/heads/main" + + // Setup the readFile mock to return different values based on the path + gitSpy.mockImplementation((path: any, encoding: any) => { + if (path === configPath) { + return Promise.resolve(mockConfig) + } else if (path === headPath) { + return Promise.resolve(mockHead) + } + return Promise.reject(new Error(`Unexpected path: ${path}`)) + }) + + const result = await getGitRepositoryInfo(workspaceRoot) + + // Verify that the SSH URL was converted to HTTPS + expect(result).toEqual({ + repositoryUrl: "https://github.com/RooCodeInc/Roo-Code.git", + repositoryName: "RooCodeInc/Roo-Code", + defaultBranch: "main", + }) + }) +}) + +describe("convertGitUrlToHttps", () => { + it("should leave HTTPS URLs unchanged", () => { + const url = "https://github.com/RooCodeInc/Roo-Code.git" + const converted = convertGitUrlToHttps(url) + + expect(converted).toBe("https://github.com/RooCodeInc/Roo-Code.git") + }) + + it("should convert SSH URLs to HTTPS format", () => { + const url = "git@github.com:RooCodeInc/Roo-Code.git" + const converted = convertGitUrlToHttps(url) + + expect(converted).toBe("https://github.com/RooCodeInc/Roo-Code.git") + }) + + it("should convert SSH URLs with ssh:// prefix to HTTPS format", () => { + const url = "ssh://git@github.com/RooCodeInc/Roo-Code.git" + const converted = convertGitUrlToHttps(url) + + expect(converted).toBe("https://github.com/RooCodeInc/Roo-Code.git") + }) + + it("should handle URLs without git@ prefix", () => { + const url = "ssh://github.com/RooCodeInc/Roo-Code.git" + const converted = convertGitUrlToHttps(url) + + expect(converted).toBe("https://github.com/RooCodeInc/Roo-Code.git") + }) + + it("should handle invalid URLs gracefully", () => { + const url = "not-a-valid-url" + const converted = convertGitUrlToHttps(url) + + expect(converted).toBe("not-a-valid-url") + }) }) describe("sanitizeGitUrl", () => { diff --git a/src/utils/git.ts b/src/utils/git.ts index 7ecf33172b..fd6abfa309 100644 --- a/src/utils/git.ts +++ b/src/utils/git.ts @@ -51,7 +51,8 @@ export async function getGitRepositoryInfo(workspaceRoot: string): Promise https://github.com/user/repo.git + if (url.startsWith("git@")) { + const match = url.match(/git@([^:]+):(.+)/) + if (match && match.length === 3) { + const [, host, path] = match + return `https://${host}/${path}` + } + } + + // Handle SSH with protocol: ssh://git@github.com/user/repo.git -> https://github.com/user/repo.git + if (url.startsWith("ssh://")) { + const match = url.match(/ssh:\/\/(?:git@)?([^\/]+)\/(.+)/) + if (match && match.length === 3) { + const [, host, path] = match + return `https://${host}/${path}` + } + } + + // Return original URL if we can't convert it + return url + } catch { + // If parsing fails, return original + return url + } +} + /** * Sanitizes a git URL to remove sensitive information like tokens * @param url The original git URL From f763a5119b0905d724f67f9277ce380fd282c973 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Sat, 28 Jun 2025 16:03:56 -0400 Subject: [PATCH 25/70] Revert "Stop double-capturing cloud telemetry" (#5220) --- src/core/task/Task.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 4af3372941..46da7485ed 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -375,18 +375,13 @@ export class Task extends EventEmitter { await provider?.postMessageToWebview({ type: "messageUpdated", clineMessage: message }) this.emit("message", { action: "updated", message }) - // Only check for telemetry if the message is complete and CloudService is enabled - if (message.partial !== true && CloudService.isEnabled()) { - // Now check if this message was already captured - const previousMessage = this.clineMessages.find((m) => m.ts === message.ts) - const wasAlreadyCaptured = previousMessage && previousMessage.partial !== true + const shouldCaptureMessage = message.partial !== true && CloudService.isEnabled() - if (!wasAlreadyCaptured) { - CloudService.instance.captureEvent({ - event: TelemetryEventName.TASK_MESSAGE, - properties: { taskId: this.taskId, message }, - }) - } + if (shouldCaptureMessage) { + CloudService.instance.captureEvent({ + event: TelemetryEventName.TASK_MESSAGE, + properties: { taskId: this.taskId, message }, + }) } } From d64e677f88ba9295d02ee8f0820c2ecfef24bce2 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Sat, 28 Jun 2025 23:48:28 -0400 Subject: [PATCH 26/70] Remove Gemini CLI provider (#5223) --- packages/types/src/provider-settings.ts | 8 - packages/types/src/providers/gemini-cli.ts | 110 ----- packages/types/src/providers/index.ts | 1 - src/api/index.ts | 3 - .../providers/__tests__/gemini-cli.spec.ts | 329 -------------- src/api/providers/gemini-cli.ts | 419 ------------------ src/api/providers/index.ts | 1 - src/i18n/locales/ca/common.json | 10 - src/i18n/locales/de/common.json | 10 - src/i18n/locales/en/common.json | 10 - src/i18n/locales/es/common.json | 10 - src/i18n/locales/fr/common.json | 10 - src/i18n/locales/hi/common.json | 10 - src/i18n/locales/id/common.json | 10 - src/i18n/locales/it/common.json | 10 - src/i18n/locales/ja/common.json | 10 - src/i18n/locales/ko/common.json | 10 - src/i18n/locales/nl/common.json | 10 - src/i18n/locales/pl/common.json | 10 - src/i18n/locales/pt-BR/common.json | 10 - src/i18n/locales/ru/common.json | 10 - src/i18n/locales/tr/common.json | 10 - src/i18n/locales/vi/common.json | 10 - src/i18n/locales/zh-CN/common.json | 10 - src/i18n/locales/zh-TW/common.json | 10 - src/shared/checkExistApiConfig.ts | 4 +- .../src/components/settings/ApiOptions.tsx | 7 - .../src/components/settings/constants.ts | 3 - .../settings/providers/GeminiCli.tsx | 81 ---- .../providers/__tests__/GeminiCli.spec.tsx | 169 ------- .../components/settings/providers/index.ts | 1 - .../components/ui/hooks/useSelectedModel.ts | 7 - webview-ui/src/i18n/locales/ca/settings.json | 15 - webview-ui/src/i18n/locales/de/settings.json | 15 - webview-ui/src/i18n/locales/en/settings.json | 15 - webview-ui/src/i18n/locales/es/settings.json | 15 - webview-ui/src/i18n/locales/fr/settings.json | 15 - webview-ui/src/i18n/locales/hi/settings.json | 15 - webview-ui/src/i18n/locales/id/settings.json | 15 - webview-ui/src/i18n/locales/it/settings.json | 15 - webview-ui/src/i18n/locales/ja/settings.json | 15 - webview-ui/src/i18n/locales/ko/settings.json | 15 - webview-ui/src/i18n/locales/nl/settings.json | 15 - webview-ui/src/i18n/locales/pl/settings.json | 15 - .../src/i18n/locales/pt-BR/settings.json | 15 - webview-ui/src/i18n/locales/ru/settings.json | 15 - webview-ui/src/i18n/locales/tr/settings.json | 15 - webview-ui/src/i18n/locales/vi/settings.json | 15 - .../src/i18n/locales/zh-CN/settings.json | 15 - .../src/i18n/locales/zh-TW/settings.json | 15 - webview-ui/src/utils/validate.ts | 3 - 51 files changed, 2 insertions(+), 1594 deletions(-) delete mode 100644 packages/types/src/providers/gemini-cli.ts delete mode 100644 src/api/providers/__tests__/gemini-cli.spec.ts delete mode 100644 src/api/providers/gemini-cli.ts delete mode 100644 webview-ui/src/components/settings/providers/GeminiCli.tsx delete mode 100644 webview-ui/src/components/settings/providers/__tests__/GeminiCli.spec.tsx diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index e940ececd1..609d0fefbf 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -19,7 +19,6 @@ export const providerNames = [ "vscode-lm", "lmstudio", "gemini", - "gemini-cli", "openai-native", "mistral", "deepseek", @@ -159,11 +158,6 @@ const geminiSchema = apiModelIdProviderModelSchema.extend({ googleGeminiBaseUrl: z.string().optional(), }) -const geminiCliSchema = apiModelIdProviderModelSchema.extend({ - geminiCliOAuthPath: z.string().optional(), - geminiCliProjectId: z.string().optional(), -}) - const openAiNativeSchema = apiModelIdProviderModelSchema.extend({ openAiNativeApiKey: z.string().optional(), openAiNativeBaseUrl: z.string().optional(), @@ -229,7 +223,6 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv vsCodeLmSchema.merge(z.object({ apiProvider: z.literal("vscode-lm") })), lmStudioSchema.merge(z.object({ apiProvider: z.literal("lmstudio") })), geminiSchema.merge(z.object({ apiProvider: z.literal("gemini") })), - geminiCliSchema.merge(z.object({ apiProvider: z.literal("gemini-cli") })), openAiNativeSchema.merge(z.object({ apiProvider: z.literal("openai-native") })), mistralSchema.merge(z.object({ apiProvider: z.literal("mistral") })), deepSeekSchema.merge(z.object({ apiProvider: z.literal("deepseek") })), @@ -257,7 +250,6 @@ export const providerSettingsSchema = z.object({ ...vsCodeLmSchema.shape, ...lmStudioSchema.shape, ...geminiSchema.shape, - ...geminiCliSchema.shape, ...openAiNativeSchema.shape, ...mistralSchema.shape, ...deepSeekSchema.shape, diff --git a/packages/types/src/providers/gemini-cli.ts b/packages/types/src/providers/gemini-cli.ts deleted file mode 100644 index 4ef498220e..0000000000 --- a/packages/types/src/providers/gemini-cli.ts +++ /dev/null @@ -1,110 +0,0 @@ -import type { ModelInfo } from "../model.js" - -// Gemini CLI models with free tier pricing (all $0) -export type GeminiCliModelId = keyof typeof geminiCliModels - -export const geminiCliDefaultModelId: GeminiCliModelId = "gemini-2.0-flash-001" - -export const geminiCliModels = { - "gemini-2.0-flash-001": { - maxTokens: 8192, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-2.0-flash-thinking-exp-01-21": { - maxTokens: 65_536, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-2.0-flash-thinking-exp-1219": { - maxTokens: 8192, - contextWindow: 32_767, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-2.0-flash-exp": { - maxTokens: 8192, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-1.5-flash-002": { - maxTokens: 8192, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-1.5-flash-exp-0827": { - maxTokens: 8192, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-1.5-flash-8b-exp-0827": { - maxTokens: 8192, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-1.5-pro-002": { - maxTokens: 8192, - contextWindow: 2_097_152, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-1.5-pro-exp-0827": { - maxTokens: 8192, - contextWindow: 2_097_152, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-exp-1206": { - maxTokens: 8192, - contextWindow: 2_097_152, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, - "gemini-2.5-flash": { - maxTokens: 64_000, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - maxThinkingTokens: 24_576, - supportsReasoningBudget: true, - }, - "gemini-2.5-pro": { - maxTokens: 64_000, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - maxThinkingTokens: 32_768, - supportsReasoningBudget: true, - requiredReasoningBudget: true, - }, -} as const satisfies Record diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index 0f3e96fdcb..267401bd91 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -4,7 +4,6 @@ export * from "./chutes.js" export * from "./claude-code.js" export * from "./deepseek.js" export * from "./gemini.js" -export * from "./gemini-cli.js" export * from "./glama.js" export * from "./groq.js" export * from "./lite-llm.js" diff --git a/src/api/index.ts b/src/api/index.ts index b70f7dcd45..960209f714 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -15,7 +15,6 @@ import { OllamaHandler, LmStudioHandler, GeminiHandler, - GeminiCliHandler, OpenAiNativeHandler, DeepSeekHandler, MistralHandler, @@ -86,8 +85,6 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler { return new LmStudioHandler(options) case "gemini": return new GeminiHandler(options) - case "gemini-cli": - return new GeminiCliHandler(options) case "openai-native": return new OpenAiNativeHandler(options) case "deepseek": diff --git a/src/api/providers/__tests__/gemini-cli.spec.ts b/src/api/providers/__tests__/gemini-cli.spec.ts deleted file mode 100644 index a84e940e96..0000000000 --- a/src/api/providers/__tests__/gemini-cli.spec.ts +++ /dev/null @@ -1,329 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from "vitest" -import { GeminiCliHandler } from "../gemini-cli" -import { geminiCliDefaultModelId, geminiCliModels } from "@roo-code/types" -import * as fs from "fs/promises" -import axios from "axios" - -vi.mock("fs/promises") -vi.mock("axios") -vi.mock("google-auth-library", () => ({ - OAuth2Client: vi.fn().mockImplementation(() => ({ - setCredentials: vi.fn(), - refreshAccessToken: vi.fn().mockResolvedValue({ - credentials: { - access_token: "refreshed-token", - refresh_token: "refresh-token", - token_type: "Bearer", - expiry_date: Date.now() + 3600 * 1000, - }, - }), - request: vi.fn(), - })), -})) - -describe("GeminiCliHandler", () => { - let handler: GeminiCliHandler - const mockCredentials = { - access_token: "test-access-token", - refresh_token: "test-refresh-token", - token_type: "Bearer", - expiry_date: Date.now() + 3600 * 1000, - } - - beforeEach(() => { - vi.clearAllMocks() - ;(fs.readFile as any).mockResolvedValue(JSON.stringify(mockCredentials)) - ;(fs.writeFile as any).mockResolvedValue(undefined) - - // Set up default mock - ;(axios.post as any).mockResolvedValue({ - data: {}, - }) - - handler = new GeminiCliHandler({ - apiModelId: geminiCliDefaultModelId, - }) - - // Set up default mock for OAuth2Client request - handler["authClient"].request = vi.fn().mockResolvedValue({ - data: {}, - }) - - // Mock the discoverProjectId to avoid real API calls in tests - handler["projectId"] = "test-project-123" - vi.spyOn(handler as any, "discoverProjectId").mockResolvedValue("test-project-123") - }) - - describe("constructor", () => { - it("should initialize with provided config", () => { - expect(handler["options"].apiModelId).toBe(geminiCliDefaultModelId) - }) - }) - - describe("getModel", () => { - it("should return correct model info", () => { - const modelInfo = handler.getModel() - expect(modelInfo.id).toBe(geminiCliDefaultModelId) - expect(modelInfo.info).toBeDefined() - expect(modelInfo.info.inputPrice).toBe(0) - expect(modelInfo.info.outputPrice).toBe(0) - }) - - it("should return default model if invalid model specified", () => { - const invalidHandler = new GeminiCliHandler({ - apiModelId: "invalid-model", - }) - const modelInfo = invalidHandler.getModel() - expect(modelInfo.id).toBe(geminiCliDefaultModelId) - }) - - it("should handle :thinking suffix", () => { - const thinkingHandler = new GeminiCliHandler({ - apiModelId: "gemini-2.5-pro:thinking", - }) - const modelInfo = thinkingHandler.getModel() - // The :thinking suffix should be removed from the ID - expect(modelInfo.id).toBe("gemini-2.5-pro") - // But the model should still have reasoning support - expect(modelInfo.info.supportsReasoningBudget).toBe(true) - expect(modelInfo.info.requiredReasoningBudget).toBe(true) - }) - }) - - describe("OAuth authentication", () => { - it("should load OAuth credentials from default path", async () => { - await handler["loadOAuthCredentials"]() - expect(fs.readFile).toHaveBeenCalledWith(expect.stringMatching(/\.gemini[/\\]oauth_creds\.json$/), "utf-8") - }) - - it("should load OAuth credentials from custom path", async () => { - const customHandler = new GeminiCliHandler({ - apiModelId: geminiCliDefaultModelId, - geminiCliOAuthPath: "/custom/path/oauth.json", - }) - await customHandler["loadOAuthCredentials"]() - expect(fs.readFile).toHaveBeenCalledWith("/custom/path/oauth.json", "utf-8") - }) - - it("should refresh expired tokens", async () => { - const expiredCredentials = { - ...mockCredentials, - expiry_date: Date.now() - 1000, // Expired - } - ;(fs.readFile as any).mockResolvedValueOnce(JSON.stringify(expiredCredentials)) - - await handler["ensureAuthenticated"]() - - expect(handler["authClient"].refreshAccessToken).toHaveBeenCalled() - expect(fs.writeFile).toHaveBeenCalledWith( - expect.stringMatching(/\.gemini[/\\]oauth_creds\.json$/), - expect.stringContaining("refreshed-token"), - ) - }) - - it("should throw error if credentials file not found", async () => { - ;(fs.readFile as any).mockRejectedValueOnce(new Error("ENOENT")) - - await expect(handler["loadOAuthCredentials"]()).rejects.toThrow("errors.geminiCli.oauthLoadFailed") - }) - }) - - describe("project ID discovery", () => { - it("should use provided project ID", async () => { - const customHandler = new GeminiCliHandler({ - apiModelId: geminiCliDefaultModelId, - geminiCliProjectId: "custom-project", - }) - - const projectId = await customHandler["discoverProjectId"]() - expect(projectId).toBe("custom-project") - expect(customHandler["projectId"]).toBe("custom-project") - }) - - it("should discover project ID through API", async () => { - // Create a new handler without the mocked discoverProjectId - const testHandler = new GeminiCliHandler({ - apiModelId: geminiCliDefaultModelId, - }) - testHandler["authClient"].request = vi.fn().mockResolvedValue({ - data: {}, - }) - - // Mock the callEndpoint method - testHandler["callEndpoint"] = vi.fn().mockResolvedValueOnce({ - cloudaicompanionProject: "discovered-project-123", - }) - - const projectId = await testHandler["discoverProjectId"]() - expect(projectId).toBe("discovered-project-123") - expect(testHandler["projectId"]).toBe("discovered-project-123") - }) - - it("should onboard user if no existing project", async () => { - // Create a new handler without the mocked discoverProjectId - const testHandler = new GeminiCliHandler({ - apiModelId: geminiCliDefaultModelId, - }) - testHandler["authClient"].request = vi.fn().mockResolvedValue({ - data: {}, - }) - - // Mock the callEndpoint method - testHandler["callEndpoint"] = vi - .fn() - .mockResolvedValueOnce({ - allowedTiers: [{ id: "free-tier", isDefault: true }], - }) - .mockResolvedValueOnce({ - done: false, - }) - .mockResolvedValueOnce({ - done: true, - response: { - cloudaicompanionProject: { - id: "onboarded-project-456", - }, - }, - }) - - const projectId = await testHandler["discoverProjectId"]() - expect(projectId).toBe("onboarded-project-456") - expect(testHandler["projectId"]).toBe("onboarded-project-456") - expect(testHandler["callEndpoint"]).toHaveBeenCalledTimes(3) - }) - }) - - describe("completePrompt", () => { - it("should complete prompt successfully", async () => { - handler["authClient"].request = vi.fn().mockResolvedValue({ - data: { - candidates: [ - { - content: { - parts: [{ text: "Test response" }], - }, - }, - ], - }, - }) - - const result = await handler.completePrompt("Test prompt") - expect(result).toBe("Test response") - }) - - it("should handle empty response", async () => { - handler["authClient"].request = vi.fn().mockResolvedValue({ - data: { - candidates: [], - }, - }) - - const result = await handler.completePrompt("Test prompt") - expect(result).toBe("") - }) - - it("should filter out thinking parts", async () => { - handler["authClient"].request = vi.fn().mockResolvedValue({ - data: { - candidates: [ - { - content: { - parts: [{ text: "Thinking...", thought: true }, { text: "Actual response" }], - }, - }, - ], - }, - }) - - const result = await handler.completePrompt("Test prompt") - expect(result).toBe("Actual response") - }) - - it("should handle API errors", async () => { - handler["authClient"].request = vi.fn().mockRejectedValue(new Error("API Error")) - - await expect(handler.completePrompt("Test prompt")).rejects.toThrow("errors.geminiCli.completionError") - }) - }) - - describe("createMessage streaming", () => { - it("should handle streaming response with reasoning", async () => { - // Create a mock Node.js readable stream - const { Readable } = require("stream") - const mockStream = new Readable({ - read() { - this.push('data: {"candidates":[{"content":{"parts":[{"text":"Hello"}]}}]}\n\n') - this.push( - 'data: {"candidates":[{"content":{"parts":[{"thought":true,"text":"thinking..."}]}}]}\n\n', - ) - this.push( - 'data: {"candidates":[{"content":{"parts":[{"text":" world"}]}}],"usageMetadata":{"promptTokenCount":10,"candidatesTokenCount":5}}\n\n', - ) - this.push("data: [DONE]\n\n") - this.push(null) // End the stream - }, - }) - - handler["authClient"].request = vi.fn().mockResolvedValue({ - data: mockStream, - }) - - const stream = handler.createMessage("System", []) - const chunks: any[] = [] - - for await (const chunk of stream) { - chunks.push(chunk) - } - - // Check we got the expected chunks - expect(chunks).toHaveLength(4) // 2 text chunks, 1 reasoning chunk, 1 usage chunk - - // Filter out only text chunks (not reasoning chunks) - const textChunks = chunks.filter((c) => c.type === "text").map((c) => c.text) - expect(textChunks).toEqual(["Hello", " world"]) - - // Check reasoning chunk - const reasoningChunks = chunks.filter((c) => c.type === "reasoning") - expect(reasoningChunks).toHaveLength(1) - expect(reasoningChunks[0].text).toBe("thinking...") - - // Check usage chunk - const usageChunks = chunks.filter((c) => c.type === "usage") - expect(usageChunks).toHaveLength(1) - expect(usageChunks[0]).toMatchObject({ - type: "usage", - inputTokens: 10, - outputTokens: 5, - totalCost: 0, - }) - }) - - it("should handle rate limit errors", async () => { - handler["authClient"].request = vi.fn().mockRejectedValue({ - response: { - status: 429, - data: { error: { message: "Rate limit exceeded" } }, - }, - }) - - const stream = handler.createMessage("System", []) - - await expect(async () => { - for await (const _chunk of stream) { - // Should throw before yielding - } - }).rejects.toThrow("errors.geminiCli.rateLimitExceeded") - }) - }) - - describe("countTokens", () => { - it("should fall back to base provider implementation", async () => { - const content = [{ type: "text" as const, text: "Hello world" }] - const tokenCount = await handler.countTokens(content) - - // Should return a number (tiktoken fallback) - expect(typeof tokenCount).toBe("number") - expect(tokenCount).toBeGreaterThan(0) - }) - }) -}) diff --git a/src/api/providers/gemini-cli.ts b/src/api/providers/gemini-cli.ts deleted file mode 100644 index 6e265511e4..0000000000 --- a/src/api/providers/gemini-cli.ts +++ /dev/null @@ -1,419 +0,0 @@ -import type { Anthropic } from "@anthropic-ai/sdk" -import { OAuth2Client } from "google-auth-library" -import * as fs from "fs/promises" -import * as path from "path" -import * as os from "os" -import axios from "axios" - -import { type ModelInfo, type GeminiCliModelId, geminiCliDefaultModelId, geminiCliModels } from "@roo-code/types" - -import type { ApiHandlerOptions } from "../../shared/api" -import { t } from "../../i18n" - -import { convertAnthropicContentToGemini, convertAnthropicMessageToGemini } from "../transform/gemini-format" -import type { ApiStream } from "../transform/stream" -import { getModelParams } from "../transform/model-params" - -import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index" -import { BaseProvider } from "./base-provider" - -// OAuth2 Configuration (from Cline implementation) -const OAUTH_CLIENT_ID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com" -const OAUTH_CLIENT_SECRET = "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" -const OAUTH_REDIRECT_URI = "http://localhost:45289" - -// Code Assist API Configuration -const CODE_ASSIST_ENDPOINT = "https://cloudcode-pa.googleapis.com" -const CODE_ASSIST_API_VERSION = "v1internal" - -interface OAuthCredentials { - access_token: string - refresh_token: string - token_type: string - expiry_date: number -} - -export class GeminiCliHandler extends BaseProvider implements SingleCompletionHandler { - protected options: ApiHandlerOptions - private authClient: OAuth2Client - private projectId: string | null = null - private credentials: OAuthCredentials | null = null - - constructor(options: ApiHandlerOptions) { - super() - this.options = options - - // Initialize OAuth2 client - this.authClient = new OAuth2Client(OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_REDIRECT_URI) - } - - private async loadOAuthCredentials(): Promise { - try { - const credPath = this.options.geminiCliOAuthPath || path.join(os.homedir(), ".gemini", "oauth_creds.json") - const credData = await fs.readFile(credPath, "utf-8") - this.credentials = JSON.parse(credData) - - // Set credentials on the OAuth2 client - if (this.credentials) { - this.authClient.setCredentials({ - access_token: this.credentials.access_token, - refresh_token: this.credentials.refresh_token, - expiry_date: this.credentials.expiry_date, - }) - } - } catch (error) { - throw new Error(t("common:errors.geminiCli.oauthLoadFailed", { error })) - } - } - - private async ensureAuthenticated(): Promise { - if (!this.credentials) { - await this.loadOAuthCredentials() - } - - // Check if token needs refresh - if (this.credentials && this.credentials.expiry_date < Date.now()) { - try { - const { credentials } = await this.authClient.refreshAccessToken() - if (credentials.access_token) { - this.credentials = { - access_token: credentials.access_token!, - refresh_token: credentials.refresh_token || this.credentials.refresh_token, - token_type: credentials.token_type || "Bearer", - expiry_date: credentials.expiry_date || Date.now() + 3600 * 1000, - } - // Optionally save refreshed credentials back to file - const credPath = - this.options.geminiCliOAuthPath || path.join(os.homedir(), ".gemini", "oauth_creds.json") - await fs.writeFile(credPath, JSON.stringify(this.credentials, null, 2)) - } - } catch (error) { - throw new Error(t("common:errors.geminiCli.tokenRefreshFailed", { error })) - } - } - } - - /** - * Call a Code Assist API endpoint - */ - private async callEndpoint(method: string, body: any, retryAuth: boolean = true): Promise { - try { - const res = await this.authClient.request({ - url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:${method}`, - method: "POST", - headers: { - "Content-Type": "application/json", - }, - responseType: "json", - data: JSON.stringify(body), - }) - return res.data - } catch (error: any) { - console.error(`[GeminiCLI] Error calling ${method}:`, error) - console.error(`[GeminiCLI] Error response:`, error.response?.data) - console.error(`[GeminiCLI] Error status:`, error.response?.status) - console.error(`[GeminiCLI] Error message:`, error.message) - - // If we get a 401 and haven't retried yet, try refreshing auth - if (error.response?.status === 401 && retryAuth) { - await this.ensureAuthenticated() // This will refresh the token - return this.callEndpoint(method, body, false) // Retry without further auth retries - } - - throw error - } - } - - /** - * Discover or retrieve the project ID - */ - private async discoverProjectId(): Promise { - // If we already have a project ID, use it - if (this.options.geminiCliProjectId) { - this.projectId = this.options.geminiCliProjectId - return this.projectId - } - - // If we've already discovered it, return it - if (this.projectId) { - return this.projectId - } - - // Start with a default project ID (can be anything for personal OAuth) - const initialProjectId = "default" - - // Prepare client metadata - const clientMetadata = { - ideType: "IDE_UNSPECIFIED", - platform: "PLATFORM_UNSPECIFIED", - pluginType: "GEMINI", - duetProject: initialProjectId, - } - - try { - // Call loadCodeAssist to discover the actual project ID - const loadRequest = { - cloudaicompanionProject: initialProjectId, - metadata: clientMetadata, - } - - const loadResponse = await this.callEndpoint("loadCodeAssist", loadRequest) - - // Check if we already have a project ID from the response - if (loadResponse.cloudaicompanionProject) { - this.projectId = loadResponse.cloudaicompanionProject - return this.projectId as string - } - - // If no existing project, we need to onboard - const defaultTier = loadResponse.allowedTiers?.find((tier: any) => tier.isDefault) - const tierId = defaultTier?.id || "free-tier" - - const onboardRequest = { - tierId: tierId, - cloudaicompanionProject: initialProjectId, - metadata: clientMetadata, - } - - let lroResponse = await this.callEndpoint("onboardUser", onboardRequest) - - // Poll until operation is complete with timeout protection - const MAX_RETRIES = 30 // Maximum number of retries (60 seconds total) - let retryCount = 0 - - while (!lroResponse.done && retryCount < MAX_RETRIES) { - await new Promise((resolve) => setTimeout(resolve, 2000)) - lroResponse = await this.callEndpoint("onboardUser", onboardRequest) - retryCount++ - } - - if (!lroResponse.done) { - throw new Error(t("common:errors.geminiCli.onboardingTimeout")) - } - - const discoveredProjectId = lroResponse.response?.cloudaicompanionProject?.id || initialProjectId - this.projectId = discoveredProjectId - return this.projectId as string - } catch (error: any) { - console.error("Failed to discover project ID:", error.response?.data || error.message) - throw new Error(t("common:errors.geminiCli.projectDiscoveryFailed")) - } - } - - /** - * Parse Server-Sent Events from a stream - */ - private async *parseSSEStream(stream: NodeJS.ReadableStream): AsyncGenerator { - let buffer = "" - - for await (const chunk of stream) { - buffer += chunk.toString() - const lines = buffer.split("\n") - buffer = lines.pop() || "" - - for (const line of lines) { - if (line.startsWith("data: ")) { - const data = line.slice(6).trim() - if (data === "[DONE]") continue - - try { - const parsed = JSON.parse(data) - yield parsed - } catch (e) { - console.error("Error parsing SSE data:", e) - } - } - } - } - } - - async *createMessage( - systemInstruction: string, - messages: Anthropic.Messages.MessageParam[], - metadata?: ApiHandlerCreateMessageMetadata, - ): ApiStream { - await this.ensureAuthenticated() - const projectId = await this.discoverProjectId() - - const { id: model, info, reasoning: thinkingConfig, maxTokens } = this.getModel() - - // Convert messages to Gemini format - const contents = messages.map(convertAnthropicMessageToGemini) - - // Prepare request body for Code Assist API - matching Cline's structure - const requestBody: any = { - model: model, - project: projectId, - request: { - contents: [ - { - role: "user", - parts: [{ text: systemInstruction }], - }, - ...contents, - ], - generationConfig: { - temperature: this.options.modelTemperature ?? 0.7, - maxOutputTokens: this.options.modelMaxTokens ?? maxTokens ?? 8192, - }, - }, - } - - // Add thinking config if applicable - if (thinkingConfig) { - requestBody.request.generationConfig.thinkingConfig = thinkingConfig - } - - try { - // Call Code Assist streaming endpoint using OAuth2Client - const response = await this.authClient.request({ - url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:streamGenerateContent`, - method: "POST", - params: { alt: "sse" }, - headers: { - "Content-Type": "application/json", - }, - responseType: "stream", - data: JSON.stringify(requestBody), - }) - - // Process the SSE stream - let lastUsageMetadata: any = undefined - - for await (const jsonData of this.parseSSEStream(response.data as NodeJS.ReadableStream)) { - // Extract content from the response - const responseData = jsonData.response || jsonData - const candidate = responseData.candidates?.[0] - - if (candidate?.content?.parts) { - for (const part of candidate.content.parts) { - if (part.text) { - // Check if this is a thinking/reasoning part - if (part.thought === true) { - yield { - type: "reasoning", - text: part.text, - } - } else { - yield { - type: "text", - text: part.text, - } - } - } - } - } - - // Store usage metadata for final reporting - if (responseData.usageMetadata) { - lastUsageMetadata = responseData.usageMetadata - } - - // Check if this is the final chunk - if (candidate?.finishReason) { - break - } - } - - // Yield final usage information - if (lastUsageMetadata) { - const inputTokens = lastUsageMetadata.promptTokenCount ?? 0 - const outputTokens = lastUsageMetadata.candidatesTokenCount ?? 0 - const cacheReadTokens = lastUsageMetadata.cachedContentTokenCount - const reasoningTokens = lastUsageMetadata.thoughtsTokenCount - - yield { - type: "usage", - inputTokens, - outputTokens, - cacheReadTokens, - reasoningTokens, - totalCost: 0, // Free tier - all costs are 0 - } - } - } catch (error: any) { - console.error("[GeminiCLI] API Error:", error.response?.status, error.response?.statusText) - console.error("[GeminiCLI] Error Response:", error.response?.data) - - if (error.response?.status === 429) { - throw new Error(t("common:errors.geminiCli.rateLimitExceeded")) - } - if (error.response?.status === 400) { - throw new Error( - t("common:errors.geminiCli.badRequest", { - details: JSON.stringify(error.response?.data) || error.message, - }), - ) - } - throw new Error(t("common:errors.geminiCli.apiError", { error: error.message })) - } - } - - override getModel() { - const modelId = this.options.apiModelId - // Handle :thinking suffix before checking if model exists - const baseModelId = modelId?.endsWith(":thinking") ? modelId.replace(":thinking", "") : modelId - let id = - baseModelId && baseModelId in geminiCliModels ? (baseModelId as GeminiCliModelId) : geminiCliDefaultModelId - const info: ModelInfo = geminiCliModels[id] - const params = getModelParams({ format: "gemini", modelId: id, model: info, settings: this.options }) - - // Return the cleaned model ID - return { id, info, ...params } - } - - async completePrompt(prompt: string): Promise { - await this.ensureAuthenticated() - const projectId = await this.discoverProjectId() - - try { - const { id: model } = this.getModel() - - const requestBody = { - model: model, - project: projectId, - request: { - contents: [{ role: "user", parts: [{ text: prompt }] }], - generationConfig: { - temperature: this.options.modelTemperature ?? 0.7, - }, - }, - } - - const response = await this.authClient.request({ - url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:generateContent`, - method: "POST", - headers: { - "Content-Type": "application/json", - }, - data: JSON.stringify(requestBody), - }) - - // Extract text from response - const responseData = response.data as any - if (responseData.candidates && responseData.candidates.length > 0) { - const candidate = responseData.candidates[0] - if (candidate.content && candidate.content.parts) { - const textParts = candidate.content.parts - .filter((part: any) => part.text && !part.thought) - .map((part: any) => part.text) - .join("") - return textParts - } - } - - return "" - } catch (error) { - if (error instanceof Error) { - throw new Error(t("common:errors.geminiCli.completionError", { error: error.message })) - } - throw error - } - } - - override async countTokens(content: Array): Promise { - // For OAuth/free tier, we can't use the token counting API - // Fall back to the base provider's tiktoken implementation - return super.countTokens(content) - } -} diff --git a/src/api/providers/index.ts b/src/api/providers/index.ts index 5bad9482a0..93df5c58ff 100644 --- a/src/api/providers/index.ts +++ b/src/api/providers/index.ts @@ -6,7 +6,6 @@ export { ClaudeCodeHandler } from "./claude-code" export { DeepSeekHandler } from "./deepseek" export { FakeAIHandler } from "./fake-ai" export { GeminiHandler } from "./gemini" -export { GeminiCliHandler } from "./gemini-cli" export { GlamaHandler } from "./glama" export { GroqHandler } from "./groq" export { HumanRelayHandler } from "./human-relay" diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json index eb90a77179..8e9f07c100 100644 --- a/src/i18n/locales/ca/common.json +++ b/src/i18n/locales/ca/common.json @@ -73,16 +73,6 @@ "processExitedWithError": "El procรฉs Claude Code ha sortit amb codi {{exitCode}}. Sortida d'error: {{output}}", "stoppedWithReason": "Claude Code s'ha aturat per la raรณ: {{reason}}", "apiKeyModelPlanMismatch": "Les claus API i els plans de subscripciรณ permeten models diferents. Assegura't que el model seleccionat estigui inclรฒs al teu pla." - }, - "geminiCli": { - "oauthLoadFailed": "No s'han pogut carregar les credencials OAuth. Si us plau, autentica't primer: {{error}}", - "tokenRefreshFailed": "No s'ha pogut actualitzar el token OAuth: {{error}}", - "onboardingTimeout": "L'operaciรณ d'onboarding ha esgotat el temps desprรฉs de 60 segons. Si us plau, torna-ho a provar mรฉs tard.", - "projectDiscoveryFailed": "No s'ha pogut descobrir l'ID del projecte. Assegura't d'estar autenticat amb 'gemini auth'.", - "rateLimitExceeded": "S'ha superat el lรญmit de velocitat. S'han assolit els lรญmits del nivell gratuรฏt.", - "badRequest": "Solยทlicitud incorrecta: {{details}}", - "apiError": "Error de l'API Gemini CLI: {{error}}", - "completionError": "Error de compleciรณ de Gemini CLI: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json index 48e34db479..fc4ce25de1 100644 --- a/src/i18n/locales/de/common.json +++ b/src/i18n/locales/de/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Claude Code Prozess wurde mit Code {{exitCode}} beendet. Fehlerausgabe: {{output}}", "stoppedWithReason": "Claude Code wurde mit Grund gestoppt: {{reason}}", "apiKeyModelPlanMismatch": "API-Schlรผssel und Abonnement-Plรคne erlauben verschiedene Modelle. Stelle sicher, dass das ausgewรคhlte Modell in deinem Plan enthalten ist." - }, - "geminiCli": { - "oauthLoadFailed": "Fehler beim Laden der OAuth-Anmeldedaten. Bitte authentifiziere dich zuerst: {{error}}", - "tokenRefreshFailed": "Fehler beim Aktualisieren des OAuth-Tokens: {{error}}", - "onboardingTimeout": "Onboarding-Vorgang nach 60 Sekunden abgebrochen. Bitte versuche es spรคter erneut.", - "projectDiscoveryFailed": "Projekt-ID konnte nicht ermittelt werden. Stelle sicher, dass du mit 'gemini auth' authentifiziert bist.", - "rateLimitExceeded": "Anfragenlimit รผberschritten. Die Limits des kostenlosen Tarifs wurden erreicht.", - "badRequest": "Ungรผltige Anfrage: {{details}}", - "apiError": "Gemini CLI API-Fehler: {{error}}", - "completionError": "Gemini CLI Vervollstรคndigungsfehler: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index 855a69c23b..3f19a1dd50 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Claude Code process exited with code {{exitCode}}. Error output: {{output}}", "stoppedWithReason": "Claude Code stopped with reason: {{reason}}", "apiKeyModelPlanMismatch": "API keys and subscription plans allow different models. Make sure the selected model is included in your plan." - }, - "geminiCli": { - "oauthLoadFailed": "Failed to load OAuth credentials. Please authenticate first: {{error}}", - "tokenRefreshFailed": "Failed to refresh OAuth token: {{error}}", - "onboardingTimeout": "Onboarding operation timed out after 60 seconds. Please try again later.", - "projectDiscoveryFailed": "Could not discover project ID. Make sure you're authenticated with 'gemini auth'.", - "rateLimitExceeded": "Rate limit exceeded. Free tier limits have been reached.", - "badRequest": "Bad request: {{details}}", - "apiError": "Gemini CLI API error: {{error}}", - "completionError": "Gemini CLI completion error: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json index 0de842ee44..4b3177619e 100644 --- a/src/i18n/locales/es/common.json +++ b/src/i18n/locales/es/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "El proceso de Claude Code terminรณ con cรณdigo {{exitCode}}. Salida de error: {{output}}", "stoppedWithReason": "Claude Code se detuvo por la razรณn: {{reason}}", "apiKeyModelPlanMismatch": "Las claves API y los planes de suscripciรณn permiten diferentes modelos. Asegรบrate de que el modelo seleccionado estรฉ incluido en tu plan." - }, - "geminiCli": { - "oauthLoadFailed": "Error al cargar credenciales OAuth. Por favor autentรญcate primero: {{error}}", - "tokenRefreshFailed": "Error al actualizar token OAuth: {{error}}", - "onboardingTimeout": "La operaciรณn de incorporaciรณn expirรณ despuรฉs de 60 segundos. Intรฉntalo de nuevo mรกs tarde.", - "projectDiscoveryFailed": "No se pudo descubrir el ID del proyecto. Asegรบrate de estar autenticado con 'gemini auth'.", - "rateLimitExceeded": "Lรญmite de velocidad excedido. Se han alcanzado los lรญmites del nivel gratuito.", - "badRequest": "Solicitud incorrecta: {{details}}", - "apiError": "Error de API de Gemini CLI: {{error}}", - "completionError": "Error de completado de Gemini CLI: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json index 2fcef289f4..93cd67ca15 100644 --- a/src/i18n/locales/fr/common.json +++ b/src/i18n/locales/fr/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Le processus Claude Code s'est terminรฉ avec le code {{exitCode}}. Sortie d'erreur : {{output}}", "stoppedWithReason": "Claude Code s'est arrรชtรฉ pour la raison : {{reason}}", "apiKeyModelPlanMismatch": "Les clรฉs API et les plans d'abonnement permettent diffรฉrents modรจles. Assurez-vous que le modรจle sรฉlectionnรฉ est inclus dans votre plan." - }, - "geminiCli": { - "oauthLoadFailed": "ร‰chec du chargement des identifiants OAuth. Veuillez vous authentifier d'abord : {{error}}", - "tokenRefreshFailed": "ร‰chec du renouvellement du token OAuth : {{error}}", - "onboardingTimeout": "L'opรฉration d'intรฉgration a expirรฉ aprรจs 60 secondes. Veuillez rรฉessayer plus tard.", - "projectDiscoveryFailed": "Impossible de dรฉcouvrir l'ID du projet. Assurez-vous d'รชtre authentifiรฉ avec 'gemini auth'.", - "rateLimitExceeded": "Limite de dรฉbit dรฉpassรฉe. Les limites du niveau gratuit ont รฉtรฉ atteintes.", - "badRequest": "Requรชte incorrecte : {{details}}", - "apiError": "Erreur API Gemini CLI : {{error}}", - "completionError": "Erreur de complรฉtion Gemini CLI : {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json index b799cc03b7..68788beacc 100644 --- a/src/i18n/locales/hi/common.json +++ b/src/i18n/locales/hi/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Claude Code เคชเฅเคฐเค•เฅเคฐเคฟเคฏเคพ เค•เฅ‹เคก {{exitCode}} เค•เฅ‡ เคธเคพเคฅ เคธเคฎเคพเคชเฅเคค เคนเฅเคˆเฅค เคคเฅเคฐเฅเคŸเคฟ เค†เค‰เคŸเคชเฅเคŸ: {{output}}", "stoppedWithReason": "Claude Code เค‡เคธ เค•เคพเคฐเคฃ เคธเฅ‡ เคฐเฅเค•เคพ: {{reason}}", "apiKeyModelPlanMismatch": "API เค•เฅเค‚เคœเฅ€ เค”เคฐ เคธเคฌเฅเคธเค•เฅเคฐเคฟเคชเฅเคถเคจ เคชเฅเคฒเคพเคจ เค…เคฒเค—-เค…เคฒเค— เคฎเฅ‰เคกเคฒ เค•เฅ€ เค…เคจเฅเคฎเคคเคฟ เคฆเฅ‡เคคเฅ‡ เคนเฅˆเค‚เฅค เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เค•เคฐเฅ‡เค‚ เค•เคฟ เคšเคฏเคจเคฟเคค เคฎเฅ‰เคกเคฒ เค†เคชเค•เฅ€ เคฏเฅ‹เคœเคจเคพ เคฎเฅ‡เค‚ เคถเคพเคฎเคฟเคฒ เคนเฅˆเฅค" - }, - "geminiCli": { - "oauthLoadFailed": "OAuth เค•เฅเคฐเฅ‡เคกเฅ‡เค‚เคถเคฟเคฏเคฒ เคฒเฅ‹เคก เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒเฅค เค•เฅƒเคชเคฏเคพ เคชเคนเคฒเฅ‡ เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เคฐเฅ‡เค‚: {{error}}", - "tokenRefreshFailed": "OAuth เคŸเฅ‹เค•เคจ เคฐเฅ€เคซเฅเคฐเฅ‡เคถ เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒ: {{error}}", - "onboardingTimeout": "เค‘เคจเคฌเฅ‹เคฐเฅเคกเคฟเค‚เค— เค‘เคชเคฐเฅ‡เคถเคจ 60 เคธเฅ‡เค•เค‚เคก เคฌเคพเคฆ เคŸเคพเค‡เคฎเค†เค‰เคŸ เคนเฅ‹ เค—เคฏเคพเฅค เค•เฅƒเคชเคฏเคพ เคฌเคพเคฆ เคฎเฅ‡เค‚ เคชเฅเคจเคƒ เคชเฅเคฐเคฏเคพเคธ เค•เคฐเฅ‡เค‚เฅค", - "projectDiscoveryFailed": "เคชเฅเคฐเฅ‹เคœเฅ‡เค•เฅเคŸ ID เค–เฅ‹เคœเคจเฅ‡ เคฎเฅ‡เค‚ เค…เคธเคฎเคฐเฅเคฅเฅค เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เค•เคฐเฅ‡เค‚ เค•เคฟ เค†เคช 'gemini auth' เค•เฅ‡ เคธเคพเคฅ เคชเฅเคฐเคฎเคพเคฃเคฟเคค เคนเฅˆเค‚เฅค", - "rateLimitExceeded": "เคฆเคฐ เคธเฅ€เคฎเคพ เคชเคพเคฐ เคนเฅ‹ เค—เคˆเฅค เคฎเฅเคซเฅเคค เคŸเคฟเคฏเคฐ เค•เฅ€ เคธเฅ€เคฎเคพ เคชเคนเฅเค‚เคš เค—เคˆ เคนเฅˆเฅค", - "badRequest": "เค—เคฒเคค เค…เคจเฅเคฐเฅ‹เคง: {{details}}", - "apiError": "Gemini CLI API เคคเฅเคฐเฅเคŸเคฟ: {{error}}", - "completionError": "Gemini CLI เคชเฅ‚เคฐเฅเคฃเคคเคพ เคคเฅเคฐเฅเคŸเคฟ: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json index 9ddd5ca2de..d6bb2ffa98 100644 --- a/src/i18n/locales/id/common.json +++ b/src/i18n/locales/id/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Proses Claude Code keluar dengan kode {{exitCode}}. Output error: {{output}}", "stoppedWithReason": "Claude Code berhenti karena alasan: {{reason}}", "apiKeyModelPlanMismatch": "Kunci API dan paket berlangganan memungkinkan model yang berbeda. Pastikan model yang dipilih termasuk dalam paket Anda." - }, - "geminiCli": { - "oauthLoadFailed": "Gagal memuat kredensial OAuth. Silakan autentikasi terlebih dahulu: {{error}}", - "tokenRefreshFailed": "Gagal memperbarui token OAuth: {{error}}", - "onboardingTimeout": "Operasi onboarding habis waktu setelah 60 detik. Silakan coba lagi nanti.", - "projectDiscoveryFailed": "Tidak dapat menemukan ID proyek. Pastikan Anda terautentikasi dengan 'gemini auth'.", - "rateLimitExceeded": "Batas kecepatan terlampaui. Batas tingkat gratis telah tercapai.", - "badRequest": "Permintaan tidak valid: {{details}}", - "apiError": "Kesalahan API Gemini CLI: {{error}}", - "completionError": "Kesalahan penyelesaian Gemini CLI: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json index d34a14d840..0ef6ee5b54 100644 --- a/src/i18n/locales/it/common.json +++ b/src/i18n/locales/it/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Il processo Claude Code รจ terminato con codice {{exitCode}}. Output di errore: {{output}}", "stoppedWithReason": "Claude Code si รจ fermato per il motivo: {{reason}}", "apiKeyModelPlanMismatch": "Le chiavi API e i piani di abbonamento consentono modelli diversi. Assicurati che il modello selezionato sia incluso nel tuo piano." - }, - "geminiCli": { - "oauthLoadFailed": "Impossibile caricare le credenziali OAuth. Autenticati prima: {{error}}", - "tokenRefreshFailed": "Impossibile aggiornare il token OAuth: {{error}}", - "onboardingTimeout": "L'operazione di onboarding รจ scaduta dopo 60 secondi. Riprova piรน tardi.", - "projectDiscoveryFailed": "Impossibile scoprire l'ID del progetto. Assicurati di essere autenticato con 'gemini auth'.", - "rateLimitExceeded": "Limite di velocitร  superato. I limiti del livello gratuito sono stati raggiunti.", - "badRequest": "Richiesta non valida: {{details}}", - "apiError": "Errore API Gemini CLI: {{error}}", - "completionError": "Errore di completamento Gemini CLI: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index 0e6afe18cf..b132470eac 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Claude Code ใƒ—ใƒญใ‚ปใ‚นใŒใ‚ณใƒผใƒ‰ {{exitCode}} ใง็ต‚ไบ†ใ—ใพใ—ใŸใ€‚ใ‚จใƒฉใƒผๅ‡บๅŠ›๏ผš{{output}}", "stoppedWithReason": "Claude Code ใŒ็†็”ฑใซใ‚ˆใ‚Šๅœๆญขใ—ใพใ—ใŸ๏ผš{{reason}}", "apiKeyModelPlanMismatch": "API ใ‚ญใƒผใจใ‚ตใƒ–ใ‚นใ‚ฏใƒชใƒ—ใ‚ทใƒงใƒณใƒ—ใƒฉใƒณใงใฏ็•ฐใชใ‚‹ใƒขใƒ‡ใƒซใŒๅˆฉ็”จๅฏ่ƒฝใงใ™ใ€‚้ธๆŠžใ—ใŸใƒขใƒ‡ใƒซใŒใƒ—ใƒฉใƒณใซๅซใพใ‚Œใฆใ„ใ‚‹ใ“ใจใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚" - }, - "geminiCli": { - "oauthLoadFailed": "OAuth่ช่จผๆƒ…ๅ ฑใฎ่ชญใฟ่พผใฟใซๅคฑๆ•—ใ—ใพใ—ใŸใ€‚ใพใš่ช่จผใ—ใฆใใ ใ•ใ„: {{error}}", - "tokenRefreshFailed": "OAuthใƒˆใƒผใ‚ฏใƒณใฎๆ›ดๆ–ฐใซๅคฑๆ•—ใ—ใพใ—ใŸ: {{error}}", - "onboardingTimeout": "ใ‚ชใƒณใƒœใƒผใƒ‡ใ‚ฃใƒณใ‚ฐๆ“ไฝœใŒ60็ง’ใงใ‚ฟใ‚คใƒ ใ‚ขใ‚ฆใƒˆใ—ใพใ—ใŸใ€‚ๅพŒใงใ‚‚ใ†ไธ€ๅบฆใŠ่ฉฆใ—ใใ ใ•ใ„ใ€‚", - "projectDiscoveryFailed": "ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆIDใ‚’็™บ่ฆ‹ใงใใพใ›ใ‚“ใงใ—ใŸใ€‚'gemini auth'ใง่ช่จผใ•ใ‚Œใฆใ„ใ‚‹ใ“ใจใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚", - "rateLimitExceeded": "ใƒฌใƒผใƒˆๅˆถ้™ใ‚’่ถ…้Žใ—ใพใ—ใŸใ€‚็„กๆ–™ใƒ—ใƒฉใƒณใฎๅˆถ้™ใซ้”ใ—ใฆใ„ใพใ™ใ€‚", - "badRequest": "ไธๆญฃใชใƒชใ‚ฏใ‚จใ‚นใƒˆ: {{details}}", - "apiError": "Gemini CLI APIใ‚จใƒฉใƒผ: {{error}}", - "completionError": "Gemini CLI่ฃœๅฎŒใ‚จใƒฉใƒผ: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json index affba735ab..079bb56a48 100644 --- a/src/i18n/locales/ko/common.json +++ b/src/i18n/locales/ko/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Claude Code ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ฝ”๋“œ {{exitCode}}๋กœ ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ์ถœ๋ ฅ: {{output}}", "stoppedWithReason": "Claude Code๊ฐ€ ๋‹ค์Œ ์ด์œ ๋กœ ์ค‘์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค: {{reason}}", "apiKeyModelPlanMismatch": "API ํ‚ค์™€ ๊ตฌ๋… ํ”Œ๋žœ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋ธ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒํ•œ ๋ชจ๋ธ์ด ํ”Œ๋žœ์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”." - }, - "geminiCli": { - "oauthLoadFailed": "OAuth ์ž๊ฒฉ ์ฆ๋ช…์„ ๋กœ๋“œํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ธ์ฆํ•˜์„ธ์š”: {{error}}", - "tokenRefreshFailed": "OAuth ํ† ํฐ์„ ์ƒˆ๋กœ ๊ณ ์น˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค: {{error}}", - "onboardingTimeout": "์˜จ๋ณด๋”ฉ ์ž‘์—…์ด 60์ดˆ ํ›„ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋‹ค์‹œ ์‹œ๋„ํ•˜์„ธ์š”.", - "projectDiscoveryFailed": "ํ”„๋กœ์ ํŠธ ID๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. 'gemini auth'๋กœ ์ธ์ฆ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.", - "rateLimitExceeded": "์†๋„ ์ œํ•œ์„ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌด๋ฃŒ ๋“ฑ๊ธ‰ ์ œํ•œ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.", - "badRequest": "์ž˜๋ชป๋œ ์š”์ฒญ: {{details}}", - "apiError": "Gemini CLI API ์˜ค๋ฅ˜: {{error}}", - "completionError": "Gemini CLI ์™„์„ฑ ์˜ค๋ฅ˜: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json index b0748a5aa6..ef27bef3d8 100644 --- a/src/i18n/locales/nl/common.json +++ b/src/i18n/locales/nl/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Claude Code proces beรซindigd met code {{exitCode}}. Foutuitvoer: {{output}}", "stoppedWithReason": "Claude Code gestopt om reden: {{reason}}", "apiKeyModelPlanMismatch": "API-sleutels en abonnementsplannen staan verschillende modellen toe. Zorg ervoor dat het geselecteerde model is opgenomen in je plan." - }, - "geminiCli": { - "oauthLoadFailed": "Kan OAuth-referenties niet laden. Authenticeer eerst: {{error}}", - "tokenRefreshFailed": "Kan OAuth-token niet vernieuwen: {{error}}", - "onboardingTimeout": "Onboarding-operatie is na 60 seconden verlopen. Probeer het later opnieuw.", - "projectDiscoveryFailed": "Kan project-ID niet ontdekken. Zorg ervoor dat je geauthenticeerd bent met 'gemini auth'.", - "rateLimitExceeded": "Snelheidslimiet overschreden. Gratis tier limieten zijn bereikt.", - "badRequest": "Ongeldig verzoek: {{details}}", - "apiError": "Gemini CLI API-fout: {{error}}", - "completionError": "Gemini CLI voltooiingsfout: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json index b8cd29976f..777bbd82b7 100644 --- a/src/i18n/locales/pl/common.json +++ b/src/i18n/locales/pl/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Proces Claude Code zakoล„czyล‚ siฤ™ kodem {{exitCode}}. Wyjล›cie bล‚ฤ™du: {{output}}", "stoppedWithReason": "Claude Code zatrzymaล‚ siฤ™ z powodu: {{reason}}", "apiKeyModelPlanMismatch": "Klucze API i plany subskrypcji pozwalajฤ… na rรณลผne modele. Upewnij siฤ™, ลผe wybrany model jest zawarty w twoim planie." - }, - "geminiCli": { - "oauthLoadFailed": "Nie udaล‚o siฤ™ zaล‚adowaฤ‡ danych uwierzytelniajฤ…cych OAuth. Najpierw siฤ™ uwierzytelnij: {{error}}", - "tokenRefreshFailed": "Nie udaล‚o siฤ™ odล›wieลผyฤ‡ tokenu OAuth: {{error}}", - "onboardingTimeout": "Operacja wdraลผania przekroczyล‚a limit czasu po 60 sekundach. Sprรณbuj ponownie pรณลบniej.", - "projectDiscoveryFailed": "Nie moลผna odkryฤ‡ ID projektu. Upewnij siฤ™, ลผe jesteล› uwierzytelniony za pomocฤ… 'gemini auth'.", - "rateLimitExceeded": "Przekroczono limit szybkoล›ci. Osiฤ…gniฤ™to limity darmowego poziomu.", - "badRequest": "Nieprawidล‚owe ลผฤ…danie: {{details}}", - "apiError": "Bล‚ฤ…d API Gemini CLI: {{error}}", - "completionError": "Bล‚ฤ…d uzupeล‚niania Gemini CLI: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json index 25779949d2..18695588c8 100644 --- a/src/i18n/locales/pt-BR/common.json +++ b/src/i18n/locales/pt-BR/common.json @@ -73,16 +73,6 @@ "processExitedWithError": "O processo Claude Code saiu com cรณdigo {{exitCode}}. Saรญda de erro: {{output}}", "stoppedWithReason": "Claude Code parou pela razรฃo: {{reason}}", "apiKeyModelPlanMismatch": "Chaves de API e planos de assinatura permitem modelos diferentes. Certifique-se de que o modelo selecionado esteja incluรญdo no seu plano." - }, - "geminiCli": { - "oauthLoadFailed": "Falha ao carregar credenciais OAuth. Por favor, autentique-se primeiro: {{error}}", - "tokenRefreshFailed": "Falha ao atualizar token OAuth: {{error}}", - "onboardingTimeout": "A operaรงรฃo de integraรงรฃo expirou apรณs 60 segundos. Por favor, tente novamente mais tarde.", - "projectDiscoveryFailed": "Nรฃo foi possรญvel descobrir o ID do projeto. Certifique-se de estar autenticado com 'gemini auth'.", - "rateLimitExceeded": "Limite de taxa excedido. Os limites do nรญvel gratuito foram atingidos.", - "badRequest": "Solicitaรงรฃo invรกlida: {{details}}", - "apiError": "Erro da API Gemini CLI: {{error}}", - "completionError": "Erro de conclusรฃo do Gemini CLI: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json index 006b7af222..b0e4f58ceb 100644 --- a/src/i18n/locales/ru/common.json +++ b/src/i18n/locales/ru/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "ะŸั€ะพั†ะตัั Claude Code ะทะฐะฒะตั€ัˆะธะปัั ั ะบะพะดะพะผ {{exitCode}}. ะ’ั‹ะฒะพะด ะพัˆะธะฑะบะธ: {{output}}", "stoppedWithReason": "Claude Code ะพัั‚ะฐะฝะพะฒะธะปัั ะฟะพ ะฟั€ะธั‡ะธะฝะต: {{reason}}", "apiKeyModelPlanMismatch": "API-ะบะปัŽั‡ะธ ะธ ะฟะปะฐะฝั‹ ะฟะพะดะฟะธัะบะธ ะฟะพะทะฒะพะปััŽั‚ ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ ั€ะฐะทะฝั‹ะต ะผะพะดะตะปะธ. ะฃะฑะตะดะธั‚ะตััŒ, ั‡ั‚ะพ ะฒั‹ะฑั€ะฐะฝะฝะฐั ะผะพะดะตะปัŒ ะฒะบะปัŽั‡ะตะฝะฐ ะฒ ะฒะฐัˆ ะฟะปะฐะฝ." - }, - "geminiCli": { - "oauthLoadFailed": "ะะต ัƒะดะฐะปะพััŒ ะทะฐะณั€ัƒะทะธั‚ัŒ ัƒั‡ะตั‚ะฝั‹ะต ะดะฐะฝะฝั‹ะต OAuth. ะกะฝะฐั‡ะฐะปะฐ ะฒั‹ะฟะพะปะฝะธั‚ะต ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ: {{error}}", - "tokenRefreshFailed": "ะะต ัƒะดะฐะปะพััŒ ะพะฑะฝะพะฒะธั‚ัŒ ั‚ะพะบะตะฝ OAuth: {{error}}", - "onboardingTimeout": "ะžะฟะตั€ะฐั†ะธั ะฟะพะดะบะปัŽั‡ะตะฝะธั ะธัั‚ะตะบะปะฐ ั‡ะตั€ะตะท 60 ัะตะบัƒะฝะด. ะŸะพะถะฐะปัƒะนัั‚ะฐ, ะฟะพะฟั€ะพะฑัƒะนั‚ะต ะฟะพะทะถะต.", - "projectDiscoveryFailed": "ะะต ัƒะดะฐะปะพััŒ ะพะฑะฝะฐั€ัƒะถะธั‚ัŒ ะธะดะตะฝั‚ะธั„ะธะบะฐั‚ะพั€ ะฟั€ะพะตะบั‚ะฐ. ะฃะฑะตะดะธั‚ะตััŒ, ั‡ั‚ะพ ะฒั‹ ะฐัƒั‚ะตะฝั‚ะธั„ะธั†ะธั€ะพะฒะฐะฝั‹ ั ะฟะพะผะพั‰ัŒัŽ 'gemini auth'.", - "rateLimitExceeded": "ะŸั€ะตะฒั‹ัˆะตะฝ ะปะธะผะธั‚ ัะบะพั€ะพัั‚ะธ. ะ”ะพัั‚ะธะณะฝัƒั‚ั‹ ะปะธะผะธั‚ั‹ ะฑะตัะฟะปะฐั‚ะฝะพะณะพ ัƒั€ะพะฒะฝั.", - "badRequest": "ะะตะฒะตั€ะฝั‹ะน ะทะฐะฟั€ะพั: {{details}}", - "apiError": "ะžัˆะธะฑะบะฐ API Gemini CLI: {{error}}", - "completionError": "ะžัˆะธะฑะบะฐ ะทะฐะฒะตั€ัˆะตะฝะธั Gemini CLI: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json index 87635c61ef..9663cac808 100644 --- a/src/i18n/locales/tr/common.json +++ b/src/i18n/locales/tr/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Claude Code iลŸlemi {{exitCode}} koduyla รงฤฑktฤฑ. Hata รงฤฑktฤฑsฤฑ: {{output}}", "stoppedWithReason": "Claude Code ลŸu nedenle durdu: {{reason}}", "apiKeyModelPlanMismatch": "API anahtarlarฤฑ ve abonelik planlarฤฑ farklฤฑ modellere izin verir. Seรงilen modelin planฤฑnฤฑza dahil olduฤŸundan emin olun." - }, - "geminiCli": { - "oauthLoadFailed": "OAuth kimlik bilgileri yรผklenemedi. Lรผtfen รถnce kimlik doฤŸrulamasฤฑ yapฤฑn: {{error}}", - "tokenRefreshFailed": "OAuth token yenilenemedi: {{error}}", - "onboardingTimeout": "Onboarding iลŸlemi 60 saniye sonra zaman aลŸฤฑmฤฑna uฤŸradฤฑ. Lรผtfen daha sonra tekrar deneyin.", - "projectDiscoveryFailed": "Proje ID'si keลŸfedilemedi. 'gemini auth' ile kimlik doฤŸrulamasฤฑ yaptฤฑฤŸฤฑnฤฑzdan emin olun.", - "rateLimitExceeded": "Hฤฑz sฤฑnฤฑrฤฑ aลŸฤฑldฤฑ. รœcretsiz seviye sฤฑnฤฑrlarฤฑna ulaลŸฤฑldฤฑ.", - "badRequest": "Geรงersiz istek: {{details}}", - "apiError": "Gemini CLI API hatasฤฑ: {{error}}", - "completionError": "Gemini CLI tamamlama hatasฤฑ: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json index 7321b3e8a6..5a9d0983f8 100644 --- a/src/i18n/locales/vi/common.json +++ b/src/i18n/locales/vi/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Tiแบฟn trรฌnh Claude Code thoรกt vแป›i mรฃ {{exitCode}}. ฤแบงu ra lแป—i: {{output}}", "stoppedWithReason": "Claude Code dแปซng lแบกi vรฌ lรฝ do: {{reason}}", "apiKeyModelPlanMismatch": "Khรณa API vร  gรณi ฤ‘ฤƒng kรฝ cho phรฉp cรกc mรด hรฌnh khรกc nhau. ฤแบฃm bแบฃo rแบฑng mรด hรฌnh ฤ‘รฃ chแปn ฤ‘ฦฐแปฃc bao gแป“m trong gรณi cแปงa bแบกn." - }, - "geminiCli": { - "oauthLoadFailed": "Khรดng thแปƒ tแบฃi thรดng tin xรกc thแปฑc OAuth. Vui lรฒng xรกc thแปฑc trฦฐแป›c: {{error}}", - "tokenRefreshFailed": "Khรดng thแปƒ lร m mแป›i token OAuth: {{error}}", - "onboardingTimeout": "Thao tรกc onboarding ฤ‘รฃ hแบฟt thแปi gian chแป sau 60 giรขy. Vui lรฒng thแปญ lแบกi sau.", - "projectDiscoveryFailed": "Khรดng thแปƒ khรกm phรก ID dแปฑ รกn. ฤแบฃm bแบฃo bแบกn ฤ‘รฃ xรกc thแปฑc bแบฑng 'gemini auth'.", - "rateLimitExceeded": "ฤรฃ vฦฐแปฃt quรก giแป›i hแบกn tแป‘c ฤ‘แป™. ฤรฃ ฤ‘แบกt ฤ‘แบฟn giแป›i hแบกn cแปงa gรณi miแป…n phรญ.", - "badRequest": "Yรชu cแบงu khรดng hแปฃp lแป‡: {{details}}", - "apiError": "Lแป—i API Gemini CLI: {{error}}", - "completionError": "Lแป—i hoร n thร nh Gemini CLI: {{error}}" } }, "warnings": { diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json index 9ebdd04b95..b355c2ec35 100644 --- a/src/i18n/locales/zh-CN/common.json +++ b/src/i18n/locales/zh-CN/common.json @@ -74,16 +74,6 @@ "processExitedWithError": "Claude Code ่ฟ›็จ‹้€€ๅ‡บ๏ผŒ้€€ๅ‡บ็ ๏ผš{{exitCode}}ใ€‚้”™่ฏฏ่พ“ๅ‡บ๏ผš{{output}}", "stoppedWithReason": "Claude Code ๅœๆญข๏ผŒๅŽŸๅ› ๏ผš{{reason}}", "apiKeyModelPlanMismatch": "API ๅฏ†้’ฅๅ’Œ่ฎข้˜…่ฎกๅˆ’ๆ”ฏๆŒไธๅŒ็š„ๆจกๅž‹ใ€‚่ฏท็กฎไฟๆ‰€้€‰ๆจกๅž‹ๅŒ…ๅซๅœจๆ‚จ็š„่ฎกๅˆ’ไธญใ€‚" - }, - "geminiCli": { - "oauthLoadFailed": "ๅŠ ่ฝฝ OAuth ๅ‡ญๆฎๅคฑ่ดฅใ€‚่ฏทๅ…ˆ่ฟ›่กŒ่บซไปฝ้ชŒ่ฏ๏ผš{{error}}", - "tokenRefreshFailed": "ๅˆทๆ–ฐ OAuth Token ๅคฑ่ดฅ๏ผš{{error}}", - "onboardingTimeout": "ๅ…ฅ้—จๆ“ไฝœๅœจ 60 ็ง’ๅŽ่ถ…ๆ—ถใ€‚่ฏท็จๅŽ้‡่ฏ•ใ€‚", - "projectDiscoveryFailed": "ๆ— ๆณ•ๅ‘็Žฐ้กน็›ฎ IDใ€‚่ฏท็กฎไฟๅทฒไฝฟ็”จ 'gemini auth' ่ฟ›่กŒ่บซไปฝ้ชŒ่ฏใ€‚", - "rateLimitExceeded": "API ่ฏทๆฑ‚้ข‘็އ้™ๅˆถๅทฒ่ถ…ๅ‡บใ€‚ๅ…่ดนๅฑ‚็บง้™ๅˆถๅทฒ่พพๅˆฐใ€‚", - "badRequest": "่ฏทๆฑ‚้”™่ฏฏ๏ผš{{details}}", - "apiError": "Gemini CLI API ้”™่ฏฏ๏ผš{{error}}", - "completionError": "Gemini CLI ่กฅๅ…จ้”™่ฏฏ๏ผš{{error}}" } }, "warnings": { diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json index a63e87f61a..6c1c9747aa 100644 --- a/src/i18n/locales/zh-TW/common.json +++ b/src/i18n/locales/zh-TW/common.json @@ -69,16 +69,6 @@ "processExitedWithError": "Claude Code ็จ‹ๅบ้€€ๅ‡บ๏ผŒ้€€ๅ‡บ็ขผ๏ผš{{exitCode}}ใ€‚้Œฏ่ชค่ผธๅ‡บ๏ผš{{output}}", "stoppedWithReason": "Claude Code ๅœๆญข๏ผŒๅŽŸๅ› ๏ผš{{reason}}", "apiKeyModelPlanMismatch": "API ้‡‘้‘ฐๅ’Œ่จ‚้–ฑๆ–นๆกˆๅ…่จฑไธๅŒ็š„ๆจกๅž‹ใ€‚่ซ‹็ขบไฟๆ‰€้ธๆจกๅž‹ๅŒ…ๅซๅœจๆ‚จ็š„ๆ–นๆกˆไธญใ€‚" - }, - "geminiCli": { - "oauthLoadFailed": "็„กๆณ•่ผ‰ๅ…ฅ OAuth ๆ†‘่ญ‰ใ€‚่ซ‹ๅ…ˆ้€ฒ่กŒ้ฉ—่ญ‰๏ผš{{error}}", - "tokenRefreshFailed": "็„กๆณ•้‡ๆ–ฐๆ•ด็† OAuth ๆฌŠๆ–๏ผš{{error}}", - "onboardingTimeout": "ๆ–ฐๆ‰‹ๅฐŽๅผ•ๆ“ไฝœๅœจ 60 ็ง’ๅพŒ้€พๆ™‚ใ€‚่ซ‹็จๅพŒๅ†่ฉฆใ€‚", - "projectDiscoveryFailed": "็„กๆณ•็™ผ็พๅฐˆๆกˆ IDใ€‚่ซ‹็ขบไฟๆ‚จๅทฒไฝฟ็”จ 'gemini auth' ้€ฒ่กŒ้ฉ—่ญ‰ใ€‚", - "rateLimitExceeded": "่ถ…้Ž้€Ÿ็އ้™ๅˆถใ€‚ๅทฒ้”ๅˆฐๅ…่ฒปๅฑค็ดš้™ๅˆถใ€‚", - "badRequest": "้Œฏ่ชค็š„่ซ‹ๆฑ‚๏ผš{{details}}", - "apiError": "Gemini CLI API ้Œฏ่ชค๏ผš{{error}}", - "completionError": "Gemini CLI ๅฎŒๆˆ้Œฏ่ชค๏ผš{{error}}" } }, "warnings": { diff --git a/src/shared/checkExistApiConfig.ts b/src/shared/checkExistApiConfig.ts index d54e98ec8e..eca2dd4fe0 100644 --- a/src/shared/checkExistApiConfig.ts +++ b/src/shared/checkExistApiConfig.ts @@ -5,8 +5,8 @@ export function checkExistKey(config: ProviderSettings | undefined) { return false } - // Special case for human-relay, fake-ai, claude-code, and gemini-cli providers which don't need any configuration. - if (config.apiProvider && ["human-relay", "fake-ai", "claude-code", "gemini-cli"].includes(config.apiProvider)) { + // Special case for human-relay, fake-ai, and claude-code providers which don't need any configuration. + if (config.apiProvider && ["human-relay", "fake-ai", "claude-code"].includes(config.apiProvider)) { return true } diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index ca96502e82..8f6050f4f2 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -15,7 +15,6 @@ import { anthropicDefaultModelId, claudeCodeDefaultModelId, geminiDefaultModelId, - geminiCliDefaultModelId, deepSeekDefaultModelId, mistralDefaultModelId, xaiDefaultModelId, @@ -41,7 +40,6 @@ import { ClaudeCode, DeepSeek, Gemini, - GeminiCli, Glama, Groq, LMStudio, @@ -261,7 +259,6 @@ const ApiOptions = ({ "claude-code": { field: "apiModelId", default: claudeCodeDefaultModelId }, "openai-native": { field: "apiModelId", default: openAiNativeDefaultModelId }, gemini: { field: "apiModelId", default: geminiDefaultModelId }, - "gemini-cli": { field: "apiModelId", default: geminiCliDefaultModelId }, deepseek: { field: "apiModelId", default: deepSeekDefaultModelId }, mistral: { field: "apiModelId", default: mistralDefaultModelId }, xai: { field: "apiModelId", default: xaiDefaultModelId }, @@ -417,10 +414,6 @@ const ApiOptions = ({ )} - {selectedProvider === "gemini-cli" && ( - - )} - {selectedProvider === "openai" && ( void -} - -export const GeminiCli = ({ apiConfiguration, setApiConfigurationField }: GeminiCliProps) => { - const { t } = useAppTranslation() - - const handleInputChange = useCallback( - ( - field: K, - transform: (event: E) => ProviderSettings[K] = inputEventTransform, - ) => - (event: E | Event) => { - setApiConfigurationField(field, transform(event as E)) - }, - [setApiConfigurationField], - ) - - return ( - <> - - - -
- {t("settings:providers.geminiCli.oauthPathDescription")} -
- -
- {t("settings:providers.geminiCli.description")} -
- -
- {t("settings:providers.geminiCli.instructions")}{" "} - gemini{" "} - {t("settings:providers.geminiCli.instructionsContinued")} -
- - - {t("settings:providers.geminiCli.setupLink")} - - -
-
- - {t("settings:providers.geminiCli.requirementsTitle")} -
-
    -
  • {t("settings:providers.geminiCli.requirement1")}
  • -
  • {t("settings:providers.geminiCli.requirement2")}
  • -
  • {t("settings:providers.geminiCli.requirement3")}
  • -
  • {t("settings:providers.geminiCli.requirement4")}
  • -
  • {t("settings:providers.geminiCli.requirement5")}
  • -
-
- -
- - - {t("settings:providers.geminiCli.freeAccess")} - -
- - ) -} diff --git a/webview-ui/src/components/settings/providers/__tests__/GeminiCli.spec.tsx b/webview-ui/src/components/settings/providers/__tests__/GeminiCli.spec.tsx deleted file mode 100644 index dc9c82f200..0000000000 --- a/webview-ui/src/components/settings/providers/__tests__/GeminiCli.spec.tsx +++ /dev/null @@ -1,169 +0,0 @@ -import { render, screen, fireEvent } from "@testing-library/react" -import { describe, it, expect, vi } from "vitest" - -import type { ProviderSettings } from "@roo-code/types" - -import { GeminiCli } from "../GeminiCli" - -// Mock the translation hook -vi.mock("@src/i18n/TranslationContext", () => ({ - useAppTranslation: () => ({ - t: (key: string) => key, - }), -})) - -// Mock VSCodeLink to render as a regular anchor tag -vi.mock("@vscode/webview-ui-toolkit/react", async () => { - const actual = await vi.importActual("@vscode/webview-ui-toolkit/react") - return { - ...actual, - VSCodeLink: ({ children, href, ...props }: any) => ( - - {children} - - ), - } -}) - -describe("GeminiCli", () => { - const mockSetApiConfigurationField = vi.fn() - const defaultProps = { - apiConfiguration: {} as ProviderSettings, - setApiConfigurationField: mockSetApiConfigurationField, - } - - beforeEach(() => { - vi.clearAllMocks() - }) - - it("renders all required elements", () => { - render() - - // Check for OAuth path input - expect(screen.getByText("settings:providers.geminiCli.oauthPath")).toBeInTheDocument() - expect(screen.getByPlaceholderText("~/.gemini/oauth_creds.json")).toBeInTheDocument() - - // Check for description text - expect(screen.getByText("settings:providers.geminiCli.description")).toBeInTheDocument() - - // Check for instructions - they're in the same div but broken up by the code element - // Find all elements that contain the instruction parts - const instructionsDivs = screen.getAllByText((_content, element) => { - // Check if this element contains all the expected text parts - const fullText = element?.textContent || "" - return ( - fullText.includes("settings:providers.geminiCli.instructions") && - fullText.includes("gemini") && - fullText.includes("settings:providers.geminiCli.instructionsContinued") - ) - }) - // Find the div with the correct classes - const instructionsDiv = instructionsDivs.find( - (div) => - div.classList.contains("text-sm") && - div.classList.contains("text-vscode-descriptionForeground") && - div.classList.contains("mt-2"), - ) - expect(instructionsDiv).toBeDefined() - expect(instructionsDiv).toBeInTheDocument() - - // Also verify the code element exists - const codeElement = screen.getByText("gemini") - expect(codeElement).toBeInTheDocument() - expect(codeElement.tagName).toBe("CODE") - - // Check for setup link - expect(screen.getByText("settings:providers.geminiCli.setupLink")).toBeInTheDocument() - - // Check for requirements - expect(screen.getByText("settings:providers.geminiCli.requirementsTitle")).toBeInTheDocument() - expect(screen.getByText("settings:providers.geminiCli.requirement1")).toBeInTheDocument() - expect(screen.getByText("settings:providers.geminiCli.requirement2")).toBeInTheDocument() - expect(screen.getByText("settings:providers.geminiCli.requirement3")).toBeInTheDocument() - expect(screen.getByText("settings:providers.geminiCli.requirement4")).toBeInTheDocument() - expect(screen.getByText("settings:providers.geminiCli.requirement5")).toBeInTheDocument() - - // Check for free access note - expect(screen.getByText("settings:providers.geminiCli.freeAccess")).toBeInTheDocument() - }) - - it("displays OAuth path from configuration", () => { - const apiConfiguration: ProviderSettings = { - geminiCliOAuthPath: "/custom/path/oauth.json", - } - - render() - - const oauthInput = screen.getByDisplayValue("/custom/path/oauth.json") - expect(oauthInput).toBeInTheDocument() - }) - - it("calls setApiConfigurationField when OAuth path is changed", () => { - render() - - const oauthInput = screen.getByPlaceholderText("~/.gemini/oauth_creds.json") - - // Simulate input event with VSCodeTextField - fireEvent.input(oauthInput, { target: { value: "/new/path.json" } }) - - // Check that setApiConfigurationField was called - expect(mockSetApiConfigurationField).toHaveBeenCalledWith("geminiCliOAuthPath", "/new/path.json") - }) - - it("renders setup link with correct href", () => { - render() - - const setupLink = screen.getByText("settings:providers.geminiCli.setupLink") - expect(setupLink).toHaveAttribute( - "href", - "https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quickstart", - ) - }) - - it("shows OAuth path description", () => { - render() - - expect(screen.getByText("settings:providers.geminiCli.oauthPathDescription")).toBeInTheDocument() - }) - - it("renders all requirements in a list", () => { - render() - - const listItems = screen.getAllByRole("listitem") - expect(listItems).toHaveLength(5) - expect(listItems[0]).toHaveTextContent("settings:providers.geminiCli.requirement1") - expect(listItems[1]).toHaveTextContent("settings:providers.geminiCli.requirement2") - expect(listItems[2]).toHaveTextContent("settings:providers.geminiCli.requirement3") - expect(listItems[3]).toHaveTextContent("settings:providers.geminiCli.requirement4") - expect(listItems[4]).toHaveTextContent("settings:providers.geminiCli.requirement5") - }) - - it("applies correct styling classes", () => { - render() - - // Check for styled warning box - const warningBox = screen.getByText("settings:providers.geminiCli.requirementsTitle").closest("div.mt-3") - expect(warningBox).toHaveClass("bg-vscode-editorWidget-background") - expect(warningBox).toHaveClass("border-vscode-editorWidget-border") - expect(warningBox).toHaveClass("rounded") - expect(warningBox).toHaveClass("p-3") - - // Check for warning icon - const warningIcon = screen.getByText("settings:providers.geminiCli.requirementsTitle").previousElementSibling - expect(warningIcon).toHaveClass("codicon-warning") - expect(warningIcon).toHaveClass("text-vscode-notificationsWarningIcon-foreground") - - // Check for check icon - const checkIcon = screen.getByText("settings:providers.geminiCli.freeAccess").previousElementSibling - expect(checkIcon).toHaveClass("codicon-check") - expect(checkIcon).toHaveClass("text-vscode-notificationsInfoIcon-foreground") - }) - - it("renders instructions with code element", () => { - render() - - const codeElement = screen.getByText("gemini") - expect(codeElement.tagName).toBe("CODE") - expect(codeElement).toHaveClass("text-vscode-textPreformat-foreground") - }) -}) diff --git a/webview-ui/src/components/settings/providers/index.ts b/webview-ui/src/components/settings/providers/index.ts index 4c7b3c9f0b..b195607430 100644 --- a/webview-ui/src/components/settings/providers/index.ts +++ b/webview-ui/src/components/settings/providers/index.ts @@ -4,7 +4,6 @@ export { Chutes } from "./Chutes" export { ClaudeCode } from "./ClaudeCode" export { DeepSeek } from "./DeepSeek" export { Gemini } from "./Gemini" -export { GeminiCli } from "./GeminiCli" export { Glama } from "./Glama" export { Groq } from "./Groq" export { LMStudio } from "./LMStudio" diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 35ed30fb3f..40c1ff2431 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -10,8 +10,6 @@ import { deepSeekModels, geminiDefaultModelId, geminiModels, - geminiCliDefaultModelId, - geminiCliModels, mistralDefaultModelId, mistralModels, openAiModelInfoSaneDefaults, @@ -159,11 +157,6 @@ function getSelectedModel({ const info = geminiModels[id as keyof typeof geminiModels] return { id, info } } - case "gemini-cli": { - const id = apiConfiguration.apiModelId ?? geminiCliDefaultModelId - const info = geminiCliModels[id as keyof typeof geminiCliModels] - return { id, info } - } case "deepseek": { const id = apiConfiguration.apiModelId ?? deepSeekDefaultModelId const info = deepSeekModels[id as keyof typeof deepSeekModels] diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index b3906fb50e..ea4f974149 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Ruta del Codi Claude", "description": "Ruta opcional al teu CLI de Claude Code. Per defecte, 'claude' si no s'estableix.", "placeholder": "Per defecte: claude" - }, - "geminiCli": { - "description": "Aquest proveรฏdor utilitza l'autenticaciรณ OAuth de l'eina Gemini CLI i no requereix claus d'API.", - "oauthPath": "Ruta de Credencials OAuth (opcional)", - "oauthPathDescription": "Ruta al fitxer de credencials OAuth. Deixa buit per utilitzar la ubicaciรณ per defecte (~/.gemini/oauth_creds.json).", - "instructions": "Si encara no t'has autenticat, executa", - "instructionsContinued": "al teu terminal primer.", - "setupLink": "Instruccions de Configuraciรณ de Gemini CLI", - "requirementsTitle": "Requisits Importants", - "requirement1": "Primer, necessites instalยทlar l'eina Gemini CLI", - "requirement2": "Desprรฉs, executa gemini al teu terminal i assegura't d'iniciar sessiรณ amb Google", - "requirement3": "Nomรฉs funciona amb comptes personals de Google (no comptes de Google Workspace)", - "requirement4": "No utilitza claus d'API - l'autenticaciรณ es gestiona via OAuth", - "requirement5": "Requereix que l'eina Gemini CLI estigui instalยทlada i autenticada primer", - "freeAccess": "Accรฉs gratuรฏt via autenticaciรณ OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index ad78931d81..c5e161bafe 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Claude-Code-Pfad", "description": "Optionaler Pfad zu Ihrer Claude Code CLI. Standard ist 'claude', wenn nicht festgelegt.", "placeholder": "Standard: claude" - }, - "geminiCli": { - "description": "Dieser Anbieter verwendet OAuth-Authentifizierung vom Gemini CLI-Tool und benรถtigt keine API-Schlรผssel.", - "oauthPath": "OAuth-Anmeldedaten-Pfad (optional)", - "oauthPathDescription": "Pfad zur OAuth-Anmeldedaten-Datei. Leer lassen, um den Standardort zu verwenden (~/.gemini/oauth_creds.json).", - "instructions": "Falls du dich noch nicht authentifiziert hast, fรผhre bitte", - "instructionsContinued": "in deinem Terminal zuerst aus.", - "setupLink": "Gemini CLI Setup-Anweisungen", - "requirementsTitle": "Wichtige Anforderungen", - "requirement1": "Zuerst musst du das Gemini CLI-Tool installieren", - "requirement2": "Dann fรผhre gemini in deinem Terminal aus und stelle sicher, dass du dich mit Google anmeldest", - "requirement3": "Funktioniert nur mit persรถnlichen Google-Konten (nicht mit Google Workspace-Konten)", - "requirement4": "Verwendet keine API-Schlรผssel - Authentifizierung wird รผber OAuth abgewickelt", - "requirement5": "Erfordert, dass das Gemini CLI-Tool zuerst installiert und authentifiziert wird", - "freeAccess": "Kostenloser Zugang รผber OAuth-Authentifizierung" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 9083d4a204..14981ea499 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Claude Code Path", "description": "Optional path to your Claude Code CLI. Defaults to 'claude' if not set.", "placeholder": "Default: claude" - }, - "geminiCli": { - "description": "This provider uses OAuth authentication from the Gemini CLI tool and does not require API keys.", - "oauthPath": "OAuth Credentials Path (optional)", - "oauthPathDescription": "Path to the OAuth credentials file. Leave empty to use the default location (~/.gemini/oauth_creds.json).", - "instructions": "If you haven't authenticated yet, please run", - "instructionsContinued": "in your terminal first.", - "setupLink": "Gemini CLI Setup Instructions", - "requirementsTitle": "Important Requirements", - "requirement1": "First, you need to install the Gemini CLI tool", - "requirement2": "Then, run gemini in your terminal and make sure you Log in with Google", - "requirement3": "Only works with personal Google accounts (not Google Workspace accounts)", - "requirement4": "Does not use API keys - authentication is handled via OAuth", - "requirement5": "Requires the Gemini CLI tool to be installed and authenticated first", - "freeAccess": "Free tier access via OAuth authentication" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index c83237d4f3..3e3d20cce1 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Ruta de Claude Code", "description": "Ruta opcional a su CLI de Claude Code. Por defecto, es 'claude' si no se establece.", "placeholder": "Por defecto: claude" - }, - "geminiCli": { - "description": "Este proveedor usa autenticaciรณn OAuth de la herramienta Gemini CLI y no requiere claves API.", - "oauthPath": "Ruta de Credenciales OAuth (opcional)", - "oauthPathDescription": "Ruta al archivo de credenciales OAuth. Deja vacรญo para usar la ubicaciรณn predeterminada (~/.gemini/oauth_creds.json).", - "instructions": "Si aรบn no te has autenticado, por favor ejecuta", - "instructionsContinued": "en tu terminal primero.", - "setupLink": "Instrucciones de Configuraciรณn de Gemini CLI", - "requirementsTitle": "Requisitos Importantes", - "requirement1": "Primero, necesitas instalar la herramienta Gemini CLI", - "requirement2": "Luego, ejecuta gemini en tu terminal y asegรบrate de iniciar sesiรณn con Google", - "requirement3": "Solo funciona con cuentas personales de Google (no cuentas de Google Workspace)", - "requirement4": "No usa claves API - la autenticaciรณn se maneja vรญa OAuth", - "requirement5": "Requiere que la herramienta Gemini CLI estรฉ instalada y autenticada primero", - "freeAccess": "Acceso gratuito vรญa autenticaciรณn OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 681d95be98..5635251876 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Chemin du code Claude", "description": "Chemin facultatif vers votre CLI Claude Code. La valeur par dรฉfaut est 'claude' si non dรฉfini.", "placeholder": "Dรฉfaut : claude" - }, - "geminiCli": { - "description": "Ce fournisseur utilise l'authentification OAuth de l'outil Gemini CLI et ne nรฉcessite pas de clรฉs API.", - "oauthPath": "Chemin des Identifiants OAuth (optionnel)", - "oauthPathDescription": "Chemin vers le fichier d'identifiants OAuth. Laissez vide pour utiliser l'emplacement par dรฉfaut (~/.gemini/oauth_creds.json).", - "instructions": "Si vous ne vous รชtes pas encore authentifiรฉ, veuillez exรฉcuter", - "instructionsContinued": "dans votre terminal d'abord.", - "setupLink": "Instructions de Configuration Gemini CLI", - "requirementsTitle": "Exigences Importantes", - "requirement1": "D'abord, vous devez installer l'outil Gemini CLI", - "requirement2": "Ensuite, exรฉcutez gemini dans votre terminal et assurez-vous de vous connecter avec Google", - "requirement3": "Fonctionne uniquement avec les comptes Google personnels (pas les comptes Google Workspace)", - "requirement4": "N'utilise pas de clรฉs API - l'authentification est gรฉrรฉe via OAuth", - "requirement5": "Nรฉcessite que l'outil Gemini CLI soit installรฉ et authentifiรฉ d'abord", - "freeAccess": "Accรจs gratuit via l'authentification OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 9d8bef3711..8de5bd1a19 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -308,21 +308,6 @@ "pathLabel": "เค•เฅเคฒเคพเค‰เคก เค•เฅ‹เคก เคชเคฅ", "description": "เค†เคชเค•เฅ‡ เค•เฅเคฒเคพเค‰เคก เค•เฅ‹เคก เคธเฅ€เคเคฒเค†เคˆ เค•เคพ เคตเฅˆเค•เคฒเฅเคชเคฟเค• เคชเคฅเฅค เคฏเคฆเคฟ เคธเฅ‡เคŸ เคจเคนเฅ€เค‚ เคนเฅˆ เคคเฅ‹ เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ 'claude' เคนเฅˆเฅค", "placeholder": "เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ: claude" - }, - "geminiCli": { - "description": "เคฏเคน เคชเฅเคฐเคฆเคพเคคเคพ Gemini CLI เคŸเฅ‚เคฒ เคธเฅ‡ OAuth เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เคพ เค‰เคชเคฏเฅ‹เค— เค•เคฐเคคเคพ เคนเฅˆ เค”เคฐ API เค•เฅเค‚เคœเคฟเคฏเฅ‹เค‚ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เคจเคนเฅ€เค‚ เคนเฅˆเฅค", - "oauthPath": "OAuth เค•เฅเคฐเฅ‡เคกเฅ‡เค‚เคถเคฟเคฏเคฒ เคชเคฅ (เคตเฅˆเค•เคฒเฅเคชเคฟเค•)", - "oauthPathDescription": "OAuth เค•เฅเคฐเฅ‡เคกเฅ‡เค‚เคถเคฟเคฏเคฒ เคซเคผเคพเค‡เคฒ เค•เคพ เคชเคฅเฅค เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ เคธเฅเคฅเคพเคจ (~/.gemini/oauth_creds.json) เค•เคพ เค‰เคชเคฏเฅ‹เค— เค•เคฐเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค–เคพเคฒเฅ€ เค›เฅ‹เคกเคผเฅ‡เค‚เฅค", - "instructions": "เคฏเคฆเคฟ เค†เคชเคจเฅ‡ เค…เคญเฅ€ เคคเค• เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เคจเคนเฅ€เค‚ เค•เคฟเคฏเคพ เคนเฅˆ, เคคเฅ‹ เค•เฅƒเคชเคฏเคพ เคชเคนเคฒเฅ‡", - "instructionsContinued": "เค•เฅ‹ เค…เคชเคจเฅ‡ เคŸเคฐเฅเคฎเคฟเคจเคฒ เคฎเฅ‡เค‚ เคšเคฒเคพเคเค‚เฅค", - "setupLink": "Gemini CLI เคธเฅ‡เคŸเค…เคช เคจเคฟเคฐเฅเคฆเฅ‡เคถ", - "requirementsTitle": "เคฎเคนเคคเฅเคตเคชเฅ‚เคฐเฅเคฃ เค†เคตเคถเฅเคฏเค•เคคเคพเคเค‚", - "requirement1": "เคชเคนเคฒเฅ‡, เค†เคชเค•เฅ‹ Gemini CLI เคŸเฅ‚เคฒ เค‡เค‚เคธเฅเคŸเฅ‰เคฒ เค•เคฐเคจเคพ เคนเฅ‹เค—เคพ", - "requirement2": "เคซเคฟเคฐ, เค…เคชเคจเฅ‡ เคŸเคฐเฅเคฎเคฟเคจเคฒ เคฎเฅ‡เค‚ gemini เคšเคฒเคพเคเค‚ เค”เคฐ เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เค•เคฐเฅ‡เค‚ เค•เคฟ เค†เคช Google เคธเฅ‡ เคฒเฅ‰เค— เค‡เคจ เค•เคฐเฅ‡เค‚", - "requirement3": "เค•เฅ‡เคตเคฒ เคตเฅเคฏเค•เฅเคคเคฟเค—เคค Google เค–เคพเคคเฅ‹เค‚ เค•เฅ‡ เคธเคพเคฅ เค•เคพเคฎ เค•เคฐเคคเคพ เคนเฅˆ (Google Workspace เค–เคพเคคเฅ‡ เคจเคนเฅ€เค‚)", - "requirement4": "API เค•เฅเค‚เคœเคฟเคฏเฅ‹เค‚ เค•เคพ เค‰เคชเคฏเฅ‹เค— เคจเคนเฅ€เค‚ เค•เคฐเคคเคพ - เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ OAuth เค•เฅ‡ เคฎเคพเคงเฅเคฏเคฎ เคธเฅ‡ เคธเค‚เคญเคพเคฒเคพ เคœเคพเคคเคพ เคนเฅˆ", - "requirement5": "Gemini CLI เคŸเฅ‚เคฒ เค•เฅ‹ เคชเคนเคฒเฅ‡ เค‡เค‚เคธเฅเคŸเฅ‰เคฒ เค”เคฐ เคชเฅเคฐเคฎเคพเคฃเคฟเคค เค•เคฐเคจเฅ‡ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เคนเฅˆ", - "freeAccess": "OAuth เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เฅ‡ เคฎเคพเคงเฅเคฏเคฎ เคธเฅ‡ เคฎเฅเคซเฅเคค เคชเคนเฅเค‚เคš" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index c5e3abf45c..8def303c05 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -312,21 +312,6 @@ "pathLabel": "Jalur Kode Claude", "description": "Jalur opsional ke Claude Code CLI Anda. Defaultnya adalah 'claude' jika tidak diatur.", "placeholder": "Default: claude" - }, - "geminiCli": { - "description": "Penyedia ini menggunakan autentikasi OAuth dari alat Gemini CLI dan tidak memerlukan kunci API.", - "oauthPath": "Jalur Kredensial OAuth (opsional)", - "oauthPathDescription": "Jalur ke file kredensial OAuth. Biarkan kosong untuk menggunakan lokasi default (~/.gemini/oauth_creds.json).", - "instructions": "Jika Anda belum melakukan autentikasi, jalankan", - "instructionsContinued": "di terminal Anda terlebih dahulu.", - "setupLink": "Petunjuk Pengaturan Gemini CLI", - "requirementsTitle": "Persyaratan Penting", - "requirement1": "Pertama, Anda perlu menginstal alat Gemini CLI", - "requirement2": "Kemudian, jalankan gemini di terminal Anda dan pastikan Anda masuk dengan Google", - "requirement3": "Hanya berfungsi dengan akun Google pribadi (bukan akun Google Workspace)", - "requirement4": "Tidak menggunakan kunci API - autentikasi ditangani melalui OAuth", - "requirement5": "Memerlukan alat Gemini CLI diinstal dan diautentikasi terlebih dahulu", - "freeAccess": "Akses gratis melalui autentikasi OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index fefdcd2ca2..572f99cbb0 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Percorso Claude Code", "description": "Percorso facoltativo per la tua CLI Claude Code. Predefinito 'claude' se non impostato.", "placeholder": "Predefinito: claude" - }, - "geminiCli": { - "description": "Questo provider utilizza l'autenticazione OAuth dallo strumento Gemini CLI e non richiede chiavi API.", - "oauthPath": "Percorso Credenziali OAuth (opzionale)", - "oauthPathDescription": "Percorso al file delle credenziali OAuth. Lascia vuoto per utilizzare la posizione predefinita (~/.gemini/oauth_creds.json).", - "instructions": "Se non ti sei ancora autenticato, esegui", - "instructionsContinued": "nel tuo terminale prima.", - "setupLink": "Istruzioni di Configurazione Gemini CLI", - "requirementsTitle": "Requisiti Importanti", - "requirement1": "Prima, devi installare lo strumento Gemini CLI", - "requirement2": "Poi, esegui gemini nel tuo terminale e assicurati di accedere con Google", - "requirement3": "Funziona solo con account Google personali (non account Google Workspace)", - "requirement4": "Non utilizza chiavi API - l'autenticazione รจ gestita tramite OAuth", - "requirement5": "Richiede che lo strumento Gemini CLI sia installato e autenticato prima", - "freeAccess": "Accesso gratuito tramite autenticazione OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index f5d198a8d4..c6a681e549 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -308,21 +308,6 @@ "pathLabel": "ใ‚ฏใƒญใƒผใƒ‰ใ‚ณใƒผใƒ‰ใƒ‘ใ‚น", "description": "Claude Code CLIใธใฎใ‚ชใƒ—ใ‚ทใƒงใƒณใƒ‘ใ‚นใ€‚่จญๅฎšใ•ใ‚Œใฆใ„ใชใ„ๅ ดๅˆใ€ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฏใ€Œclaudeใ€ใงใ™ใ€‚", "placeholder": "ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆ๏ผšclaude" - }, - "geminiCli": { - "description": "ใ“ใฎใƒ—ใƒญใƒใ‚คใƒ€ใƒผใฏGemini CLIใƒ„ใƒผใƒซใ‹ใ‚‰ใฎOAuth่ช่จผใ‚’ไฝฟ็”จใ—ใ€APIใ‚ญใƒผใฏๅฟ…่ฆใ‚ใ‚Šใพใ›ใ‚“ใ€‚", - "oauthPath": "OAuth่ช่จผๆƒ…ๅ ฑใƒ‘ใ‚น๏ผˆใ‚ชใƒ—ใ‚ทใƒงใƒณ๏ผ‰", - "oauthPathDescription": "OAuth่ช่จผๆƒ…ๅ ฑใƒ•ใ‚กใ‚คใƒซใธใฎใƒ‘ใ‚นใ€‚ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎๅ ดๆ‰€๏ผˆ~/.gemini/oauth_creds.json๏ผ‰ใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆใฏ็ฉบใฎใพใพใซใ—ใฆใใ ใ•ใ„ใ€‚", - "instructions": "ใพใ ่ช่จผใ—ใฆใ„ใชใ„ๅ ดๅˆใฏใ€ใพใš", - "instructionsContinued": "ใ‚’ใ‚ฟใƒผใƒŸใƒŠใƒซใงๅฎŸ่กŒใ—ใฆใใ ใ•ใ„ใ€‚", - "setupLink": "Gemini CLI ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ๆ‰‹้ †", - "requirementsTitle": "้‡่ฆใช่ฆไปถ", - "requirement1": "ใพใšใ€Gemini CLIใƒ„ใƒผใƒซใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™", - "requirement2": "ๆฌกใซใ€ใ‚ฟใƒผใƒŸใƒŠใƒซใงgeminiใ‚’ๅฎŸ่กŒใ—ใ€Googleใงใƒญใ‚ฐใ‚คใƒณใ™ใ‚‹ใ“ใจใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„", - "requirement3": "ๅ€‹ไบบใฎGoogleใ‚ขใ‚ซใ‚ฆใƒณใƒˆใงใฎใฟๅ‹•ไฝœใ—ใพใ™๏ผˆGoogle Workspaceใ‚ขใ‚ซใ‚ฆใƒณใƒˆใฏไธๅฏ๏ผ‰", - "requirement4": "APIใ‚ญใƒผใฏไฝฟ็”จใ—ใพใ›ใ‚“ - ่ช่จผใฏOAuthใงๅ‡ฆ็†ใ•ใ‚Œใพใ™", - "requirement5": "Gemini CLIใƒ„ใƒผใƒซใŒๆœ€ๅˆใซใ‚คใƒณใ‚นใƒˆใƒผใƒซใ•ใ‚Œใ€่ช่จผใ•ใ‚Œใฆใ„ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™", - "freeAccess": "OAuth่ช่จผใซใ‚ˆใ‚‹็„กๆ–™ใ‚ขใ‚ฏใ‚ปใ‚น" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 5476b044bf..6ae68428bd 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -308,21 +308,6 @@ "pathLabel": "ํด๋กœ๋“œ ์ฝ”๋“œ ๊ฒฝ๋กœ", "description": "Claude Code CLI์˜ ์„ ํƒ์  ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด 'claude'๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ž…๋‹ˆ๋‹ค.", "placeholder": "๊ธฐ๋ณธ๊ฐ’: claude" - }, - "geminiCli": { - "description": "์ด ๊ณต๊ธ‰์ž๋Š” Gemini CLI ๋„๊ตฌ์˜ OAuth ์ธ์ฆ์„ ์‚ฌ์šฉํ•˜๋ฉฐ API ํ‚ค๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.", - "oauthPath": "OAuth ์ž๊ฒฉ ์ฆ๋ช… ๊ฒฝ๋กœ (์„ ํƒ์‚ฌํ•ญ)", - "oauthPathDescription": "OAuth ์ž๊ฒฉ ์ฆ๋ช… ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์œ„์น˜(~/.gemini/oauth_creds.json)๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋น„์›Œ๋‘์„ธ์š”.", - "instructions": "์•„์ง ์ธ์ฆํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด", - "instructionsContinued": "๋ฅผ ํ„ฐ๋ฏธ๋„์—์„œ ๋จผ์ € ์‹คํ–‰ํ•˜์„ธ์š”.", - "setupLink": "Gemini CLI ์„ค์ • ์ง€์นจ", - "requirementsTitle": "์ค‘์š”ํ•œ ์š”๊ตฌ์‚ฌํ•ญ", - "requirement1": "๋จผ์ € Gemini CLI ๋„๊ตฌ๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค", - "requirement2": "๊ทธ ๋‹ค์Œ ํ„ฐ๋ฏธ๋„์—์„œ gemini๋ฅผ ์‹คํ–‰ํ•˜๊ณ  Google๋กœ ๋กœ๊ทธ์ธํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”", - "requirement3": "๊ฐœ์ธ Google ๊ณ„์ •์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค (Google Workspace ๊ณ„์ • ๋ถˆ๊ฐ€)", - "requirement4": "API ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค - ์ธ์ฆ์€ OAuth๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค", - "requirement5": "Gemini CLI ๋„๊ตฌ๊ฐ€ ๋จผ์ € ์„ค์น˜๋˜๊ณ  ์ธ์ฆ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค", - "freeAccess": "OAuth ์ธ์ฆ์„ ํ†ตํ•œ ๋ฌด๋ฃŒ ์•ก์„ธ์Šค" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 88a66c0d5f..c6d1bb7992 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Claude Code Pad", "description": "Optioneel pad naar uw Claude Code CLI. Standaard 'claude' als niet ingesteld.", "placeholder": "Standaard: claude" - }, - "geminiCli": { - "description": "Deze provider gebruikt OAuth-authenticatie van de Gemini CLI-tool en vereist geen API-sleutels.", - "oauthPath": "OAuth-referentiepad (optioneel)", - "oauthPathDescription": "Pad naar het OAuth-referentiebestand. Laat leeg om de standaardlocatie te gebruiken (~/.gemini/oauth_creds.json).", - "instructions": "Als je nog niet bent geauthenticeerd, voer dan eerst", - "instructionsContinued": "uit in je terminal.", - "setupLink": "Gemini CLI Setup-instructies", - "requirementsTitle": "Belangrijke vereisten", - "requirement1": "Eerst moet je de Gemini CLI-tool installeren", - "requirement2": "Voer vervolgens gemini uit in je terminal en zorg ervoor dat je inlogt met Google", - "requirement3": "Werkt alleen met persoonlijke Google-accounts (geen Google Workspace-accounts)", - "requirement4": "Gebruikt geen API-sleutels - authenticatie wordt afgehandeld via OAuth", - "requirement5": "Vereist dat de Gemini CLI-tool eerst wordt geรฏnstalleerd en geauthenticeerd", - "freeAccess": "Gratis toegang via OAuth-authenticatie" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index 4a446f7095..b702d7b5a5 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -308,21 +308,6 @@ "pathLabel": "ลšcieลผka Claude Code", "description": "Opcjonalna ล›cieลผka do Twojego CLI Claude Code. Domyล›lnie 'claude', jeล›li nie ustawiono.", "placeholder": "Domyล›lnie: claude" - }, - "geminiCli": { - "description": "Ten dostawca uลผywa uwierzytelniania OAuth z narzฤ™dzia Gemini CLI i nie wymaga kluczy API.", - "oauthPath": "ลšcieลผka danych uwierzytelniajฤ…cych OAuth (opcjonalne)", - "oauthPathDescription": "ลšcieลผka do pliku danych uwierzytelniajฤ…cych OAuth. Pozostaw puste, aby uลผyฤ‡ domyล›lnej lokalizacji (~/.gemini/oauth_creds.json).", - "instructions": "Jeล›li jeszcze siฤ™ nie uwierzytelniล‚eล›, uruchom najpierw", - "instructionsContinued": "w swoim terminalu.", - "setupLink": "Instrukcje konfiguracji Gemini CLI", - "requirementsTitle": "Waลผne wymagania", - "requirement1": "Najpierw musisz zainstalowaฤ‡ narzฤ™dzie Gemini CLI", - "requirement2": "Nastฤ™pnie uruchom gemini w swoim terminalu i upewnij siฤ™, ลผe logujesz siฤ™ przez Google", - "requirement3": "Dziaล‚a tylko z osobistymi kontami Google (nie z kontami Google Workspace)", - "requirement4": "Nie uลผywa kluczy API - uwierzytelnianie jest obsล‚ugiwane przez OAuth", - "requirement5": "Wymaga, aby narzฤ™dzie Gemini CLI byล‚o najpierw zainstalowane i uwierzytelnione", - "freeAccess": "Darmowy dostฤ™p przez uwierzytelnianie OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index b4ae11c2ac..be7bfe2d0d 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Caminho do Claude Code", "description": "Caminho opcional para o seu Claude Code CLI. O padrรฃo รฉ 'claude' se nรฃo for definido.", "placeholder": "Padrรฃo: claude" - }, - "geminiCli": { - "description": "Este provedor usa autenticaรงรฃo OAuth da ferramenta Gemini CLI e nรฃo requer chaves de API.", - "oauthPath": "Caminho das Credenciais OAuth (opcional)", - "oauthPathDescription": "Caminho para o arquivo de credenciais OAuth. Deixe vazio para usar o local padrรฃo (~/.gemini/oauth_creds.json).", - "instructions": "Se vocรช ainda nรฃo se autenticou, execute", - "instructionsContinued": "no seu terminal primeiro.", - "setupLink": "Instruรงรตes de Configuraรงรฃo do Gemini CLI", - "requirementsTitle": "Requisitos Importantes", - "requirement1": "Primeiro, vocรช precisa instalar a ferramenta Gemini CLI", - "requirement2": "Em seguida, execute gemini no seu terminal e certifique-se de fazer login com o Google", - "requirement3": "Funciona apenas com contas pessoais do Google (nรฃo contas do Google Workspace)", - "requirement4": "Nรฃo usa chaves de API - a autenticaรงรฃo รฉ tratada via OAuth", - "requirement5": "Requer que a ferramenta Gemini CLI seja instalada e autenticada primeiro", - "freeAccess": "Acesso gratuito via autenticaรงรฃo OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 79c13741da..b0693f4532 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -308,21 +308,6 @@ "pathLabel": "ะŸัƒั‚ัŒ ะบ Claude Code", "description": "ะะตะพะฑัะทะฐั‚ะตะปัŒะฝั‹ะน ะฟัƒั‚ัŒ ะบ ะฒะฐัˆะตะผัƒ Claude Code CLI. ะŸะพ ัƒะผะพะปั‡ะฐะฝะธัŽ ะธัะฟะพะปัŒะทัƒะตั‚ัั 'claude', ะตัะปะธ ะฝะต ัƒัั‚ะฐะฝะพะฒะปะตะฝะพ.", "placeholder": "ะŸะพ ัƒะผะพะปั‡ะฐะฝะธัŽ: claude" - }, - "geminiCli": { - "description": "ะญั‚ะพั‚ ะฟั€ะพะฒะฐะนะดะตั€ ะธัะฟะพะปัŒะทัƒะตั‚ OAuth-ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ ะธะท ะธะฝัั‚ั€ัƒะผะตะฝั‚ะฐ Gemini CLI ะธ ะฝะต ั‚ั€ะตะฑัƒะตั‚ API-ะบะปัŽั‡ะตะน.", - "oauthPath": "ะŸัƒั‚ัŒ ะบ ัƒั‡ะตั‚ะฝั‹ะผ ะดะฐะฝะฝั‹ะผ OAuth (ะฝะตะพะฑัะทะฐั‚ะตะปัŒะฝะพ)", - "oauthPathDescription": "ะŸัƒั‚ัŒ ะบ ั„ะฐะนะปัƒ ัƒั‡ะตั‚ะฝั‹ั… ะดะฐะฝะฝั‹ั… OAuth. ะžัั‚ะฐะฒัŒั‚ะต ะฟัƒัั‚ั‹ะผ ะดะปั ะธัะฟะพะปัŒะทะพะฒะฐะฝะธั ะผะตัั‚ะพะฟะพะปะพะถะตะฝะธั ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ (~/.gemini/oauth_creds.json).", - "instructions": "ะ•ัะปะธ ะฒั‹ ะตั‰ะต ะฝะต ะฟั€ะพัˆะปะธ ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ, ะฒั‹ะฟะพะปะฝะธั‚ะต", - "instructionsContinued": "ะฒ ะฒะฐัˆะตะผ ั‚ะตั€ะผะธะฝะฐะปะต ัะฝะฐั‡ะฐะปะฐ.", - "setupLink": "ะ˜ะฝัั‚ั€ัƒะบั†ะธะธ ะฟะพ ะฝะฐัั‚ั€ะพะนะบะต Gemini CLI", - "requirementsTitle": "ะ’ะฐะถะฝั‹ะต ั‚ั€ะตะฑะพะฒะฐะฝะธั", - "requirement1": "ะกะฝะฐั‡ะฐะปะฐ ะฒะฐะผ ะฝัƒะถะฝะพ ัƒัั‚ะฐะฝะพะฒะธั‚ัŒ ะธะฝัั‚ั€ัƒะผะตะฝั‚ Gemini CLI", - "requirement2": "ะ—ะฐั‚ะตะผ ะทะฐะฟัƒัั‚ะธั‚ะต gemini ะฒ ะฒะฐัˆะตะผ ั‚ะตั€ะผะธะฝะฐะปะต ะธ ัƒะฑะตะดะธั‚ะตััŒ, ั‡ั‚ะพ ะฒั‹ ะฒะพัˆะปะธ ะฒ Google", - "requirement3": "ะ ะฐะฑะพั‚ะฐะตั‚ ั‚ะพะปัŒะบะพ ั ะปะธั‡ะฝั‹ะผะธ ะฐะบะบะฐัƒะฝั‚ะฐะผะธ Google (ะฝะต ั ะฐะบะบะฐัƒะฝั‚ะฐะผะธ Google Workspace)", - "requirement4": "ะะต ะธัะฟะพะปัŒะทัƒะตั‚ API-ะบะปัŽั‡ะธ - ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธั ะพะฑั€ะฐะฑะฐั‚ั‹ะฒะฐะตั‚ัั ั‡ะตั€ะตะท OAuth", - "requirement5": "ะขั€ะตะฑัƒะตั‚, ั‡ั‚ะพะฑั‹ ะธะฝัั‚ั€ัƒะผะตะฝั‚ Gemini CLI ะฑั‹ะป ัะฝะฐั‡ะฐะปะฐ ัƒัั‚ะฐะฝะพะฒะปะตะฝ ะธ ะฐัƒั‚ะตะฝั‚ะธั„ะธั†ะธั€ะพะฒะฐะฝ", - "freeAccess": "ะ‘ะตัะฟะปะฐั‚ะฝั‹ะน ะดะพัั‚ัƒะฟ ั‡ะตั€ะตะท OAuth-ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index e6335c6dad..06bd626406 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Claude Code Yolu", "description": "Claude Code CLI'nize isteฤŸe baฤŸlฤฑ yol. Ayarlanmazsa varsayฤฑlan olarak 'claude' kullanฤฑlฤฑr.", "placeholder": "Varsayฤฑlan: claude" - }, - "geminiCli": { - "description": "Bu saฤŸlayฤฑcฤฑ Gemini CLI aracฤฑndan OAuth kimlik doฤŸrulamasฤฑ kullanฤฑr ve API anahtarlarฤฑ gerektirmez.", - "oauthPath": "OAuth Kimlik Bilgileri Yolu (isteฤŸe baฤŸlฤฑ)", - "oauthPathDescription": "OAuth kimlik bilgileri dosyasฤฑnฤฑn yolu. Varsayฤฑlan konumu kullanmak iรงin boลŸ bฤฑrakฤฑn (~/.gemini/oauth_creds.json).", - "instructions": "Henรผz kimlik doฤŸrulamasฤฑ yapmadฤฑysanฤฑz, รถnce", - "instructionsContinued": "komutunu terminalinizde รงalฤฑลŸtฤฑrฤฑn.", - "setupLink": "Gemini CLI Kurulum Talimatlarฤฑ", - "requirementsTitle": "ร–nemli Gereksinimler", - "requirement1": "ร–nce Gemini CLI aracฤฑnฤฑ yรผklemeniz gerekir", - "requirement2": "Sonra terminalinizde gemini รงalฤฑลŸtฤฑrฤฑn ve Google ile giriลŸ yaptฤฑฤŸฤฑnฤฑzdan emin olun", - "requirement3": "Sadece kiลŸisel Google hesaplarฤฑyla รงalฤฑลŸฤฑr (Google Workspace hesaplarฤฑ deฤŸil)", - "requirement4": "API anahtarlarฤฑ kullanmaz - kimlik doฤŸrulama OAuth ile yapฤฑlฤฑr", - "requirement5": "Gemini CLI aracฤฑnฤฑn รถnce yรผklenmesi ve kimlik doฤŸrulamasฤฑ yapฤฑlmasฤฑ gerekir", - "freeAccess": "OAuth kimlik doฤŸrulamasฤฑ ile รผcretsiz eriลŸim" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index f860292e02..c434276b3b 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -308,21 +308,6 @@ "pathLabel": "ฤฦฐแปng dแบซn Claude Code", "description": "ฤฦฐแปng dแบซn tรนy chแปn ฤ‘แบฟn Claude Code CLI cแปงa bแบกn. Mแบทc ฤ‘แป‹nh lร  'claude' nแบฟu khรดng ฤ‘ฦฐแปฃc ฤ‘แบทt.", "placeholder": "Mแบทc ฤ‘แป‹nh: claude" - }, - "geminiCli": { - "description": "Nhร  cung cแบฅp nร y sแปญ dแปฅng xรกc thแปฑc OAuth tแปซ cรดng cแปฅ Gemini CLI vร  khรดng yรชu cแบงu khรณa API.", - "oauthPath": "ฤฦฐแปng dแบซn Thรดng tin xรกc thแปฑc OAuth (tรนy chแปn)", - "oauthPathDescription": "ฤฦฐแปng dแบซn ฤ‘แบฟn tแป‡p thรดng tin xรกc thแปฑc OAuth. ฤแปƒ trแป‘ng ฤ‘แปƒ sแปญ dแปฅng vแป‹ trรญ mแบทc ฤ‘แป‹nh (~/.gemini/oauth_creds.json).", - "instructions": "Nแบฟu bแบกn chฦฐa xรกc thแปฑc, vui lรฒng chแบกy", - "instructionsContinued": "trong terminal cแปงa bแบกn trฦฐแป›c.", - "setupLink": "Hฦฐแป›ng dแบซn Thiแบฟt lแบญp Gemini CLI", - "requirementsTitle": "Yรชu cแบงu Quan trแปng", - "requirement1": "Trฦฐแป›c tiรชn, bแบกn cแบงn cร i ฤ‘แบทt cรดng cแปฅ Gemini CLI", - "requirement2": "Sau ฤ‘รณ, chแบกy gemini trong terminal cแปงa bแบกn vร  ฤ‘แบฃm bแบฃo bแบกn ฤ‘ฤƒng nhแบญp bแบฑng Google", - "requirement3": "Chแป‰ hoแบกt ฤ‘แป™ng vแป›i tร i khoแบฃn Google cรก nhรขn (khรดng phแบฃi tร i khoแบฃn Google Workspace)", - "requirement4": "Khรดng sแปญ dแปฅng khรณa API - xรกc thแปฑc ฤ‘ฦฐแปฃc xแปญ lรฝ qua OAuth", - "requirement5": "Yรชu cแบงu cรดng cแปฅ Gemini CLI ฤ‘ฦฐแปฃc cร i ฤ‘แบทt vร  xรกc thแปฑc trฦฐแป›c", - "freeAccess": "Truy cแบญp miแป…n phรญ qua xรกc thแปฑc OAuth" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index f2e80cee7f..80bcab26eb 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Claude Code ่ทฏๅพ„", "description": "ๆ‚จ็š„ Claude Code CLI ็š„ๅฏ้€‰่ทฏๅพ„ใ€‚ๅฆ‚ๆžœๆœช่ฎพ็ฝฎ๏ผŒๅˆ™้ป˜่ฎคไธบ โ€œclaudeโ€ใ€‚", "placeholder": "้ป˜่ฎค๏ผšclaude" - }, - "geminiCli": { - "description": "ๆญคๆไพ›ๅ•†ไฝฟ็”จ Gemini CLI ๅทฅๅ…ท็š„ OAuth ่บซไปฝ้ชŒ่ฏ๏ผŒไธ้œ€่ฆ API ๅฏ†้’ฅใ€‚", - "oauthPath": "OAuth ๅ‡ญๆฎ่ทฏๅพ„๏ผˆๅฏ้€‰๏ผ‰", - "oauthPathDescription": "OAuth ๅ‡ญๆฎๆ–‡ไปถ็š„่ทฏๅพ„ใ€‚็•™็ฉบไปฅไฝฟ็”จ้ป˜่ฎคไฝ็ฝฎ๏ผˆ~/.gemini/oauth_creds.json๏ผ‰ใ€‚", - "instructions": "ๅฆ‚ๆžœๆ‚จๅฐšๆœช่ฟ›่กŒ่บซไปฝ้ชŒ่ฏ๏ผŒ่ฏทๅ…ˆ่ฟ่กŒ", - "instructionsContinued": "ๅœจๆ‚จ็š„็ปˆ็ซฏไธญใ€‚", - "setupLink": "Gemini CLI ่ฎพ็ฝฎ่ฏดๆ˜Ž", - "requirementsTitle": "้‡่ฆ่ฆๆฑ‚", - "requirement1": "้ฆ–ๅ…ˆ๏ผŒๆ‚จ้œ€่ฆๅฎ‰่ฃ… Gemini CLI ๅทฅๅ…ท", - "requirement2": "็„ถๅŽ๏ผŒๅœจ็ปˆ็ซฏไธญ่ฟ่กŒ gemini ๅนถ็กฎไฟไฝฟ็”จ Google ็™ปๅฝ•", - "requirement3": "ไป…้€‚็”จไบŽไธชไบบ Google ่ดฆๆˆท๏ผˆไธๆ”ฏๆŒ Google Workspace ่ดฆๆˆท๏ผ‰", - "requirement4": "ไธไฝฟ็”จ API ๅฏ†้’ฅ - ่บซไปฝ้ชŒ่ฏ้€š่ฟ‡ OAuth ๅค„็†", - "requirement5": "้œ€่ฆๅ…ˆๅฎ‰่ฃ…ๅนถ้ชŒ่ฏ Gemini CLI ๅทฅๅ…ท", - "freeAccess": "้€š่ฟ‡ OAuth ่บซไปฝ้ชŒ่ฏๅ…่ดน่ฎฟ้—ฎ" } }, "browser": { diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 874fbe7a37..033230ebb4 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -308,21 +308,6 @@ "pathLabel": "Claude Code ่ทฏๅพ‘", "description": "ๅฏ้ธ็š„ Claude Code CLI ่ทฏๅพ‘ใ€‚ๅฆ‚ๆžœๆœช่จญๅฎš๏ผŒๅ‰‡้ ่จญ็‚บ 'claude'ใ€‚", "placeholder": "้ ่จญ๏ผšclaude" - }, - "geminiCli": { - "description": "ๆญคๆไพ›ๅ•†ไฝฟ็”จ Gemini CLI ๅทฅๅ…ท็š„ OAuth ่บซไปฝ้ฉ—่ญ‰๏ผŒไธ้œ€่ฆ API ้‡‘้‘ฐใ€‚", - "oauthPath": "OAuth ๆ†‘่ญ‰่ทฏๅพ‘๏ผˆๅฏ้ธ๏ผ‰", - "oauthPathDescription": "OAuth ๆ†‘่ญ‰ๆช”ๆกˆ็š„่ทฏๅพ‘ใ€‚็•™็ฉบไปฅไฝฟ็”จ้ ่จญไฝ็ฝฎ๏ผˆ~/.gemini/oauth_creds.json๏ผ‰ใ€‚", - "instructions": "ๅฆ‚ๆžœๆ‚จๅฐšๆœช้€ฒ่กŒ่บซไปฝ้ฉ—่ญ‰๏ผŒ่ซ‹ๅ…ˆๅŸท่กŒ", - "instructionsContinued": "ๅœจๆ‚จ็š„็ต‚็ซฏๆฉŸไธญใ€‚", - "setupLink": "Gemini CLI ่จญๅฎš่ชชๆ˜Ž", - "requirementsTitle": "้‡่ฆ่ฆๆฑ‚", - "requirement1": "้ฆ–ๅ…ˆ๏ผŒๆ‚จ้œ€่ฆๅฎ‰่ฃ Gemini CLI ๅทฅๅ…ท", - "requirement2": "็„ถๅพŒ๏ผŒๅœจ็ต‚็ซฏๆฉŸไธญๅŸท่กŒ gemini ไธฆ็ขบไฟไฝฟ็”จ Google ็™ปๅ…ฅ", - "requirement3": "ๅƒ…้ฉ็”จๆ–ผๅ€‹ไบบ Google ๅธณๆˆถ๏ผˆไธๆ”ฏๆด Google Workspace ๅธณๆˆถ๏ผ‰", - "requirement4": "ไธไฝฟ็”จ API ้‡‘้‘ฐ - ่บซไปฝ้ฉ—่ญ‰้€้Ž OAuth ่™•็†", - "requirement5": "้œ€่ฆๅ…ˆๅฎ‰่ฃไธฆ้ฉ—่ญ‰ Gemini CLI ๅทฅๅ…ท", - "freeAccess": "้€้Ž OAuth ่บซไปฝ้ฉ—่ญ‰ๅ…่ฒปๅญ˜ๅ–" } }, "browser": { diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index d902195d5c..1040b60c2d 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -72,9 +72,6 @@ function validateModelsAndKeysProvided(apiConfiguration: ProviderSettings): stri return i18next.t("settings:validation.apiKey") } break - case "gemini-cli": - // OAuth-based provider, no API key validation needed - break case "openai-native": if (!apiConfiguration.openAiNativeApiKey) { return i18next.t("settings:validation.apiKey") From a480937b22010a36c7d046bf06931c176cc9927d Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Sat, 28 Jun 2025 23:56:48 -0400 Subject: [PATCH 27/70] Add changeset for v3.22.5 patch release (#5224) --- .changeset/v3.22.5.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/v3.22.5.md diff --git a/.changeset/v3.22.5.md b/.changeset/v3.22.5.md new file mode 100644 index 0000000000..09095dc22f --- /dev/null +++ b/.changeset/v3.22.5.md @@ -0,0 +1,5 @@ +--- +"roo-cline": patch +--- + +- Remove Gemini CLI provider while we work with Google on a better integration From 0c89162199d96bf42055b75bff60242c8553c68d Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Sun, 29 Jun 2025 00:16:58 -0400 Subject: [PATCH 28/70] Try to avoid type error from removing gemini-cli (#5226) --- .changeset/public-bugs-hang.md | 5 +++++ packages/types/src/provider-settings.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/public-bugs-hang.md diff --git a/.changeset/public-bugs-hang.md b/.changeset/public-bugs-hang.md new file mode 100644 index 0000000000..bf44f7d1d0 --- /dev/null +++ b/.changeset/public-bugs-hang.md @@ -0,0 +1,5 @@ +--- +"roo-cline": patch +--- + +Bump diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 609d0fefbf..76020be74e 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -19,6 +19,7 @@ export const providerNames = [ "vscode-lm", "lmstudio", "gemini", + "gemini-cli", "openai-native", "mistral", "deepseek", From 5cda9e453bb3b8174cc646a24654ea5d9a64e8c9 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Sun, 29 Jun 2025 00:45:40 -0400 Subject: [PATCH 29/70] Bring back more gemini cli types (#5227) --- packages/types/src/provider-settings.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 76020be74e..e940ececd1 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -159,6 +159,11 @@ const geminiSchema = apiModelIdProviderModelSchema.extend({ googleGeminiBaseUrl: z.string().optional(), }) +const geminiCliSchema = apiModelIdProviderModelSchema.extend({ + geminiCliOAuthPath: z.string().optional(), + geminiCliProjectId: z.string().optional(), +}) + const openAiNativeSchema = apiModelIdProviderModelSchema.extend({ openAiNativeApiKey: z.string().optional(), openAiNativeBaseUrl: z.string().optional(), @@ -224,6 +229,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv vsCodeLmSchema.merge(z.object({ apiProvider: z.literal("vscode-lm") })), lmStudioSchema.merge(z.object({ apiProvider: z.literal("lmstudio") })), geminiSchema.merge(z.object({ apiProvider: z.literal("gemini") })), + geminiCliSchema.merge(z.object({ apiProvider: z.literal("gemini-cli") })), openAiNativeSchema.merge(z.object({ apiProvider: z.literal("openai-native") })), mistralSchema.merge(z.object({ apiProvider: z.literal("mistral") })), deepSeekSchema.merge(z.object({ apiProvider: z.literal("deepseek") })), @@ -251,6 +257,7 @@ export const providerSettingsSchema = z.object({ ...vsCodeLmSchema.shape, ...lmStudioSchema.shape, ...geminiSchema.shape, + ...geminiCliSchema.shape, ...openAiNativeSchema.shape, ...mistralSchema.shape, ...deepSeekSchema.shape, From b45252d490c44229e64cf9537d0c29d5e75ccd3a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 29 Jun 2025 01:06:59 -0400 Subject: [PATCH 30/70] Changeset version bump (#5225) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Matt Rubens --- .changeset/public-bugs-hang.md | 5 ----- .changeset/v3.22.5.md | 5 ----- CHANGELOG.md | 4 ++++ src/package.json | 2 +- 4 files changed, 5 insertions(+), 11 deletions(-) delete mode 100644 .changeset/public-bugs-hang.md delete mode 100644 .changeset/v3.22.5.md diff --git a/.changeset/public-bugs-hang.md b/.changeset/public-bugs-hang.md deleted file mode 100644 index bf44f7d1d0..0000000000 --- a/.changeset/public-bugs-hang.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"roo-cline": patch ---- - -Bump diff --git a/.changeset/v3.22.5.md b/.changeset/v3.22.5.md deleted file mode 100644 index 09095dc22f..0000000000 --- a/.changeset/v3.22.5.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"roo-cline": patch ---- - -- Remove Gemini CLI provider while we work with Google on a better integration diff --git a/CHANGELOG.md b/CHANGELOG.md index 367671f56d..f5fe9aef4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Roo Code Changelog +## [3.22.5] - 2025-06-28 + +- Remove Gemini CLI provider while we work with Google on a better integration + ## [3.22.4] - 2025-06-27 - Fix: resolve E2BIG error by passing large prompts via stdin to Claude CLI (thanks @Fovty!) diff --git a/src/package.json b/src/package.json index 71085517db..4a91b44eb3 100644 --- a/src/package.json +++ b/src/package.json @@ -3,7 +3,7 @@ "displayName": "%extension.displayName%", "description": "%extension.description%", "publisher": "RooVeterinaryInc", - "version": "3.22.4", + "version": "3.22.5", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From cd60bb3a7edcfff6cda8c9252642ec962f62ceb3 Mon Sep 17 00:00:00 2001 From: roomote Date: Mon, 30 Jun 2025 06:01:44 -0700 Subject: [PATCH 31/70] Fixes #5206: Update apply_diff tool documentation to accurately reflect multi-file capabilities (#5232) * Fixes #5206 * Fix failing test: Update snapshot after documentation changes - Updated system-prompt.spec.ts snapshot to match new tool descriptions - Changes reflect updated multi-file diff strategy documentation - Addresses test failure mentioned in PR #5232 comment by @mrubens --- src/core/diff/strategies/multi-file-search-replace.ts | 4 +++- src/core/diff/strategies/multi-search-replace.ts | 4 ++-- .../__snapshots__/system-prompt/with-diff-enabled-true.snap | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/diff/strategies/multi-file-search-replace.ts b/src/core/diff/strategies/multi-file-search-replace.ts index 1554201675..d875d723a1 100644 --- a/src/core/diff/strategies/multi-file-search-replace.ts +++ b/src/core/diff/strategies/multi-file-search-replace.ts @@ -95,6 +95,8 @@ export class MultiFileSearchReplaceDiffStrategy implements DiffStrategy { Description: Request to apply targeted modifications to one or more files by searching for specific sections of content and replacing them. This tool supports both single-file and multi-file operations, allowing you to make changes across multiple files in a single request. +**IMPORTANT: You MUST use multiple files in a single operation whenever possible to maximize efficiency and minimize back-and-forth.** + You can perform multiple distinct search and replace operations within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter. This is the preferred way to make several targeted changes efficiently. The SEARCH section must exactly match existing content including whitespace and indentation. @@ -157,7 +159,7 @@ def calculate_total(items): -Search/Replace content with multi edits in one file: +Search/Replace content with multi edits across multiple files: diff --git a/src/core/diff/strategies/multi-search-replace.ts b/src/core/diff/strategies/multi-search-replace.ts index 9e740a6571..b90ef4072d 100644 --- a/src/core/diff/strategies/multi-search-replace.ts +++ b/src/core/diff/strategies/multi-search-replace.ts @@ -93,7 +93,7 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy { getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string { return `## apply_diff Description: Request to apply targeted modifications to an existing file by searching for specific sections of content and replacing them. This tool is ideal for precise, surgical edits when you know the exact content to change. It helps maintain proper indentation and formatting. -You can perform multiple distinct search and replace operations within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter. This is the preferred way to make several targeted changes to one file efficiently. +You can perform multiple distinct search and replace operations within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter. This is the preferred way to make several targeted changes efficiently. The SEARCH section must exactly match existing content including whitespace and indentation. If you're not confident in the exact content to search for, use the read_file tool first to get the exact content. When applying the diffs, be extra careful to remember to change any closing brackets or other syntax that may be affected by the diff farther down in the file. @@ -145,7 +145,7 @@ def calculate_total(items): \`\`\` -Search/Replace content with multi edits: +Search/Replace content with multiple edits: \`\`\` <<<<<<< SEARCH :start_line:1 diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap index 6612df745e..744cadfab4 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap @@ -168,7 +168,7 @@ Examples: ## apply_diff Description: Request to apply targeted modifications to an existing file by searching for specific sections of content and replacing them. This tool is ideal for precise, surgical edits when you know the exact content to change. It helps maintain proper indentation and formatting. -You can perform multiple distinct search and replace operations within a single `apply_diff` call by providing multiple SEARCH/REPLACE blocks in the `diff` parameter. This is the preferred way to make several targeted changes to one file efficiently. +You can perform multiple distinct search and replace operations within a single `apply_diff` call by providing multiple SEARCH/REPLACE blocks in the `diff` parameter. This is the preferred way to make several targeted changes efficiently. The SEARCH section must exactly match existing content including whitespace and indentation. If you're not confident in the exact content to search for, use the read_file tool first to get the exact content. When applying the diffs, be extra careful to remember to change any closing brackets or other syntax that may be affected by the diff farther down in the file. @@ -220,7 +220,7 @@ def calculate_total(items): ``` -Search/Replace content with multi edits: +Search/Replace content with multiple edits: ``` <<<<<<< SEARCH :start_line:1 From 8c493b393f1f8877ee59486633196173e4130645 Mon Sep 17 00:00:00 2001 From: PaperBoardOfficial Date: Mon, 30 Jun 2025 20:07:18 +0530 Subject: [PATCH 32/70] fixed profile context condensation threshold (#5230) --- src/core/task/Task.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 46da7485ed..ef5db499d2 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1708,6 +1708,8 @@ export class Task extends EventEmitter { const contextWindow = modelInfo.contextWindow + const currentProfileId = state?.listApiConfigMeta.find((profile) => profile.name === state?.currentApiConfigName)?.id ?? "default"; + const truncateResult = await truncateConversationIfNeeded({ messages: this.apiConversationHistory, totalTokens: contextTokens, @@ -1721,7 +1723,7 @@ export class Task extends EventEmitter { customCondensingPrompt, condensingApiHandler, profileThresholds, - currentProfileId: state?.currentApiConfigName || "default", + currentProfileId, }) if (truncateResult.messages !== this.apiConversationHistory) { await this.overwriteApiConversationHistory(truncateResult.messages) From 64279166c496759412fb1a11962a4932027e9d66 Mon Sep 17 00:00:00 2001 From: Murilo Pires <50873657+MuriloFP@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:40:53 -0300 Subject: [PATCH 33/70] fix: resolve URL loading timeout issues in @ mentions (#5160) Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> Co-authored-by: Daniel Riccio --- src/core/mentions/__tests__/index.spec.ts | 408 ++++++------------ src/core/mentions/index.ts | 49 ++- src/i18n/locales/ca/common.json | 7 + src/i18n/locales/de/common.json | 7 + src/i18n/locales/en/common.json | 7 + src/i18n/locales/es/common.json | 7 + src/i18n/locales/fr/common.json | 7 + src/i18n/locales/hi/common.json | 7 + src/i18n/locales/id/common.json | 7 + src/i18n/locales/it/common.json | 7 + src/i18n/locales/ja/common.json | 7 + src/i18n/locales/ko/common.json | 7 + src/i18n/locales/nl/common.json | 7 + src/i18n/locales/pl/common.json | 7 + src/i18n/locales/pt-BR/common.json | 7 + src/i18n/locales/ru/common.json | 7 + src/i18n/locales/tr/common.json | 7 + src/i18n/locales/vi/common.json | 7 + src/i18n/locales/zh-CN/common.json | 7 + src/i18n/locales/zh-TW/common.json | 7 + src/services/browser/BrowserSession.ts | 12 +- src/services/browser/UrlContentFetcher.ts | 53 ++- .../__tests__/UrlContentFetcher.spec.ts | 290 +++++++++++++ 23 files changed, 651 insertions(+), 287 deletions(-) create mode 100644 src/services/browser/__tests__/UrlContentFetcher.spec.ts diff --git a/src/core/mentions/__tests__/index.spec.ts b/src/core/mentions/__tests__/index.spec.ts index 0f97c1ef89..e65dbb44e0 100644 --- a/src/core/mentions/__tests__/index.spec.ts +++ b/src/core/mentions/__tests__/index.spec.ts @@ -1,310 +1,160 @@ -import type { Mock } from "vitest" +// npx vitest core/mentions/__tests__/index.spec.ts -// Mock modules - must come before imports -vi.mock("vscode", () => { - const createMockUri = (scheme: string, path: string) => ({ - scheme, - authority: "", - path, - query: "", - fragment: "", - fsPath: path, - with: vi.fn(), - toString: () => path, - toJSON: () => ({ - scheme, - authority: "", - path, - query: "", - fragment: "", - }), - }) - - const mockExecuteCommand = vi.fn() - const mockOpenExternal = vi.fn() - const mockShowErrorMessage = vi.fn() - - return { - workspace: { - workspaceFolders: [ - { - uri: { fsPath: "/test/workspace" }, - }, - ] as { uri: { fsPath: string } }[] | undefined, - getWorkspaceFolder: vi.fn().mockReturnValue("/test/workspace"), - fs: { - stat: vi.fn(), - writeFile: vi.fn(), - }, - openTextDocument: vi.fn().mockResolvedValue({}), - }, - window: { - showErrorMessage: mockShowErrorMessage, - showInformationMessage: vi.fn(), - showWarningMessage: vi.fn(), - createTextEditorDecorationType: vi.fn(), - createOutputChannel: vi.fn(), - createWebviewPanel: vi.fn(), - showTextDocument: vi.fn().mockResolvedValue({}), - activeTextEditor: undefined as - | undefined - | { - document: { - uri: { fsPath: string } - } - }, - }, - commands: { - executeCommand: mockExecuteCommand, - }, - env: { - openExternal: mockOpenExternal, - }, - Uri: { - parse: vi.fn((url: string) => createMockUri("https", url)), - file: vi.fn((path: string) => createMockUri("file", path)), - }, - Position: vi.fn(), - Range: vi.fn(), - TextEdit: vi.fn(), - WorkspaceEdit: vi.fn(), - DiagnosticSeverity: { - Error: 0, - Warning: 1, - Information: 2, - Hint: 3, - }, - } -}) -vi.mock("../../../services/browser/UrlContentFetcher") -vi.mock("../../../utils/git") -vi.mock("../../../utils/path") -vi.mock("fs/promises", () => ({ - default: { - stat: vi.fn(), - readdir: vi.fn(), - }, - stat: vi.fn(), - readdir: vi.fn(), -})) -vi.mock("../../../integrations/misc/open-file", () => ({ - openFile: vi.fn(), -})) -vi.mock("../../../integrations/misc/extract-text", () => ({ - extractTextFromFile: vi.fn(), -})) - -// Now import the modules that use the mocks -import { parseMentions, openMention } from "../index" -import { UrlContentFetcher } from "../../../services/browser/UrlContentFetcher" -import * as git from "../../../utils/git" -import { getWorkspacePath } from "../../../utils/path" -import fs from "fs/promises" -import * as path from "path" -import { openFile } from "../../../integrations/misc/open-file" -import { extractTextFromFile } from "../../../integrations/misc/extract-text" +import { describe, it, expect, vi, beforeEach } from "vitest" import * as vscode from "vscode" -;(getWorkspacePath as Mock).mockReturnValue("/test/workspace") +import { parseMentions } from "../index" +import { UrlContentFetcher } from "../../../services/browser/UrlContentFetcher" +import { t } from "../../../i18n" -describe("mentions", () => { - const mockCwd = "/test/workspace" +// Mock vscode +vi.mock("vscode", () => ({ + window: { + showErrorMessage: vi.fn(), + }, +})) + +// Mock i18n +vi.mock("../../../i18n", () => ({ + t: vi.fn((key: string) => key), +})) + +describe("parseMentions - URL error handling", () => { let mockUrlContentFetcher: UrlContentFetcher + let consoleErrorSpy: any beforeEach(() => { vi.clearAllMocks() + consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}) - // Create a mock instance with just the methods we need mockUrlContentFetcher = { - launchBrowser: vi.fn().mockResolvedValue(undefined), - closeBrowser: vi.fn().mockResolvedValue(undefined), - urlToMarkdown: vi.fn().mockResolvedValue(""), - } as unknown as UrlContentFetcher - - // Reset all vscode mocks using vi.mocked - vi.mocked(vscode.workspace.fs.stat).mockReset() - vi.mocked(vscode.workspace.fs.writeFile).mockReset() - vi.mocked(vscode.workspace.openTextDocument) - .mockReset() - .mockResolvedValue({} as any) - vi.mocked(vscode.window.showTextDocument) - .mockReset() - .mockResolvedValue({} as any) - vi.mocked(vscode.window.showErrorMessage).mockReset() - vi.mocked(vscode.commands.executeCommand).mockReset() - vi.mocked(vscode.env.openExternal).mockReset() + launchBrowser: vi.fn(), + urlToMarkdown: vi.fn(), + closeBrowser: vi.fn(), + } as any }) - describe("parseMentions", () => { - let mockUrlFetcher: UrlContentFetcher + it("should handle timeout errors with appropriate message", async () => { + const timeoutError = new Error("Navigation timeout of 30000 ms exceeded") + vi.mocked(mockUrlContentFetcher.urlToMarkdown).mockRejectedValue(timeoutError) - beforeEach(() => { - mockUrlFetcher = new (UrlContentFetcher as any)() - ;(fs.stat as Mock).mockResolvedValue({ isFile: () => true, isDirectory: () => false }) - ;(extractTextFromFile as Mock).mockResolvedValue("Mock file content") - }) + const result = await parseMentions("Check @https://example.com", "/test", mockUrlContentFetcher) - it("should parse git commit mentions", async () => { - const commitHash = "abc1234" - const commitInfo = `abc1234 Fix bug in parser - -Author: John Doe -Date: Mon Jan 5 23:50:06 2025 -0500 - -Detailed commit message with multiple lines -- Fixed parsing issue -- Added tests` - - vi.mocked(git.getCommitInfo).mockResolvedValue(commitInfo) - - const result = await parseMentions(`Check out this commit @${commitHash}`, mockCwd, mockUrlContentFetcher) - - expect(result).toContain(`'${commitHash}' (see below for commit info)`) - expect(result).toContain(``) - expect(result).toContain(commitInfo) - }) - - it("should handle errors fetching git info", async () => { - const commitHash = "abc1234" - const errorMessage = "Failed to get commit info" - - vi.mocked(git.getCommitInfo).mockRejectedValue(new Error(errorMessage)) - - const result = await parseMentions(`Check out this commit @${commitHash}`, mockCwd, mockUrlContentFetcher) - - expect(result).toContain(`'${commitHash}' (see below for commit info)`) - expect(result).toContain(``) - expect(result).toContain(`Error fetching commit info: ${errorMessage}`) - }) - - it("should correctly parse mentions with escaped spaces and fetch content", async () => { - const text = "Please check the file @/path/to/file\\ with\\ spaces.txt" - const expectedUnescaped = "path/to/file with spaces.txt" // Note: leading '/' removed by slice(1) in parseMentions - const expectedAbsPath = path.resolve(mockCwd, expectedUnescaped) - - const result = await parseMentions(text, mockCwd, mockUrlFetcher) - - // Check if fs.stat was called with the unescaped path - expect(fs.stat).toHaveBeenCalledWith(expectedAbsPath) - // Check if extractTextFromFile was called with the unescaped path - expect(extractTextFromFile).toHaveBeenCalledWith(expectedAbsPath) - - // Check the output format - expect(result).toContain(`'path/to/file\\ with\\ spaces.txt' (see below for file content)`) - expect(result).toContain( - `\nMock file content\n`, - ) - }) - - it("should handle folder mentions with escaped spaces", async () => { - const text = "Look in @/my\\ documents/folder\\ name/" - const expectedUnescaped = "my documents/folder name/" - const expectedAbsPath = path.resolve(mockCwd, expectedUnescaped) - ;(fs.stat as Mock).mockResolvedValue({ isFile: () => false, isDirectory: () => true }) - ;(fs.readdir as Mock).mockResolvedValue([]) // Empty directory - - const result = await parseMentions(text, mockCwd, mockUrlFetcher) - - expect(fs.stat).toHaveBeenCalledWith(expectedAbsPath) - expect(fs.readdir).toHaveBeenCalledWith(expectedAbsPath, { withFileTypes: true }) - expect(result).toContain(`'my\\ documents/folder\\ name/' (see below for folder content)`) - expect(result).toContain(``) // Content check might be more complex - }) - - it("should handle errors when accessing paths with escaped spaces", async () => { - const text = "Check @/nonexistent\\ file.txt" - const expectedUnescaped = "nonexistent file.txt" - const expectedAbsPath = path.resolve(mockCwd, expectedUnescaped) - const mockError = new Error("ENOENT: no such file or directory") - ;(fs.stat as Mock).mockRejectedValue(mockError) - - const result = await parseMentions(text, mockCwd, mockUrlFetcher) - - expect(fs.stat).toHaveBeenCalledWith(expectedAbsPath) - expect(result).toContain( - `\nError fetching content: Failed to access path "nonexistent\\ file.txt": ${mockError.message}\n`, - ) - }) - - // Add more tests for parseMentions if needed (URLs, other mentions combined with escaped paths etc.) + expect(consoleErrorSpy).toHaveBeenCalledWith("Error fetching URL https://example.com:", timeoutError) + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("common:errors.url_fetch_error_with_url") + expect(result).toContain("Error fetching content: Navigation timeout of 30000 ms exceeded") }) - describe("openMention", () => { - beforeEach(() => { - ;(getWorkspacePath as Mock).mockReturnValue(mockCwd) - }) + it("should handle DNS resolution errors", async () => { + const dnsError = new Error("net::ERR_NAME_NOT_RESOLVED") + vi.mocked(mockUrlContentFetcher.urlToMarkdown).mockRejectedValue(dnsError) - it("should handle URLs", async () => { - const url = "https://example.com" - await openMention(url) - const mockUri = vscode.Uri.parse(url) - expect(vscode.env.openExternal).toHaveBeenCalled() - const calledArg = (vscode.env.openExternal as Mock).mock.calls[0][0] - expect(calledArg).toEqual( - expect.objectContaining({ - scheme: mockUri.scheme, - authority: mockUri.authority, - path: mockUri.path, - query: mockUri.query, - fragment: mockUri.fragment, - }), - ) - }) + const result = await parseMentions("Check @https://nonexistent.example", "/test", mockUrlContentFetcher) - it("should unescape file path before opening", async () => { - const mention = "/file\\ with\\ spaces.txt" - const expectedUnescaped = "file with spaces.txt" - const expectedAbsPath = path.resolve(mockCwd, expectedUnescaped) + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("common:errors.url_fetch_error_with_url") + expect(result).toContain("Error fetching content: net::ERR_NAME_NOT_RESOLVED") + }) - await openMention(mention) + it("should handle network disconnection errors", async () => { + const networkError = new Error("net::ERR_INTERNET_DISCONNECTED") + vi.mocked(mockUrlContentFetcher.urlToMarkdown).mockRejectedValue(networkError) - expect(openFile).toHaveBeenCalledWith(expectedAbsPath) - expect(vscode.commands.executeCommand).not.toHaveBeenCalled() - }) + const result = await parseMentions("Check @https://example.com", "/test", mockUrlContentFetcher) - it("should unescape folder path before revealing", async () => { - const mention = "/folder\\ with\\ spaces/" - const expectedUnescaped = "folder with spaces/" - const expectedAbsPath = path.resolve(mockCwd, expectedUnescaped) - const expectedUri = { fsPath: expectedAbsPath } // From mock - ;(vscode.Uri.file as Mock).mockReturnValue(expectedUri) + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("common:errors.url_fetch_error_with_url") + expect(result).toContain("Error fetching content: net::ERR_INTERNET_DISCONNECTED") + }) - await openMention(mention) + it("should handle 403 Forbidden errors", async () => { + const forbiddenError = new Error("403 Forbidden") + vi.mocked(mockUrlContentFetcher.urlToMarkdown).mockRejectedValue(forbiddenError) - expect(vscode.commands.executeCommand).toHaveBeenCalledWith("revealInExplorer", expectedUri) - expect(vscode.Uri.file).toHaveBeenCalledWith(expectedAbsPath) - expect(openFile).not.toHaveBeenCalled() - }) + const result = await parseMentions("Check @https://example.com", "/test", mockUrlContentFetcher) - it("should handle mentions without paths correctly", async () => { - await openMention("problems") - expect(vscode.commands.executeCommand).toHaveBeenCalledWith("workbench.actions.view.problems") + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("common:errors.url_fetch_error_with_url") + expect(result).toContain("Error fetching content: 403 Forbidden") + }) - await openMention("terminal") - expect(vscode.commands.executeCommand).toHaveBeenCalledWith("workbench.action.terminal.focus") + it("should handle 404 Not Found errors", async () => { + const notFoundError = new Error("404 Not Found") + vi.mocked(mockUrlContentFetcher.urlToMarkdown).mockRejectedValue(notFoundError) - await openMention("http://example.com") - expect(vscode.env.openExternal).toHaveBeenCalled() // Check if called, specific URI mock might be needed for detailed check + const result = await parseMentions("Check @https://example.com/missing", "/test", mockUrlContentFetcher) - await openMention("git-changes") // Assuming no specific action for this yet - // Add expectations if an action is defined for git-changes + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("common:errors.url_fetch_error_with_url") + expect(result).toContain("Error fetching content: 404 Not Found") + }) - await openMention("a1b2c3d") // Assuming no specific action for commit hashes yet - // Add expectations if an action is defined for commit hashes - }) + it("should handle generic errors with fallback message", async () => { + const genericError = new Error("Some unexpected error") + vi.mocked(mockUrlContentFetcher.urlToMarkdown).mockRejectedValue(genericError) - it("should do nothing if mention is undefined or empty", async () => { - await openMention(undefined) - await openMention("") - expect(openFile).not.toHaveBeenCalled() - expect(vscode.commands.executeCommand).not.toHaveBeenCalled() - expect(vscode.env.openExternal).not.toHaveBeenCalled() - }) + const result = await parseMentions("Check @https://example.com", "/test", mockUrlContentFetcher) - it("should do nothing if cwd is not available", async () => { - ;(getWorkspacePath as Mock).mockReturnValue(undefined) - await openMention("/some\\ path.txt") - expect(openFile).not.toHaveBeenCalled() - expect(vscode.commands.executeCommand).not.toHaveBeenCalled() - }) + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("common:errors.url_fetch_error_with_url") + expect(result).toContain("Error fetching content: Some unexpected error") + }) + + it("should handle non-Error objects thrown", async () => { + const nonErrorObject = { code: "UNKNOWN", details: "Something went wrong" } + vi.mocked(mockUrlContentFetcher.urlToMarkdown).mockRejectedValue(nonErrorObject) + + const result = await parseMentions("Check @https://example.com", "/test", mockUrlContentFetcher) + + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("common:errors.url_fetch_error_with_url") + expect(result).toContain("Error fetching content:") + }) + + it("should handle browser launch errors correctly", async () => { + const launchError = new Error("Failed to launch browser") + vi.mocked(mockUrlContentFetcher.launchBrowser).mockRejectedValue(launchError) + + const result = await parseMentions("Check @https://example.com", "/test", mockUrlContentFetcher) + + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith( + "Error fetching content for https://example.com: Failed to launch browser", + ) + expect(result).toContain("Error fetching content: Failed to launch browser") + // Should not attempt to fetch URL if browser launch failed + expect(mockUrlContentFetcher.urlToMarkdown).not.toHaveBeenCalled() + }) + + it("should handle browser launch errors without message property", async () => { + const launchError = "String error" + vi.mocked(mockUrlContentFetcher.launchBrowser).mockRejectedValue(launchError) + + const result = await parseMentions("Check @https://example.com", "/test", mockUrlContentFetcher) + + expect(vscode.window.showErrorMessage).toHaveBeenCalledWith( + "Error fetching content for https://example.com: String error", + ) + expect(result).toContain("Error fetching content: String error") + }) + + it("should successfully fetch URL content when no errors occur", async () => { + vi.mocked(mockUrlContentFetcher.urlToMarkdown).mockResolvedValue("# Example Content\n\nThis is the content.") + + const result = await parseMentions("Check @https://example.com", "/test", mockUrlContentFetcher) + + expect(vscode.window.showErrorMessage).not.toHaveBeenCalled() + expect(result).toContain('') + expect(result).toContain("# Example Content\n\nThis is the content.") + expect(result).toContain("") + }) + + it("should handle multiple URLs with mixed success and failure", async () => { + vi.mocked(mockUrlContentFetcher.urlToMarkdown) + .mockResolvedValueOnce("# First Site") + .mockRejectedValueOnce(new Error("timeout")) + + const result = await parseMentions( + "Check @https://example1.com and @https://example2.com", + "/test", + mockUrlContentFetcher, + ) + + expect(result).toContain('') + expect(result).toContain("# First Site") + expect(result).toContain('') + expect(result).toContain("Error fetching content: timeout") }) }) diff --git a/src/core/mentions/index.ts b/src/core/mentions/index.ts index 8ae4f7f131..780b27d1f7 100644 --- a/src/core/mentions/index.ts +++ b/src/core/mentions/index.ts @@ -19,6 +19,32 @@ import { FileContextTracker } from "../context-tracking/FileContextTracker" import { RooIgnoreController } from "../ignore/RooIgnoreController" +import { t } from "../../i18n" + +function getUrlErrorMessage(error: unknown): string { + const errorMessage = error instanceof Error ? error.message : String(error) + + // Check for common error patterns and return appropriate message + if (errorMessage.includes("timeout")) { + return t("common:errors.url_timeout") + } + if (errorMessage.includes("net::ERR_NAME_NOT_RESOLVED")) { + return t("common:errors.url_not_found") + } + if (errorMessage.includes("net::ERR_INTERNET_DISCONNECTED")) { + return t("common:errors.no_internet") + } + if (errorMessage.includes("403") || errorMessage.includes("Forbidden")) { + return t("common:errors.url_forbidden") + } + if (errorMessage.includes("404") || errorMessage.includes("Not Found")) { + return t("common:errors.url_page_not_found") + } + + // Default error message + return t("common:errors.url_fetch_failed", { error: errorMessage }) +} + export async function openMention(mention?: string): Promise { if (!mention) { return @@ -84,7 +110,8 @@ export async function parseMentions( await urlContentFetcher.launchBrowser() } catch (error) { launchBrowserError = error - vscode.window.showErrorMessage(`Error fetching content for ${urlMention}: ${error.message}`) + const errorMessage = error instanceof Error ? error.message : String(error) + vscode.window.showErrorMessage(`Error fetching content for ${urlMention}: ${errorMessage}`) } } @@ -92,14 +119,28 @@ export async function parseMentions( if (mention.startsWith("http")) { let result: string if (launchBrowserError) { - result = `Error fetching content: ${launchBrowserError.message}` + const errorMessage = + launchBrowserError instanceof Error ? launchBrowserError.message : String(launchBrowserError) + result = `Error fetching content: ${errorMessage}` } else { try { const markdown = await urlContentFetcher.urlToMarkdown(mention) result = markdown } catch (error) { - vscode.window.showErrorMessage(`Error fetching content for ${mention}: ${error.message}`) - result = `Error fetching content: ${error.message}` + console.error(`Error fetching URL ${mention}:`, error) + + // Get raw error message for AI + const rawErrorMessage = error instanceof Error ? error.message : String(error) + + // Get localized error message for UI notification + const localizedErrorMessage = getUrlErrorMessage(error) + + vscode.window.showErrorMessage( + t("common:errors.url_fetch_error_with_url", { url: mention, error: localizedErrorMessage }), + ) + + // Send raw error message to AI model + result = `Error fetching content: ${rawErrorMessage}` } } parsedText += `\n\n\n${result}\n` diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json index 8e9f07c100..0c465dcfd3 100644 --- a/src/i18n/locales/ca/common.json +++ b/src/i18n/locales/ca/common.json @@ -62,6 +62,13 @@ "condensed_recently": "El context s'ha condensat recentment; s'omet aquest intent", "condense_handler_invalid": "El gestor de l'API per condensar el context no รฉs vร lid", "condense_context_grew": "La mida del context ha augmentat durant la condensaciรณ; s'omet aquest intent", + "url_timeout": "El lloc web ha trigat massa a carregar (timeout). Aixรฒ pot ser degut a una connexiรณ lenta, un lloc web pesat o temporalment no disponible. Pots tornar-ho a provar mรฉs tard o comprovar si la URL รฉs correcta.", + "url_not_found": "No s'ha pogut trobar l'adreรงa del lloc web. Comprova si la URL รฉs correcta i torna-ho a provar.", + "no_internet": "No hi ha connexiรณ a internet. Comprova la teva connexiรณ de xarxa i torna-ho a provar.", + "url_forbidden": "L'accรฉs a aquest lloc web estร  prohibit. El lloc pot bloquejar l'accรฉs automatitzat o requerir autenticaciรณ.", + "url_page_not_found": "No s'ha trobat la pร gina. Comprova si la URL รฉs correcta.", + "url_fetch_failed": "Error en obtenir el contingut de la URL: {{error}}", + "url_fetch_error_with_url": "Error en obtenir contingut per {{url}}: {{error}}", "share_task_failed": "Ha fallat compartir la tasca. Si us plau, torna-ho a provar.", "share_no_active_task": "No hi ha cap tasca activa per compartir", "share_auth_required": "Es requereix autenticaciรณ. Si us plau, inicia sessiรณ per compartir tasques.", diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json index fc4ce25de1..148e51200a 100644 --- a/src/i18n/locales/de/common.json +++ b/src/i18n/locales/de/common.json @@ -58,6 +58,13 @@ "condensed_recently": "Kontext wurde kรผrzlich verdichtet; dieser Versuch wird รผbersprungen", "condense_handler_invalid": "API-Handler zum Verdichten des Kontexts ist ungรผltig", "condense_context_grew": "KontextgrรถรŸe ist wรคhrend der Verdichtung gewachsen; dieser Versuch wird รผbersprungen", + "url_timeout": "Die Website hat zu lange zum Laden gebraucht (Timeout). Das kรถnnte an einer langsamen Verbindung, einer schweren Website oder vorรผbergehender Nichtverfรผgbarkeit liegen. Du kannst es spรคter nochmal versuchen oder prรผfen, ob die URL korrekt ist.", + "url_not_found": "Die Website-Adresse konnte nicht gefunden werden. Bitte prรผfe, ob die URL korrekt ist und versuche es erneut.", + "no_internet": "Keine Internetverbindung. Bitte prรผfe deine Netzwerkverbindung und versuche es erneut.", + "url_forbidden": "Zugriff auf diese Website ist verboten. Die Seite kรถnnte automatisierten Zugriff blockieren oder eine Authentifizierung erfordern.", + "url_page_not_found": "Die Seite wurde nicht gefunden. Bitte prรผfe, ob die URL korrekt ist.", + "url_fetch_failed": "Fehler beim Abrufen des URL-Inhalts: {{error}}", + "url_fetch_error_with_url": "Fehler beim Abrufen des Inhalts fรผr {{url}}: {{error}}", "share_task_failed": "Teilen der Aufgabe fehlgeschlagen. Bitte versuche es erneut.", "share_no_active_task": "Keine aktive Aufgabe zum Teilen", "share_auth_required": "Authentifizierung erforderlich. Bitte melde dich an, um Aufgaben zu teilen.", diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index 3f19a1dd50..b1b3de42b6 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -58,6 +58,13 @@ "condensed_recently": "Context was condensed recently; skipping this attempt", "condense_handler_invalid": "API handler for condensing context is invalid", "condense_context_grew": "Context size increased during condensing; skipping this attempt", + "url_timeout": "The website took too long to load (timeout). This could be due to a slow connection, heavy website, or the site being temporarily unavailable. You can try again later or check if the URL is correct.", + "url_not_found": "The website address could not be found. Please check if the URL is correct and try again.", + "no_internet": "No internet connection. Please check your network connection and try again.", + "url_forbidden": "Access to this website is forbidden. The site may block automated access or require authentication.", + "url_page_not_found": "The page was not found. Please check if the URL is correct.", + "url_fetch_failed": "Failed to fetch URL content: {{error}}", + "url_fetch_error_with_url": "Error fetching content for {{url}}: {{error}}", "share_task_failed": "Failed to share task. Please try again.", "share_no_active_task": "No active task to share", "share_auth_required": "Authentication required. Please sign in to share tasks.", diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json index 4b3177619e..0916a64a88 100644 --- a/src/i18n/locales/es/common.json +++ b/src/i18n/locales/es/common.json @@ -58,6 +58,13 @@ "condensed_recently": "El contexto se condensรณ recientemente; se omite este intento", "condense_handler_invalid": "El manejador de API para condensar el contexto no es vรกlido", "condense_context_grew": "El tamaรฑo del contexto aumentรณ durante la condensaciรณn; se omite este intento", + "url_timeout": "El sitio web tardรณ demasiado en cargar (timeout). Esto podrรญa deberse a una conexiรณn lenta, un sitio web pesado o que estรฉ temporalmente no disponible. Puedes intentarlo mรกs tarde o verificar si la URL es correcta.", + "url_not_found": "No se pudo encontrar la direcciรณn del sitio web. Por favor verifica si la URL es correcta e intรฉntalo de nuevo.", + "no_internet": "Sin conexiรณn a internet. Por favor verifica tu conexiรณn de red e intรฉntalo de nuevo.", + "url_forbidden": "El acceso a este sitio web estรก prohibido. El sitio puede bloquear el acceso automatizado o requerir autenticaciรณn.", + "url_page_not_found": "La pรกgina no fue encontrada. Por favor verifica si la URL es correcta.", + "url_fetch_failed": "Error al obtener el contenido de la URL: {{error}}", + "url_fetch_error_with_url": "Error al obtener contenido para {{url}}: {{error}}", "share_task_failed": "Error al compartir la tarea. Por favor, intรฉntalo de nuevo.", "share_no_active_task": "No hay tarea activa para compartir", "share_auth_required": "Se requiere autenticaciรณn. Por favor, inicia sesiรณn para compartir tareas.", diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json index 93cd67ca15..40809077ab 100644 --- a/src/i18n/locales/fr/common.json +++ b/src/i18n/locales/fr/common.json @@ -58,6 +58,13 @@ "condensed_recently": "Le contexte a รฉtรฉ condensรฉ rรฉcemment ; cette tentative est ignorรฉe", "condense_handler_invalid": "Le gestionnaire d'API pour condenser le contexte est invalide", "condense_context_grew": "La taille du contexte a augmentรฉ pendant la condensation ; cette tentative est ignorรฉe", + "url_timeout": "Le site web a pris trop de temps ร  charger (timeout). Cela pourrait รชtre dรป ร  une connexion lente, un site web lourd ou temporairement indisponible. Tu peux rรฉessayer plus tard ou vรฉrifier si l'URL est correcte.", + "url_not_found": "L'adresse du site web n'a pas pu รชtre trouvรฉe. Vรฉrifie si l'URL est correcte et rรฉessaie.", + "no_internet": "Pas de connexion internet. Vรฉrifie ta connexion rรฉseau et rรฉessaie.", + "url_forbidden": "L'accรจs ร  ce site web est interdit. Le site peut bloquer l'accรจs automatisรฉ ou nรฉcessiter une authentification.", + "url_page_not_found": "La page n'a pas รฉtรฉ trouvรฉe. Vรฉrifie si l'URL est correcte.", + "url_fetch_failed": "ร‰chec de rรฉcupรฉration du contenu de l'URL : {{error}}", + "url_fetch_error_with_url": "Erreur lors de la rรฉcupรฉration du contenu pour {{url}} : {{error}}", "share_task_failed": "ร‰chec du partage de la tรขche. Veuillez rรฉessayer.", "share_no_active_task": "Aucune tรขche active ร  partager", "share_auth_required": "Authentification requise. Veuillez vous connecter pour partager des tรขches.", diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json index 68788beacc..4b6c473d96 100644 --- a/src/i18n/locales/hi/common.json +++ b/src/i18n/locales/hi/common.json @@ -58,6 +58,13 @@ "condensed_recently": "เคธเค‚เคฆเคฐเฅเคญ เคนเคพเคฒ เคนเฅ€ เคฎเฅ‡เค‚ เคธเค‚เค•เฅเคทเคฟเคชเฅเคค เค•เคฟเคฏเคพ เค—เคฏเคพ เคฅเคพ; เค‡เคธ เคชเฅเคฐเคฏเคพเคธ เค•เฅ‹ เค›เฅ‹เคกเคผเคพ เคœเคพ เคฐเคนเคพ เคนเฅˆ", "condense_handler_invalid": "เคธเค‚เคฆเคฐเฅเคญ เค•เฅ‹ เคธเค‚เค•เฅเคทเคฟเคชเฅเคค เค•เคฐเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค API เคนเฅˆเค‚เคกเคฒเคฐ เค…เคฎเคพเคจเฅเคฏ เคนเฅˆ", "condense_context_grew": "เคธเค‚เค•เฅเคทเคฟเคชเฅเคคเฅ€เค•เคฐเคฃ เค•เฅ‡ เคฆเฅŒเคฐเคพเคจ เคธเค‚เคฆเคฐเฅเคญ เค•เคพ เค†เค•เคพเคฐ เคฌเคขเคผ เค—เคฏเคพ; เค‡เคธ เคชเฅเคฐเคฏเคพเคธ เค•เฅ‹ เค›เฅ‹เคกเคผเคพ เคœเคพ เคฐเคนเคพ เคนเฅˆ", + "url_timeout": "เคตเฅ‡เคฌเคธเคพเค‡เคŸ เคฒเฅ‹เคก เคนเฅ‹เคจเฅ‡ เคฎเฅ‡เค‚ เคฌเคนเฅเคค เคธเคฎเคฏ เคฒเค—เคพ (เคŸเคพเค‡เคฎเค†เค‰เคŸ)เฅค เคฏเคน เคงเฅ€เคฎเฅ‡ เค•เคจเฅ‡เค•เฅเคถเคจ, เคญเคพเคฐเฅ€ เคตเฅ‡เคฌเคธเคพเค‡เคŸ เคฏเคพ เค…เคธเฅเคฅเคพเคฏเฅ€ เคฐเฅ‚เคช เคธเฅ‡ เค…เคจเฅเคชเคฒเคฌเฅเคง เคนเฅ‹เคจเฅ‡ เค•เฅ‡ เค•เคพเคฐเคฃ เคนเฅ‹ เคธเค•เคคเคพ เคนเฅˆเฅค เค†เคช เคฌเคพเคฆ เคฎเฅ‡เค‚ เคซเคฟเคฐ เคธเฅ‡ เค•เฅ‹เคถเคฟเคถ เค•เคฐ เคธเค•เคคเฅ‡ เคนเฅˆเค‚ เคฏเคพ เคœเคพเค‚เคš เคธเค•เคคเฅ‡ เคนเฅˆเค‚ เค•เคฟ URL เคธเคนเฅ€ เคนเฅˆ เคฏเคพ เคจเคนเฅ€เค‚เฅค", + "url_not_found": "เคตเฅ‡เคฌเคธเคพเค‡เคŸ เค•เคพ เคชเคคเคพ เคจเคนเฅ€เค‚ เคฎเคฟเคฒ เคธเค•เคพเฅค เค•เฅƒเคชเคฏเคพ เคœเคพเค‚เคšเฅ‡เค‚ เค•เคฟ URL เคธเคนเฅ€ เคนเฅˆ เค”เคฐ เคซเคฟเคฐ เคธเฅ‡ เค•เฅ‹เคถเคฟเคถ เค•เคฐเฅ‡เค‚เฅค", + "no_internet": "เค‡เค‚เคŸเคฐเคจเฅ‡เคŸ เค•เคจเฅ‡เค•เฅเคถเคจ เคจเคนเฅ€เค‚ เคนเฅˆเฅค เค•เฅƒเคชเคฏเคพ เค…เคชเคจเคพ เคจเฅ‡เคŸเคตเคฐเฅเค• เค•เคจเฅ‡เค•เฅเคถเคจ เคœเคพเค‚เคšเฅ‡เค‚ เค”เคฐ เคซเคฟเคฐ เคธเฅ‡ เค•เฅ‹เคถเคฟเคถ เค•เคฐเฅ‡เค‚เฅค", + "url_forbidden": "เค‡เคธ เคตเฅ‡เคฌเคธเคพเค‡เคŸ เคคเค• เคชเคนเฅเค‚เคš เคชเฅเคฐเคคเคฟเคฌเค‚เคงเคฟเคค เคนเฅˆเฅค เคธเคพเค‡เคŸ เคธเฅเคตเคšเคพเคฒเคฟเคค เคชเคนเฅเค‚เคš เค•เฅ‹ เคฌเฅเคฒเฅ‰เค• เค•เคฐ เคธเค•เคคเฅ€ เคนเฅˆ เคฏเคพ เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เคนเฅ‹ เคธเค•เคคเฅ€ เคนเฅˆเฅค", + "url_page_not_found": "เคชเฅ‡เคœ เคจเคนเฅ€เค‚ เคฎเคฟเคฒเคพเฅค เค•เฅƒเคชเคฏเคพ เคœเคพเค‚เคšเฅ‡เค‚ เค•เคฟ URL เคธเคนเฅ€ เคนเฅˆเฅค", + "url_fetch_failed": "URL เคธเคพเคฎเค—เฅเคฐเฅ€ เคชเฅเคฐเคพเคชเฅเคค เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคคเฅเคฐเฅเคŸเคฟ: {{error}}", + "url_fetch_error_with_url": "{{url}} เค•เฅ‡ เคฒเคฟเค เคธเคพเคฎเค—เฅเคฐเฅ€ เคชเฅเคฐเคพเคชเฅเคค เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคคเฅเคฐเฅเคŸเคฟ: {{error}}", "share_task_failed": "เค•เคพเคฐเฅเคฏ เคธเคพเคเคพ เค•เคฐเคจเฅ‡ เคฎเฅ‡เค‚ เคตเคฟเคซเคฒเฅค เค•เฅƒเคชเคฏเคพ เคชเฅเคจเคƒ เคชเฅเคฐเคฏเคพเคธ เค•เคฐเฅ‡เค‚เฅค", "share_no_active_task": "เคธเคพเคเคพ เค•เคฐเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค•เฅ‹เคˆ เคธเค•เฅเคฐเคฟเคฏ เค•เคพเคฐเฅเคฏ เคจเคนเฅ€เค‚", "share_auth_required": "เคชเฅเคฐเคฎเคพเคฃเฅ€เค•เคฐเคฃ เค†เคตเคถเฅเคฏเค• เคนเฅˆเฅค เค•เคพเคฐเฅเคฏ เคธเคพเคเคพ เค•เคฐเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค•เฅƒเคชเคฏเคพ เคธเคพเค‡เคจ เค‡เคจ เค•เคฐเฅ‡เค‚เฅค", diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json index d6bb2ffa98..7bc320f268 100644 --- a/src/i18n/locales/id/common.json +++ b/src/i18n/locales/id/common.json @@ -58,6 +58,13 @@ "condensed_recently": "Konteks baru saja dikompres; melewati percobaan ini", "condense_handler_invalid": "Handler API untuk mengompres konteks tidak valid", "condense_context_grew": "Ukuran konteks bertambah saat mengompres; melewati percobaan ini", + "url_timeout": "Situs web membutuhkan waktu terlalu lama untuk dimuat (timeout). Ini bisa disebabkan oleh koneksi lambat, situs web berat, atau sementara tidak tersedia. Kamu bisa mencoba lagi nanti atau memeriksa apakah URL sudah benar.", + "url_not_found": "Alamat situs web tidak dapat ditemukan. Silakan periksa apakah URL sudah benar dan coba lagi.", + "no_internet": "Tidak ada koneksi internet. Silakan periksa koneksi jaringan kamu dan coba lagi.", + "url_forbidden": "Akses ke situs web ini dilarang. Situs mungkin memblokir akses otomatis atau memerlukan autentikasi.", + "url_page_not_found": "Halaman tidak ditemukan. Silakan periksa apakah URL sudah benar.", + "url_fetch_failed": "Gagal mengambil konten URL: {{error}}", + "url_fetch_error_with_url": "Error mengambil konten untuk {{url}}: {{error}}", "share_task_failed": "Gagal membagikan tugas. Silakan coba lagi.", "share_no_active_task": "Tidak ada tugas aktif untuk dibagikan", "share_auth_required": "Autentikasi diperlukan. Silakan masuk untuk berbagi tugas.", diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json index 0ef6ee5b54..2b0969a40d 100644 --- a/src/i18n/locales/it/common.json +++ b/src/i18n/locales/it/common.json @@ -58,6 +58,13 @@ "condensed_recently": "Il contesto รจ stato condensato di recente; questo tentativo viene saltato", "condense_handler_invalid": "Il gestore API per condensare il contesto non รจ valido", "condense_context_grew": "La dimensione del contesto รจ aumentata durante la condensazione; questo tentativo viene saltato", + "url_timeout": "Il sito web ha impiegato troppo tempo a caricarsi (timeout). Questo potrebbe essere dovuto a una connessione lenta, un sito web pesante o temporaneamente non disponibile. Puoi riprovare piรน tardi o verificare se l'URL รจ corretto.", + "url_not_found": "L'indirizzo del sito web non รจ stato trovato. Verifica se l'URL รจ corretto e riprova.", + "no_internet": "Nessuna connessione internet. Verifica la tua connessione di rete e riprova.", + "url_forbidden": "L'accesso a questo sito web รจ vietato. Il sito potrebbe bloccare l'accesso automatizzato o richiedere autenticazione.", + "url_page_not_found": "La pagina non รจ stata trovata. Verifica se l'URL รจ corretto.", + "url_fetch_failed": "Errore nel recupero del contenuto URL: {{error}}", + "url_fetch_error_with_url": "Errore nel recupero del contenuto per {{url}}: {{error}}", "share_task_failed": "Condivisione dell'attivitร  fallita. Riprova.", "share_no_active_task": "Nessuna attivitร  attiva da condividere", "share_auth_required": "Autenticazione richiesta. Accedi per condividere le attivitร .", diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index b132470eac..3466c82e73 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -58,6 +58,13 @@ "condensed_recently": "ใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใฏๆœ€่ฟ‘ๅœง็ธฎใ•ใ‚Œใพใ—ใŸ๏ผ›ใ“ใฎ่ฉฆ่กŒใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ—ใพใ™", "condense_handler_invalid": "ใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚’ๅœง็ธฎใ™ใ‚‹ใŸใ‚ใฎAPIใƒใƒณใƒ‰ใƒฉใƒผใŒ็„กๅŠนใงใ™", "condense_context_grew": "ๅœง็ธฎไธญใซใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚ตใ‚คใ‚บใŒๅข—ๅŠ ใ—ใพใ—ใŸ๏ผ›ใ“ใฎ่ฉฆ่กŒใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ—ใพใ™", + "url_timeout": "ใ‚ฆใ‚งใƒ–ใ‚ตใ‚คใƒˆใฎ่ชญใฟ่พผใฟใŒใ‚ฟใ‚คใƒ ใ‚ขใ‚ฆใƒˆใ—ใพใ—ใŸใ€‚ๆŽฅ็ถšใŒ้…ใ„ใ€ใ‚ฆใ‚งใƒ–ใ‚ตใ‚คใƒˆใŒ้‡ใ„ใ€ใพใŸใฏไธ€ๆ™‚็š„ใซๅˆฉ็”จใงใใชใ„ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚ๅพŒใงใ‚‚ใ†ไธ€ๅบฆ่ฉฆใ™ใ‹ใ€URLใŒๆญฃใ—ใ„ใ‹็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚", + "url_not_found": "ใ‚ฆใ‚งใƒ–ใ‚ตใ‚คใƒˆใฎใ‚ขใƒ‰ใƒฌใ‚นใŒ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“ใงใ—ใŸใ€‚URLใŒๆญฃใ—ใ„ใ‹็ขบ่ชใ—ใฆใ‚‚ใ†ไธ€ๅบฆ่ฉฆใ—ใฆใใ ใ•ใ„ใ€‚", + "no_internet": "ใ‚คใƒณใ‚ฟใƒผใƒใƒƒใƒˆๆŽฅ็ถšใŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใƒใƒƒใƒˆใƒฏใƒผใ‚ฏๆŽฅ็ถšใ‚’็ขบ่ชใ—ใฆใ‚‚ใ†ไธ€ๅบฆ่ฉฆใ—ใฆใใ ใ•ใ„ใ€‚", + "url_forbidden": "ใ“ใฎใ‚ฆใ‚งใƒ–ใ‚ตใ‚คใƒˆใธใฎใ‚ขใ‚ฏใ‚ปใ‚นใŒ็ฆๆญขใ•ใ‚Œใฆใ„ใพใ™ใ€‚ใ‚ตใ‚คใƒˆใŒ่‡ชๅ‹•ใ‚ขใ‚ฏใ‚ปใ‚นใ‚’ใƒ–ใƒญใƒƒใ‚ฏใ—ใฆใ„ใ‚‹ใ‹ใ€่ช่จผใŒๅฟ…่ฆใชๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚", + "url_page_not_found": "ใƒšใƒผใ‚ธใŒ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“ใงใ—ใŸใ€‚URLใŒๆญฃใ—ใ„ใ‹็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚", + "url_fetch_failed": "URLใ‚ณใƒณใƒ†ใƒณใƒ„ใฎๅ–ๅพ—ใซๅคฑๆ•—ใ—ใพใ—ใŸ๏ผš{{error}}", + "url_fetch_error_with_url": "{{url}} ใฎใ‚ณใƒณใƒ†ใƒณใƒ„ๅ–ๅพ—ใ‚จใƒฉใƒผ๏ผš{{error}}", "share_task_failed": "ใ‚ฟใ‚นใ‚ฏใฎๅ…ฑๆœ‰ใซๅคฑๆ•—ใ—ใพใ—ใŸ", "share_no_active_task": "ๅ…ฑๆœ‰ใ™ใ‚‹ใ‚ขใ‚ฏใƒ†ใ‚ฃใƒ–ใชใ‚ฟใ‚นใ‚ฏใŒใ‚ใ‚Šใพใ›ใ‚“", "share_auth_required": "่ช่จผใŒๅฟ…่ฆใงใ™ใ€‚ใ‚ฟใ‚นใ‚ฏใ‚’ๅ…ฑๆœ‰ใ™ใ‚‹ใซใฏใ‚ตใ‚คใƒณใ‚คใƒณใ—ใฆใใ ใ•ใ„ใ€‚", diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json index 079bb56a48..3fc50cb95b 100644 --- a/src/i18n/locales/ko/common.json +++ b/src/i18n/locales/ko/common.json @@ -58,6 +58,13 @@ "condensed_recently": "์ปจํ…์ŠคํŠธ๊ฐ€ ์ตœ๊ทผ ์••์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค; ์ด ์‹œ๋„๋ฅผ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค", "condense_handler_invalid": "์ปจํ…์ŠคํŠธ ์••์ถ•์„ ์œ„ํ•œ API ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค", "condense_context_grew": "์••์ถ• ์ค‘ ์ปจํ…์ŠคํŠธ ํฌ๊ธฐ๊ฐ€ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค; ์ด ์‹œ๋„๋ฅผ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค", + "url_timeout": "์›น์‚ฌ์ดํŠธ ๋กœ๋”ฉ์ด ๋„ˆ๋ฌด ์˜ค๋ž˜ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค(ํƒ€์ž„์•„์›ƒ). ๋А๋ฆฐ ์—ฐ๊ฒฐ, ๋ฌด๊ฑฐ์šด ์›น์‚ฌ์ดํŠธ ๋˜๋Š” ์ผ์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ƒํƒœ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋‹ค์‹œ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ URL์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.", + "url_not_found": "์›น์‚ฌ์ดํŠธ ์ฃผ์†Œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. URL์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•˜๊ณ  ๋‹ค์‹œ ์‹œ๋„ํ•ด ์ฃผ์„ธ์š”.", + "no_internet": "์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ํ™•์ธํ•˜๊ณ  ๋‹ค์‹œ ์‹œ๋„ํ•ด ์ฃผ์„ธ์š”.", + "url_forbidden": "์ด ์›น์‚ฌ์ดํŠธ์— ๋Œ€ํ•œ ์ ‘๊ทผ์ด ๊ธˆ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ดํŠธ๊ฐ€ ์ž๋™ ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•˜๊ฑฐ๋‚˜ ์ธ์ฆ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.", + "url_page_not_found": "ํŽ˜์ด์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. URL์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.", + "url_fetch_failed": "URL ์ฝ˜ํ…์ธ  ๊ฐ€์ ธ์˜ค๊ธฐ ์‹คํŒจ: {{error}}", + "url_fetch_error_with_url": "{{url}} ์ฝ˜ํ…์ธ  ๊ฐ€์ ธ์˜ค๊ธฐ ์˜ค๋ฅ˜: {{error}}", "share_task_failed": "์ž‘์—… ๊ณต์œ ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค", "share_no_active_task": "๊ณต์œ ํ•  ํ™œ์„ฑ ์ž‘์—…์ด ์—†์Šต๋‹ˆ๋‹ค", "share_auth_required": "์ธ์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์„ ๊ณต์œ ํ•˜๋ ค๋ฉด ๋กœ๊ทธ์ธํ•˜์„ธ์š”.", diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json index ef27bef3d8..22f7b50b8f 100644 --- a/src/i18n/locales/nl/common.json +++ b/src/i18n/locales/nl/common.json @@ -58,6 +58,13 @@ "condensed_recently": "Context is recent gecomprimeerd; deze poging wordt overgeslagen", "condense_handler_invalid": "API-handler voor het comprimeren van context is ongeldig", "condense_context_grew": "Contextgrootte nam toe tijdens comprimeren; deze poging wordt overgeslagen", + "url_timeout": "De website deed er te lang over om te laden (timeout). Dit kan komen door een trage verbinding, een zware website of tijdelijke onbeschikbaarheid. Je kunt het later opnieuw proberen of controleren of de URL correct is.", + "url_not_found": "Het websiteadres kon niet worden gevonden. Controleer of de URL correct is en probeer opnieuw.", + "no_internet": "Geen internetverbinding. Controleer je netwerkverbinding en probeer opnieuw.", + "url_forbidden": "Toegang tot deze website is verboden. De site kan geautomatiseerde toegang blokkeren of authenticatie vereisen.", + "url_page_not_found": "De pagina werd niet gevonden. Controleer of de URL correct is.", + "url_fetch_failed": "Fout bij ophalen van URL-inhoud: {{error}}", + "url_fetch_error_with_url": "Fout bij ophalen van inhoud voor {{url}}: {{error}}", "share_task_failed": "Delen van taak mislukt", "share_no_active_task": "Geen actieve taak om te delen", "share_auth_required": "Authenticatie vereist. Log in om taken te delen.", diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json index 777bbd82b7..d6a2248eed 100644 --- a/src/i18n/locales/pl/common.json +++ b/src/i18n/locales/pl/common.json @@ -58,6 +58,13 @@ "condensed_recently": "Kontekst zostaล‚ niedawno skondensowany; pomijanie tej prรณby", "condense_handler_invalid": "Nieprawidล‚owy handler API do kondensowania kontekstu", "condense_context_grew": "Rozmiar kontekstu wzrรณsล‚ podczas kondensacji; pomijanie tej prรณby", + "url_timeout": "Strona internetowa ล‚adowaล‚a siฤ™ zbyt dล‚ugo (timeout). Moลผe to byฤ‡ spowodowane wolnym poล‚ฤ…czeniem, ciฤ™ลผkฤ… stronฤ… lub tymczasowฤ… niedostฤ™pnoล›ciฤ…. Moลผesz sprรณbowaฤ‡ ponownie pรณลบniej lub sprawdziฤ‡, czy URL jest poprawny.", + "url_not_found": "Nie moลผna znaleลบฤ‡ adresu strony internetowej. Sprawdลบ, czy URL jest poprawny i sprรณbuj ponownie.", + "no_internet": "Brak poล‚ฤ…czenia z internetem. Sprawdลบ poล‚ฤ…czenie sieciowe i sprรณbuj ponownie.", + "url_forbidden": "Dostฤ™p do tej strony internetowej jest zabroniony. Strona moลผe blokowaฤ‡ automatyczny dostฤ™p lub wymagaฤ‡ uwierzytelnienia.", + "url_page_not_found": "Strona nie zostaล‚a znaleziona. Sprawdลบ, czy URL jest poprawny.", + "url_fetch_failed": "Bล‚ฤ…d pobierania zawartoล›ci URL: {{error}}", + "url_fetch_error_with_url": "Bล‚ฤ…d pobierania zawartoล›ci dla {{url}}: {{error}}", "share_task_failed": "Nie udaล‚o siฤ™ udostฤ™pniฤ‡ zadania", "share_no_active_task": "Brak aktywnego zadania do udostฤ™pnienia", "share_auth_required": "Wymagana autoryzacja. Zaloguj siฤ™, aby udostฤ™pniaฤ‡ zadania.", diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json index 18695588c8..9283f04e78 100644 --- a/src/i18n/locales/pt-BR/common.json +++ b/src/i18n/locales/pt-BR/common.json @@ -62,6 +62,13 @@ "condensed_recently": "O contexto foi condensado recentemente; pulando esta tentativa", "condense_handler_invalid": "O manipulador de API para condensar o contexto รฉ invรกlido", "condense_context_grew": "O tamanho do contexto aumentou durante a condensaรงรฃo; pulando esta tentativa", + "url_timeout": "O site demorou muito para carregar (timeout). Isso pode ser devido a uma conexรฃo lenta, site pesado ou temporariamente indisponรญvel. Vocรช pode tentar novamente mais tarde ou verificar se a URL estรก correta.", + "url_not_found": "O endereรงo do site nรฃo pรดde ser encontrado. Verifique se a URL estรก correta e tente novamente.", + "no_internet": "Sem conexรฃo com a internet. Verifique sua conexรฃo de rede e tente novamente.", + "url_forbidden": "O acesso a este site estรก proibido. O site pode bloquear acesso automatizado ou exigir autenticaรงรฃo.", + "url_page_not_found": "A pรกgina nรฃo foi encontrada. Verifique se a URL estรก correta.", + "url_fetch_failed": "Falha ao buscar conteรบdo da URL: {{error}}", + "url_fetch_error_with_url": "Erro ao buscar conteรบdo para {{url}}: {{error}}", "share_task_failed": "Falha ao compartilhar tarefa", "share_no_active_task": "Nenhuma tarefa ativa para compartilhar", "share_auth_required": "Autenticaรงรฃo necessรกria. Faรงa login para compartilhar tarefas.", diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json index b0e4f58ceb..e25f4c3040 100644 --- a/src/i18n/locales/ru/common.json +++ b/src/i18n/locales/ru/common.json @@ -58,6 +58,13 @@ "condensed_recently": "ะšะพะฝั‚ะตะบัั‚ ะฑั‹ะป ะฝะตะดะฐะฒะฝะพ ัะถะฐั‚; ะฟั€ะพะฟัƒัะบะฐะตะผ ัั‚ัƒ ะฟะพะฟั‹ั‚ะบัƒ", "condense_handler_invalid": "ะžะฑั€ะฐะฑะพั‚ั‡ะธะบ API ะดะปั ัะถะฐั‚ะธั ะบะพะฝั‚ะตะบัั‚ะฐ ะฝะตะดะตะนัั‚ะฒะธั‚ะตะปะตะฝ", "condense_context_grew": "ะ ะฐะทะผะตั€ ะบะพะฝั‚ะตะบัั‚ะฐ ัƒะฒะตะปะธั‡ะธะปัั ะฒะพ ะฒั€ะตะผั ัะถะฐั‚ะธั; ะฟั€ะพะฟัƒัะบะฐะตะผ ัั‚ัƒ ะฟะพะฟั‹ั‚ะบัƒ", + "url_timeout": "ะ’ะตะฑ-ัะฐะนั‚ ัะปะธัˆะบะพะผ ะดะพะปะณะพ ะทะฐะณั€ัƒะถะฐะปัั (ั‚ะฐะนะผะฐัƒั‚). ะญั‚ะพ ะผะพะถะตั‚ ะฑั‹ั‚ัŒ ะธะท-ะทะฐ ะผะตะดะปะตะฝะฝะพะณะพ ัะพะตะดะธะฝะตะฝะธั, ั‚ัะถะตะปะพะณะพ ะฒะตะฑ-ัะฐะนั‚ะฐ ะธะปะธ ะฒั€ะตะผะตะฝะฝะพะน ะฝะตะดะพัั‚ัƒะฟะฝะพัั‚ะธ. ะขั‹ ะผะพะถะตัˆัŒ ะฟะพะฟั€ะพะฑะพะฒะฐั‚ัŒ ะฟะพะทะถะต ะธะปะธ ะฟั€ะพะฒะตั€ะธั‚ัŒ ะฟั€ะฐะฒะธะปัŒะฝะพัั‚ัŒ URL.", + "url_not_found": "ะะดั€ะตั ะฒะตะฑ-ัะฐะนั‚ะฐ ะฝะต ะฝะฐะนะดะตะฝ. ะŸั€ะพะฒะตั€ัŒ ะฟั€ะฐะฒะธะปัŒะฝะพัั‚ัŒ URL ะธ ะฟะพะฟั€ะพะฑัƒะน ัะฝะพะฒะฐ.", + "no_internet": "ะะตั‚ ะฟะพะดะบะปัŽั‡ะตะฝะธั ะบ ะธะฝั‚ะตั€ะฝะตั‚ัƒ. ะŸั€ะพะฒะตั€ัŒ ัะตั‚ะตะฒะพะต ะฟะพะดะบะปัŽั‡ะตะฝะธะต ะธ ะฟะพะฟั€ะพะฑัƒะน ัะฝะพะฒะฐ.", + "url_forbidden": "ะ”ะพัั‚ัƒะฟ ะบ ัั‚ะพะผัƒ ะฒะตะฑ-ัะฐะนั‚ัƒ ะทะฐะฟั€ะตั‰ะตะฝ. ะกะฐะนั‚ ะผะพะถะตั‚ ะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ ะฐะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธะน ะดะพัั‚ัƒะฟ ะธะปะธ ั‚ั€ะตะฑะพะฒะฐั‚ัŒ ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธัŽ.", + "url_page_not_found": "ะกั‚ั€ะฐะฝะธั†ะฐ ะฝะต ะฝะฐะนะดะตะฝะฐ. ะŸั€ะพะฒะตั€ัŒ ะฟั€ะฐะฒะธะปัŒะฝะพัั‚ัŒ URL.", + "url_fetch_failed": "ะžัˆะธะฑะบะฐ ะฟะพะปัƒั‡ะตะฝะธั ัะพะดะตั€ะถะธะผะพะณะพ URL: {{error}}", + "url_fetch_error_with_url": "ะžัˆะธะฑะบะฐ ะฟะพะปัƒั‡ะตะฝะธั ัะพะดะตั€ะถะธะผะพะณะพ ะดะปั {{url}}: {{error}}", "share_task_failed": "ะะต ัƒะดะฐะปะพััŒ ะฟะพะดะตะปะธั‚ัŒัั ะทะฐะดะฐั‡ะตะน", "share_no_active_task": "ะะตั‚ ะฐะบั‚ะธะฒะฝะพะน ะทะฐะดะฐั‡ะธ ะดะปั ัะพะฒะผะตัั‚ะฝะพะณะพ ะธัะฟะพะปัŒะทะพะฒะฐะฝะธั", "share_auth_required": "ะขั€ะตะฑัƒะตั‚ัั ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธั. ะ’ะพะนะดะธั‚ะต ะฒ ัะธัั‚ะตะผัƒ ะดะปั ัะพะฒะผะตัั‚ะฝะพะณะพ ะดะพัั‚ัƒะฟะฐ ะบ ะทะฐะดะฐั‡ะฐะผ.", diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json index 9663cac808..6f31478aec 100644 --- a/src/i18n/locales/tr/common.json +++ b/src/i18n/locales/tr/common.json @@ -58,6 +58,13 @@ "condensed_recently": "BaฤŸlam yakฤฑn zamanda sฤฑkฤฑลŸtฤฑrฤฑldฤฑ; bu deneme atlanฤฑyor", "condense_handler_invalid": "BaฤŸlamฤฑ sฤฑkฤฑลŸtฤฑrmak iรงin API iลŸleyicisi geรงersiz", "condense_context_grew": "SฤฑkฤฑลŸtฤฑrma sฤฑrasฤฑnda baฤŸlam boyutu arttฤฑ; bu deneme atlanฤฑyor", + "url_timeout": "Web sitesi yรผklenmesi รงok uzun sรผrdรผ (zaman aลŸฤฑmฤฑ). Bu yavaลŸ baฤŸlantฤฑ, aฤŸฤฑr web sitesi veya geรงici olarak kullanฤฑlamama nedeniyle olabilir. Daha sonra tekrar deneyebilir veya URL'nin doฤŸru olup olmadฤฑฤŸฤฑnฤฑ kontrol edebilirsin.", + "url_not_found": "Web sitesi adresi bulunamadฤฑ. URL'nin doฤŸru olup olmadฤฑฤŸฤฑnฤฑ kontrol et ve tekrar dene.", + "no_internet": "ฤฐnternet baฤŸlantฤฑsฤฑ yok. AฤŸ baฤŸlantฤฑnฤฑ kontrol et ve tekrar dene.", + "url_forbidden": "Bu web sitesine eriลŸim yasak. Site otomatik eriลŸimi engelliyor veya kimlik doฤŸrulama gerektiriyor olabilir.", + "url_page_not_found": "Sayfa bulunamadฤฑ. URL'nin doฤŸru olup olmadฤฑฤŸฤฑnฤฑ kontrol et.", + "url_fetch_failed": "URL iรงeriฤŸi getirme hatasฤฑ: {{error}}", + "url_fetch_error_with_url": "{{url}} iรงin iรงerik getirme hatasฤฑ: {{error}}", "share_task_failed": "Gรถrev paylaลŸฤฑlamadฤฑ", "share_no_active_task": "PaylaลŸฤฑlacak aktif gรถrev yok", "share_auth_required": "Kimlik doฤŸrulama gerekli. Gรถrevleri paylaลŸmak iรงin lรผtfen giriลŸ yapฤฑn.", diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json index 5a9d0983f8..0e0df3ae6c 100644 --- a/src/i18n/locales/vi/common.json +++ b/src/i18n/locales/vi/common.json @@ -58,6 +58,13 @@ "condensed_recently": "Ngแปฏ cแบฃnh ฤ‘รฃ ฤ‘ฦฐแปฃc nรฉn gแบงn ฤ‘รขy; bแป qua lแบงn thแปญ nร y", "condense_handler_invalid": "Trรฌnh xแปญ lรฝ API ฤ‘แปƒ nรฉn ngแปฏ cแบฃnh khรดng hแปฃp lแป‡", "condense_context_grew": "Kรญch thฦฐแป›c ngแปฏ cแบฃnh tฤƒng lรชn trong quรก trรฌnh nรฉn; bแป qua lแบงn thแปญ nร y", + "url_timeout": "Trang web mแบฅt quรก nhiแปu thแปi gian ฤ‘แปƒ tแบฃi (timeout). ฤiแปu nร y cรณ thแปƒ do kแบฟt nแป‘i chแบญm, trang web nแบทng hoแบทc tแบกm thแปi khรดng khแบฃ dแปฅng. Bแบกn cรณ thแปƒ thแปญ lแบกi sau hoแบทc kiแปƒm tra xem URL cรณ ฤ‘รบng khรดng.", + "url_not_found": "Khรดng thแปƒ tรฌm thแบฅy ฤ‘แป‹a chแป‰ trang web. Vui lรฒng kiแปƒm tra URL cรณ ฤ‘รบng khรดng vร  thแปญ lแบกi.", + "no_internet": "Khรดng cรณ kแบฟt nแป‘i internet. Vui lรฒng kiแปƒm tra kแบฟt nแป‘i mแบกng vร  thแปญ lแบกi.", + "url_forbidden": "Truy cแบญp vร o trang web nร y bแป‹ cแบฅm. Trang cรณ thแปƒ chแบทn truy cแบญp tแปฑ ฤ‘แป™ng hoแบทc yรชu cแบงu xรกc thแปฑc.", + "url_page_not_found": "Khรดng tรฌm thแบฅy trang. Vui lรฒng kiแปƒm tra URL cรณ ฤ‘รบng khรดng.", + "url_fetch_failed": "Lแป—i lแบฅy nแป™i dung URL: {{error}}", + "url_fetch_error_with_url": "Lแป—i lแบฅy nแป™i dung cho {{url}}: {{error}}", "share_task_failed": "Khรดng thแปƒ chia sแบป nhiแป‡m vแปฅ", "share_no_active_task": "Khรดng cรณ nhiแป‡m vแปฅ hoแบกt ฤ‘แป™ng ฤ‘แปƒ chia sแบป", "share_auth_required": "Cแบงn xรกc thแปฑc. Vui lรฒng ฤ‘ฤƒng nhแบญp ฤ‘แปƒ chia sแบป nhiแป‡m vแปฅ.", diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json index b355c2ec35..191fb65521 100644 --- a/src/i18n/locales/zh-CN/common.json +++ b/src/i18n/locales/zh-CN/common.json @@ -63,6 +63,13 @@ "condensed_recently": "ไธŠไธ‹ๆ–‡ๆœ€่ฟ‘ๅทฒๅŽ‹็ผฉ๏ผ›่ทณ่ฟ‡ๆญคๆฌกๅฐ่ฏ•", "condense_handler_invalid": "ๅŽ‹็ผฉไธŠไธ‹ๆ–‡็š„APIๅค„็†็จ‹ๅบๆ— ๆ•ˆ", "condense_context_grew": "ๅŽ‹็ผฉ่ฟ‡็จ‹ไธญไธŠไธ‹ๆ–‡ๅคงๅฐๅขžๅŠ ๏ผ›่ทณ่ฟ‡ๆญคๆฌกๅฐ่ฏ•", + "url_timeout": "็ฝ‘็ซ™ๅŠ ่ฝฝ่ถ…ๆ—ถใ€‚่ฟ™ๅฏ่ƒฝๆ˜ฏ็”ฑไบŽ็ฝ‘็ปœ่ฟžๆŽฅ็ผ“ๆ…ขใ€็ฝ‘็ซ™่ดŸ่ฝฝ่ฟ‡้‡ๆˆ–ๆš‚ๆ—ถไธๅฏ็”จใ€‚ไฝ ๅฏไปฅ็จๅŽ้‡่ฏ•ๆˆ–ๆฃ€ๆŸฅ URL ๆ˜ฏๅฆๆญฃ็กฎใ€‚", + "url_not_found": "ๆ‰พไธๅˆฐ็ฝ‘็ซ™ๅœฐๅ€ใ€‚่ฏทๆฃ€ๆŸฅ URL ๆ˜ฏๅฆๆญฃ็กฎๅนถ้‡่ฏ•ใ€‚", + "no_internet": "ๆ— ็ฝ‘็ปœ่ฟžๆŽฅใ€‚่ฏทๆฃ€ๆŸฅ็ฝ‘็ปœ่ฟžๆŽฅๅนถ้‡่ฏ•ใ€‚", + "url_forbidden": "่ฎฟ้—ฎๆญค็ฝ‘็ซ™่ขซ็ฆๆญขใ€‚่ฏฅ็ฝ‘็ซ™ๅฏ่ƒฝ้˜ปๆญข่‡ชๅŠจ่ฎฟ้—ฎๆˆ–้œ€่ฆ่บซไปฝ้ชŒ่ฏใ€‚", + "url_page_not_found": "้กต้ขๆœชๆ‰พๅˆฐใ€‚่ฏทๆฃ€ๆŸฅ URL ๆ˜ฏๅฆๆญฃ็กฎใ€‚", + "url_fetch_failed": "่Žทๅ– URL ๅ†…ๅฎนๅคฑ่ดฅ๏ผš{{error}}", + "url_fetch_error_with_url": "่Žทๅ– {{url}} ๅ†…ๅฎนๆ—ถๅ‡บ้”™๏ผš{{error}}", "share_task_failed": "ๅˆ†ไบซไปปๅŠกๅคฑ่ดฅใ€‚่ฏท้‡่ฏ•ใ€‚", "share_no_active_task": "ๆฒกๆœ‰ๆดป่ทƒไปปๅŠกๅฏๅˆ†ไบซ", "share_auth_required": "้œ€่ฆ่บซไปฝ้ชŒ่ฏใ€‚่ฏท็™ปๅฝ•ไปฅๅˆ†ไบซไปปๅŠกใ€‚", diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json index 6c1c9747aa..3e6d9f23ba 100644 --- a/src/i18n/locales/zh-TW/common.json +++ b/src/i18n/locales/zh-TW/common.json @@ -58,6 +58,13 @@ "condensed_recently": "ไธŠไธ‹ๆ–‡ๆœ€่ฟ‘ๅทฒๅฃ“็ธฎ๏ผ›่ทณ้Žๆญคๆฌกๅ˜—่ฉฆ", "condense_handler_invalid": "ๅฃ“็ธฎไธŠไธ‹ๆ–‡็š„ API ่™•็†็จ‹ๅผ็„กๆ•ˆ", "condense_context_grew": "ๅฃ“็ธฎ้Ž็จ‹ไธญไธŠไธ‹ๆ–‡ๅคงๅฐๅขžๅŠ ๏ผ›่ทณ้Žๆญคๆฌกๅ˜—่ฉฆ", + "url_timeout": "็ถฒ็ซ™่ผ‰ๅ…ฅ่ถ…ๆ™‚ใ€‚้€™ๅฏ่ƒฝๆ˜ฏ็”ฑๆ–ผ็ถฒ่ทฏ้€ฃ็ทš็ทฉๆ…ขใ€็ถฒ็ซ™่ฒ ่ผ‰้Ž้‡ๆˆ–ๆšซๆ™‚็„กๆณ•ไฝฟ็”จใ€‚ไฝ ๅฏไปฅ็จๅพŒ้‡่ฉฆๆˆ–ๆชขๆŸฅ URL ๆ˜ฏๅฆๆญฃ็ขบใ€‚", + "url_not_found": "ๆ‰พไธๅˆฐ็ถฒ็ซ™ไฝๅ€ใ€‚่ซ‹ๆชขๆŸฅ URL ๆ˜ฏๅฆๆญฃ็ขบไธฆ้‡่ฉฆใ€‚", + "no_internet": "็„ก็ถฒ่ทฏ้€ฃ็ทšใ€‚่ซ‹ๆชขๆŸฅ็ถฒ่ทฏ้€ฃ็ทšไธฆ้‡่ฉฆใ€‚", + "url_forbidden": "ๅญ˜ๅ–ๆญค็ถฒ็ซ™่ขซ็ฆๆญขใ€‚่ฉฒ็ถฒ็ซ™ๅฏ่ƒฝๅฐ้Ž–่‡ชๅ‹•ๅญ˜ๅ–ๆˆ–้œ€่ฆ่บซๅˆ†้ฉ—่ญ‰ใ€‚", + "url_page_not_found": "ๆ‰พไธๅˆฐ้ ้ขใ€‚่ซ‹ๆชขๆŸฅ URL ๆ˜ฏๅฆๆญฃ็ขบใ€‚", + "url_fetch_failed": "ๅ–ๅพ— URL ๅ…งๅฎนๅคฑๆ•—๏ผš{{error}}", + "url_fetch_error_with_url": "ๅ–ๅพ— {{url}} ๅ…งๅฎนๆ™‚็™ผ็”Ÿ้Œฏ่ชค๏ผš{{error}}", "share_task_failed": "ๅˆ†ไบซๅทฅไฝœๅคฑๆ•—ใ€‚่ซ‹้‡่ฉฆใ€‚", "share_no_active_task": "ๆฒ’ๆœ‰ๆดป่บ็š„ๅทฅไฝœๅฏๅˆ†ไบซ", "share_auth_required": "้œ€่ฆ่บซไปฝ้ฉ—่ญ‰ใ€‚่ซ‹็™ปๅ…ฅไปฅๅˆ†ไบซๅทฅไฝœใ€‚", diff --git a/src/services/browser/BrowserSession.ts b/src/services/browser/BrowserSession.ts index 7704caba0c..75b432f01d 100644 --- a/src/services/browser/BrowserSession.ts +++ b/src/services/browser/BrowserSession.ts @@ -10,6 +10,9 @@ import { fileExistsAtPath } from "../../utils/fs" import { BrowserActionResult } from "../../shared/ExtensionMessage" import { discoverChromeHostUrl, tryChromeHostUrl } from "./browserDiscovery" +// Timeout constants +const BROWSER_NAVIGATION_TIMEOUT = 15_000 // 15 seconds + interface PCRStats { puppeteer: { launch: typeof launch } executablePath: string @@ -320,7 +323,7 @@ export class BrowserSession { * Navigate to a URL with standard loading options */ private async navigatePageToUrl(page: Page, url: string): Promise { - await page.goto(url, { timeout: 7_000, waitUntil: ["domcontentloaded", "networkidle2"] }) + await page.goto(url, { timeout: BROWSER_NAVIGATION_TIMEOUT, waitUntil: ["domcontentloaded", "networkidle2"] }) await this.waitTillHTMLStable(page) } @@ -403,7 +406,10 @@ export class BrowserSession { console.log(`Root domain: ${this.getRootDomain(currentUrl)}`) console.log(`New URL: ${normalizedNewUrl}`) return this.doAction(async (page) => { - await page.reload({ timeout: 7_000, waitUntil: ["domcontentloaded", "networkidle2"] }) + await page.reload({ + timeout: BROWSER_NAVIGATION_TIMEOUT, + waitUntil: ["domcontentloaded", "networkidle2"], + }) await this.waitTillHTMLStable(page) }) } @@ -476,7 +482,7 @@ export class BrowserSession { await page .waitForNavigation({ waitUntil: ["domcontentloaded", "networkidle2"], - timeout: 7000, + timeout: BROWSER_NAVIGATION_TIMEOUT, }) .catch(() => {}) await this.waitTillHTMLStable(page) diff --git a/src/services/browser/UrlContentFetcher.ts b/src/services/browser/UrlContentFetcher.ts index caf19ee83b..8f4de7fbb4 100644 --- a/src/services/browser/UrlContentFetcher.ts +++ b/src/services/browser/UrlContentFetcher.ts @@ -7,6 +7,11 @@ import TurndownService from "turndown" // @ts-ignore import PCR from "puppeteer-chromium-resolver" import { fileExistsAtPath } from "../../utils/fs" +import { serializeError } from "serialize-error" + +// Timeout constants +const URL_FETCH_TIMEOUT = 30_000 // 30 seconds +const URL_FETCH_FALLBACK_TIMEOUT = 20_000 // 20 seconds for fallback interface PCRStats { puppeteer: { launch: typeof launch } @@ -48,11 +53,24 @@ export class UrlContentFetcher { this.browser = await stats.puppeteer.launch({ args: [ "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", + "--disable-dev-shm-usage", + "--disable-accelerated-2d-canvas", + "--no-first-run", + "--disable-gpu", + "--disable-features=VizDisplayCompositor", ], executablePath: stats.executablePath, }) // (latest version of puppeteer does not add headless to user agent) this.page = await this.browser?.newPage() + + // Set additional page configurations to improve loading success + if (this.page) { + await this.page.setViewport({ width: 1280, height: 720 }) + await this.page.setExtraHTTPHeaders({ + "Accept-Language": "en-US,en;q=0.9", + }) + } } async closeBrowser(): Promise { @@ -71,7 +89,40 @@ export class UrlContentFetcher { - domcontentloaded is when the basic DOM is loaded this should be sufficient for most doc sites */ - await this.page.goto(url, { timeout: 10_000, waitUntil: ["domcontentloaded", "networkidle2"] }) + try { + await this.page.goto(url, { + timeout: URL_FETCH_TIMEOUT, + waitUntil: ["domcontentloaded", "networkidle2"], + }) + } catch (error) { + // Use serialize-error to safely extract error information + const serializedError = serializeError(error) + const errorMessage = serializedError.message || String(error) + const errorName = serializedError.name + + // Only retry for timeout or network-related errors + const shouldRetry = + errorMessage.includes("timeout") || + errorMessage.includes("net::") || + errorMessage.includes("NetworkError") || + errorMessage.includes("ERR_") || + errorName === "TimeoutError" + + if (shouldRetry) { + // If networkidle2 fails due to timeout/network issues, try with just domcontentloaded as fallback + console.warn( + `Failed to load ${url} with networkidle2, retrying with domcontentloaded only: ${errorMessage}`, + ) + await this.page.goto(url, { + timeout: URL_FETCH_FALLBACK_TIMEOUT, + waitUntil: ["domcontentloaded"], + }) + } else { + // For other errors, throw them as-is + throw error + } + } + const content = await this.page.content() // use cheerio to parse and clean up the HTML diff --git a/src/services/browser/__tests__/UrlContentFetcher.spec.ts b/src/services/browser/__tests__/UrlContentFetcher.spec.ts new file mode 100644 index 0000000000..917b27c5f2 --- /dev/null +++ b/src/services/browser/__tests__/UrlContentFetcher.spec.ts @@ -0,0 +1,290 @@ +// npx vitest services/browser/__tests__/UrlContentFetcher.spec.ts + +import { describe, it, expect, vi, beforeEach, afterEach } from "vitest" +import { UrlContentFetcher } from "../UrlContentFetcher" +import { fileExistsAtPath } from "../../../utils/fs" +import * as path from "path" + +// Mock dependencies +vi.mock("vscode", () => ({ + ExtensionContext: vi.fn(), + Uri: { + file: vi.fn((path) => ({ fsPath: path })), + }, +})) + +// Mock fs/promises +vi.mock("fs/promises", () => ({ + default: { + mkdir: vi.fn().mockResolvedValue(undefined), + }, + mkdir: vi.fn().mockResolvedValue(undefined), +})) + +// Mock utils/fs +vi.mock("../../../utils/fs", () => ({ + fileExistsAtPath: vi.fn().mockResolvedValue(true), +})) + +// Mock cheerio +vi.mock("cheerio", () => ({ + load: vi.fn(() => { + const $ = vi.fn((selector) => ({ + remove: vi.fn().mockReturnThis(), + })) as any + $.html = vi.fn().mockReturnValue("Test content") + return $ + }), +})) + +// Mock turndown +vi.mock("turndown", () => { + return { + default: class MockTurndownService { + turndown = vi.fn().mockReturnValue("# Test content") + }, + } +}) + +// Mock puppeteer-chromium-resolver +vi.mock("puppeteer-chromium-resolver", () => ({ + default: vi.fn().mockResolvedValue({ + puppeteer: { + launch: vi.fn().mockResolvedValue({ + newPage: vi.fn().mockResolvedValue({ + goto: vi.fn(), + content: vi.fn().mockResolvedValue("Test content"), + setViewport: vi.fn().mockResolvedValue(undefined), + setExtraHTTPHeaders: vi.fn().mockResolvedValue(undefined), + }), + close: vi.fn().mockResolvedValue(undefined), + }), + }, + executablePath: "/path/to/chromium", + }), +})) + +// Mock serialize-error +vi.mock("serialize-error", () => ({ + serializeError: vi.fn((error) => { + if (error instanceof Error) { + return { message: error.message, name: error.name } + } else if (typeof error === "string") { + return { message: error } + } else if (error && typeof error === "object" && "message" in error) { + return { message: String(error.message), name: "name" in error ? String(error.name) : undefined } + } else { + return { message: String(error) } + } + }), +})) + +describe("UrlContentFetcher", () => { + let urlContentFetcher: UrlContentFetcher + let mockContext: any + let mockPage: any + let mockBrowser: any + let PCR: any + + beforeEach(async () => { + vi.clearAllMocks() + + mockContext = { + globalStorageUri: { + fsPath: "/test/storage", + }, + } + + mockPage = { + goto: vi.fn(), + content: vi.fn().mockResolvedValue("Test content"), + setViewport: vi.fn().mockResolvedValue(undefined), + setExtraHTTPHeaders: vi.fn().mockResolvedValue(undefined), + } + + mockBrowser = { + newPage: vi.fn().mockResolvedValue(mockPage), + close: vi.fn().mockResolvedValue(undefined), + } + + // Reset PCR mock + // @ts-ignore + PCR = (await import("puppeteer-chromium-resolver")).default + vi.mocked(PCR).mockResolvedValue({ + puppeteer: { + launch: vi.fn().mockResolvedValue(mockBrowser), + }, + executablePath: "/path/to/chromium", + }) + + urlContentFetcher = new UrlContentFetcher(mockContext) + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + describe("launchBrowser", () => { + it("should launch browser with correct arguments", async () => { + await urlContentFetcher.launchBrowser() + + expect(vi.mocked(PCR)).toHaveBeenCalledWith({ + downloadPath: path.join("/test/storage", "puppeteer"), + }) + + const stats = await vi.mocked(PCR).mock.results[0].value + expect(stats.puppeteer.launch).toHaveBeenCalledWith({ + args: [ + "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", + "--disable-dev-shm-usage", + "--disable-accelerated-2d-canvas", + "--no-first-run", + "--disable-gpu", + "--disable-features=VizDisplayCompositor", + ], + executablePath: "/path/to/chromium", + }) + }) + + it("should set viewport and headers after launching", async () => { + await urlContentFetcher.launchBrowser() + + expect(mockPage.setViewport).toHaveBeenCalledWith({ width: 1280, height: 720 }) + expect(mockPage.setExtraHTTPHeaders).toHaveBeenCalledWith({ + "Accept-Language": "en-US,en;q=0.9", + }) + }) + + it("should not launch browser if already launched", async () => { + await urlContentFetcher.launchBrowser() + const initialCallCount = vi.mocked(PCR).mock.calls.length + + await urlContentFetcher.launchBrowser() + expect(vi.mocked(PCR)).toHaveBeenCalledTimes(initialCallCount) + }) + }) + + describe("urlToMarkdown", () => { + beforeEach(async () => { + await urlContentFetcher.launchBrowser() + }) + + it("should successfully fetch and convert URL to markdown", async () => { + mockPage.goto.mockResolvedValueOnce(undefined) + + const result = await urlContentFetcher.urlToMarkdown("https://example.com") + + expect(mockPage.goto).toHaveBeenCalledWith("https://example.com", { + timeout: 30000, + waitUntil: ["domcontentloaded", "networkidle2"], + }) + expect(result).toBe("# Test content") + }) + + it("should retry with domcontentloaded only when networkidle2 fails", async () => { + const timeoutError = new Error("Navigation timeout of 30000 ms exceeded") + mockPage.goto.mockRejectedValueOnce(timeoutError).mockResolvedValueOnce(undefined) + + const result = await urlContentFetcher.urlToMarkdown("https://example.com") + + expect(mockPage.goto).toHaveBeenCalledTimes(2) + expect(mockPage.goto).toHaveBeenNthCalledWith(1, "https://example.com", { + timeout: 30000, + waitUntil: ["domcontentloaded", "networkidle2"], + }) + expect(mockPage.goto).toHaveBeenNthCalledWith(2, "https://example.com", { + timeout: 20000, + waitUntil: ["domcontentloaded"], + }) + expect(result).toBe("# Test content") + }) + + it("should retry for network errors", async () => { + const networkError = new Error("net::ERR_CONNECTION_REFUSED") + mockPage.goto.mockRejectedValueOnce(networkError).mockResolvedValueOnce(undefined) + + const result = await urlContentFetcher.urlToMarkdown("https://example.com") + + expect(mockPage.goto).toHaveBeenCalledTimes(2) + expect(result).toBe("# Test content") + }) + + it("should retry for TimeoutError", async () => { + const timeoutError = new Error("TimeoutError: Navigation timeout") + timeoutError.name = "TimeoutError" + mockPage.goto.mockRejectedValueOnce(timeoutError).mockResolvedValueOnce(undefined) + + const result = await urlContentFetcher.urlToMarkdown("https://example.com") + + expect(mockPage.goto).toHaveBeenCalledTimes(2) + expect(result).toBe("# Test content") + }) + + it("should not retry for non-network/timeout errors", async () => { + const otherError = new Error("Some other error") + mockPage.goto.mockRejectedValueOnce(otherError) + + await expect(urlContentFetcher.urlToMarkdown("https://example.com")).rejects.toThrow("Some other error") + expect(mockPage.goto).toHaveBeenCalledTimes(1) + }) + + it("should throw error if browser not initialized", async () => { + const newFetcher = new UrlContentFetcher(mockContext) + + await expect(newFetcher.urlToMarkdown("https://example.com")).rejects.toThrow("Browser not initialized") + }) + + it("should handle errors without message property", async () => { + const errorWithoutMessage = { code: "UNKNOWN_ERROR" } + mockPage.goto.mockRejectedValueOnce(errorWithoutMessage) + + // serialize-error will convert this to a proper error with the object stringified + await expect(urlContentFetcher.urlToMarkdown("https://example.com")).rejects.toThrow() + + // Should not retry for non-network errors + expect(mockPage.goto).toHaveBeenCalledTimes(1) + }) + + it("should handle error objects with message property", async () => { + const errorWithMessage = { message: "Custom error", code: "CUSTOM_ERROR" } + mockPage.goto.mockRejectedValueOnce(errorWithMessage) + + await expect(urlContentFetcher.urlToMarkdown("https://example.com")).rejects.toThrow("Custom error") + + // Should not retry for error objects with message property (they're treated as known errors) + expect(mockPage.goto).toHaveBeenCalledTimes(1) + }) + + it("should retry for error objects with network-related messages", async () => { + const errorWithNetworkMessage = { message: "net::ERR_CONNECTION_REFUSED", code: "NETWORK_ERROR" } + mockPage.goto.mockRejectedValueOnce(errorWithNetworkMessage).mockResolvedValueOnce(undefined) + + const result = await urlContentFetcher.urlToMarkdown("https://example.com") + + // Should retry for network-related errors even in non-Error objects + expect(mockPage.goto).toHaveBeenCalledTimes(2) + expect(result).toBe("# Test content") + }) + + it("should handle string errors", async () => { + const stringError = "Simple string error" + mockPage.goto.mockRejectedValueOnce(stringError) + + await expect(urlContentFetcher.urlToMarkdown("https://example.com")).rejects.toThrow("Simple string error") + expect(mockPage.goto).toHaveBeenCalledTimes(1) + }) + }) + + describe("closeBrowser", () => { + it("should close browser and reset state", async () => { + await urlContentFetcher.launchBrowser() + await urlContentFetcher.closeBrowser() + + expect(mockBrowser.close).toHaveBeenCalled() + }) + + it("should handle closing when browser not initialized", async () => { + await expect(urlContentFetcher.closeBrowser()).resolves.not.toThrow() + }) + }) +}) From 562a00743858502f37d6452afd1c64191e01c2db Mon Sep 17 00:00:00 2001 From: takakoutso Date: Mon, 30 Jun 2025 10:45:51 -0400 Subject: [PATCH 34/70] feat: Add automatic configuration import on extension startup (#4848) Co-authored-by: Roo Code Co-authored-by: Daniel Riccio --- src/core/config/importExport.ts | 90 +++++++++++-------- src/extension.ts | 14 +++ src/i18n/locales/ca/common.json | 4 +- src/i18n/locales/de/common.json | 4 +- src/i18n/locales/en/common.json | 4 +- src/i18n/locales/es/common.json | 4 +- src/i18n/locales/fr/common.json | 4 +- src/i18n/locales/hi/common.json | 4 +- src/i18n/locales/id/common.json | 4 +- src/i18n/locales/it/common.json | 4 +- src/i18n/locales/ja/common.json | 4 +- src/i18n/locales/ko/common.json | 4 +- src/i18n/locales/nl/common.json | 4 +- src/i18n/locales/pl/common.json | 4 +- src/i18n/locales/pt-BR/common.json | 4 +- src/i18n/locales/ru/common.json | 4 +- src/i18n/locales/tr/common.json | 4 +- src/i18n/locales/vi/common.json | 4 +- src/i18n/locales/zh-CN/common.json | 4 +- src/i18n/locales/zh-TW/common.json | 4 +- src/package.json | 5 ++ src/package.nls.ca.json | 3 +- src/package.nls.de.json | 3 +- src/package.nls.es.json | 3 +- src/package.nls.fr.json | 3 +- src/package.nls.hi.json | 3 +- src/package.nls.id.json | 3 +- src/package.nls.it.json | 3 +- src/package.nls.ja.json | 3 +- src/package.nls.json | 3 +- src/package.nls.ko.json | 3 +- src/package.nls.nl.json | 3 +- src/package.nls.pl.json | 3 +- src/package.nls.pt-BR.json | 3 +- src/package.nls.ru.json | 3 +- src/package.nls.tr.json | 3 +- src/package.nls.vi.json | 3 +- src/package.nls.zh-CN.json | 3 +- src/package.nls.zh-TW.json | 3 +- .../__tests__/autoImportSettings.spec.ts | 7 +- src/utils/autoImportSettings.ts | 25 ++---- 41 files changed, 173 insertions(+), 94 deletions(-) diff --git a/src/core/config/importExport.ts b/src/core/config/importExport.ts index 65638ab95e..6ffbbf7136 100644 --- a/src/core/config/importExport.ts +++ b/src/core/config/importExport.ts @@ -14,7 +14,7 @@ import { ContextProxy } from "./ContextProxy" import { CustomModesManager } from "./CustomModesManager" import { t } from "../../i18n" -type ImportOptions = { +export type ImportOptions = { providerSettingsManager: ProviderSettingsManager contextProxy: ContextProxy customModesManager: CustomModesManager @@ -24,7 +24,6 @@ type ExportOptions = { providerSettingsManager: ProviderSettingsManager contextProxy: ContextProxy } - type ImportWithProviderOptions = ImportOptions & { provider: { settingsImportedAt?: number @@ -33,33 +32,14 @@ type ImportWithProviderOptions = ImportOptions & { } /** - * Import settings from a file using a file dialog - * @param options - Import options containing managers and proxy - * @returns Promise resolving to import result + * Imports configuration from a specific file path + * Shares base functionality for import settings for both the manual + * and automatic settings importing */ -export const importSettings = async ({ providerSettingsManager, contextProxy, customModesManager }: ImportOptions) => { - const uris = await vscode.window.showOpenDialog({ - filters: { JSON: ["json"] }, - canSelectMany: false, - }) - - if (!uris) { - return { success: false, error: "User cancelled file selection" } - } - - return await importSettingsFromFile({ providerSettingsManager, contextProxy, customModesManager }, uris[0]) -} - -/** - * Import settings from a specific file - * @param options - Import options containing managers and proxy - * @param fileUri - URI of the file to import from - * @returns Promise resolving to import result - */ -export const importSettingsFromFile = async ( +export async function importSettingsFromPath( + filePath: string, { providerSettingsManager, contextProxy, customModesManager }: ImportOptions, - fileUri: vscode.Uri, -) => { +) { const schema = z.object({ providerProfiles: providerProfilesSchema, globalSettings: globalSettingsSchema.optional(), @@ -68,8 +48,9 @@ export const importSettingsFromFile = async ( try { const previousProviderProfiles = await providerSettingsManager.export() - const data = JSON.parse(await fs.readFile(fileUri.fsPath, "utf-8")) - const { providerProfiles: newProviderProfiles, globalSettings = {} } = schema.parse(data) + const { providerProfiles: newProviderProfiles, globalSettings = {} } = schema.parse( + JSON.parse(await fs.readFile(filePath, "utf-8")), + ) const providerProfiles = { currentApiConfigName: newProviderProfiles.currentApiConfigName, @@ -119,6 +100,45 @@ export const importSettingsFromFile = async ( } } +/** + * Import settings from a file using a file dialog + * @param options - Import options containing managers and proxy + * @returns Promise resolving to import result + */ +export const importSettings = async ({ providerSettingsManager, contextProxy, customModesManager }: ImportOptions) => { + const uris = await vscode.window.showOpenDialog({ + filters: { JSON: ["json"] }, + canSelectMany: false, + }) + + if (!uris) { + return { success: false, error: "User cancelled file selection" } + } + + return importSettingsFromPath(uris[0].fsPath, { + providerSettingsManager, + contextProxy, + customModesManager, + }) +} + +/** + * Import settings from a specific file + * @param options - Import options containing managers and proxy + * @param fileUri - URI of the file to import from + * @returns Promise resolving to import result + */ +export const importSettingsFromFile = async ( + { providerSettingsManager, contextProxy, customModesManager }: ImportOptions, + fileUri: vscode.Uri, +) => { + return importSettingsFromPath(fileUri.fsPath, { + providerSettingsManager, + contextProxy, + customModesManager, + }) +} + export const exportSettings = async ({ providerSettingsManager, contextProxy }: ExportOptions) => { const uri = await vscode.window.showSaveDialog({ filters: { JSON: ["json"] }, @@ -162,13 +182,13 @@ export const importSettingsWithFeedback = async ( if (filePath) { // Validate file path and check if file exists try { - const fileUri = vscode.Uri.file(filePath) // Check if file exists and is readable - await fs.access(fileUri.fsPath, fs.constants.F_OK | fs.constants.R_OK) - result = await importSettingsFromFile( - { providerSettingsManager, contextProxy, customModesManager }, - fileUri, - ) + await fs.access(filePath, fs.constants.F_OK | fs.constants.R_OK) + result = await importSettingsFromPath(filePath, { + providerSettingsManager, + contextProxy, + customModesManager, + }) } catch (error) { result = { success: false, diff --git a/src/extension.ts b/src/extension.ts index 9e3daad662..bd43bcbf8a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -28,6 +28,7 @@ import { McpServerManager } from "./services/mcp/McpServerManager" import { CodeIndexManager } from "./services/code-index/manager" import { MdmService } from "./services/mdm/MdmService" import { migrateSettings } from "./utils/migrateSettings" +import { autoImportSettings } from "./utils/autoImportSettings" import { API } from "./extension/api" import { @@ -120,6 +121,19 @@ export async function activate(context: vscode.ExtensionContext) { }), ) + // Auto-import configuration if specified in settings + try { + await autoImportSettings(outputChannel, { + providerSettingsManager: provider.providerSettingsManager, + contextProxy: provider.contextProxy, + customModesManager: provider.customModesManager, + }) + } catch (error) { + outputChannel.appendLine( + `[AutoImport] Error during auto-import: ${error instanceof Error ? error.message : String(error)}`, + ) + } + registerCommands({ context, outputChannel, provider }) /** diff --git a/src/i18n/locales/ca/common.json b/src/i18n/locales/ca/common.json index 0c465dcfd3..3ff61fca0a 100644 --- a/src/i18n/locales/ca/common.json +++ b/src/i18n/locales/ca/common.json @@ -84,7 +84,8 @@ }, "warnings": { "no_terminal_content": "No s'ha seleccionat contingut de terminal", - "missing_task_files": "Els fitxers d'aquesta tasca falten. Vols eliminar-la de la llista de tasques?" + "missing_task_files": "Els fitxers d'aquesta tasca falten. Vols eliminar-la de la llista de tasques?", + "auto_import_failed": "Ha fallat la importaciรณ automร tica de la configuraciรณ de RooCode: {{error}}" }, "info": { "no_changes": "No s'han trobat canvis.", @@ -93,6 +94,7 @@ "custom_storage_path_set": "Ruta d'emmagatzematge personalitzada establerta: {{path}}", "default_storage_path": "S'ha reprรจs l'รบs de la ruta d'emmagatzematge predeterminada", "settings_imported": "Configuraciรณ importada correctament.", + "auto_import_success": "Configuraciรณ de RooCode importada automร ticament des de {{filename}}", "share_link_copied": "Enllaรง de comparticiรณ copiat al portapapers", "image_copied_to_clipboard": "URI de dades de la imatge copiada al portapapers", "image_saved": "Imatge desada a {{path}}", diff --git a/src/i18n/locales/de/common.json b/src/i18n/locales/de/common.json index 148e51200a..cd16ba2b59 100644 --- a/src/i18n/locales/de/common.json +++ b/src/i18n/locales/de/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "Kein Terminal-Inhalt ausgewรคhlt", - "missing_task_files": "Die Dateien dieser Aufgabe fehlen. Mรถchtest du sie aus der Aufgabenliste entfernen?" + "missing_task_files": "Die Dateien dieser Aufgabe fehlen. Mรถchtest du sie aus der Aufgabenliste entfernen?", + "auto_import_failed": "Fehler beim automatischen Import der RooCode-Einstellungen: {{error}}" }, "info": { "no_changes": "Keine ร„nderungen gefunden.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "Benutzerdefinierter Speicherpfad festgelegt: {{path}}", "default_storage_path": "Auf Standardspeicherpfad zurรผckgesetzt", "settings_imported": "Einstellungen erfolgreich importiert.", + "auto_import_success": "RooCode-Einstellungen automatisch importiert aus {{filename}}", "share_link_copied": "Share-Link in die Zwischenablage kopiert", "image_copied_to_clipboard": "Bild-Daten-URI in die Zwischenablage kopiert", "image_saved": "Bild gespeichert unter {{path}}", diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index b1b3de42b6..386986316b 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "No terminal content selected", - "missing_task_files": "This task's files are missing. Would you like to remove it from the task list?" + "missing_task_files": "This task's files are missing. Would you like to remove it from the task list?", + "auto_import_failed": "Failed to auto-import RooCode settings: {{error}}" }, "info": { "no_changes": "No changes found.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "Custom storage path set: {{path}}", "default_storage_path": "Reverted to using default storage path", "settings_imported": "Settings imported successfully.", + "auto_import_success": "RooCode settings automatically imported from {{filename}}", "share_link_copied": "Share link copied to clipboard", "organization_share_link_copied": "Organization share link copied to clipboard!", "public_share_link_copied": "Public share link copied to clipboard!", diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json index 0916a64a88..20ffda84dd 100644 --- a/src/i18n/locales/es/common.json +++ b/src/i18n/locales/es/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "No hay contenido de terminal seleccionado", - "missing_task_files": "Los archivos de esta tarea faltan. ยฟDeseas eliminarla de la lista de tareas?" + "missing_task_files": "Los archivos de esta tarea faltan. ยฟDeseas eliminarla de la lista de tareas?", + "auto_import_failed": "Error al importar automรกticamente la configuraciรณn de RooCode: {{error}}" }, "info": { "no_changes": "No se encontraron cambios.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "Ruta de almacenamiento personalizada establecida: {{path}}", "default_storage_path": "Se ha vuelto a usar la ruta de almacenamiento predeterminada", "settings_imported": "Configuraciรณn importada correctamente.", + "auto_import_success": "Configuraciรณn de RooCode importada automรกticamente desde {{filename}}", "share_link_copied": "Enlace de compartir copiado al portapapeles", "image_copied_to_clipboard": "URI de datos de imagen copiada al portapapeles", "image_saved": "Imagen guardada en {{path}}", diff --git a/src/i18n/locales/fr/common.json b/src/i18n/locales/fr/common.json index 40809077ab..3c7c9b0a67 100644 --- a/src/i18n/locales/fr/common.json +++ b/src/i18n/locales/fr/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "Aucun contenu de terminal sรฉlectionnรฉ", - "missing_task_files": "Les fichiers de cette tรขche sont introuvables. Souhaitez-vous la supprimer de la liste des tรขches ?" + "missing_task_files": "Les fichiers de cette tรขche sont introuvables. Souhaitez-vous la supprimer de la liste des tรขches ?", + "auto_import_failed": "ร‰chec de l'importation automatique des paramรจtres RooCode : {{error}}" }, "info": { "no_changes": "Aucun changement trouvรฉ.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "Chemin de stockage personnalisรฉ dรฉfini : {{path}}", "default_storage_path": "Retour au chemin de stockage par dรฉfaut", "settings_imported": "Paramรจtres importรฉs avec succรจs.", + "auto_import_success": "Paramรจtres RooCode importรฉs automatiquement depuis {{filename}}", "share_link_copied": "Lien de partage copiรฉ dans le presse-papiers", "image_copied_to_clipboard": "URI de donnรฉes d'image copiรฉe dans le presse-papiers", "image_saved": "Image enregistrรฉe dans {{path}}", diff --git a/src/i18n/locales/hi/common.json b/src/i18n/locales/hi/common.json index 4b6c473d96..16698d4ddd 100644 --- a/src/i18n/locales/hi/common.json +++ b/src/i18n/locales/hi/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "เค•เฅ‹เคˆ เคŸเคฐเฅเคฎเคฟเคจเคฒ เคธเคพเคฎเค—เฅเคฐเฅ€ เคšเคฏเคจเคฟเคค เคจเคนเฅ€เค‚", - "missing_task_files": "เค‡เคธ เคŸเคพเคธเฅเค• เค•เฅ€ เคซเคพเค‡เคฒเฅ‡เค‚ เค—เคพเคฏเคฌ เคนเฅˆเค‚เฅค เค•เฅเคฏเคพ เค†เคช เค‡เคธเฅ‡ เคŸเคพเคธเฅเค• เคธเฅ‚เคšเฅ€ เคธเฅ‡ เคนเคŸเคพเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚?" + "missing_task_files": "เค‡เคธ เคŸเคพเคธเฅเค• เค•เฅ€ เคซเคพเค‡เคฒเฅ‡เค‚ เค—เคพเคฏเคฌ เคนเฅˆเค‚เฅค เค•เฅเคฏเคพ เค†เคช เค‡เคธเฅ‡ เคŸเคพเคธเฅเค• เคธเฅ‚เคšเฅ€ เคธเฅ‡ เคนเคŸเคพเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚?", + "auto_import_failed": "RooCode เคธเฅ‡เคŸเคฟเค‚เค—เฅเคธ เค•เคพ เคธเฅเคตเคšเคพเคฒเคฟเคค เค†เคฏเคพเคค เคตเคฟเคซเคฒ: {{error}}" }, "info": { "no_changes": "เค•เฅ‹เคˆ เคชเคฐเคฟเคตเคฐเฅเคคเคจ เคจเคนเฅ€เค‚ เคฎเคฟเคฒเคพเฅค", @@ -89,6 +90,7 @@ "custom_storage_path_set": "เค•เคธเฅเคŸเคฎ เคธเฅเคŸเฅ‹เคฐเฅ‡เคœ เคชเคพเคฅ เคธเฅ‡เคŸ เค•เคฟเคฏเคพ เค—เคฏเคพ: {{path}}", "default_storage_path": "เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ เคธเฅเคŸเฅ‹เคฐเฅ‡เคœ เคชเคพเคฅ เค•เคพ เค‰เคชเคฏเฅ‹เค— เคชเฅเคจเคƒ เคถเฅเคฐเฅ‚ เค•เคฟเคฏเคพ เค—เคฏเคพ", "settings_imported": "เคธเฅ‡เคŸเคฟเค‚เค—เฅเคธ เคธเคซเคฒเคคเคพเคชเฅ‚เคฐเฅเคตเค• เค‡เคฎเฅเคชเฅ‹เคฐเฅเคŸ เค•เฅ€ เค—เคˆเค‚เฅค", + "auto_import_success": "RooCode เคธเฅ‡เคŸเคฟเค‚เค—เฅเคธ {{filename}} เคธเฅ‡ เคธเฅเคตเคšเคพเคฒเคฟเคค เคฐเฅ‚เคช เคธเฅ‡ เค†เคฏเคพเคค เค•เฅ€ เค—เคˆเค‚", "share_link_copied": "เคธเคพเคเคพ เคฒเคฟเค‚เค• เค•เฅเคฒเคฟเคชเคฌเฅ‹เคฐเฅเคก เคชเคฐ เค•เฅ‰เคชเฅ€ เค•เคฟเคฏเคพ เค—เคฏเคพ", "image_copied_to_clipboard": "เค›เคตเคฟ เคกเฅ‡เคŸเคพ URI เค•เฅเคฒเคฟเคชเคฌเฅ‹เคฐเฅเคก เคฎเฅ‡เค‚ เค•เฅ‰เคชเฅ€ เค•เฅ€ เค—เคˆ", "image_saved": "เค›เคตเคฟ {{path}} เคฎเฅ‡เค‚ เคธเคนเฅ‡เคœเฅ€ เค—เคˆ", diff --git a/src/i18n/locales/id/common.json b/src/i18n/locales/id/common.json index 7bc320f268..f1512095bc 100644 --- a/src/i18n/locales/id/common.json +++ b/src/i18n/locales/id/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "Tidak ada konten terminal yang dipilih", - "missing_task_files": "File tugas ini hilang. Apakah kamu ingin menghapusnya dari daftar tugas?" + "missing_task_files": "File tugas ini hilang. Apakah kamu ingin menghapusnya dari daftar tugas?", + "auto_import_failed": "Gagal mengimpor pengaturan RooCode secara otomatis: {{error}}" }, "info": { "no_changes": "Tidak ada perubahan ditemukan.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "Path penyimpanan kustom diatur: {{path}}", "default_storage_path": "Kembali menggunakan path penyimpanan default", "settings_imported": "Pengaturan berhasil diimpor.", + "auto_import_success": "Pengaturan RooCode berhasil diimpor secara otomatis dari {{filename}}", "share_link_copied": "Link bagikan disalin ke clipboard", "image_copied_to_clipboard": "Data URI gambar disalin ke clipboard", "image_saved": "Gambar disimpan ke {{path}}", diff --git a/src/i18n/locales/it/common.json b/src/i18n/locales/it/common.json index 2b0969a40d..96408088c3 100644 --- a/src/i18n/locales/it/common.json +++ b/src/i18n/locales/it/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "Nessun contenuto del terminale selezionato", - "missing_task_files": "I file di questa attivitร  sono mancanti. Vuoi rimuoverla dall'elenco delle attivitร ?" + "missing_task_files": "I file di questa attivitร  sono mancanti. Vuoi rimuoverla dall'elenco delle attivitร ?", + "auto_import_failed": "Importazione automatica delle impostazioni RooCode fallita: {{error}}" }, "info": { "no_changes": "Nessuna modifica trovata.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "Percorso di archiviazione personalizzato impostato: {{path}}", "default_storage_path": "Tornato al percorso di archiviazione predefinito", "settings_imported": "Impostazioni importate con successo.", + "auto_import_success": "Impostazioni RooCode importate automaticamente da {{filename}}", "share_link_copied": "Link di condivisione copiato negli appunti", "image_copied_to_clipboard": "URI dati dell'immagine copiato negli appunti", "image_saved": "Immagine salvata in {{path}}", diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index 3466c82e73..bdd7f5bbc8 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "้ธๆŠžใ•ใ‚ŒใŸใ‚ฟใƒผใƒŸใƒŠใƒซใ‚ณใƒณใƒ†ใƒณใƒ„ใŒใ‚ใ‚Šใพใ›ใ‚“", - "missing_task_files": "ใ“ใฎใ‚ฟใ‚นใ‚ฏใฎใƒ•ใ‚กใ‚คใƒซใŒ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“ใ€‚ใ‚ฟใ‚นใ‚ฏใƒชใ‚นใƒˆใ‹ใ‚‰ๅ‰Š้™คใ—ใพใ™ใ‹๏ผŸ" + "missing_task_files": "ใ“ใฎใ‚ฟใ‚นใ‚ฏใฎใƒ•ใ‚กใ‚คใƒซใŒ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“ใ€‚ใ‚ฟใ‚นใ‚ฏใƒชใ‚นใƒˆใ‹ใ‚‰ๅ‰Š้™คใ—ใพใ™ใ‹๏ผŸ", + "auto_import_failed": "RooCode่จญๅฎšใฎ่‡ชๅ‹•ใ‚คใƒณใƒใƒผใƒˆใซๅคฑๆ•—ใ—ใพใ—ใŸ๏ผš{{error}}" }, "info": { "no_changes": "ๅค‰ๆ›ดใฏ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“ใงใ—ใŸใ€‚", @@ -89,6 +90,7 @@ "custom_storage_path_set": "ใ‚ซใ‚นใ‚ฟใƒ ใ‚นใƒˆใƒฌใƒผใ‚ธใƒ‘ใ‚นใŒ่จญๅฎšใ•ใ‚Œใพใ—ใŸ๏ผš{{path}}", "default_storage_path": "ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎใ‚นใƒˆใƒฌใƒผใ‚ธใƒ‘ใ‚นใซๆˆปใ‚Šใพใ—ใŸ", "settings_imported": "่จญๅฎšใŒๆญฃๅธธใซใ‚คใƒณใƒใƒผใƒˆใ•ใ‚Œใพใ—ใŸใ€‚", + "auto_import_success": "RooCode่จญๅฎšใŒ{{filename}}ใ‹ใ‚‰่‡ชๅ‹•ใ‚คใƒณใƒใƒผใƒˆใ•ใ‚Œใพใ—ใŸ", "share_link_copied": "ๅ…ฑๆœ‰ใƒชใƒณใ‚ฏใŒใ‚ฏใƒชใƒƒใƒ—ใƒœใƒผใƒ‰ใซใ‚ณใƒ”ใƒผใ•ใ‚Œใพใ—ใŸ", "image_copied_to_clipboard": "็”ปๅƒใƒ‡ใƒผใ‚ฟURIใŒใ‚ฏใƒชใƒƒใƒ—ใƒœใƒผใƒ‰ใซใ‚ณใƒ”ใƒผใ•ใ‚Œใพใ—ใŸ", "image_saved": "็”ปๅƒใ‚’{{path}}ใซไฟๅญ˜ใ—ใพใ—ใŸ", diff --git a/src/i18n/locales/ko/common.json b/src/i18n/locales/ko/common.json index 3fc50cb95b..205c49b6c3 100644 --- a/src/i18n/locales/ko/common.json +++ b/src/i18n/locales/ko/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "์„ ํƒ๋œ ํ„ฐ๋ฏธ๋„ ๋‚ด์šฉ์ด ์—†์Šต๋‹ˆ๋‹ค", - "missing_task_files": "์ด ์ž‘์—…์˜ ํŒŒ์ผ์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ž‘์—… ๋ชฉ๋ก์—์„œ ์ œ๊ฑฐํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?" + "missing_task_files": "์ด ์ž‘์—…์˜ ํŒŒ์ผ์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ž‘์—… ๋ชฉ๋ก์—์„œ ์ œ๊ฑฐํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", + "auto_import_failed": "RooCode ์„ค์ • ์ž๋™ ๊ฐ€์ ธ์˜ค๊ธฐ ์‹คํŒจ: {{error}}" }, "info": { "no_changes": "๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์—†์Šต๋‹ˆ๋‹ค.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "์‚ฌ์šฉ์ž ์ง€์ • ์ €์žฅ ๊ฒฝ๋กœ ์„ค์ •๋จ: {{path}}", "default_storage_path": "๊ธฐ๋ณธ ์ €์žฅ ๊ฒฝ๋กœ๋กœ ๋˜๋Œ์•„๊ฐ”์Šต๋‹ˆ๋‹ค", "settings_imported": "์„ค์ •์ด ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™€์กŒ์Šต๋‹ˆ๋‹ค.", + "auto_import_success": "{{filename}}์—์„œ RooCode ์„ค์ •์„ ์ž๋™์œผ๋กœ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค", "share_link_copied": "๊ณต์œ  ๋งํฌ๊ฐ€ ํด๋ฆฝ๋ณด๋“œ์— ๋ณต์‚ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค", "image_copied_to_clipboard": "์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ URI๊ฐ€ ํด๋ฆฝ๋ณด๋“œ์— ๋ณต์‚ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค", "image_saved": "์ด๋ฏธ์ง€๊ฐ€ {{path}}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค", diff --git a/src/i18n/locales/nl/common.json b/src/i18n/locales/nl/common.json index 22f7b50b8f..8f2be38bd5 100644 --- a/src/i18n/locales/nl/common.json +++ b/src/i18n/locales/nl/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "Geen terminalinhoud geselecteerd", - "missing_task_files": "De bestanden van deze taak ontbreken. Wil je deze uit de takenlijst verwijderen?" + "missing_task_files": "De bestanden van deze taak ontbreken. Wil je deze uit de takenlijst verwijderen?", + "auto_import_failed": "Automatisch importeren van RooCode-instellingen mislukt: {{error}}" }, "info": { "no_changes": "Geen wijzigingen gevonden.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "Aangepast opslagpad ingesteld: {{path}}", "default_storage_path": "Terug naar standaard opslagpad", "settings_imported": "Instellingen succesvol geรฏmporteerd.", + "auto_import_success": "RooCode-instellingen automatisch geรฏmporteerd van {{filename}}", "share_link_copied": "Deellink gekopieerd naar klembord", "image_copied_to_clipboard": "Afbeelding data-URI gekopieerd naar klembord", "image_saved": "Afbeelding opgeslagen naar {{path}}", diff --git a/src/i18n/locales/pl/common.json b/src/i18n/locales/pl/common.json index d6a2248eed..be7f6e8ee7 100644 --- a/src/i18n/locales/pl/common.json +++ b/src/i18n/locales/pl/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "Nie wybrano zawartoล›ci terminala", - "missing_task_files": "Pliki tego zadania sฤ… brakujฤ…ce. Czy chcesz usunฤ…ฤ‡ je z listy zadaล„?" + "missing_task_files": "Pliki tego zadania sฤ… brakujฤ…ce. Czy chcesz usunฤ…ฤ‡ je z listy zadaล„?", + "auto_import_failed": "Nie udaล‚o siฤ™ automatycznie zaimportowaฤ‡ ustawieล„ RooCode: {{error}}" }, "info": { "no_changes": "Nie znaleziono zmian.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "Ustawiono niestandardowฤ… ล›cieลผkฤ™ przechowywania: {{path}}", "default_storage_path": "Wznowiono uลผywanie domyล›lnej ล›cieลผki przechowywania", "settings_imported": "Ustawienia zaimportowane pomyล›lnie.", + "auto_import_success": "Ustawienia RooCode zostaล‚y automatycznie zaimportowane z {{filename}}", "share_link_copied": "Link udostฤ™pniania skopiowany do schowka", "image_copied_to_clipboard": "URI danych obrazu skopiowane do schowka", "image_saved": "Obraz zapisany w {{path}}", diff --git a/src/i18n/locales/pt-BR/common.json b/src/i18n/locales/pt-BR/common.json index 9283f04e78..d98b90325a 100644 --- a/src/i18n/locales/pt-BR/common.json +++ b/src/i18n/locales/pt-BR/common.json @@ -84,7 +84,8 @@ }, "warnings": { "no_terminal_content": "Nenhum conteรบdo do terminal selecionado", - "missing_task_files": "Os arquivos desta tarefa estรฃo faltando. Deseja removรช-la da lista de tarefas?" + "missing_task_files": "Os arquivos desta tarefa estรฃo faltando. Deseja removรช-la da lista de tarefas?", + "auto_import_failed": "Falha ao importar automaticamente as configuraรงรตes do RooCode: {{error}}" }, "info": { "no_changes": "Nenhuma alteraรงรฃo encontrada.", @@ -93,6 +94,7 @@ "custom_storage_path_set": "Caminho de armazenamento personalizado definido: {{path}}", "default_storage_path": "Retornado ao caminho de armazenamento padrรฃo", "settings_imported": "Configuraรงรตes importadas com sucesso.", + "auto_import_success": "Configuraรงรตes do RooCode importadas automaticamente de {{filename}}", "share_link_copied": "Link de compartilhamento copiado para a รกrea de transferรชncia", "image_copied_to_clipboard": "URI de dados da imagem copiada para a รกrea de transferรชncia", "image_saved": "Imagem salva em {{path}}", diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json index e25f4c3040..037957f046 100644 --- a/src/i18n/locales/ru/common.json +++ b/src/i18n/locales/ru/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "ะะต ะฒั‹ะฑั€ะฐะฝะพ ัะพะดะตั€ะถะธะผะพะต ั‚ะตั€ะผะธะฝะฐะปะฐ", - "missing_task_files": "ะคะฐะนะปั‹ ัั‚ะพะน ะทะฐะดะฐั‡ะธ ะพั‚ััƒั‚ัั‚ะฒัƒัŽั‚. ะฅะพั‚ะธั‚ะต ัƒะดะฐะปะธั‚ัŒ ะตั‘ ะธะท ัะฟะธัะบะฐ ะทะฐะดะฐั‡?" + "missing_task_files": "ะคะฐะนะปั‹ ัั‚ะพะน ะทะฐะดะฐั‡ะธ ะพั‚ััƒั‚ัั‚ะฒัƒัŽั‚. ะฅะพั‚ะธั‚ะต ัƒะดะฐะปะธั‚ัŒ ะตั‘ ะธะท ัะฟะธัะบะฐ ะทะฐะดะฐั‡?", + "auto_import_failed": "ะะต ัƒะดะฐะปะพััŒ ะฐะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธ ะธะผะฟะพั€ั‚ะธั€ะพะฒะฐั‚ัŒ ะฝะฐัั‚ั€ะพะนะบะธ RooCode: {{error}}" }, "info": { "no_changes": "ะ˜ะทะผะตะฝะตะฝะธั ะฝะต ะฝะฐะนะดะตะฝั‹.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "ะฃัั‚ะฐะฝะพะฒะปะตะฝ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบะธะน ะฟัƒั‚ัŒ ั…ั€ะฐะฝะตะฝะธั: {{path}}", "default_storage_path": "ะ’ะพะทะฒั€ะฐั‰ะตะฝะพ ะธัะฟะพะปัŒะทะพะฒะฐะฝะธะต ะฟัƒั‚ะธ ั…ั€ะฐะฝะตะฝะธั ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ", "settings_imported": "ะะฐัั‚ั€ะพะนะบะธ ัƒัะฟะตัˆะฝะพ ะธะผะฟะพั€ั‚ะธั€ะพะฒะฐะฝั‹.", + "auto_import_success": "ะะฐัั‚ั€ะพะนะบะธ RooCode ะฐะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธ ะธะผะฟะพั€ั‚ะธั€ะพะฒะฐะฝั‹ ะธะท {{filename}}", "share_link_copied": "ะกัั‹ะปะบะฐ ะดะปั ัะพะฒะผะตัั‚ะฝะพะณะพ ะธัะฟะพะปัŒะทะพะฒะฐะฝะธั ัะบะพะฟะธั€ะพะฒะฐะฝะฐ ะฒ ะฑัƒั„ะตั€ ะพะฑะผะตะฝะฐ", "image_copied_to_clipboard": "URI ะดะฐะฝะฝั‹ั… ะธะทะพะฑั€ะฐะถะตะฝะธั ัะบะพะฟะธั€ะพะฒะฐะฝ ะฒ ะฑัƒั„ะตั€ ะพะฑะผะตะฝะฐ", "image_saved": "ะ˜ะทะพะฑั€ะฐะถะตะฝะธะต ัะพั…ั€ะฐะฝะตะฝะพ ะฒ {{path}}", diff --git a/src/i18n/locales/tr/common.json b/src/i18n/locales/tr/common.json index 6f31478aec..b77b8a4e1c 100644 --- a/src/i18n/locales/tr/common.json +++ b/src/i18n/locales/tr/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "Seรงili terminal iรงeriฤŸi yok", - "missing_task_files": "Bu gรถrevin dosyalarฤฑ eksik. Gรถrev listesinden kaldฤฑrmak istiyor musunuz?" + "missing_task_files": "Bu gรถrevin dosyalarฤฑ eksik. Gรถrev listesinden kaldฤฑrmak istiyor musunuz?", + "auto_import_failed": "RooCode ayarlarฤฑ otomatik olarak iรงe aktarฤฑlamadฤฑ: {{error}}" }, "info": { "no_changes": "DeฤŸiลŸiklik bulunamadฤฑ.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "ร–zel depolama yolu ayarlandฤฑ: {{path}}", "default_storage_path": "Varsayฤฑlan depolama yoluna geri dรถnรผldรผ", "settings_imported": "Ayarlar baลŸarฤฑyla iรงe aktarฤฑldฤฑ.", + "auto_import_success": "RooCode ayarlarฤฑ {{filename}} dosyasฤฑndan otomatik olarak iรงe aktarฤฑldฤฑ", "share_link_copied": "PaylaลŸฤฑm baฤŸlantฤฑsฤฑ panoya kopyalandฤฑ", "image_copied_to_clipboard": "Resim veri URI'si panoya kopyalandฤฑ", "image_saved": "Resim {{path}} konumuna kaydedildi", diff --git a/src/i18n/locales/vi/common.json b/src/i18n/locales/vi/common.json index 0e0df3ae6c..321a7d71e4 100644 --- a/src/i18n/locales/vi/common.json +++ b/src/i18n/locales/vi/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "Khรดng cรณ nแป™i dung terminal ฤ‘ฦฐแปฃc chแปn", - "missing_task_files": "Cรกc tแป‡p cแปงa nhiแป‡m vแปฅ nร y bแป‹ thiแบฟu. Bแบกn cรณ muแป‘n xรณa nรณ khแปi danh sรกch nhiแป‡m vแปฅ khรดng?" + "missing_task_files": "Cรกc tแป‡p cแปงa nhiแป‡m vแปฅ nร y bแป‹ thiแบฟu. Bแบกn cรณ muแป‘n xรณa nรณ khแปi danh sรกch nhiแป‡m vแปฅ khรดng?", + "auto_import_failed": "Khรดng thแปƒ tแปฑ ฤ‘แป™ng nhแบญp cร i ฤ‘แบทt RooCode: {{error}}" }, "info": { "no_changes": "Khรดng tรฌm thแบฅy thay ฤ‘แป•i nร o.", @@ -89,6 +90,7 @@ "custom_storage_path_set": "ฤรฃ thiแบฟt lแบญp ฤ‘ฦฐแปng dแบซn lฦฐu trแปฏ tรนy chแป‰nh: {{path}}", "default_storage_path": "ฤรฃ quay lแบกi sแปญ dแปฅng ฤ‘ฦฐแปng dแบซn lฦฐu trแปฏ mแบทc ฤ‘แป‹nh", "settings_imported": "Cร i ฤ‘แบทt ฤ‘รฃ ฤ‘ฦฐแปฃc nhแบญp thร nh cรดng.", + "auto_import_success": "Cร i ฤ‘แบทt RooCode ฤ‘รฃ ฤ‘ฦฐแปฃc tแปฑ ฤ‘แป™ng nhแบญp tแปซ {{filename}}", "share_link_copied": "Liรชn kแบฟt chia sแบป ฤ‘รฃ ฤ‘ฦฐแปฃc sao chรฉp vร o clipboard", "image_copied_to_clipboard": "URI dแปฏ liแป‡u hรฌnh แบฃnh ฤ‘รฃ ฤ‘ฦฐแปฃc sao chรฉp vร o clipboard", "image_saved": "Hรฌnh แบฃnh ฤ‘รฃ ฤ‘ฦฐแปฃc lฦฐu vร o {{path}}", diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json index 191fb65521..e716bc26a1 100644 --- a/src/i18n/locales/zh-CN/common.json +++ b/src/i18n/locales/zh-CN/common.json @@ -85,7 +85,8 @@ }, "warnings": { "no_terminal_content": "ๆฒกๆœ‰้€‰ๆ‹ฉ็ปˆ็ซฏๅ†…ๅฎน", - "missing_task_files": "ๆญคไปปๅŠก็š„ๆ–‡ไปถไธขๅคฑใ€‚ๆ‚จๆƒณไปŽไปปๅŠกๅˆ—่กจไธญๅˆ ้™คๅฎƒๅ—๏ผŸ" + "missing_task_files": "ๆญคไปปๅŠก็š„ๆ–‡ไปถไธขๅคฑใ€‚ๆ‚จๆƒณไปŽไปปๅŠกๅˆ—่กจไธญๅˆ ้™คๅฎƒๅ—๏ผŸ", + "auto_import_failed": "่‡ชๅŠจๅฏผๅ…ฅ RooCode ่ฎพ็ฝฎๅคฑ่ดฅ๏ผš{{error}}" }, "info": { "no_changes": "ๆœชๆ‰พๅˆฐๆ›ดๆ”นใ€‚", @@ -94,6 +95,7 @@ "custom_storage_path_set": "่‡ชๅฎšไน‰ๅญ˜ๅ‚จ่ทฏๅพ„ๅทฒ่ฎพ็ฝฎ๏ผš{{path}}", "default_storage_path": "ๅทฒๆขๅคไฝฟ็”จ้ป˜่ฎคๅญ˜ๅ‚จ่ทฏๅพ„", "settings_imported": "่ฎพ็ฝฎๅทฒๆˆๅŠŸๅฏผๅ…ฅใ€‚", + "auto_import_success": "ๅทฒ่‡ชๅŠจๅฏผๅ…ฅ RooCode ่ฎพ็ฝฎ๏ผš{{filename}}", "share_link_copied": "ๅˆ†ไบซ้“พๆŽฅๅทฒๅคๅˆถๅˆฐๅ‰ช่ดดๆฟ", "image_copied_to_clipboard": "ๅ›พ็‰‡ๆ•ฐๆฎ URI ๅทฒๅคๅˆถๅˆฐๅ‰ช่ดดๆฟ", "image_saved": "ๅ›พ็‰‡ๅทฒไฟๅญ˜ๅˆฐ {{path}}", diff --git a/src/i18n/locales/zh-TW/common.json b/src/i18n/locales/zh-TW/common.json index 3e6d9f23ba..6ecece8835 100644 --- a/src/i18n/locales/zh-TW/common.json +++ b/src/i18n/locales/zh-TW/common.json @@ -80,7 +80,8 @@ }, "warnings": { "no_terminal_content": "ๆฒ’ๆœ‰้ธๆ“‡็ต‚็ซฏๆฉŸๅ…งๅฎน", - "missing_task_files": "ๆญคๅทฅไฝœ็š„ๆช”ๆกˆ้บๅคฑใ€‚ๆ‚จๆƒณๅพžๅทฅไฝœๅˆ—่กจไธญๅˆช้™คๅฎƒๅ—Ž๏ผŸ" + "missing_task_files": "ๆญคๅทฅไฝœ็š„ๆช”ๆกˆ้บๅคฑใ€‚ๆ‚จๆƒณๅพžๅทฅไฝœๅˆ—่กจไธญๅˆช้™คๅฎƒๅ—Ž๏ผŸ", + "auto_import_failed": "่‡ชๅ‹•ๅŒฏๅ…ฅ RooCode ่จญๅฎšๅคฑๆ•—๏ผš{{error}}" }, "info": { "no_changes": "ๆฒ’ๆœ‰ๆ‰พๅˆฐๆ›ดๆ”นใ€‚", @@ -89,6 +90,7 @@ "custom_storage_path_set": "่‡ช่จ‚ๅ„ฒๅญ˜่ทฏๅพ‘ๅทฒ่จญๅฎš๏ผš{{path}}", "default_storage_path": "ๅทฒๆขๅพฉไฝฟ็”จ้ ่จญๅ„ฒๅญ˜่ทฏๅพ‘", "settings_imported": "่จญๅฎšๅทฒๆˆๅŠŸๅŒฏๅ…ฅใ€‚", + "auto_import_success": "ๅทฒ่‡ชๅ‹•ๅŒฏๅ…ฅ RooCode ่จญๅฎš๏ผš{{filename}}", "share_link_copied": "ๅˆ†ไบซ้€ฃ็ตๅทฒ่ค‡่ฃฝๅˆฐๅ‰ช่ฒผ็ฐฟ", "image_copied_to_clipboard": "ๅœ–็‰‡่ณ‡ๆ–™ URI ๅทฒ่ค‡่ฃฝๅˆฐๅ‰ช่ฒผ็ฐฟ", "image_saved": "ๅœ–็‰‡ๅทฒๅ„ฒๅญ˜่‡ณ {{path}}", diff --git a/src/package.json b/src/package.json index 4a91b44eb3..4232bf2be7 100644 --- a/src/package.json +++ b/src/package.json @@ -333,6 +333,11 @@ "type": "boolean", "default": true, "description": "%settings.enableCodeActions.description%" + }, + "roo-cline.autoImportSettingsPath": { + "type": "string", + "default": "", + "description": "%settings.autoImportSettingsPath.description%" } } } diff --git a/src/package.nls.ca.json b/src/package.nls.ca.json index f20f269e20..978caf3df3 100644 --- a/src/package.nls.ca.json +++ b/src/package.nls.ca.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "El proveรฏdor del model de llenguatge (p. ex. copilot)", "settings.vsCodeLmModelSelector.family.description": "La famรญlia del model de llenguatge (p. ex. gpt-4)", "settings.customStoragePath.description": "Ruta d'emmagatzematge personalitzada. Deixeu-la buida per utilitzar la ubicaciรณ predeterminada. Admet rutes absolutes (p. ex. 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Habilitar correccions rร pides de Roo Code." + "settings.enableCodeActions.description": "Habilitar correccions rร pides de Roo Code.", + "settings.autoImportSettingsPath.description": "Ruta a un fitxer de configuraciรณ de RooCode per importar automร ticament en iniciar l'extensiรณ. Admet rutes absolutes i rutes relatives al directori d'inici (per exemple, '~/Documents/roo-code-settings.json'). Deixeu-ho en blanc per desactivar la importaciรณ automร tica." } diff --git a/src/package.nls.de.json b/src/package.nls.de.json index 781b310668..32b38f7dee 100644 --- a/src/package.nls.de.json +++ b/src/package.nls.de.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "Der Anbieter des Sprachmodells (z.B. copilot)", "settings.vsCodeLmModelSelector.family.description": "Die Familie des Sprachmodells (z.B. gpt-4)", "settings.customStoragePath.description": "Benutzerdefinierter Speicherpfad. Leer lassen, um den Standardspeicherort zu verwenden. Unterstรผtzt absolute Pfade (z.B. 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Roo Code Schnelle Problembehebung aktivieren." + "settings.enableCodeActions.description": "Roo Code Schnelle Problembehebung aktivieren.", + "settings.autoImportSettingsPath.description": "Pfad zu einer RooCode-Konfigurationsdatei, die beim Start der Erweiterung automatisch importiert wird. Unterstรผtzt absolute Pfade und Pfade relativ zum Home-Verzeichnis (z.B. '~/Documents/roo-code-settings.json'). Leer lassen, um den automatischen Import zu deaktivieren." } diff --git a/src/package.nls.es.json b/src/package.nls.es.json index 4938f5ea64..dc76f15e94 100644 --- a/src/package.nls.es.json +++ b/src/package.nls.es.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "El proveedor del modelo de lenguaje (ej. copilot)", "settings.vsCodeLmModelSelector.family.description": "La familia del modelo de lenguaje (ej. gpt-4)", "settings.customStoragePath.description": "Ruta de almacenamiento personalizada. Dejar vacรญo para usar la ubicaciรณn predeterminada. Admite rutas absolutas (ej. 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Habilitar correcciones rรกpidas de Roo Code." + "settings.enableCodeActions.description": "Habilitar correcciones rรกpidas de Roo Code.", + "settings.autoImportSettingsPath.description": "Ruta a un archivo de configuraciรณn de RooCode para importar automรกticamente al iniciar la extensiรณn. Admite rutas absolutas y rutas relativas al directorio de inicio (por ejemplo, '~/Documents/roo-code-settings.json'). Dejar vacรญo para desactivar la importaciรณn automรกtica." } diff --git a/src/package.nls.fr.json b/src/package.nls.fr.json index ada2502e4f..621cab976e 100644 --- a/src/package.nls.fr.json +++ b/src/package.nls.fr.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "Le fournisseur du modรจle de langage (ex: copilot)", "settings.vsCodeLmModelSelector.family.description": "La famille du modรจle de langage (ex: gpt-4)", "settings.customStoragePath.description": "Chemin de stockage personnalisรฉ. Laisser vide pour utiliser l'emplacement par dรฉfaut. Prend en charge les chemins absolus (ex: 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Activer les correctifs rapides de Roo Code." + "settings.enableCodeActions.description": "Activer les correctifs rapides de Roo Code.", + "settings.autoImportSettingsPath.description": "Chemin d'accรจs ร  un fichier de configuration RooCode ร  importer automatiquement au dรฉmarrage de l'extension. Prend en charge les chemins absolus et les chemins relatifs au rรฉpertoire de base (par exemple, '~/Documents/roo-code-settings.json'). Laisser vide pour dรฉsactiver l'importation automatique." } diff --git a/src/package.nls.hi.json b/src/package.nls.hi.json index f06e21cf06..d54f1d829e 100644 --- a/src/package.nls.hi.json +++ b/src/package.nls.hi.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "เคญเคพเคทเคพ เคฎเฅ‰เคกเคฒ เค•เคพ เคตเคฟเค•เฅเคฐเฅ‡เคคเคพ (เค‰เคฆเคพ. copilot)", "settings.vsCodeLmModelSelector.family.description": "เคญเคพเคทเคพ เคฎเฅ‰เคกเคฒ เค•เคพ เคชเคฐเคฟเคตเคพเคฐ (เค‰เคฆเคพ. gpt-4)", "settings.customStoragePath.description": "เค•เคธเฅเคŸเคฎ เคธเฅเคŸเฅ‹เคฐเฅ‡เคœ เคชเคพเคฅเฅค เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ เคธเฅเคฅเคพเคจ เค•เคพ เค‰เคชเคฏเฅ‹เค— เค•เคฐเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค–เคพเคฒเฅ€ เค›เฅ‹เคกเคผเฅ‡เค‚เฅค เคชเฅ‚เคฐเฅเคฃ เคชเคฅ เค•เคพ เคธเคฎเคฐเฅเคฅเคจ เค•เคฐเคคเคพ เคนเฅˆ (เค‰เคฆเคพ. 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Roo Code เคคเฅเคตเคฐเคฟเคค เคธเฅเคงเคพเคฐ เคธเค•เฅเคทเคฎ เค•เคฐเฅ‡เค‚" + "settings.enableCodeActions.description": "Roo Code เคคเฅเคตเคฐเคฟเคค เคธเฅเคงเคพเคฐ เคธเค•เฅเคทเคฎ เค•เคฐเฅ‡เค‚", + "settings.autoImportSettingsPath.description": "RooCode เค•เฅ‰เคจเฅเคซเคผเคฟเค—เคฐเฅ‡เคถเคจ เคซเคผเคพเค‡เคฒ เค•เคพ เคชเคฅ เคœเคฟเคธเฅ‡ เคเค•เฅเคธเคŸเฅ‡เค‚เคถเคจ เคธเฅเคŸเคพเคฐเฅเคŸเค…เคช เคชเคฐ เคธเฅเคตเคšเคพเคฒเคฟเคค เคฐเฅ‚เคช เคธเฅ‡ เค†เคฏเคพเคค เค•เคฟเคฏเคพ เคœเคพเคเค—เคพเฅค เคนเฅ‹เคฎ เคกเคพเคฏเคฐเฅ‡เค•เฅเคŸเคฐเฅ€ เค•เฅ‡ เคธเคพเคชเฅ‡เค•เฅเคท เคชเฅ‚เคฐเฅเคฃ เคชเคฅ เค”เคฐ เคชเคฅเฅ‹เค‚ เค•เคพ เคธเคฎเคฐเฅเคฅเคจ เค•เคฐเคคเคพ เคนเฅˆ (เค‰เคฆเคพเคนเคฐเคฃ เค•เฅ‡ เคฒเคฟเค '~/Documents/roo-code-settings.json')เฅค เค‘เคŸเฅ‹-เค‡เค‚เคชเฅ‹เคฐเฅเคŸ เค•เฅ‹ เค…เค•เฅเคทเคฎ เค•เคฐเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค–เคพเคฒเฅ€ เค›เฅ‹เคกเคผ เคฆเฅ‡เค‚เฅค" } diff --git a/src/package.nls.id.json b/src/package.nls.id.json index c7461aab6b..99313d151e 100644 --- a/src/package.nls.id.json +++ b/src/package.nls.id.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "Vendor dari model bahasa (misalnya copilot)", "settings.vsCodeLmModelSelector.family.description": "Keluarga dari model bahasa (misalnya gpt-4)", "settings.customStoragePath.description": "Path penyimpanan kustom. Biarkan kosong untuk menggunakan lokasi default. Mendukung path absolut (misalnya 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Aktifkan perbaikan cepat Roo Code." + "settings.enableCodeActions.description": "Aktifkan perbaikan cepat Roo Code.", + "settings.autoImportSettingsPath.description": "Path ke file konfigurasi RooCode untuk diimpor secara otomatis saat ekstensi dimulai. Mendukung path absolut dan path relatif terhadap direktori home (misalnya '~/Documents/roo-code-settings.json'). Biarkan kosong untuk menonaktifkan impor otomatis." } diff --git a/src/package.nls.it.json b/src/package.nls.it.json index cc63935e60..0fca90870c 100644 --- a/src/package.nls.it.json +++ b/src/package.nls.it.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "Il fornitore del modello linguistico (es. copilot)", "settings.vsCodeLmModelSelector.family.description": "La famiglia del modello linguistico (es. gpt-4)", "settings.customStoragePath.description": "Percorso di archiviazione personalizzato. Lasciare vuoto per utilizzare la posizione predefinita. Supporta percorsi assoluti (es. 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Abilita correzioni rapide di Roo Code." + "settings.enableCodeActions.description": "Abilita correzioni rapide di Roo Code.", + "settings.autoImportSettingsPath.description": "Percorso di un file di configurazione di RooCode da importare automaticamente all'avvio dell'estensione. Supporta percorsi assoluti e percorsi relativi alla directory home (ad es. '~/Documents/roo-code-settings.json'). Lasciare vuoto per disabilitare l'importazione automatica." } diff --git a/src/package.nls.ja.json b/src/package.nls.ja.json index 7e601d3c78..5fd4ade628 100644 --- a/src/package.nls.ja.json +++ b/src/package.nls.ja.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "่จ€่ชžใƒขใƒ‡ใƒซใฎใƒ™ใƒณใƒ€ใƒผ๏ผˆไพ‹๏ผšcopilot๏ผ‰", "settings.vsCodeLmModelSelector.family.description": "่จ€่ชžใƒขใƒ‡ใƒซใฎใƒ•ใ‚กใƒŸใƒชใƒผ๏ผˆไพ‹๏ผšgpt-4๏ผ‰", "settings.customStoragePath.description": "ใ‚ซใ‚นใ‚ฟใƒ ใ‚นใƒˆใƒฌใƒผใ‚ธใƒ‘ใ‚นใ€‚ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใฎๅ ดๆ‰€ใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆใฏ็ฉบใฎใพใพใซใ—ใพใ™ใ€‚็ตถๅฏพใƒ‘ใ‚นใ‚’ใ‚ตใƒใƒผใƒˆใ—ใพใ™๏ผˆไพ‹๏ผš'D:\\RooCodeStorage'๏ผ‰", - "settings.enableCodeActions.description": "Roo Codeใฎใ‚ฏใ‚คใƒƒใ‚ฏไฟฎๆญฃใ‚’ๆœ‰ๅŠนใซใ™ใ‚‹ใ€‚" + "settings.enableCodeActions.description": "Roo Codeใฎใ‚ฏใ‚คใƒƒใ‚ฏไฟฎๆญฃใ‚’ๆœ‰ๅŠนใซใ™ใ‚‹ใ€‚", + "settings.autoImportSettingsPath.description": "ๆ‹กๅผตๆฉŸ่ƒฝใฎ่ตทๅ‹•ๆ™‚ใซ่‡ชๅ‹•็š„ใซใ‚คใƒณใƒใƒผใƒˆใ™ใ‚‹RooCode่จญๅฎšใƒ•ใ‚กใ‚คใƒซใธใฎใƒ‘ใ‚นใ€‚็ตถๅฏพใƒ‘ใ‚นใจใƒ›ใƒผใƒ ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‹ใ‚‰ใฎ็›ธๅฏพใƒ‘ใ‚นใ‚’ใ‚ตใƒใƒผใƒˆใ—ใพใ™๏ผˆไพ‹๏ผš'~/Documents/roo-code-settings.json'๏ผ‰ใ€‚่‡ชๅ‹•ใ‚คใƒณใƒใƒผใƒˆใ‚’็„กๅŠนใซใ™ใ‚‹ใซใฏใ€็ฉบใฎใพใพใซใ—ใพใ™ใ€‚" } diff --git a/src/package.nls.json b/src/package.nls.json index b6880b8bfe..23885f80be 100644 --- a/src/package.nls.json +++ b/src/package.nls.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "The vendor of the language model (e.g. copilot)", "settings.vsCodeLmModelSelector.family.description": "The family of the language model (e.g. gpt-4)", "settings.customStoragePath.description": "Custom storage path. Leave empty to use the default location. Supports absolute paths (e.g. 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Enable Roo Code quick fixes" + "settings.enableCodeActions.description": "Enable Roo Code quick fixes", + "settings.autoImportSettingsPath.description": "Path to a RooCode configuration file to automatically import on extension startup. Supports absolute paths and paths relative to the home directory (e.g. '~/Documents/roo-code-settings.json'). Leave empty to disable auto-import." } diff --git a/src/package.nls.ko.json b/src/package.nls.ko.json index e305da4c4c..e6e30c155b 100644 --- a/src/package.nls.ko.json +++ b/src/package.nls.ko.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "์–ธ์–ด ๋ชจ๋ธ ๊ณต๊ธ‰์ž (์˜ˆ: copilot)", "settings.vsCodeLmModelSelector.family.description": "์–ธ์–ด ๋ชจ๋ธ ๊ณ„์—ด (์˜ˆ: gpt-4)", "settings.customStoragePath.description": "์‚ฌ์šฉ์ž ์ง€์ • ์ €์žฅ์†Œ ๊ฒฝ๋กœ. ๊ธฐ๋ณธ ์œ„์น˜๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋น„์›Œ๋‘์„ธ์š”. ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค (์˜ˆ: 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Roo Code ๋น ๋ฅธ ์ˆ˜์ • ์‚ฌ์šฉ ์„ค์ •" + "settings.enableCodeActions.description": "Roo Code ๋น ๋ฅธ ์ˆ˜์ • ์‚ฌ์šฉ ์„ค์ •", + "settings.autoImportSettingsPath.description": "ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘ ์‹œ ์ž๋™์œผ๋กœ ๊ฐ€์ ธ์˜ฌ RooCode ๊ตฌ์„ฑ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ์ ˆ๋Œ€ ๊ฒฝ๋กœ ๋ฐ ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ์— ๋Œ€ํ•œ ์ƒ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: '~/Documents/roo-code-settings.json'). ์ž๋™ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด ๋น„์›Œ ๋‘ก๋‹ˆ๋‹ค." } diff --git a/src/package.nls.nl.json b/src/package.nls.nl.json index 3cd1880941..095aace43e 100644 --- a/src/package.nls.nl.json +++ b/src/package.nls.nl.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "De leverancier van het taalmodel (bijv. copilot)", "settings.vsCodeLmModelSelector.family.description": "De familie van het taalmodel (bijv. gpt-4)", "settings.customStoragePath.description": "Aangepast opslagpad. Laat leeg om de standaardlocatie te gebruiken. Ondersteunt absolute paden (bijv. 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Snelle correcties van Roo Code inschakelen." + "settings.enableCodeActions.description": "Snelle correcties van Roo Code inschakelen.", + "settings.autoImportSettingsPath.description": "Pad naar een RooCode-configuratiebestand om automatisch te importeren bij het opstarten van de extensie. Ondersteunt absolute paden en paden ten opzichte van de thuismap (bijv. '~/Documents/roo-code-settings.json'). Laat leeg om automatisch importeren uit te schakelen." } diff --git a/src/package.nls.pl.json b/src/package.nls.pl.json index 275c404d06..9963d96db6 100644 --- a/src/package.nls.pl.json +++ b/src/package.nls.pl.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "Dostawca modelu jฤ™zykowego (np. copilot)", "settings.vsCodeLmModelSelector.family.description": "Rodzina modelu jฤ™zykowego (np. gpt-4)", "settings.customStoragePath.description": "Niestandardowa ล›cieลผka przechowywania. Pozostaw puste, aby uลผyฤ‡ domyล›lnej lokalizacji. Obsล‚uguje ล›cieลผki bezwzglฤ™dne (np. 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Wล‚ฤ…cz szybkie poprawki Roo Code." + "settings.enableCodeActions.description": "Wล‚ฤ…cz szybkie poprawki Roo Code.", + "settings.autoImportSettingsPath.description": "ลšcieลผka do pliku konfiguracyjnego RooCode, ktรณry ma byฤ‡ automatycznie importowany podczas uruchamiania rozszerzenia. Obsล‚uguje ล›cieลผki bezwzglฤ™dne i ล›cieลผki wzglฤ™dne do katalogu domowego (np. '~/Documents/roo-code-settings.json'). Pozostaw puste, aby wyล‚ฤ…czyฤ‡ automatyczne importowanie." } diff --git a/src/package.nls.pt-BR.json b/src/package.nls.pt-BR.json index 057f255c44..aaec3b4533 100644 --- a/src/package.nls.pt-BR.json +++ b/src/package.nls.pt-BR.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "O fornecedor do modelo de linguagem (ex: copilot)", "settings.vsCodeLmModelSelector.family.description": "A famรญlia do modelo de linguagem (ex: gpt-4)", "settings.customStoragePath.description": "Caminho de armazenamento personalizado. Deixe vazio para usar o local padrรฃo. Suporta caminhos absolutos (ex: 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Habilitar correรงรตes rรกpidas do Roo Code." + "settings.enableCodeActions.description": "Habilitar correรงรตes rรกpidas do Roo Code.", + "settings.autoImportSettingsPath.description": "Caminho para um arquivo de configuraรงรฃo do RooCode para importar automaticamente na inicializaรงรฃo da extensรฃo. Suporta caminhos absolutos e caminhos relativos ao diretรณrio inicial (por exemplo, '~/Documents/roo-code-settings.json'). Deixe em branco para desativar a importaรงรฃo automรกtica." } diff --git a/src/package.nls.ru.json b/src/package.nls.ru.json index 02a5bcf93d..632c1e3628 100644 --- a/src/package.nls.ru.json +++ b/src/package.nls.ru.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "ะŸะพัั‚ะฐะฒั‰ะธะบ ัะทั‹ะบะพะฒะพะน ะผะพะดะตะปะธ (ะฝะฐะฟั€ะธะผะตั€, copilot)", "settings.vsCodeLmModelSelector.family.description": "ะกะตะผะตะนัั‚ะฒะพ ัะทั‹ะบะพะฒะพะน ะผะพะดะตะปะธ (ะฝะฐะฟั€ะธะผะตั€, gpt-4)", "settings.customStoragePath.description": "ะŸะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบะธะน ะฟัƒั‚ัŒ ั…ั€ะฐะฝะตะฝะธั. ะžัั‚ะฐะฒัŒั‚ะต ะฟัƒัั‚ั‹ะผ ะดะปั ะธัะฟะพะปัŒะทะพะฒะฐะฝะธั ะฟัƒั‚ะธ ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ. ะŸะพะดะดะตั€ะถะธะฒะฐะตั‚ ะฐะฑัะพะปัŽั‚ะฝั‹ะต ะฟัƒั‚ะธ (ะฝะฐะฟั€ะธะผะตั€, 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "ะ’ะบะปัŽั‡ะธั‚ัŒ ะฑั‹ัั‚ั€ั‹ะต ะธัะฟั€ะฐะฒะปะตะฝะธั Roo Code." + "settings.enableCodeActions.description": "ะ’ะบะปัŽั‡ะธั‚ัŒ ะฑั‹ัั‚ั€ั‹ะต ะธัะฟั€ะฐะฒะปะตะฝะธั Roo Code.", + "settings.autoImportSettingsPath.description": "ะŸัƒั‚ัŒ ะบ ั„ะฐะนะปัƒ ะบะพะฝั„ะธะณัƒั€ะฐั†ะธะธ RooCode ะดะปั ะฐะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะพะณะพ ะธะผะฟะพั€ั‚ะฐ ะฟั€ะธ ะทะฐะฟัƒัะบะต ั€ะฐััˆะธั€ะตะฝะธั. ะŸะพะดะดะตั€ะถะธะฒะฐะตั‚ ะฐะฑัะพะปัŽั‚ะฝั‹ะต ะฟัƒั‚ะธ ะธ ะฟัƒั‚ะธ ะพั‚ะฝะพัะธั‚ะตะปัŒะฝะพ ะดะพะผะฐัˆะฝะตะณะพ ะบะฐั‚ะฐะปะพะณะฐ (ะฝะฐะฟั€ะธะผะตั€, '~/Documents/roo-code-settings.json'). ะžัั‚ะฐะฒัŒั‚ะต ะฟัƒัั‚ั‹ะผ, ั‡ั‚ะพะฑั‹ ะพั‚ะบะปัŽั‡ะธั‚ัŒ ะฐะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธะน ะธะผะฟะพั€ั‚." } diff --git a/src/package.nls.tr.json b/src/package.nls.tr.json index dda6e9e8d1..a0b6c47d4f 100644 --- a/src/package.nls.tr.json +++ b/src/package.nls.tr.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "Dil modelinin saฤŸlayฤฑcฤฑsฤฑ (รถrn: copilot)", "settings.vsCodeLmModelSelector.family.description": "Dil modelinin ailesi (รถrn: gpt-4)", "settings.customStoragePath.description": "ร–zel depolama yolu. Varsayฤฑlan konumu kullanmak iรงin boลŸ bฤฑrakฤฑn. Mutlak yollarฤฑ destekler (รถrn: 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Roo Code hฤฑzlฤฑ dรผzeltmeleri etkinleลŸtir." + "settings.enableCodeActions.description": "Roo Code hฤฑzlฤฑ dรผzeltmeleri etkinleลŸtir.", + "settings.autoImportSettingsPath.description": "Uzantฤฑ baลŸlangฤฑcฤฑnda otomatik olarak iรงe aktarฤฑlacak bir RooCode yapฤฑlandฤฑrma dosyasฤฑnฤฑn yolu. Mutlak yollarฤฑ ve ana dizine gรถreli yollarฤฑ destekler (รถr. '~/Documents/roo-code-settings.json'). Otomatik iรงe aktarmayฤฑ devre dฤฑลŸฤฑ bฤฑrakmak iรงin boลŸ bฤฑrakฤฑn." } diff --git a/src/package.nls.vi.json b/src/package.nls.vi.json index 985465acb7..2b5013fed0 100644 --- a/src/package.nls.vi.json +++ b/src/package.nls.vi.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "Nhร  cung cแบฅp mรด hรฌnh ngรดn ngแปฏ (vรญ dแปฅ: copilot)", "settings.vsCodeLmModelSelector.family.description": "Hแป mรด hรฌnh ngรดn ngแปฏ (vรญ dแปฅ: gpt-4)", "settings.customStoragePath.description": "ฤฦฐแปng dแบซn lฦฐu trแปฏ tรนy chแป‰nh. ฤแปƒ trแป‘ng ฤ‘แปƒ sแปญ dแปฅng vแป‹ trรญ mแบทc ฤ‘แป‹nh. Hแป— trแปฃ ฤ‘ฦฐแปng dแบซn tuyแป‡t ฤ‘แป‘i (vรญ dแปฅ: 'D:\\RooCodeStorage')", - "settings.enableCodeActions.description": "Bแบญt sแปญa lแป—i nhanh Roo Code." + "settings.enableCodeActions.description": "Bแบญt sแปญa lแป—i nhanh Roo Code.", + "settings.autoImportSettingsPath.description": "ฤฦฐแปng dแบซn ฤ‘แบฟn tแป‡p cแบฅu hรฌnh RooCode ฤ‘แปƒ tแปฑ ฤ‘แป™ng nhแบญp khi khแปŸi ฤ‘แป™ng tiแป‡n รญch mแปŸ rแป™ng. Hแป— trแปฃ ฤ‘ฦฐแปng dแบซn tuyแป‡t ฤ‘แป‘i vร  ฤ‘ฦฐแปng dแบซn tฦฐฦกng ฤ‘แป‘i ฤ‘แบฟn thฦฐ mแปฅc chรญnh (vรญ dแปฅ: '~/Documents/roo-code-settings.json'). ฤแปƒ trแป‘ng ฤ‘แปƒ tแบฏt tรญnh nฤƒng tแปฑ ฤ‘แป™ng nhแบญp." } diff --git a/src/package.nls.zh-CN.json b/src/package.nls.zh-CN.json index 25d4e15c0a..76bc991c36 100644 --- a/src/package.nls.zh-CN.json +++ b/src/package.nls.zh-CN.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "่ฏญ่จ€ๆจกๅž‹็š„ไพ›ๅบ”ๅ•†๏ผˆไพ‹ๅฆ‚๏ผšcopilot๏ผ‰", "settings.vsCodeLmModelSelector.family.description": "่ฏญ่จ€ๆจกๅž‹็š„็ณปๅˆ—๏ผˆไพ‹ๅฆ‚๏ผšgpt-4๏ผ‰", "settings.customStoragePath.description": "่‡ชๅฎšไน‰ๅญ˜ๅ‚จ่ทฏๅพ„ใ€‚็•™็ฉบไปฅไฝฟ็”จ้ป˜่ฎคไฝ็ฝฎใ€‚ๆ”ฏๆŒ็ปๅฏน่ทฏๅพ„๏ผˆไพ‹ๅฆ‚๏ผš'D:\\RooCodeStorage'๏ผ‰", - "settings.enableCodeActions.description": "ๅฏ็”จ Roo Code ๅฟซ้€Ÿไฟฎๅค" + "settings.enableCodeActions.description": "ๅฏ็”จ Roo Code ๅฟซ้€Ÿไฟฎๅค", + "settings.autoImportSettingsPath.description": "RooCode ้…็ฝฎๆ–‡ไปถ็š„่ทฏๅพ„๏ผŒ็”จไบŽๅœจๆ‰ฉๅฑ•ๅฏๅŠจๆ—ถ่‡ชๅŠจๅฏผๅ…ฅใ€‚ๆ”ฏๆŒ็ปๅฏน่ทฏๅพ„ๅ’Œ็›ธๅฏนไบŽไธป็›ฎๅฝ•็š„่ทฏๅพ„๏ผˆไพ‹ๅฆ‚ '~/Documents/roo-code-settings.json'๏ผ‰ใ€‚็•™็ฉบไปฅ็ฆ็”จ่‡ชๅŠจๅฏผๅ…ฅใ€‚" } diff --git a/src/package.nls.zh-TW.json b/src/package.nls.zh-TW.json index 918b4bff33..c833708541 100644 --- a/src/package.nls.zh-TW.json +++ b/src/package.nls.zh-TW.json @@ -31,5 +31,6 @@ "settings.vsCodeLmModelSelector.vendor.description": "่ชž่จ€ๆจกๅž‹ไพ›ๆ‡‰ๅ•†๏ผˆไพ‹ๅฆ‚๏ผšcopilot๏ผ‰", "settings.vsCodeLmModelSelector.family.description": "่ชž่จ€ๆจกๅž‹็ณปๅˆ—๏ผˆไพ‹ๅฆ‚๏ผšgpt-4๏ผ‰", "settings.customStoragePath.description": "่‡ช่จ‚ๅ„ฒๅญ˜่ทฏๅพ‘ใ€‚็•™็ฉบไปฅไฝฟ็”จ้ ่จญไฝ็ฝฎใ€‚ๆ”ฏๆด็ต•ๅฐ่ทฏๅพ‘๏ผˆไพ‹ๅฆ‚๏ผš'D:\\RooCodeStorage'๏ผ‰", - "settings.enableCodeActions.description": "ๅ•Ÿ็”จ Roo Code ๅฟซ้€Ÿไฟฎๅพฉใ€‚" + "settings.enableCodeActions.description": "ๅ•Ÿ็”จ Roo Code ๅฟซ้€Ÿไฟฎๅพฉใ€‚", + "settings.autoImportSettingsPath.description": "RooCode ่จญๅฎšๆช”ๆกˆ็š„่ทฏๅพ‘๏ผŒ็”จๆ–ผๅœจๆ“ดๅ……ๅŠŸ่ƒฝๅ•Ÿๅ‹•ๆ™‚่‡ชๅ‹•ๅŒฏๅ…ฅใ€‚ๆ”ฏๆด็ต•ๅฐ่ทฏๅพ‘ๅ’Œ็›ธๅฐๆ–ผไธป็›ฎ้Œ„็š„่ทฏๅพ‘๏ผˆไพ‹ๅฆ‚ '~/Documents/roo-code-settings.json'๏ผ‰ใ€‚็•™็ฉบไปฅๅœ็”จ่‡ชๅ‹•ๅŒฏๅ…ฅใ€‚" } diff --git a/src/utils/__tests__/autoImportSettings.spec.ts b/src/utils/__tests__/autoImportSettings.spec.ts index 04d2a6a6c7..2b9b42293f 100644 --- a/src/utils/__tests__/autoImportSettings.spec.ts +++ b/src/utils/__tests__/autoImportSettings.spec.ts @@ -9,9 +9,6 @@ vi.mock("vscode", () => ({ showInformationMessage: vi.fn(), showWarningMessage: vi.fn(), }, - Uri: { - file: vi.fn((path: string) => ({ fsPath: path })), - }, })) vi.mock("fs/promises", () => ({ @@ -228,7 +225,9 @@ describe("autoImportSettings", () => { expect(mockOutputChannel.appendLine).toHaveBeenCalledWith( expect.stringContaining("[AutoImport] Failed to import settings:"), ) - expect(vscode.window.showWarningMessage).toHaveBeenCalledWith("warnings.auto_import_failed") + expect(vscode.window.showWarningMessage).toHaveBeenCalledWith( + expect.stringContaining("warnings.auto_import_failed"), + ) expect(mockProviderSettingsManager.import).not.toHaveBeenCalled() }) diff --git a/src/utils/autoImportSettings.ts b/src/utils/autoImportSettings.ts index d5871f3224..f3ab4080d7 100644 --- a/src/utils/autoImportSettings.ts +++ b/src/utils/autoImportSettings.ts @@ -6,16 +6,7 @@ import { Package } from "../shared/package" import { fileExistsAtPath } from "./fs" import { t } from "../i18n" -import { importSettingsFromFile } from "../core/config/importExport" -import { ProviderSettingsManager } from "../core/config/ProviderSettingsManager" -import { ContextProxy } from "../core/config/ContextProxy" -import { CustomModesManager } from "../core/config/CustomModesManager" - -type ImportOptions = { - providerSettingsManager: ProviderSettingsManager - contextProxy: ContextProxy - customModesManager: CustomModesManager -} +import { importSettingsFromPath, ImportOptions } from "../core/config/importExport" /** * Automatically imports RooCode settings from a specified path if it exists. @@ -46,15 +37,11 @@ export async function autoImportSettings( } // Attempt to import the configuration - const fileUri = vscode.Uri.file(resolvedPath) - const result = await importSettingsFromFile( - { - providerSettingsManager, - contextProxy, - customModesManager, - }, - fileUri, - ) + const result = await importSettingsFromPath(resolvedPath, { + providerSettingsManager, + contextProxy, + customModesManager, + }) if (result.success) { outputChannel.appendLine(`[AutoImport] Successfully imported settings from ${resolvedPath}`) From fb711a097cdccd9ae62df2c742ce0c06892d8166 Mon Sep 17 00:00:00 2001 From: roomote Date: Mon, 30 Jun 2025 07:48:57 -0700 Subject: [PATCH 35/70] Fixes #4903: Consistent cancellation error messages for thinking vs streaming phases (#4904) Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com> --- src/core/task/Task.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index ef5db499d2..bc7cd31f26 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1425,10 +1425,15 @@ export class Task extends EventEmitter { // cancel task. this.abortTask() - await abortStream( - "streaming_failed", - error.message ?? JSON.stringify(serializeError(error), null, 2), - ) + // Check if this was a user-initiated cancellation + // If this.abort is true, it means the user clicked cancel, so we should + // treat this as "user_cancelled" rather than "streaming_failed" + const cancelReason = this.abort ? "user_cancelled" : "streaming_failed" + const streamingFailedMessage = this.abort + ? undefined + : (error.message ?? JSON.stringify(serializeError(error), null, 2)) + + await abortStream(cancelReason, streamingFailedMessage) const history = await provider?.getTaskWithId(this.taskId) From 000a9e526803c6f217577494be5fc56ca1245475 Mon Sep 17 00:00:00 2001 From: Kevin Zhao Date: Mon, 30 Jun 2025 23:49:32 +0900 Subject: [PATCH 36/70] feat: update AWS Bedrock cross-region inference profile mapping, Closed issue #2704 (#4973) --- packages/types/src/providers/bedrock.ts | 119 ++---- .../bedrock-inference-profiles.spec.ts | 249 +++++++++++ src/api/providers/__tests__/bedrock.spec.ts | 394 ++++++++++++++++-- src/api/providers/bedrock.ts | 75 ++-- 4 files changed, 684 insertions(+), 153 deletions(-) create mode 100644 src/api/providers/__tests__/bedrock-inference-profiles.spec.ts diff --git a/packages/types/src/providers/bedrock.ts b/packages/types/src/providers/bedrock.ts index a15f041252..58e860dd94 100644 --- a/packages/types/src/providers/bedrock.ts +++ b/packages/types/src/providers/bedrock.ts @@ -360,78 +360,49 @@ export const BEDROCK_MAX_TOKENS = 4096 export const BEDROCK_DEFAULT_CONTEXT = 128_000 -export const BEDROCK_REGION_INFO: Record< - string, - { - regionId: string - description: string - pattern?: string - multiRegion?: boolean - } -> = { - /* - * This JSON generated by AWS's AI assistant - Amazon Q on March 29, 2025 - * - * - Africa (Cape Town) region does not appear to support Amazon Bedrock at this time. - * - Some Asia Pacific regions, such as Asia Pacific (Hong Kong) and Asia Pacific (Jakarta), are not listed among the supported regions for Bedrock services. - * - Middle East regions, including Middle East (Bahrain) and Middle East (UAE), are not mentioned in the list of supported regions for Bedrock. [3] - * - China regions (Beijing and Ningxia) are not listed as supported for Amazon Bedrock. - * - Some newer or specialized AWS regions may not have Bedrock support yet. - */ - "us.": { regionId: "us-east-1", description: "US East (N. Virginia)", pattern: "us-", multiRegion: true }, - "use.": { regionId: "us-east-1", description: "US East (N. Virginia)" }, - "use1.": { regionId: "us-east-1", description: "US East (N. Virginia)" }, - "use2.": { regionId: "us-east-2", description: "US East (Ohio)" }, - "usw.": { regionId: "us-west-2", description: "US West (Oregon)" }, - "usw2.": { regionId: "us-west-2", description: "US West (Oregon)" }, - "ug.": { - regionId: "us-gov-west-1", - description: "AWS GovCloud (US-West)", - pattern: "us-gov-", - multiRegion: true, - }, - "uge1.": { regionId: "us-gov-east-1", description: "AWS GovCloud (US-East)" }, - "ugw1.": { regionId: "us-gov-west-1", description: "AWS GovCloud (US-West)" }, - "eu.": { regionId: "eu-west-1", description: "Europe (Ireland)", pattern: "eu-", multiRegion: true }, - "euw1.": { regionId: "eu-west-1", description: "Europe (Ireland)" }, - "euw2.": { regionId: "eu-west-2", description: "Europe (London)" }, - "euw3.": { regionId: "eu-west-3", description: "Europe (Paris)" }, - "euc1.": { regionId: "eu-central-1", description: "Europe (Frankfurt)" }, - "euc2.": { regionId: "eu-central-2", description: "Europe (Zurich)" }, - "eun1.": { regionId: "eu-north-1", description: "Europe (Stockholm)" }, - "eus1.": { regionId: "eu-south-1", description: "Europe (Milan)" }, - "eus2.": { regionId: "eu-south-2", description: "Europe (Spain)" }, - "ap.": { - regionId: "ap-southeast-1", - description: "Asia Pacific (Singapore)", - pattern: "ap-", - multiRegion: true, - }, - "ape1.": { regionId: "ap-east-1", description: "Asia Pacific (Hong Kong)" }, - "apne1.": { regionId: "ap-northeast-1", description: "Asia Pacific (Tokyo)" }, - "apne2.": { regionId: "ap-northeast-2", description: "Asia Pacific (Seoul)" }, - "apne3.": { regionId: "ap-northeast-3", description: "Asia Pacific (Osaka)" }, - "aps1.": { regionId: "ap-south-1", description: "Asia Pacific (Mumbai)" }, - "aps2.": { regionId: "ap-south-2", description: "Asia Pacific (Hyderabad)" }, - "apse1.": { regionId: "ap-southeast-1", description: "Asia Pacific (Singapore)" }, - "apse2.": { regionId: "ap-southeast-2", description: "Asia Pacific (Sydney)" }, - "ca.": { regionId: "ca-central-1", description: "Canada (Central)", pattern: "ca-", multiRegion: true }, - "cac1.": { regionId: "ca-central-1", description: "Canada (Central)" }, - "sa.": { regionId: "sa-east-1", description: "South America (Sรฃo Paulo)", pattern: "sa-", multiRegion: true }, - "sae1.": { regionId: "sa-east-1", description: "South America (Sรฃo Paulo)" }, +// AWS Bedrock Inference Profile mapping based on official documentation +// https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html +// This mapping is pre-ordered by pattern length (descending) to ensure more specific patterns match first +export const AWS_INFERENCE_PROFILE_MAPPING: Array<[string, string]> = [ + // US Government Cloud โ†’ ug. inference profile (most specific prefix first) + ["us-gov-", "ug."], + // Americas regions โ†’ us. inference profile + ["us-", "us."], + // Europe regions โ†’ eu. inference profile + ["eu-", "eu."], + // Asia Pacific regions โ†’ apac. inference profile + ["ap-", "apac."], + // Canada regions โ†’ ca. inference profile + ["ca-", "ca."], + // South America regions โ†’ sa. inference profile + ["sa-", "sa."], +] - // These are not official - they weren't generated by Amazon Q nor were - // found in the AWS documentation but another Roo contributor found apac. - // Was needed so I've added the pattern of the other geo zones. - "apac.": { regionId: "ap-southeast-1", description: "Default APAC region", pattern: "ap-", multiRegion: true }, - "emea.": { regionId: "eu-west-1", description: "Default EMEA region", pattern: "eu-", multiRegion: true }, - "amer.": { regionId: "us-east-1", description: "Default Americas region", pattern: "us-", multiRegion: true }, -} - -export const BEDROCK_REGIONS = Object.values(BEDROCK_REGION_INFO) - // Extract all region IDs - .map((info) => ({ value: info.regionId, label: info.regionId })) - // Filter to unique region IDs (remove duplicates) - .filter((region, index, self) => index === self.findIndex((r) => r.value === region.value)) - // Sort alphabetically by region ID - .sort((a, b) => a.value.localeCompare(b.value)) +// AWS Bedrock supported regions for the regions dropdown +// Based on official AWS documentation +export const BEDROCK_REGIONS = [ + { value: "us-east-1", label: "us-east-1" }, + { value: "us-east-2", label: "us-east-2" }, + { value: "us-west-1", label: "us-west-1" }, + { value: "us-west-2", label: "us-west-2" }, + { value: "ap-northeast-1", label: "ap-northeast-1" }, + { value: "ap-northeast-2", label: "ap-northeast-2" }, + { value: "ap-northeast-3", label: "ap-northeast-3" }, + { value: "ap-south-1", label: "ap-south-1" }, + { value: "ap-south-2", label: "ap-south-2" }, + { value: "ap-southeast-1", label: "ap-southeast-1" }, + { value: "ap-southeast-2", label: "ap-southeast-2" }, + { value: "ap-east-1", label: "ap-east-1" }, + { value: "eu-central-1", label: "eu-central-1" }, + { value: "eu-central-2", label: "eu-central-2" }, + { value: "eu-west-1", label: "eu-west-1" }, + { value: "eu-west-2", label: "eu-west-2" }, + { value: "eu-west-3", label: "eu-west-3" }, + { value: "eu-north-1", label: "eu-north-1" }, + { value: "eu-south-1", label: "eu-south-1" }, + { value: "eu-south-2", label: "eu-south-2" }, + { value: "ca-central-1", label: "ca-central-1" }, + { value: "sa-east-1", label: "sa-east-1" }, + { value: "us-gov-east-1", label: "us-gov-east-1" }, + { value: "us-gov-west-1", label: "us-gov-west-1" }, +].sort((a, b) => a.value.localeCompare(b.value)) diff --git a/src/api/providers/__tests__/bedrock-inference-profiles.spec.ts b/src/api/providers/__tests__/bedrock-inference-profiles.spec.ts new file mode 100644 index 0000000000..7eef16d241 --- /dev/null +++ b/src/api/providers/__tests__/bedrock-inference-profiles.spec.ts @@ -0,0 +1,249 @@ +// npx vitest run src/api/providers/__tests__/bedrock-inference-profiles.spec.ts + +import { AWS_INFERENCE_PROFILE_MAPPING } from "@roo-code/types" +import { AwsBedrockHandler } from "../bedrock" +import { ApiHandlerOptions } from "../../../shared/api" + +// Mock AWS SDK +vitest.mock("@aws-sdk/client-bedrock-runtime", () => { + return { + BedrockRuntimeClient: vitest.fn().mockImplementation(() => ({ + send: vitest.fn(), + config: { region: "us-east-1" }, + })), + ConverseCommand: vitest.fn(), + ConverseStreamCommand: vitest.fn(), + } +}) + +describe("AWS Bedrock Inference Profiles", () => { + // Helper function to create a handler with specific options + const createHandler = (options: Partial = {}) => { + const defaultOptions: ApiHandlerOptions = { + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + awsRegion: "us-east-1", + ...options, + } + return new AwsBedrockHandler(defaultOptions) + } + + describe("AWS_INFERENCE_PROFILE_MAPPING constant", () => { + it("should contain all expected region mappings", () => { + expect(AWS_INFERENCE_PROFILE_MAPPING).toEqual([ + ["us-gov-", "ug."], + ["us-", "us."], + ["eu-", "eu."], + ["ap-", "apac."], + ["ca-", "ca."], + ["sa-", "sa."], + ]) + }) + + it("should be ordered by pattern length (descending)", () => { + const lengths = AWS_INFERENCE_PROFILE_MAPPING.map(([pattern]) => pattern.length) + const sortedLengths = [...lengths].sort((a, b) => b - a) + expect(lengths).toEqual(sortedLengths) + }) + + it("should have valid inference profile prefixes", () => { + AWS_INFERENCE_PROFILE_MAPPING.forEach(([regionPattern, inferenceProfile]) => { + expect(regionPattern).toMatch(/^[a-z-]+$/) + expect(inferenceProfile).toMatch(/^[a-z]+\.$/) + }) + }) + }) + + describe("getPrefixForRegion function", () => { + it("should return correct prefix for US government regions", () => { + const handler = createHandler() + expect((handler as any).constructor.getPrefixForRegion("us-gov-east-1")).toBe("ug.") + expect((handler as any).constructor.getPrefixForRegion("us-gov-west-1")).toBe("ug.") + }) + + it("should return correct prefix for US commercial regions", () => { + const handler = createHandler() + expect((handler as any).constructor.getPrefixForRegion("us-east-1")).toBe("us.") + expect((handler as any).constructor.getPrefixForRegion("us-west-1")).toBe("us.") + expect((handler as any).constructor.getPrefixForRegion("us-west-2")).toBe("us.") + }) + + it("should return correct prefix for European regions", () => { + const handler = createHandler() + expect((handler as any).constructor.getPrefixForRegion("eu-west-1")).toBe("eu.") + expect((handler as any).constructor.getPrefixForRegion("eu-central-1")).toBe("eu.") + expect((handler as any).constructor.getPrefixForRegion("eu-north-1")).toBe("eu.") + expect((handler as any).constructor.getPrefixForRegion("eu-south-1")).toBe("eu.") + }) + + it("should return correct prefix for Asia Pacific regions", () => { + const handler = createHandler() + expect((handler as any).constructor.getPrefixForRegion("ap-southeast-1")).toBe("apac.") + expect((handler as any).constructor.getPrefixForRegion("ap-northeast-1")).toBe("apac.") + expect((handler as any).constructor.getPrefixForRegion("ap-south-1")).toBe("apac.") + expect((handler as any).constructor.getPrefixForRegion("ap-east-1")).toBe("apac.") + }) + + it("should return correct prefix for Canada regions", () => { + const handler = createHandler() + expect((handler as any).constructor.getPrefixForRegion("ca-central-1")).toBe("ca.") + expect((handler as any).constructor.getPrefixForRegion("ca-west-1")).toBe("ca.") + }) + + it("should return correct prefix for South America regions", () => { + const handler = createHandler() + expect((handler as any).constructor.getPrefixForRegion("sa-east-1")).toBe("sa.") + }) + + it("should return undefined for unsupported regions", () => { + const handler = createHandler() + expect((handler as any).constructor.getPrefixForRegion("af-south-1")).toBeUndefined() + expect((handler as any).constructor.getPrefixForRegion("me-south-1")).toBeUndefined() + expect((handler as any).constructor.getPrefixForRegion("cn-north-1")).toBeUndefined() + expect((handler as any).constructor.getPrefixForRegion("invalid-region")).toBeUndefined() + }) + + it("should prioritize longer patterns over shorter ones", () => { + const handler = createHandler() + // us-gov- should be matched before us- + expect((handler as any).constructor.getPrefixForRegion("us-gov-east-1")).toBe("ug.") + expect((handler as any).constructor.getPrefixForRegion("us-gov-west-1")).toBe("ug.") + + // Regular us- regions should still work + expect((handler as any).constructor.getPrefixForRegion("us-east-1")).toBe("us.") + expect((handler as any).constructor.getPrefixForRegion("us-west-2")).toBe("us.") + }) + }) + + describe("Cross-region inference integration", () => { + it("should apply ug. prefix for US government regions", () => { + const handler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "us-gov-east-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const model = handler.getModel() + expect(model.id).toBe("ug.anthropic.claude-3-sonnet-20240229-v1:0") + }) + + it("should apply us. prefix for US commercial regions", () => { + const handler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "us-east-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const model = handler.getModel() + expect(model.id).toBe("us.anthropic.claude-3-sonnet-20240229-v1:0") + }) + + it("should apply eu. prefix for European regions", () => { + const handler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "eu-west-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const model = handler.getModel() + expect(model.id).toBe("eu.anthropic.claude-3-sonnet-20240229-v1:0") + }) + + it("should apply apac. prefix for Asia Pacific regions", () => { + const handler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "ap-southeast-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const model = handler.getModel() + expect(model.id).toBe("apac.anthropic.claude-3-sonnet-20240229-v1:0") + }) + + it("should apply ca. prefix for Canada regions", () => { + const handler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "ca-central-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const model = handler.getModel() + expect(model.id).toBe("ca.anthropic.claude-3-sonnet-20240229-v1:0") + }) + + it("should apply sa. prefix for South America regions", () => { + const handler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "sa-east-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const model = handler.getModel() + expect(model.id).toBe("sa.anthropic.claude-3-sonnet-20240229-v1:0") + }) + + it("should not apply prefix when cross-region inference is disabled", () => { + const handler = createHandler({ + awsUseCrossRegionInference: false, + awsRegion: "us-gov-east-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const model = handler.getModel() + expect(model.id).toBe("anthropic.claude-3-sonnet-20240229-v1:0") + }) + + it("should handle unsupported regions gracefully", () => { + const handler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "af-south-1", // Unsupported region + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const model = handler.getModel() + // Should remain unchanged when no prefix is found + expect(model.id).toBe("anthropic.claude-3-sonnet-20240229-v1:0") + }) + + it("should work with different model IDs", () => { + const testModels = [ + "anthropic.claude-3-haiku-20240307-v1:0", + "anthropic.claude-3-opus-20240229-v1:0", + "amazon.nova-pro-v1:0", + "meta.llama3-1-70b-instruct-v1:0", + ] + + testModels.forEach((modelId) => { + const handler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "eu-west-1", + apiModelId: modelId, + }) + + const model = handler.getModel() + expect(model.id).toBe(`eu.${modelId}`) + }) + }) + + it("should prioritize us-gov- over us- in cross-region inference", () => { + // Test that us-gov-east-1 gets ug. prefix, not us. + const govHandler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "us-gov-east-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const govModel = govHandler.getModel() + expect(govModel.id).toBe("ug.anthropic.claude-3-sonnet-20240229-v1:0") + + // Test that regular us-east-1 still gets us. prefix + const usHandler = createHandler({ + awsUseCrossRegionInference: true, + awsRegion: "us-east-1", + apiModelId: "anthropic.claude-3-sonnet-20240229-v1:0", + }) + + const usModel = usHandler.getModel() + expect(usModel.id).toBe("us.anthropic.claude-3-sonnet-20240229-v1:0") + }) + }) +}) diff --git a/src/api/providers/__tests__/bedrock.spec.ts b/src/api/providers/__tests__/bedrock.spec.ts index 80f6338629..ad0ae2bdb5 100644 --- a/src/api/providers/__tests__/bedrock.spec.ts +++ b/src/api/providers/__tests__/bedrock.spec.ts @@ -74,42 +74,6 @@ describe("AwsBedrockHandler", () => { expect(modelInfo.info).toBeDefined() }) - it("should handle inference-profile ARN with apne3 region prefix", () => { - const originalParseArn = AwsBedrockHandler.prototype["parseArn"] - const parseArnMock = vi.fn().mockImplementation(function (this: any, arn: string, region?: string) { - return originalParseArn.call(this, arn, region) - }) - AwsBedrockHandler.prototype["parseArn"] = parseArnMock - - try { - const customArnHandler = new AwsBedrockHandler({ - apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", - awsAccessKey: "test-access-key", - awsSecretKey: "test-secret-key", - awsRegion: "ap-northeast-3", - awsCustomArn: - "arn:aws:bedrock:ap-northeast-3:123456789012:inference-profile/apne3.anthropic.claude-3-5-sonnet-20241022-v2:0", - }) - - const modelInfo = customArnHandler.getModel() - - expect(modelInfo.id).toBe( - "arn:aws:bedrock:ap-northeast-3:123456789012:inference-profile/apne3.anthropic.claude-3-5-sonnet-20241022-v2:0", - ) - expect(modelInfo.info).toBeDefined() - - expect(parseArnMock).toHaveBeenCalledWith( - "arn:aws:bedrock:ap-northeast-3:123456789012:inference-profile/apne3.anthropic.claude-3-5-sonnet-20241022-v2:0", - "ap-northeast-3", - ) - - expect((customArnHandler as any).arnInfo.modelId).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0") - expect((customArnHandler as any).arnInfo.crossRegionInference).toBe(false) - } finally { - AwsBedrockHandler.prototype["parseArn"] = originalParseArn - } - }) - it("should use default prompt router model when prompt router arn is entered but no model can be identified from the ARN", () => { const customArnHandler = new AwsBedrockHandler({ awsCustomArn: @@ -127,6 +91,270 @@ describe("AwsBedrockHandler", () => { }) }) + describe("region mapping and cross-region inference", () => { + describe("getPrefixForRegion", () => { + it("should return correct prefix for US regions", () => { + // Access private static method using type casting + const getPrefixForRegion = (AwsBedrockHandler as any).getPrefixForRegion + + expect(getPrefixForRegion("us-east-1")).toBe("us.") + expect(getPrefixForRegion("us-west-2")).toBe("us.") + expect(getPrefixForRegion("us-gov-west-1")).toBe("ug.") + }) + + it("should return correct prefix for EU regions", () => { + const getPrefixForRegion = (AwsBedrockHandler as any).getPrefixForRegion + + expect(getPrefixForRegion("eu-west-1")).toBe("eu.") + expect(getPrefixForRegion("eu-central-1")).toBe("eu.") + expect(getPrefixForRegion("eu-north-1")).toBe("eu.") + }) + + it("should return correct prefix for APAC regions", () => { + const getPrefixForRegion = (AwsBedrockHandler as any).getPrefixForRegion + + expect(getPrefixForRegion("ap-southeast-1")).toBe("apac.") + expect(getPrefixForRegion("ap-northeast-1")).toBe("apac.") + expect(getPrefixForRegion("ap-south-1")).toBe("apac.") + }) + + it("should return undefined for unsupported regions", () => { + const getPrefixForRegion = (AwsBedrockHandler as any).getPrefixForRegion + + expect(getPrefixForRegion("unknown-region")).toBeUndefined() + expect(getPrefixForRegion("")).toBeUndefined() + expect(getPrefixForRegion("invalid")).toBeUndefined() + }) + }) + + describe("isSystemInferenceProfile", () => { + it("should return true for AWS inference profile prefixes", () => { + const isSystemInferenceProfile = (AwsBedrockHandler as any).isSystemInferenceProfile + + expect(isSystemInferenceProfile("us.")).toBe(true) + expect(isSystemInferenceProfile("eu.")).toBe(true) + expect(isSystemInferenceProfile("apac.")).toBe(true) + }) + + it("should return false for other prefixes", () => { + const isSystemInferenceProfile = (AwsBedrockHandler as any).isSystemInferenceProfile + + expect(isSystemInferenceProfile("ap.")).toBe(false) + expect(isSystemInferenceProfile("apne1.")).toBe(false) + expect(isSystemInferenceProfile("use1.")).toBe(false) + expect(isSystemInferenceProfile("custom.")).toBe(false) + expect(isSystemInferenceProfile("")).toBe(false) + }) + }) + + describe("parseBaseModelId", () => { + it("should remove defined inference profile prefixes", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + }) + + // Access private method using type casting + const parseBaseModelId = (handler as any).parseBaseModelId.bind(handler) + + expect(parseBaseModelId("us.anthropic.claude-3-5-sonnet-20241022-v2:0")).toBe( + "anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + expect(parseBaseModelId("eu.anthropic.claude-3-haiku-20240307-v1:0")).toBe( + "anthropic.claude-3-haiku-20240307-v1:0", + ) + expect(parseBaseModelId("apac.anthropic.claude-3-opus-20240229-v1:0")).toBe( + "anthropic.claude-3-opus-20240229-v1:0", + ) + }) + + it("should not modify model IDs without defined prefixes", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + }) + + const parseBaseModelId = (handler as any).parseBaseModelId.bind(handler) + + expect(parseBaseModelId("anthropic.claude-3-5-sonnet-20241022-v2:0")).toBe( + "anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + expect(parseBaseModelId("amazon.titan-text-express-v1")).toBe("amazon.titan-text-express-v1") + }) + + it("should not modify model IDs with other prefixes", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + }) + + const parseBaseModelId = (handler as any).parseBaseModelId.bind(handler) + + // Other prefixes should be preserved as part of the model ID + expect(parseBaseModelId("ap.anthropic.claude-3-5-sonnet-20241022-v2:0")).toBe( + "ap.anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + expect(parseBaseModelId("apne1.anthropic.claude-3-5-sonnet-20241022-v2:0")).toBe( + "apne1.anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + expect(parseBaseModelId("use1.anthropic.claude-3-5-sonnet-20241022-v2:0")).toBe( + "use1.anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + }) + }) + + describe("cross-region inference integration", () => { + it("should apply correct prefix when cross-region inference is enabled", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + awsUseCrossRegionInference: true, + }) + + const model = handler.getModel() + expect(model.id).toBe("us.anthropic.claude-3-5-sonnet-20241022-v2:0") + }) + + it("should apply correct prefix for different regions", () => { + const euHandler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "eu-west-1", + awsUseCrossRegionInference: true, + }) + + const apacHandler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "ap-southeast-1", + awsUseCrossRegionInference: true, + }) + + expect(euHandler.getModel().id).toBe("eu.anthropic.claude-3-5-sonnet-20241022-v2:0") + expect(apacHandler.getModel().id).toBe("apac.anthropic.claude-3-5-sonnet-20241022-v2:0") + }) + + it("should not apply prefix when cross-region inference is disabled", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + awsUseCrossRegionInference: false, + }) + + const model = handler.getModel() + expect(model.id).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0") + }) + + it("should not apply prefix for unsupported regions", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "unknown-region", + awsUseCrossRegionInference: true, + }) + + const model = handler.getModel() + expect(model.id).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0") + }) + }) + + describe("ARN parsing with inference profiles", () => { + it("should detect cross-region inference from ARN model ID", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "test", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + }) + + const parseArn = (handler as any).parseArn.bind(handler) + + const result = parseArn( + "arn:aws:bedrock:us-east-1:123456789012:foundation-model/us.anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + + expect(result.isValid).toBe(true) + expect(result.crossRegionInference).toBe(true) + expect(result.modelId).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0") + }) + + it("should not detect cross-region inference for non-prefixed models", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "test", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + }) + + const parseArn = (handler as any).parseArn.bind(handler) + + const result = parseArn( + "arn:aws:bedrock:us-east-1:123456789012:foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + + expect(result.isValid).toBe(true) + expect(result.crossRegionInference).toBe(false) + expect(result.modelId).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0") + }) + + it("should detect cross-region inference for defined prefixes", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "test", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + }) + + const parseArn = (handler as any).parseArn.bind(handler) + + const euResult = parseArn( + "arn:aws:bedrock:eu-west-1:123456789012:foundation-model/eu.anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + const apacResult = parseArn( + "arn:aws:bedrock:ap-southeast-1:123456789012:foundation-model/apac.anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + + expect(euResult.crossRegionInference).toBe(true) + expect(euResult.modelId).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0") + + expect(apacResult.crossRegionInference).toBe(true) + expect(apacResult.modelId).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0") + }) + + it("should not detect cross-region inference for other prefixes", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "test", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + }) + + const parseArn = (handler as any).parseArn.bind(handler) + + // Other prefixes should not trigger cross-region inference detection + const result = parseArn( + "arn:aws:bedrock:us-east-1:123456789012:foundation-model/ap.anthropic.claude-3-5-sonnet-20241022-v2:0", + ) + + expect(result.crossRegionInference).toBe(false) + expect(result.modelId).toBe("ap.anthropic.claude-3-5-sonnet-20241022-v2:0") // Should be preserved as-is + }) + }) + }) + describe("image handling", () => { const mockImageData = Buffer.from("test-image-data").toString("base64") @@ -242,4 +470,98 @@ describe("AwsBedrockHandler", () => { expect(secondImage.image).toHaveProperty("format", "png") }) }) + + describe("error handling and validation", () => { + it("should handle invalid regions gracefully", () => { + expect(() => { + new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "", // Empty region + }) + }).not.toThrow() + }) + + it("should validate ARN format and provide helpful error messages", () => { + expect(() => { + new AwsBedrockHandler({ + apiModelId: "test", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + awsCustomArn: "invalid-arn-format", + }) + }).toThrow(/INVALID_ARN_FORMAT/) + }) + + it("should handle malformed ARNs with missing components", () => { + expect(() => { + new AwsBedrockHandler({ + apiModelId: "test", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + awsCustomArn: "arn:aws:bedrock:us-east-1", + }) + }).toThrow(/INVALID_ARN_FORMAT/) + }) + }) + + describe("model information and configuration", () => { + it("should preserve model information after applying cross-region prefixes", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + awsUseCrossRegionInference: true, + }) + + const model = handler.getModel() + + // Model ID should have prefix + expect(model.id).toBe("us.anthropic.claude-3-5-sonnet-20241022-v2:0") + + // But model info should remain the same + expect(model.info.maxTokens).toBe(8192) + expect(model.info.contextWindow).toBe(200_000) + expect(model.info.supportsImages).toBe(true) + expect(model.info.supportsPromptCache).toBe(true) + }) + + it("should handle model configuration overrides correctly", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + modelMaxTokens: 4096, + awsModelContextWindow: 100_000, + }) + + const model = handler.getModel() + + // Should use override values + expect(model.info.maxTokens).toBe(4096) + expect(model.info.contextWindow).toBe(100_000) + }) + + it("should handle unknown models with sensible defaults", () => { + const handler = new AwsBedrockHandler({ + apiModelId: "unknown.model.id", + awsAccessKey: "test", + awsSecretKey: "test", + awsRegion: "us-east-1", + }) + + const model = handler.getModel() + + // Should fall back to default model info + expect(model.info.maxTokens).toBeDefined() + expect(model.info.contextWindow).toBeDefined() + expect(typeof model.info.supportsImages).toBe("boolean") + expect(typeof model.info.supportsPromptCache).toBe("boolean") + }) + }) }) diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index d8a370e08f..a25fea5200 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -20,7 +20,7 @@ import { BEDROCK_DEFAULT_TEMPERATURE, BEDROCK_MAX_TOKENS, BEDROCK_DEFAULT_CONTEXT, - BEDROCK_REGION_INFO, + AWS_INFERENCE_PROFILE_MAPPING, } from "@roo-code/types" import { ApiStream } from "../transform/stream" @@ -482,7 +482,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH if (streamEvent.contentBlockStart) { const cbStart = streamEvent.contentBlockStart - // Check if this is a reasoning block (official AWS SDK structure) + // Check if this is a reasoning block (AWS SDK structure) if (cbStart.contentBlock?.reasoningContent) { if (cbStart.contentBlockIndex && cbStart.contentBlockIndex > 0) { yield { type: "reasoning", text: "\n" } @@ -493,7 +493,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH } } // Check for thinking block - handle both possible AWS SDK structures - // cbStart.contentBlock: newer/official structure + // cbStart.contentBlock: newer structure // cbStart.content_block: alternative structure seen in some AWS SDK versions else if (cbStart.contentBlock?.type === "thinking" || cbStart.content_block?.type === "thinking") { const contentBlock = cbStart.contentBlock || cbStart.content_block @@ -522,11 +522,11 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH // Process reasoning and text content deltas // Multiple structures are supported for AWS SDK compatibility: - // - delta.reasoningContent.text: official AWS docs structure for reasoning + // - delta.reasoningContent.text: AWS docs structure for reasoning // - delta.thinking: alternative structure for thinking content // - delta.text: standard text content if (delta) { - // Check for reasoningContent property (official AWS SDK structure) + // Check for reasoningContent property (AWS SDK structure) if (delta.reasoningContent?.text) { yield { type: "reasoning", @@ -827,7 +827,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH if (originalModelId && result.modelId !== originalModelId) { // If the model ID changed after parsing, it had a region prefix let prefix = originalModelId.replace(result.modelId, "") - result.crossRegionInference = AwsBedrockHandler.prefixIsMultiRegion(prefix) + result.crossRegionInference = AwsBedrockHandler.isSystemInferenceProfile(prefix) } // Check if region in ARN matches provided region (if specified) @@ -851,29 +851,21 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH } //This strips any region prefix that used on cross-region model inference ARNs - private parseBaseModelId(modelId: string) { + private parseBaseModelId(modelId: string): string { if (!modelId) { return modelId } - const knownRegionPrefixes = AwsBedrockHandler.getPrefixList() - - // Find if the model ID starts with any known region prefix - const matchedPrefix = knownRegionPrefixes.find((prefix) => modelId.startsWith(prefix)) - - if (matchedPrefix) { - // Remove the region prefix from the model ID - return modelId.substring(matchedPrefix.length) - } else { - // If no known prefix was found, check for a generic pattern - // Look for a pattern where the first segment before a dot doesn't contain dots or colons - // and the remaining parts still contain at least one dot - const genericPrefixMatch = modelId.match(/^([^.:]+)\.(.+\..+)$/) - - if (genericPrefixMatch) { - return genericPrefixMatch[2] + // Remove AWS cross-region inference profile prefixes + // as defined in AWS_INFERENCE_PROFILE_MAPPING + for (const [_, inferenceProfile] of AWS_INFERENCE_PROFILE_MAPPING) { + if (modelId.startsWith(inferenceProfile)) { + // Remove the inference profile prefix from the model ID + return modelId.substring(inferenceProfile.length) } } + + // Return the model ID as-is for all other cases return modelId } @@ -950,14 +942,12 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH //a model was selected from the drop down modelConfig = this.getModelById(this.options.apiModelId as string) - if (this.options.awsUseCrossRegionInference) { - // Get the current region - const region = this.options.awsRegion || "" - // Use the helper method to get the appropriate prefix for this region - const prefix = AwsBedrockHandler.getPrefixForRegion(region) - - // Apply the prefix if one was found, otherwise use the model ID as is - modelConfig.id = prefix ? `${prefix}${modelConfig.id}` : modelConfig.id + // Add cross-region inference prefix if enabled + if (this.options.awsUseCrossRegionInference && this.options.awsRegion) { + const prefix = AwsBedrockHandler.getPrefixForRegion(this.options.awsRegion) + if (prefix) { + modelConfig.id = `${prefix}${modelConfig.id}` + } } } @@ -1023,24 +1013,23 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH * *************************************************************************************/ - private static getPrefixList(): string[] { - return Object.keys(BEDROCK_REGION_INFO) - } - private static getPrefixForRegion(region: string): string | undefined { - for (const [prefix, info] of Object.entries(BEDROCK_REGION_INFO)) { - if (info.pattern && region.startsWith(info.pattern)) { - return prefix + // Use AWS recommended inference profile prefixes + // Array is pre-sorted by pattern length (descending) to ensure more specific patterns match first + for (const [regionPattern, inferenceProfile] of AWS_INFERENCE_PROFILE_MAPPING) { + if (region.startsWith(regionPattern)) { + return inferenceProfile } } + return undefined } - private static prefixIsMultiRegion(arnPrefix: string): boolean { - for (const [prefix, info] of Object.entries(BEDROCK_REGION_INFO)) { - if (arnPrefix === prefix) { - if (info?.multiRegion) return info.multiRegion - else return false + private static isSystemInferenceProfile(prefix: string): boolean { + // Check if the prefix is defined in AWS_INFERENCE_PROFILE_MAPPING + for (const [_, inferenceProfile] of AWS_INFERENCE_PROFILE_MAPPING) { + if (prefix === inferenceProfile) { + return true } } return false From 904e956179c266b6bfbd2d701a2c20333622c952 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Mon, 30 Jun 2025 08:53:55 -0600 Subject: [PATCH 37/70] feat: add persistent version indicator on chat screen (#5115) (#5128) Co-authored-by: Daniel Riccio --- webview-ui/src/components/chat/ChatView.tsx | 18 ++- .../chat/__tests__/ChatView.spec.tsx | 115 ++++++++++++++++++ .../components/common/VersionIndicator.tsx | 23 ++++ webview-ui/src/i18n/locales/ca/chat.json | 3 + webview-ui/src/i18n/locales/de/chat.json | 3 + webview-ui/src/i18n/locales/en/chat.json | 3 + webview-ui/src/i18n/locales/es/chat.json | 3 + webview-ui/src/i18n/locales/fr/chat.json | 3 + webview-ui/src/i18n/locales/hi/chat.json | 3 + webview-ui/src/i18n/locales/id/chat.json | 3 + webview-ui/src/i18n/locales/it/chat.json | 3 + webview-ui/src/i18n/locales/ja/chat.json | 3 + webview-ui/src/i18n/locales/ko/chat.json | 3 + webview-ui/src/i18n/locales/nl/chat.json | 3 + webview-ui/src/i18n/locales/pl/chat.json | 3 + webview-ui/src/i18n/locales/pt-BR/chat.json | 3 + webview-ui/src/i18n/locales/ru/chat.json | 3 + webview-ui/src/i18n/locales/tr/chat.json | 3 + webview-ui/src/i18n/locales/vi/chat.json | 3 + webview-ui/src/i18n/locales/zh-CN/chat.json | 3 + webview-ui/src/i18n/locales/zh-TW/chat.json | 3 + 21 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 webview-ui/src/components/common/VersionIndicator.tsx diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index a4f18c870c..e9c5a17415 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -33,6 +33,7 @@ import RooTips from "@src/components/welcome/RooTips" import { StandardTooltip } from "@src/components/ui" import TelemetryBanner from "../common/TelemetryBanner" +import VersionIndicator from "../common/VersionIndicator" import { useTaskSearch } from "../history/useTaskSearch" import HistoryPreview from "../history/HistoryPreview" import Announcement from "./Announcement" @@ -151,6 +152,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction(false) const [showCheckpointWarning, setShowCheckpointWarning] = useState(false) const [isCondensing, setIsCondensing] = useState(false) + const [showAnnouncementModal, setShowAnnouncementModal] = useState(false) const everVisibleMessagesTsRef = useRef>( new LRUCache({ max: 250, @@ -1365,7 +1367,21 @@ const ChatViewComponent: React.ForwardRefRenderFunction - {showAnnouncement && } + {/* Version indicator in top-right corner */} + setShowAnnouncementModal(true)} className="absolute top-2 right-3 z-10" /> + + {(showAnnouncement || showAnnouncementModal) && ( + { + if (showAnnouncementModal) { + setShowAnnouncementModal(false) + } + if (showAnnouncement) { + hideAnnouncement() + } + }} + /> + )} {task ? ( <> ({ default: () => null, })) +vi.mock("@src/components/common/VersionIndicator", () => ({ + default: function MockVersionIndicator({ onClick, className }: { onClick: () => void; className?: string }) { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const React = require("react") + return React.createElement( + "button", + { + onClick, + className, + "aria-label": "chat:versionIndicator.ariaLabel", + "data-testid": "version-indicator", + }, + "v3.21.5", + ) + }, +})) + +vi.mock("@src/components/modals/Announcement", () => ({ + default: function MockAnnouncement({ hideAnnouncement }: { hideAnnouncement: () => void }) { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const React = require("react") + return React.createElement( + "div", + { "data-testid": "announcement-modal" }, + React.createElement("div", null, "What's New"), + React.createElement("button", { onClick: hideAnnouncement }, "Close"), + ) + }, +})) + +// Mock i18n +vi.mock("react-i18next", () => ({ + useTranslation: () => ({ + t: (key: string, options?: any) => { + if (key === "chat:versionIndicator.ariaLabel" && options?.version) { + return `Version ${options.version}` + } + return key + }, + }), + initReactI18next: { + type: "3rdParty", + init: () => {}, + }, + Trans: ({ i18nKey, children }: { i18nKey: string; children?: React.ReactNode }) => { + return <>{children || i18nKey} + }, +})) + interface ChatTextAreaProps { onSend: (value: string) => void inputValue?: string @@ -1068,3 +1117,69 @@ describe("ChatView - Focus Grabbing Tests", () => { expect(mockFocus).toHaveBeenCalledTimes(FOCUS_CALLS_ON_INIT) }) }) + +describe("ChatView - Version Indicator Tests", () => { + beforeEach(() => vi.clearAllMocks()) + + it("displays version indicator button", () => { + const { getByLabelText } = renderChatView() + + // First hydrate state + mockPostMessage({ + clineMessages: [], + }) + + // Check that version indicator is displayed + const versionButton = getByLabelText(/version/i) + expect(versionButton).toBeInTheDocument() + expect(versionButton).toHaveTextContent(/^v\d+\.\d+\.\d+/) + }) + + it("opens announcement modal when version indicator is clicked", () => { + const { container } = renderChatView() + + // First hydrate state + mockPostMessage({ + clineMessages: [], + }) + + // Find version indicator + const versionButton = container.querySelector('button[aria-label*="version"]') as HTMLButtonElement + expect(versionButton).toBeTruthy() + + // Click should trigger modal - we'll just verify the button exists and is clickable + // The actual modal rendering is handled by the component state + expect(versionButton.onclick).toBeDefined() + }) + + it("version indicator has correct styling classes", () => { + const { getByTestId } = renderChatView() + + // First hydrate state + mockPostMessage({ + clineMessages: [], + }) + + // Check styling classes - the VersionIndicator component receives className prop + const versionButton = getByTestId("version-indicator") + expect(versionButton).toBeInTheDocument() + // The className is passed as a prop to VersionIndicator + expect(versionButton.className).toContain("absolute top-2 right-3 z-10") + }) + + it("version indicator has proper accessibility attributes", () => { + const { container } = renderChatView() + + // First hydrate state + mockPostMessage({ + clineMessages: [], + }) + + // Check accessibility - find button by its content + const versionButton = container.querySelector('button[aria-label*="version"]') + expect(versionButton).toBeTruthy() + expect(versionButton).toHaveAttribute("aria-label") + // The mock returns the key, so we check for that + expect(versionButton?.getAttribute("aria-label")).toBe("chat:versionIndicator.ariaLabel") + }) +}) diff --git a/webview-ui/src/components/common/VersionIndicator.tsx b/webview-ui/src/components/common/VersionIndicator.tsx new file mode 100644 index 0000000000..b0c517fdaf --- /dev/null +++ b/webview-ui/src/components/common/VersionIndicator.tsx @@ -0,0 +1,23 @@ +import React from "react" +import { useTranslation } from "react-i18next" +import { Package } from "@roo/package" + +interface VersionIndicatorProps { + onClick: () => void + className?: string +} + +const VersionIndicator: React.FC = ({ onClick, className = "" }) => { + const { t } = useTranslation() + + return ( + + ) +} + +export default VersionIndicator diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 4db48e40f3..07f1e25b53 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -310,5 +310,8 @@ "indexed": "Indexat", "error": "Error d'รญndex", "status": "Estat de l'รญndex" + }, + "versionIndicator": { + "ariaLabel": "Versiรณ {{version}} - Feu clic per veure les notes de llanรงament" } } diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index 3ee69f9ae4..b5c2336e46 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -310,5 +310,8 @@ "indexed": "Indiziert", "error": "Index-Fehler", "status": "Index-Status" + }, + "versionIndicator": { + "ariaLabel": "Version {{version}} - Klicken Sie, um die Versionshinweise anzuzeigen" } } diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 9ee8e167bd..3e5c2bfc60 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -310,5 +310,8 @@ "indexed": "Indexed", "error": "Index error", "status": "Index status" + }, + "versionIndicator": { + "ariaLabel": "Version {{version}} - Click to view release notes" } } diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index 7072d0ea16..db90a70057 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -310,5 +310,8 @@ "indexed": "Indexado", "error": "Error de รญndice", "status": "Estado del รญndice" + }, + "versionIndicator": { + "ariaLabel": "Versiรณn {{version}} - Haz clic para ver las notas de la versiรณn" } } diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 25d5074f45..b0d20bc7b2 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -310,5 +310,8 @@ "indexed": "Indexรฉ", "error": "Erreur d'index", "status": "Statut de l'index" + }, + "versionIndicator": { + "ariaLabel": "Version {{version}} - Cliquez pour voir les notes de version" } } diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index e67068d090..24e2af1eb7 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -310,5 +310,8 @@ "indexed": "เค‡เค‚เคกเฅ‡เค•เฅเคธ เค•เคฟเคฏเคพ เค—เคฏเคพ", "error": "เค‡เค‚เคกเฅ‡เค•เฅเคธ เคคเฅเคฐเฅเคŸเคฟ", "status": "เค‡เค‚เคกเฅ‡เค•เฅเคธ เคธเฅเคฅเคฟเคคเคฟ" + }, + "versionIndicator": { + "ariaLabel": "เคธเค‚เคธเฅเค•เคฐเคฃ {{version}} - เคฐเคฟเคฒเฅ€เคœเคผ เคจเฅ‹เคŸเฅเคธ เคฆเฅ‡เค–เคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค•เฅเคฒเคฟเค• เค•เคฐเฅ‡เค‚" } } diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index 259665a406..0568b58913 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -316,5 +316,8 @@ "indexed": "Terindeks", "error": "Error indeks", "status": "Status indeks" + }, + "versionIndicator": { + "ariaLabel": "Versi {{version}} - Klik untuk melihat catatan rilis" } } diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index bbf8c8be6a..1f7d6b463f 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -310,5 +310,8 @@ "indexed": "Indicizzato", "error": "Errore indice", "status": "Stato indice" + }, + "versionIndicator": { + "ariaLabel": "Versione {{version}} - Clicca per visualizzare le note di rilascio" } } diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index 0278edd4b6..255acb717f 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -310,5 +310,8 @@ "indexed": "ใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚นไฝœๆˆๆธˆใฟ", "error": "ใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚นใ‚จใƒฉใƒผ", "status": "ใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚น็Šถๆ…‹" + }, + "versionIndicator": { + "ariaLabel": "ใƒใƒผใ‚ธใƒงใƒณ {{version}} - ใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆใƒชใƒชใƒผใ‚นใƒŽใƒผใƒˆใ‚’่กจ็คบ" } } diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 5373831426..b83c400574 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -310,5 +310,8 @@ "indexed": "์ธ๋ฑ์‹ฑ ์™„๋ฃŒ", "error": "์ธ๋ฑ์Šค ์˜ค๋ฅ˜", "status": "์ธ๋ฑ์Šค ์ƒํƒœ" + }, + "versionIndicator": { + "ariaLabel": "๋ฒ„์ „ {{version}} - ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ๋ฅผ ๋ณด๋ ค๋ฉด ํด๋ฆญํ•˜์„ธ์š”" } } diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index 2dc60da09e..4b6877389d 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -310,5 +310,8 @@ "indexed": "Geรฏndexeerd", "error": "Index fout", "status": "Index status" + }, + "versionIndicator": { + "ariaLabel": "Versie {{version}} - Klik om release notes te bekijken" } } diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index 0af70c595b..fe1a47156a 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -310,5 +310,8 @@ "indexed": "Zaindeksowane", "error": "Bล‚ฤ…d indeksu", "status": "Status indeksu" + }, + "versionIndicator": { + "ariaLabel": "Wersja {{version}} - Kliknij, aby wyล›wietliฤ‡ informacje o wydaniu" } } diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index a09f8174f6..f8dd3542c0 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -310,5 +310,8 @@ "indexed": "Indexado", "error": "Erro do รญndice", "status": "Status do รญndice" + }, + "versionIndicator": { + "ariaLabel": "Versรฃo {{version}} - Clique para ver as notas de lanรงamento" } } diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index 89d35f322a..b07d8d49f7 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -310,5 +310,8 @@ "indexed": "ะŸั€ะพะธะฝะดะตะบัะธั€ะพะฒะฐะฝะพ", "error": "ะžัˆะธะฑะบะฐ ะธะฝะดะตะบัะฐ", "status": "ะกั‚ะฐั‚ัƒั ะธะฝะดะตะบัะฐ" + }, + "versionIndicator": { + "ariaLabel": "ะ’ะตั€ัะธั {{version}} - ะะฐะถะผะธั‚ะต, ั‡ั‚ะพะฑั‹ ะฟั€ะพัะผะพั‚ั€ะตั‚ัŒ ะฟั€ะธะผะตั‡ะฐะฝะธั ะบ ะฒั‹ะฟัƒัะบัƒ" } } diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index f12fa62bbb..f5625842b1 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -310,5 +310,8 @@ "indexed": "ฤฐndekslendi", "error": "ฤฐndeks hatasฤฑ", "status": "ฤฐndeks durumu" + }, + "versionIndicator": { + "ariaLabel": "Sรผrรผm {{version}} - Sรผrรผm notlarฤฑnฤฑ gรถrรผntรผlemek iรงin tฤฑklayฤฑn" } } diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index c2338e33aa..05f9ed8a3d 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -310,5 +310,8 @@ "indexed": "ฤรฃ lแบญp chแป‰ mแปฅc", "error": "Lแป—i chแป‰ mแปฅc", "status": "Trแบกng thรกi chแป‰ mแปฅc" + }, + "versionIndicator": { + "ariaLabel": "Phiรชn bแบฃn {{version}} - Nhแบฅp ฤ‘แปƒ xem ghi chรบ phรกt hร nh" } } diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index f3fb857f06..d85c633699 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -310,5 +310,8 @@ "indexed": "ๅทฒ็ดขๅผ•", "error": "็ดขๅผ•้”™่ฏฏ", "status": "็ดขๅผ•็Šถๆ€" + }, + "versionIndicator": { + "ariaLabel": "็‰ˆๆœฌ {{version}} - ็‚นๅ‡ปๆŸฅ็œ‹ๅ‘ๅธƒ่ฏดๆ˜Ž" } } diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 9a20f129a3..b3659f6869 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -310,5 +310,8 @@ "indexed": "ๅทฒ็ดขๅผ•", "error": "็ดขๅผ•้Œฏ่ชค", "status": "็ดขๅผ•็‹€ๆ…‹" + }, + "versionIndicator": { + "ariaLabel": "็‰ˆๆœฌ {{version}} - ้ปžๆ“ŠๆŸฅ็œ‹็™ผๅธƒ่ชชๆ˜Ž" } } From b9626a7eff2cee95451e40d87c5156e80a08819e Mon Sep 17 00:00:00 2001 From: Murilo Pires <50873657+MuriloFP@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:56:34 -0300 Subject: [PATCH 38/70] fix: cap API retry exponential backoff at 10 minutes (#5171) Co-authored-by: Daniel Riccio --- src/core/task/Task.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index bc7cd31f26..4f0d32c8c1 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -86,6 +86,9 @@ import { ApiMessage } from "../task-persistence/apiMessages" import { getMessagesSinceLastSummary, summarizeConversation } from "../condense" import { maybeRemoveImageBlocks } from "../../api/transform/image-cleaning" +// Constants +const MAX_EXPONENTIAL_BACKOFF_SECONDS = 600 // 10 minutes + export type ClineEvents = { message: [{ action: "created" | "updated"; message: ClineMessage }] taskStarted: [] @@ -1799,7 +1802,10 @@ export class Task extends EventEmitter { } const baseDelay = requestDelaySeconds || 5 - let exponentialDelay = Math.ceil(baseDelay * Math.pow(2, retryAttempt)) + let exponentialDelay = Math.min( + Math.ceil(baseDelay * Math.pow(2, retryAttempt)), + MAX_EXPONENTIAL_BACKOFF_SECONDS, + ) // If the error is a 429, and the error details contain a retry delay, use that delay instead of exponential backoff if (error.status === 429) { From 24eb6e4c290ce01a968742cc4ff383483323e901 Mon Sep 17 00:00:00 2001 From: SannidhyaSah Date: Mon, 30 Jun 2025 20:26:49 +0530 Subject: [PATCH 39/70] fix: prevent Qdrant URL field from auto-filling with default value (#5217) Co-authored-by: Daniel Riccio --- .../src/components/settings/CodeIndexSettings.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/webview-ui/src/components/settings/CodeIndexSettings.tsx b/webview-ui/src/components/settings/CodeIndexSettings.tsx index 13c9524d9f..f385ae2bc6 100644 --- a/webview-ui/src/components/settings/CodeIndexSettings.tsx +++ b/webview-ui/src/components/settings/CodeIndexSettings.tsx @@ -51,6 +51,7 @@ export const CodeIndexSettings: React.FC = ({ areSettingsCommitted, }) => { const { t } = useAppTranslation() + const DEFAULT_QDRANT_URL = "http://localhost:6333" const [indexingStatus, setIndexingStatus] = useState({ systemStatus: "Standby", message: "", @@ -425,13 +426,23 @@ export const CodeIndexSettings: React.FC = ({
setCachedStateField("codebaseIndexConfig", { ...codebaseIndexConfig, codebaseIndexQdrantUrl: e.target.value, }) } + onBlur={(e: any) => { + // Set default value if field is empty on blur + if (!e.target.value) { + setCachedStateField("codebaseIndexConfig", { + ...codebaseIndexConfig, + codebaseIndexQdrantUrl: DEFAULT_QDRANT_URL, + }) + } + }} style={{ width: "100%" }}>
From 298908fe1d6315c909a944dd439d6ead4aae1e80 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Mon, 30 Jun 2025 12:07:00 -0600 Subject: [PATCH 40/70] fix: ensure VersionIndicator only shows on welcome screen (#5288) Co-authored-by: Daniel Riccio --- webview-ui/src/components/chat/ChatView.tsx | 11 +- .../chat/__tests__/ChatView.spec.tsx | 145 +++++++++++++++--- 2 files changed, 127 insertions(+), 29 deletions(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index e9c5a17415..85770c82c5 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -1367,9 +1367,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction - {/* Version indicator in top-right corner */} - setShowAnnouncementModal(true)} className="absolute top-2 right-3 z-10" /> - {(showAnnouncement || showAnnouncementModal) && ( { @@ -1410,7 +1407,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction ) : ( -
+
{/* Moved Task Bar Header Here */} {tasks.length !== 0 && (
@@ -1426,6 +1423,12 @@ const ChatViewComponent: React.ForwardRefRenderFunction 0 ? "mt-0" : ""} px-3.5 min-[370px]:px-10 pt-5 transition-all duration-300`}> + {/* Version indicator in top-right corner - only on welcome screen */} + setShowAnnouncementModal(true)} + className="absolute top-2 right-3 z-10" + /> + {telemetrySetting === "unset" && } {/* Show the task history preview if expanded and tasks exist */} diff --git a/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx b/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx index e4d3c8635c..0343cb6c96 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx @@ -61,23 +61,17 @@ vi.mock("../AutoApproveMenu", () => ({ default: () => null, })) -vi.mock("@src/components/common/VersionIndicator", () => ({ - default: function MockVersionIndicator({ onClick, className }: { onClick: () => void; className?: string }) { - // eslint-disable-next-line @typescript-eslint/no-require-imports - const React = require("react") - return React.createElement( - "button", - { - onClick, - className, - "aria-label": "chat:versionIndicator.ariaLabel", - "data-testid": "version-indicator", - }, - "v3.21.5", - ) - }, +// Mock VersionIndicator - returns null by default to prevent rendering in tests +vi.mock("../../common/VersionIndicator", () => ({ + default: vi.fn(() => null), })) +// Get the mock function after the module is mocked +const mockVersionIndicator = vi.mocked( + // @ts-expect-error - accessing mocked module + (await import("../../common/VersionIndicator")).default, +) + vi.mock("@src/components/modals/Announcement", () => ({ default: function MockAnnouncement({ hideAnnouncement }: { hideAnnouncement: () => void }) { // eslint-disable-next-line @typescript-eslint/no-require-imports @@ -1121,7 +1115,25 @@ describe("ChatView - Focus Grabbing Tests", () => { describe("ChatView - Version Indicator Tests", () => { beforeEach(() => vi.clearAllMocks()) + // Helper function to create a mock VersionIndicator implementation + const createMockVersionIndicator = ( + ariaLabel: string = "chat:versionIndicator.ariaLabel", + version: string = "v3.21.5", + ) => { + return (props?: { onClick?: () => void; className?: string }) => { + const { onClick, className } = props || {} + return ( + + ) + } + } + it("displays version indicator button", () => { + // Temporarily override the mock for this test + mockVersionIndicator.mockImplementation(createMockVersionIndicator()) + const { getByLabelText } = renderChatView() // First hydrate state @@ -1133,10 +1145,16 @@ describe("ChatView - Version Indicator Tests", () => { const versionButton = getByLabelText(/version/i) expect(versionButton).toBeInTheDocument() expect(versionButton).toHaveTextContent(/^v\d+\.\d+\.\d+/) + + // Reset mock + mockVersionIndicator.mockReturnValue(null) }) it("opens announcement modal when version indicator is clicked", () => { - const { container } = renderChatView() + // Temporarily override the mock for this test + mockVersionIndicator.mockImplementation(createMockVersionIndicator("Version 3.22.5", "v3.22.5")) + + const { getByTestId } = renderChatView() // First hydrate state mockPostMessage({ @@ -1144,15 +1162,21 @@ describe("ChatView - Version Indicator Tests", () => { }) // Find version indicator - const versionButton = container.querySelector('button[aria-label*="version"]') as HTMLButtonElement - expect(versionButton).toBeTruthy() + const versionButton = getByTestId("version-indicator") + expect(versionButton).toBeInTheDocument() // Click should trigger modal - we'll just verify the button exists and is clickable // The actual modal rendering is handled by the component state expect(versionButton.onclick).toBeDefined() + + // Reset mock + mockVersionIndicator.mockReturnValue(null) }) it("version indicator has correct styling classes", () => { + // Temporarily override the mock for this test + mockVersionIndicator.mockImplementation(createMockVersionIndicator("Version 3.22.5", "v3.22.5")) + const { getByTestId } = renderChatView() // First hydrate state @@ -1165,21 +1189,92 @@ describe("ChatView - Version Indicator Tests", () => { expect(versionButton).toBeInTheDocument() // The className is passed as a prop to VersionIndicator expect(versionButton.className).toContain("absolute top-2 right-3 z-10") + + // Reset mock + mockVersionIndicator.mockReturnValue(null) }) it("version indicator has proper accessibility attributes", () => { - const { container } = renderChatView() + // Temporarily override the mock for this test + mockVersionIndicator.mockImplementation(createMockVersionIndicator("Version 3.22.5", "v3.22.5")) + + const { getByTestId } = renderChatView() // First hydrate state mockPostMessage({ clineMessages: [], }) - // Check accessibility - find button by its content - const versionButton = container.querySelector('button[aria-label*="version"]') - expect(versionButton).toBeTruthy() - expect(versionButton).toHaveAttribute("aria-label") - // The mock returns the key, so we check for that - expect(versionButton?.getAttribute("aria-label")).toBe("chat:versionIndicator.ariaLabel") + // Check accessibility + const versionButton = getByTestId("version-indicator") + expect(versionButton).toBeInTheDocument() + expect(versionButton).toHaveAttribute("aria-label", "Version 3.22.5") + + // Reset mock + mockVersionIndicator.mockReturnValue(null) + }) + + it("does not display version indicator when there is an active task", () => { + const { queryByTestId } = renderChatView() + + // Hydrate state with an active task - any message in the array makes task truthy + mockPostMessage({ + clineMessages: [ + { + type: "say", + say: "task", + ts: Date.now(), + text: "Active task in progress", + }, + ], + }) + + // Version indicator should not be present during task execution + const versionButton = queryByTestId("version-indicator") + expect(versionButton).not.toBeInTheDocument() + }) + + it("displays version indicator only on welcome screen (no task)", () => { + // Temporarily override the mock for this test + mockVersionIndicator.mockImplementation(createMockVersionIndicator("Version 3.22.5", "v3.22.5")) + + const { queryByTestId, rerender } = renderChatView() + + // First, hydrate with no messages (welcome screen) + mockPostMessage({ + clineMessages: [], + }) + + // Version indicator should be present + let versionButton = queryByTestId("version-indicator") + expect(versionButton).toBeInTheDocument() + + // Reset mock to return null for the second part of the test + mockVersionIndicator.mockReturnValue(null) + + // Now add a task - any message makes task truthy + mockPostMessage({ + clineMessages: [ + { + type: "say", + say: "task", + ts: Date.now(), + text: "Starting a new task", + }, + ], + }) + + // Force a re-render to ensure the component updates + rerender( + + + + + , + ) + + // Version indicator should disappear + versionButton = queryByTestId("version-indicator") + expect(versionButton).not.toBeInTheDocument() }) }) From 18c3f5dc3321cbb33ec5b4daa22caa5ea855a670 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Mon, 30 Jun 2025 15:46:56 -0600 Subject: [PATCH 41/70] feat: change default mode to architect for new installations (#5289) * feat: change default mode to architect for new installations - Reordered modes array to put architect mode first - Updated test to reflect architect as the default mode - Maintains backward compatibility for existing users * test: update snapshots and fix tests for architect default mode - Update all snapshot tests to reflect architect as the default mode - Fix mode destructuring in validateToolUse tests - All tests now pass with the new default mode configuration * docs: add comment explaining mode ordering for default selection Addresses PR review feedback to clarify that the first mode in the array serves as the default for new installations * fix: Update integration test to use lowercase mode name The test was using 'Ask' (capitalized) but modes are now lowercase 'ask'. This was causing the test to timeout as the mode validation failed. --- apps/vscode-e2e/src/suite/task.test.ts | 2 +- .../architect-mode-rules.snap | 2 +- .../code-mode-rules.snap | 2 +- .../combined-custom-instructions.snap | 2 +- .../empty-mode-instructions.snap | 2 +- .../generic-rules-fallback.snap | 2 +- .../global-and-mode-instructions.snap | 2 +- .../mcp-server-creation-disabled.snap | 39 +++++++------------ .../mcp-server-creation-enabled.snap | 39 +++++++------------ .../partial-reads-enabled.snap | 39 +++++++------------ .../prioritized-instructions-order.snap | 2 +- .../trimmed-mode-instructions.snap | 2 +- .../undefined-mode-instructions.snap | 2 +- .../with-custom-instructions.snap | 2 +- .../with-preferred-language.snap | 2 +- .../consistent-system-prompt.snap | 39 +++++++------------ .../with-computer-use-support.snap | 39 +++++++------------ .../with-diff-enabled-false.snap | 39 +++++++------------ .../system-prompt/with-diff-enabled-true.snap | 39 +++++++------------ .../with-diff-enabled-undefined.snap | 39 +++++++------------ .../with-different-viewport-size.snap | 39 +++++++------------ .../system-prompt/with-mcp-hub-provided.snap | 39 +++++++------------ .../system-prompt/with-undefined-mcp-hub.snap | 39 +++++++------------ .../tools/__tests__/validateToolUse.spec.ts | 4 +- src/shared/__tests__/modes.spec.ts | 2 +- src/shared/modes.ts | 21 +++++----- 26 files changed, 192 insertions(+), 288 deletions(-) diff --git a/apps/vscode-e2e/src/suite/task.test.ts b/apps/vscode-e2e/src/suite/task.test.ts index 96b1198fd4..31e03271b5 100644 --- a/apps/vscode-e2e/src/suite/task.test.ts +++ b/apps/vscode-e2e/src/suite/task.test.ts @@ -20,7 +20,7 @@ suite("Roo Code Task", function () { }) const taskId = await api.startNewTask({ - configuration: { mode: "Ask", alwaysAllowModeSwitch: true, autoApprovalEnabled: true }, + configuration: { mode: "ask", alwaysAllowModeSwitch: true, autoApprovalEnabled: true }, text: "Hello world, what is your name? Respond with 'My name is ...'", }) diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-rules.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-rules.snap index 8a4da6613d..1935611f44 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-rules.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-rules.snap @@ -6,7 +6,7 @@ USER'S CUSTOM INSTRUCTIONS The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. Rules: -# Rules from .clinerules-architect: +# Rules from .clinerules-code: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/code-mode-rules.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/code-mode-rules.snap index 1935611f44..8a4da6613d 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/code-mode-rules.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/code-mode-rules.snap @@ -6,7 +6,7 @@ USER'S CUSTOM INSTRUCTIONS The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/combined-custom-instructions.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/combined-custom-instructions.snap index d9e638e9fa..2a2c4ba78a 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/combined-custom-instructions.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/combined-custom-instructions.snap @@ -12,7 +12,7 @@ Mode-specific Instructions: Custom test instructions Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/empty-mode-instructions.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/empty-mode-instructions.snap index 1935611f44..8a4da6613d 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/empty-mode-instructions.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/empty-mode-instructions.snap @@ -6,7 +6,7 @@ USER'S CUSTOM INSTRUCTIONS The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/generic-rules-fallback.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/generic-rules-fallback.snap index 1935611f44..8a4da6613d 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/generic-rules-fallback.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/generic-rules-fallback.snap @@ -6,7 +6,7 @@ USER'S CUSTOM INSTRUCTIONS The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/global-and-mode-instructions.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/global-and-mode-instructions.snap index 2fb6cfece2..f4cd5cbec9 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/global-and-mode-instructions.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/global-and-mode-instructions.snap @@ -12,7 +12,7 @@ Mode-specific Instructions: Mode-specific instructions Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap index bf9a0ef02f..7bed96ad21 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -269,28 +269,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## use_mcp_tool Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. Parameters: @@ -558,8 +536,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap index 7b3e18690c..b3032babad 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -269,28 +269,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## use_mcp_tool Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. Parameters: @@ -564,8 +542,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap index b77b77e1e2..66eeae3e7e 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -274,28 +274,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -501,8 +479,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/prioritized-instructions-order.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/prioritized-instructions-order.snap index 5adfbb744e..b72616ec3c 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/prioritized-instructions-order.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/prioritized-instructions-order.snap @@ -12,7 +12,7 @@ Mode-specific Instructions: Second instruction Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/trimmed-mode-instructions.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/trimmed-mode-instructions.snap index 28497df14f..18dc9547ab 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/trimmed-mode-instructions.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/trimmed-mode-instructions.snap @@ -9,7 +9,7 @@ Mode-specific Instructions: Custom mode instructions Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/undefined-mode-instructions.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/undefined-mode-instructions.snap index 1935611f44..8a4da6613d 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/undefined-mode-instructions.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/undefined-mode-instructions.snap @@ -6,7 +6,7 @@ USER'S CUSTOM INSTRUCTIONS The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/with-custom-instructions.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/with-custom-instructions.snap index 9ee1dd3365..9e1f02ec2f 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/with-custom-instructions.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/with-custom-instructions.snap @@ -9,7 +9,7 @@ Mode-specific Instructions: Custom test instructions Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/with-preferred-language.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/with-preferred-language.snap index 2fba8f9cbb..c563fa36fb 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/with-preferred-language.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/with-preferred-language.snap @@ -9,7 +9,7 @@ Language Preference: You should always speak and think in the "es" language. Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap index 2f2a41916d..98ef98fcad 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -269,28 +269,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -496,8 +474,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap index 1cf0529e19..a525fba656 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -322,28 +322,6 @@ Example: Requesting to click on the element at coordinates 450,300 450,300 -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -552,8 +530,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap index 2f2a41916d..98ef98fcad 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -269,28 +269,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -496,8 +474,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap index 744cadfab4..e6b1dc7a85 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -357,28 +357,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -584,8 +562,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap index 2f2a41916d..98ef98fcad 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -269,28 +269,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -496,8 +474,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap index 28b31eefcf..25cf8be089 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -322,28 +322,6 @@ Example: Requesting to click on the element at coordinates 450,300 450,300 -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -552,8 +530,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap index 7b3e18690c..b3032babad 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -269,28 +269,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## use_mcp_tool Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. Parameters: @@ -564,8 +542,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap index 2f2a41916d..98ef98fcad 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap @@ -1,4 +1,4 @@ -You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. +You are Roo, an experienced technical leader who is inquisitive and an excellent planner. Your goal is to gather information and get context to create a detailed plan for accomplishing the user's task, which the user will review and approve before they switch into another mode to implement the solution. ==== @@ -269,28 +269,6 @@ Examples: true -## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: `touch ./testdata/example.file`, `dir ./examples/model1/data/yaml`, or `go test ./cmd/front --config ./cmd/front/config.yml`. If directed by the user, you may open a terminal in a different directory by using the `cwd` parameter. -Parameters: -- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. -- cwd: (optional) The working directory to execute the command in (default: /test/path) -Usage: - -Your command here -Working directory path (optional) - - -Example: Requesting to execute npm run dev - -npm run dev - - -Example: Requesting to execute ls in a specific directory if directed - -ls -la -/home/user/projects - - ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -496,8 +474,21 @@ The following additional instructions are provided by the user, and should be fo Language Preference: You should always speak and think in the "en" language. +Mode-specific Instructions: +1. Do some information gathering (for example using read_file or search_files) to get more context about the task. + +2. You should also ask the user clarifying questions to get a better understanding of the task. + +3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. + +4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. + +5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. + +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + Rules: -# Rules from .clinerules-code: +# Rules from .clinerules-architect: Mock mode-specific rules # Rules from .clinerules: Mock generic rules \ No newline at end of file diff --git a/src/core/tools/__tests__/validateToolUse.spec.ts b/src/core/tools/__tests__/validateToolUse.spec.ts index 89d03fea70..7802674605 100644 --- a/src/core/tools/__tests__/validateToolUse.spec.ts +++ b/src/core/tools/__tests__/validateToolUse.spec.ts @@ -7,7 +7,9 @@ import { TOOL_GROUPS } from "../../../shared/tools" import { validateToolUse } from "../validateToolUse" -const [codeMode, architectMode, askMode] = modes.map((mode) => mode.slug) +const codeMode = modes.find((m) => m.slug === "code")?.slug || "code" +const architectMode = modes.find((m) => m.slug === "architect")?.slug || "architect" +const askMode = modes.find((m) => m.slug === "ask")?.slug || "ask" describe("mode-validator", () => { describe("isToolAllowedForMode", () => { diff --git a/src/shared/__tests__/modes.spec.ts b/src/shared/__tests__/modes.spec.ts index 8ca7eec150..acf7da84c8 100644 --- a/src/shared/__tests__/modes.spec.ts +++ b/src/shared/__tests__/modes.spec.ts @@ -356,7 +356,7 @@ describe("FileRestrictionError", () => { const result = await getFullModeDetails("non-existent") expect(result).toMatchObject({ ...modes[0], - customInstructions: "", + // The first mode (architect) has its own customInstructions }) }) }) diff --git a/src/shared/modes.ts b/src/shared/modes.ts index 53bc2369db..47387551ff 100644 --- a/src/shared/modes.ts +++ b/src/shared/modes.ts @@ -60,17 +60,8 @@ export function getToolsForMode(groups: readonly GroupEntry[]): string[] { } // Main modes configuration as an ordered array +// Note: The first mode in this array is the default mode for new installations export const modes: readonly ModeConfig[] = [ - { - slug: "code", - name: "๐Ÿ’ป Code", - roleDefinition: - "You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.", - whenToUse: - "Use this mode when you need to write, modify, or refactor code. Ideal for implementing features, fixing bugs, creating new files, or making code improvements across any programming language or framework.", - description: "Write, modify, and refactor code", - groups: ["read", "edit", "browser", "command", "mcp"], - }, { slug: "architect", name: "๐Ÿ—๏ธ Architect", @@ -83,6 +74,16 @@ export const modes: readonly ModeConfig[] = [ customInstructions: "1. Do some information gathering (for example using read_file or search_files) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.\n\n4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.\n\n5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file.\n\n6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.", }, + { + slug: "code", + name: "๐Ÿ’ป Code", + roleDefinition: + "You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.", + whenToUse: + "Use this mode when you need to write, modify, or refactor code. Ideal for implementing features, fixing bugs, creating new files, or making code improvements across any programming language or framework.", + description: "Write, modify, and refactor code", + groups: ["read", "edit", "browser", "command", "mcp"], + }, { slug: "ask", name: "โ“ Ask", From 569b276d93df80f002f4ff4bcd8924facf09cf3b Mon Sep 17 00:00:00 2001 From: Andrew Shu <57741937+andrewshu2000@users.noreply.github.com> Date: Tue, 1 Jul 2025 10:23:11 +1000 Subject: [PATCH 42/70] feat: adding default headers and testing for litellm fetcher (#5242) * chore: adding x-title header and testing for litellm * chore: indentation fi and headers order fix * chore: spacing fix * chore: removed white space * fix: allow user headers to override default headers and clean up formatting - Reorder header spread in router-provider.ts so user-provided openAiHeaders can override DEFAULT_HEADERS - Remove unnecessary blank lines after imports for consistency - This matches the pattern used in openai.ts where DEFAULT_HEADERS come first --------- Co-authored-by: Brendan-Z Co-authored-by: Daniel Riccio --- src/api/providers/fetchers/__tests__/litellm.spec.ts | 4 ++++ src/api/providers/fetchers/litellm.ts | 2 ++ src/api/providers/router-provider.ts | 11 ++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/api/providers/fetchers/__tests__/litellm.spec.ts b/src/api/providers/fetchers/__tests__/litellm.spec.ts index f4db3bc12e..07bbe9871a 100644 --- a/src/api/providers/fetchers/__tests__/litellm.spec.ts +++ b/src/api/providers/fetchers/__tests__/litellm.spec.ts @@ -4,6 +4,7 @@ vi.mock("axios") import type { Mock } from "vitest" import axios from "axios" import { getLiteLLMModels } from "../litellm" +import { DEFAULT_HEADERS } from "../../constants" const mockedAxios = axios as typeof axios & { get: Mock @@ -32,6 +33,7 @@ describe("getLiteLLMModels", () => { headers: { Authorization: "Bearer test-api-key", "Content-Type": "application/json", + ...DEFAULT_HEADERS, }, timeout: 5000, }) @@ -83,6 +85,7 @@ describe("getLiteLLMModels", () => { headers: { Authorization: "Bearer test-api-key", "Content-Type": "application/json", + ...DEFAULT_HEADERS, }, timeout: 5000, }) @@ -125,6 +128,7 @@ describe("getLiteLLMModels", () => { expect(mockedAxios.get).toHaveBeenCalledWith("http://localhost:4000/v1/model/info", { headers: { "Content-Type": "application/json", + ...DEFAULT_HEADERS, }, timeout: 5000, }) diff --git a/src/api/providers/fetchers/litellm.ts b/src/api/providers/fetchers/litellm.ts index 47617cd390..0891527406 100644 --- a/src/api/providers/fetchers/litellm.ts +++ b/src/api/providers/fetchers/litellm.ts @@ -4,6 +4,7 @@ import { LITELLM_COMPUTER_USE_MODELS } from "@roo-code/types" import type { ModelRecord } from "../../../shared/api" +import { DEFAULT_HEADERS } from "../constants" /** * Fetches available models from a LiteLLM server * @@ -16,6 +17,7 @@ export async function getLiteLLMModels(apiKey: string, baseUrl: string): Promise try { const headers: Record = { "Content-Type": "application/json", + ...DEFAULT_HEADERS, } if (apiKey) { diff --git a/src/api/providers/router-provider.ts b/src/api/providers/router-provider.ts index c64b29571a..25e9a11e1b 100644 --- a/src/api/providers/router-provider.ts +++ b/src/api/providers/router-provider.ts @@ -7,6 +7,8 @@ import { ApiHandlerOptions, RouterName, ModelRecord } from "../../shared/api" import { BaseProvider } from "./base-provider" import { getModels } from "./fetchers/modelCache" +import { DEFAULT_HEADERS } from "./constants" + type RouterProviderOptions = { name: RouterName baseURL: string @@ -43,7 +45,14 @@ export abstract class RouterProvider extends BaseProvider { this.defaultModelId = defaultModelId this.defaultModelInfo = defaultModelInfo - this.client = new OpenAI({ baseURL, apiKey }) + this.client = new OpenAI({ + baseURL, + apiKey, + defaultHeaders: { + ...DEFAULT_HEADERS, + ...(options.openAiHeaders || {}), + }, + }) } public async fetchModel() { From 951f2d0fad6dc7ae9fa41d229760b9f4379adba8 Mon Sep 17 00:00:00 2001 From: roomote Date: Tue, 1 Jul 2025 06:42:46 -0700 Subject: [PATCH 43/70] Fix #5294: Prevent Architect mode from providing time estimates (#5295) * Fixes #5294: Add instruction to Architect mode to avoid time estimates - Updated Architect mode custom instructions to explicitly prohibit providing time estimates - Added clear guidance to focus on actionable plans without speculating about implementation timeframes - Updated test snapshot to reflect the new instruction - All tests passing * More tweaks to prompt --------- Co-authored-by: Matt Rubens --- .../add-custom-instructions/architect-mode-prompt.snap | 4 ++-- .../add-custom-instructions/mcp-server-creation-disabled.snap | 4 ++-- .../add-custom-instructions/mcp-server-creation-enabled.snap | 4 ++-- .../add-custom-instructions/partial-reads-enabled.snap | 4 ++-- .../__snapshots__/system-prompt/consistent-system-prompt.snap | 4 ++-- .../system-prompt/with-computer-use-support.snap | 4 ++-- .../__snapshots__/system-prompt/with-diff-enabled-false.snap | 4 ++-- .../__snapshots__/system-prompt/with-diff-enabled-true.snap | 4 ++-- .../system-prompt/with-diff-enabled-undefined.snap | 4 ++-- .../system-prompt/with-different-viewport-size.snap | 4 ++-- .../__snapshots__/system-prompt/with-mcp-hub-provided.snap | 4 ++-- .../__snapshots__/system-prompt/with-undefined-mcp-hub.snap | 4 ++-- src/shared/modes.ts | 2 +- 13 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap index 98ef98fcad..47edfe467a 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap @@ -483,9 +483,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap index 7bed96ad21..c964d5f6ed 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap @@ -545,9 +545,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap index b3032babad..5a25768204 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap @@ -551,9 +551,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap index 66eeae3e7e..f74e394d2d 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap @@ -488,9 +488,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap index 98ef98fcad..47edfe467a 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap @@ -483,9 +483,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap index a525fba656..ecd22a6d6e 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap @@ -539,9 +539,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap index 98ef98fcad..47edfe467a 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap @@ -483,9 +483,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap index e6b1dc7a85..9514c93ea3 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap @@ -571,9 +571,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap index 98ef98fcad..47edfe467a 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap @@ -483,9 +483,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap index 25cf8be089..32acd4c169 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap @@ -539,9 +539,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap index b3032babad..5a25768204 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap @@ -551,9 +551,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap index 98ef98fcad..47edfe467a 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap @@ -483,9 +483,9 @@ Mode-specific Instructions: 4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. -5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file. +5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. -6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** Rules: # Rules from .clinerules-architect: diff --git a/src/shared/modes.ts b/src/shared/modes.ts index 47387551ff..23efdc45f7 100644 --- a/src/shared/modes.ts +++ b/src/shared/modes.ts @@ -72,7 +72,7 @@ export const modes: readonly ModeConfig[] = [ description: "Plan and design before implementation", groups: ["read", ["edit", { fileRegex: "\\.md$", description: "Markdown files only" }], "browser", "mcp"], customInstructions: - "1. Do some information gathering (for example using read_file or search_files) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.\n\n4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.\n\n5. Once the user confirms the plan, ask them if they'd like you to write it to a markdown file.\n\n6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.", + "1. Do some information gathering (for example using read_file or search_files) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.\n\n4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.\n\n5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**", }, { slug: "code", From 6b7cfdc6ac9b6d4755ec3606e8868336242ff89b Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Tue, 1 Jul 2025 08:32:23 -0600 Subject: [PATCH 44/70] feat: add translation workflow to issue-fixer mode (#5281) --- .roo/rules-issue-fixer/1_Workflow.xml | 70 ++++++++++++++++++--- .roo/rules-issue-fixer/2_best_practices.xml | 3 + 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/.roo/rules-issue-fixer/1_Workflow.xml b/.roo/rules-issue-fixer/1_Workflow.xml index 40971a1064..ed1e64be16 100644 --- a/.roo/rules-issue-fixer/1_Workflow.xml +++ b/.roo/rules-issue-fixer/1_Workflow.xml @@ -252,11 +252,63 @@ - [ ] No linting errors If any criteria fail, return to implementation step. - - - - - Run Tests and Checks + + + + + Check for Translation Requirements + + After implementing changes, analyze if any translations are required: + + Translation is needed if the implementation includes: + 1. New user-facing text strings in UI components + 2. New error messages or user notifications + 3. Updated documentation files that need localization + 4. New command descriptions or tooltips + 5. Changes to announcement files or release notes + 6. New configuration options with user-visible descriptions + + Check for these patterns: + - Hard-coded strings in React components (.tsx/.jsx files) + - New entries needed in i18n JSON files + - Updated markdown documentation files + - New VSCode command contributions + - Changes to user-facing configuration schemas + + If translations are required: + + + translate + Translation needed for issue #[issue-number] implementation. + + The following changes require translation into all supported languages: + + **Files with new/updated user-facing content:** + - [List specific files and what content needs translation] + - [Include context about where the strings appear] + - [Note any special formatting or constraints] + + **Translation scope:** + - [Specify if it's new strings, updated strings, or both] + - [List specific JSON keys that need attention] + - [Note any markdown files that need localization] + + **Context for translators:** + - [Explain the feature/fix being implemented] + - [Provide context about how the text is used] + - [Note any technical terms or constraints] + + Please ensure all translations maintain consistency with existing terminology and follow the project's localization guidelines. + + + Wait for the translation task to complete before proceeding to testing. + + If no translations are required, continue to the next step. + + + + + Run Tests and Checks Run comprehensive tests to ensure quality: @@ -289,7 +341,7 @@ - + Prepare Summary Create a comprehensive summary of the implementation: @@ -341,7 +393,7 @@ - + Prepare for Pull Request If user wants to create a pull request, prepare everything needed: @@ -429,7 +481,7 @@ - + Create Pull Request Once user approves, create the pull request using GitHub MCP: @@ -492,7 +544,7 @@ - + Monitor PR Checks After the PR is created, monitor the CI/CD checks to ensure they pass: diff --git a/.roo/rules-issue-fixer/2_best_practices.xml b/.roo/rules-issue-fixer/2_best_practices.xml index 7d3a87aa9a..dede40a92f 100644 --- a/.roo/rules-issue-fixer/2_best_practices.xml +++ b/.roo/rules-issue-fixer/2_best_practices.xml @@ -12,4 +12,7 @@ - Update documentation when needed - Add tests for any new functionality - Check for accessibility issues (for UI changes) + - Delegate translation tasks to translate mode when implementing user-facing changes + - Always check for hard-coded strings and internationalization needs + - Wait for translation completion before proceeding to final testing \ No newline at end of file From adb3ee9a11cdfb1ab74489737589e91f37492b7c Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Tue, 1 Jul 2025 08:32:38 -0600 Subject: [PATCH 45/70] feat: add translation orchestration to PR Fixer mode (#5280) Co-authored-by: Daniel Riccio --- .roo/rules-pr-fixer/1_workflow.xml | 18 +++- .roo/rules-pr-fixer/2_best_practices.xml | 10 ++ .roo/rules-pr-fixer/3_common_patterns.xml | 88 +++++++++++++--- .roo/rules-pr-fixer/4_tool_usage.xml | 69 +++++++++++++ .roo/rules-pr-fixer/5_examples.xml | 116 +++++++++++++++++++++- 5 files changed, 276 insertions(+), 25 deletions(-) diff --git a/.roo/rules-pr-fixer/1_workflow.xml b/.roo/rules-pr-fixer/1_workflow.xml index 845a05d4ea..4b43e99217 100644 --- a/.roo/rules-pr-fixer/1_workflow.xml +++ b/.roo/rules-pr-fixer/1_workflow.xml @@ -41,17 +41,24 @@ Execute the user's chosen course of action. - Check out the PR branch locally using 'gh pr checkout'. - Apply code changes based on review feedback. - Fix failing tests. - Resolve conflicts by rebasing the PR branch and force-pushing. + Check out the PR branch locally using 'gh pr checkout --force'. + Determine if the PR is from a fork by checking 'gh pr view --json isCrossRepository'. + Apply code changes based on review feedback using file editing tools. + Fix failing tests by modifying test files or source code as needed. + For conflict resolution: Use GIT_EDITOR=true for non-interactive rebases, then resolve conflicts via file editing. + If changes affect user-facing content (i18n files, UI components, announcements), delegate translation updates using the new_task tool with translate mode. + Commit changes using git commands. + Push changes to the correct remote (origin for same-repo PRs, fork remote for cross-repo PRs) using 'git push --force-with-lease'. Verify that the pushed changes resolve the issues. - Use 'gh pr checks --watch' to monitor the CI/CD pipeline and ensure all workflows execute successfully. + Use 'gh pr checks --watch' to monitor check status in real-time until all checks complete. + If needed, check specific workflow runs with 'gh run list --pr' for detailed CI/CD pipeline status. + Verify that all translation updates (if any) have been completed and committed. + Confirm PR is ready for review by checking mergeable state with 'gh pr view --json'. @@ -60,5 +67,6 @@ All actionable review comments have been addressed. All tests are passing. The PR is free of merge conflicts. + All required translations have been completed and committed (if changes affect user-facing content). \ No newline at end of file diff --git a/.roo/rules-pr-fixer/2_best_practices.xml b/.roo/rules-pr-fixer/2_best_practices.xml index 1576daa3c1..e9ef4a8b27 100644 --- a/.roo/rules-pr-fixer/2_best_practices.xml +++ b/.roo/rules-pr-fixer/2_best_practices.xml @@ -10,6 +10,16 @@ Address issues one at a time (e.g., fix tests first, then address comments). This makes the process more manageable and easier to validate. Tackling all issues at once can be complex and error-prone. + + Handle Fork Remotes Correctly + Always check if a PR comes from a fork (cross-repository) before pushing changes. Use 'gh pr view --json isCrossRepository' to determine the correct remote. + Pushing to the wrong remote (e.g., origin instead of fork) will fail for cross-repository PRs. + + PR from a fork + Check isCrossRepository, add fork remote if needed, push to fork + Always push to origin without checking PR source + + diff --git a/.roo/rules-pr-fixer/3_common_patterns.xml b/.roo/rules-pr-fixer/3_common_patterns.xml index 659aa7d07f..5d2c7f033f 100644 --- a/.roo/rules-pr-fixer/3_common_patterns.xml +++ b/.roo/rules-pr-fixer/3_common_patterns.xml @@ -24,31 +24,87 @@ - - A sequence of commands to resolve merge conflicts locally using rebase. + + Commands to detect merge conflicts. + + + + + Rebase operations using GIT_EDITOR to prevent interactive prompts. + + + + Check current conflict status without interactive input. + - Command to check out a pull request branch locally. + Check out a pull request branch locally. - - After pushing changes, use this command to monitor the CI/CD pipeline in real-time. + + + Determine the correct remote to push to (handles forks). + + + + Monitor PR checks in real-time as they run. + + + + + Push operations that handle both origin and fork remotes correctly. + + + + + Commit operations that work in automated environments. + diff --git a/.roo/rules-pr-fixer/4_tool_usage.xml b/.roo/rules-pr-fixer/4_tool_usage.xml index 10361dc3ec..15833f3dd7 100644 --- a/.roo/rules-pr-fixer/4_tool_usage.xml +++ b/.roo/rules-pr-fixer/4_tool_usage.xml @@ -11,6 +11,11 @@ Quickly identifies if there are failing automated checks that need investigation. + new_task (mode: translate) + When changes affect user-facing content, i18n files, or UI components that require translation. + Ensures translation consistency across all supported languages when PR fixes involve user-facing changes. + + gh pr checks --watch After pushing a fix, to confirm that the changes have resolved the CI/CD failures. Provides real-time feedback on whether the fix was successful. @@ -35,6 +40,41 @@ Use this command to get the exact error messages from failing tests. Search the log for keywords like 'error', 'failed', or 'exception' to quickly find the root cause. + Always specify run ID explicitly to avoid interactive selection prompts. + + + + + + Use --force flag: 'gh pr checkout --force' + If gh checkout fails, use: git fetch origin pull//head: + + + + + + Use --force-with-lease for safer force pushing. + Use GIT_EDITOR=true to prevent interactive prompts during rebases. + Always determine the correct remote before pushing (origin vs fork). + + + Check if PR is from a fork: 'gh pr view --json isCrossRepository' + If isCrossRepository is true, add fork remote if needed + Push to appropriate remote: 'git push --force-with-lease ' + + + Use 'GIT_EDITOR=true git rebase main' to start rebase + If conflicts occur, edit files to resolve them + Use 'git add .' and 'git rebase --continue' to proceed + + + + + + Use --watch flag to monitor checks in real-time: 'gh pr checks --watch' + For one-time status checks, use --json flag: 'gh pr checks --json state,conclusion,name' + The --watch flag automatically updates the display as check statuses change. + Use 'gh run list --pr ' to get detailed workflow status if needed. @@ -45,5 +85,34 @@ Example suggestions: "Address review comments first.", "Tackle the failing tests.", "Resolve merge conflicts." + + + + Use when PR fixes involve changes to user-facing strings, i18n files, or UI components. + Provide specific details about what content needs translation in the message. + Include file paths and descriptions of the changes made. + List all affected languages that need updates. + Wait for translation completion before proceeding to validation phase. + + + Changes to webview-ui/src/i18n/locales/en/*.json files + Changes to src/i18n/locales/en/*.json files + Modifications to UI components with user-facing text + Updates to announcement files or documentation requiring localization + Addition of new error messages or user notifications + + +translate +Translation updates needed for PR #1234 fixes. Please translate the following changes: + +Files modified: +- webview-ui/src/i18n/locales/en/common.json: Added new error message "connection_failed" +- webview-ui/src/components/settings/ApiSettings.tsx: Updated button text from "Save" to "Save Configuration" + +Please ensure all supported languages (ca, de, es, fr, hi, id, it, ja, ko, nl, pl, pt-BR, ru, tr, vi, zh-CN, zh-TW) are updated with appropriate translations for these changes. + + ]]> + \ No newline at end of file diff --git a/.roo/rules-pr-fixer/5_examples.xml b/.roo/rules-pr-fixer/5_examples.xml index e34a79421f..0ff98de250 100644 --- a/.roo/rules-pr-fixer/5_examples.xml +++ b/.roo/rules-pr-fixer/5_examples.xml @@ -62,7 +62,7 @@ Check out the pull request branch. - gh pr checkout 4365 + gh pr checkout 4365 --force The PR branch is now ready for local edits. @@ -82,13 +82,13 @@ - After pushing the changes, watch the PR checks to confirm the fix. + After pushing the changes, monitor PR checks in real-time. - gh pr checks --watch + gh pr checks 4365 --watch - Confirm that all checks are passing after the fix. + Monitor checks continuously until all complete. The --watch flag provides real-time updates as check statuses change. @@ -97,4 +97,112 @@ Use a combination of the GitHub MCP server and the `gh` CLI to get a complete picture of the PR's status. + + + + A pull request has review comments requesting UI text changes that require translation updates across all supported languages. + + + + Fix PR #1234 in RooCodeInc/Roo-Code - the reviewer asked to change button text and there are some failing tests. + + + + + Get PR details and analyze changes. + + + github + get_pull_request + + { + "owner": "RooCodeInc", + "repo": "Roo-Code", + "pullNumber": 1234 + } + + + + Identify the files changed and review feedback requiring UI text modifications. + + + + Check out PR and apply the requested changes. + + +gh pr checkout 1234 --force + + + Make the requested button text changes in the UI components. + + + + Identify translation requirements and delegate to translate mode. + + +translate +Translation updates needed for PR #1234 fixes. The following changes were made based on review feedback: + +Files modified: +- webview-ui/src/components/settings/ApiSettings.tsx: Changed button text from "Save" to "Save Configuration" +- webview-ui/src/i18n/locales/en/common.json: Updated key "save_button" to "save_config_button" + +Please update all supported languages (ca, de, es, fr, hi, id, it, ja, ko, nl, pl, pt-BR, ru, tr, vi, zh-CN, zh-TW) with appropriate translations for: +- New key "save_config_button" with translation equivalent to "Save Configuration" +- Any other text changes that affect user-facing content + +Ensure consistency across all language files and maintain the same context and tone as existing translations. + + + Translation subtask created and all language files updated. + + + + Commit all changes including translations with automated git configuration. + + +git add . && git commit -m "fix: update button text and translations as requested in review" + + + All code changes and translation updates are now committed. + + + + Check if PR is from a fork and push to correct remote. + + +gh pr view 1234 --json isCrossRepository,headRepositoryOwner,headRefName + + + Determine if this is a cross-repository PR to know which remote to push to. + + + + Push changes to the appropriate remote. + + +git push --force-with-lease origin + + + Push changes safely to update the pull request. Use 'fork' remote instead if PR is from a fork. + + + + Monitor CI status in real-time. + + +gh pr checks 1234 --watch + + + Watch CI checks continuously until all tests pass. The --watch flag provides automatic updates as check statuses change. + + + + + Always check if PR fixes involve user-facing content that requires translation. + Use new_task with translate mode to ensure consistent translation updates. + Include detailed context about what changed and why in translation requests. + Verify translation completeness before considering the PR fix complete. + + From 933f28fe327c9e476a068e4ebce8ea05e6f9d72f Mon Sep 17 00:00:00 2001 From: Murilo Pires <50873657+MuriloFP@users.noreply.github.com> Date: Tue, 1 Jul 2025 11:33:32 -0300 Subject: [PATCH 46/70] fix: Exclude cache files from rules compilation (#5283) Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> --- .../__tests__/custom-instructions.spec.ts | 100 ++++++++++++++++++ .../prompts/sections/custom-instructions.ts | 47 +++++++- 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/src/core/prompts/sections/__tests__/custom-instructions.spec.ts b/src/core/prompts/sections/__tests__/custom-instructions.spec.ts index 111cefaf27..9c8e003143 100644 --- a/src/core/prompts/sections/__tests__/custom-instructions.spec.ts +++ b/src/core/prompts/sections/__tests__/custom-instructions.spec.ts @@ -221,6 +221,106 @@ describe("loadRuleFiles", () => { expect(readFileMock).toHaveBeenCalledWith(expectedFile2Path, "utf-8") }) + it("should filter out cache files from .roo/rules/ directory", async () => { + // Simulate .roo/rules directory exists + statMock.mockResolvedValueOnce({ + isDirectory: vi.fn().mockReturnValue(true), + } as any) + + // Simulate listing files including cache files + readdirMock.mockResolvedValueOnce([ + { name: "rule1.txt", isFile: () => true, isSymbolicLink: () => false, parentPath: "/fake/path/.roo/rules" }, + { name: ".DS_Store", isFile: () => true, isSymbolicLink: () => false, parentPath: "/fake/path/.roo/rules" }, + { name: "Thumbs.db", isFile: () => true, isSymbolicLink: () => false, parentPath: "/fake/path/.roo/rules" }, + { name: "rule2.md", isFile: () => true, isSymbolicLink: () => false, parentPath: "/fake/path/.roo/rules" }, + { name: "cache.log", isFile: () => true, isSymbolicLink: () => false, parentPath: "/fake/path/.roo/rules" }, + { + name: "backup.bak", + isFile: () => true, + isSymbolicLink: () => false, + parentPath: "/fake/path/.roo/rules", + }, + { name: "temp.tmp", isFile: () => true, isSymbolicLink: () => false, parentPath: "/fake/path/.roo/rules" }, + { + name: "script.pyc", + isFile: () => true, + isSymbolicLink: () => false, + parentPath: "/fake/path/.roo/rules", + }, + ] as any) + + statMock.mockImplementation((path) => { + return Promise.resolve({ + isFile: vi.fn().mockReturnValue(true), + }) as any + }) + + readFileMock.mockImplementation((filePath: PathLike) => { + const pathStr = filePath.toString() + const normalizedPath = pathStr.replace(/\\/g, "/") + + // Only rule files should be read - cache files should be skipped + if (normalizedPath === "/fake/path/.roo/rules/rule1.txt") { + return Promise.resolve("rule 1 content") + } + if (normalizedPath === "/fake/path/.roo/rules/rule2.md") { + return Promise.resolve("rule 2 content") + } + + // Cache files should not be read due to filtering + // If they somehow are read, return recognizable content + if (normalizedPath === "/fake/path/.roo/rules/.DS_Store") { + return Promise.resolve("DS_STORE_BINARY_CONTENT") + } + if (normalizedPath === "/fake/path/.roo/rules/Thumbs.db") { + return Promise.resolve("THUMBS_DB_CONTENT") + } + if (normalizedPath === "/fake/path/.roo/rules/backup.bak") { + return Promise.resolve("BACKUP_CONTENT") + } + if (normalizedPath === "/fake/path/.roo/rules/cache.log") { + return Promise.resolve("LOG_CONTENT") + } + if (normalizedPath === "/fake/path/.roo/rules/temp.tmp") { + return Promise.resolve("TEMP_CONTENT") + } + if (normalizedPath === "/fake/path/.roo/rules/script.pyc") { + return Promise.resolve("PYTHON_BYTECODE") + } + + return Promise.reject({ code: "ENOENT" }) + }) + + const result = await loadRuleFiles("/fake/path") + + // Should contain rule files + expect(result).toContain("rule 1 content") + expect(result).toContain("rule 2 content") + + // Should NOT contain cache file content - they should be filtered out + expect(result).not.toContain("DS_STORE_BINARY_CONTENT") + expect(result).not.toContain("THUMBS_DB_CONTENT") + expect(result).not.toContain("BACKUP_CONTENT") + expect(result).not.toContain("LOG_CONTENT") + expect(result).not.toContain("TEMP_CONTENT") + expect(result).not.toContain("PYTHON_BYTECODE") + + // Verify cache files are not read at all + const expectedCacheFiles = [ + "/fake/path/.roo/rules/.DS_Store", + "/fake/path/.roo/rules/Thumbs.db", + "/fake/path/.roo/rules/backup.bak", + "/fake/path/.roo/rules/cache.log", + "/fake/path/.roo/rules/temp.tmp", + "/fake/path/.roo/rules/script.pyc", + ] + + for (const cacheFile of expectedCacheFiles) { + const expectedPath = process.platform === "win32" ? cacheFile.replace(/\//g, "\\") : cacheFile + expect(readFileMock).not.toHaveBeenCalledWith(expectedPath, "utf-8") + } + }) + it("should fall back to .roorules when .roo/rules/ is empty", async () => { // Simulate .roo/rules directory exists statMock.mockResolvedValueOnce({ diff --git a/src/core/prompts/sections/custom-instructions.ts b/src/core/prompts/sections/custom-instructions.ts index 0e1ddfd24f..3c8558a57f 100644 --- a/src/core/prompts/sections/custom-instructions.ts +++ b/src/core/prompts/sections/custom-instructions.ts @@ -123,6 +123,10 @@ async function readTextFilesFromDirectory(dirPath: string): Promise item !== null) } catch (err) { return [] @@ -297,3 +301,44 @@ The following additional instructions are provided by the user, and should be fo ${joinedSections}` : "" } + +/** + * Check if a file should be included in rule compilation. + * Excludes cache files and system files that shouldn't be processed as rules. + */ +function shouldIncludeRuleFile(filename: string): boolean { + const basename = path.basename(filename) + + const cachePatterns = [ + "*.DS_Store", + "*.bak", + "*.cache", + "*.crdownload", + "*.db", + "*.dmp", + "*.dump", + "*.eslintcache", + "*.lock", + "*.log", + "*.old", + "*.part", + "*.partial", + "*.pyc", + "*.pyo", + "*.stackdump", + "*.swo", + "*.swp", + "*.temp", + "*.tmp", + "Thumbs.db", + ] + + return !cachePatterns.some((pattern) => { + if (pattern.startsWith("*.")) { + const extension = pattern.slice(1) + return basename.endsWith(extension) + } else { + return basename === pattern + } + }) +} From a348a2ae9a82057ffb1610ca9502208a0db43576 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Tue, 1 Jul 2025 12:41:23 -0600 Subject: [PATCH 47/70] feat: add user-configurable search score threshold slider for semantic search (#5027) (#5041) Co-authored-by: Daniel Riccio --- packages/types/src/codebase-index.ts | 1 + .../__tests__/config-manager.spec.ts | 147 ++++++++++++++++++ src/services/code-index/config-manager.ts | 26 +++- src/services/code-index/embedders/ollama.ts | 29 +++- .../code-index/embedders/openai-compatible.ts | 30 +++- src/services/code-index/embedders/openai.ts | 29 +++- src/shared/embeddingModels.ts | 62 ++++++-- .../components/chat/CodebaseSearchResult.tsx | 8 +- .../components/settings/CodeIndexSettings.tsx | 80 ++++++++++ .../__tests__/CodeIndexSettings.spec.tsx | 133 +++++++++++++++- webview-ui/src/i18n/locales/ca/chat.json | 3 +- webview-ui/src/i18n/locales/ca/settings.json | 4 + webview-ui/src/i18n/locales/de/chat.json | 3 +- webview-ui/src/i18n/locales/de/settings.json | 4 + webview-ui/src/i18n/locales/en/chat.json | 3 +- webview-ui/src/i18n/locales/en/settings.json | 4 + webview-ui/src/i18n/locales/es/chat.json | 3 +- webview-ui/src/i18n/locales/es/settings.json | 4 + webview-ui/src/i18n/locales/fr/chat.json | 3 +- webview-ui/src/i18n/locales/fr/settings.json | 4 + webview-ui/src/i18n/locales/hi/chat.json | 3 +- webview-ui/src/i18n/locales/hi/settings.json | 4 + webview-ui/src/i18n/locales/id/chat.json | 3 +- webview-ui/src/i18n/locales/id/settings.json | 4 + webview-ui/src/i18n/locales/it/chat.json | 3 +- webview-ui/src/i18n/locales/it/settings.json | 4 + webview-ui/src/i18n/locales/ja/chat.json | 3 +- webview-ui/src/i18n/locales/ja/settings.json | 4 + webview-ui/src/i18n/locales/ko/chat.json | 3 +- webview-ui/src/i18n/locales/ko/settings.json | 4 + webview-ui/src/i18n/locales/nl/chat.json | 3 +- webview-ui/src/i18n/locales/nl/settings.json | 4 + webview-ui/src/i18n/locales/pl/chat.json | 3 +- webview-ui/src/i18n/locales/pl/settings.json | 4 + webview-ui/src/i18n/locales/pt-BR/chat.json | 3 +- .../src/i18n/locales/pt-BR/settings.json | 4 + webview-ui/src/i18n/locales/ru/chat.json | 3 +- webview-ui/src/i18n/locales/ru/settings.json | 4 + webview-ui/src/i18n/locales/tr/chat.json | 3 +- webview-ui/src/i18n/locales/tr/settings.json | 4 + webview-ui/src/i18n/locales/vi/chat.json | 3 +- webview-ui/src/i18n/locales/vi/settings.json | 4 + webview-ui/src/i18n/locales/zh-CN/chat.json | 3 +- .../src/i18n/locales/zh-CN/settings.json | 4 + webview-ui/src/i18n/locales/zh-TW/chat.json | 3 +- .../src/i18n/locales/zh-TW/settings.json | 4 + 46 files changed, 630 insertions(+), 41 deletions(-) diff --git a/packages/types/src/codebase-index.ts b/packages/types/src/codebase-index.ts index e86c17627f..7263068415 100644 --- a/packages/types/src/codebase-index.ts +++ b/packages/types/src/codebase-index.ts @@ -10,6 +10,7 @@ export const codebaseIndexConfigSchema = z.object({ codebaseIndexEmbedderProvider: z.enum(["openai", "ollama", "openai-compatible"]).optional(), codebaseIndexEmbedderBaseUrl: z.string().optional(), codebaseIndexEmbedderModelId: z.string().optional(), + codebaseIndexSearchMinScore: z.number().min(0).max(1).optional(), }) export type CodebaseIndexConfig = z.infer diff --git a/src/services/code-index/__tests__/config-manager.spec.ts b/src/services/code-index/__tests__/config-manager.spec.ts index f5a759c158..2da19a6a1e 100644 --- a/src/services/code-index/__tests__/config-manager.spec.ts +++ b/src/services/code-index/__tests__/config-manager.spec.ts @@ -709,6 +709,153 @@ describe("CodeIndexConfigManager", () => { const result = await configManager.loadConfiguration() expect(result.requiresRestart).toBe(false) }) + + describe("currentSearchMinScore priority system", () => { + it("should return user-configured score when set", async () => { + mockContextProxy.getGlobalState.mockReturnValue({ + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "openai", + codebaseIndexEmbedderModelId: "text-embedding-3-small", + codebaseIndexSearchMinScore: 0.8, // User setting + }) + mockContextProxy.getSecret.mockImplementation((key: string) => { + if (key === "codeIndexOpenAiKey") return "test-key" + return undefined + }) + + await configManager.loadConfiguration() + expect(configManager.currentSearchMinScore).toBe(0.8) + }) + + it("should fall back to model-specific threshold when user setting is undefined", async () => { + mockContextProxy.getGlobalState.mockReturnValue({ + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "ollama", + codebaseIndexEmbedderModelId: "nomic-embed-code", + // No codebaseIndexSearchMinScore - user hasn't configured it + }) + + await configManager.loadConfiguration() + // nomic-embed-code has a specific threshold of 0.15 + expect(configManager.currentSearchMinScore).toBe(0.15) + }) + + it("should fall back to default SEARCH_MIN_SCORE when neither user setting nor model threshold exists", async () => { + mockContextProxy.getGlobalState.mockReturnValue({ + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "openai", + codebaseIndexEmbedderModelId: "unknown-model", // Model not in profiles + // No codebaseIndexSearchMinScore + }) + mockContextProxy.getSecret.mockImplementation((key: string) => { + if (key === "codeIndexOpenAiKey") return "test-key" + return undefined + }) + + await configManager.loadConfiguration() + // Should fall back to default SEARCH_MIN_SCORE (0.4) + expect(configManager.currentSearchMinScore).toBe(0.4) + }) + + it("should respect user setting of 0 (edge case)", async () => { + mockContextProxy.getGlobalState.mockReturnValue({ + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "ollama", + codebaseIndexEmbedderModelId: "nomic-embed-code", + codebaseIndexSearchMinScore: 0, // User explicitly sets 0 + }) + + await configManager.loadConfiguration() + // Should return 0, not fall back to model threshold (0.15) + expect(configManager.currentSearchMinScore).toBe(0) + }) + + it("should use model-specific threshold with openai-compatible provider", async () => { + mockContextProxy.getGlobalState.mockImplementation((key: string) => { + if (key === "codebaseIndexConfig") { + return { + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "openai-compatible", + codebaseIndexEmbedderModelId: "nomic-embed-code", + // No codebaseIndexSearchMinScore + } + } + if (key === "codebaseIndexOpenAiCompatibleBaseUrl") return "https://api.example.com/v1" + return undefined + }) + mockContextProxy.getSecret.mockImplementation((key: string) => { + if (key === "codebaseIndexOpenAiCompatibleApiKey") return "test-api-key" + return undefined + }) + + await configManager.loadConfiguration() + // openai-compatible provider also has nomic-embed-code with 0.15 threshold + expect(configManager.currentSearchMinScore).toBe(0.15) + }) + + it("should use default model ID when modelId is not specified", async () => { + mockContextProxy.getGlobalState.mockReturnValue({ + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "openai", + // No modelId specified + // No codebaseIndexSearchMinScore + }) + mockContextProxy.getSecret.mockImplementation((key: string) => { + if (key === "codeIndexOpenAiKey") return "test-key" + return undefined + }) + + await configManager.loadConfiguration() + // Should use default model (text-embedding-3-small) threshold (0.4) + expect(configManager.currentSearchMinScore).toBe(0.4) + }) + + it("should handle priority correctly: user > model > default", async () => { + // Test 1: User setting takes precedence + mockContextProxy.getGlobalState.mockReturnValue({ + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "ollama", + codebaseIndexEmbedderModelId: "nomic-embed-code", // Has 0.15 threshold + codebaseIndexSearchMinScore: 0.9, // User overrides + }) + + await configManager.loadConfiguration() + expect(configManager.currentSearchMinScore).toBe(0.9) // User setting wins + + // Test 2: Model threshold when no user setting + mockContextProxy.getGlobalState.mockReturnValue({ + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "ollama", + codebaseIndexEmbedderModelId: "nomic-embed-code", + // No user setting + }) + + const newManager = new CodeIndexConfigManager(mockContextProxy) + await newManager.loadConfiguration() + expect(newManager.currentSearchMinScore).toBe(0.15) // Model threshold + + // Test 3: Default when neither exists + mockContextProxy.getGlobalState.mockReturnValue({ + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "openai", + codebaseIndexEmbedderModelId: "custom-unknown-model", + // No user setting, unknown model + }) + + const anotherManager = new CodeIndexConfigManager(mockContextProxy) + await anotherManager.loadConfiguration() + expect(anotherManager.currentSearchMinScore).toBe(0.4) // Default + }) + }) }) describe("empty/missing API key handling", () => { diff --git a/src/services/code-index/config-manager.ts b/src/services/code-index/config-manager.ts index 678cec36a1..d0eb9268b2 100644 --- a/src/services/code-index/config-manager.ts +++ b/src/services/code-index/config-manager.ts @@ -3,7 +3,7 @@ import { ContextProxy } from "../../core/config/ContextProxy" import { EmbedderProvider } from "./interfaces/manager" import { CodeIndexConfig, PreviousConfigSnapshot } from "./interfaces/config" import { SEARCH_MIN_SCORE } from "./constants" -import { getDefaultModelId, getModelDimension } from "../../shared/embeddingModels" +import { getDefaultModelId, getModelDimension, getModelScoreThreshold } from "../../shared/embeddingModels" /** * Manages configuration state and validation for the code indexing feature. @@ -34,10 +34,10 @@ export class CodeIndexConfigManager { const codebaseIndexConfig = this.contextProxy?.getGlobalState("codebaseIndexConfig") ?? { codebaseIndexEnabled: false, codebaseIndexQdrantUrl: "http://localhost:6333", - codebaseIndexSearchMinScore: 0.4, codebaseIndexEmbedderProvider: "openai", codebaseIndexEmbedderBaseUrl: "", codebaseIndexEmbedderModelId: "", + codebaseIndexSearchMinScore: undefined, } const { @@ -46,6 +46,7 @@ export class CodeIndexConfigManager { codebaseIndexEmbedderProvider, codebaseIndexEmbedderBaseUrl, codebaseIndexEmbedderModelId, + codebaseIndexSearchMinScore, } = codebaseIndexConfig const openAiKey = this.contextProxy?.getSecret("codeIndexOpenAiKey") ?? "" @@ -60,8 +61,8 @@ export class CodeIndexConfigManager { this.isEnabled = codebaseIndexEnabled || false this.qdrantUrl = codebaseIndexQdrantUrl this.qdrantApiKey = qdrantApiKey ?? "" + this.searchMinScore = codebaseIndexSearchMinScore this.openAiOptions = { openAiNativeApiKey: openAiKey } - this.searchMinScore = SEARCH_MIN_SCORE // Set embedder provider with support for openai-compatible if (codebaseIndexEmbedderProvider === "ollama") { @@ -139,7 +140,7 @@ export class CodeIndexConfigManager { openAiCompatibleOptions: this.openAiCompatibleOptions, qdrantUrl: this.qdrantUrl, qdrantApiKey: this.qdrantApiKey, - searchMinScore: this.searchMinScore, + searchMinScore: this.currentSearchMinScore, }, requiresRestart, } @@ -294,7 +295,7 @@ export class CodeIndexConfigManager { openAiCompatibleOptions: this.openAiCompatibleOptions, qdrantUrl: this.qdrantUrl, qdrantApiKey: this.qdrantApiKey, - searchMinScore: this.searchMinScore, + searchMinScore: this.currentSearchMinScore, } } @@ -337,9 +338,18 @@ export class CodeIndexConfigManager { } /** - * Gets the configured minimum search score. + * Gets the configured minimum search score based on user setting, model-specific threshold, or fallback. + * Priority: 1) User setting, 2) Model-specific threshold, 3) Default SEARCH_MIN_SCORE constant. */ - public get currentSearchMinScore(): number | undefined { - return this.searchMinScore + public get currentSearchMinScore(): number { + // First check if user has configured a custom score threshold + if (this.searchMinScore !== undefined) { + return this.searchMinScore + } + + // Fall back to model-specific threshold + const currentModelId = this.modelId ?? getDefaultModelId(this.embedderProvider) + const modelSpecificThreshold = getModelScoreThreshold(this.embedderProvider, currentModelId) + return modelSpecificThreshold ?? SEARCH_MIN_SCORE } } diff --git a/src/services/code-index/embedders/ollama.ts b/src/services/code-index/embedders/ollama.ts index 748ed188a4..2f212c7745 100644 --- a/src/services/code-index/embedders/ollama.ts +++ b/src/services/code-index/embedders/ollama.ts @@ -1,5 +1,7 @@ import { ApiHandlerOptions } from "../../../shared/api" import { EmbedderInfo, EmbeddingResponse, IEmbedder } from "../interfaces" +import { getModelQueryPrefix } from "../../../shared/embeddingModels" +import { MAX_ITEM_TOKENS } from "../constants" import { t } from "../../../i18n" /** @@ -25,6 +27,31 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { const modelToUse = model || this.defaultModelId const url = `${this.baseUrl}/api/embed` // Endpoint as specified + // Apply model-specific query prefix if required + const queryPrefix = getModelQueryPrefix("ollama", modelToUse) + const processedTexts = queryPrefix + ? texts.map((text, index) => { + // Prevent double-prefixing + if (text.startsWith(queryPrefix)) { + return text + } + const prefixedText = `${queryPrefix}${text}` + const estimatedTokens = Math.ceil(prefixedText.length / 4) + if (estimatedTokens > MAX_ITEM_TOKENS) { + console.warn( + t("embeddings:textWithPrefixExceedsTokenLimit", { + index, + estimatedTokens, + maxTokens: MAX_ITEM_TOKENS, + }), + ) + // Return original text if adding prefix would exceed limit + return text + } + return prefixedText + }) + : texts + try { // Note: Standard Ollama API uses 'prompt' for single text, not 'input' for array. // Implementing based on user's specific request structure. @@ -35,7 +62,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { }, body: JSON.stringify({ model: modelToUse, - input: texts, // Using 'input' as requested + input: processedTexts, // Using 'input' as requested }), }) diff --git a/src/services/code-index/embedders/openai-compatible.ts b/src/services/code-index/embedders/openai-compatible.ts index 0983cc297f..8bf35eea24 100644 --- a/src/services/code-index/embedders/openai-compatible.ts +++ b/src/services/code-index/embedders/openai-compatible.ts @@ -6,7 +6,7 @@ import { MAX_BATCH_RETRIES as MAX_RETRIES, INITIAL_RETRY_DELAY_MS as INITIAL_DELAY_MS, } from "../constants" -import { getDefaultModelId } from "../../../shared/embeddingModels" +import { getDefaultModelId, getModelQueryPrefix } from "../../../shared/embeddingModels" import { t } from "../../../i18n" interface EmbeddingItem { @@ -59,9 +59,35 @@ export class OpenAICompatibleEmbedder implements IEmbedder { */ async createEmbeddings(texts: string[], model?: string): Promise { const modelToUse = model || this.defaultModelId + + // Apply model-specific query prefix if required + const queryPrefix = getModelQueryPrefix("openai-compatible", modelToUse) + const processedTexts = queryPrefix + ? texts.map((text, index) => { + // Prevent double-prefixing + if (text.startsWith(queryPrefix)) { + return text + } + const prefixedText = `${queryPrefix}${text}` + const estimatedTokens = Math.ceil(prefixedText.length / 4) + if (estimatedTokens > MAX_ITEM_TOKENS) { + console.warn( + t("embeddings:textWithPrefixExceedsTokenLimit", { + index, + estimatedTokens, + maxTokens: MAX_ITEM_TOKENS, + }), + ) + // Return original text if adding prefix would exceed limit + return text + } + return prefixedText + }) + : texts + const allEmbeddings: number[][] = [] const usage = { promptTokens: 0, totalTokens: 0 } - const remainingTexts = [...texts] + const remainingTexts = [...processedTexts] while (remainingTexts.length > 0) { const currentBatch: string[] = [] diff --git a/src/services/code-index/embedders/openai.ts b/src/services/code-index/embedders/openai.ts index d0dc132df7..667c2f46d4 100644 --- a/src/services/code-index/embedders/openai.ts +++ b/src/services/code-index/embedders/openai.ts @@ -8,6 +8,7 @@ import { MAX_BATCH_RETRIES as MAX_RETRIES, INITIAL_RETRY_DELAY_MS as INITIAL_DELAY_MS, } from "../constants" +import { getModelQueryPrefix } from "../../../shared/embeddingModels" import { t } from "../../../i18n" /** @@ -36,9 +37,35 @@ export class OpenAiEmbedder extends OpenAiNativeHandler implements IEmbedder { */ async createEmbeddings(texts: string[], model?: string): Promise { const modelToUse = model || this.defaultModelId + + // Apply model-specific query prefix if required + const queryPrefix = getModelQueryPrefix("openai", modelToUse) + const processedTexts = queryPrefix + ? texts.map((text, index) => { + // Prevent double-prefixing + if (text.startsWith(queryPrefix)) { + return text + } + const prefixedText = `${queryPrefix}${text}` + const estimatedTokens = Math.ceil(prefixedText.length / 4) + if (estimatedTokens > MAX_ITEM_TOKENS) { + console.warn( + t("embeddings:textWithPrefixExceedsTokenLimit", { + index, + estimatedTokens, + maxTokens: MAX_ITEM_TOKENS, + }), + ) + // Return original text if adding prefix would exceed limit + return text + } + return prefixedText + }) + : texts + const allEmbeddings: number[][] = [] const usage = { promptTokens: 0, totalTokens: 0 } - const remainingTexts = [...texts] + const remainingTexts = [...processedTexts] while (remainingTexts.length > 0) { const currentBatch: string[] = [] diff --git a/src/shared/embeddingModels.ts b/src/shared/embeddingModels.ts index cd7c1d4e6b..c78dc6c487 100644 --- a/src/shared/embeddingModels.ts +++ b/src/shared/embeddingModels.ts @@ -6,6 +6,8 @@ export type EmbedderProvider = "openai" | "ollama" | "openai-compatible" // Add export interface EmbeddingModelProfile { dimension: number + scoreThreshold?: number // Model-specific minimum score threshold for semantic search + queryPrefix?: string // Optional prefix required by the model for queries // Add other model-specific properties if needed, e.g., context window size } @@ -18,21 +20,31 @@ export type EmbeddingModelProfiles = { // Example profiles - expand this list as needed export const EMBEDDING_MODEL_PROFILES: EmbeddingModelProfiles = { openai: { - "text-embedding-3-small": { dimension: 1536 }, - "text-embedding-3-large": { dimension: 3072 }, - "text-embedding-ada-002": { dimension: 1536 }, + "text-embedding-3-small": { dimension: 1536, scoreThreshold: 0.4 }, + "text-embedding-3-large": { dimension: 3072, scoreThreshold: 0.4 }, + "text-embedding-ada-002": { dimension: 1536, scoreThreshold: 0.4 }, }, ollama: { - "nomic-embed-text": { dimension: 768 }, - "mxbai-embed-large": { dimension: 1024 }, - "all-minilm": { dimension: 384 }, + "nomic-embed-text": { dimension: 768, scoreThreshold: 0.4 }, + "nomic-embed-code": { + dimension: 3584, + scoreThreshold: 0.15, + queryPrefix: "Represent this query for searching relevant code: ", + }, + "mxbai-embed-large": { dimension: 1024, scoreThreshold: 0.4 }, + "all-minilm": { dimension: 384, scoreThreshold: 0.4 }, // Add default Ollama model if applicable, e.g.: // 'default': { dimension: 768 } // Assuming a default dimension }, "openai-compatible": { - "text-embedding-3-small": { dimension: 1536 }, - "text-embedding-3-large": { dimension: 3072 }, - "text-embedding-ada-002": { dimension: 1536 }, + "text-embedding-3-small": { dimension: 1536, scoreThreshold: 0.4 }, + "text-embedding-3-large": { dimension: 3072, scoreThreshold: 0.4 }, + "text-embedding-ada-002": { dimension: 1536, scoreThreshold: 0.4 }, + "nomic-embed-code": { + dimension: 3584, + scoreThreshold: 0.15, + queryPrefix: "Represent this query for searching relevant code: ", + }, }, } @@ -59,6 +71,38 @@ export function getModelDimension(provider: EmbedderProvider, modelId: string): return modelProfile.dimension } +/** + * Retrieves the score threshold for a given provider and model ID. + * @param provider The embedder provider (e.g., "openai"). + * @param modelId The specific model ID (e.g., "text-embedding-3-small"). + * @returns The score threshold or undefined if the model is not found. + */ +export function getModelScoreThreshold(provider: EmbedderProvider, modelId: string): number | undefined { + const providerProfiles = EMBEDDING_MODEL_PROFILES[provider] + if (!providerProfiles) { + return undefined + } + + const modelProfile = providerProfiles[modelId] + return modelProfile?.scoreThreshold +} + +/** + * Retrieves the query prefix for a given provider and model ID. + * @param provider The embedder provider (e.g., "openai"). + * @param modelId The specific model ID (e.g., "nomic-embed-code"). + * @returns The query prefix or undefined if the model doesn't require one. + */ +export function getModelQueryPrefix(provider: EmbedderProvider, modelId: string): string | undefined { + const providerProfiles = EMBEDDING_MODEL_PROFILES[provider] + if (!providerProfiles) { + return undefined + } + + const modelProfile = providerProfiles[modelId] + return modelProfile?.queryPrefix +} + /** * Gets the default *specific* embedding model ID based on the provider. * Does not include the provider prefix. diff --git a/webview-ui/src/components/chat/CodebaseSearchResult.tsx b/webview-ui/src/components/chat/CodebaseSearchResult.tsx index 4a2ced6178..4d48749ecd 100644 --- a/webview-ui/src/components/chat/CodebaseSearchResult.tsx +++ b/webview-ui/src/components/chat/CodebaseSearchResult.tsx @@ -1,4 +1,5 @@ import React from "react" +import { useTranslation } from "react-i18next" import { vscode } from "@src/utils/vscode" import { StandardTooltip } from "@/components/ui" @@ -12,6 +13,8 @@ interface CodebaseSearchResultProps { } const CodebaseSearchResult: React.FC = ({ filePath, score, startLine, endLine }) => { + const { t } = useTranslation("chat") + const handleClick = () => { console.log(filePath) vscode.postMessage({ @@ -24,7 +27,7 @@ const CodebaseSearchResult: React.FC = ({ filePath, s } return ( - +
@@ -35,6 +38,9 @@ const CodebaseSearchResult: React.FC = ({ filePath, s {filePath.split("/").slice(0, -1).join("/")} + + {score.toFixed(3)} +
diff --git a/webview-ui/src/components/settings/CodeIndexSettings.tsx b/webview-ui/src/components/settings/CodeIndexSettings.tsx index f385ae2bc6..8aae766b8f 100644 --- a/webview-ui/src/components/settings/CodeIndexSettings.tsx +++ b/webview-ui/src/components/settings/CodeIndexSettings.tsx @@ -7,6 +7,7 @@ import { Trans } from "react-i18next" import { CodebaseIndexConfig, CodebaseIndexModels, ProviderSettings } from "@roo-code/types" import { EmbedderProvider } from "@roo/embeddingModels" +import { SEARCH_MIN_SCORE } from "../../../../src/services/code-index/constants" import { vscode } from "@src/utils/vscode" import { useAppTranslation } from "@src/i18n/TranslationContext" @@ -27,6 +28,12 @@ import { AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, + Slider, + Button, + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, } from "@src/components/ui" import { SetCachedStateField } from "./types" @@ -59,6 +66,7 @@ export const CodeIndexSettings: React.FC = ({ totalItems: 0, currentItemUnit: "items", }) + const [advancedExpanded, setAdvancedExpanded] = useState(false) // Safely calculate available models for current provider const currentProvider = codebaseIndexConfig?.codebaseIndexEmbedderProvider @@ -506,6 +514,78 @@ export const CodeIndexSettings: React.FC = ({ )}
+ + {/* Advanced Configuration Section */} +
+ + + {advancedExpanded && ( +
+
+
+ + {t("settings:codeIndex.searchMinScoreLabel")} + +
+ + setCachedStateField("codebaseIndexConfig", { + ...codebaseIndexConfig, + codebaseIndexSearchMinScore: value, + }) + } + data-testid="search-min-score-slider" + aria-label={t("settings:codeIndex.searchMinScoreLabel")} + /> + + {( + codebaseIndexConfig.codebaseIndexSearchMinScore ?? SEARCH_MIN_SCORE + ).toFixed(2)} + + + + + + + +

{t("settings:codeIndex.searchMinScoreResetTooltip")}

+
+
+
+
+
+ {t("settings:codeIndex.searchMinScoreDescription")} +
+
+
+
+ )} +
)} diff --git a/webview-ui/src/components/settings/__tests__/CodeIndexSettings.spec.tsx b/webview-ui/src/components/settings/__tests__/CodeIndexSettings.spec.tsx index 3c3dae7956..802d5e8813 100644 --- a/webview-ui/src/components/settings/__tests__/CodeIndexSettings.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/CodeIndexSettings.spec.tsx @@ -43,6 +43,11 @@ vi.mock("@src/i18n/TranslationContext", () => ({ "settings:codeIndex.clearDataDialog.description": "This will remove all indexed data", "settings:codeIndex.clearDataDialog.cancelButton": "Cancel", "settings:codeIndex.clearDataDialog.confirmButton": "Confirm", + "settings:codeIndex.searchMinScoreLabel": "Search Score Threshold", + "settings:codeIndex.searchMinScoreDescription": + "Minimum similarity score (0.0-1.0) required for search results. Lower values return more results but may be less relevant. Higher values return fewer but more relevant results.", + "settings:codeIndex.searchMinScoreResetTooltip": "Reset to default value (0.4)", + "settings:codeIndex.advancedConfigLabel": "Advanced Configuration", } return translations[key] || key }, @@ -85,6 +90,24 @@ vi.mock("@src/components/ui", () => ({ AlertDialogHeader: ({ children }: any) =>
{children}
, AlertDialogTitle: ({ children }: any) =>
{children}
, AlertDialogTrigger: ({ children }: any) =>
{children}
, + Slider: ({ value, onValueChange, "data-testid": dataTestId }: any) => ( + onValueChange && onValueChange([parseFloat(e.target.value)])} + data-testid={dataTestId} + role="slider" + /> + ), + Button: ({ children, onClick, "data-testid": dataTestId, ...props }: any) => ( + + ), + Tooltip: ({ children }: any) =>
{children}
, + TooltipContent: ({ children }: any) =>
{children}
, + TooltipProvider: ({ children }: any) =>
{children}
, + TooltipTrigger: ({ children }: any) =>
{children}
, })) vi.mock("@vscode/webview-ui-toolkit/react", () => ({ @@ -158,6 +181,7 @@ describe("CodeIndexSettings", () => { codebaseIndexEmbedderProvider: "openai" as const, codebaseIndexEmbedderModelId: "text-embedding-3-small", codebaseIndexQdrantUrl: "http://localhost:6333", + codebaseIndexSearchMinScore: 0.4, }, apiConfiguration: { codeIndexOpenAiKey: "", @@ -204,7 +228,7 @@ describe("CodeIndexSettings", () => { expect(screen.getByText("Base URL")).toBeInTheDocument() expect(screen.getByText("API Key")).toBeInTheDocument() - expect(screen.getAllByTestId("vscode-textfield")).toHaveLength(6) // Base URL, API Key, Embedding Dimension, Model ID, Qdrant URL, Qdrant Key + expect(screen.getAllByTestId("vscode-textfield")).toHaveLength(6) // Base URL, API Key, Embedding Dimension, Model ID, Qdrant URL, Qdrant Key (Search Min Score is now a slider) }) it("should hide OpenAI Compatible fields when different provider is selected", () => { @@ -817,6 +841,113 @@ describe("CodeIndexSettings", () => { }) }) + describe("Search Minimum Score Slider", () => { + const expandAdvancedConfig = () => { + const advancedButton = screen.getByRole("button", { name: /Advanced Configuration/i }) + fireEvent.click(advancedButton) + } + + it("should render advanced configuration toggle button", () => { + render() + + expect(screen.getByRole("button", { name: /Advanced Configuration/i })).toBeInTheDocument() + expect(screen.getByText("Advanced Configuration")).toBeInTheDocument() + }) + + it("should render search minimum score slider with reset button when expanded", () => { + render() + + expandAdvancedConfig() + + expect(screen.getByTestId("search-min-score-slider")).toBeInTheDocument() + expect(screen.getByTestId("search-min-score-reset-button")).toBeInTheDocument() + expect(screen.getByText("Search Score Threshold")).toBeInTheDocument() + }) + + it("should display current search minimum score value when expanded", () => { + const propsWithScore = { + ...defaultProps, + codebaseIndexConfig: { + ...defaultProps.codebaseIndexConfig, + codebaseIndexSearchMinScore: 0.65, + }, + } + + render() + + expandAdvancedConfig() + + expect(screen.getByText("0.65")).toBeInTheDocument() + }) + + it("should call setCachedStateField when slider value changes", () => { + render() + + expandAdvancedConfig() + + const slider = screen.getByTestId("search-min-score-slider") + fireEvent.change(slider, { target: { value: "0.8" } }) + + expect(mockSetCachedStateField).toHaveBeenCalledWith("codebaseIndexConfig", { + ...defaultProps.codebaseIndexConfig, + codebaseIndexSearchMinScore: 0.8, + }) + }) + + it("should reset to default value when reset button is clicked", () => { + const propsWithScore = { + ...defaultProps, + codebaseIndexConfig: { + ...defaultProps.codebaseIndexConfig, + codebaseIndexSearchMinScore: 0.8, + }, + } + + render() + + expandAdvancedConfig() + + const resetButton = screen.getByTestId("search-min-score-reset-button") + fireEvent.click(resetButton) + + expect(mockSetCachedStateField).toHaveBeenCalledWith("codebaseIndexConfig", { + ...defaultProps.codebaseIndexConfig, + codebaseIndexSearchMinScore: 0.4, + }) + }) + + it("should use default value when no score is set", () => { + const propsWithoutScore = { + ...defaultProps, + codebaseIndexConfig: { + ...defaultProps.codebaseIndexConfig, + codebaseIndexSearchMinScore: undefined, + }, + } + + render() + + expandAdvancedConfig() + + expect(screen.getByText("0.40")).toBeInTheDocument() + }) + + it("should toggle advanced section visibility", () => { + render() + + // Initially collapsed - should not see slider + expect(screen.queryByTestId("search-min-score-slider")).not.toBeInTheDocument() + + // Expand advanced section + expandAdvancedConfig() + expect(screen.getByTestId("search-min-score-slider")).toBeInTheDocument() + + // Collapse again + expandAdvancedConfig() + expect(screen.queryByTestId("search-min-score-slider")).not.toBeInTheDocument() + }) + }) + describe("Error Handling", () => { it("should handle invalid provider gracefully", () => { const propsWithInvalidProvider = { diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 07f1e25b53..82d8a2fffd 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo vol cercar a la base de codi {{query}}:", "wantsToSearchWithPath": "Roo vol cercar a la base de codi {{query}} a {{path}}:", - "didSearch": "S'han trobat {{count}} resultat(s) per a {{query}}:" + "didSearch": "S'han trobat {{count}} resultat(s) per a {{query}}:", + "resultTooltip": "Puntuaciรณ de similitud: {{score}} (fes clic per obrir el fitxer)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index ea4f974149..7cee95070b 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "URL d'Ollama:", "qdrantUrlLabel": "URL de Qdrant", "qdrantKeyLabel": "Clau de Qdrant:", + "advancedConfigLabel": "Configuraciรณ avanรงada", + "searchMinScoreLabel": "Llindar de puntuaciรณ de cerca", + "searchMinScoreDescription": "Puntuaciรณ mรญnima de similitud (0.0-1.0) requerida per als resultats de la cerca. Valors mรฉs baixos retornen mรฉs resultats perรฒ poden ser menys rellevants. Valors mรฉs alts retornen menys resultats perรฒ mรฉs rellevants.", + "searchMinScoreResetTooltip": "Restablir al valor per defecte (0.4)", "startIndexingButton": "Iniciar indexaciรณ", "clearIndexDataButton": "Esborrar dades d'รญndex", "unsavedSettingsMessage": "Si us plau, deseu la configuraciรณ abans d'iniciar el procรฉs d'indexaciรณ.", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index b5c2336e46..b78f6d4f93 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo mรถchte den Codebase nach {{query}} durchsuchen:", "wantsToSearchWithPath": "Roo mรถchte den Codebase nach {{query}} in {{path}} durchsuchen:", - "didSearch": "{{count}} Ergebnis(se) fรผr {{query}} gefunden:" + "didSearch": "{{count}} Ergebnis(se) fรผr {{query}} gefunden:", + "resultTooltip": "ร„hnlichkeitswert: {{score}} (klicken zum ร–ffnen der Datei)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index c5e161bafe..1d0e10892d 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama-URL:", "qdrantUrlLabel": "Qdrant-URL", "qdrantKeyLabel": "Qdrant-Schlรผssel:", + "advancedConfigLabel": "Erweiterte Konfiguration", + "searchMinScoreLabel": "Suchergebnis-Schwellenwert", + "searchMinScoreDescription": "Mindestรคhnlichkeitswert (0.0-1.0), der fรผr Suchergebnisse erforderlich ist. Niedrigere Werte liefern mehr Ergebnisse, die jedoch mรถglicherweise weniger relevant sind. Hรถhere Werte liefern weniger, aber relevantere Ergebnisse.", + "searchMinScoreResetTooltip": "Auf Standardwert zurรผcksetzen (0.4)", "startIndexingButton": "Indexierung starten", "clearIndexDataButton": "Indexdaten lรถschen", "unsavedSettingsMessage": "Bitte speichere deine Einstellungen, bevor du den Indexierungsprozess startest.", diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 3e5c2bfc60..d07fd90394 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -201,7 +201,8 @@ "codebaseSearch": { "wantsToSearch": "Roo wants to search the codebase for {{query}}:", "wantsToSearchWithPath": "Roo wants to search the codebase for {{query}} in {{path}}:", - "didSearch": "Found {{count}} result(s) for {{query}}:" + "didSearch": "Found {{count}} result(s) for {{query}}:", + "resultTooltip": "Similarity score: {{score}} (click to open file)" }, "commandOutput": "Command Output", "response": "Response", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 14981ea499..bc6515ce28 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL:", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrant Key:", + "advancedConfigLabel": "Advanced Configuration", + "searchMinScoreLabel": "Search Score Threshold", + "searchMinScoreDescription": "Minimum similarity score (0.0-1.0) required for search results. Lower values return more results but may be less relevant. Higher values return fewer but more relevant results.", + "searchMinScoreResetTooltip": "Reset to default value (0.4)", "startIndexingButton": "Start Indexing", "clearIndexDataButton": "Clear Index Data", "unsavedSettingsMessage": "Please save your settings before starting the indexing process.", diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index db90a70057..2af576e88e 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo quiere buscar en la base de cรณdigo {{query}}:", "wantsToSearchWithPath": "Roo quiere buscar en la base de cรณdigo {{query}} en {{path}}:", - "didSearch": "Se encontraron {{count}} resultado(s) para {{query}}:" + "didSearch": "Se encontraron {{count}} resultado(s) para {{query}}:", + "resultTooltip": "Puntuaciรณn de similitud: {{score}} (haz clic para abrir el archivo)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 3e3d20cce1..0e3d4ac2b8 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "URL de Ollama:", "qdrantUrlLabel": "URL de Qdrant", "qdrantKeyLabel": "Clave de Qdrant:", + "advancedConfigLabel": "Configuraciรณn avanzada", + "searchMinScoreLabel": "Umbral de puntuaciรณn de bรบsqueda", + "searchMinScoreDescription": "Puntuaciรณn mรญnima de similitud (0.0-1.0) requerida para los resultados de bรบsqueda. Valores mรกs bajos devuelven mรกs resultados pero pueden ser menos relevantes. Valores mรกs altos devuelven menos resultados pero mรกs relevantes.", + "searchMinScoreResetTooltip": "Restablecer al valor predeterminado (0.4)", "startIndexingButton": "Iniciar indexaciรณn", "clearIndexDataButton": "Borrar datos de รญndice", "unsavedSettingsMessage": "Por favor guarda tus ajustes antes de iniciar el proceso de indexaciรณn.", diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index b0d20bc7b2..0b1e030f8f 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo veut rechercher dans la base de code {{query}} :", "wantsToSearchWithPath": "Roo veut rechercher dans la base de code {{query}} dans {{path}} :", - "didSearch": "{{count}} rรฉsultat(s) trouvรฉ(s) pour {{query}} :" + "didSearch": "{{count}} rรฉsultat(s) trouvรฉ(s) pour {{query}} :", + "resultTooltip": "Score de similaritรฉ : {{score}} (cliquer pour ouvrir le fichier)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 5635251876..2ec2daaf8a 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "URL Ollama :", "qdrantUrlLabel": "URL Qdrant", "qdrantKeyLabel": "Clรฉ Qdrant :", + "advancedConfigLabel": "Configuration avancรฉe", + "searchMinScoreLabel": "Seuil de score de recherche", + "searchMinScoreDescription": "Score de similaritรฉ minimum (0.0-1.0) requis pour les rรฉsultats de recherche. Des valeurs plus faibles renvoient plus de rรฉsultats mais peuvent รชtre moins pertinents. Des valeurs plus รฉlevรฉes renvoient moins de rรฉsultats mais plus pertinents.", + "searchMinScoreResetTooltip": "Rรฉinitialiser ร  la valeur par dรฉfaut (0.4)", "startIndexingButton": "Dรฉmarrer l'indexation", "clearIndexDataButton": "Effacer les donnรฉes d'index", "unsavedSettingsMessage": "Merci d'enregistrer tes paramรจtres avant de dรฉmarrer le processus d'indexation.", diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index 24e2af1eb7..dbbe65ca4c 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo เค•เฅ‹เคกเคฌเฅ‡เคธ เคฎเฅ‡เค‚ {{query}} เค–เฅ‹เคœเคจเคพ เคšเคพเคนเคคเคพ เคนเฅˆ:", "wantsToSearchWithPath": "Roo {{path}} เคฎเฅ‡เค‚ เค•เฅ‹เคกเคฌเฅ‡เคธ เคฎเฅ‡เค‚ {{query}} เค–เฅ‹เคœเคจเคพ เคšเคพเคนเคคเคพ เคนเฅˆ:", - "didSearch": "{{query}} เค•เฅ‡ เคฒเคฟเค {{count}} เคชเคฐเคฟเคฃเคพเคฎ เคฎเคฟเคฒเฅ‡:" + "didSearch": "{{query}} เค•เฅ‡ เคฒเคฟเค {{count}} เคชเคฐเคฟเคฃเคพเคฎ เคฎเคฟเคฒเฅ‡:", + "resultTooltip": "เคธเคฎเคพเคจเคคเคพ เคธเฅเค•เฅ‹เคฐ: {{score}} (เคซเคผเคพเค‡เคฒ เค–เฅ‹เคฒเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค•เฅเคฒเคฟเค• เค•เคฐเฅ‡เค‚)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 8de5bd1a19..2cdc9949c0 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL:", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrant เค•เฅเค‚เคœเฅ€:", + "advancedConfigLabel": "เค‰เคจเฅเคจเคค เค•เฅ‰เคจเฅเคซเคผเคฟเค—เคฐเฅ‡เคถเคจ", + "searchMinScoreLabel": "เค–เฅ‹เคœ เคธเฅเค•เฅ‹เคฐ เคฅเฅเคฐเฅ‡เคธเคนเฅ‹เคฒเฅเคก", + "searchMinScoreDescription": "เค–เฅ‹เคœ เคชเคฐเคฟเคฃเคพเคฎเฅ‹เค‚ เค•เฅ‡ เคฒเคฟเค เค†เคตเคถเฅเคฏเค• เคจเฅเคฏเฅ‚เคจเคคเคฎ เคธเคฎเคพเคจเคคเคพ เคธเฅเค•เฅ‹เคฐ (0.0-1.0)เฅค เค•เคฎ เคฎเคพเคจ เค…เคงเคฟเค• เคชเคฐเคฟเคฃเคพเคฎ เคฒเฅŒเคŸเคพเคคเฅ‡ เคนเฅˆเค‚ เคฒเฅ‡เค•เคฟเคจ เค•เคฎ เคชเฅเคฐเคพเคธเค‚เค—เคฟเค• เคนเฅ‹ เคธเค•เคคเฅ‡ เคนเฅˆเค‚เฅค เค‰เคšเฅเคš เคฎเคพเคจ เค•เคฎ เคฒเฅ‡เค•เคฟเคจ เค…เคงเคฟเค• เคชเฅเคฐเคพเคธเค‚เค—เคฟเค• เคชเคฐเคฟเคฃเคพเคฎ เคฒเฅŒเคŸเคพเคคเฅ‡ เคนเฅˆเค‚เฅค", + "searchMinScoreResetTooltip": "เคกเคฟเคซเคผเฅ‰เคฒเฅเคŸ เคฎเคพเคจ เคชเคฐ เคฐเฅ€เคธเฅ‡เคŸ เค•เคฐเฅ‡เค‚ (0.4)", "startIndexingButton": "เค‡เค‚เคกเฅ‡เค•เฅเคธเคฟเค‚เค— เคถเฅเคฐเฅ‚ เค•เคฐเฅ‡เค‚", "clearIndexDataButton": "เค‡เค‚เคกเฅ‡เค•เฅเคธ เคกเฅ‡เคŸเคพ เคธเคพเคซเคผ เค•เคฐเฅ‡เค‚", "unsavedSettingsMessage": "เค‡เค‚เคกเฅ‡เค•เฅเคธเคฟเค‚เค— เคชเฅเคฐเค•เฅเคฐเคฟเคฏเคพ เคถเฅเคฐเฅ‚ เค•เคฐเคจเฅ‡ เคธเฅ‡ เคชเคนเคฒเฅ‡ เค•เฅƒเคชเคฏเคพ เค…เคชเคจเฅ€ เคธเฅ‡เคŸเคฟเค‚เค—เฅเคธ เคธเคนเฅ‡เคœเฅ‡เค‚เฅค", diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index 0568b58913..c45a25d486 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -207,7 +207,8 @@ "codebaseSearch": { "wantsToSearch": "Roo ingin mencari codebase untuk {{query}}:", "wantsToSearchWithPath": "Roo ingin mencari codebase untuk {{query}} di {{path}}:", - "didSearch": "Ditemukan {{count}} hasil untuk {{query}}:" + "didSearch": "Ditemukan {{count}} hasil untuk {{query}}:", + "resultTooltip": "Skor kemiripan: {{score}} (klik untuk membuka file)" }, "commandOutput": "Output Perintah", "response": "Respons", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 8def303c05..6b6c62c520 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL:", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrant Key:", + "advancedConfigLabel": "Konfigurasi Lanjutan", + "searchMinScoreLabel": "Ambang Batas Skor Pencarian", + "searchMinScoreDescription": "Skor kesamaan minimum (0.0-1.0) yang diperlukan untuk hasil pencarian. Nilai yang lebih rendah mengembalikan lebih banyak hasil tetapi mungkin kurang relevan. Nilai yang lebih tinggi mengembalikan lebih sedikit hasil tetapi lebih relevan.", + "searchMinScoreResetTooltip": "Reset ke nilai default (0.4)", "startIndexingButton": "Mulai Pengindeksan", "clearIndexDataButton": "Hapus Data Indeks", "unsavedSettingsMessage": "Silakan simpan pengaturan kamu sebelum memulai proses pengindeksan.", diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index 1f7d6b463f..9b31a7d136 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo vuole cercare nella base di codice {{query}}:", "wantsToSearchWithPath": "Roo vuole cercare nella base di codice {{query}} in {{path}}:", - "didSearch": "Trovato {{count}} risultato/i per {{query}}:" + "didSearch": "Trovato {{count}} risultato/i per {{query}}:", + "resultTooltip": "Punteggio di somiglianza: {{score}} (clicca per aprire il file)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 572f99cbb0..3340371c51 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "URL Ollama:", "qdrantUrlLabel": "URL Qdrant", "qdrantKeyLabel": "Chiave Qdrant:", + "advancedConfigLabel": "Configurazione avanzata", + "searchMinScoreLabel": "Soglia punteggio di ricerca", + "searchMinScoreDescription": "Punteggio minimo di somiglianza (0.0-1.0) richiesto per i risultati della ricerca. Valori piรน bassi restituiscono piรน risultati ma potrebbero essere meno pertinenti. Valori piรน alti restituiscono meno risultati ma piรน pertinenti.", + "searchMinScoreResetTooltip": "Ripristina al valore predefinito (0.4)", "startIndexingButton": "Avvia indicizzazione", "clearIndexDataButton": "Cancella dati indice", "unsavedSettingsMessage": "Per favore salva le tue impostazioni prima di avviare il processo di indicizzazione.", diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index 255acb717f..894d75c7a0 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Rooใฏใ‚ณใƒผใƒ‰ใƒ™ใƒผใ‚นใง {{query}} ใ‚’ๆคœ็ดขใ—ใŸใ„:", "wantsToSearchWithPath": "Rooใฏ {{path}} ๅ†…ใฎใ‚ณใƒผใƒ‰ใƒ™ใƒผใ‚นใง {{query}} ใ‚’ๆคœ็ดขใ—ใŸใ„:", - "didSearch": "{{query}} ใฎๆคœ็ดข็ตๆžœ: {{count}} ไปถ" + "didSearch": "{{query}} ใฎๆคœ็ดข็ตๆžœ: {{count}} ไปถ", + "resultTooltip": "้กžไผผๅบฆใ‚นใ‚ณใ‚ข: {{score}} (ใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆใƒ•ใ‚กใ‚คใƒซใ‚’้–‹ใ)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index c6a681e549..9321e174fe 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL๏ผš", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrantใ‚ญใƒผ๏ผš", + "advancedConfigLabel": "่ฉณ็ดฐ่จญๅฎš", + "searchMinScoreLabel": "ๆคœ็ดขใ‚นใ‚ณใ‚ขใฎใ—ใใ„ๅ€ค", + "searchMinScoreDescription": "ๆคœ็ดข็ตๆžœใซๅฟ…่ฆใชๆœ€ๅฐ้กžไผผๅบฆใ‚นใ‚ณใ‚ข๏ผˆ0.0-1.0๏ผ‰ใ€‚ๅ€คใ‚’ไฝŽใใ™ใ‚‹ใจใ‚ˆใ‚Šๅคšใใฎ็ตๆžœใŒ่ฟ”ใ•ใ‚Œใพใ™ใŒใ€้–ข้€ฃๆ€งใŒไฝŽใใชใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚ๅ€คใ‚’้ซ˜ใใ™ใ‚‹ใจ่ฟ”ใ•ใ‚Œใ‚‹็ตๆžœใฏๅฐ‘ใชใใชใ‚Šใพใ™ใŒใ€ใ‚ˆใ‚Š้–ข้€ฃๆ€งใŒ้ซ˜ใใชใ‚Šใพใ™ใ€‚", + "searchMinScoreResetTooltip": "ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆๅ€ค๏ผˆ0.4๏ผ‰ใซใƒชใ‚ปใƒƒใƒˆ", "startIndexingButton": "ใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚นไฝœๆˆใ‚’้–‹ๅง‹", "clearIndexDataButton": "ใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚นใƒ‡ใƒผใ‚ฟใ‚’ใ‚ฏใƒชใ‚ข", "unsavedSettingsMessage": "ใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚นไฝœๆˆใƒ—ใƒญใ‚ปใ‚นใ‚’้–‹ๅง‹ใ™ใ‚‹ๅ‰ใซ่จญๅฎšใ‚’ไฟๅญ˜ใ—ใฆใใ ใ•ใ„ใ€‚", diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index b83c400574..64b5833c20 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo๊ฐ€ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ {{query}}์„(๋ฅผ) ๊ฒ€์ƒ‰ํ•˜๊ณ  ์‹ถ์–ดํ•ฉ๋‹ˆ๋‹ค:", "wantsToSearchWithPath": "Roo๊ฐ€ {{path}}์—์„œ {{query}}์„(๋ฅผ) ๊ฒ€์ƒ‰ํ•˜๊ณ  ์‹ถ์–ดํ•ฉ๋‹ˆ๋‹ค:", - "didSearch": "{{query}}์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ {{count}}๊ฐœ ์ฐพ์Œ:" + "didSearch": "{{query}}์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ {{count}}๊ฐœ ์ฐพ์Œ:", + "resultTooltip": "์œ ์‚ฌ๋„ ์ ์ˆ˜: {{score}} (ํด๋ฆญํ•˜์—ฌ ํŒŒ์ผ ์—ด๊ธฐ)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 6ae68428bd..f431df970e 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL:", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrant ํ‚ค:", + "advancedConfigLabel": "๊ณ ๊ธ‰ ๊ตฌ์„ฑ", + "searchMinScoreLabel": "๊ฒ€์ƒ‰ ์ ์ˆ˜ ์ž„๊ณ„๊ฐ’", + "searchMinScoreDescription": "๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์— ํ•„์š”ํ•œ ์ตœ์†Œ ์œ ์‚ฌ๋„ ์ ์ˆ˜(0.0-1.0). ๊ฐ’์ด ๋‚ฎ์„์ˆ˜๋ก ๋” ๋งŽ์€ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜ํ™˜๋˜์ง€๋งŒ ๊ด€๋ จ์„ฑ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ’์ด ๋†’์„์ˆ˜๋ก ๊ฒฐ๊ณผ๋Š” ์ ์ง€๋งŒ ๊ด€๋ จ์„ฑ์ด ๋†’์€ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.", + "searchMinScoreResetTooltip": "๊ธฐ๋ณธ๊ฐ’(0.4)์œผ๋กœ ์žฌ์„ค์ •", "startIndexingButton": "์ธ๋ฑ์‹ฑ ์‹œ์ž‘", "clearIndexDataButton": "์ธ๋ฑ์Šค ๋ฐ์ดํ„ฐ ์ง€์šฐ๊ธฐ", "unsavedSettingsMessage": "์ธ๋ฑ์‹ฑ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ์„ค์ •์„ ์ €์žฅํ•ด ์ฃผ์„ธ์š”.", diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index 4b6877389d..c393d00440 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo wil de codebase doorzoeken op {{query}}:", "wantsToSearchWithPath": "Roo wil de codebase doorzoeken op {{query}} in {{path}}:", - "didSearch": "{{count}} resultaat/resultaten gevonden voor {{query}}:" + "didSearch": "{{count}} resultaat/resultaten gevonden voor {{query}}:", + "resultTooltip": "Gelijkenisscore: {{score}} (klik om bestand te openen)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index c6d1bb7992..9fdf043f33 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL:", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrant-sleutel:", + "advancedConfigLabel": "Geavanceerde configuratie", + "searchMinScoreLabel": "Zoekscore drempel", + "searchMinScoreDescription": "Minimale overeenkomstscore (0.0-1.0) vereist voor zoekresultaten. Lagere waarden leveren meer resultaten op, maar zijn mogelijk minder relevant. Hogere waarden leveren minder, maar relevantere resultaten op.", + "searchMinScoreResetTooltip": "Reset naar standaardwaarde (0.4)", "startIndexingButton": "Indexering starten", "clearIndexDataButton": "Indexgegevens wissen", "unsavedSettingsMessage": "Sla je instellingen op voordat je het indexeringsproces start.", diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index fe1a47156a..03d62ffe59 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo chce przeszukaฤ‡ bazฤ™ kodu w poszukiwaniu {{query}}:", "wantsToSearchWithPath": "Roo chce przeszukaฤ‡ bazฤ™ kodu w poszukiwaniu {{query}} w {{path}}:", - "didSearch": "Znaleziono {{count}} wynik(รณw) dla {{query}}:" + "didSearch": "Znaleziono {{count}} wynik(รณw) dla {{query}}:", + "resultTooltip": "Wynik podobieล„stwa: {{score}} (kliknij, aby otworzyฤ‡ plik)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index b702d7b5a5..d760a88564 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "URL Ollama:", "qdrantUrlLabel": "URL Qdrant", "qdrantKeyLabel": "Klucz Qdrant:", + "advancedConfigLabel": "Konfiguracja zaawansowana", + "searchMinScoreLabel": "Prรณg wyniku wyszukiwania", + "searchMinScoreDescription": "Minimalny wynik podobieล„stwa (0.0-1.0) wymagany dla wynikรณw wyszukiwania. Niลผsze wartoล›ci zwracajฤ… wiฤ™cej wynikรณw, ale mogฤ… byฤ‡ mniej trafne. Wyลผsze wartoล›ci zwracajฤ… mniej wynikรณw, ale bardziej trafnych.", + "searchMinScoreResetTooltip": "Zresetuj do wartoล›ci domyล›lnej (0.4)", "startIndexingButton": "Rozpocznij indeksowanie", "clearIndexDataButton": "Wyczyล›ฤ‡ dane indeksu", "unsavedSettingsMessage": "Zapisz swoje ustawienia przed rozpoczฤ™ciem procesu indeksowania.", diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index f8dd3542c0..9e467fbc98 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo quer pesquisar na base de cรณdigo por {{query}}:", "wantsToSearchWithPath": "Roo quer pesquisar na base de cรณdigo por {{query}} em {{path}}:", - "didSearch": "Encontrado {{count}} resultado(s) para {{query}}:" + "didSearch": "Encontrado {{count}} resultado(s) para {{query}}:", + "resultTooltip": "Pontuaรงรฃo de similaridade: {{score}} (clique para abrir o arquivo)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index be7bfe2d0d..53ffaff53c 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "URL Ollama:", "qdrantUrlLabel": "URL Qdrant", "qdrantKeyLabel": "Chave Qdrant:", + "advancedConfigLabel": "Configuraรงรฃo Avanรงada", + "searchMinScoreLabel": "Limite de pontuaรงรฃo de busca", + "searchMinScoreDescription": "Pontuaรงรฃo mรญnima de similaridade (0.0-1.0) necessรกria para os resultados da busca. Valores mais baixos retornam mais resultados, mas podem ser menos relevantes. Valores mais altos retornam menos resultados, mas mais relevantes.", + "searchMinScoreResetTooltip": "Redefinir para o valor padrรฃo (0.4)", "startIndexingButton": "Iniciar Indexaรงรฃo", "clearIndexDataButton": "Limpar Dados de รndice", "unsavedSettingsMessage": "Por favor, salve suas configuraรงรตes antes de iniciar o processo de indexaรงรฃo.", diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index b07d8d49f7..6bb38b51f5 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo ั…ะพั‡ะตั‚ ะฒั‹ะฟะพะปะฝะธั‚ัŒ ะฟะพะธัะบ ะฒ ะบะพะดะพะฒะพะน ะฑะฐะทะต ะฟะพ {{query}}:", "wantsToSearchWithPath": "Roo ั…ะพั‡ะตั‚ ะฒั‹ะฟะพะปะฝะธั‚ัŒ ะฟะพะธัะบ ะฒ ะบะพะดะพะฒะพะน ะฑะฐะทะต ะฟะพ {{query}} ะฒ {{path}}:", - "didSearch": "ะะฐะนะดะตะฝะพ {{count}} ั€ะตะทัƒะปัŒั‚ะฐั‚(ะพะฒ) ะดะปั {{query}}:" + "didSearch": "ะะฐะนะดะตะฝะพ {{count}} ั€ะตะทัƒะปัŒั‚ะฐั‚(ะพะฒ) ะดะปั {{query}}:", + "resultTooltip": "ะžั†ะตะฝะบะฐ ัั…ะพะถะตัั‚ะธ: {{score}} (ะฝะฐะถะผะธั‚ะต, ั‡ั‚ะพะฑั‹ ะพั‚ะบั€ั‹ั‚ัŒ ั„ะฐะนะป)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index b0693f4532..2033d18ce7 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "URL Ollama:", "qdrantUrlLabel": "URL Qdrant", "qdrantKeyLabel": "ะšะปัŽั‡ Qdrant:", + "advancedConfigLabel": "ะ ะฐััˆะธั€ะตะฝะฝะฐั ะบะพะฝั„ะธะณัƒั€ะฐั†ะธั", + "searchMinScoreLabel": "ะŸะพั€ะพะณ ะพั†ะตะฝะบะธ ะฟะพะธัะบะฐ", + "searchMinScoreDescription": "ะœะธะฝะธะผะฐะปัŒะฝั‹ะน ะฑะฐะปะป ัั…ะพะดัั‚ะฒะฐ (0.0-1.0), ะฝะตะพะฑั…ะพะดะธะผั‹ะน ะดะปั ั€ะตะทัƒะปัŒั‚ะฐั‚ะพะฒ ะฟะพะธัะบะฐ. ะ‘ะพะปะตะต ะฝะธะทะบะธะต ะทะฝะฐั‡ะตะฝะธั ะฒะพะทะฒั€ะฐั‰ะฐัŽั‚ ะฑะพะปัŒัˆะต ั€ะตะทัƒะปัŒั‚ะฐั‚ะพะฒ, ะฝะพ ะพะฝะธ ะผะพะณัƒั‚ ะฑั‹ั‚ัŒ ะผะตะฝะตะต ั€ะตะปะตะฒะฐะฝั‚ะฝั‹ะผะธ. ะ‘ะพะปะตะต ะฒั‹ัะพะบะธะต ะทะฝะฐั‡ะตะฝะธั ะฒะพะทะฒั€ะฐั‰ะฐัŽั‚ ะผะตะฝัŒัˆะต ั€ะตะทัƒะปัŒั‚ะฐั‚ะพะฒ, ะฝะพ ะฑะพะปะตะต ั€ะตะปะตะฒะฐะฝั‚ะฝั‹ั….", + "searchMinScoreResetTooltip": "ะกะฑั€ะพัะธั‚ัŒ ะบ ะทะฝะฐั‡ะตะฝะธัŽ ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ (0.4)", "startIndexingButton": "ะะฐั‡ะฐั‚ัŒ ะธะฝะดะตะบัะฐั†ะธัŽ", "clearIndexDataButton": "ะžั‡ะธัั‚ะธั‚ัŒ ะดะฐะฝะฝั‹ะต ะธะฝะดะตะบัะฐ", "unsavedSettingsMessage": "ะŸะพะถะฐะปัƒะนัั‚ะฐ, ัะพั…ั€ะฐะฝะธ ะฝะฐัั‚ั€ะพะนะบะธ ะฟะตั€ะตะด ะทะฐะฟัƒัะบะพะผ ะฟั€ะพั†ะตััะฐ ะธะฝะดะตะบัะฐั†ะธะธ.", diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index f5625842b1..ec0311265d 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo kod tabanฤฑnda {{query}} aramak istiyor:", "wantsToSearchWithPath": "Roo {{path}} iรงinde kod tabanฤฑnda {{query}} aramak istiyor:", - "didSearch": "{{query}} iรงin {{count}} sonuรง bulundu:" + "didSearch": "{{query}} iรงin {{count}} sonuรง bulundu:", + "resultTooltip": "Benzerlik puanฤฑ: {{score}} (dosyayฤฑ aรงmak iรงin tฤฑklayฤฑn)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 06bd626406..338e18fd36 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL:", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrant Anahtarฤฑ:", + "advancedConfigLabel": "GeliลŸmiลŸ Yapฤฑlandฤฑrma", + "searchMinScoreLabel": "Arama Skoru EลŸiฤŸi", + "searchMinScoreDescription": "Arama sonuรงlarฤฑ iรงin gereken minimum benzerlik puanฤฑ (0.0-1.0). DรผลŸรผk deฤŸerler daha fazla sonuรง dรถndรผrรผr ancak daha az alakalฤฑ olabilir. Yรผksek deฤŸerler daha az ancak daha alakalฤฑ sonuรงlar dรถndรผrรผr.", + "searchMinScoreResetTooltip": "Varsayฤฑlan deฤŸere sฤฑfฤฑrla (0.4)", "startIndexingButton": "ฤฐndekslemeyi BaลŸlat", "clearIndexDataButton": "ฤฐndeks Verilerini Temizle", "unsavedSettingsMessage": "ฤฐndeksleme iลŸlemini baลŸlatmadan รถnce lรผtfen ayarlarฤฑnฤฑ kaydet.", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index 05f9ed8a3d..c8cc05aaae 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo muแป‘n tรฌm kiแบฟm trong cฦก sแปŸ mรฃ cho {{query}}:", "wantsToSearchWithPath": "Roo muแป‘n tรฌm kiแบฟm trong cฦก sแปŸ mรฃ cho {{query}} trong {{path}}:", - "didSearch": "ฤรฃ tรฌm thแบฅy {{count}} kแบฟt quแบฃ cho {{query}}:" + "didSearch": "ฤรฃ tรฌm thแบฅy {{count}} kแบฟt quแบฃ cho {{query}}:", + "resultTooltip": "ฤiแปƒm tฦฐฦกng tแปฑ: {{score}} (nhแบฅp ฤ‘แปƒ mแปŸ tแป‡p)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index c434276b3b..413ace0339 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "URL Ollama:", "qdrantUrlLabel": "URL Qdrant", "qdrantKeyLabel": "Khรณa Qdrant:", + "advancedConfigLabel": "Cแบฅu hรฌnh nรขng cao", + "searchMinScoreLabel": "Ngฦฐแปกng ฤ‘iแปƒm tรฌm kiแบฟm", + "searchMinScoreDescription": "ฤiแปƒm tฦฐฦกng ฤ‘แป“ng tแป‘i thiแปƒu (0.0-1.0) cแบงn thiแบฟt cho kแบฟt quแบฃ tรฌm kiแบฟm. Giรก trแป‹ thแบฅp hฦกn trแบฃ vแป nhiแปu kแบฟt quแบฃ hฦกn nhฦฐng cรณ thแปƒ kรฉm liรชn quan hฦกn. Giรก trแป‹ cao hฦกn trแบฃ vแป รญt kแบฟt quแบฃ hฦกn nhฦฐng cรณ liรชn quan hฦกn.", + "searchMinScoreResetTooltip": "ฤแบทt lแบกi vแป giรก trแป‹ mแบทc ฤ‘แป‹nh (0.4)", "startIndexingButton": "Bแบฏt ฤ‘แบงu lแบญp chแป‰ mแปฅc", "clearIndexDataButton": "Xรณa dแปฏ liแป‡u chแป‰ mแปฅc", "unsavedSettingsMessage": "Vui lรฒng lฦฐu cร i ฤ‘แบทt cแปงa bแบกn trฦฐแป›c khi bแบฏt ฤ‘แบงu quรก trรฌnh lแบญp chแป‰ mแปฅc.", diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index d85c633699..038f239f07 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo ้œ€่ฆๆœ็ดขไปฃ็ ๅบ“: {{query}}", "wantsToSearchWithPath": "Roo ้œ€่ฆๅœจ {{path}} ไธญๆœ็ดข: {{query}}", - "didSearch": "ๆ‰พๅˆฐ {{count}} ไธช็ป“ๆžœ: {{query}}" + "didSearch": "ๆ‰พๅˆฐ {{count}} ไธช็ป“ๆžœ: {{query}}", + "resultTooltip": "็›ธไผผๅบฆ่ฏ„ๅˆ†: {{score}} (็‚นๅ‡ปๆ‰“ๅผ€ๆ–‡ไปถ)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 80bcab26eb..38299eb124 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL๏ผš", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrant ๅฏ†้’ฅ๏ผš", + "advancedConfigLabel": "้ซ˜็บง้…็ฝฎ", + "searchMinScoreLabel": "ๆœ็ดขๅˆ†ๆ•ฐ้˜ˆๅ€ผ", + "searchMinScoreDescription": "ๆœ็ดข็ป“ๆžœๆ‰€้œ€็š„ๆœ€ไฝŽ็›ธไผผๅบฆๅˆ†ๆ•ฐ๏ผˆ0.0-1.0๏ผ‰ใ€‚่พƒไฝŽ็š„ๅ€ผ่ฟ”ๅ›žๆ›ดๅคš็ป“ๆžœ๏ผŒไฝ†ๅฏ่ƒฝไธๅคช็›ธๅ…ณใ€‚่พƒ้ซ˜็š„ๅ€ผ่ฟ”ๅ›ž่พƒๅฐ‘ไฝ†ๆ›ด็›ธๅ…ณ็š„็ป“ๆžœใ€‚", + "searchMinScoreResetTooltip": "ๆขๅค้ป˜่ฎคๅ€ผ (0.4)", "startIndexingButton": "ๅผ€ๅง‹็ดขๅผ•", "clearIndexDataButton": "ๆธ…้™ค็ดขๅผ•ๆ•ฐๆฎ", "unsavedSettingsMessage": "่ฏทๅ…ˆไฟๅญ˜่ฎพ็ฝฎๅ†ๅผ€ๅง‹็ดขๅผ•่ฟ‡็จ‹ใ€‚", diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index b3659f6869..298a3b76f4 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -294,7 +294,8 @@ "codebaseSearch": { "wantsToSearch": "Roo ๆƒณ่ฆๆœๅฐ‹็จ‹ๅผ็ขผๅบซ๏ผš{{query}}", "wantsToSearchWithPath": "Roo ๆƒณ่ฆๅœจ {{path}} ไธญๆœๅฐ‹๏ผš{{query}}", - "didSearch": "ๆ‰พๅˆฐ {{count}} ๅ€‹็ตๆžœ๏ผš{{query}}" + "didSearch": "ๆ‰พๅˆฐ {{count}} ๅ€‹็ตๆžœ๏ผš{{query}}", + "resultTooltip": "็›ธไผผๅบฆ่ฉ•ๅˆ†๏ผš{{score}} (้ปžๆ“Š้–‹ๅ•Ÿๆช”ๆกˆ)" }, "read-batch": { "approve": { diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 033230ebb4..e7b902a7d9 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -56,6 +56,10 @@ "ollamaUrlLabel": "Ollama URL๏ผš", "qdrantUrlLabel": "Qdrant URL", "qdrantKeyLabel": "Qdrant ้‡‘้‘ฐ๏ผš", + "advancedConfigLabel": "้€ฒ้šŽ่จญๅฎš", + "searchMinScoreLabel": "ๆœๅฐ‹ๅˆ†ๆ•ธ้–พๅ€ผ", + "searchMinScoreDescription": "ๆœๅฐ‹็ตๆžœๆ‰€้œ€็š„ๆœ€ไฝŽ็›ธไผผๅบฆๅˆ†ๆ•ธ๏ผˆ0.0-1.0๏ผ‰ใ€‚่ผƒไฝŽ็š„ๅ€ผๆœƒๅ‚ณๅ›žๆ›ดๅคš็ตๆžœ๏ผŒไฝ†ๅฏ่ƒฝ่ผƒไธ็›ธ้—œใ€‚่ผƒ้ซ˜็š„ๅ€ผๆœƒๅ‚ณๅ›ž่ผƒๅฐ‘ไฝ†ๆ›ด็›ธ้—œ็š„็ตๆžœใ€‚", + "searchMinScoreResetTooltip": "้‡่จญ็‚บ้ ่จญๅ€ผ (0.4)", "startIndexingButton": "้–‹ๅง‹็ดขๅผ•", "clearIndexDataButton": "ๆธ…้™ค็ดขๅผ•่ณ‡ๆ–™", "unsavedSettingsMessage": "่ซ‹ๅ…ˆๅ„ฒๅญ˜่จญๅฎšๅ†้–‹ๅง‹็ดขๅผ•็จ‹ๅบใ€‚", From 781beeb30fcb3ddb59343e2d2599e26f30161526 Mon Sep 17 00:00:00 2001 From: Will Li Date: Tue, 1 Jul 2025 11:43:16 -0700 Subject: [PATCH 48/70] Auto approve follow up questions (#5296) --- packages/types/src/followup.ts | 41 +++++++ packages/types/src/global-settings.ts | 4 + packages/types/src/index.ts | 1 + src/core/webview/ClineProvider.ts | 6 + src/core/webview/webviewMessageHandler.ts | 8 ++ src/shared/WebviewMessage.ts | 2 + .../src/components/chat/AutoApproveMenu.tsx | 8 ++ webview-ui/src/components/chat/ChatRow.tsx | 8 +- webview-ui/src/components/chat/ChatView.tsx | 99 +++++++++++++--- .../src/components/chat/FollowUpSuggest.tsx | 109 +++++++++++++----- .../settings/AutoApproveSettings.tsx | 34 ++++++ .../components/settings/AutoApproveToggle.tsx | 13 ++- .../src/components/settings/SettingsView.tsx | 6 + .../__tests__/AutoApproveToggle.spec.tsx | 1 + .../src/context/ExtensionStateContext.tsx | 19 +++ webview-ui/src/i18n/locales/ca/chat.json | 4 +- webview-ui/src/i18n/locales/ca/settings.json | 5 + webview-ui/src/i18n/locales/de/chat.json | 4 +- webview-ui/src/i18n/locales/de/settings.json | 5 + webview-ui/src/i18n/locales/en/chat.json | 4 +- webview-ui/src/i18n/locales/en/settings.json | 5 + webview-ui/src/i18n/locales/es/chat.json | 4 +- webview-ui/src/i18n/locales/es/settings.json | 5 + webview-ui/src/i18n/locales/fr/chat.json | 4 +- webview-ui/src/i18n/locales/fr/settings.json | 5 + webview-ui/src/i18n/locales/hi/chat.json | 4 +- webview-ui/src/i18n/locales/hi/settings.json | 5 + webview-ui/src/i18n/locales/id/chat.json | 4 +- webview-ui/src/i18n/locales/id/settings.json | 5 + webview-ui/src/i18n/locales/it/chat.json | 4 +- webview-ui/src/i18n/locales/it/settings.json | 5 + webview-ui/src/i18n/locales/ja/chat.json | 4 +- webview-ui/src/i18n/locales/ja/settings.json | 5 + webview-ui/src/i18n/locales/ko/chat.json | 4 +- webview-ui/src/i18n/locales/ko/settings.json | 5 + webview-ui/src/i18n/locales/nl/chat.json | 4 +- webview-ui/src/i18n/locales/nl/settings.json | 5 + webview-ui/src/i18n/locales/pl/chat.json | 4 +- webview-ui/src/i18n/locales/pl/settings.json | 5 + webview-ui/src/i18n/locales/pt-BR/chat.json | 4 +- .../src/i18n/locales/pt-BR/settings.json | 5 + webview-ui/src/i18n/locales/ru/chat.json | 4 +- webview-ui/src/i18n/locales/ru/settings.json | 5 + webview-ui/src/i18n/locales/tr/chat.json | 4 +- webview-ui/src/i18n/locales/tr/settings.json | 5 + webview-ui/src/i18n/locales/vi/chat.json | 4 +- webview-ui/src/i18n/locales/vi/settings.json | 5 + webview-ui/src/i18n/locales/zh-CN/chat.json | 4 +- .../src/i18n/locales/zh-CN/settings.json | 5 + webview-ui/src/i18n/locales/zh-TW/chat.json | 4 +- .../src/i18n/locales/zh-TW/settings.json | 5 + 51 files changed, 453 insertions(+), 68 deletions(-) create mode 100644 packages/types/src/followup.ts diff --git a/packages/types/src/followup.ts b/packages/types/src/followup.ts new file mode 100644 index 0000000000..1a5424cd11 --- /dev/null +++ b/packages/types/src/followup.ts @@ -0,0 +1,41 @@ +import { z } from "zod" + +/** + * Interface for follow-up data structure used in follow-up questions + * This represents the data structure for follow-up questions that the LLM can ask + * to gather more information needed to complete a task. + */ +export interface FollowUpData { + /** The question being asked by the LLM */ + question?: string + /** Array of suggested answers that the user can select */ + suggest?: Array +} + +/** + * Interface for a suggestion item with optional mode switching + */ +export interface SuggestionItem { + /** The text of the suggestion */ + answer: string + /** Optional mode to switch to when selecting this suggestion */ + mode?: string +} + +/** + * Zod schema for SuggestionItem + */ +export const suggestionItemSchema = z.object({ + answer: z.string(), + mode: z.string().optional(), +}) + +/** + * Zod schema for FollowUpData + */ +export const followUpDataSchema = z.object({ + question: z.string().optional(), + suggest: z.array(suggestionItemSchema).optional(), +}) + +export type FollowUpDataType = z.infer diff --git a/packages/types/src/global-settings.ts b/packages/types/src/global-settings.ts index e713cafa4c..7cd051c6bf 100644 --- a/packages/types/src/global-settings.ts +++ b/packages/types/src/global-settings.ts @@ -45,6 +45,8 @@ export const globalSettingsSchema = z.object({ alwaysAllowModeSwitch: z.boolean().optional(), alwaysAllowSubtasks: z.boolean().optional(), alwaysAllowExecute: z.boolean().optional(), + alwaysAllowFollowupQuestions: z.boolean().optional(), + followupAutoApproveTimeoutMs: z.number().optional(), allowedCommands: z.array(z.string()).optional(), allowedMaxRequests: z.number().nullish(), autoCondenseContext: z.boolean().optional(), @@ -189,6 +191,8 @@ export const EVALS_SETTINGS: RooCodeSettings = { alwaysAllowModeSwitch: true, alwaysAllowSubtasks: true, alwaysAllowExecute: true, + alwaysAllowFollowupQuestions: true, + followupAutoApproveTimeoutMs: 0, allowedCommands: ["*"], browserToolEnabled: false, diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 345bc3e311..6c6db9ccd5 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -4,6 +4,7 @@ export * from "./api.js" export * from "./codebase-index.js" export * from "./cloud.js" export * from "./experiment.js" +export * from "./followup.js" export * from "./global-settings.js" export * from "./history.js" export * from "./ipc.js" diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 51cb9a275b..9d99eea1d4 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1411,6 +1411,8 @@ export class ClineProvider codebaseIndexConfig, codebaseIndexModels, profileThresholds, + alwaysAllowFollowupQuestions, + followupAutoApproveTimeoutMs, } = await this.getState() const telemetryKey = process.env.POSTHOG_API_KEY @@ -1521,6 +1523,8 @@ export class ClineProvider profileThresholds: profileThresholds ?? {}, cloudApiUrl: getRooCodeApiUrl(), hasOpenedModeSelector: this.getGlobalState("hasOpenedModeSelector") ?? false, + alwaysAllowFollowupQuestions: alwaysAllowFollowupQuestions ?? false, + followupAutoApproveTimeoutMs: followupAutoApproveTimeoutMs ?? 60000, } } @@ -1601,6 +1605,8 @@ export class ClineProvider alwaysAllowMcp: stateValues.alwaysAllowMcp ?? false, alwaysAllowModeSwitch: stateValues.alwaysAllowModeSwitch ?? false, alwaysAllowSubtasks: stateValues.alwaysAllowSubtasks ?? false, + alwaysAllowFollowupQuestions: stateValues.alwaysAllowFollowupQuestions ?? false, + followupAutoApproveTimeoutMs: stateValues.followupAutoApproveTimeoutMs ?? 60000, allowedMaxRequests: stateValues.allowedMaxRequests, autoCondenseContext: stateValues.autoCondenseContext ?? true, autoCondenseContextPercent: stateValues.autoCondenseContextPercent ?? 100, diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index cac94aa0ce..af053044b2 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -1100,6 +1100,14 @@ export const webviewMessageHandler = async ( await updateGlobalState("maxWorkspaceFiles", fileCount) await provider.postStateToWebview() break + case "alwaysAllowFollowupQuestions": + await updateGlobalState("alwaysAllowFollowupQuestions", message.bool ?? false) + await provider.postStateToWebview() + break + case "followupAutoApproveTimeoutMs": + await updateGlobalState("followupAutoApproveTimeoutMs", message.value) + await provider.postStateToWebview() + break case "browserToolEnabled": await updateGlobalState("browserToolEnabled", message.bool ?? true) await provider.postStateToWebview() diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 7efc97e8c7..42718595c3 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -37,6 +37,8 @@ export interface WebviewMessage { | "alwaysAllowWriteOutsideWorkspace" | "alwaysAllowWriteProtected" | "alwaysAllowExecute" + | "alwaysAllowFollowupQuestions" + | "followupAutoApproveTimeoutMs" | "webviewDidLaunch" | "newTask" | "askResponse" diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index ac02d6b8c4..8d838f0a18 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -25,6 +25,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { alwaysAllowModeSwitch, alwaysAllowSubtasks, alwaysApproveResubmit, + alwaysAllowFollowupQuestions, allowedMaxRequests, setAlwaysAllowReadOnly, setAlwaysAllowWrite, @@ -34,6 +35,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { setAlwaysAllowModeSwitch, setAlwaysAllowSubtasks, setAlwaysApproveResubmit, + setAlwaysAllowFollowupQuestions, setAllowedMaxRequests, } = useExtensionState() @@ -68,6 +70,9 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { case "alwaysApproveResubmit": setAlwaysApproveResubmit(value) break + case "alwaysAllowFollowupQuestions": + setAlwaysAllowFollowupQuestions(value) + break } }, [ @@ -79,6 +84,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { setAlwaysAllowModeSwitch, setAlwaysAllowSubtasks, setAlwaysApproveResubmit, + setAlwaysAllowFollowupQuestions, ], ) @@ -94,6 +100,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { alwaysAllowModeSwitch: alwaysAllowModeSwitch, alwaysAllowSubtasks: alwaysAllowSubtasks, alwaysApproveResubmit: alwaysApproveResubmit, + alwaysAllowFollowupQuestions: alwaysAllowFollowupQuestions, }), [ alwaysAllowReadOnly, @@ -104,6 +111,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { alwaysAllowModeSwitch, alwaysAllowSubtasks, alwaysApproveResubmit, + alwaysAllowFollowupQuestions, ], ) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 43824c5902..f61eb8c5e0 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -10,6 +10,7 @@ import type { ClineMessage } from "@roo-code/types" import { ClineApiReqInfo, ClineAskUseMcpServer, ClineSayTool } from "@roo/ExtensionMessage" import { COMMAND_OUTPUT_STRING } from "@roo/combineCommandSequences" import { safeJsonParse } from "@roo/safeJsonParse" +import { FollowUpData, SuggestionItem } from "@roo-code/types" import { useCopyToClipboard } from "@src/utils/clipboard" import { useExtensionState } from "@src/context/ExtensionStateContext" @@ -48,8 +49,9 @@ interface ChatRowProps { isStreaming: boolean onToggleExpand: (ts: number) => void onHeightChange: (isTaller: boolean) => void - onSuggestionClick?: (answer: string, event?: React.MouseEvent) => void + onSuggestionClick?: (suggestion: SuggestionItem, event?: React.MouseEvent) => void onBatchFileResponse?: (response: { [key: string]: boolean }) => void + onFollowUpUnmount?: () => void } // eslint-disable-next-line @typescript-eslint/no-empty-object-type @@ -98,6 +100,7 @@ export const ChatRowContent = ({ isStreaming, onToggleExpand, onSuggestionClick, + onFollowUpUnmount, onBatchFileResponse, }: ChatRowContentProps) => { const { t } = useTranslation() @@ -279,7 +282,7 @@ export const ChatRowContent = ({ const followUpData = useMemo(() => { if (message.type === "ask" && message.ask === "followup" && !message.partial) { - return safeJsonParse(message.text) + return safeJsonParse(message.text) } return null }, [message.type, message.ask, message.partial, message.text]) @@ -1215,6 +1218,7 @@ export const ChatRowContent = ({ suggestions={followUpData?.suggest} onSuggestionClick={onSuggestionClick} ts={message?.ts} + onUnmount={onFollowUpUnmount} /> ) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 85770c82c5..874f0de3c2 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -15,6 +15,7 @@ import type { ClineAsk, ClineMessage } from "@roo-code/types" import { ClineSayBrowserAction, ClineSayTool, ExtensionMessage } from "@roo/ExtensionMessage" import { McpServer, McpTool } from "@roo/mcp" import { findLast } from "@roo/array" +import { FollowUpData, SuggestionItem } from "@roo-code/types" import { combineApiRequests } from "@roo/combineApiRequests" import { combineCommandSequences } from "@roo/combineCommandSequences" import { getApiMetrics } from "@roo/getApiMetrics" @@ -88,11 +89,13 @@ const ChatViewComponent: React.ForwardRefRenderFunction { + // Update local state and notify extension to sync mode change + setMode(modeSlug) + + // Send the mode switch message + vscode.postMessage({ + type: "mode", + text: modeSlug, + }) + }, + [setMode], + ) + const handleSuggestionClickInRow = useCallback( - (answer: string, event?: React.MouseEvent) => { + (suggestion: SuggestionItem, event?: React.MouseEvent) => { + // Check if we need to switch modes + if (suggestion.mode) { + // Only switch modes if it's a manual click (event exists) or auto-approval is allowed + const isManualClick = !!event + if (isManualClick || alwaysAllowModeSwitch) { + // Switch mode without waiting + switchToMode(suggestion.mode) + } + } + if (event?.shiftKey) { // Always append to existing text, don't overwrite setInputValue((currentValue) => { - return currentValue !== "" ? `${currentValue} \n${answer}` : answer + return currentValue !== "" ? `${currentValue} \n${suggestion.answer}` : suggestion.answer }) } else { - handleSendMessage(answer, []) + handleSendMessage(suggestion.answer, []) } }, - [handleSendMessage, setInputValue], // setInputValue is stable, handleSendMessage depends on clineAsk + [handleSendMessage, setInputValue, switchToMode, alwaysAllowModeSwitch], ) const handleBatchFileResponse = useCallback((response: { [key: string]: boolean }) => { @@ -1208,6 +1241,15 @@ const ChatViewComponent: React.ForwardRefRenderFunction { + // Clear the auto-approve timeout to prevent race conditions + if (autoApproveTimeoutRef.current) { + clearTimeout(autoApproveTimeoutRef.current) + autoApproveTimeoutRef.current = null + } + }, []) + const itemContent = useCallback( (index: number, messageOrGroup: ClineMessage | ClineMessage[]) => { // browser session group @@ -1243,6 +1285,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction ) }, @@ -1255,6 +1298,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction { if (lastMessage?.ask && isAutoApproved(lastMessage)) { - if (lastMessage.ask === "tool" && isWriteToolAction(lastMessage)) { + // Special handling for follow-up questions + if (lastMessage.ask === "followup") { + // Handle invalid JSON + let followUpData: FollowUpData = {} + try { + followUpData = JSON.parse(lastMessage.text || "{}") as FollowUpData + } catch (error) { + console.error("Failed to parse follow-up data:", error) + return + } + + if (followUpData && followUpData.suggest && followUpData.suggest.length > 0) { + // Wait for the configured timeout before auto-selecting the first suggestion + await new Promise((resolve) => { + autoApproveTimeoutRef.current = setTimeout(resolve, followupAutoApproveTimeoutMs) + }) + + // Get the first suggestion + const firstSuggestion = followUpData.suggest[0] + + // Handle the suggestion click + handleSuggestionClickInRow(firstSuggestion) + return + } + } else if (lastMessage.ask === "tool" && isWriteToolAction(lastMessage)) { await new Promise((resolve) => { autoApproveTimeoutRef.current = setTimeout(resolve, writeDelayMs) }) } - if (autoApproveTimeoutRef.current === null || autoApproveTimeoutRef.current) { - vscode.postMessage({ type: "askResponse", askResponse: "yesButtonClicked" }) + vscode.postMessage({ type: "askResponse", askResponse: "yesButtonClicked" }) - setSendingDisabled(true) - setClineAsk(undefined) - setEnableButtons(false) - } + setSendingDisabled(true) + setClineAsk(undefined) + setEnableButtons(false) } } autoApprove() @@ -1303,6 +1369,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction m.slug === mode) const nextModeIndex = (currentModeIndex + 1) % allModes.length // Update local state and notify extension to sync mode change - setMode(allModes[nextModeIndex].slug) - vscode.postMessage({ - type: "mode", - text: allModes[nextModeIndex].slug, - }) - }, [mode, setMode, customModes]) + switchToMode(allModes[nextModeIndex].slug) + }, [mode, customModes, switchToMode]) // Add keyboard event handler const handleKeyDown = useCallback( diff --git a/webview-ui/src/components/chat/FollowUpSuggest.tsx b/webview-ui/src/components/chat/FollowUpSuggest.tsx index 6e1ec58814..5649da744a 100644 --- a/webview-ui/src/components/chat/FollowUpSuggest.tsx +++ b/webview-ui/src/components/chat/FollowUpSuggest.tsx @@ -1,40 +1,85 @@ -import { useCallback } from "react" +import { useCallback, useEffect, useState } from "react" import { Edit } from "lucide-react" import { Button, StandardTooltip } from "@/components/ui" -import { vscode } from "@/utils/vscode" import { useAppTranslation } from "@src/i18n/TranslationContext" +import { useExtensionState } from "@src/context/ExtensionStateContext" +import { SuggestionItem } from "@roo-code/types" -interface SuggestionItem { - answer: string - mode?: string -} +const DEFAULT_FOLLOWUP_TIMEOUT_MS = 60000 +const COUNTDOWN_INTERVAL_MS = 1000 interface FollowUpSuggestProps { - suggestions?: (string | SuggestionItem)[] - onSuggestionClick?: (answer: string, event?: React.MouseEvent) => void + suggestions?: SuggestionItem[] + onSuggestionClick?: (suggestion: SuggestionItem, event?: React.MouseEvent) => void ts: number + onUnmount?: () => void } -export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }: FollowUpSuggestProps) => { +export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1, onUnmount }: FollowUpSuggestProps) => { + const { autoApprovalEnabled, alwaysAllowFollowupQuestions, followupAutoApproveTimeoutMs } = useExtensionState() + const [countdown, setCountdown] = useState(null) + const [suggestionSelected, setSuggestionSelected] = useState(false) const { t } = useAppTranslation() - const handleSuggestionClick = useCallback( - (suggestion: string | SuggestionItem, event: React.MouseEvent) => { - const suggestionText = typeof suggestion === "string" ? suggestion : suggestion.answer - const mode = typeof suggestion === "object" ? suggestion.mode : undefined - // If there's a mode switch and it's not a shift-click (which just copies to input), switch modes first - if (mode && !event.shiftKey) { - vscode.postMessage({ - type: "mode", - text: mode, + // Start countdown timer when auto-approval is enabled for follow-up questions + useEffect(() => { + // Only start countdown if auto-approval is enabled for follow-up questions and no suggestion has been selected + if (autoApprovalEnabled && alwaysAllowFollowupQuestions && suggestions.length > 0 && !suggestionSelected) { + // Start with the configured timeout in seconds + const timeoutMs = + typeof followupAutoApproveTimeoutMs === "number" && !isNaN(followupAutoApproveTimeoutMs) + ? followupAutoApproveTimeoutMs + : DEFAULT_FOLLOWUP_TIMEOUT_MS + + // Convert milliseconds to seconds for the countdown + setCountdown(Math.floor(timeoutMs / 1000)) + + // Update countdown every second + const intervalId = setInterval(() => { + setCountdown((prevCountdown) => { + if (prevCountdown === null || prevCountdown <= 1) { + clearInterval(intervalId) + return null + } + return prevCountdown - 1 }) + }, COUNTDOWN_INTERVAL_MS) + + // Clean up interval on unmount and notify parent component + return () => { + clearInterval(intervalId) + // Notify parent component that this component is unmounting + // so it can clear any related timeouts + onUnmount?.() + } + } else { + setCountdown(null) + } + }, [ + autoApprovalEnabled, + alwaysAllowFollowupQuestions, + suggestions, + followupAutoApproveTimeoutMs, + suggestionSelected, + onUnmount, + ]) + const handleSuggestionClick = useCallback( + (suggestion: SuggestionItem, event: React.MouseEvent) => { + // Mark a suggestion as selected if it's not a shift-click (which just copies to input) + if (!event.shiftKey) { + setSuggestionSelected(true) + // Also notify parent component to cancel auto-approval timeout + // This prevents race conditions between visual countdown and actual timeout + onUnmount?.() } - onSuggestionClick?.(suggestionText, event) + // Pass the suggestion object to the parent component + // The parent component will handle mode switching if needed + onSuggestionClick?.(suggestion, event) }, - [onSuggestionClick], + [onSuggestionClick, onUnmount], ) // Don't render if there are no suggestions or no click handler. @@ -44,23 +89,29 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }: return (
- {suggestions.map((suggestion) => { - const suggestionText = typeof suggestion === "string" ? suggestion : suggestion.answer - const mode = typeof suggestion === "object" ? suggestion.mode : undefined + {suggestions.map((suggestion, index) => { + const isFirstSuggestion = index === 0 return ( -
+
- {mode && ( + {suggestion.mode && (
- {mode} + {suggestion.mode}
)} @@ -69,7 +120,7 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }: onClick={(e) => { e.stopPropagation() // Simulate shift-click by directly calling the handler with shiftKey=true. - onSuggestionClick?.(suggestionText, { ...e, shiftKey: true }) + onSuggestionClick?.(suggestion, { ...e, shiftKey: true }) }}>
)} + {alwaysAllowFollowupQuestions && ( +
+
+ +
{t("settings:autoApprove.followupQuestions.label")}
+
+
+
+ + setCachedStateField("followupAutoApproveTimeoutMs", value) + } + data-testid="followup-timeout-slider" + /> + {followupAutoApproveTimeoutMs / 1000}s +
+
+ {t("settings:autoApprove.followupQuestions.timeoutLabel")} +
+
+
+ )} + {alwaysAllowExecute && (
diff --git a/webview-ui/src/components/settings/AutoApproveToggle.tsx b/webview-ui/src/components/settings/AutoApproveToggle.tsx index d2b6694f75..6c82d3c984 100644 --- a/webview-ui/src/components/settings/AutoApproveToggle.tsx +++ b/webview-ui/src/components/settings/AutoApproveToggle.tsx @@ -14,6 +14,7 @@ type AutoApproveToggles = Pick< | "alwaysAllowModeSwitch" | "alwaysAllowSubtasks" | "alwaysAllowExecute" + | "alwaysAllowFollowupQuestions" > export type AutoApproveSetting = keyof AutoApproveToggles @@ -83,6 +84,13 @@ export const autoApproveSettingsConfig: Record {Object.values(autoApproveSettingsConfig).map(({ key, descriptionKey, labelKey, icon, testId }) => ( diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 8712b81cf2..c3b9179e37 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -174,6 +174,8 @@ const SettingsView = forwardRef(({ onDone, t codebaseIndexModels, customSupportPrompts, profileThresholds, + alwaysAllowFollowupQuestions, + followupAutoApproveTimeoutMs, } = cachedState const apiConfiguration = useMemo(() => cachedState.apiConfiguration ?? {}, [cachedState.apiConfiguration]) @@ -311,6 +313,8 @@ const SettingsView = forwardRef(({ onDone, t vscode.postMessage({ type: "updateExperimental", values: experiments }) vscode.postMessage({ type: "alwaysAllowModeSwitch", bool: alwaysAllowModeSwitch }) vscode.postMessage({ type: "alwaysAllowSubtasks", bool: alwaysAllowSubtasks }) + vscode.postMessage({ type: "alwaysAllowFollowupQuestions", bool: alwaysAllowFollowupQuestions }) + vscode.postMessage({ type: "followupAutoApproveTimeoutMs", value: followupAutoApproveTimeoutMs }) vscode.postMessage({ type: "condensingApiConfigId", text: condensingApiConfigId || "" }) vscode.postMessage({ type: "updateCondensingPrompt", text: customCondensingPrompt || "" }) vscode.postMessage({ type: "updateSupportPrompt", values: customSupportPrompts || {} }) @@ -599,6 +603,8 @@ const SettingsView = forwardRef(({ onDone, t alwaysAllowModeSwitch={alwaysAllowModeSwitch} alwaysAllowSubtasks={alwaysAllowSubtasks} alwaysAllowExecute={alwaysAllowExecute} + alwaysAllowFollowupQuestions={alwaysAllowFollowupQuestions} + followupAutoApproveTimeoutMs={followupAutoApproveTimeoutMs} allowedCommands={allowedCommands} setCachedStateField={setCachedStateField} /> diff --git a/webview-ui/src/components/settings/__tests__/AutoApproveToggle.spec.tsx b/webview-ui/src/components/settings/__tests__/AutoApproveToggle.spec.tsx index 97e5dcc96b..ac8c054f65 100644 --- a/webview-ui/src/components/settings/__tests__/AutoApproveToggle.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/AutoApproveToggle.spec.tsx @@ -25,6 +25,7 @@ describe("AutoApproveToggle", () => { alwaysAllowModeSwitch: true, alwaysAllowSubtasks: false, alwaysAllowExecute: true, + alwaysAllowFollowupQuestions: false, onToggle: mockOnToggle, } diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index c87ccdb6e9..ea3c6208d7 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -40,6 +40,10 @@ export interface ExtensionStateContextType extends ExtensionState { mdmCompliant?: boolean hasOpenedModeSelector: boolean // New property to track if user has opened mode selector setHasOpenedModeSelector: (value: boolean) => void // Setter for the new property + alwaysAllowFollowupQuestions: boolean // New property for follow-up questions auto-approve + setAlwaysAllowFollowupQuestions: (value: boolean) => void // Setter for the new property + followupAutoApproveTimeoutMs: number | undefined // Timeout in ms for auto-approving follow-up questions + setFollowupAutoApproveTimeoutMs: (value: number) => void // Setter for the timeout condensingApiConfigId?: string setCondensingApiConfigId: (value: string) => void customCondensingPrompt?: string @@ -226,6 +230,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode const [currentCheckpoint, setCurrentCheckpoint] = useState() const [extensionRouterModels, setExtensionRouterModels] = useState(undefined) const [marketplaceItems, setMarketplaceItems] = useState([]) + const [alwaysAllowFollowupQuestions, setAlwaysAllowFollowupQuestions] = useState(false) // Add state for follow-up questions auto-approve + const [followupAutoApproveTimeoutMs, setFollowupAutoApproveTimeoutMs] = useState(undefined) // Will be set from global settings const [marketplaceInstalledMetadata, setMarketplaceInstalledMetadata] = useState({ project: {}, global: {}, @@ -255,6 +261,14 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode setState((prevState) => mergeExtensionState(prevState, newState)) setShowWelcome(!checkExistKey(newState.apiConfiguration)) setDidHydrateState(true) + // Update alwaysAllowFollowupQuestions if present in state message + if ((newState as any).alwaysAllowFollowupQuestions !== undefined) { + setAlwaysAllowFollowupQuestions((newState as any).alwaysAllowFollowupQuestions) + } + // Update followupAutoApproveTimeoutMs if present in state message + if ((newState as any).followupAutoApproveTimeoutMs !== undefined) { + setFollowupAutoApproveTimeoutMs((newState as any).followupAutoApproveTimeoutMs) + } // Handle marketplace data if present in state message if (newState.marketplaceItems !== undefined) { setMarketplaceItems(newState.marketplaceItems) @@ -352,6 +366,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode marketplaceItems, marketplaceInstalledMetadata, profileThresholds: state.profileThresholds ?? {}, + alwaysAllowFollowupQuestions, + followupAutoApproveTimeoutMs, setExperimentEnabled: (id, enabled) => setState((prevState) => ({ ...prevState, experiments: { ...prevState.experiments, [id]: enabled } })), setApiConfiguration, @@ -367,6 +383,9 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode setAlwaysAllowMcp: (value) => setState((prevState) => ({ ...prevState, alwaysAllowMcp: value })), setAlwaysAllowModeSwitch: (value) => setState((prevState) => ({ ...prevState, alwaysAllowModeSwitch: value })), setAlwaysAllowSubtasks: (value) => setState((prevState) => ({ ...prevState, alwaysAllowSubtasks: value })), + setAlwaysAllowFollowupQuestions, + setFollowupAutoApproveTimeoutMs: (value) => + setState((prevState) => ({ ...prevState, followupAutoApproveTimeoutMs: value })), setShowAnnouncement: (value) => setState((prevState) => ({ ...prevState, shouldShowAnnouncement: value })), setAllowedCommands: (value) => setState((prevState) => ({ ...prevState, allowedCommands: value })), setAllowedMaxRequests: (value) => setState((prevState) => ({ ...prevState, allowedMaxRequests: value })), diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 82d8a2fffd..dbcd9e69dd 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -234,7 +234,9 @@ "tokens": "tokens" }, "followUpSuggest": { - "copyToInput": "Copiar a l'entrada (o Shift + clic)" + "copyToInput": "Copiar a l'entrada (o Shift + clic)", + "autoSelectCountdown": "Selecciรณ automร tica en {{count}}s", + "countdownDisplay": "{{count}}s" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} publicat", diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index 7cee95070b..3fe9cd78b9 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -114,6 +114,11 @@ "label": "Subtasques", "description": "Permetre la creaciรณ i finalitzaciรณ de subtasques sense requerir aprovaciรณ" }, + "followupQuestions": { + "label": "Pregunta", + "description": "Seleccionar automร ticament la primera resposta suggerida per a preguntes de seguiment desprรฉs del temps d'espera configurat", + "timeoutLabel": "Temps d'espera abans de seleccionar automร ticament la primera resposta" + }, "execute": { "label": "Executar", "description": "Executar automร ticament comandes de terminal permeses sense requerir aprovaciรณ", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index b78f6d4f93..057016af31 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -234,7 +234,9 @@ "tokens": "Tokens" }, "followUpSuggest": { - "copyToInput": "In Eingabefeld kopieren (oder Shift + Klick)" + "copyToInput": "In Eingabefeld kopieren (oder Shift + Klick)", + "autoSelectCountdown": "Automatische Auswahl in {{count}}s", + "countdownDisplay": "{{count}}s" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} verรถffentlicht", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 1d0e10892d..bf33512650 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -114,6 +114,11 @@ "label": "Teilaufgaben", "description": "Erstellung und Abschluss von Unteraufgaben ohne Genehmigung erlauben" }, + "followupQuestions": { + "label": "Frage", + "description": "Automatisch die erste vorgeschlagene Antwort fรผr Folgefragen nach der konfigurierten Zeitรผberschreitung auswรคhlen", + "timeoutLabel": "Wartezeit vor der automatischen Auswahl der ersten Antwort" + }, "execute": { "label": "Ausfรผhren", "description": "Erlaubte Terminal-Befehle automatisch ohne Genehmigung ausfรผhren", diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index d07fd90394..1f19490eef 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -258,7 +258,9 @@ "seconds": "{{count}}s" }, "followUpSuggest": { - "copyToInput": "Copy to input (same as shift + click)" + "copyToInput": "Copy to input (same as shift + click)", + "autoSelectCountdown": "Auto-selecting in {{count}}s", + "countdownDisplay": "{{count}}s" }, "browser": { "rooWantsToUse": "Roo wants to use the browser:", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index bc6515ce28..b18f526e15 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -114,6 +114,11 @@ "label": "Subtasks", "description": "Allow creation and completion of subtasks without requiring approval" }, + "followupQuestions": { + "label": "Question", + "description": "Automatically select the first suggested answer for follow-up questions after the configured timeout", + "timeoutLabel": "Time to wait before auto-selecting the first answer" + }, "execute": { "label": "Execute", "description": "Automatically execute allowed terminal commands without requiring approval", diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index 2af576e88e..7f7b2583c6 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -234,7 +234,9 @@ "tokens": "tokens" }, "followUpSuggest": { - "copyToInput": "Copiar a la entrada (o Shift + clic)" + "copyToInput": "Copiar a la entrada (o Shift + clic)", + "autoSelectCountdown": "Selecciรณn automรกtica en {{count}}s", + "countdownDisplay": "{{count}}s" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} publicado", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 0e3d4ac2b8..92d12b4e24 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -114,6 +114,11 @@ "label": "Subtareas", "description": "Permitir la creaciรณn y finalizaciรณn de subtareas sin requerir aprobaciรณn" }, + "followupQuestions": { + "label": "Pregunta", + "description": "Seleccionar automรกticamente la primera respuesta sugerida para preguntas de seguimiento despuรฉs del tiempo de espera configurado", + "timeoutLabel": "Tiempo de espera antes de seleccionar automรกticamente la primera respuesta" + }, "execute": { "label": "Ejecutar", "description": "Ejecutar automรกticamente comandos de terminal permitidos sin requerir aprobaciรณn", diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 0b1e030f8f..fc310e57a1 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -234,7 +234,9 @@ "tokens": "tokens" }, "followUpSuggest": { - "copyToInput": "Copier vers l'entrรฉe (ou Shift + clic)" + "copyToInput": "Copier vers l'entrรฉe (ou Shift + clic)", + "autoSelectCountdown": "Sรฉlection automatique dans {{count}}s", + "countdownDisplay": "{{count}}s" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} est sortie", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 2ec2daaf8a..7c3f38b7b3 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -114,6 +114,11 @@ "label": "Sous-tรขches", "description": "Permettre la crรฉation et l'achรจvement des sous-tรขches sans nรฉcessiter d'approbation" }, + "followupQuestions": { + "label": "Question", + "description": "Sรฉlectionner automatiquement la premiรจre rรฉponse suggรฉrรฉe pour les questions de suivi aprรจs le dรฉlai configurรฉ", + "timeoutLabel": "Temps d'attente avant la sรฉlection automatique de la premiรจre rรฉponse" + }, "execute": { "label": "Exรฉcuter", "description": "Exรฉcuter automatiquement les commandes de terminal autorisรฉes sans nรฉcessiter d'approbation", diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index dbbe65ca4c..b3b2fe0b2d 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -234,7 +234,9 @@ "tokens": "เคŸเฅ‹เค•เคจ" }, "followUpSuggest": { - "copyToInput": "เค‡เคจเคชเฅเคŸ เคฎเฅ‡เค‚ เค•เฅ‰เคชเฅ€ เค•เคฐเฅ‡เค‚ (เคฏเคพ Shift + เค•เฅเคฒเคฟเค•)" + "copyToInput": "เค‡เคจเคชเฅเคŸ เคฎเฅ‡เค‚ เค•เฅ‰เคชเฅ€ เค•เคฐเฅ‡เค‚ (เคฏเคพ Shift + เค•เฅเคฒเคฟเค•)", + "autoSelectCountdown": "{{count}}s เคฎเฅ‡เค‚ เคธเฅเคตเคšเคพเคฒเคฟเคค เคฐเฅ‚เคช เคธเฅ‡ เคšเคฏเคจ เคนเฅ‹ เคฐเคนเคพ เคนเฅˆ", + "countdownDisplay": "{{count}}เคธเฅ‡เค•เค‚เคก" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} เคฐเคฟเคฒเฅ€เคœเคผ เคนเฅเค†", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 2cdc9949c0..36cfc01896 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -114,6 +114,11 @@ "label": "เค‰เคช-เค•เคพเคฐเฅเคฏ", "description": "เค…เคจเฅเคฎเฅ‹เคฆเคจ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เค•เฅ‡ เคฌเคฟเคจเคพ เค‰เคช-เค•เคพเคฐเฅเคฏเฅ‹เค‚ เค•เฅ‡ เคจเคฟเคฐเฅเคฎเคพเคฃ เค”เคฐ เคชเฅ‚เคฐเฅเคฃเคคเคพ เค•เฅ€ เค…เคจเฅเคฎเคคเคฟ เคฆเฅ‡เค‚" }, + "followupQuestions": { + "label": "เคชเฅเคฐเคถเฅเคจ", + "description": "เค•เฅ‰เคจเฅเคซเคผเคฟเค—เคฐ เค•เคฟเค เค—เค เคŸเคพเค‡เคฎเค†เค‰เคŸ เค•เฅ‡ เคฌเคพเคฆ เค…เคจเฅเคตเคฐเฅเคคเฅ€ เคชเฅเคฐเคถเฅเคจเฅ‹เค‚ เค•เฅ‡ เคฒเคฟเค เคชเคนเคฒเฅ‡ เคธเฅเคเคพเค เค—เค เค‰เคคเฅเคคเคฐ เค•เฅ‹ เคธเฅเคตเคšเคพเคฒเคฟเคค เคฐเฅ‚เคช เคธเฅ‡ เคšเฅเคจเฅ‡เค‚", + "timeoutLabel": "เคชเคนเคฒเฅ‡ เค‰เคคเฅเคคเคฐ เค•เฅ‹ เคธเฅเคตเคšเคพเคฒเคฟเคค เคฐเฅ‚เคช เคธเฅ‡ เคšเฅเคจเคจเฅ‡ เคธเฅ‡ เคชเคนเคฒเฅ‡ เคชเฅเคฐเคคเฅ€เค•เฅเคทเคพ เค•เคฐเคจเฅ‡ เค•เคพ เคธเคฎเคฏ" + }, "execute": { "label": "เคจเคฟเคทเฅเคชเคพเคฆเคฟเคค เค•เคฐเฅ‡เค‚", "description": "เค…เคจเฅเคฎเฅ‹เคฆเคจ เค•เฅ€ เค†เคตเคถเฅเคฏเค•เคคเคพ เค•เฅ‡ เคฌเคฟเคจเคพ เคธเฅเคตเคšเคพเคฒเคฟเคค เคฐเฅ‚เคช เคธเฅ‡ เค…เคจเฅเคฎเคค เคŸเคฐเฅเคฎเคฟเคจเคฒ เค•เคฎเคพเค‚เคก เคจเคฟเคทเฅเคชเคพเคฆเคฟเคค เค•เคฐเฅ‡เค‚", diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index c45a25d486..be9d3919ff 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -264,7 +264,9 @@ "seconds": "{{count}}d" }, "followUpSuggest": { - "copyToInput": "Salin ke input (sama dengan shift + klik)" + "copyToInput": "Salin ke input (sama dengan shift + klik)", + "autoSelectCountdown": "Pemilihan otomatis dalam {{count}}dtk", + "countdownDisplay": "{{count}}dtk" }, "browser": { "rooWantsToUse": "Roo ingin menggunakan browser:", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 6b6c62c520..08a23cd30c 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -114,6 +114,11 @@ "label": "Subtugas", "description": "Izinkan pembuatan dan penyelesaian subtugas tanpa memerlukan persetujuan" }, + "followupQuestions": { + "label": "Pertanyaan", + "description": "Secara otomatis memilih jawaban pertama yang disarankan untuk pertanyaan lanjutan setelah batas waktu yang dikonfigurasi", + "timeoutLabel": "Waktu tunggu sebelum otomatis memilih jawaban pertama" + }, "execute": { "label": "Eksekusi", "description": "Secara otomatis mengeksekusi perintah terminal yang diizinkan tanpa memerlukan persetujuan", diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index 9b31a7d136..5fa468801d 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -234,7 +234,9 @@ "tokens": "token" }, "followUpSuggest": { - "copyToInput": "Copia nell'input (o Shift + clic)" + "copyToInput": "Copia nell'input (o Shift + clic)", + "autoSelectCountdown": "Selezione automatica in {{count}}s", + "countdownDisplay": "{{count}}s" }, "announcement": { "title": "๐ŸŽ‰ Rilasciato Roo Code {{version}}", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 3340371c51..4897212d0f 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -114,6 +114,11 @@ "label": "Sottoattivitร ", "description": "Consenti la creazione e il completamento di attivitร  secondarie senza richiedere approvazione" }, + "followupQuestions": { + "label": "Domanda", + "description": "Seleziona automaticamente la prima risposta suggerita per le domande di follow-up dopo il timeout configurato", + "timeoutLabel": "Tempo di attesa prima di selezionare automaticamente la prima risposta" + }, "execute": { "label": "Esegui", "description": "Esegui automaticamente i comandi del terminale consentiti senza richiedere approvazione", diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index 894d75c7a0..776b611a89 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -234,7 +234,9 @@ "tokens": "ใƒˆใƒผใ‚ฏใƒณ" }, "followUpSuggest": { - "copyToInput": "ๅ…ฅๅŠ›ๆฌ„ใซใ‚ณใƒ”ใƒผ๏ผˆใพใŸใฏShift + ใ‚ฏใƒชใƒƒใ‚ฏ๏ผ‰" + "copyToInput": "ๅ…ฅๅŠ›ๆฌ„ใซใ‚ณใƒ”ใƒผ๏ผˆใพใŸใฏShift + ใ‚ฏใƒชใƒƒใ‚ฏ๏ผ‰", + "autoSelectCountdown": "{{count}}็ง’ๅพŒใซ่‡ชๅ‹•้ธๆŠžใ—ใพใ™", + "countdownDisplay": "{{count}}็ง’" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ใƒชใƒชใƒผใ‚น", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index 9321e174fe..4165726ade 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -114,6 +114,11 @@ "label": "ใ‚ตใƒ–ใ‚ฟใ‚นใ‚ฏ", "description": "ๆ‰ฟ่ชใชใ—ใงใ‚ตใƒ–ใ‚ฟใ‚นใ‚ฏใฎไฝœๆˆใจๅฎŒไบ†ใ‚’่จฑๅฏ" }, + "followupQuestions": { + "label": "่ณชๅ•", + "description": "่จญๅฎšใ•ใ‚ŒใŸๆ™‚้–“ใŒ็ตŒ้Žใ™ใ‚‹ใจใ€ใƒ•ใ‚ฉใƒญใƒผใ‚ขใƒƒใƒ—่ณชๅ•ใฎๆœ€ๅˆใฎๆๆกˆๅ›ž็ญ”ใ‚’่‡ชๅ‹•็š„ใซ้ธๆŠžใ—ใพใ™", + "timeoutLabel": "ๆœ€ๅˆใฎๅ›ž็ญ”ใ‚’่‡ชๅ‹•้ธๆŠžใ™ใ‚‹ใพใงใฎๅพ…ๆฉŸๆ™‚้–“" + }, "execute": { "label": "ๅฎŸ่กŒ", "description": "ๆ‰ฟ่ชใชใ—ใง่‡ชๅ‹•็š„ใซ่จฑๅฏใ•ใ‚ŒใŸใ‚ฟใƒผใƒŸใƒŠใƒซใ‚ณใƒžใƒณใƒ‰ใ‚’ๅฎŸ่กŒ", diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 64b5833c20..65e4c0c480 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -234,7 +234,9 @@ "tokens": "ํ† ํฐ" }, "followUpSuggest": { - "copyToInput": "์ž…๋ ฅ์ฐฝ์— ๋ณต์‚ฌ (๋˜๋Š” Shift + ํด๋ฆญ)" + "copyToInput": "์ž…๋ ฅ์ฐฝ์— ๋ณต์‚ฌ (๋˜๋Š” Shift + ํด๋ฆญ)", + "autoSelectCountdown": "{{count}}์ดˆ ํ›„ ์ž๋™ ์„ ํƒ", + "countdownDisplay": "{{count}}์ดˆ" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ์ถœ์‹œ", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index f431df970e..e68297599c 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -114,6 +114,11 @@ "label": "ํ•˜์œ„ ์ž‘์—…", "description": "์Šน์ธ ์—†์ด ํ•˜์œ„ ์ž‘์—… ์ƒ์„ฑ ๋ฐ ์™„๋ฃŒ ํ—ˆ์šฉ" }, + "followupQuestions": { + "label": "์งˆ๋ฌธ", + "description": "์„ค์ •๋œ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ํ›„์† ์งˆ๋ฌธ์— ๋Œ€ํ•œ ์ฒซ ๋ฒˆ์งธ ์ œ์•ˆ ๋‹ต๋ณ€์„ ์ž๋™์œผ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค", + "timeoutLabel": "์ฒซ ๋ฒˆ์งธ ๋‹ต๋ณ€์„ ์ž๋™ ์„ ํƒํ•˜๊ธฐ ์ „ ๋Œ€๊ธฐ ์‹œ๊ฐ„" + }, "execute": { "label": "์‹คํ–‰", "description": "์Šน์ธ ์—†์ด ์ž๋™์œผ๋กœ ํ—ˆ์šฉ๋œ ํ„ฐ๋ฏธ๋„ ๋ช…๋ น ์‹คํ–‰", diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index c393d00440..fc3f87562d 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -244,7 +244,9 @@ "tokens": "tokens" }, "followUpSuggest": { - "copyToInput": "Kopiรซren naar invoer (zelfde als shift + klik)" + "copyToInput": "Kopiรซren naar invoer (zelfde als shift + klik)", + "autoSelectCountdown": "Automatische selectie in {{count}}s", + "countdownDisplay": "{{count}}s" }, "browser": { "rooWantsToUse": "Roo wil de browser gebruiken:", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 9fdf043f33..254334df54 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -114,6 +114,11 @@ "label": "Subtaken", "description": "Subtaken aanmaken en afronden zonder goedkeuring" }, + "followupQuestions": { + "label": "Vraag", + "description": "Selecteer automatisch het eerste voorgestelde antwoord voor vervolgvragen na de geconfigureerde time-out", + "timeoutLabel": "Wachttijd voordat het eerste antwoord automatisch wordt geselecteerd" + }, "execute": { "label": "Uitvoeren", "description": "Automatisch toegestane terminalcommando's uitvoeren zonder goedkeuring", diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index 03d62ffe59..b930cf776c 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -234,7 +234,9 @@ "tokens": "tokeny" }, "followUpSuggest": { - "copyToInput": "Kopiuj do pola wprowadzania (lub Shift + klikniฤ™cie)" + "copyToInput": "Kopiuj do pola wprowadzania (lub Shift + klikniฤ™cie)", + "autoSelectCountdown": "Automatyczny wybรณr za {{count}}s", + "countdownDisplay": "{{count}}s" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} wydany", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index d760a88564..02a7d0d04d 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -114,6 +114,11 @@ "label": "Podzadania", "description": "Zezwalaj na tworzenie i ukoล„czenie podzadaล„ bez koniecznoล›ci zatwierdzania" }, + "followupQuestions": { + "label": "Pytanie", + "description": "Automatycznie wybierz pierwszฤ… sugerowanฤ… odpowiedลบ na pytania uzupeล‚niajฤ…ce po skonfigurowanym limicie czasu", + "timeoutLabel": "Czas oczekiwania przed automatycznym wybraniem pierwszej odpowiedzi" + }, "execute": { "label": "Wykonaj", "description": "Automatycznie wykonuj dozwolone polecenia terminala bez koniecznoล›ci zatwierdzania", diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index 9e467fbc98..1bf23c88e4 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -234,7 +234,9 @@ "tokens": "tokens" }, "followUpSuggest": { - "copyToInput": "Copiar para entrada (ou Shift + clique)" + "copyToInput": "Copiar para entrada (ou Shift + clique)", + "autoSelectCountdown": "Seleรงรฃo automรกtica em {{count}}s", + "countdownDisplay": "{{count}}s" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} Lanรงado", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 53ffaff53c..8c7b6c9a24 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -114,6 +114,11 @@ "label": "Subtarefas", "description": "Permitir a criaรงรฃo e conclusรฃo de subtarefas sem exigir aprovaรงรฃo" }, + "followupQuestions": { + "label": "Pergunta", + "description": "Selecionar automaticamente a primeira resposta sugerida para perguntas de acompanhamento apรณs o tempo limite configurado", + "timeoutLabel": "Tempo de espera antes de selecionar automaticamente a primeira resposta" + }, "execute": { "label": "Executar", "description": "Executar automaticamente comandos de terminal permitidos sem exigir aprovaรงรฃo", diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index 6bb38b51f5..c709b97fa2 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -244,7 +244,9 @@ "tokens": "ั‚ะพะบะตะฝั‹" }, "followUpSuggest": { - "copyToInput": "ะกะบะพะฟะธั€ะพะฒะฐั‚ัŒ ะฒะพ ะฒะฒะพะด (ั‚ะพ ะถะต, ั‡ั‚ะพ shift + ะบะปะธะบ)" + "copyToInput": "ะกะบะพะฟะธั€ะพะฒะฐั‚ัŒ ะฒะพ ะฒะฒะพะด (ั‚ะพ ะถะต, ั‡ั‚ะพ shift + ะบะปะธะบ)", + "autoSelectCountdown": "ะะฒั‚ะพะฒั‹ะฑะพั€ ั‡ะตั€ะตะท {{count}}ั", + "countdownDisplay": "{{count}}ั" }, "browser": { "rooWantsToUse": "Roo ั…ะพั‡ะตั‚ ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ ะฑั€ะฐัƒะทะตั€:", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 2033d18ce7..e60b97f775 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -114,6 +114,11 @@ "label": "ะŸะพะดะทะฐะดะฐั‡ะธ", "description": "ะ ะฐะทั€ะตัˆะธั‚ัŒ ัะพะทะดะฐะฝะธะต ะธ ะฒั‹ะฟะพะปะฝะตะฝะธะต ะฟะพะดะทะฐะดะฐั‡ ะฑะตะท ะฝะตะพะฑั…ะพะดะธะผะพัั‚ะธ ะพะดะพะฑั€ะตะฝะธั" }, + "followupQuestions": { + "label": "ะ’ะพะฟั€ะพั", + "description": "ะะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธ ะฒั‹ะฑะธั€ะฐั‚ัŒ ะฟะตั€ะฒั‹ะน ะฟั€ะตะดะปะพะถะตะฝะฝั‹ะน ะพั‚ะฒะตั‚ ะฝะฐ ะดะพะฟะพะปะฝะธั‚ะตะปัŒะฝั‹ะต ะฒะพะฟั€ะพัั‹ ะฟะพัะปะต ะฝะฐัั‚ั€ะพะตะฝะฝะพะณะพ ั‚ะฐะนะผ-ะฐัƒั‚ะฐ", + "timeoutLabel": "ะ’ั€ะตะผั ะพะถะธะดะฐะฝะธั ะฟะตั€ะตะด ะฐะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธะผ ะฒั‹ะฑะพั€ะพะผ ะฟะตั€ะฒะพะณะพ ะพั‚ะฒะตั‚ะฐ" + }, "execute": { "label": "ะ’ั‹ะฟะพะปะฝะตะฝะธะต", "description": "ะะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธ ะฒั‹ะฟะพะปะฝัั‚ัŒ ั€ะฐะทั€ะตัˆั‘ะฝะฝั‹ะต ะบะพะผะฐะฝะดั‹ ั‚ะตั€ะผะธะฝะฐะปะฐ ะฑะตะท ะฝะตะพะฑั…ะพะดะธะผะพัั‚ะธ ะพะดะพะฑั€ะตะฝะธั", diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index ec0311265d..1bc530f37a 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -234,7 +234,9 @@ "tokens": "token" }, "followUpSuggest": { - "copyToInput": "GiriลŸ alanฤฑna kopyala (veya Shift + tฤฑklama)" + "copyToInput": "GiriลŸ alanฤฑna kopyala (veya Shift + tฤฑklama)", + "autoSelectCountdown": "{{count}}s iรงinde otomatik seรงilecek", + "countdownDisplay": "{{count}}sn" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} Yayฤฑnlandฤฑ", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 338e18fd36..c7ced157f6 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -114,6 +114,11 @@ "label": "Alt Gรถrevler", "description": "Onay gerektirmeden alt gรถrevlerin oluลŸturulmasฤฑna ve tamamlanmasฤฑna izin ver" }, + "followupQuestions": { + "label": "Soru", + "description": "Yapฤฑlandฤฑrฤฑlan zaman aลŸฤฑmฤฑndan sonra takip sorularฤฑna iliลŸkin ilk รถnerilen yanฤฑtฤฑ otomatik olarak seรง", + "timeoutLabel": "ฤฐlk yanฤฑtฤฑ otomatik olarak seรงmeden รถnce beklenecek sรผre" + }, "execute": { "label": "Yรผrรผt", "description": "Onay gerektirmeden otomatik olarak izin verilen terminal komutlarฤฑnฤฑ yรผrรผt", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index c8cc05aaae..24521d8aa4 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -234,7 +234,9 @@ "tokens": "token" }, "followUpSuggest": { - "copyToInput": "Sao chรฉp vร o รด nhแบญp liแป‡u (hoแบทc Shift + nhแบฅp chuแป™t)" + "copyToInput": "Sao chรฉp vร o รด nhแบญp liแป‡u (hoแบทc Shift + nhแบฅp chuแป™t)", + "autoSelectCountdown": "Tแปฑ ฤ‘แป™ng chแปn sau {{count}}s", + "countdownDisplay": "{{count}}s" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ฤรฃ phรกt hร nh", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 413ace0339..c82bfdd7a2 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -114,6 +114,11 @@ "label": "Cรดng viแป‡c phแปฅ", "description": "Cho phรฉp tแบกo vร  hoร n thร nh cรกc cรดng viแป‡c phแปฅ mร  khรดng cแบงn phรช duyแป‡t" }, + "followupQuestions": { + "label": "Cรขu hแปi", + "description": "Tแปฑ ฤ‘แป™ng chแปn cรขu trแบฃ lแปi ฤ‘แบงu tiรชn ฤ‘ฦฐแปฃc ฤ‘แป xuแบฅt cho cรกc cรขu hแปi tiแบฟp theo sau thแปi gian chแป ฤ‘รฃ cแบฅu hรฌnh", + "timeoutLabel": "Thแปi gian chแป trฦฐแป›c khi tแปฑ ฤ‘แป™ng chแปn cรขu trแบฃ lแปi ฤ‘แบงu tiรชn" + }, "execute": { "label": "Thแปฑc thi", "description": "Tแปฑ ฤ‘แป™ng thแปฑc thi cรกc lแป‡nh terminal ฤ‘ฦฐแปฃc phรฉp mร  khรดng cแบงn phรช duyแป‡t", diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index 038f239f07..c4c4f1c5a2 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -234,7 +234,9 @@ "tokens": "tokens" }, "followUpSuggest": { - "copyToInput": "ๅคๅˆถๅˆฐ่พ“ๅ…ฅๆก†๏ผˆๆˆ–ๆŒ‰ไฝShift็‚นๅ‡ป๏ผ‰" + "copyToInput": "ๅคๅˆถๅˆฐ่พ“ๅ…ฅๆก†๏ผˆๆˆ–ๆŒ‰ไฝShift็‚นๅ‡ป๏ผ‰", + "autoSelectCountdown": "{{count}}็ง’ๅŽ่‡ชๅŠจ้€‰ๆ‹ฉ", + "countdownDisplay": "{{count}}็ง’" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ๅทฒๅ‘ๅธƒ", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 38299eb124..d4ce96e8e4 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -114,6 +114,11 @@ "label": "ๅญไปปๅŠก", "description": "ๅ…่ฎธๅˆ›ๅปบๅ’ŒๅฎŒๆˆๅญไปปๅŠก่€Œๆ— ้œ€ๆ‰นๅ‡†" }, + "followupQuestions": { + "label": "้—ฎ้ข˜", + "description": "ๅœจ้…็ฝฎ็š„่ถ…ๆ—ถๆ—ถ้—ดๅŽ่‡ชๅŠจ้€‰ๆ‹ฉๅŽ็ปญ้—ฎ้ข˜็š„็ฌฌไธ€ไธชๅปบ่ฎฎ็ญ”ๆกˆ", + "timeoutLabel": "่‡ชๅŠจ้€‰ๆ‹ฉ็ฌฌไธ€ไธช็ญ”ๆกˆๅ‰็š„็ญ‰ๅพ…ๆ—ถ้—ด" + }, "execute": { "label": "ๆ‰ง่กŒ", "description": "่‡ชๅŠจๆ‰ง่กŒ็™ฝๅๅ•ไธญ็š„ๅ‘ฝไปค่€Œๆ— ้œ€ๆ‰นๅ‡†", diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 298a3b76f4..a4b60ddf79 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -234,7 +234,9 @@ "tokens": "tokens" }, "followUpSuggest": { - "copyToInput": "่ค‡่ฃฝๅˆฐ่ผธๅ…ฅๆก†๏ผˆๆˆ–ๆŒ‰ไฝ Shift ไธฆ้ปž้ธ๏ผ‰" + "copyToInput": "่ค‡่ฃฝๅˆฐ่ผธๅ…ฅๆก†๏ผˆๆˆ–ๆŒ‰ไฝ Shift ไธฆ้ปž้ธ๏ผ‰", + "autoSelectCountdown": "{{count}}็ง’ๅพŒ่‡ชๅ‹•้ธๆ“‡", + "countdownDisplay": "{{count}}็ง’" }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ๅทฒ็™ผๅธƒ", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index e7b902a7d9..be6ad5d80c 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -114,6 +114,11 @@ "label": "ๅญๅทฅไฝœ", "description": "ๅ…่จฑๅปบ็ซ‹ๅ’ŒๅฎŒๆˆๅญๅทฅไฝœ่€Œ็„ก้œ€ๆ ธๅ‡†" }, + "followupQuestions": { + "label": "ๅ•้กŒ", + "description": "ๅœจ่จญๅฎš็š„้€พๆ™‚ๆ™‚้–“ๅพŒ่‡ชๅ‹•้ธๆ“‡ๅพŒ็บŒๅ•้กŒ็š„็ฌฌไธ€ๅ€‹ๅปบ่ญฐ็ญ”ๆกˆ", + "timeoutLabel": "่‡ชๅ‹•้ธๆ“‡็ฌฌไธ€ๅ€‹็ญ”ๆกˆๅ‰็š„็ญ‰ๅพ…ๆ™‚้–“" + }, "execute": { "label": "ๅŸท่กŒ", "description": "่‡ชๅ‹•ๅŸท่กŒๅ…่จฑ็š„็ต‚็ซฏๆฉŸๅ‘ฝไปค่€Œ็„ก้œ€ๆ ธๅ‡†", From ff1e8ac2eec0b1f3824a3b428e564b630e9d46bc Mon Sep 17 00:00:00 2001 From: SannidhyaSah Date: Wed, 2 Jul 2025 00:44:50 +0530 Subject: [PATCH 49/70] fix: remove context size from environment details (#5165) (#5312) Co-authored-by: Matt Rubens Co-authored-by: Daniel Riccio Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com> --- .../environment/__tests__/getEnvironmentDetails.spec.ts | 1 - src/core/environment/getEnvironmentDetails.ts | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/environment/__tests__/getEnvironmentDetails.spec.ts b/src/core/environment/__tests__/getEnvironmentDetails.spec.ts index 02423f8ebd..f7e63d86c6 100644 --- a/src/core/environment/__tests__/getEnvironmentDetails.spec.ts +++ b/src/core/environment/__tests__/getEnvironmentDetails.spec.ts @@ -146,7 +146,6 @@ describe("getEnvironmentDetails", () => { expect(result).toContain("# VSCode Visible Files") expect(result).toContain("# VSCode Open Tabs") expect(result).toContain("# Current Time") - expect(result).toContain("# Current Context Size (Tokens)") expect(result).toContain("# Current Cost") expect(result).toContain("# Current Mode") expect(result).toContain("test-model") diff --git a/src/core/environment/getEnvironmentDetails.ts b/src/core/environment/getEnvironmentDetails.ts index 944eb94190..9120b5e8c7 100644 --- a/src/core/environment/getEnvironmentDetails.ts +++ b/src/core/environment/getEnvironmentDetails.ts @@ -197,13 +197,8 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo // Add context tokens information. const { contextTokens, totalCost } = getApiMetrics(cline.clineMessages) - const { id: modelId, info: modelInfo } = cline.api.getModel() - const contextWindow = modelInfo.contextWindow + const { id: modelId } = cline.api.getModel() - const contextPercentage = - contextTokens && contextWindow ? Math.round((contextTokens / contextWindow) * 100) : undefined - - details += `\n\n# Current Context Size (Tokens)\n${contextTokens ? `${contextTokens.toLocaleString()} (${contextPercentage}%)` : "(Not available)"}` details += `\n\n# Current Cost\n${totalCost !== null ? `$${totalCost.toFixed(2)}` : "(Not available)"}` // Add current mode and any mode-specific warnings. From 0ee3680fb4afcfde2d8ae42ff370253724041903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DEV=C3=97PAIN?= <170700110+devxpain@users.noreply.github.com> Date: Wed, 2 Jul 2025 03:50:05 +0800 Subject: [PATCH 50/70] feat(dx): streamline extension installation and documentation (#4284) --- README.md | 48 ++++++++++++++++++---- package.json | 1 + scripts/install-vsix.js | 91 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 scripts/install-vsix.js diff --git a/README.md b/README.md index 48055236e6..d4906d4cb3 100644 --- a/README.md +++ b/README.md @@ -138,21 +138,53 @@ pnpm install 3. **Run the extension**: -Press `F5` (or **Run** โ†’ **Start Debugging**) in VSCode to open a new window with Roo Code running. +There are several ways to run the Roo Code extension: -Changes to the webview will appear immediately. Changes to the core extension will require a restart of the extension host. +### Development Mode (F5) -Alternatively you can build a .vsix and install it directly in VSCode: +For active development, use VSCode's built-in debugging: + +Press `F5` (or go to **Run** โ†’ **Start Debugging**) in VSCode. This will open a new VSCode window with the Roo Code extension running. + +- Changes to the webview will appear immediately. +- Changes to the core extension will also hot reload automatically. + +### Automated VSIX Installation + +To build and install the extension as a VSIX package directly into VSCode: ```sh -pnpm vsix +pnpm install:vsix [-y] [--editor=] ``` -A `.vsix` file will appear in the `bin/` directory which can be installed with: +This command will: -```sh -code --install-extension bin/roo-cline-.vsix -``` +- Ask which editor command to use (code/cursor/code-insiders) - defaults to 'code' +- Uninstall any existing version of the extension. +- Build the latest VSIX package. +- Install the newly built VSIX. +- Prompt you to restart VS Code for changes to take effect. + +Options: + +- `-y`: Skip all confirmation prompts and use defaults +- `--editor=`: Specify the editor command (e.g., `--editor=cursor` or `--editor=code-insiders`) + +### Manual VSIX Installation + +If you prefer to install the VSIX package manually: + +1. First, build the VSIX package: + ```sh + pnpm vsix + ``` +2. A `.vsix` file will be generated in the `bin/` directory (e.g., `bin/roo-cline-.vsix`). +3. Install it manually using the VSCode CLI: + ```sh + code --install-extension bin/roo-cline-.vsix + ``` + +--- We use [changesets](https://github.com/changesets/changesets) for versioning and publishing. Check our `CHANGELOG.md` for release notes. diff --git a/package.json b/package.json index 0741895029..61f1f6cdaf 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "vsix": "turbo vsix --log-order grouped --output-logs new-only", "vsix:nightly": "turbo vsix:nightly --log-order grouped --output-logs new-only", "clean": "turbo clean --log-order grouped --output-logs new-only && rimraf dist out bin .vite-port .turbo", + "install:vsix": "pnpm install --frozen-lockfile && pnpm clean && pnpm vsix && node scripts/install-vsix.js", "changeset:version": "cp CHANGELOG.md src/CHANGELOG.md && changeset version && cp -vf src/CHANGELOG.md .", "knip": "knip --include files", "update-contributors": "node scripts/update-contributors.js", diff --git a/scripts/install-vsix.js b/scripts/install-vsix.js new file mode 100644 index 0000000000..0ed9b6d376 --- /dev/null +++ b/scripts/install-vsix.js @@ -0,0 +1,91 @@ +const { execSync } = require("child_process") +const fs = require("fs") +const readline = require("readline") + +// detect "yes" flags +const autoYes = process.argv.includes("-y") + +// detect editor command from args or default to "code" +const editorArg = process.argv.find((arg) => arg.startsWith("--editor=")) +const defaultEditor = editorArg ? editorArg.split("=")[1] : "code" + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}) + +const askQuestion = (question) => { + return new Promise((resolve) => { + rl.question(question, (answer) => { + resolve(answer) + }) + }) +} + +async function main() { + try { + const packageJson = JSON.parse(fs.readFileSync("./src/package.json", "utf-8")) + const name = packageJson.name + const version = packageJson.version + const vsixFileName = `./bin/${name}-${version}.vsix` + const publisher = packageJson.publisher + const extensionId = `${publisher}.${name}` + + console.log("\n๐Ÿš€ Roo Code VSIX Installer") + console.log("========================") + console.log("\nThis script will:") + console.log("1. Uninstall any existing version of the Roo Code extension") + console.log("2. Install the newly built VSIX package") + console.log(`\nExtension: ${extensionId}`) + console.log(`VSIX file: ${vsixFileName}`) + + // Ask for editor command if not provided + let editorCommand = defaultEditor + if (!editorArg && !autoYes) { + const editorAnswer = await askQuestion( + "\nWhich editor command to use? (code/cursor/code-insiders) [default: code]: ", + ) + if (editorAnswer.trim()) { + editorCommand = editorAnswer.trim() + } + } + + // skip prompt if auto-yes + const answer = autoYes ? "y" : await askQuestion("\nDo you wish to continue? (y/n): ") + + if (answer.toLowerCase() !== "y") { + console.log("Installation cancelled.") + rl.close() + process.exit(0) + } + + console.log(`\nProceeding with installation using '${editorCommand}' command...`) + + try { + execSync(`${editorCommand} --uninstall-extension ${extensionId}`, { stdio: "inherit" }) + } catch (e) { + console.log("Extension not installed, skipping uninstall step") + } + + if (!fs.existsSync(vsixFileName)) { + console.error(`\nโŒ VSIX file not found: ${vsixFileName}`) + console.error("Make sure the build completed successfully") + rl.close() + process.exit(1) + } + + execSync(`${editorCommand} --install-extension ${vsixFileName}`, { stdio: "inherit" }) + + console.log(`\nโœ… Successfully installed extension from ${vsixFileName}`) + console.log("\nโš ๏ธ IMPORTANT: You need to restart VS Code for the changes to take effect.") + console.log(" Please close and reopen VS Code to use the updated extension.\n") + + rl.close() + } catch (error) { + console.error("\nโŒ Failed to install extension:", error.message) + rl.close() + process.exit(1) + } +} + +main() From a1ae29cdcdcd3bc7c658477a7712eaf2c86b25f0 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Tue, 1 Jul 2025 15:50:24 -0400 Subject: [PATCH 51/70] Suppress mermaid error rendering (#5308) --- webview-ui/src/components/common/MermaidBlock.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/webview-ui/src/components/common/MermaidBlock.tsx b/webview-ui/src/components/common/MermaidBlock.tsx index 229b957765..95c795fdc5 100644 --- a/webview-ui/src/components/common/MermaidBlock.tsx +++ b/webview-ui/src/components/common/MermaidBlock.tsx @@ -46,6 +46,7 @@ mermaid.initialize({ startOnLoad: false, securityLevel: "loose", theme: "dark", + suppressErrorRendering: true, themeVariables: { ...MERMAID_THEME, fontSize: "16px", From 1acbd45dc224bb2e813ba627d0597a21bf4a17d1 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Tue, 1 Jul 2025 15:04:57 -0600 Subject: [PATCH 52/70] refactor: update issue-fixer mode to use GitHub CLI instead of MCP (#5320) --- .roo/rules-issue-fixer/1_Workflow.xml | 170 +++++--------- .roo/rules-issue-fixer/4_github_cli_usage.xml | 221 ++++++++++++++++++ .../4_github_mcp_tool_usage.xml | 88 ------- .../5_pull_request_workflow.xml | 24 +- .../8_github_communication_guidelines.xml | 10 - .../9_pr_review_workflow.xml | 30 --- .roomodes | 8 +- 7 files changed, 310 insertions(+), 241 deletions(-) create mode 100644 .roo/rules-issue-fixer/4_github_cli_usage.xml delete mode 100644 .roo/rules-issue-fixer/4_github_mcp_tool_usage.xml delete mode 100644 .roo/rules-issue-fixer/9_pr_review_workflow.xml diff --git a/.roo/rules-issue-fixer/1_Workflow.xml b/.roo/rules-issue-fixer/1_Workflow.xml index ed1e64be16..db1e968c67 100644 --- a/.roo/rules-issue-fixer/1_Workflow.xml +++ b/.roo/rules-issue-fixer/1_Workflow.xml @@ -1,62 +1,41 @@ - Determine Workflow Type and Retrieve Context + Retrieve Issue Context - First, determine what type of work is needed. The user will provide either: - - An issue number/URL (e.g., "#123" or GitHub issue URL) - for new implementation - - A PR number/URL (e.g., "#456" or GitHub PR URL) - for addressing review feedback - - A description of changes needed for an existing PR + The user should provide a full GitHub issue URL (e.g., "https://github.com/owner/repo/issues/123") for implementation. - For Issue-based workflow: - Extract the issue number and retrieve it: + Parse the URL to extract: + - Owner (organization or username) + - Repository name + - Issue number - - github - get_issue - - { - "owner": "RooCodeInc", - "repo": "Roo-Code", - "issue_number": [extracted number] - } - - + For example, from https://github.com/RooCodeInc/Roo-Code/issues/123: + - Owner: RooCodeInc + - Repo: Roo-Code + - Issue: 123 - For PR Review workflow: - Extract the PR number and retrieve it: + Then retrieve the issue: - - github - get_pull_request - - { - "owner": "RooCodeInc", - "repo": "Roo-Code", - "pull_number": [extracted number] - } - - + + gh issue view [issue-number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author + - Then get PR review comments: + If the command fails with an authentication error (e.g., "gh: Not authenticated" or "HTTP 401"), ask the user to authenticate: + + GitHub CLI is not authenticated. Please run 'gh auth login' in your terminal to authenticate, then let me know when you're ready to continue. + + I've authenticated, please continue + I need help with authentication + Let's use a different approach + + - - github - get_pull_request_reviews - - { - "owner": "RooCodeInc", - "repo": "Roo-Code", - "pull_number": [extracted number] - } - - + Analyze the issue to determine: + 1. All requirements and acceptance criteria + 2. Technical details mentioned + 3. Any linked issues or discussions - Analyze the context to determine: - 1. Type of work (new issue implementation vs PR feedback) - 2. All requirements and acceptance criteria - 3. Specific changes requested (for PR reviews) - 4. Technical details mentioned - 5. Any linked issues or discussions + Note: For PR review feedback, users should use the dedicated pr-fixer mode instead. @@ -69,23 +48,20 @@ - Community suggestions - Any decisions or changes to requirements - - github - get_issue_comments - - { - "owner": "RooCodeInc", - "repo": "Roo-Code", - "issue_number": [issue number] - } - - + + gh issue view [issue number] --repo [owner]/[repo] --comments + Also check for: 1. Related issues mentioned in the body or comments 2. Linked pull requests 3. Referenced discussions + If related PRs are mentioned, view them: + + gh pr view [pr-number] --repo [owner]/[repo] + + Document all requirements and constraints found. @@ -109,16 +85,9 @@ - Identify patterns to follow - Find related components and utilities - For PR Reviews: - - Search for files mentioned in review comments - - Find related files that use similar patterns - - Locate test files for modified functionality - - Identify files that import/depend on changed code - Example searches based on issue type: - Bug: Search for error messages, function names, component names - Feature: Search for similar functionality, API endpoints, UI components - - PR Review: Search for patterns mentioned in feedback CRITICAL: Always read multiple related files together to understand: - Current code patterns and conventions @@ -133,10 +102,15 @@ - read_file to examine specific implementations (read multiple files at once) - search_files for specific patterns or error messages - Also use GitHub tools: - - list_commits to see recent changes to affected files - - get_commit to understand specific changes - - list_pull_requests to find related PRs + Also use GitHub CLI to check recent changes: + + gh api repos/[owner]/[repo]/commits?path=[file-path]&per_page=10 --jq '.[].sha + " " + .[].commit.message' + + + Search for related PRs: + + gh pr list --repo [owner]/[repo] --search "[relevant search terms]" --limit 10 + Document: - All files that need modification @@ -464,13 +438,13 @@ **Branch:** [branch-name] **Title:** [PR title] - **Target:** RooCodeInc/Roo-Code (main branch) + **Target:** [owner]/[repo] (main branch) Here's the PR description: [Show prepared PR description] - Would you like me to create this pull request to RooCodeInc/Roo-Code? + Would you like me to create this pull request to [owner]/[repo]? Yes, create the pull request Let me review the PR description first @@ -484,46 +458,28 @@ Create Pull Request - Once user approves, create the pull request using GitHub MCP: + Once user approves, create the pull request using GitHub CLI: - - github - create_pull_request - - { - "owner": "RooCodeInc", - "repo": "Roo-Code", - "title": "[Type]: [Brief description] (#[issue-number])", - "head": "[user-fork-owner]:[branch-name]", - "base": "main", - "body": "[Complete PR description from step 9]", - "draft": false, - "maintainer_can_modify": true - } - - + If the user doesn't have push access to [owner]/[repo], fork the repository: + + gh repo fork [owner]/[repo] --clone + - Note: The "head" parameter format depends on where the branch exists: - - If user has push access: "branch-name" - - If working from a fork: "username:branch-name" + Create the pull request: + + gh pr create --repo [owner]/[repo] --base main --title "[Type]: [Brief description] (#[issue-number])" --body "[Complete PR description from step 10]" --maintainer-can-modify + + + The gh CLI will automatically handle the fork workflow if needed. After PR creation: - 1. Capture the PR number and URL from the response + 1. Capture the PR number and URL from the command output 2. Link the PR to the issue by commenting on the issue 3. Inform the user of the successful creation - - github - add_issue_comment - - { - "owner": "RooCodeInc", - "repo": "Roo-Code", - "issue_number": [original issue number], - "body": "PR #[new PR number] has been created to address this issue: [PR URL]" - } - - + + gh issue comment [original issue number] --repo [owner]/[repo] --body "PR #[new PR number] has been created to address this issue: [PR URL]" + Final message to user: ``` @@ -550,7 +506,7 @@ After the PR is created, monitor the CI/CD checks to ensure they pass: - gh pr checks --watch + gh pr checks [PR number] --repo [owner]/[repo] --watch This command will: diff --git a/.roo/rules-issue-fixer/4_github_cli_usage.xml b/.roo/rules-issue-fixer/4_github_cli_usage.xml new file mode 100644 index 0000000000..e12fb06a5b --- /dev/null +++ b/.roo/rules-issue-fixer/4_github_cli_usage.xml @@ -0,0 +1,221 @@ + + + This mode uses the GitHub CLI (gh) for all GitHub operations. + The mode assumes the user has gh installed and authenticated. If authentication errors occur, + the mode will prompt the user to authenticate. + + Users must provide full GitHub issue URLs (e.g., https://github.com/owner/repo/issues/123) + so the mode can extract the repository information dynamically. + + + + https://github.com/[owner]/[repo]/issues/[number] + + - Owner: The organization or username + - Repo: The repository name + - Number: The issue number + + + + + Assume authenticated, handle errors gracefully + Only check authentication if a gh command fails with auth error + + - "gh: Not authenticated" + - "HTTP 401" + - "HTTP 403: Resource not accessible" + + + + + + Retrieve the issue details at the start + Always use first to get the full issue content + gh issue view [issue-number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author + + + gh issue view 123 --repo octocat/hello-world --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author + + + + + + Get additional context and requirements from issue comments + Always use after viewing issue to see full discussion + gh issue view [issue-number] --repo [owner]/[repo] --comments + + + gh issue view 123 --repo octocat/hello-world --comments + + + + + + + Find recent changes to affected files + Use during codebase exploration + gh api repos/[owner]/[repo]/commits?path=[file-path]&per_page=10 + + + gh api repos/octocat/hello-world/commits?path=src/api/index.ts&per_page=10 --jq '.[].sha + " " + .[].commit.message' + + + + + + Search for code patterns on GitHub + Use to supplement local codebase_search + gh search code "[search-query]" --repo [owner]/[repo] + + + gh search code "function handleError" --repo octocat/hello-world --limit 10 + + + + + + + + Add progress updates or ask questions on issues + Use if clarification needed or to show progress + gh issue comment [issue-number] --repo [owner]/[repo] --body "[comment]" + + + gh issue comment 123 --repo octocat/hello-world --body "Working on this issue. Found the root cause in the theme detection logic." + + + + + + Find related or similar PRs + Use to understand similar changes + gh pr list --repo [owner]/[repo] --search "[search-terms]" + + + gh pr list --repo octocat/hello-world --search "dark theme" --limit 10 + + + + + + View the diff of a pull request + Use to understand changes in a PR + gh pr diff [pr-number] --repo [owner]/[repo] + + + gh pr diff 456 --repo octocat/hello-world + + + + + + + + Create a pull request + Use in step 11 after user approval + + - Target the repository from the provided URL + - Use "main" as the base branch unless specified otherwise + - Include issue number in PR title + - Use --maintainer-can-modify flag + + gh pr create --repo [owner]/[repo] --base main --title "[title]" --body "[body]" --maintainer-can-modify + + + gh pr create --repo octocat/hello-world --base main --title "fix: Resolve dark theme button visibility (#123)" --body "## Description + +Fixes #123 + +[Full PR description]" --maintainer-can-modify + + + + If working from a fork, ensure the fork is set as the remote and push the branch there first. + The gh CLI will automatically handle the fork workflow. + + + + + Fork the repository if user doesn't have push access + Use if user needs to work from a fork + gh repo fork [owner]/[repo] --clone + + + gh repo fork octocat/hello-world --clone + + + + + + Monitor CI/CD checks on a pull request + Use after creating PR to ensure checks pass + gh pr checks [pr-number] --repo [owner]/[repo] --watch + + + gh pr checks 789 --repo octocat/hello-world --watch + + + + + + + + Access GitHub API directly for advanced operations + Use when specific gh commands don't provide needed functionality + + + + gh api repos/[owner]/[repo] --jq '.default_branch' + + + + + gh api repos/[owner]/[repo]/contents/README.md --jq '.content' | base64 -d + + + + + gh api repos/[owner]/[repo]/actions/runs --jq '.workflow_runs[0:5] | .[] | .id, .status, .conclusion' + + + + + + Check GitHub Actions workflow status + Use to monitor CI/CD pipeline + gh run list --repo [owner]/[repo] --limit 5 + + + gh run list --repo octocat/hello-world --limit 5 + + + + + + + + gh: Not authenticated. Run 'gh auth login' to authenticate. + + Ask user to authenticate: + + GitHub CLI is not authenticated. Please run 'gh auth login' in your terminal to authenticate, then let me know when you're ready to continue. + + I've authenticated, please continue + I need help with authentication + Let's use a different approach + + + + + + + HTTP 403: Resource not accessible by integration + + Check if working from a fork is needed: + + gh repo fork [owner]/[repo] --clone + + + + + \ No newline at end of file diff --git a/.roo/rules-issue-fixer/4_github_mcp_tool_usage.xml b/.roo/rules-issue-fixer/4_github_mcp_tool_usage.xml deleted file mode 100644 index 49b12f96ca..0000000000 --- a/.roo/rules-issue-fixer/4_github_mcp_tool_usage.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - Retrieve the issue details at the start - Always use first to get the full issue content - - - - Get additional context and requirements - Always use after get_issue to see full discussion - - - - Find recent changes to affected files - Use during codebase exploration - - - - Find code patterns on GitHub - Use to supplement local codebase_search - - - - - - Add progress updates or ask questions - Use if clarification needed or to show progress - - - - Find related or similar PRs - Use to understand similar changes - - - - Get details of related PRs - Use when issue references specific PRs - - - - - - Create a pull request to RooCodeInc/Roo-Code - Use in step 10 after user approval - - - Always target RooCodeInc/Roo-Code repository - - Use "main" as the base branch unless specified otherwise - - Include issue number in PR title - - Set maintainer_can_modify to true - - - - github - create_pull_request - - { - "owner": "RooCodeInc", - "repo": "Roo-Code", - "title": "fix: Resolve dark theme button visibility (#123)", - "head": "username:fix/issue-123-dark-theme-button", - "base": "main", - "body": "## Description\n\nFixes #123\n\n[Full PR description]", - "draft": false, - "maintainer_can_modify": true - } - - - - - - - Fork the repository if user doesn't have push access - Use if user needs to work from a fork - - - github - fork_repository - - { - "owner": "RooCodeInc", - "repo": "Roo-Code" - } - - - - - - \ No newline at end of file diff --git a/.roo/rules-issue-fixer/5_pull_request_workflow.xml b/.roo/rules-issue-fixer/5_pull_request_workflow.xml index 79102fcf37..60a8385e3e 100644 --- a/.roo/rules-issue-fixer/5_pull_request_workflow.xml +++ b/.roo/rules-issue-fixer/5_pull_request_workflow.xml @@ -4,6 +4,7 @@ 2. Push to appropriate branch (fork or direct) 3. Prepare comprehensive PR description 4. Get user approval before creating PR + 5. Extract owner and repo from the provided GitHub URL @@ -22,9 +23,30 @@ - Screenshots/demos if applicable + + Use GitHub CLI to create the pull request: + + gh pr create --repo [owner]/[repo] --base main --title "[title]" --body "[description]" --maintainer-can-modify + + + If working from a fork, ensure you've forked first: + + gh repo fork [owner]/[repo] --clone + + + The gh CLI automatically handles fork workflows. + + - 1. Comment on original issue with PR link + 1. Comment on original issue with PR link: + + gh issue comment [issue-number] --repo [owner]/[repo] --body "PR #[pr-number] has been created to address this issue: [PR URL]" + 2. Inform user of successful creation 3. Provide next steps and tracking info + 4. Monitor PR checks: + + gh pr checks [pr-number] --repo [owner]/[repo] --watch + \ No newline at end of file diff --git a/.roo/rules-issue-fixer/8_github_communication_guidelines.xml b/.roo/rules-issue-fixer/8_github_communication_guidelines.xml index 91ef0de89e..627908f1f7 100644 --- a/.roo/rules-issue-fixer/8_github_communication_guidelines.xml +++ b/.roo/rules-issue-fixer/8_github_communication_guidelines.xml @@ -1,14 +1,4 @@ - - - Keep comments concise and focused on technical substance - - Avoid overly verbose explanations unless specifically requested - - Sound human and conversational, not robotic - - Address specific feedback points directly - - Use bullet points for multiple changes - - Reference line numbers or specific code when relevant - - Example: "Updated the error handling in `validateInput()` to catch edge cases as requested. Also added the missing null check on line 45." - - - Provide brief status updates when working on complex issues - Ask specific questions if requirements are unclear diff --git a/.roo/rules-issue-fixer/9_pr_review_workflow.xml b/.roo/rules-issue-fixer/9_pr_review_workflow.xml deleted file mode 100644 index 849ee7f1df..0000000000 --- a/.roo/rules-issue-fixer/9_pr_review_workflow.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - When working on PR review feedback: - 1. Read all review comments carefully - 2. Identify specific changes requested - 3. Group related feedback into logical changes - 4. Address each point systematically - 5. Test changes thoroughly - 6. Respond to each review comment when pushing updates - 7. Use "Resolved" or brief explanations for each addressed point - - - - For partial workflows (user-requested changes to existing PRs): - 1. Focus only on the specific changes requested - 2. Don't refactor unrelated code unless explicitly asked - 3. Maintain consistency with existing PR approach - 4. Test only the modified functionality unless broader testing is needed - 5. Update PR description if significant changes are made - - - - When responding to review comments: - - "โœ… Fixed - [brief description of change]" - - "โœ… Added - [what was added]" - - "โœ… Updated - [what was changed]" - - "โ“ Question - [if clarification needed]" - - Keep responses short and action-oriented - - \ No newline at end of file diff --git a/.roomodes b/.roomodes index 236026c738..d9b3586f45 100644 --- a/.roomodes +++ b/.roomodes @@ -148,16 +148,14 @@ customModes: - Building new features based on detailed proposals - Ensuring all acceptance criteria are met before completion - Creating pull requests with proper documentation - - Handling PR review feedback and implementing requested changes - - Making concise, human-sounding GitHub comments that focus on technical substance + - Using GitHub CLI for all GitHub operations - You work with issues from the RooCodeInc/Roo-Code repository, transforming them into working code that addresses all requirements while maintaining code quality and consistency. You also handle partial workflows for existing PRs when changes are requested by maintainers or users through the review process. - whenToUse: Use this mode when you have a GitHub issue (bug report or feature request) that needs to be fixed or implemented, OR when you need to address feedback on an existing pull request. Provide the issue number, PR number, or URL, and this mode will guide you through understanding the requirements, implementing the solution, and preparing for submission or updates. + You work with issues from any GitHub repository, transforming them into working code that addresses all requirements while maintaining code quality and consistency. You use the GitHub CLI (gh) for all GitHub operations instead of MCP tools. + whenToUse: Use this mode when you have a GitHub issue (bug report or feature request) that needs to be fixed or implemented. Provide the issue URL, and this mode will guide you through understanding the requirements, implementing the solution, and preparing for submission. groups: - read - edit - command - - mcp source: project - slug: issue-writer name: ๐Ÿ“ Issue Writer From b4dc3a486e10edb68df727f2e4ed87af6ea036cb Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Tue, 1 Jul 2025 17:11:19 -0400 Subject: [PATCH 53/70] Add optional share links to templates (#5318) --- .github/ISSUE_TEMPLATE/bug_report.yml | 12 +++++++++++- .github/ISSUE_TEMPLATE/feature_request.yml | 10 ++++++++++ .github/pull_request_template.md | 8 ++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5bfc08f80f..44626273b5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -53,6 +53,16 @@ body: validations: required: true + - type: textarea + id: roo-code-tasks + attributes: + label: Roo Code Task Links (Optional) + description: | + If you have any publicly shared task links that demonstrate the issue, please paste them here. + This helps maintainers understand the context. + Example: https://app.roocode.com/share/task-id + placeholder: Paste your Roo Code share links here, one per line + - type: textarea id: steps attributes: @@ -85,4 +95,4 @@ body: attributes: label: ๐Ÿ“„ Relevant Logs or Errors (Optional) description: Paste API logs, terminal output, or errors here. Use triple backticks (```) for code formatting. - render: shell \ No newline at end of file + render: shell diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 85263d8813..4863f9ffa6 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -57,6 +57,16 @@ body: label: Additional context (optional) description: Mockups, screenshots, links, user quotes, or other relevant information that supports your proposal. + - type: textarea + id: roo-code-tasks + attributes: + label: Roo Code Task Links (Optional) + description: | + If you used Roo Code to explore this feature request or develop solutions, share the public task links here. + This helps maintainers understand the context and any exploration you've done. + Example: https://app.roocode.com/share/task-id + placeholder: Paste your Roo Code share links here, one per line + - type: checkboxes id: checklist attributes: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 765c70614c..e83e44cd66 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -12,6 +12,14 @@ Before submitting your PR, please ensure: Closes: # +### Roo Code Task Context (Optional) + + + ### Description -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Llicรจncia diff --git a/locales/de/README.md b/locales/de/README.md index 05fb7d3bd3..ec220fe9ca 100644 --- a/locales/de/README.md +++ b/locales/de/README.md @@ -50,13 +50,13 @@ Sehen Sie sich das [CHANGELOG](../../CHANGELOG.md) fรผr detaillierte Updates und --- -## ๐ŸŽ‰ Roo Code 3.21 verรถffentlicht +## ๐ŸŽ‰ Roo Code 3.22 verรถffentlicht -Roo Code 3.21 bringt wichtige neue Funktionen und Verbesserungen basierend auf eurem Feedback! +Roo Code 3.22 bringt mรคchtige neue Funktionen und bedeutende Verbesserungen, um deinen Entwicklungsworkflow zu verbessern! -- **Roo Marketplace Launch** - Der Marketplace ist jetzt live! Der Marketplace ist jetzt live! Entdecke und installiere Modi und MCPs einfacher als je zuvor. -- **Gemini 2.5 Modelle** - Unterstรผtzung fรผr neue Gemini 2.5 Pro, Flash und Flash Lite Modelle hinzugefรผgt. -- **Excel-Datei-Unterstรผtzung & Mehr** - Excel (.xlsx) Datei-Unterstรผtzung hinzugefรผgt und zahlreiche Fehlerbehebungen und Verbesserungen! +- **1-Klick-Aufgaben-Teilen** - Teile deine Aufgaben sofort mit Kollegen und der Community mit einem einzigen Klick. +- **Globale .roo-Verzeichnis-Unterstรผtzung** - Lade Regeln und Konfigurationen aus einem globalen .roo-Verzeichnis fรผr konsistente Einstellungen รผber Projekte hinweg. +- **Verbesserte รœbergรคnge von Architekt zu Code** - Nahtlose รœbergaben von der Planung im Architekten-Modus zur Implementierung im Code-Modus. --- @@ -181,41 +181,43 @@ Wir lieben Community-Beitrรคge! Beginnen Sie mit dem Lesen unserer [CONTRIBUTING Danke an alle unsere Mitwirkenden, die geholfen haben, Roo Code zu verbessern! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Lizenz diff --git a/locales/es/README.md b/locales/es/README.md index cd652e745a..c5939b353e 100644 --- a/locales/es/README.md +++ b/locales/es/README.md @@ -50,13 +50,13 @@ Consulta el [CHANGELOG](../../CHANGELOG.md) para ver actualizaciones detalladas --- -## ๐ŸŽ‰ Roo Code 3.21 Lanzado +## ๐ŸŽ‰ Roo Code 3.22 Lanzado -ยกRoo Code 3.21 trae importantes nuevas funciones y mejoras basadas en vuestros comentarios! +ยกRoo Code 3.22 trae nuevas funcionalidades poderosas y mejoras significativas para mejorar tu flujo de trabajo de desarrollo! -- **Lanzamiento del Marketplace de Roo** - ยกEl marketplace ya estรก en funcionamiento! ยกEl marketplace ya estรก en funcionamiento! Descubre e instala modos y MCPs mรกs fรกcilmente que nunca. -- **Modelos Gemini 2.5** - Se ha aรฑadido soporte para los nuevos modelos Gemini 2.5 Pro, Flash y Flash Lite. -- **Soporte de Archivos Excel y Mรกs** - ยกSe ha aรฑadido soporte para archivos Excel (.xlsx) y numerosas correcciones de errores y mejoras! +- **Compartir tareas con 1 clic** - Comparte tus tareas instantรกneamente con colegas y la comunidad con un solo clic. +- **Soporte de directorio .roo global** - Carga reglas y configuraciones desde un directorio .roo global para configuraciones consistentes entre proyectos. +- **Transiciones mejoradas de Arquitecto a Cรณdigo** - Transferencias fluidas desde la planificaciรณn en modo Arquitecto hasta la implementaciรณn en modo Cรณdigo. --- @@ -181,41 +181,43 @@ Usamos [changesets](https://github.com/changesets/changesets) para versionar y p ยกGracias a todos nuestros colaboradores que han ayudado a mejorar Roo Code! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Licencia diff --git a/locales/fr/README.md b/locales/fr/README.md index 9c093562e2..f65cf68408 100644 --- a/locales/fr/README.md +++ b/locales/fr/README.md @@ -50,13 +50,13 @@ Consultez le [CHANGELOG](../../CHANGELOG.md) pour des mises ร  jour dรฉtaillรฉes --- -## ๐ŸŽ‰ Roo Code 3.21 est sorti +## ๐ŸŽ‰ Roo Code 3.22 est sorti -Roo Code 3.21 apporte de nouvelles fonctionnalitรฉs majeures et des amรฉliorations basรฉes sur vos retours ! +Roo Code 3.22 apporte de puissantes nouvelles fonctionnalitรฉs et des amรฉliorations significatives pour amรฉliorer ton flux de travail de dรฉveloppement ! -- **Le marketplace est maintenant en ligne ! Le marketplace est maintenant en ligne !** Dรฉcouvrez et installez des modes et des MCPs plus facilement que jamais. -- **Ajout du support pour les nouveaux modรจles Gemini 2.5 Pro, Flash et Flash Lite.** -- **Support des Fichiers Excel et Plus !** - Support MCP amรฉliorรฉ, plus de contrรดles Mermaid, support de rรฉflexion dans Amazon Bedrock, et bien plus ! +- **Partage de tรขches en 1 clic** - Partage tes tรขches instantanรฉment avec tes collรจgues et la communautรฉ en un seul clic. +- **Support du rรฉpertoire .roo global** - Charge les rรจgles et configurations depuis un rรฉpertoire .roo global pour des paramรจtres cohรฉrents entre les projets. +- **Transitions amรฉliorรฉes d'Architecte vers Code** - Transferts fluides de la planification en mode Architecte vers l'implรฉmentation en mode Code. --- @@ -181,41 +181,43 @@ Nous adorons les contributions de la communautรฉ ! Commencez par lire notre [CON Merci ร  tous nos contributeurs qui ont aidรฉ ร  amรฉliorer Roo Code ! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Licence diff --git a/locales/ja/README.md b/locales/ja/README.md index 1d31dc9da7..11e2edae4e 100644 --- a/locales/ja/README.md +++ b/locales/ja/README.md @@ -50,13 +50,13 @@ --- -## ๐ŸŽ‰ Roo Code 3.21 ใƒชใƒชใƒผใ‚น +## ๐ŸŽ‰ Roo Code 3.22 ใƒชใƒชใƒผใ‚น -Roo Code 3.21ใฏใ€็š†ๆง˜ใฎใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏใซๅŸบใฅใๆ–ฐใ—ใ„ไธป่ฆๆฉŸ่ƒฝใจๆ”นๅ–„ใ‚’ใ‚‚ใŸใ‚‰ใ—ใพใ™๏ผ +Roo Code 3.22ใฏใ€้–‹็™บใƒฏใƒผใ‚ฏใƒ•ใƒญใƒผใ‚’ๅ‘ไธŠใ•ใ›ใ‚‹ๅผทๅŠ›ใชๆ–ฐๆฉŸ่ƒฝใจ้‡่ฆใชๆ”นๅ–„ใ‚’ใ‚‚ใŸใ‚‰ใ—ใพใ™๏ผ -- **ใƒžใƒผใ‚ฑใƒƒใƒˆใƒ—ใƒฌใ‚คใ‚นใŒ็จผๅƒ้–‹ๅง‹๏ผใƒžใƒผใ‚ฑใƒƒใƒˆใƒ—ใƒฌใ‚คใ‚นใŒ็จผๅƒ้–‹ๅง‹๏ผ** ใ“ใ‚ŒใพใงไปฅไธŠใซ็ฐกๅ˜ใซใƒขใƒผใƒ‰ใจMCPใ‚’็™บ่ฆ‹ใ—ใฆใ‚คใƒณใ‚นใƒˆใƒผใƒซใงใใพใ™ใ€‚ -- **ๆ–ฐใ—ใ„Gemini 2.5 Proใ€Flashใ€Flash Liteใƒขใƒ‡ใƒซใฎใ‚ตใƒใƒผใƒˆใ‚’่ฟฝๅŠ ใ€‚** -- **Excel ใƒ•ใ‚กใ‚คใƒซใ‚ตใƒใƒผใƒˆใชใฉ** - MCP ใ‚ตใƒใƒผใƒˆใฎๅ‘ไธŠใ€Mermaidๅˆถๅพกใฎ่ฟฝๅŠ ใ€Amazon Bedrock thinking ใ‚ตใƒใƒผใƒˆใ€ใใฎไป–ๅคšๆ•ฐ๏ผ +- **1ใ‚ฏใƒชใƒƒใ‚ฏใ‚ฟใ‚นใ‚ฏๅ…ฑๆœ‰** - ๅŒๅƒšใ‚„ใ‚ณใƒŸใƒฅใƒ‹ใƒ†ใ‚ฃใจใ‚ฟใ‚นใ‚ฏใ‚’1ใ‚ฏใƒชใƒƒใ‚ฏใง็žฌๆ™‚ใซๅ…ฑๆœ‰ใงใใพใ™ใ€‚ +- **ใ‚ฐใƒญใƒผใƒใƒซ.rooใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚ตใƒใƒผใƒˆ** - ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ้–“ใงไธ€่ฒซใ—ใŸ่จญๅฎšใฎใŸใ‚ใซใ‚ฐใƒญใƒผใƒใƒซ.rooใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‹ใ‚‰ใƒซใƒผใƒซใจ่จญๅฎšใ‚’่ชญใฟ่พผใฟใพใ™ใ€‚ +- **ๆ”นๅ–„ใ•ใ‚ŒใŸใ‚ขใƒผใ‚ญใƒ†ใ‚ฏใƒˆใ‹ใ‚‰ใ‚ณใƒผใƒ‰ใธใฎ็งป่กŒ** - ใ‚ขใƒผใ‚ญใƒ†ใ‚ฏใƒˆใƒขใƒผใƒ‰ใงใฎ่จˆ็”ปใ‹ใ‚‰ใ‚ณใƒผใƒ‰ใƒขใƒผใƒ‰ใงใฎๅฎŸ่ฃ…ใธใฎใ‚ทใƒผใƒ ใƒฌใ‚นใชๅผ•ใ็ถ™ใŽใ€‚ --- @@ -181,41 +181,43 @@ code --install-extension bin/roo-cline-.vsix Roo Codeใฎๆ”นๅ–„ใซ่ฒข็Œฎใ—ใฆใใ‚ŒใŸใ™ในใฆใฎ่ฒข็Œฎ่€…ใซๆ„Ÿ่ฌใ—ใพใ™๏ผ -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## ใƒฉใ‚คใ‚ปใƒณใ‚น diff --git a/locales/ko/README.md b/locales/ko/README.md index d03fd157b3..ace26896f2 100644 --- a/locales/ko/README.md +++ b/locales/ko/README.md @@ -50,13 +50,13 @@ --- -## ๐ŸŽ‰ Roo Code 3.21 ์ถœ์‹œ +## ๐ŸŽ‰ Roo Code 3.22 ์ถœ์‹œ -Roo Code 3.21์ด ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•œ ์ƒˆ๋กœ์šด ์ฃผ์š” ๊ธฐ๋Šฅ๊ณผ ๊ฐœ์„ ์‚ฌํ•ญ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค! +Roo Code 3.22๊ฐ€ ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๊ฐ•๋ ฅํ•œ ์ƒˆ ๊ธฐ๋Šฅ๊ณผ ์ค‘์š”ํ•œ ๊ฐœ์„ ์‚ฌํ•ญ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค! -- **๋งˆ์ผ“ํ”Œ๋ ˆ์ด์Šค๊ฐ€ ์ด์ œ ๋ผ์ด๋ธŒ์ž…๋‹ˆ๋‹ค! ๋งˆ์ผ“ํ”Œ๋ ˆ์ด์Šค๊ฐ€ ์ด์ œ ๋ผ์ด๋ธŒ์ž…๋‹ˆ๋‹ค!** ๊ทธ ์–ด๋А ๋•Œ๋ณด๋‹ค ์‰ฝ๊ฒŒ ๋ชจ๋“œ์™€ MCP๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  ์„ค์น˜ํ•˜์„ธ์š”. -- **์ƒˆ๋กœ์šด Gemini 2.5 Pro, Flash, Flash Lite ๋ชจ๋ธ ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.** -- **Excel ํŒŒ์ผ ์ง€์› ๋“ฑ** - ํ–ฅ์ƒ๋œ MCP ์ง€์›, ๋” ๋งŽ์€ Mermaid ์ œ์–ด, Amazon Bedrock thinking ์ง€์› ๋“ฑ! +- **1ํด๋ฆญ ์ž‘์—… ๊ณต์œ ** - ๋™๋ฃŒ์™€ ์ปค๋ฎค๋‹ˆํ‹ฐ์— ํ•œ ๋ฒˆ์˜ ํด๋ฆญ์œผ๋กœ ์ฆ‰์‹œ ์ž‘์—…์„ ๊ณต์œ ํ•˜์„ธ์š”. +- **๊ธ€๋กœ๋ฒŒ .roo ๋””๋ ‰ํ† ๋ฆฌ ์ง€์›** - ํ”„๋กœ์ ํŠธ ๊ฐ„ ์ผ๊ด€๋œ ์„ค์ •์„ ์œ„ํ•ด ๊ธ€๋กœ๋ฒŒ .roo ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๊ทœ์น™๊ณผ ๊ตฌ์„ฑ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. +- **๊ฐœ์„ ๋œ ์•„ํ‚คํ…ํŠธ์—์„œ ์ฝ”๋“œ๋กœ์˜ ์ „ํ™˜** - ์•„ํ‚คํ…ํŠธ ๋ชจ๋“œ์—์„œ์˜ ๊ณ„ํš๋ถ€ํ„ฐ ์ฝ”๋“œ ๋ชจ๋“œ์—์„œ์˜ ๊ตฌํ˜„๊นŒ์ง€ ์›ํ™œํ•œ ์ธ์ˆ˜์ธ๊ณ„. --- @@ -181,41 +181,43 @@ code --install-extension bin/roo-cline-.vsix Roo Code๋ฅผ ๋” ์ข‹๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ ๋„์›€์„ ์ค€ ๋ชจ๋“  ๊ธฐ์—ฌ์ž์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## ๋ผ์ด์„ ์Šค diff --git a/locales/nl/README.md b/locales/nl/README.md index 218c12b725..68a0dbd5f2 100644 --- a/locales/nl/README.md +++ b/locales/nl/README.md @@ -50,13 +50,13 @@ Bekijk de [CHANGELOG](../../CHANGELOG.md) voor gedetailleerde updates en fixes. --- -## ๐ŸŽ‰ Roo Code 3.21 Uitgebracht +## ๐ŸŽ‰ Roo Code 3.22 Uitgebracht -Roo Code 3.21 brengt krachtige nieuwe functies en verbeteringen op basis van jullie feedback! +Roo Code 3.22 brengt krachtige nieuwe functies en significante verbeteringen om je ontwikkelingsworkflow te verbeteren! -- **De marketplace is nu live! De marketplace is nu live!** Ontdek en installeer modi en MCP's eenvoudiger dan ooit tevoren. -- **Ondersteuning toegevoegd voor nieuwe Gemini 2.5 Pro, Flash en Flash Lite modellen.** -- **Excel Bestandsondersteuning & Meer** - Verbeterde Mermaid-controls voor betere diagramvisualisatie en nieuwe Amazon Bedrock thinking-ondersteuning voor meer geavanceerde AI-interacties! +- **1-Klik Taak Delen** - Deel je taken direct met collega's en de gemeenschap met een enkele klik. +- **Globale .roo Directory Ondersteuning** - Laad regels en configuraties vanuit een globale .roo directory voor consistente instellingen tussen projecten. +- **Verbeterde Architect naar Code Overgangen** - Naadloze overdrachten van planning in Architect-modus naar implementatie in Code-modus. --- @@ -181,41 +181,43 @@ We houden van bijdragen uit de community! Begin met het lezen van onze [CONTRIBU Dank aan alle bijdragers die Roo Code beter hebben gemaakt! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Licentie diff --git a/locales/pl/README.md b/locales/pl/README.md index 023f27cb15..62e2eccda5 100644 --- a/locales/pl/README.md +++ b/locales/pl/README.md @@ -50,13 +50,13 @@ Sprawdลบ [CHANGELOG](../../CHANGELOG.md), aby uzyskaฤ‡ szczegรณล‚owe informacje --- -## ๐ŸŽ‰ Roo Code 3.21 zostaล‚ wydany +## ๐ŸŽ‰ Roo Code 3.22 zostaล‚ wydany -Roo Code 3.21 wprowadza potฤ™ลผne nowe funkcje i usprawnienia na podstawie opinii uลผytkownikรณw! +Roo Code 3.22 wprowadza potฤ™ลผne nowe funkcje i znaczฤ…ce usprawnienia, aby ulepszyฤ‡ Twรณj przepล‚yw pracy deweloperskiej! -- **Marketplace jest teraz na ลผywo! Marketplace jest teraz na ลผywo!** Odkrywaj i instaluj tryby oraz MCP ล‚atwiej niลผ kiedykolwiek wczeล›niej. -- **Dodano wsparcie dla nowych modeli Gemini 2.5 Pro, Flash i Flash Lite.** -- **Wsparcie plikรณw Excel i wiฤ™cej** - Ulepszone kontrolki Mermaid dla lepszej wizualizacji diagramรณw oraz nowe wsparcie Amazon Bedrock thinking dla bardziej zaawansowanych interakcji z AI! +- **Udostฤ™pnianie zadaล„ jednym klikniฤ™ciem** - Udostฤ™pniaj swoje zadania natychmiast wspรณล‚pracownikom i spoล‚ecznoล›ci jednym klikniฤ™ciem. +- **Wsparcie globalnego katalogu .roo** - ลaduj zasady i konfiguracje z globalnego katalogu .roo dla spรณjnych ustawieล„ miฤ™dzy projektami. +- **Ulepszone przejล›cia z Architekta do Kodu** - Pล‚ynne przekazania od planowania w trybie Architekta do implementacji w trybie Kodu. --- @@ -181,41 +181,43 @@ Kochamy wkล‚ad spoล‚ecznoล›ci! Zacznij od przeczytania naszego [CONTRIBUTING.md] Dziฤ™kujemy wszystkim naszym wspรณล‚twรณrcom, ktรณrzy pomogli ulepszyฤ‡ Roo Code! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Licencja diff --git a/locales/pt-BR/README.md b/locales/pt-BR/README.md index 74d4d36a43..88d5f3e7be 100644 --- a/locales/pt-BR/README.md +++ b/locales/pt-BR/README.md @@ -50,13 +50,13 @@ Confira o [CHANGELOG](../../CHANGELOG.md) para atualizaรงรตes e correรงรตes deta --- -## ๐ŸŽ‰ Roo Code 3.21 foi lanรงado +## ๐ŸŽ‰ Roo Code 3.22 foi lanรงado -O Roo Code 3.21 introduz novos recursos poderosos e melhorias baseadas no feedback dos usuรกrios! +O Roo Code 3.22 traz novos recursos poderosos e melhorias significativas para aprimorar seu fluxo de trabalho de desenvolvimento! -- **O marketplace estรก agora disponรญvel! O marketplace estรก agora disponรญvel!** Descubra e instale modos e MCPs mais facilmente do que nunca. -- **Adicionado suporte para os novos modelos Gemini 2.5 Pro, Flash e Flash Lite.** -- **Suporte a Arquivos Excel e Mais** - Controles Mermaid aprimorados para melhor visualizaรงรฃo de diagramas e novo suporte Amazon Bedrock thinking para interaรงรตes de IA mais avanรงadas! +- **Compartilhamento de Tarefas com 1 Clique** - Compartilhe suas tarefas instantaneamente com colegas e a comunidade com um รบnico clique. +- **Suporte a Diretรณrio .roo Global** - Carregue regras e configuraรงรตes de um diretรณrio .roo global para configuraรงรตes consistentes entre projetos. +- **Transiรงรตes Aprimoradas de Arquiteto para Cรณdigo** - Transferรชncias perfeitas do planejamento no modo Arquiteto para implementaรงรฃo no modo Cรณdigo. --- @@ -181,41 +181,43 @@ Adoramos contribuiรงรตes da comunidade! Comece lendo nosso [CONTRIBUTING.md](CON Obrigado a todos os nossos contribuidores que ajudaram a tornar o Roo Code melhor! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Licenรงa diff --git a/locales/ru/README.md b/locales/ru/README.md index 3e9133cb97..5d1bb222ce 100644 --- a/locales/ru/README.md +++ b/locales/ru/README.md @@ -50,13 +50,13 @@ --- -## ๐ŸŽ‰ ะ’ั‹ะฟัƒั‰ะตะฝ Roo Code 3.21 +## ๐ŸŽ‰ ะ’ั‹ะฟัƒั‰ะตะฝ Roo Code 3.22 -Roo Code 3.21 ะฟั€ะตะดัั‚ะฐะฒะปัะตั‚ ัะบัะฟะตั€ะธะผะตะฝั‚ะฐะปัŒะฝั‹ะน ะผะฐั€ะบะตั‚ะฟะปะตะนั ะธ ัƒะปัƒั‡ัˆะตะฝะธั ั„ะฐะนะปะพะฒั‹ั… ะพะฟะตั€ะฐั†ะธะน! +Roo Code 3.22 ะฟั€ะตะดัั‚ะฐะฒะปัะตั‚ ะผะพั‰ะฝั‹ะต ะฝะพะฒั‹ะต ั„ัƒะฝะบั†ะธะธ ะธ ะทะฝะฐั‡ะธั‚ะตะปัŒะฝั‹ะต ัƒะปัƒั‡ัˆะตะฝะธั ะดะปั ะฟะพะฒั‹ัˆะตะฝะธั ัั„ั„ะตะบั‚ะธะฒะฝะพัั‚ะธ ะฒะฐัˆะตะณะพ ั€ะฐะฑะพั‡ะตะณะพ ะฟั€ะพั†ะตััะฐ ั€ะฐะทั€ะฐะฑะพั‚ะบะธ! -- **ะœะฐั€ะบะตั‚ะฟะปะตะนั ั‚ะตะฟะตั€ัŒ ะดะพัั‚ัƒะฟะตะฝ! ะœะฐั€ะบะตั‚ะฟะปะตะนั ั‚ะตะฟะตั€ัŒ ะดะพัั‚ัƒะฟะตะฝ!** ะžั‚ะบั€ั‹ะฒะฐะนั‚ะต ะธ ัƒัั‚ะฐะฝะฐะฒะปะธะฒะฐะนั‚ะต ั€ะตะถะธะผั‹ ะธ MCP ะฟั€ะพั‰ะต, ั‡ะตะผ ะบะพะณะดะฐ-ะปะธะฑะพ. -- **ะ”ะพะฑะฐะฒะปะตะฝะฐ ะฟะพะดะดะตั€ะถะบะฐ ะฝะพะฒั‹ั… ะผะพะดะตะปะตะน Gemini 2.5 Pro, Flash ะธ Flash Lite.** -- **ะŸะพะดะดะตั€ะถะบะฐ ั„ะฐะนะปะพะฒ Excel ะธ ะผะฝะพะณะพะต ะดั€ัƒะณะพะต!** - ะะพะฒั‹ะต ัะปะตะผะตะฝั‚ั‹ ัƒะฟั€ะฐะฒะปะตะฝะธั Mermaid ะธ ะฟะพะดะดะตั€ะถะบะฐ ะผั‹ัˆะปะตะฝะธั Amazon Bedrock ะดะปั ั€ะฐััˆะธั€ะตะฝะฝั‹ั… ะฒะพะทะผะพะถะฝะพัั‚ะตะน MCP. +- **ะžะฑะผะตะฝ ะทะฐะดะฐั‡ะฐะผะธ ะฒ 1 ะบะปะธะบ** - ะœะณะฝะพะฒะตะฝะฝะพ ะดะตะปะธั‚ะตััŒ ัะฒะพะธะผะธ ะทะฐะดะฐั‡ะฐะผะธ ั ะบะพะปะปะตะณะฐะผะธ ะธ ัะพะพะฑั‰ะตัั‚ะฒะพะผ ะพะดะฝะธะผ ะบะปะธะบะพะผ. +- **ะŸะพะดะดะตั€ะถะบะฐ ะณะปะพะฑะฐะปัŒะฝะพะณะพ ะบะฐั‚ะฐะปะพะณะฐ .roo** - ะ—ะฐะณั€ัƒะถะฐะนั‚ะต ะฟั€ะฐะฒะธะปะฐ ะธ ะบะพะฝั„ะธะณัƒั€ะฐั†ะธะธ ะธะท ะณะปะพะฑะฐะปัŒะฝะพะณะพ ะบะฐั‚ะฐะปะพะณะฐ .roo ะดะปั ัะพะณะปะฐัะพะฒะฐะฝะฝั‹ั… ะฝะฐัั‚ั€ะพะตะบ ะผะตะถะดัƒ ะฟั€ะพะตะบั‚ะฐะผะธ. +- **ะฃะปัƒั‡ัˆะตะฝะฝั‹ะต ะฟะตั€ะตั…ะพะดั‹ ะพั‚ ะั€ั…ะธั‚ะตะบั‚ะพั€ะฐ ะบ ะšะพะดัƒ** - ะŸะปะฐะฒะฝั‹ะต ะฟะตั€ะตะดะฐั‡ะธ ะพั‚ ะฟะปะฐะฝะธั€ะพะฒะฐะฝะธั ะฒ ั€ะตะถะธะผะต ะั€ั…ะธั‚ะตะบั‚ะพั€ะฐ ะบ ั€ะตะฐะปะธะทะฐั†ะธะธ ะฒ ั€ะตะถะธะผะต ะšะพะดะฐ. --- @@ -181,41 +181,43 @@ code --install-extension bin/roo-cline-.vsix ะกะฟะฐัะธะฑะพ ะฒัะตะผ ะฝะฐัˆะธะผ ัƒั‡ะฐัั‚ะฝะธะบะฐะผ, ะบะพั‚ะพั€ั‹ะต ะฟะพะผะพะณะปะธ ัะดะตะปะฐั‚ัŒ Roo Code ะปัƒั‡ัˆะต! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## ะ›ะธั†ะตะฝะทะธั diff --git a/locales/tr/README.md b/locales/tr/README.md index cc26916c32..326b46cc62 100644 --- a/locales/tr/README.md +++ b/locales/tr/README.md @@ -50,13 +50,13 @@ Detaylฤฑ gรผncellemeler ve dรผzeltmeler iรงin [CHANGELOG](../../CHANGELOG.md) do --- -## ๐ŸŽ‰ Roo Code 3.21 Yayฤฑnlandฤฑ +## ๐ŸŽ‰ Roo Code 3.22 Yayฤฑnlandฤฑ -Roo Code 3.21 deneysel pazar yeri ve geliลŸmiลŸ dosya iลŸlemleri sunuyor! +Roo Code 3.22 geliลŸtirme iลŸ akฤฑลŸฤฑnฤฑzฤฑ geliลŸtirmek iรงin gรผรงlรผ yeni รถzellikler ve รถnemli iyileลŸtirmeler getiriyor! -- **Pazar yeri artฤฑk canlฤฑ! Pazar yeri artฤฑk canlฤฑ!** Modlarฤฑ ve MCP'leri her zamankinden daha kolay keลŸfedin ve kurun. -- **Yeni Gemini 2.5 Pro, Flash ve Flash Lite modelleri iรงin destek eklendi.** -- **Excel Dosya DesteฤŸi ve Daha Fazlasฤฑ!** - GeliลŸmiลŸ MCP yetenekleri iรงin yeni Mermaid kontrolleri ve Amazon Bedrock dรผลŸรผnce desteฤŸi. +- **1-Tฤฑk Gรถrev PaylaลŸฤฑmฤฑ** - Gรถrevlerinizi tek tฤฑkla meslektaลŸlarฤฑnฤฑz ve toplulukla anฤฑnda paylaลŸฤฑn. +- **Global .roo Dizin DesteฤŸi** - Projeler arasฤฑ tutarlฤฑ ayarlar iรงin global .roo dizininden kurallarฤฑ ve konfigรผrasyonlarฤฑ yรผkleyin. +- **GeliลŸmiลŸ Mimar'dan Kod'a GeรงiลŸler** - Mimar modunda planlamadan Kod modunda uygulamaya sorunsuz aktarฤฑmlar. --- @@ -181,41 +181,43 @@ Topluluk katkฤฑlarฤฑnฤฑ seviyoruz! [CONTRIBUTING.md](CONTRIBUTING.md) dosyasฤฑn Roo Code'u daha iyi hale getirmeye yardฤฑmcฤฑ olan tรผm katkฤฑda bulunanlara teลŸekkรผr ederiz! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Lisans diff --git a/locales/vi/README.md b/locales/vi/README.md index 3f21cb2729..3d4a02d0ca 100644 --- a/locales/vi/README.md +++ b/locales/vi/README.md @@ -50,13 +50,13 @@ Kiแปƒm tra [CHANGELOG](../../CHANGELOG.md) ฤ‘แปƒ biแบฟt thรดng tin chi tiแบฟt v --- -## ๐ŸŽ‰ ฤรฃ Phรกt Hร nh Roo Code 3.21 +## ๐ŸŽ‰ ฤรฃ Phรกt Hร nh Roo Code 3.22 -Roo Code 3.21 giแป›i thiแป‡u marketplace thแปญ nghiแป‡m vร  cแบฃi tiแบฟn cรกc thao tรกc tแบญp tin! +Roo Code 3.22 mang ฤ‘แบฟn nhแปฏng tรญnh nฤƒng mแป›i mแบกnh mแบฝ vร  cแบฃi tiแบฟn ฤ‘รกng kแปƒ ฤ‘แปƒ nรขng cao quy trรฌnh phรกt triแปƒn cแปงa bแบกn! -- **Marketplace hiแป‡n ฤ‘รฃ hoแบกt ฤ‘แป™ng! Marketplace hiแป‡n ฤ‘รฃ hoแบกt ฤ‘แป™ng!** Khรกm phรก vร  cร i ฤ‘แบทt cรกc chแบฟ ฤ‘แป™ vร  MCP dแป… dร ng hฦกn bao giแป hแบฟt. -- **ฤรฃ thรชm hแป— trแปฃ cho cรกc mรด hรฌnh Gemini 2.5 Pro, Flash vร  Flash Lite mแป›i.** -- **Hแป— trแปฃ tแบญp tin Excel vร  nhiแปu hฦกn nแปฏa!** - Cรกc ฤ‘iแปu khiแปƒn Mermaid mแป›i vร  hแป— trแปฃ suy nghฤฉ Amazon Bedrock cho khแบฃ nฤƒng MCP nรขng cao. +- **Chia Sแบป Tรกc Vแปฅ 1-Cรบ Nhแบฅp** - Chia sแบป tรกc vแปฅ cแปงa bแบกn ngay lแบญp tแปฉc vแป›i ฤ‘แป“ng nghiแป‡p vร  cแป™ng ฤ‘แป“ng chแป‰ bแบฑng mแป™t cรบ nhแบฅp. +- **Hแป— Trแปฃ Thฦฐ Mแปฅc .roo Toร n Cแปฅc** - Tแบฃi quy tแบฏc vร  cแบฅu hรฌnh tแปซ thฦฐ mแปฅc .roo toร n cแปฅc ฤ‘แปƒ cรณ cร i ฤ‘แบทt nhแบฅt quรกn giแปฏa cรกc dแปฑ รกn. +- **Cแบฃi Thiแป‡n Chuyแปƒn ฤแป•i tแปซ Architect sang Code** - Chuyแปƒn giao liแปn mแบกch tแปซ lแบญp kแบฟ hoแบกch trong chแบฟ ฤ‘แป™ Architect sang triแปƒn khai trong chแบฟ ฤ‘แป™ Code. --- @@ -181,41 +181,43 @@ Chรบng tรดi rแบฅt hoan nghรชnh ฤ‘รณng gรณp tแปซ cแป™ng ฤ‘แป“ng! Bแบฏt ฤ‘แบงu b Cแบฃm ฦกn tแบฅt cแบฃ nhแปฏng ngฦฐแปi ฤ‘รณng gรณp ฤ‘รฃ giรบp cแบฃi thiแป‡n Roo Code! -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## Giแบฅy Phรฉp diff --git a/locales/zh-CN/README.md b/locales/zh-CN/README.md index b6eb4e8ab5..5efcd537c2 100644 --- a/locales/zh-CN/README.md +++ b/locales/zh-CN/README.md @@ -50,13 +50,13 @@ --- -## ๐ŸŽ‰ Roo Code 3.21 ๅทฒๅ‘ๅธƒ +## ๐ŸŽ‰ Roo Code 3.22 ๅทฒๅ‘ๅธƒ -Roo Code 3.21 ๆ นๆฎๆ‚จ็š„ๅ้ฆˆๅธฆๆฅ้‡่ฆ็š„ๆ–ฐๅŠŸ่ƒฝๅ’Œๆ”น่ฟ›๏ผ +Roo Code 3.22 ๅธฆๆฅๅผบๅคง็š„ๆ–ฐๅŠŸ่ƒฝๅ’Œ้‡ๅคงๆ”น่ฟ›๏ผŒๆๅ‡ๆ‚จ็š„ๅผ€ๅ‘ๅทฅไฝœๆต็จ‹๏ผ -- **ๅธ‚ๅœบ็ŽฐๅทฒไธŠ็บฟ๏ผๅธ‚ๅœบ็ŽฐๅทฒไธŠ็บฟ๏ผ** ไปŽๆ–ฐๅธ‚ๅœบๅ‘็Žฐๅ’Œๅฎ‰่ฃ…ๆจกๅผๅ’Œ MCP ๆฏ”ไปฅๅพ€ๆ›ดๅฎนๆ˜“๏ผˆๅœจๅฎž้ชŒๆ€ง่ฎพ็ฝฎไธญๅฏ็”จ๏ผ‰ใ€‚ -- **ๆ–ฐๅขž Gemini 2.5 Proใ€Flash ๅ’Œ Flash Lite ๆจกๅž‹ๆ”ฏๆŒใ€‚** ๅคšไธชๅนถๅ‘ๆ–‡ไปถๅ†™ๅ…ฅ็Žฐๅœจๅœจๅฎž้ชŒๆ€ง่ฎพ็ฝฎไธญๅฏ็”จ๏ผŒๅคšไธชๅนถๅ‘่ฏปๅ–ๅทฒไปŽๅฎž้ชŒๆ€งๅŠŸ่ƒฝๆฏ•ไธš๏ผŒ็ŽฐๅœจไฝไบŽไธŠไธ‹ๆ–‡่ฎพ็ฝฎไธญใ€‚ -- **Excel ๆ–‡ไปถๆ”ฏๆŒๅŠๆ›ดๅคšๅŠŸ่ƒฝ๏ผ** - ๅขžๅผบ็š„ MCP ๆ”ฏๆŒใ€ๆ›ดๅคš Mermaid ๆŽงไปถใ€Amazon Bedrock ไธญ็š„ๆ€่€ƒๆ”ฏๆŒ๏ผŒไปฅๅŠๆ›ดๅคšๅŠŸ่ƒฝ๏ผ +- **ไธ€้”ฎไปปๅŠกๅˆ†ไบซ** - ไธ€้”ฎๅณๅฏไธŽๅŒไบ‹ๅ’Œ็คพๅŒบๅˆ†ไบซๆ‚จ็š„ไปปๅŠกใ€‚ +- **ๅ…จๅฑ€ .roo ็›ฎๅฝ•ๆ”ฏๆŒ** - ไปŽๅ…จๅฑ€ .roo ็›ฎๅฝ•ๅŠ ่ฝฝ่ง„ๅˆ™ๅ’Œ้…็ฝฎ๏ผŒ็กฎไฟ้กน็›ฎ้—ด่ฎพ็ฝฎไธ€่‡ดใ€‚ +- **ๆ”น่ฟ›็š„ๆžถๆž„ๅธˆๅˆฐไปฃ็ ๆจกๅผ่ฝฌๆข** - ไปŽๆžถๆž„ๅธˆๆจกๅผ็š„่ง„ๅˆ’ๅˆฐไปฃ็ ๆจกๅผ็š„ๅฎž็Žฐ๏ผŒๅฎž็Žฐๆ— ็ผไบคๆŽฅใ€‚ --- @@ -181,41 +181,43 @@ code --install-extension bin/roo-cline-.vsix ๆ„Ÿ่ฐขๆ‰€ๆœ‰ๅธฎๅŠฉๆ”น่ฟ› Roo Code ็š„่ดก็Œฎ่€…๏ผ -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## ่ฎธๅฏ่ฏ diff --git a/locales/zh-TW/README.md b/locales/zh-TW/README.md index cc4c2f67c7..1f22263006 100644 --- a/locales/zh-TW/README.md +++ b/locales/zh-TW/README.md @@ -51,13 +51,13 @@ --- -## ๐ŸŽ‰ Roo Code 3.21 ๅทฒ็™ผๅธƒ +## ๐ŸŽ‰ Roo Code 3.22 ๅทฒ็™ผๅธƒ -Roo Code 3.21 ๆŽจๅ‡บๅฏฆ้ฉ—ๆ€งๅธ‚้›†ๅ’Œๆช”ๆกˆๆ“ไฝœๆ”น้€ฒ๏ผ +Roo Code 3.22 ๅธถไพ†ๅผทๅคง็š„ๆ–ฐๅŠŸ่ƒฝๅ’Œ้‡ๅคงๆ”น้€ฒ๏ผŒไปฅๆๅ‡ๆ‚จ็š„้–‹็™ผๅทฅไฝœๆต็จ‹๏ผ -- **ๅธ‚้›†็พๅทฒไธŠ็ทš๏ผๅธ‚้›†็พๅทฒไธŠ็ทš๏ผ** ๅพžๆ–ฐๅธ‚้›†ๆŽข็ดขไธฆๅฎ‰่ฃๆจกๅผๅ’Œ MCP ๆฏ”ไปฅๅพ€ๆ›ดๅฎนๆ˜“๏ผˆๅœจๅฏฆ้ฉ—ๆ€ง่จญๅฎšไธญๅ•Ÿ็”จ๏ผ‰ใ€‚ -- **ๆ–ฐๅขž Gemini 2.5 Proใ€Flash ๅ’Œ Flash Lite ๆจกๅž‹ๆ”ฏๆดใ€‚** ๅคš้‡ๅŒๆ™‚ๆช”ๆกˆๅฏซๅ…ฅ็พๅœจๅฏๅœจๅฏฆ้ฉ—ๆ€ง่จญๅฎšไธญไฝฟ็”จ๏ผŒๅคš้‡ๅŒๆ™‚่ฎ€ๅ–ๅทฒ็งป่‡ณไธŠไธ‹ๆ–‡่จญๅฎšใ€‚ -- **Excel ๆช”ๆกˆๆ”ฏๆดๅŠๆ›ดๅคšๅŠŸ่ƒฝ๏ผ** - ๆ–ฐ็š„ Mermaid ๆŽงๅˆถ้ …ๅ’Œ Amazon Bedrock ๆ€่€ƒๆ”ฏๆด๏ผŒๆไพ›ๅขžๅผท็š„ MCP ๅŠŸ่ƒฝใ€‚ +- **ไธ€้ตไปปๅ‹™ๅˆ†ไบซ** - ๅช้œ€ไธ€้ตๅณๅฏ็ซ‹ๅณ่ˆ‡ๅŒไบ‹ๅ’Œ็คพ็พคๅˆ†ไบซๆ‚จ็š„ไปปๅ‹™ใ€‚ +- **ๅ…จๅŸŸ .roo ็›ฎ้Œ„ๆ”ฏๆด** - ๅพžๅ…จๅŸŸ .roo ็›ฎ้Œ„่ผ‰ๅ…ฅ่ฆๅ‰‡ๅ’Œ่จญๅฎš๏ผŒ็ขบไฟๅฐˆๆกˆ้–“่จญๅฎš็š„ไธ€่‡ดๆ€งใ€‚ +- **ๆ”น้€ฒ็š„ๆžถๆง‹ๅธซๅˆฐ็จ‹ๅผ็ขผ่ฝ‰ๆ›** - ๅพžๆžถๆง‹ๅธซๆจกๅผ็š„่ฆๅŠƒๅˆฐ็จ‹ๅผ็ขผๆจกๅผ็š„ๅฏฆไฝœ๏ผŒๅฏฆ็พ็„ก็ธซไบคๆŽฅใ€‚ --- @@ -182,41 +182,43 @@ code --install-extension bin/roo-cline-.vsix ๆ„Ÿ่ฌๆ‰€ๆœ‰ๅนซๅŠฉๆ”น้€ฒ Roo Code ็š„่ฒข็ป่€…๏ผ -|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| -|:---:|:---:|:---:|:---:|:---:|:---:| -|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| -|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | + +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| +| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| +| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| +| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| +| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| +| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| +| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| +| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| +| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| +| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| +| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| +| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| +| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| +| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| +| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| +| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| +| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| +| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| +| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| +| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| +| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| +| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| +| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| +| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| +| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| +| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| +| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| +| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | + ## ๆŽˆๆฌŠ diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 9d99eea1d4..8eb6108a76 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -110,7 +110,7 @@ export class ClineProvider public isViewLaunched = false public settingsImportedAt?: number - public readonly latestAnnouncementId = "jun-17-2025-3-21" // Update for v3.21.0 announcement + public readonly latestAnnouncementId = "jul-02-2025-3-22-6" // Update for v3.22.6 announcement public readonly providerSettingsManager: ProviderSettingsManager public readonly customModesManager: CustomModesManager diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index dbcd9e69dd..1dd892a39f 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -239,14 +239,14 @@ "countdownDisplay": "{{count}}s" }, "announcement": { - "title": "๐ŸŽ‰ Roo Code {{version}} publicat", - "description": "Roo Code {{version}} porta noves funcionalitats potents i millores basades en els teus comentaris.", + "title": "๐ŸŽ‰ Roo Code {{version}} Llanรงat", + "description": "Roo Code {{version}} porta noves funcions potents i millores significatives per millorar el vostre flux de treball de desenvolupament.", "whatsNew": "Novetats", - "feature1": "Llanรงament del Marketplace Roo - El marketplace ja estร  en funcionament! Descobreix i instalยทla modes i MCP mรฉs fร cilment que mai.", - "feature2": "Models Gemini 2.5 - S'ha afegit suport per als nous models Gemini 2.5 Pro, Flash i Flash Lite.", - "feature3": "Suport per a fitxers Excel i mรฉs - S'ha afegit suport per a fitxers Excel (.xlsx) i nombroses correccions d'errors i millores!", - "hideButton": "Amagar anunci", - "detailsDiscussLinks": "Obtingues mรฉs detalls i participa a Discord i Reddit ๐Ÿš€" + "feature1": "Comparticiรณ de Tasques amb 1 Clic: Comparteix instantร niament les vostres tasques amb companys i la comunitat amb un sol clic.", + "feature2": "Suport per a Directori Global .roo: Carrega regles i configuracions des d'un directori global .roo per a configuracions consistents entre projectes.", + "feature3": "Transicions Millorades d'Arquitecte a Codi: Transferรจncies fluides de la planificaciรณ en mode Arquitecte a la implementaciรณ en mode Codi.", + "hideButton": "Amaga l'anunci", + "detailsDiscussLinks": "Obtรฉn mรฉs detalls i uneix-te a les discussions a Discord i Reddit ๐Ÿš€" }, "browser": { "rooWantsToUse": "Roo vol utilitzar el navegador:", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index 057016af31..c62fe9d3bb 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} verรถffentlicht", - "description": "Roo Code {{version}} bringt wichtige neue Funktionen und Verbesserungen basierend auf deinem Feedback.", + "description": "Roo Code {{version}} bringt mรคchtige neue Funktionen und bedeutende Verbesserungen, um deinen Entwicklungsworkflow zu verbessern.", "whatsNew": "Was ist neu", - "feature1": "Roo Marketplace Launch: Der Marketplace ist jetzt live! Entdecke und installiere Modi und MCPs einfacher denn je.", - "feature2": "Gemini 2.5 Modelle: Unterstรผtzung fรผr neue Gemini 2.5 Pro, Flash und Flash Lite Modelle hinzugefรผgt.", - "feature3": "Excel-Datei-Unterstรผtzung & mehr: Excel (.xlsx) Datei-Unterstรผtzung hinzugefรผgt sowie zahlreiche Fehlerbehebungen und Verbesserungen!", + "feature1": "1-Klick-Aufgaben-Teilen: Teile deine Aufgaben sofort mit Kollegen und der Community mit einem einzigen Klick.", + "feature2": "Globale .roo-Verzeichnis-Unterstรผtzung: Lade Regeln und Konfigurationen aus einem globalen .roo-Verzeichnis fรผr konsistente Einstellungen รผber Projekte hinweg.", + "feature3": "Verbesserte Architect-zu-Code-รœbergรคnge: Nahtlose รœbergaben von der Planung im Architect-Modus zur Implementierung im Code-Modus.", "hideButton": "Ankรผndigung ausblenden", "detailsDiscussLinks": "Erhalte mehr Details und diskutiere auf Discord und Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 1f19490eef..ea4f8920f5 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -245,11 +245,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} Released", - "description": "Roo Code {{version}} brings major new features and improvements based on your feedback.", + "description": "Roo Code {{version}} brings powerful new features and significant improvements to enhance your development workflow.", "whatsNew": "What's New", - "feature1": "Roo Marketplace Launch: The marketplace is now live! Discover and install modes and MCPs easier than ever before.", - "feature2": "Gemini 2.5 Models: Added support for new Gemini 2.5 Pro, Flash, and Flash Lite models.", - "feature3": "Excel File Support & More: Added Excel (.xlsx) file support and numerous bug fixes and improvements!", + "feature1": "1-Click Task Sharing: Share your tasks instantly with colleagues and the community with a single click.", + "feature2": "Global .roo Directory Support: Load rules and configurations from a global .roo directory for consistent settings across projects.", + "feature3": "Improved Architect to Code Transitions: Seamless handoffs from planning in Architect mode to implementation in Code mode.", "hideButton": "Hide announcement", "detailsDiscussLinks": "Get more details and discuss in Discord and Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index 7f7b2583c6..a4349b13dc 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} publicado", - "description": "Roo Code {{version}} trae importantes nuevas funcionalidades y mejoras basadas en tus comentarios.", + "description": "Roo Code {{version}} trae poderosas nuevas funcionalidades y mejoras significativas para mejorar tu flujo de trabajo de desarrollo.", "whatsNew": "Novedades", - "feature1": "Lanzamiento del Marketplace de Roo: ยกEl marketplace ya estรก disponible! Descubre e instala modos y MCPs mรกs fรกcil que nunca.", - "feature2": "Modelos Gemini 2.5: Se agregรณ soporte para los nuevos modelos Gemini 2.5 Pro, Flash y Flash Lite.", - "feature3": "Soporte de archivos Excel y mรกs: ยกSe agregรณ soporte para archivos Excel (.xlsx) y numerosas correcciones de errores y mejoras!", + "feature1": "Compartir tareas con 1 clic: Comparte tus tareas instantรกneamente con colegas y la comunidad con un solo clic.", + "feature2": "Soporte de directorio .roo global: Carga reglas y configuraciones desde un directorio .roo global para configuraciones consistentes entre proyectos.", + "feature3": "Transiciones mejoradas de Arquitecto a Cรณdigo: Transferencias fluidas desde la planificaciรณn en modo Arquitecto hasta la implementaciรณn en modo Cรณdigo.", "hideButton": "Ocultar anuncio", "detailsDiscussLinks": "Obtรฉn mรกs detalles y participa en Discord y Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index fc310e57a1..b5f06354bb 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} est sortie", - "description": "Roo Code {{version}} apporte de nouvelles fonctionnalitรฉs majeures et des amรฉliorations basรฉes sur vos retours.", + "description": "Roo Code {{version}} apporte de puissantes nouvelles fonctionnalitรฉs et des amรฉliorations significatives pour amรฉliorer ton flux de travail de dรฉveloppement.", "whatsNew": "Quoi de neuf", - "feature1": "Lancement du Marketplace Roo : Le marketplace est maintenant en ligne ! Dรฉcouvrez et installez des modes et des MCPs plus facilement que jamais.", - "feature2": "Modรจles Gemini 2.5 : Ajout du support pour les nouveaux modรจles Gemini 2.5 Pro, Flash et Flash Lite.", - "feature3": "Support des fichiers Excel et plus : Ajout du support des fichiers Excel (.xlsx) et de nombreuses corrections de bugs et amรฉliorations !", + "feature1": "Partage de tรขches en 1 clic : Partage tes tรขches instantanรฉment avec tes collรจgues et la communautรฉ en un seul clic.", + "feature2": "Support du rรฉpertoire .roo global : Charge les rรจgles et configurations depuis un rรฉpertoire .roo global pour des paramรจtres cohรฉrents entre les projets.", + "feature3": "Transitions Architecte vers Code amรฉliorรฉes : Transferts fluides de la planification en mode Architecte vers l'implรฉmentation en mode Code.", "hideButton": "Masquer l'annonce", "detailsDiscussLinks": "Obtenez plus de dรฉtails et participez aux discussions sur Discord et Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index b3b2fe0b2d..9afdcbdd38 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -240,13 +240,13 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} เคฐเคฟเคฒเฅ€เคœเคผ เคนเฅเค†", - "description": "Roo Code {{version}} เค†เคชเค•เฅ‡ เคซเฅ€เคกเคฌเฅˆเค• เค•เฅ‡ เค†เคงเคพเคฐ เคชเคฐ เคถเค•เฅเคคเคฟเคถเคพเคฒเฅ€ เคจเคˆ เคธเฅเคตเคฟเคงเคพเคเค เค”เคฐ เคธเฅเคงเคพเคฐ เคฒเคพเคคเคพ เคนเฅˆเฅค", - "whatsNew": "เคจเคˆ เคธเฅเคตเคฟเคงเคพเคเค", - "feature1": "Roo Marketplace เคฒเฅ‰เคจเฅเคš - Marketplace เค…เคฌ เคฒเคพเค‡เคต เคนเฅˆ! เคชเคนเคฒเฅ‡ เคธเฅ‡ เค•เคนเฅ€เค‚ เค†เคธเคพเคจ เคคเคฐเฅ€เค•เฅ‡ เคธเฅ‡ modes เค”เคฐ MCP เค–เฅ‹เคœเฅ‡เค‚ เค”เคฐ เค‡เค‚เคธเฅเคŸเฅ‰เคฒ เค•เคฐเฅ‡เค‚เฅค", - "feature2": "Gemini 2.5 Models - เคจเค Gemini 2.5 Pro, Flash, เค”เคฐ Flash Lite models เค•เฅ‡ เคฒเคฟเค เคธเคฎเคฐเฅเคฅเคจ เคœเฅ‹เคกเคผเคพ เค—เคฏเคพเฅค", - "feature3": "Excel File เคธเคฎเคฐเฅเคฅเคจ เค”เคฐ เค…เคงเคฟเค• - Excel (.xlsx) file เคธเคฎเคฐเฅเคฅเคจ เคœเฅ‹เคกเคผเคพ เค—เคฏเคพ เค”เคฐ เค•เคˆ bug fixes เค”เคฐ เคธเฅเคงเคพเคฐ!", - "hideButton": "เค˜เฅ‹เคทเคฃเคพ เค›เคฟเคชเคพเคเค", - "detailsDiscussLinks": "Discord เค”เคฐ Reddit เคชเคฐ เค…เคงเคฟเค• เคœเคพเคจเค•เคพเคฐเฅ€ เคชเฅเคฐเคพเคชเฅเคค เค•เคฐเฅ‡เค‚ เค”เคฐ เคšเคฐเฅเคšเคพ เคฎเฅ‡เค‚ เคญเคพเค— เคฒเฅ‡เค‚ ๐Ÿš€" + "description": "Roo Code {{version}} เค†เคชเค•เฅ‡ เคตเคฟเค•เคพเคธ เคตเคฐเฅเค•เคซเคผเฅเคฒเฅ‹ เค•เฅ‹ เคฌเฅ‡เคนเคคเคฐ เคฌเคจเคพเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เคถเค•เฅเคคเคฟเคถเคพเคฒเฅ€ เคจเคˆ เคธเฅเคตเคฟเคงเคพเคเค‚ เค”เคฐ เคฎเคนเคคเฅเคตเคชเฅ‚เคฐเฅเคฃ เคธเฅเคงเคพเคฐ เคฒเฅ‡เค•เคฐ เค†เคฏเคพ เคนเฅˆเฅค", + "whatsNew": "เคจเคฏเคพ เค•เฅเคฏเคพ เคนเฅˆ", + "feature1": "1-เค•เฅเคฒเคฟเค• เคŸเคพเคธเฅเค• เคถเฅ‡เคฏเคฐเคฟเค‚เค—: เค…เคชเคจเฅ‡ เคŸเคพเคธเฅเค• เค•เฅ‹ เคธเคนเค•เคฐเฅเคฎเคฟเคฏเฅ‹เค‚ เค”เคฐ เคธเคฎเฅเคฆเคพเคฏ เค•เฅ‡ เคธเคพเคฅ เคเค• เค•เฅเคฒเคฟเค• เคฎเฅ‡เค‚ เคคเฅเคฐเค‚เคค เคธเคพเคเคพ เค•เคฐเฅ‡เค‚เฅค", + "feature2": "เค—เฅเคฒเฅ‹เคฌเคฒ .roo เคกเคพเคฏเคฐเฅ‡เค•เฅเคŸเคฐเฅ€ เคธเคฎเคฐเฅเคฅเคจ: เคชเฅเคฐเฅ‹เคœเฅ‡เค•เฅเคŸเฅเคธ เคฎเฅ‡เค‚ เคจเคฟเคฐเค‚เคคเคฐ เคธเฅ‡เคŸเคฟเค‚เค—เฅเคธ เค•เฅ‡ เคฒเคฟเค เค—เฅเคฒเฅ‹เคฌเคฒ .roo เคกเคพเคฏเคฐเฅ‡เค•เฅเคŸเคฐเฅ€ เคธเฅ‡ เคจเคฟเคฏเคฎ เค”เคฐ เค•เฅ‰เคจเฅเคซเคผเคฟเค—เคฐเฅ‡เคถเคจ เคฒเฅ‹เคก เค•เคฐเฅ‡เค‚เฅค", + "feature3": "เคฌเฅ‡เคนเคคเคฐ เค†เคฐเฅเค•เคฟเคŸเฅ‡เค•เฅเคŸ เคธเฅ‡ เค•เฅ‹เคก เคŸเฅเคฐเคพเค‚เคœเคผเคฟเคถเคจ: เค†เคฐเฅเค•เคฟเคŸเฅ‡เค•เฅเคŸ เคฎเฅ‹เคก เคฎเฅ‡เค‚ เคชเฅเคฒเคพเคจเคฟเค‚เค— เคธเฅ‡ เค•เฅ‹เคก เคฎเฅ‹เคก เคฎเฅ‡เค‚ เค‡เคฎเฅเคชเฅเคฒเฅ€เคฎเฅ‡เค‚เคŸเฅ‡เคถเคจ เคคเค• เคธเคนเคœ เคธเฅเคฅเคพเคจเคพเค‚เคคเคฐเคฃเฅค", + "hideButton": "เค˜เฅ‹เคทเคฃเคพ เค›เฅเคชเคพเคเค‚", + "detailsDiscussLinks": "Discord เค”เคฐ Reddit เคชเคฐ เค…เคงเคฟเค• เคตเคฟเคตเคฐเคฃ เคชเฅเคฐเคพเคชเฅเคค เค•เคฐเฅ‡เค‚ เค”เคฐ เคšเคฐเฅเคšเคพเค“เค‚ เคฎเฅ‡เค‚ เคถเคพเคฎเคฟเคฒ เคนเฅ‹เค‚ ๐Ÿš€" }, "browser": { "rooWantsToUse": "Roo เคฌเฅเคฐเคพเค‰เคœเคผเคฐ เค•เคพ เค‰เคชเคฏเฅ‹เค— เค•เคฐเคจเคพ เคšเคพเคนเคคเคพ เคนเฅˆ:", diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index be9d3919ff..fc0bd5056f 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -251,13 +251,13 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} Dirilis", - "description": "Roo Code {{version}} menghadirkan fitur baru yang powerful dan perbaikan berdasarkan feedback kamu.", - "whatsNew": "Apa yang Baru", - "feature1": "Peluncuran Roo Marketplace - Marketplace sekarang sudah live! Temukan dan install mode serta MCP lebih mudah dari sebelumnya.", - "feature2": "Model Gemini 2.5 - Menambahkan dukungan untuk model Gemini 2.5 Pro, Flash, dan Flash Lite yang baru.", - "feature3": "Dukungan File Excel & Lainnya - Menambahkan dukungan file Excel (.xlsx) dan banyak perbaikan bug serta peningkatan!", + "description": "Roo Code {{version}} menghadirkan fitur-fitur baru yang kuat dan peningkatan signifikan untuk meningkatkan alur kerja pengembangan Anda.", + "whatsNew": "Yang Baru", + "feature1": "Berbagi Tugas 1-Klik: Bagikan tugas Anda secara instan dengan rekan kerja dan komunitas hanya dengan satu klik.", + "feature2": "Dukungan Direktori Global .roo: Muat aturan dan konfigurasi dari direktori global .roo untuk pengaturan yang konsisten di seluruh proyek.", + "feature3": "Transisi Arsitektur ke Kode yang Ditingkatkan: Transfer yang mulus dari perencanaan di mode Arsitektur ke implementasi di mode Kode.", "hideButton": "Sembunyikan pengumuman", - "detailsDiscussLinks": "Dapatkan detail lebih lanjut dan diskusi di Discord dan Reddit ๐Ÿš€" + "detailsDiscussLinks": "Dapatkan detail lebih lanjut dan bergabung dalam diskusi di Discord dan Reddit ๐Ÿš€" }, "reasoning": { "thinking": "Berpikir", diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index 5fa468801d..f49a25dfa6 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Rilasciato Roo Code {{version}}", - "description": "Roo Code {{version}} introduce importanti nuove funzionalitร  e miglioramenti basati sui tuoi feedback.", + "description": "Roo Code {{version}} porta nuove potenti funzionalitร  e miglioramenti significativi per potenziare il tuo flusso di lavoro di sviluppo.", "whatsNew": "Novitร ", - "feature1": "Lancio del Marketplace Roo: Il marketplace รจ ora attivo! Scopri e installa modalitร  e MCP piรน facilmente che mai.", - "feature2": "Modelli Gemini 2.5: Aggiunto supporto per i nuovi modelli Gemini 2.5 Pro, Flash e Flash Lite.", - "feature3": "Supporto File Excel e altro: Aggiunto supporto per file Excel (.xlsx) e numerose correzioni di bug e miglioramenti!", + "feature1": "Condivisione Task con 1 Clic: Condividi istantaneamente i tuoi task con colleghi e la community con un solo clic.", + "feature2": "Supporto Directory Globale .roo: Carica regole e configurazioni da una directory globale .roo per impostazioni coerenti tra progetti.", + "feature3": "Transizioni Migliorate da Architetto a Codice: Trasferimenti fluidi dalla pianificazione in modalitร  Architetto all'implementazione in modalitร  Codice.", "hideButton": "Nascondi annuncio", "detailsDiscussLinks": "Ottieni maggiori dettagli e partecipa alle discussioni su Discord e Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index 776b611a89..cb5ebcdafd 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ใƒชใƒชใƒผใ‚น", - "description": "Roo Code {{version}}ใฏใ€ใ‚ใชใŸใฎใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏใซๅŸบใฅใ้‡่ฆใชๆ–ฐๆฉŸ่ƒฝใจๆ”นๅ–„ใ‚’ใ‚‚ใŸใ‚‰ใ—ใพใ™ใ€‚", + "description": "Roo Code {{version}}ใฏใ€้–‹็™บใƒฏใƒผใ‚ฏใƒ•ใƒญใƒผใ‚’ๅ‘ไธŠใ•ใ›ใ‚‹ๅผทๅŠ›ใชๆ–ฐๆฉŸ่ƒฝใจ้‡่ฆใชๆ”นๅ–„ใ‚’ใ‚‚ใŸใ‚‰ใ—ใพใ™ใ€‚", "whatsNew": "ๆ–ฐๆฉŸ่ƒฝ", - "feature1": "Roo ใƒžใƒผใ‚ฑใƒƒใƒˆใƒ—ใƒฌใ‚คใ‚น้–‹ๅง‹: ใƒžใƒผใ‚ฑใƒƒใƒˆใƒ—ใƒฌใ‚คใ‚นใŒ้–‹ๅง‹ใ•ใ‚Œใพใ—ใŸ๏ผใ“ใ‚ŒใพใงไปฅไธŠใซ็ฐกๅ˜ใซใƒขใƒผใƒ‰ใจMCPใ‚’็™บ่ฆ‹ใƒปใ‚คใƒณใ‚นใƒˆใƒผใƒซใ€‚", - "feature2": "Gemini 2.5 ใƒขใƒ‡ใƒซ: ๆ–ฐใ—ใ„Gemini 2.5 Proใ€Flashใ€Flash Liteใƒขใƒ‡ใƒซใฎใ‚ตใƒใƒผใƒˆใ‚’่ฟฝๅŠ ใ€‚", - "feature3": "Excelใƒ•ใ‚กใ‚คใƒซใ‚ตใƒใƒผใƒˆใชใฉ: Excel (.xlsx) ใƒ•ใ‚กใ‚คใƒซใ‚ตใƒใƒผใƒˆใจๅคšๆ•ฐใฎใƒใ‚ฐไฟฎๆญฃใƒปๆ”นๅ–„ใ‚’่ฟฝๅŠ ๏ผ", + "feature1": "1ใ‚ฏใƒชใƒƒใ‚ฏใ‚ฟใ‚นใ‚ฏๅ…ฑๆœ‰: ใƒฏใƒณใ‚ฏใƒชใƒƒใ‚ฏใงๅŒๅƒšใ‚„ใ‚ณใƒŸใƒฅใƒ‹ใƒ†ใ‚ฃใจใ‚ฟใ‚นใ‚ฏใ‚’็žฌๆ™‚ใซๅ…ฑๆœ‰ใงใใพใ™ใ€‚", + "feature2": "ใ‚ฐใƒญใƒผใƒใƒซ.rooใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚ตใƒใƒผใƒˆ: ใ‚ฐใƒญใƒผใƒใƒซ.rooใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‹ใ‚‰ใƒซใƒผใƒซใจ่จญๅฎšใ‚’่ชญใฟ่พผใฟใ€ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ้–“ใงไธ€่ฒซใ—ใŸ่จญๅฎšใ‚’ๅฎŸ็พใ€‚", + "feature3": "ๆ”นๅ–„ใ•ใ‚ŒใŸใ‚ขใƒผใ‚ญใƒ†ใ‚ฏใƒˆใ‹ใ‚‰ใ‚ณใƒผใƒ‰ใธใฎ็งป่กŒ: ใ‚ขใƒผใ‚ญใƒ†ใ‚ฏใƒˆใƒขใƒผใƒ‰ใงใฎ่จˆ็”ปใ‹ใ‚‰ใ‚ณใƒผใƒ‰ใƒขใƒผใƒ‰ใงใฎๅฎŸ่ฃ…ใธใฎใ‚ทใƒผใƒ ใƒฌใ‚นใชๅผ•ใ็ถ™ใŽใ€‚", "hideButton": "้€š็Ÿฅใ‚’้ž่กจ็คบ", "detailsDiscussLinks": "่ฉณ็ดฐใฏDiscordใจRedditใงใ”็ขบ่ชใƒปใƒ‡ใ‚ฃใ‚นใ‚ซใƒƒใ‚ทใƒงใƒณใใ ใ•ใ„ ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 65e4c0c480..1f86dc8cf4 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -240,13 +240,13 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ์ถœ์‹œ", - "description": "Roo Code {{version}}์€ ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ค‘์š”ํ•œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๊ณผ ๊ฐœ์„ ์‚ฌํ•ญ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.", + "description": "Roo Code {{version}}์€ ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๊ฐ•๋ ฅํ•œ ์ƒˆ ๊ธฐ๋Šฅ๊ณผ ์ค‘์š”ํ•œ ๊ฐœ์„ ์‚ฌํ•ญ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.", "whatsNew": "์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ", - "feature1": "Roo ๋งˆ์ผ“ํ”Œ๋ ˆ์ด์Šค ์ถœ์‹œ: ๋งˆ์ผ“ํ”Œ๋ ˆ์ด์Šค๊ฐ€ ์ด์ œ ๋ผ์ด๋ธŒ์ž…๋‹ˆ๋‹ค! ๊ทธ ์–ด๋А ๋•Œ๋ณด๋‹ค ์‰ฝ๊ฒŒ ๋ชจ๋“œ์™€ MCP๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  ์„ค์น˜ํ•˜์„ธ์š”.", - "feature2": "Gemini 2.5 ๋ชจ๋ธ: ์ƒˆ๋กœ์šด Gemini 2.5 Pro, Flash, Flash Lite ๋ชจ๋ธ ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.", - "feature3": "Excel ํŒŒ์ผ ์ง€์› ๋ฐ ๊ธฐํƒ€: Excel (.xlsx) ํŒŒ์ผ ์ง€์›๊ณผ ์ˆ˜๋งŽ์€ ๋ฒ„๊ทธ ์ˆ˜์ • ๋ฐ ๊ฐœ์„ ์‚ฌํ•ญ ์ถ”๊ฐ€!", + "feature1": "์›ํด๋ฆญ ์ž‘์—… ๊ณต์œ : ํ•œ ๋ฒˆ์˜ ํด๋ฆญ์œผ๋กœ ๋™๋ฃŒ ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ์™€ ์ž‘์—…์„ ์ฆ‰์‹œ ๊ณต์œ ํ•˜์„ธ์š”.", + "feature2": "๊ธ€๋กœ๋ฒŒ .roo ๋””๋ ‰ํ† ๋ฆฌ ์ง€์›: ๊ธ€๋กœ๋ฒŒ .roo ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๊ทœ์น™๊ณผ ๊ตฌ์„ฑ์„ ๋กœ๋“œํ•˜์—ฌ ํ”„๋กœ์ ํŠธ ๊ฐ„ ์ผ๊ด€๋œ ์„ค์ •์„ ์œ ์ง€ํ•˜์„ธ์š”.", + "feature3": "๊ฐœ์„ ๋œ ์•„ํ‚คํ…ํŠธ์—์„œ ์ฝ”๋“œ๋กœ์˜ ์ „ํ™˜: ์•„ํ‚คํ…ํŠธ ๋ชจ๋“œ์—์„œ์˜ ๊ณ„ํš๋ถ€ํ„ฐ ์ฝ”๋“œ ๋ชจ๋“œ์—์„œ์˜ ๊ตฌํ˜„๊นŒ์ง€ ์›ํ™œํ•œ ์ธ์ˆ˜์ธ๊ณ„.", "hideButton": "๊ณต์ง€ ์ˆจ๊ธฐ๊ธฐ", - "detailsDiscussLinks": "Discord์™€ Reddit์—์„œ ๋” ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜๊ณ  ๋…ผ์˜ํ•˜์„ธ์š” ๐Ÿš€" + "detailsDiscussLinks": "Discord์™€ Reddit์—์„œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ํ™•์ธํ•˜๊ณ  ํ† ๋ก ์— ์ฐธ์—ฌํ•˜์„ธ์š” ๐Ÿš€" }, "browser": { "rooWantsToUse": "Roo๊ฐ€ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ดํ•ฉ๋‹ˆ๋‹ค:", diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index fc3f87562d..d228d7b0c2 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -225,13 +225,13 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} uitgebracht", - "description": "Roo Code {{version}} brengt krachtige nieuwe functies en verbeteringen op basis van jouw feedback.", + "description": "Roo Code {{version}} brengt krachtige nieuwe functies en significante verbeteringen om je ontwikkelingsworkflow te verbeteren.", "whatsNew": "Wat is er nieuw", - "feature1": "Roo Marketplace Launch - De marketplace is nu live! Ontdek en installeer modi en MCP's makkelijker dan ooit tevoren.", - "feature2": "Gemini 2.5 Modellen - Ondersteuning toegevoegd voor nieuwe Gemini 2.5 Pro, Flash en Flash Lite modellen.", - "feature3": "Excel Bestandsondersteuning & Meer - Excel (.xlsx) bestandsondersteuning toegevoegd en talloze bugfixes en verbeteringen!", + "feature1": "1-Klik Taak Delen: Deel je taken direct met collega's en de community met slechts รฉรฉn klik.", + "feature2": "Globale .roo Directory Ondersteuning: Laad regels en configuraties vanuit een globale .roo directory voor consistente instellingen tussen projecten.", + "feature3": "Verbeterde Architect naar Code Overgangen: Soepele overdrachten van planning in Architect modus naar implementatie in Code modus.", "hideButton": "Aankondiging verbergen", - "detailsDiscussLinks": "Meer details en discussie in Discord en Reddit ๐Ÿš€" + "detailsDiscussLinks": "Krijg meer details en doe mee aan discussies op Discord en Reddit ๐Ÿš€" }, "reasoning": { "thinking": "Denkt na", diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index b930cf776c..fdb39b0851 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} wydany", - "description": "Roo Code {{version}} przynosi potฤ™ลผne nowe funkcje i ulepszenia na podstawie Twoich opinii.", + "description": "Roo Code {{version}} wprowadza potฤ™ลผne nowe funkcje i znaczฤ…ce ulepszenia, aby ulepszyฤ‡ Twรณj przepล‚yw pracy programistycznej.", "whatsNew": "Co nowego", - "feature1": "Uruchomienie Roo Marketplace - Marketplace jest juลผ dostฤ™pny! Odkrywaj i instaluj tryby oraz MCP ล‚atwiej niลผ kiedykolwiek wczeล›niej.", - "feature2": "Modele Gemini 2.5 - Dodano wsparcie dla nowych modeli Gemini 2.5 Pro, Flash i Flash Lite.", - "feature3": "Wsparcie dla plikรณw Excel i wiฤ™cej - Dodano wsparcie dla plikรณw Excel (.xlsx) oraz liczne poprawki bล‚ฤ™dรณw i ulepszenia!", + "feature1": "Udostฤ™pnianie zadaล„ jednym klikniฤ™ciem: Natychmiast udostฤ™pniaj swoje zadania wspรณล‚pracownikom i spoล‚ecznoล›ci jednym klikniฤ™ciem.", + "feature2": "Wsparcie globalnego katalogu .roo: ลaduj reguล‚y i konfiguracje z globalnego katalogu .roo dla spรณjnych ustawieล„ miฤ™dzy projektami.", + "feature3": "Ulepszone przejล›cia z Architekta do Kodu: Pล‚ynne transfery z planowania w trybie Architekta do implementacji w trybie Kodu.", "hideButton": "Ukryj ogล‚oszenie", "detailsDiscussLinks": "Uzyskaj wiฤ™cej szczegรณล‚รณw i doล‚ฤ…cz do dyskusji na Discord i Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index 1bf23c88e4..b37879f2f0 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} Lanรงado", - "description": "Roo Code {{version}} traz importantes novos recursos e melhorias baseados no seu feedback.", + "description": "Roo Code {{version}} traz novos recursos poderosos e melhorias significativas para aprimorar seu fluxo de trabalho de desenvolvimento.", "whatsNew": "O que hรก de novo", - "feature1": "Lanรงamento do Marketplace Roo: O marketplace estรก agora no ar! Descubra e instale modos e MCPs mais facilmente do que nunca.", - "feature2": "Modelos Gemini 2.5: Adicionado suporte para novos modelos Gemini 2.5 Pro, Flash e Flash Lite.", - "feature3": "Suporte a Arquivos Excel e Mais: Adicionado suporte a arquivos Excel (.xlsx) e numerosas correรงรตes de bugs e melhorias!", + "feature1": "Compartilhamento de Tarefas com 1 Clique: Compartilhe instantaneamente suas tarefas com colegas e a comunidade com apenas um clique.", + "feature2": "Suporte a Diretรณrio Global .roo: Carregue regras e configuraรงรตes de um diretรณrio global .roo para configuraรงรตes consistentes entre projetos.", + "feature3": "Transiรงรตes Aprimoradas de Arquiteto para Cรณdigo: Transferรชncias suaves do planejamento no modo Arquiteto para implementaรงรฃo no modo Cรณdigo.", "hideButton": "Ocultar anรบncio", "detailsDiscussLinks": "Obtenha mais detalhes e participe da discussรฃo no Discord e Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index c709b97fa2..5865e41a53 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -225,11 +225,11 @@ }, "announcement": { "title": "๐ŸŽ‰ ะ’ั‹ะฟัƒั‰ะตะฝ Roo Code {{version}}", - "description": "Roo Code {{version}} ะฟั€ะธะฝะพัะธั‚ ะฒะฐะถะฝั‹ะต ะฝะพะฒั‹ะต ั„ัƒะฝะบั†ะธะธ ะธ ัƒะปัƒั‡ัˆะตะฝะธั ะฝะฐ ะพัะฝะพะฒะต ะฒะฐัˆะธั… ะพั‚ะทั‹ะฒะพะฒ.", + "description": "Roo Code {{version}} ะฟั€ะธะฝะพัะธั‚ ะผะพั‰ะฝั‹ะต ะฝะพะฒั‹ะต ั„ัƒะฝะบั†ะธะธ ะธ ะทะฝะฐั‡ะธั‚ะตะปัŒะฝั‹ะต ัƒะปัƒั‡ัˆะตะฝะธั ะดะปั ัะพะฒะตั€ัˆะตะฝัั‚ะฒะพะฒะฐะฝะธั ะฒะฐัˆะตะณะพ ั€ะฐะฑะพั‡ะตะณะพ ะฟั€ะพั†ะตััะฐ ั€ะฐะทั€ะฐะฑะพั‚ะบะธ.", "whatsNew": "ะงั‚ะพ ะฝะพะฒะพะณะพ", - "feature1": "ะ—ะฐะฟัƒัะบ Roo Marketplace: ะœะฐั€ะบะตั‚ะฟะปะตะนั ั‚ะตะฟะตั€ัŒ ะฒ ัะตั‚ะธ! ะžั‚ะบั€ั‹ะฒะฐะนั‚ะต ะธ ัƒัั‚ะฐะฝะฐะฒะปะธะฒะฐะนั‚ะต ั€ะตะถะธะผั‹ ะธ MCP ะฟั€ะพั‰ะต, ั‡ะตะผ ะบะพะณะดะฐ-ะปะธะฑะพ.", - "feature2": "ะœะพะดะตะปะธ Gemini 2.5: ะ”ะพะฑะฐะฒะปะตะฝะฐ ะฟะพะดะดะตั€ะถะบะฐ ะฝะพะฒั‹ั… ะผะพะดะตะปะตะน Gemini 2.5 Pro, Flash ะธ Flash Lite.", - "feature3": "ะŸะพะดะดะตั€ะถะบะฐ ั„ะฐะนะปะพะฒ Excel ะธ ะผะฝะพะณะพะต ะดั€ัƒะณะพะต: ะ”ะพะฑะฐะฒะปะตะฝะฐ ะฟะพะดะดะตั€ะถะบะฐ ั„ะฐะนะปะพะฒ Excel (.xlsx) ะธ ะผะฝะพะถะตัั‚ะฒะพ ะธัะฟั€ะฐะฒะปะตะฝะธะน ะพัˆะธะฑะพะบ ะธ ัƒะปัƒั‡ัˆะตะฝะธะน!", + "feature1": "ะžะฑะผะตะฝ ะทะฐะดะฐั‡ะฐะผะธ ะฒ 1 ะบะปะธะบ: ะœะณะฝะพะฒะตะฝะฝะพ ะดะตะปะธั‚ะตััŒ ัะฒะพะธะผะธ ะทะฐะดะฐั‡ะฐะผะธ ั ะบะพะปะปะตะณะฐะผะธ ะธ ัะพะพะฑั‰ะตัั‚ะฒะพะผ ะพะดะฝะธะผ ะบะปะธะบะพะผ.", + "feature2": "ะŸะพะดะดะตั€ะถะบะฐ ะณะปะพะฑะฐะปัŒะฝะพะณะพ ะบะฐั‚ะฐะปะพะณะฐ .roo: ะ—ะฐะณั€ัƒะถะฐะนั‚ะต ะฟั€ะฐะฒะธะปะฐ ะธ ะบะพะฝั„ะธะณัƒั€ะฐั†ะธะธ ะธะท ะณะปะพะฑะฐะปัŒะฝะพะณะพ ะบะฐั‚ะฐะปะพะณะฐ .roo ะดะปั ัะพะณะปะฐัะพะฒะฐะฝะฝั‹ั… ะฝะฐัั‚ั€ะพะตะบ ะผะตะถะดัƒ ะฟั€ะพะตะบั‚ะฐะผะธ.", + "feature3": "ะฃะปัƒั‡ัˆะตะฝะฝั‹ะต ะฟะตั€ะตั…ะพะดั‹ ะพั‚ ะั€ั…ะธั‚ะตะบั‚ะพั€ะฐ ะบ ะšะพะดัƒ: ะŸะปะฐะฒะฝั‹ะต ะฟะตั€ะตั…ะพะดั‹ ะพั‚ ะฟะปะฐะฝะธั€ะพะฒะฐะฝะธั ะฒ ั€ะตะถะธะผะต ะั€ั…ะธั‚ะตะบั‚ะพั€ะฐ ะบ ั€ะตะฐะปะธะทะฐั†ะธะธ ะฒ ั€ะตะถะธะผะต ะšะพะดะฐ.", "hideButton": "ะกะบั€ั‹ั‚ัŒ ะพะฑัŠัะฒะปะตะฝะธะต", "detailsDiscussLinks": "ะŸะพะดั€ะพะฑะฝะตะต ะธ ะพะฑััƒะถะดะตะฝะธะต ะฒ Discord ะธ Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 1bc530f37a..6c5bd20353 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -240,13 +240,13 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} Yayฤฑnlandฤฑ", - "description": "Roo Code {{version}} geri bildirimlerinize dayalฤฑ gรผรงlรผ yeni รถzellikler ve iyileลŸtirmeler getiriyor.", + "description": "Roo Code {{version}}, geliลŸtirme iลŸ akฤฑลŸฤฑnฤฑzฤฑ geliลŸtirmek iรงin gรผรงlรผ yeni รถzellikler ve รถnemli iyileลŸtirmeler getiriyor.", "whatsNew": "Yenilikler", - "feature1": "Roo Marketplace Lansmanฤฑ - Marketplace artฤฑk canlฤฑ! Modlarฤฑ ve MCP'leri her zamankinden daha kolay keลŸfedin ve kurun.", - "feature2": "Gemini 2.5 Modelleri - Yeni Gemini 2.5 Pro, Flash ve Flash Lite modelleri iรงin destek eklendi.", - "feature3": "Excel Dosya DesteฤŸi ve Daha Fazlasฤฑ - Excel (.xlsx) dosya desteฤŸi eklendi ve sayฤฑsฤฑz hata dรผzeltmesi ve iyileลŸtirme!", + "feature1": "Tek Tฤฑkla Gรถrev PaylaลŸฤฑmฤฑ: Gรถrevlerinizi meslektaลŸlarฤฑnฤฑz ve toplulukla tek tฤฑkla anฤฑnda paylaลŸฤฑn.", + "feature2": "Global .roo Dizin DesteฤŸi: Projeler arasฤฑ tutarlฤฑ ayarlar iรงin global .roo dizininden kurallar ve yapฤฑlandฤฑrmalar yรผkleyin.", + "feature3": "GeliลŸtirilmiลŸ Mimar'dan Kod'a GeรงiลŸler: Mimar modunda planlamadan Kod modunda uygulamaya sorunsuz aktarฤฑmlar.", "hideButton": "Duyuruyu gizle", - "detailsDiscussLinks": "Discord ve Reddit รผzerinde daha fazla ayrฤฑntฤฑ edinin ve tartฤฑลŸmalara katฤฑlฤฑn ๐Ÿš€" + "detailsDiscussLinks": "Discord ve Reddit'te daha fazla ayrฤฑntฤฑ alฤฑn ve tartฤฑลŸmalara katฤฑlฤฑn ๐Ÿš€" }, "browser": { "rooWantsToUse": "Roo tarayฤฑcฤฑyฤฑ kullanmak istiyor:", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index 24521d8aa4..eb7cdc2306 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ฤรฃ phรกt hร nh", - "description": "Roo Code {{version}} mang ฤ‘แบฟn cรกc tรญnh nฤƒng mแบกnh mแบฝ vร  cแบฃi tiแบฟn mแป›i dแปฑa trรชn phแบฃn hแป“i cแปงa bแบกn.", + "description": "Roo Code {{version}} mang ฤ‘แบฟn cรกc tรญnh nฤƒng mแบกnh mแบฝ mแป›i vร  cแบฃi tiแบฟn ฤ‘รกng kแปƒ ฤ‘แปƒ nรขng cao quy trรฌnh phรกt triแปƒn cแปงa bแบกn.", "whatsNew": "Cรณ gรฌ mแป›i", - "feature1": "Ra mแบฏt Roo Marketplace - Marketplace hiแป‡n ฤ‘รฃ hoแบกt ฤ‘แป™ng! Khรกm phรก vร  cร i ฤ‘แบทt cรกc chแบฟ ฤ‘แป™ vร  MCP dแป… dร ng hฦกn bao giแป hแบฟt.", - "feature2": "Cรกc mรด hรฌnh Gemini 2.5 - ฤรฃ thรชm hแป— trแปฃ cho cรกc mรด hรฌnh Gemini 2.5 Pro, Flash vร  Flash Lite mแป›i.", - "feature3": "Hแป— trแปฃ tแป‡p Excel & Nhiแปu hฦกn nแปฏa - ฤรฃ thรชm hแป— trแปฃ tแป‡p Excel (.xlsx) vร  vรด sแป‘ sแปญa lแป—i cรนng cแบฃi tiแบฟn!", + "feature1": "Chia sแบป Nhiแป‡m vแปฅ 1-Click: Chia sแบป nhiแป‡m vแปฅ cแปงa bแบกn vแป›i ฤ‘แป“ng nghiแป‡p vร  cแป™ng ฤ‘แป“ng ngay lแบญp tแปฉc chแป‰ vแป›i mแป™t cรบ nhแบฅp chuแป™t.", + "feature2": "Hแป— trแปฃ Thฦฐ mแปฅc .roo Toร n cแปฅc: Tแบฃi quy tแบฏc vร  cแบฅu hรฌnh tแปซ thฦฐ mแปฅc .roo toร n cแปฅc ฤ‘แปƒ cรณ cร i ฤ‘แบทt nhแบฅt quรกn giแปฏa cรกc dแปฑ รกn.", + "feature3": "Cแบฃi thiแป‡n Chuyแปƒn ฤ‘แป•i tแปซ Architect sang Code: Chuyแปƒn ฤ‘แป•i mฦฐแปฃt mร  tแปซ lแบญp kแบฟ hoแบกch trong chแบฟ ฤ‘แป™ Architect sang triแปƒn khai trong chแบฟ ฤ‘แป™ Code.", "hideButton": "แบจn thรดng bรกo", "detailsDiscussLinks": "Nhแบญn thรชm chi tiแบฟt vร  thแบฃo luแบญn tแบกi Discord vร  Reddit ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index c4c4f1c5a2..93494e6f50 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ๅทฒๅ‘ๅธƒ", - "description": "Roo Code {{version}} ๅธฆๆฅๅŸบไบŽๆ‚จๅ้ฆˆ็š„้‡่ฆๆ–ฐๅŠŸ่ƒฝๅ’Œๆ”น่ฟ›ใ€‚", + "description": "Roo Code {{version}} ๅธฆๆฅๅผบๅคง็š„ๆ–ฐๅŠŸ่ƒฝๅ’Œ้‡ๅคงๆ”น่ฟ›๏ผŒๆๅ‡ๆ‚จ็š„ๅผ€ๅ‘ๅทฅไฝœๆต็จ‹ใ€‚", "whatsNew": "ๆ–ฐ็‰นๆ€ง", - "feature1": "Roo ๅธ‚ๅœบๆญฃๅผไธŠ็บฟ: ๅธ‚ๅœบ็ŽฐๅทฒไธŠ็บฟ๏ผๆฏ”ไปฅๅพ€ๆ›ด่ฝปๆพๅœฐๅ‘็Žฐๅ’Œๅฎ‰่ฃ…ๆจกๅผๅŠ MCPใ€‚", - "feature2": "Gemini 2.5 ๆจกๅž‹: ๆ–ฐๅขžๅฏนๆ–ฐ็‰ˆ Gemini 2.5 Proใ€Flash ๅ’Œ Flash Lite ๆจกๅž‹็š„ๆ”ฏๆŒใ€‚", - "feature3": "Excel ๆ–‡ไปถๆ”ฏๆŒๅŠๆ›ดๅคš: ๆ–ฐๅขž Excel (.xlsx) ๆ–‡ไปถๆ”ฏๆŒไปฅๅŠๅคง้‡้”™่ฏฏไฟฎๅคๅ’Œๆ”น่ฟ›๏ผ", + "feature1": "ไธ€้”ฎไปปๅŠกๅˆ†ไบซ: ไธ€้”ฎๅณๅฏไธŽๅŒไบ‹ๅ’Œ็คพๅŒบๅˆ†ไบซๆ‚จ็š„ไปปๅŠกใ€‚", + "feature2": "ๅ…จๅฑ€ .roo ็›ฎๅฝ•ๆ”ฏๆŒ: ไปŽๅ…จๅฑ€ .roo ็›ฎๅฝ•ๅŠ ่ฝฝ่ง„ๅˆ™ๅ’Œ้…็ฝฎ๏ผŒ็กฎไฟ้กน็›ฎ้—ด่ฎพ็ฝฎไธ€่‡ดใ€‚", + "feature3": "ๆ”น่ฟ›็š„ๆžถๆž„ๅธˆๅˆฐไปฃ็ ่ฝฌๆข: ไปŽๆžถๆž„ๅธˆๆจกๅผ็š„่ง„ๅˆ’ๅˆฐไปฃ็ ๆจกๅผ็š„ๅฎž็Žฐ๏ผŒๅฎž็Žฐๆ— ็ผไบคๆŽฅใ€‚", "hideButton": "้š่—ๅ…ฌๅ‘Š", "detailsDiscussLinks": "ๅœจ Discord ๅ’Œ Reddit ่Žทๅ–ๆ›ดๅคš่ฏฆๆƒ…ๅนถๅ‚ไธŽ่ฎจ่ฎบ ๐Ÿš€" }, diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index a4b60ddf79..e7a476cb37 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -240,11 +240,11 @@ }, "announcement": { "title": "๐ŸŽ‰ Roo Code {{version}} ๅทฒ็™ผๅธƒ", - "description": "Roo Code {{version}} ๅธถไพ†ๅŸบๆ–ผๆ‚จๆ„่ฆ‹ๅ›ž้ฅ‹็š„้‡่ฆๆ–ฐๅŠŸ่ƒฝ่ˆ‡ๆ”น้€ฒใ€‚", + "description": "Roo Code {{version}} ๅธถไพ†ๅผทๅคง็š„ๆ–ฐๅŠŸ่ƒฝๅ’Œ้‡ๅคงๆ”น้€ฒ๏ผŒๆๅ‡ๆ‚จ็š„้–‹็™ผๅทฅไฝœๆต็จ‹ใ€‚", "whatsNew": "ๆ–ฐๅŠŸ่ƒฝ", - "feature1": "Roo ๅธ‚ๅ ดๆญฃๅผไธŠ็ทš: ๅธ‚ๅ ด็พๅทฒไธŠ็ทš๏ผๆฏ”ไปฅๅพ€ๆ›ด่ผ•้ฌ†ๅœฐๆŽข็ดขไธฆๅฎ‰่ฃๆจกๅผๅ’Œ MCPใ€‚", - "feature2": "Gemini 2.5 ๆจกๅž‹: ๆ–ฐๅขžๅฐๆ–ฐ็‰ˆ Gemini 2.5 Proใ€Flash ๅ’Œ Flash Lite ๆจกๅž‹็š„ๆ”ฏๆดใ€‚", - "feature3": "Excel ๆช”ๆกˆๆ”ฏๆดๅŠๆ›ดๅคš: ๆ–ฐๅขž Excel (.xlsx) ๆช”ๆกˆๆ”ฏๆดไปฅๅŠๅคง้‡้Œฏ่ชคไฟฎๅพฉๅ’Œๆ”น้€ฒ๏ผ", + "feature1": "ไธ€้ตๅˆ†ไบซๅทฅไฝœ๏ผšๅช้œ€ไธ€้ตๅณๅฏ็ซ‹ๅณ่ˆ‡ๅŒไบ‹ๅ’Œ็คพ็พคๅˆ†ไบซๆ‚จ็š„ๅทฅไฝœใ€‚", + "feature2": "ๅ…จๅŸŸ .roo ็›ฎ้Œ„ๆ”ฏๆด๏ผšๅพžๅ…จๅŸŸ .roo ็›ฎ้Œ„่ผ‰ๅ…ฅ่ฆๅ‰‡ๅ’Œ่จญๅฎš๏ผŒ็ขบไฟๅฐˆๆกˆ้–“่จญๅฎšไธ€่‡ดใ€‚", + "feature3": "ๆ”น้€ฒ็š„ Architect ๅˆฐ Code ่ฝ‰ๆ›๏ผšๅพž Architect ๆจกๅผ็š„่ฆๅŠƒๅˆฐ Code ๆจกๅผ็š„ๅฏฆไฝœ๏ผŒ่ฝ‰ๆ›ๆ›ดๅŠ ้ †ๆšขใ€‚", "hideButton": "้šฑ่—ๅ…ฌๅ‘Š", "detailsDiscussLinks": "ๅœจ Discord ๅ’Œ Reddit ๅ–ๅพ—ๆ›ดๅคš่ฉณ็ดฐ่ณ‡่จŠไธฆๅƒ่ˆ‡่จŽ่ซ– ๐Ÿš€" }, From 7704463a7b4b382058e6f95cb63dbf700c3c58b7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Jul 2025 17:16:31 -0400 Subject: [PATCH 61/70] Update contributors list (#5213) Co-authored-by: mrubens <2600+mrubens@users.noreply.github.com> --- README.md | 71 +++++++++++++++++++-------------------- locales/ca/README.md | 73 ++++++++++++++++++++--------------------- locales/de/README.md | 73 ++++++++++++++++++++--------------------- locales/es/README.md | 73 ++++++++++++++++++++--------------------- locales/fr/README.md | 73 ++++++++++++++++++++--------------------- locales/hi/README.md | 63 ++++++++++++++++++----------------- locales/id/README.md | 63 ++++++++++++++++++----------------- locales/it/README.md | 63 ++++++++++++++++++----------------- locales/ja/README.md | 73 ++++++++++++++++++++--------------------- locales/ko/README.md | 73 ++++++++++++++++++++--------------------- locales/nl/README.md | 73 ++++++++++++++++++++--------------------- locales/pl/README.md | 73 ++++++++++++++++++++--------------------- locales/pt-BR/README.md | 73 ++++++++++++++++++++--------------------- locales/ru/README.md | 73 ++++++++++++++++++++--------------------- locales/tr/README.md | 73 ++++++++++++++++++++--------------------- locales/vi/README.md | 73 ++++++++++++++++++++--------------------- locales/zh-CN/README.md | 73 ++++++++++++++++++++--------------------- locales/zh-TW/README.md | 73 ++++++++++++++++++++--------------------- 18 files changed, 636 insertions(+), 646 deletions(-) diff --git a/README.md b/README.md index cb3d372a4a..4d6e5cd9db 100644 --- a/README.md +++ b/README.md @@ -208,41 +208,42 @@ Thanks to all our contributors who have helped make Roo Code better! -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | +| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| +| System233
System233
| jr
jr
| MuriloFP
MuriloFP
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| +| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| qdaxb
qdaxb
| +| feifei325
feifei325
| zhangtony239
zhangtony239
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| monotykamary
monotykamary
| sachasayan
sachasayan
| cannuri
cannuri
| +| vigneshsubbiah16
vigneshsubbiah16
| shariqriazz
shariqriazz
| pugazhendhi-m
pugazhendhi-m
| lloydchang
lloydchang
| dtrugman
dtrugman
| chrarnoldus
chrarnoldus
| +| Szpadel
Szpadel
| diarmidmackenzie
diarmidmackenzie
| olweraltuve
olweraltuve
| psv2522
psv2522
| Premshay
Premshay
| kiwina
kiwina
| +| lupuletic
lupuletic
| aheizi
aheizi
| SannidhyaSah
SannidhyaSah
| PeterDaveHello
PeterDaveHello
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| +| nbihan-mediware
nbihan-mediware
| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| dleffel
dleffel
| StevenTCramer
StevenTCramer
| pdecat
pdecat
| +| noritaka1166
noritaka1166
| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| +| slytechnical
slytechnical
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| +| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| +| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| liwilliam2021
liwilliam2021
| avtc
avtc
| dlab-anton
dlab-anton
| +| eonghk
eonghk
| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| +| zeozeozeo
zeozeozeo
| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| +| bramburn
bramburn
| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| devxpain
devxpain
| snoyiatk
snoyiatk
| +| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| +| mdp
mdp
| napter
napter
| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| +| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| +| kinandan
kinandan
| nevermorec
nevermorec
| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| +| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| +| maekawataiki
maekawataiki
| AlexandruSmirnov
AlexandruSmirnov
| PretzelVector
PretzelVector
| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| +| takakoutso
takakoutso
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| shaybc
shaybc
| seedlord
seedlord
| +| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| pokutuna
pokutuna
| philipnext
philipnext
| +| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| +| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| celestial-vault
celestial-vault
| linegel
linegel
| +| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| dleen
dleen
| +| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| benashby
benashby
| Atlogit
Atlogit
| +| atlasgong
atlasgong
| andrewshu2000
andrewshu2000
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| HadesArchitect
HadesArchitect
| +| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| AMHesch
AMHesch
| +| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| R-omk
R-omk
| Sarke
Sarke
| +| PaperBoardOfficial
PaperBoardOfficial
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| marvijo-code
marvijo-code
| +| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| Rexarrior
Rexarrior
| +| KevinZhao
KevinZhao
| ksze
ksze
| Fovty
Fovty
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| +| pfitz
pfitz
| ExactDoug
ExactDoug
| | | | | diff --git a/locales/ca/README.md b/locales/ca/README.md index cf3c37f719..511175d766 100644 --- a/locales/ca/README.md +++ b/locales/ca/README.md @@ -181,43 +181,42 @@ Ens encanten les contribucions de la comunitat! Comenceu llegint el nostre [CONT Grร cies a tots els nostres colยทlaboradors que han ajudat a millorar Roo Code! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Llicรจncia diff --git a/locales/de/README.md b/locales/de/README.md index ec220fe9ca..2dbaaa4363 100644 --- a/locales/de/README.md +++ b/locales/de/README.md @@ -181,43 +181,42 @@ Wir lieben Community-Beitrรคge! Beginnen Sie mit dem Lesen unserer [CONTRIBUTING Danke an alle unsere Mitwirkenden, die geholfen haben, Roo Code zu verbessern! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Lizenz diff --git a/locales/es/README.md b/locales/es/README.md index c5939b353e..45942a0ee5 100644 --- a/locales/es/README.md +++ b/locales/es/README.md @@ -181,43 +181,42 @@ Usamos [changesets](https://github.com/changesets/changesets) para versionar y p ยกGracias a todos nuestros colaboradores que han ayudado a mejorar Roo Code! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Licencia diff --git a/locales/fr/README.md b/locales/fr/README.md index f65cf68408..cb7c02166b 100644 --- a/locales/fr/README.md +++ b/locales/fr/README.md @@ -181,43 +181,42 @@ Nous adorons les contributions de la communautรฉ ! Commencez par lire notre [CON Merci ร  tous nos contributeurs qui ont aidรฉ ร  amรฉliorer Roo Code ! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Licence diff --git a/locales/hi/README.md b/locales/hi/README.md index d05baccf48..38cfae33a4 100644 --- a/locales/hi/README.md +++ b/locales/hi/README.md @@ -184,38 +184,39 @@ Roo Code เค•เฅ‹ เคฌเฅ‡เคนเคคเคฐ เคฌเคจเคพเคจเฅ‡ เคฎเฅ‡เค‚ เคฎเคฆเคฆ เค•เคฐเคจเฅ‡ |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| |Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## เคฒเคพเค‡เคธเฅ‡เค‚เคธ diff --git a/locales/id/README.md b/locales/id/README.md index 0903a209a5..2dfd3000fd 100644 --- a/locales/id/README.md +++ b/locales/id/README.md @@ -178,38 +178,39 @@ Terima kasih kepada semua kontributor kami yang telah membantu membuat Roo Code |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| |Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## License diff --git a/locales/it/README.md b/locales/it/README.md index 5de5eb9937..34f6d3d029 100644 --- a/locales/it/README.md +++ b/locales/it/README.md @@ -184,38 +184,39 @@ Grazie a tutti i nostri contributori che hanno aiutato a migliorare Roo Code! |mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| |:---:|:---:|:---:|:---:|:---:|:---:| |KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| -|System233
System233
|jr
jr
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
|MuriloFP
MuriloFP
| -|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|feifei325
feifei325
| -|qdaxb
qdaxb
|zhangtony239
zhangtony239
|cannuri
cannuri
|monotykamary
monotykamary
|sachasayan
sachasayan
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -|dtrugman
dtrugman
|lloydchang
lloydchang
|pugazhendhi-m
pugazhendhi-m
|shariqriazz
shariqriazz
|vigneshsubbiah16
vigneshsubbiah16
|chrarnoldus
chrarnoldus
| -|Szpadel
Szpadel
|lupuletic
lupuletic
|kiwina
kiwina
|Premshay
Premshay
|psv2522
psv2522
|olweraltuve
olweraltuve
| -|diarmidmackenzie
diarmidmackenzie
|PeterDaveHello
PeterDaveHello
|aheizi
aheizi
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
|nbihan-mediware
nbihan-mediware
| -|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|StevenTCramer
StevenTCramer
|SannidhyaSah
SannidhyaSah
|pdecat
pdecat
|noritaka1166
noritaka1166
| -|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
|slytechnical
slytechnical
| -|dleffel
dleffel
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| |Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| -|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|avtc
avtc
|dlab-anton
dlab-anton
|eonghk
eonghk
| -|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
|zeozeozeo
zeozeozeo
| -|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
|bramburn
bramburn
| -|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|snoyiatk
snoyiatk
|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
| -|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
|mdp
mdp
|napter
napter
| -|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
| -|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
|kinandan
kinandan
|nevermorec
nevermorec
| -|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
| -|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
|maekawataiki
maekawataiki
|PretzelVector
PretzelVector
| -|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
| -|shaybc
shaybc
|seedlord
seedlord
|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
| -|pokutuna
pokutuna
|philipnext
philipnext
|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
| -|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
| -|linegel
linegel
|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
| -|dleen
dleen
|devxpain
devxpain
|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
| -|benashby
benashby
|Atlogit
Atlogit
|atlasgong
atlasgong
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
| -|HadesArchitect
HadesArchitect
|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
| -|AMHesch
AMHesch
|AlexandruSmirnov
AlexandruSmirnov
|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
| -|R-omk
R-omk
|Sarke
Sarke
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
| -|marvijo-code
marvijo-code
|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
| -|Rexarrior
Rexarrior
|ksze
ksze
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
|pfitz
pfitz
| -|ExactDoug
ExactDoug
|celestial-vault
celestial-vault
| | | | | +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Licenza diff --git a/locales/ja/README.md b/locales/ja/README.md index 11e2edae4e..07b12f1792 100644 --- a/locales/ja/README.md +++ b/locales/ja/README.md @@ -181,43 +181,42 @@ code --install-extension bin/roo-cline-.vsix Roo Codeใฎๆ”นๅ–„ใซ่ฒข็Œฎใ—ใฆใใ‚ŒใŸใ™ในใฆใฎ่ฒข็Œฎ่€…ใซๆ„Ÿ่ฌใ—ใพใ™๏ผ - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## ใƒฉใ‚คใ‚ปใƒณใ‚น diff --git a/locales/ko/README.md b/locales/ko/README.md index ace26896f2..8d9e0381c1 100644 --- a/locales/ko/README.md +++ b/locales/ko/README.md @@ -181,43 +181,42 @@ code --install-extension bin/roo-cline-.vsix Roo Code๋ฅผ ๋” ์ข‹๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ ๋„์›€์„ ์ค€ ๋ชจ๋“  ๊ธฐ์—ฌ์ž์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## ๋ผ์ด์„ ์Šค diff --git a/locales/nl/README.md b/locales/nl/README.md index 68a0dbd5f2..b083ddf1b1 100644 --- a/locales/nl/README.md +++ b/locales/nl/README.md @@ -181,43 +181,42 @@ We houden van bijdragen uit de community! Begin met het lezen van onze [CONTRIBU Dank aan alle bijdragers die Roo Code beter hebben gemaakt! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Licentie diff --git a/locales/pl/README.md b/locales/pl/README.md index 62e2eccda5..86be4bc846 100644 --- a/locales/pl/README.md +++ b/locales/pl/README.md @@ -181,43 +181,42 @@ Kochamy wkล‚ad spoล‚ecznoล›ci! Zacznij od przeczytania naszego [CONTRIBUTING.md] Dziฤ™kujemy wszystkim naszym wspรณล‚twรณrcom, ktรณrzy pomogli ulepszyฤ‡ Roo Code! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Licencja diff --git a/locales/pt-BR/README.md b/locales/pt-BR/README.md index 88d5f3e7be..ffcdd994d3 100644 --- a/locales/pt-BR/README.md +++ b/locales/pt-BR/README.md @@ -181,43 +181,42 @@ Adoramos contribuiรงรตes da comunidade! Comece lendo nosso [CONTRIBUTING.md](CON Obrigado a todos os nossos contribuidores que ajudaram a tornar o Roo Code melhor! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Licenรงa diff --git a/locales/ru/README.md b/locales/ru/README.md index 5d1bb222ce..35250c85ec 100644 --- a/locales/ru/README.md +++ b/locales/ru/README.md @@ -181,43 +181,42 @@ code --install-extension bin/roo-cline-.vsix ะกะฟะฐัะธะฑะพ ะฒัะตะผ ะฝะฐัˆะธะผ ัƒั‡ะฐัั‚ะฝะธะบะฐะผ, ะบะพั‚ะพั€ั‹ะต ะฟะพะผะพะณะปะธ ัะดะตะปะฐั‚ัŒ Roo Code ะปัƒั‡ัˆะต! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## ะ›ะธั†ะตะฝะทะธั diff --git a/locales/tr/README.md b/locales/tr/README.md index 326b46cc62..ae52f4aeec 100644 --- a/locales/tr/README.md +++ b/locales/tr/README.md @@ -181,43 +181,42 @@ Topluluk katkฤฑlarฤฑnฤฑ seviyoruz! [CONTRIBUTING.md](CONTRIBUTING.md) dosyasฤฑn Roo Code'u daha iyi hale getirmeye yardฤฑmcฤฑ olan tรผm katkฤฑda bulunanlara teลŸekkรผr ederiz! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Lisans diff --git a/locales/vi/README.md b/locales/vi/README.md index 3d4a02d0ca..9bc0a1a0a3 100644 --- a/locales/vi/README.md +++ b/locales/vi/README.md @@ -181,43 +181,42 @@ Chรบng tรดi rแบฅt hoan nghรชnh ฤ‘รณng gรณp tแปซ cแป™ng ฤ‘แป“ng! Bแบฏt ฤ‘แบงu b Cแบฃm ฦกn tแบฅt cแบฃ nhแปฏng ngฦฐแปi ฤ‘รณng gรณp ฤ‘รฃ giรบp cแบฃi thiแป‡n Roo Code! - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## Giแบฅy Phรฉp diff --git a/locales/zh-CN/README.md b/locales/zh-CN/README.md index 5efcd537c2..c8e06ba65b 100644 --- a/locales/zh-CN/README.md +++ b/locales/zh-CN/README.md @@ -181,43 +181,42 @@ code --install-extension bin/roo-cline-.vsix ๆ„Ÿ่ฐขๆ‰€ๆœ‰ๅธฎๅŠฉๆ”น่ฟ› Roo Code ็š„่ดก็Œฎ่€…๏ผ - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## ่ฎธๅฏ่ฏ diff --git a/locales/zh-TW/README.md b/locales/zh-TW/README.md index 1f22263006..770d0303a5 100644 --- a/locales/zh-TW/README.md +++ b/locales/zh-TW/README.md @@ -182,43 +182,42 @@ code --install-extension bin/roo-cline-.vsix ๆ„Ÿ่ฌๆ‰€ๆœ‰ๅนซๅŠฉๆ”น้€ฒ Roo Code ็š„่ฒข็ป่€…๏ผ - -| mrubens
mrubens
| saoudrizwan
saoudrizwan
| cte
cte
| samhvw8
samhvw8
| daniel-lxs
daniel-lxs
| hannesrudolph
hannesrudolph
| -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| KJ7LNW
KJ7LNW
| a8trejo
a8trejo
| ColemanRoo
ColemanRoo
| canrobins13
canrobins13
| stea9499
stea9499
| joemanley201
joemanley201
| -| System233
System233
| jr
jr
| nissa-seru
nissa-seru
| jquanton
jquanton
| NyxJae
NyxJae
| MuriloFP
MuriloFP
| -| elianiva
elianiva
| d-oit
d-oit
| punkpeye
punkpeye
| wkordalski
wkordalski
| xyOz-dev
xyOz-dev
| feifei325
feifei325
| -| qdaxb
qdaxb
| zhangtony239
zhangtony239
| cannuri
cannuri
| monotykamary
monotykamary
| sachasayan
sachasayan
| Smartsheet-JB-Brown
Smartsheet-JB-Brown
| -| dtrugman
dtrugman
| lloydchang
lloydchang
| pugazhendhi-m
pugazhendhi-m
| shariqriazz
shariqriazz
| vigneshsubbiah16
vigneshsubbiah16
| chrarnoldus
chrarnoldus
| -| Szpadel
Szpadel
| lupuletic
lupuletic
| kiwina
kiwina
| Premshay
Premshay
| psv2522
psv2522
| olweraltuve
olweraltuve
| -| diarmidmackenzie
diarmidmackenzie
| PeterDaveHello
PeterDaveHello
| aheizi
aheizi
| hassoncs
hassoncs
| ChuKhaLi
ChuKhaLi
| nbihan-mediware
nbihan-mediware
| -| RaySinner
RaySinner
| afshawnlotfi
afshawnlotfi
| StevenTCramer
StevenTCramer
| SannidhyaSah
SannidhyaSah
| pdecat
pdecat
| noritaka1166
noritaka1166
| -| kyle-apex
kyle-apex
| emshvac
emshvac
| Lunchb0ne
Lunchb0ne
| SmartManoj
SmartManoj
| vagadiya
vagadiya
| slytechnical
slytechnical
| -| dleffel
dleffel
| arthurauffray
arthurauffray
| upamune
upamune
| NamesMT
NamesMT
| taylorwilsdon
taylorwilsdon
| sammcj
sammcj
| -| Ruakij
Ruakij
| p12tic
p12tic
| gtaylor
gtaylor
| aitoroses
aitoroses
| axkirillov
axkirillov
| ross
ross
| -| mr-ryan-james
mr-ryan-james
| heyseth
heyseth
| taisukeoe
taisukeoe
| avtc
avtc
| dlab-anton
dlab-anton
| eonghk
eonghk
| -| kcwhite
kcwhite
| ronyblum
ronyblum
| teddyOOXX
teddyOOXX
| vincentsong
vincentsong
| yongjer
yongjer
| zeozeozeo
zeozeozeo
| -| ashktn
ashktn
| franekp
franekp
| yt3trees
yt3trees
| benzntech
benzntech
| anton-otee
anton-otee
| bramburn
bramburn
| -| olearycrew
olearycrew
| brunobergher
brunobergher
| catrielmuller
catrielmuller
| snoyiatk
snoyiatk
| GitlyHallows
GitlyHallows
| jcbdev
jcbdev
| -| Chenjiayuan195
Chenjiayuan195
| julionav
julionav
| KanTakahiro
KanTakahiro
| SplittyDev
SplittyDev
| mdp
mdp
| napter
napter
| -| philfung
philfung
| dairui1
dairui1
| dqroid
dqroid
| forestyoo
forestyoo
| GOODBOY008
GOODBOY008
| hatsu38
hatsu38
| -| hongzio
hongzio
| im47cn
im47cn
| shoopapa
shoopapa
| jwcraig
jwcraig
| kinandan
kinandan
| nevermorec
nevermorec
| -| bannzai
bannzai
| axmo
axmo
| asychin
asychin
| amittell
amittell
| Yoshino-Yukitaro
Yoshino-Yukitaro
| Yikai-Liao
Yikai-Liao
| -| zxdvd
zxdvd
| vladstudio
vladstudio
| tmsjngx0
tmsjngx0
| tgfjt
tgfjt
| maekawataiki
maekawataiki
| PretzelVector
PretzelVector
| -| zetaloop
zetaloop
| cdlliuy
cdlliuy
| user202729
user202729
| student20880
student20880
| shohei-ihaya
shohei-ihaya
| shivamd1810
shivamd1810
| -| shaybc
shaybc
| seedlord
seedlord
| samir-nimbly
samir-nimbly
| robertheadley
robertheadley
| refactorthis
refactorthis
| qingyuan1109
qingyuan1109
| -| pokutuna
pokutuna
| philipnext
philipnext
| village-way
village-way
| oprstchn
oprstchn
| nobu007
nobu007
| mosleyit
mosleyit
| -| moqimoqidea
moqimoqidea
| mlopezr
mlopezr
| mecab
mecab
| olup
olup
| lightrabbit
lightrabbit
| kohii
kohii
| -| linegel
linegel
| edwin-truthsearch-io
edwin-truthsearch-io
| EamonNerbonne
EamonNerbonne
| dbasclpy
dbasclpy
| dflatline
dflatline
| Deon588
Deon588
| -| dleen
dleen
| devxpain
devxpain
| CW-B-W
CW-B-W
| chadgauth
chadgauth
| thecolorblue
thecolorblue
| bogdan0083
bogdan0083
| -| benashby
benashby
| Atlogit
Atlogit
| atlasgong
atlasgong
| andreastempsch
andreastempsch
| alasano
alasano
| QuinsZouls
QuinsZouls
| -| HadesArchitect
HadesArchitect
| alarno
alarno
| nexon33
nexon33
| adilhafeez
adilhafeez
| adamwlarson
adamwlarson
| adamhill
adamhill
| -| AMHesch
AMHesch
| AlexandruSmirnov
AlexandruSmirnov
| samsilveira
samsilveira
| 01Rian
01Rian
| RSO
RSO
| SECKainersdorfer
SECKainersdorfer
| -| R-omk
R-omk
| Sarke
Sarke
| OlegOAndreev
OlegOAndreev
| kvokka
kvokka
| ecmasx
ecmasx
| mollux
mollux
| -| marvijo-code
marvijo-code
| markijbema
markijbema
| mamertofabian
mamertofabian
| monkeyDluffy6017
monkeyDluffy6017
| libertyteeth
libertyteeth
| shtse8
shtse8
| -| Rexarrior
Rexarrior
| ksze
ksze
| Jdo300
Jdo300
| hesara
hesara
| DeXtroTip
DeXtroTip
| pfitz
pfitz
| -| ExactDoug
ExactDoug
| celestial-vault
celestial-vault
| | | | | - +|mrubens
mrubens
|saoudrizwan
saoudrizwan
|cte
cte
|samhvw8
samhvw8
|daniel-lxs
daniel-lxs
|hannesrudolph
hannesrudolph
| +|:---:|:---:|:---:|:---:|:---:|:---:| +|KJ7LNW
KJ7LNW
|a8trejo
a8trejo
|ColemanRoo
ColemanRoo
|canrobins13
canrobins13
|stea9499
stea9499
|joemanley201
joemanley201
| +|System233
System233
|jr
jr
|MuriloFP
MuriloFP
|nissa-seru
nissa-seru
|jquanton
jquanton
|NyxJae
NyxJae
| +|elianiva
elianiva
|d-oit
d-oit
|punkpeye
punkpeye
|wkordalski
wkordalski
|xyOz-dev
xyOz-dev
|qdaxb
qdaxb
| +|feifei325
feifei325
|zhangtony239
zhangtony239
|Smartsheet-JB-Brown
Smartsheet-JB-Brown
|monotykamary
monotykamary
|sachasayan
sachasayan
|cannuri
cannuri
| +|vigneshsubbiah16
vigneshsubbiah16
|shariqriazz
shariqriazz
|pugazhendhi-m
pugazhendhi-m
|lloydchang
lloydchang
|dtrugman
dtrugman
|chrarnoldus
chrarnoldus
| +|Szpadel
Szpadel
|diarmidmackenzie
diarmidmackenzie
|olweraltuve
olweraltuve
|psv2522
psv2522
|Premshay
Premshay
|kiwina
kiwina
| +|lupuletic
lupuletic
|aheizi
aheizi
|SannidhyaSah
SannidhyaSah
|PeterDaveHello
PeterDaveHello
|hassoncs
hassoncs
|ChuKhaLi
ChuKhaLi
| +|nbihan-mediware
nbihan-mediware
|RaySinner
RaySinner
|afshawnlotfi
afshawnlotfi
|dleffel
dleffel
|StevenTCramer
StevenTCramer
|pdecat
pdecat
| +|noritaka1166
noritaka1166
|kyle-apex
kyle-apex
|emshvac
emshvac
|Lunchb0ne
Lunchb0ne
|SmartManoj
SmartManoj
|vagadiya
vagadiya
| +|slytechnical
slytechnical
|arthurauffray
arthurauffray
|upamune
upamune
|NamesMT
NamesMT
|taylorwilsdon
taylorwilsdon
|sammcj
sammcj
| +|Ruakij
Ruakij
|p12tic
p12tic
|gtaylor
gtaylor
|aitoroses
aitoroses
|axkirillov
axkirillov
|ross
ross
| +|mr-ryan-james
mr-ryan-james
|heyseth
heyseth
|taisukeoe
taisukeoe
|liwilliam2021
liwilliam2021
|avtc
avtc
|dlab-anton
dlab-anton
| +|eonghk
eonghk
|kcwhite
kcwhite
|ronyblum
ronyblum
|teddyOOXX
teddyOOXX
|vincentsong
vincentsong
|yongjer
yongjer
| +|zeozeozeo
zeozeozeo
|ashktn
ashktn
|franekp
franekp
|yt3trees
yt3trees
|benzntech
benzntech
|anton-otee
anton-otee
| +|bramburn
bramburn
|olearycrew
olearycrew
|brunobergher
brunobergher
|catrielmuller
catrielmuller
|devxpain
devxpain
|snoyiatk
snoyiatk
| +|GitlyHallows
GitlyHallows
|jcbdev
jcbdev
|Chenjiayuan195
Chenjiayuan195
|julionav
julionav
|KanTakahiro
KanTakahiro
|SplittyDev
SplittyDev
| +|mdp
mdp
|napter
napter
|philfung
philfung
|dairui1
dairui1
|dqroid
dqroid
|forestyoo
forestyoo
| +|GOODBOY008
GOODBOY008
|hatsu38
hatsu38
|hongzio
hongzio
|im47cn
im47cn
|shoopapa
shoopapa
|jwcraig
jwcraig
| +|kinandan
kinandan
|nevermorec
nevermorec
|bannzai
bannzai
|axmo
axmo
|asychin
asychin
|amittell
amittell
| +|Yoshino-Yukitaro
Yoshino-Yukitaro
|Yikai-Liao
Yikai-Liao
|zxdvd
zxdvd
|vladstudio
vladstudio
|tmsjngx0
tmsjngx0
|tgfjt
tgfjt
| +|maekawataiki
maekawataiki
|AlexandruSmirnov
AlexandruSmirnov
|PretzelVector
PretzelVector
|zetaloop
zetaloop
|cdlliuy
cdlliuy
|user202729
user202729
| +|takakoutso
takakoutso
|student20880
student20880
|shohei-ihaya
shohei-ihaya
|shivamd1810
shivamd1810
|shaybc
shaybc
|seedlord
seedlord
| +|samir-nimbly
samir-nimbly
|robertheadley
robertheadley
|refactorthis
refactorthis
|qingyuan1109
qingyuan1109
|pokutuna
pokutuna
|philipnext
philipnext
| +|village-way
village-way
|oprstchn
oprstchn
|nobu007
nobu007
|mosleyit
mosleyit
|moqimoqidea
moqimoqidea
|mlopezr
mlopezr
| +|mecab
mecab
|olup
olup
|lightrabbit
lightrabbit
|kohii
kohii
|celestial-vault
celestial-vault
|linegel
linegel
| +|edwin-truthsearch-io
edwin-truthsearch-io
|EamonNerbonne
EamonNerbonne
|dbasclpy
dbasclpy
|dflatline
dflatline
|Deon588
Deon588
|dleen
dleen
| +|CW-B-W
CW-B-W
|chadgauth
chadgauth
|thecolorblue
thecolorblue
|bogdan0083
bogdan0083
|benashby
benashby
|Atlogit
Atlogit
| +|atlasgong
atlasgong
|andrewshu2000
andrewshu2000
|andreastempsch
andreastempsch
|alasano
alasano
|QuinsZouls
QuinsZouls
|HadesArchitect
HadesArchitect
| +|alarno
alarno
|nexon33
nexon33
|adilhafeez
adilhafeez
|adamwlarson
adamwlarson
|adamhill
adamhill
|AMHesch
AMHesch
| +|samsilveira
samsilveira
|01Rian
01Rian
|RSO
RSO
|SECKainersdorfer
SECKainersdorfer
|R-omk
R-omk
|Sarke
Sarke
| +|PaperBoardOfficial
PaperBoardOfficial
|OlegOAndreev
OlegOAndreev
|kvokka
kvokka
|ecmasx
ecmasx
|mollux
mollux
|marvijo-code
marvijo-code
| +|markijbema
markijbema
|mamertofabian
mamertofabian
|monkeyDluffy6017
monkeyDluffy6017
|libertyteeth
libertyteeth
|shtse8
shtse8
|Rexarrior
Rexarrior
| +|KevinZhao
KevinZhao
|ksze
ksze
|Fovty
Fovty
|Jdo300
Jdo300
|hesara
hesara
|DeXtroTip
DeXtroTip
| +|pfitz
pfitz
|ExactDoug
ExactDoug
| | | | | ## ๆŽˆๆฌŠ From 6355cb010c464571ad9d96f70b5343e5a3f13620 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Jul 2025 17:20:21 -0400 Subject: [PATCH 62/70] Changeset version bump (#5358) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Matt Rubens --- .changeset/v3.22.6.md | 27 --------------------------- CHANGELOG.md | 25 +++++++++++++++++++++++++ src/package.json | 2 +- 3 files changed, 26 insertions(+), 28 deletions(-) delete mode 100644 .changeset/v3.22.6.md diff --git a/.changeset/v3.22.6.md b/.changeset/v3.22.6.md deleted file mode 100644 index 184144fa2c..0000000000 --- a/.changeset/v3.22.6.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -"roo-cline": patch ---- - -- Add automatic configuration import on extension startup (thanks @takakoutso!) -- Add user-configurable search score threshold slider for semantic search (thanks @hannesrudolph!) -- Add import/export modes functionality (thanks @hannesrudolph!) -- Add persistent version indicator on chat screen (thanks @hannesrudolph!) -- Add default headers and testing for litellm fetcher (thanks @andrewshu2000!) -- Add translation orchestration for PR Fixer and Issue Fixer modes (thanks @hannesrudolph!) -- Add auto approve follow up questions (thanks @liwilliam2021!) -- Fix consistent cancellation error messages for thinking vs streaming phases (thanks @roomote!) -- Fix AWS Bedrock cross-region inference profile mapping (thanks @KevinZhao!) -- Fix URL loading timeout issues in @ mentions (thanks @MuriloFP!) -- Fix API retry exponential backoff capped at 10 minutes (thanks @MuriloFP!) -- Fix Qdrant URL field auto-filling with default value (thanks @SannidhyaSah!) -- Fix profile context condensation threshold (thanks @PaperBoardOfficial!) -- Fix apply_diff tool documentation for multi-file capabilities -- Fix cache files excluded from rules compilation (thanks @MuriloFP!) -- Add streamlined extension installation and documentation (thanks @devxpain!) -- Fix Architect mode from providing time estimates -- Remove context size from environment details -- Change default mode to architect for new installations -- Suppress Mermaid error rendering -- Improve Mermaid buttons with light background in light mode (thanks @chrarnoldus!) -- Add .vscode/ to write-protected files/directories -- Update AWS Bedrock cross-region inference profile mapping (thanks @KevinZhao!) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5fe9aef4c..9a629487e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Roo Code Changelog +## [3.22.6] - 2025-07-02 + +- Add timer-based auto approve for follow up questions (thanks @liwilliam2021!) +- Add import/export modes functionality +- Add persistent version indicator on chat screen +- Add automatic configuration import on extension startup (thanks @takakoutso!) +- Add user-configurable search score threshold slider for semantic search (thanks @hannesrudolph!) +- Add default headers and testing for litellm fetcher (thanks @andrewshu2000!) +- Fix consistent cancellation error messages for thinking vs streaming phases +- Fix AWS Bedrock cross-region inference profile mapping (thanks @KevinZhao!) +- Fix URL loading timeout issues in @ mentions (thanks @MuriloFP!) +- Fix API retry exponential backoff capped at 10 minutes (thanks @MuriloFP!) +- Fix Qdrant URL field auto-filling with default value (thanks @SannidhyaSah!) +- Fix profile context condensation threshold (thanks @PaperBoardOfficial!) +- Fix apply_diff tool documentation for multi-file capabilities +- Fix cache files excluded from rules compilation (thanks @MuriloFP!) +- Add streamlined extension installation and documentation (thanks @devxpain!) +- Prevent Architect mode from providing time estimates +- Remove context size from environment details +- Change default mode to architect for new installations +- Suppress Mermaid error rendering +- Improve Mermaid buttons with light background in light mode (thanks @chrarnoldus!) +- Add .vscode/ to write-protected files/directories +- Update AWS Bedrock cross-region inference profile mapping (thanks @KevinZhao!) + ## [3.22.5] - 2025-06-28 - Remove Gemini CLI provider while we work with Google on a better integration diff --git a/src/package.json b/src/package.json index 4232bf2be7..30168c951c 100644 --- a/src/package.json +++ b/src/package.json @@ -3,7 +3,7 @@ "displayName": "%extension.displayName%", "description": "%extension.description%", "publisher": "RooVeterinaryInc", - "version": "3.22.5", + "version": "3.22.6", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From c72f4a4b5e54c4b9ad751f499821c52aeec7d055 Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Wed, 2 Jul 2025 17:48:50 -0500 Subject: [PATCH 63/70] docs: add compact testing guidelines to project rules (#5353) --- .roo/rules/rules.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.roo/rules/rules.md b/.roo/rules/rules.md index d3795393f3..b423021844 100644 --- a/.roo/rules/rules.md +++ b/.roo/rules/rules.md @@ -6,6 +6,12 @@ - Ensure all tests pass before submitting changes - The vitest framework is used for testing; the `describe`, `test`, `it`, etc functions are defined by default in `tsconfig.json` and therefore don't need to be imported - Tests must be run from the same directory as the `package.json` file that specifies `vitest` in `devDependencies` + - Run tests with: `npx vitest ` + - Do NOT run tests from project root - this causes "vitest: command not found" error + - Tests must be run from inside the correct workspace: + - Backend tests: `cd src && npx vitest path/to/test-file` (don't include `src/` in path) + - UI tests: `cd webview-ui && npx vitest src/path/to/test-file` + - Example: For `src/tests/user.test.ts`, run `cd src && npx vitest tests/user.test.ts` NOT `npx vitest src/tests/user.test.ts` 2. Lint Rules: From 1cb69d2dc689699ec5aa6e8e92fbb34e46b1e51c Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 2 Jul 2025 22:25:58 -0400 Subject: [PATCH 64/70] Remove reference to file that no longer exists (#5360) --- .roo/rules/rules.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.roo/rules/rules.md b/.roo/rules/rules.md index b423021844..aad45c9bc6 100644 --- a/.roo/rules/rules.md +++ b/.roo/rules/rules.md @@ -21,7 +21,3 @@ - Use Tailwind CSS classes instead of inline style objects for new markup - VSCode CSS variables must be added to webview-ui/src/index.css before using them in Tailwind classes - Example: `
` instead of style objects - -# Adding a New Setting - -To add a new setting that persists its state, follow the steps in docs/settings.md From 19cd001f8d6f364abe3ca98bc3bf9a449f8817da Mon Sep 17 00:00:00 2001 From: WuWen Date: Thu, 3 Jul 2025 11:50:15 +0800 Subject: [PATCH 65/70] fix access_mcp_resource fails to handle images correctly (#5254) --- src/core/tools/accessMcpResourceTool.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/tools/accessMcpResourceTool.ts b/src/core/tools/accessMcpResourceTool.ts index 22b1aba909..c8a40f9236 100644 --- a/src/core/tools/accessMcpResourceTool.ts +++ b/src/core/tools/accessMcpResourceTool.ts @@ -73,7 +73,11 @@ export async function accessMcpResourceTool( resourceResult?.contents.forEach((item) => { if (item.mimeType?.startsWith("image") && item.blob) { - images.push(item.blob) + if (item.blob.startsWith("data:")) { + images.push(item.blob) + } else { + images.push(`data:${item.mimeType};base64,` + item.blob) + } } }) From 87aa688f33d1de8d94b4f43cf6f69874af413afc Mon Sep 17 00:00:00 2001 From: SannidhyaSah Date: Thu, 3 Jul 2025 09:21:42 +0530 Subject: [PATCH 66/70] feat: add Gemini embedding provider for codebase indexing (#5228) Co-authored-by: Daniel Riccio --- packages/types/src/codebase-index.ts | 4 +- packages/types/src/global-settings.ts | 1 + .../__tests__/config-manager.spec.ts | 40 +++++++++++ .../__tests__/service-factory.spec.ts | 70 +++++++++++++++++++ src/services/code-index/config-manager.ts | 22 ++++++ src/services/code-index/constants/index.ts | 3 + .../embedders/__tests__/gemini.spec.ts | 58 +++++++++++++++ src/services/code-index/embedders/gemini.ts | 64 +++++++++++++++++ .../code-index/embedders/openai-compatible.ts | 9 ++- src/services/code-index/interfaces/config.ts | 2 + .../code-index/interfaces/embedder.ts | 2 +- src/services/code-index/interfaces/manager.ts | 2 +- src/services/code-index/service-factory.ts | 9 +++ src/shared/embeddingModels.ts | 9 ++- .../components/settings/CodeIndexSettings.tsx | 34 +++++++-- webview-ui/src/i18n/locales/ca/settings.json | 3 + webview-ui/src/i18n/locales/de/settings.json | 3 + webview-ui/src/i18n/locales/en/settings.json | 3 + webview-ui/src/i18n/locales/es/settings.json | 3 + webview-ui/src/i18n/locales/fr/settings.json | 3 + webview-ui/src/i18n/locales/hi/settings.json | 3 + webview-ui/src/i18n/locales/id/settings.json | 3 + webview-ui/src/i18n/locales/it/settings.json | 3 + webview-ui/src/i18n/locales/ja/settings.json | 3 + webview-ui/src/i18n/locales/ko/settings.json | 3 + webview-ui/src/i18n/locales/nl/settings.json | 3 + webview-ui/src/i18n/locales/pl/settings.json | 3 + .../src/i18n/locales/pt-BR/settings.json | 3 + webview-ui/src/i18n/locales/ru/settings.json | 3 + webview-ui/src/i18n/locales/tr/settings.json | 3 + webview-ui/src/i18n/locales/vi/settings.json | 3 + .../src/i18n/locales/zh-CN/settings.json | 3 + .../src/i18n/locales/zh-TW/settings.json | 3 + 33 files changed, 372 insertions(+), 11 deletions(-) create mode 100644 src/services/code-index/embedders/__tests__/gemini.spec.ts create mode 100644 src/services/code-index/embedders/gemini.ts diff --git a/packages/types/src/codebase-index.ts b/packages/types/src/codebase-index.ts index 7263068415..df7ff85671 100644 --- a/packages/types/src/codebase-index.ts +++ b/packages/types/src/codebase-index.ts @@ -7,7 +7,7 @@ import { z } from "zod" export const codebaseIndexConfigSchema = z.object({ codebaseIndexEnabled: z.boolean().optional(), codebaseIndexQdrantUrl: z.string().optional(), - codebaseIndexEmbedderProvider: z.enum(["openai", "ollama", "openai-compatible"]).optional(), + codebaseIndexEmbedderProvider: z.enum(["openai", "ollama", "openai-compatible", "gemini"]).optional(), codebaseIndexEmbedderBaseUrl: z.string().optional(), codebaseIndexEmbedderModelId: z.string().optional(), codebaseIndexSearchMinScore: z.number().min(0).max(1).optional(), @@ -23,6 +23,7 @@ export const codebaseIndexModelsSchema = z.object({ openai: z.record(z.string(), z.object({ dimension: z.number() })).optional(), ollama: z.record(z.string(), z.object({ dimension: z.number() })).optional(), "openai-compatible": z.record(z.string(), z.object({ dimension: z.number() })).optional(), + gemini: z.record(z.string(), z.object({ dimension: z.number() })).optional(), }) export type CodebaseIndexModels = z.infer @@ -37,6 +38,7 @@ export const codebaseIndexProviderSchema = z.object({ codebaseIndexOpenAiCompatibleBaseUrl: z.string().optional(), codebaseIndexOpenAiCompatibleApiKey: z.string().optional(), codebaseIndexOpenAiCompatibleModelDimension: z.number().optional(), + codebaseIndexGeminiApiKey: z.string().optional(), }) export type CodebaseIndexProvider = z.infer diff --git a/packages/types/src/global-settings.ts b/packages/types/src/global-settings.ts index e6d9a1eed5..6a0dda1cf2 100644 --- a/packages/types/src/global-settings.ts +++ b/packages/types/src/global-settings.ts @@ -147,6 +147,7 @@ export const SECRET_STATE_KEYS = [ "codeIndexOpenAiKey", "codeIndexQdrantApiKey", "codebaseIndexOpenAiCompatibleApiKey", + "codebaseIndexGeminiApiKey", ] as const satisfies readonly (keyof ProviderSettings)[] export type SecretState = Pick diff --git a/src/services/code-index/__tests__/config-manager.spec.ts b/src/services/code-index/__tests__/config-manager.spec.ts index 2da19a6a1e..3993421378 100644 --- a/src/services/code-index/__tests__/config-manager.spec.ts +++ b/src/services/code-index/__tests__/config-manager.spec.ts @@ -1049,6 +1049,46 @@ describe("CodeIndexConfigManager", () => { expect(configManager.isFeatureConfigured).toBe(false) }) + it("should validate Gemini configuration correctly", async () => { + mockContextProxy.getGlobalState.mockImplementation((key: string) => { + if (key === "codebaseIndexConfig") { + return { + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "gemini", + } + } + return undefined + }) + mockContextProxy.getSecret.mockImplementation((key: string) => { + if (key === "codebaseIndexGeminiApiKey") return "test-gemini-key" + return undefined + }) + + await configManager.loadConfiguration() + expect(configManager.isFeatureConfigured).toBe(true) + }) + + it("should return false when Gemini API key is missing", async () => { + mockContextProxy.getGlobalState.mockImplementation((key: string) => { + if (key === "codebaseIndexConfig") { + return { + codebaseIndexEnabled: true, + codebaseIndexQdrantUrl: "http://qdrant.local", + codebaseIndexEmbedderProvider: "gemini", + } + } + return undefined + }) + mockContextProxy.getSecret.mockImplementation((key: string) => { + if (key === "codebaseIndexGeminiApiKey") return "" + return undefined + }) + + await configManager.loadConfiguration() + expect(configManager.isFeatureConfigured).toBe(false) + }) + it("should return false when required values are missing", async () => { mockContextProxy.getGlobalState.mockReturnValue({ codebaseIndexEnabled: true, diff --git a/src/services/code-index/__tests__/service-factory.spec.ts b/src/services/code-index/__tests__/service-factory.spec.ts index a539549bad..5e2d878ffb 100644 --- a/src/services/code-index/__tests__/service-factory.spec.ts +++ b/src/services/code-index/__tests__/service-factory.spec.ts @@ -3,12 +3,14 @@ import { CodeIndexServiceFactory } from "../service-factory" import { OpenAiEmbedder } from "../embedders/openai" import { CodeIndexOllamaEmbedder } from "../embedders/ollama" import { OpenAICompatibleEmbedder } from "../embedders/openai-compatible" +import { GeminiEmbedder } from "../embedders/gemini" import { QdrantVectorStore } from "../vector-store/qdrant-client" // Mock the embedders and vector store vitest.mock("../embedders/openai") vitest.mock("../embedders/ollama") vitest.mock("../embedders/openai-compatible") +vitest.mock("../embedders/gemini") vitest.mock("../vector-store/qdrant-client") // Mock the embedding models module @@ -20,6 +22,7 @@ vitest.mock("../../../shared/embeddingModels", () => ({ const MockedOpenAiEmbedder = OpenAiEmbedder as MockedClass const MockedCodeIndexOllamaEmbedder = CodeIndexOllamaEmbedder as MockedClass const MockedOpenAICompatibleEmbedder = OpenAICompatibleEmbedder as MockedClass +const MockedGeminiEmbedder = GeminiEmbedder as MockedClass const MockedQdrantVectorStore = QdrantVectorStore as MockedClass // Import the mocked functions @@ -259,6 +262,49 @@ describe("CodeIndexServiceFactory", () => { ) }) + it("should create GeminiEmbedder when using Gemini provider", () => { + // Arrange + const testConfig = { + embedderProvider: "gemini", + geminiOptions: { + apiKey: "test-gemini-api-key", + }, + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + + // Act + factory.createEmbedder() + + // Assert + expect(MockedGeminiEmbedder).toHaveBeenCalledWith("test-gemini-api-key") + }) + + it("should throw error when Gemini API key is missing", () => { + // Arrange + const testConfig = { + embedderProvider: "gemini", + geminiOptions: { + apiKey: undefined, + }, + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + + // Act & Assert + expect(() => factory.createEmbedder()).toThrow("Gemini configuration missing for embedder creation") + }) + + it("should throw error when Gemini options are missing", () => { + // Arrange + const testConfig = { + embedderProvider: "gemini", + geminiOptions: undefined, + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + + // Act & Assert + expect(() => factory.createEmbedder()).toThrow("Gemini configuration missing for embedder creation") + }) + it("should throw error for invalid embedder provider", () => { // Arrange const testConfig = { @@ -454,6 +500,30 @@ describe("CodeIndexServiceFactory", () => { ) }) + it("should use fixed dimension 768 for Gemini provider", () => { + // Arrange + const testConfig = { + embedderProvider: "gemini", + modelId: "text-embedding-004", // This is ignored by Gemini + qdrantUrl: "http://localhost:6333", + qdrantApiKey: "test-key", + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + + // Act + factory.createVectorStore() + + // Assert + // getModelDimension should not be called for Gemini + expect(mockGetModelDimension).not.toHaveBeenCalled() + expect(MockedQdrantVectorStore).toHaveBeenCalledWith( + "/test/workspace", + "http://localhost:6333", + 768, // Fixed dimension for Gemini + "test-key", + ) + }) + it("should use default model when config.modelId is undefined", () => { // Arrange const testConfig = { diff --git a/src/services/code-index/config-manager.ts b/src/services/code-index/config-manager.ts index d0eb9268b2..a27088ba14 100644 --- a/src/services/code-index/config-manager.ts +++ b/src/services/code-index/config-manager.ts @@ -16,6 +16,7 @@ export class CodeIndexConfigManager { private openAiOptions?: ApiHandlerOptions private ollamaOptions?: ApiHandlerOptions private openAiCompatibleOptions?: { baseUrl: string; apiKey: string; modelDimension?: number } + private geminiOptions?: { apiKey: string } private qdrantUrl?: string = "http://localhost:6333" private qdrantApiKey?: string private searchMinScore?: number @@ -56,6 +57,7 @@ export class CodeIndexConfigManager { const openAiCompatibleModelDimension = this.contextProxy?.getGlobalState( "codebaseIndexOpenAiCompatibleModelDimension", ) as number | undefined + const geminiApiKey = this.contextProxy?.getSecret("codebaseIndexGeminiApiKey") ?? "" // Update instance variables with configuration this.isEnabled = codebaseIndexEnabled || false @@ -69,6 +71,8 @@ export class CodeIndexConfigManager { this.embedderProvider = "ollama" } else if (codebaseIndexEmbedderProvider === "openai-compatible") { this.embedderProvider = "openai-compatible" + } else if (codebaseIndexEmbedderProvider === "gemini") { + this.embedderProvider = "gemini" } else { this.embedderProvider = "openai" } @@ -87,6 +91,8 @@ export class CodeIndexConfigManager { modelDimension: openAiCompatibleModelDimension, } : undefined + + this.geminiOptions = geminiApiKey ? { apiKey: geminiApiKey } : undefined } /** @@ -102,6 +108,7 @@ export class CodeIndexConfigManager { openAiOptions?: ApiHandlerOptions ollamaOptions?: ApiHandlerOptions openAiCompatibleOptions?: { baseUrl: string; apiKey: string } + geminiOptions?: { apiKey: string } qdrantUrl?: string qdrantApiKey?: string searchMinScore?: number @@ -119,6 +126,7 @@ export class CodeIndexConfigManager { openAiCompatibleBaseUrl: this.openAiCompatibleOptions?.baseUrl ?? "", openAiCompatibleApiKey: this.openAiCompatibleOptions?.apiKey ?? "", openAiCompatibleModelDimension: this.openAiCompatibleOptions?.modelDimension, + geminiApiKey: this.geminiOptions?.apiKey ?? "", qdrantUrl: this.qdrantUrl ?? "", qdrantApiKey: this.qdrantApiKey ?? "", } @@ -138,6 +146,7 @@ export class CodeIndexConfigManager { openAiOptions: this.openAiOptions, ollamaOptions: this.ollamaOptions, openAiCompatibleOptions: this.openAiCompatibleOptions, + geminiOptions: this.geminiOptions, qdrantUrl: this.qdrantUrl, qdrantApiKey: this.qdrantApiKey, searchMinScore: this.currentSearchMinScore, @@ -166,6 +175,10 @@ export class CodeIndexConfigManager { const apiKey = this.openAiCompatibleOptions?.apiKey const qdrantUrl = this.qdrantUrl return !!(baseUrl && apiKey && qdrantUrl) + } else if (this.embedderProvider === "gemini") { + const apiKey = this.geminiOptions?.apiKey + const qdrantUrl = this.qdrantUrl + return !!(apiKey && qdrantUrl) } return false // Should not happen if embedderProvider is always set correctly } @@ -186,6 +199,7 @@ export class CodeIndexConfigManager { const prevOpenAiCompatibleBaseUrl = prev?.openAiCompatibleBaseUrl ?? "" const prevOpenAiCompatibleApiKey = prev?.openAiCompatibleApiKey ?? "" const prevOpenAiCompatibleModelDimension = prev?.openAiCompatibleModelDimension + const prevGeminiApiKey = prev?.geminiApiKey ?? "" const prevQdrantUrl = prev?.qdrantUrl ?? "" const prevQdrantApiKey = prev?.qdrantApiKey ?? "" @@ -243,6 +257,13 @@ export class CodeIndexConfigManager { } } + if (this.embedderProvider === "gemini") { + const currentGeminiApiKey = this.geminiOptions?.apiKey ?? "" + if (prevGeminiApiKey !== currentGeminiApiKey) { + return true + } + } + // Qdrant configuration changes const currentQdrantUrl = this.qdrantUrl ?? "" const currentQdrantApiKey = this.qdrantApiKey ?? "" @@ -293,6 +314,7 @@ export class CodeIndexConfigManager { openAiOptions: this.openAiOptions, ollamaOptions: this.ollamaOptions, openAiCompatibleOptions: this.openAiCompatibleOptions, + geminiOptions: this.geminiOptions, qdrantUrl: this.qdrantUrl, qdrantApiKey: this.qdrantApiKey, searchMinScore: this.currentSearchMinScore, diff --git a/src/services/code-index/constants/index.ts b/src/services/code-index/constants/index.ts index cbf6941817..fc66571fbb 100644 --- a/src/services/code-index/constants/index.ts +++ b/src/services/code-index/constants/index.ts @@ -23,3 +23,6 @@ export const PARSING_CONCURRENCY = 10 export const MAX_BATCH_TOKENS = 100000 export const MAX_ITEM_TOKENS = 8191 export const BATCH_PROCESSING_CONCURRENCY = 10 + +/**Gemini Embedder */ +export const GEMINI_MAX_ITEM_TOKENS = 2048 diff --git a/src/services/code-index/embedders/__tests__/gemini.spec.ts b/src/services/code-index/embedders/__tests__/gemini.spec.ts new file mode 100644 index 0000000000..6d518f65aa --- /dev/null +++ b/src/services/code-index/embedders/__tests__/gemini.spec.ts @@ -0,0 +1,58 @@ +import { vitest, describe, it, expect, beforeEach } from "vitest" +import type { MockedClass } from "vitest" +import { GeminiEmbedder } from "../gemini" +import { OpenAICompatibleEmbedder } from "../openai-compatible" + +// Mock the OpenAICompatibleEmbedder +vitest.mock("../openai-compatible") + +const MockedOpenAICompatibleEmbedder = OpenAICompatibleEmbedder as MockedClass + +describe("GeminiEmbedder", () => { + let embedder: GeminiEmbedder + + beforeEach(() => { + vitest.clearAllMocks() + }) + + describe("constructor", () => { + it("should create an instance with correct fixed values passed to OpenAICompatibleEmbedder", () => { + // Arrange + const apiKey = "test-gemini-api-key" + + // Act + embedder = new GeminiEmbedder(apiKey) + + // Assert + expect(MockedOpenAICompatibleEmbedder).toHaveBeenCalledWith( + "https://generativelanguage.googleapis.com/v1beta/openai/", + apiKey, + "text-embedding-004", + 2048, + ) + }) + + it("should throw error when API key is not provided", () => { + // Act & Assert + expect(() => new GeminiEmbedder("")).toThrow("API key is required for Gemini embedder") + expect(() => new GeminiEmbedder(null as any)).toThrow("API key is required for Gemini embedder") + expect(() => new GeminiEmbedder(undefined as any)).toThrow("API key is required for Gemini embedder") + }) + }) + + describe("embedderInfo", () => { + it("should return correct embedder info with dimension 768", () => { + // Arrange + embedder = new GeminiEmbedder("test-api-key") + + // Act + const info = embedder.embedderInfo + + // Assert + expect(info).toEqual({ + name: "gemini", + }) + expect(GeminiEmbedder.dimension).toBe(768) + }) + }) +}) diff --git a/src/services/code-index/embedders/gemini.ts b/src/services/code-index/embedders/gemini.ts new file mode 100644 index 0000000000..38bb132df7 --- /dev/null +++ b/src/services/code-index/embedders/gemini.ts @@ -0,0 +1,64 @@ +import { OpenAICompatibleEmbedder } from "./openai-compatible" +import { IEmbedder, EmbeddingResponse, EmbedderInfo } from "../interfaces/embedder" +import { GEMINI_MAX_ITEM_TOKENS } from "../constants" + +/** + * Gemini embedder implementation that wraps the OpenAI Compatible embedder + * with fixed configuration for Google's Gemini embedding API. + * + * Fixed values: + * - Base URL: https://generativelanguage.googleapis.com/v1beta/openai/ + * - Model: text-embedding-004 + * - Dimension: 768 + */ +export class GeminiEmbedder implements IEmbedder { + private readonly openAICompatibleEmbedder: OpenAICompatibleEmbedder + private static readonly GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/" + private static readonly GEMINI_MODEL = "text-embedding-004" + private static readonly GEMINI_DIMENSION = 768 + + /** + * Creates a new Gemini embedder + * @param apiKey The Gemini API key for authentication + */ + constructor(apiKey: string) { + if (!apiKey) { + throw new Error("API key is required for Gemini embedder") + } + + // Create an OpenAI Compatible embedder with Gemini's fixed configuration + this.openAICompatibleEmbedder = new OpenAICompatibleEmbedder( + GeminiEmbedder.GEMINI_BASE_URL, + apiKey, + GeminiEmbedder.GEMINI_MODEL, + GEMINI_MAX_ITEM_TOKENS, + ) + } + + /** + * Creates embeddings for the given texts using Gemini's embedding API + * @param texts Array of text strings to embed + * @param model Optional model identifier (ignored - always uses text-embedding-004) + * @returns Promise resolving to embedding response + */ + async createEmbeddings(texts: string[], model?: string): Promise { + // Always use the fixed Gemini model, ignoring any passed model parameter + return this.openAICompatibleEmbedder.createEmbeddings(texts, GeminiEmbedder.GEMINI_MODEL) + } + + /** + * Returns information about this embedder + */ + get embedderInfo(): EmbedderInfo { + return { + name: "gemini", + } + } + + /** + * Gets the fixed dimension for Gemini embeddings + */ + static get dimension(): number { + return GeminiEmbedder.GEMINI_DIMENSION + } +} diff --git a/src/services/code-index/embedders/openai-compatible.ts b/src/services/code-index/embedders/openai-compatible.ts index 8bf35eea24..f7e679abf6 100644 --- a/src/services/code-index/embedders/openai-compatible.ts +++ b/src/services/code-index/embedders/openai-compatible.ts @@ -29,14 +29,16 @@ interface OpenAIEmbeddingResponse { export class OpenAICompatibleEmbedder implements IEmbedder { private embeddingsClient: OpenAI private readonly defaultModelId: string + private readonly maxItemTokens: number /** * Creates a new OpenAI Compatible embedder * @param baseUrl The base URL for the OpenAI-compatible API endpoint * @param apiKey The API key for authentication * @param modelId Optional model identifier (defaults to "text-embedding-3-small") + * @param maxItemTokens Optional maximum tokens per item (defaults to MAX_ITEM_TOKENS) */ - constructor(baseUrl: string, apiKey: string, modelId?: string) { + constructor(baseUrl: string, apiKey: string, modelId?: string, maxItemTokens?: number) { if (!baseUrl) { throw new Error("Base URL is required for OpenAI Compatible embedder") } @@ -49,6 +51,7 @@ export class OpenAICompatibleEmbedder implements IEmbedder { apiKey: apiKey, }) this.defaultModelId = modelId || getDefaultModelId("openai-compatible") + this.maxItemTokens = maxItemTokens || MAX_ITEM_TOKENS } /** @@ -98,12 +101,12 @@ export class OpenAICompatibleEmbedder implements IEmbedder { const text = remainingTexts[i] const itemTokens = Math.ceil(text.length / 4) - if (itemTokens > MAX_ITEM_TOKENS) { + if (itemTokens > this.maxItemTokens) { console.warn( t("embeddings:textExceedsTokenLimit", { index: i, itemTokens, - maxTokens: MAX_ITEM_TOKENS, + maxTokens: this.maxItemTokens, }), ) processedIndices.push(i) diff --git a/src/services/code-index/interfaces/config.ts b/src/services/code-index/interfaces/config.ts index 0843120fd9..3501ec950c 100644 --- a/src/services/code-index/interfaces/config.ts +++ b/src/services/code-index/interfaces/config.ts @@ -12,6 +12,7 @@ export interface CodeIndexConfig { openAiOptions?: ApiHandlerOptions ollamaOptions?: ApiHandlerOptions openAiCompatibleOptions?: { baseUrl: string; apiKey: string; modelDimension?: number } + geminiOptions?: { apiKey: string } qdrantUrl?: string qdrantApiKey?: string searchMinScore?: number @@ -30,6 +31,7 @@ export type PreviousConfigSnapshot = { openAiCompatibleBaseUrl?: string openAiCompatibleApiKey?: string openAiCompatibleModelDimension?: number + geminiApiKey?: string qdrantUrl?: string qdrantApiKey?: string } diff --git a/src/services/code-index/interfaces/embedder.ts b/src/services/code-index/interfaces/embedder.ts index 820fba9b8e..3ea6293aa5 100644 --- a/src/services/code-index/interfaces/embedder.ts +++ b/src/services/code-index/interfaces/embedder.ts @@ -21,7 +21,7 @@ export interface EmbeddingResponse { } } -export type AvailableEmbedders = "openai" | "ollama" | "openai-compatible" +export type AvailableEmbedders = "openai" | "ollama" | "openai-compatible" | "gemini" export interface EmbedderInfo { name: AvailableEmbedders diff --git a/src/services/code-index/interfaces/manager.ts b/src/services/code-index/interfaces/manager.ts index f3d577d82f..70e3fd9765 100644 --- a/src/services/code-index/interfaces/manager.ts +++ b/src/services/code-index/interfaces/manager.ts @@ -70,7 +70,7 @@ export interface ICodeIndexManager { } export type IndexingState = "Standby" | "Indexing" | "Indexed" | "Error" -export type EmbedderProvider = "openai" | "ollama" | "openai-compatible" +export type EmbedderProvider = "openai" | "ollama" | "openai-compatible" | "gemini" export interface IndexProgressUpdate { systemStatus: IndexingState diff --git a/src/services/code-index/service-factory.ts b/src/services/code-index/service-factory.ts index afd083b204..2a19c8ebab 100644 --- a/src/services/code-index/service-factory.ts +++ b/src/services/code-index/service-factory.ts @@ -2,6 +2,7 @@ import * as vscode from "vscode" import { OpenAiEmbedder } from "./embedders/openai" import { CodeIndexOllamaEmbedder } from "./embedders/ollama" import { OpenAICompatibleEmbedder } from "./embedders/openai-compatible" +import { GeminiEmbedder } from "./embedders/gemini" import { EmbedderProvider, getDefaultModelId, getModelDimension } from "../../shared/embeddingModels" import { QdrantVectorStore } from "./vector-store/qdrant-client" import { codeParser, DirectoryScanner, FileWatcher } from "./processors" @@ -53,6 +54,11 @@ export class CodeIndexServiceFactory { config.openAiCompatibleOptions.apiKey, config.modelId, ) + } else if (provider === "gemini") { + if (!config.geminiOptions?.apiKey) { + throw new Error("Gemini configuration missing for embedder creation") + } + return new GeminiEmbedder(config.geminiOptions.apiKey) } throw new Error(`Invalid embedder type configured: ${config.embedderProvider}`) @@ -78,6 +84,9 @@ export class CodeIndexServiceFactory { // Fallback if not provided or invalid in openAiCompatibleOptions vectorSize = getModelDimension(provider, modelId) } + } else if (provider === "gemini") { + // Gemini's text-embedding-004 has a fixed dimension of 768 + vectorSize = 768 } else { vectorSize = getModelDimension(provider, modelId) } diff --git a/src/shared/embeddingModels.ts b/src/shared/embeddingModels.ts index c78dc6c487..4c6bc24319 100644 --- a/src/shared/embeddingModels.ts +++ b/src/shared/embeddingModels.ts @@ -2,7 +2,7 @@ * Defines profiles for different embedding models, including their dimensions. */ -export type EmbedderProvider = "openai" | "ollama" | "openai-compatible" // Add other providers as needed +export type EmbedderProvider = "openai" | "ollama" | "openai-compatible" | "gemini" // Add other providers as needed export interface EmbeddingModelProfile { dimension: number @@ -46,6 +46,9 @@ export const EMBEDDING_MODEL_PROFILES: EmbeddingModelProfiles = { queryPrefix: "Represent this query for searching relevant code: ", }, }, + gemini: { + "text-embedding-004": { dimension: 768 }, + }, } /** @@ -129,6 +132,10 @@ export function getDefaultModelId(provider: EmbedderProvider): string { // Return a placeholder or throw an error, depending on desired behavior return "unknown-default" // Placeholder specific model ID } + + case "gemini": + return "text-embedding-004" + default: // Fallback for unknown providers console.warn(`Unknown provider for default model ID: ${provider}. Falling back to OpenAI default.`) diff --git a/webview-ui/src/components/settings/CodeIndexSettings.tsx b/webview-ui/src/components/settings/CodeIndexSettings.tsx index 8aae766b8f..ea6fc75fdd 100644 --- a/webview-ui/src/components/settings/CodeIndexSettings.tsx +++ b/webview-ui/src/components/settings/CodeIndexSettings.tsx @@ -71,9 +71,9 @@ export const CodeIndexSettings: React.FC = ({ // Safely calculate available models for current provider const currentProvider = codebaseIndexConfig?.codebaseIndexEmbedderProvider const modelsForProvider = - currentProvider === "openai" || currentProvider === "ollama" || currentProvider === "openai-compatible" - ? codebaseIndexModels?.[currentProvider] || codebaseIndexModels?.openai - : codebaseIndexModels?.openai + currentProvider === "openai" || currentProvider === "openai-compatible" + ? (codebaseIndexModels?.openai ?? codebaseIndexModels?.["openai-compatible"]) + : codebaseIndexModels?.[currentProvider as keyof typeof codebaseIndexModels] const availableModelIds = Object.keys(modelsForProvider || {}) useEffect(() => { @@ -154,6 +154,10 @@ export const CodeIndexSettings: React.FC = ({ .positive("Dimension must be a positive number") .optional(), }), + gemini: baseSchema.extend({ + codebaseIndexEmbedderProvider: z.literal("gemini"), + codebaseIndexGeminiApiKey: z.string().min(1, "Gemini API key is required"), + }), } try { @@ -162,7 +166,9 @@ export const CodeIndexSettings: React.FC = ({ ? providerSchemas.openai : config.codebaseIndexEmbedderProvider === "ollama" ? providerSchemas.ollama - : providerSchemas["openai-compatible"] + : config.codebaseIndexEmbedderProvider === "gemini" + ? providerSchemas.gemini + : providerSchemas["openai-compatible"] schema.parse({ ...config, @@ -170,6 +176,7 @@ export const CodeIndexSettings: React.FC = ({ codebaseIndexOpenAiCompatibleBaseUrl: apiConfig.codebaseIndexOpenAiCompatibleBaseUrl, codebaseIndexOpenAiCompatibleApiKey: apiConfig.codebaseIndexOpenAiCompatibleApiKey, codebaseIndexOpenAiCompatibleModelDimension: apiConfig.codebaseIndexOpenAiCompatibleModelDimension, + codebaseIndexGeminiApiKey: apiConfig.codebaseIndexGeminiApiKey, }) return true } catch { @@ -284,6 +291,7 @@ export const CodeIndexSettings: React.FC = ({ {t("settings:codeIndex.openaiCompatibleProvider")} + {t("settings:codeIndex.geminiProvider")}
@@ -428,6 +436,24 @@ export const CodeIndexSettings: React.FC = ({
)} + {codebaseIndexConfig?.codebaseIndexEmbedderProvider === "gemini" && ( +
+
+
{t("settings:codeIndex.geminiApiKeyLabel")}
+
+
+ + setApiConfigurationField("codebaseIndexGeminiApiKey", e.target.value) + } + placeholder={t("settings:codeIndex.geminiApiKeyPlaceholder")} + style={{ width: "100%" }}> +
+
+ )} +
{t("settings:codeIndex.qdrantUrlLabel")}
diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index 3fe9cd78b9..a82d081d8c 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Seleccionar proveรฏdor", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "Clau API:", + "geminiApiKeyPlaceholder": "Introduรฏu la vostra clau d'API de Gemini", "openaiCompatibleProvider": "Compatible amb OpenAI", "openaiCompatibleBaseUrlLabel": "URL base:", "openaiCompatibleApiKeyLabel": "Clau API:", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index bf33512650..137176336c 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Anbieter auswรคhlen", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API-Schlรผssel:", + "geminiApiKeyPlaceholder": "Geben Sie Ihren Gemini-API-Schlรผssel ein", "openaiCompatibleProvider": "OpenAI-kompatibel", "openaiCompatibleBaseUrlLabel": "Basis-URL:", "openaiCompatibleApiKeyLabel": "API-Schlรผssel:", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index b18f526e15..0d5e91da9d 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Select provider", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API Key:", + "geminiApiKeyPlaceholder": "Enter your Gemini API key", "openaiCompatibleProvider": "OpenAI Compatible", "openaiKeyLabel": "OpenAI Key:", "openaiCompatibleBaseUrlLabel": "Base URL:", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 92d12b4e24..77a1179cbe 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Seleccionar proveedor", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "Clave API:", + "geminiApiKeyPlaceholder": "Introduce tu clave de API de Gemini", "openaiCompatibleProvider": "Compatible con OpenAI", "openaiCompatibleBaseUrlLabel": "URL base:", "openaiCompatibleApiKeyLabel": "Clave API:", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 7c3f38b7b3..6dad3cfda5 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Sรฉlectionner un fournisseur", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "Clรฉ API :", + "geminiApiKeyPlaceholder": "Entrez votre clรฉ API Gemini", "openaiCompatibleProvider": "Compatible OpenAI", "openaiCompatibleBaseUrlLabel": "URL de base :", "openaiCompatibleApiKeyLabel": "Clรฉ API :", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 36cfc01896..82d50a47f6 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "เคชเฅเคฐเคฆเคพเคคเคพ เคšเฅเคจเฅ‡เค‚", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API เค•เฅเค‚เคœเฅ€:", + "geminiApiKeyPlaceholder": "เค…เคชเคจเคพ เคœเฅ‡เคฎเคฟเคจเฅ€ เคเคชเฅ€เค†เคˆ เค•เฅเค‚เคœเฅ€ เคฆเคฐเฅเคœ เค•เคฐเฅ‡เค‚", "openaiCompatibleProvider": "OpenAI เคธเค‚เค—เคค", "openaiCompatibleBaseUrlLabel": "เค†เคงเคพเคฐ URL:", "openaiCompatibleApiKeyLabel": "API เค•เฅเค‚เคœเฅ€:", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 08a23cd30c..dca77632d7 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Pilih provider", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API Key:", + "geminiApiKeyPlaceholder": "Masukkan kunci API Gemini Anda", "openaiCompatibleProvider": "OpenAI Compatible", "openaiKeyLabel": "OpenAI Key:", "openaiCompatibleBaseUrlLabel": "Base URL:", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 4897212d0f..d95279c136 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Seleziona fornitore", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "Chiave API:", + "geminiApiKeyPlaceholder": "Inserisci la tua chiave API Gemini", "openaiCompatibleProvider": "Compatibile con OpenAI", "openaiCompatibleBaseUrlLabel": "URL di base:", "openaiCompatibleApiKeyLabel": "Chiave API:", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index 4165726ade..1747666c58 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "ใƒ—ใƒญใƒใ‚คใƒ€ใƒผใ‚’้ธๆŠž", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "APIใ‚ญใƒผ๏ผš", + "geminiApiKeyPlaceholder": "Gemini APIใ‚ญใƒผใ‚’ๅ…ฅๅŠ›ใ—ใฆใใ ใ•ใ„", "openaiCompatibleProvider": "OpenAIไบ’ๆ›", "openaiCompatibleBaseUrlLabel": "ใƒ™ใƒผใ‚นURL๏ผš", "openaiCompatibleApiKeyLabel": "APIใ‚ญใƒผ๏ผš", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index e68297599c..fca611defc 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "์ œ๊ณต์ž ์„ ํƒ", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API ํ‚ค:", + "geminiApiKeyPlaceholder": "Gemini API ํ‚ค๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”", "openaiCompatibleProvider": "OpenAI ํ˜ธํ™˜", "openaiCompatibleBaseUrlLabel": "๊ธฐ๋ณธ URL:", "openaiCompatibleApiKeyLabel": "API ํ‚ค:", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 254334df54..d83d65565b 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Selecteer provider", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API-sleutel:", + "geminiApiKeyPlaceholder": "Voer uw Gemini API-sleutel in", "openaiCompatibleProvider": "OpenAI-compatibel", "openaiCompatibleBaseUrlLabel": "Basis-URL:", "openaiCompatibleApiKeyLabel": "API-sleutel:", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index 02a7d0d04d..41eb6ce2dc 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Wybierz dostawcฤ™", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "Klucz API:", + "geminiApiKeyPlaceholder": "Wprowadลบ swรณj klucz API Gemini", "openaiCompatibleProvider": "Kompatybilny z OpenAI", "openaiCompatibleBaseUrlLabel": "Bazowy URL:", "openaiCompatibleApiKeyLabel": "Klucz API:", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 8c7b6c9a24..93fce73817 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Selecionar provedor", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "Chave de API:", + "geminiApiKeyPlaceholder": "Digite sua chave de API do Gemini", "openaiCompatibleProvider": "Compatรญvel com OpenAI", "openaiCompatibleBaseUrlLabel": "URL Base:", "openaiCompatibleApiKeyLabel": "Chave de API:", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index e60b97f775..7c0983b2ed 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "ะ’ั‹ะฑะตั€ะธั‚ะต ะฟั€ะพะฒะฐะนะดะตั€ะฐ", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "ะšะปัŽั‡ API:", + "geminiApiKeyPlaceholder": "ะ’ะฒะตะดะธั‚ะต ัะฒะพะน API-ะบะปัŽั‡ Gemini", "openaiCompatibleProvider": "OpenAI-ัะพะฒะผะตัั‚ะธะผั‹ะน", "openaiCompatibleBaseUrlLabel": "ะ‘ะฐะทะพะฒั‹ะน URL:", "openaiCompatibleApiKeyLabel": "ะšะปัŽั‡ API:", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index c7ced157f6..6e050e4585 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "SaฤŸlayฤฑcฤฑ seรง", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API Anahtarฤฑ:", + "geminiApiKeyPlaceholder": "Gemini API anahtarฤฑnฤฑzฤฑ girin", "openaiCompatibleProvider": "OpenAI Uyumlu", "openaiCompatibleBaseUrlLabel": "Temel URL:", "openaiCompatibleApiKeyLabel": "API Anahtarฤฑ:", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index c82bfdd7a2..a3b68e96a5 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "Chแปn nhร  cung cแบฅp", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "Khรณa API:", + "geminiApiKeyPlaceholder": "Nhแบญp khรณa API Gemini cแปงa bแบกn", "openaiCompatibleProvider": "Tฦฐฦกng thรญch OpenAI", "openaiCompatibleBaseUrlLabel": "URL cฦก sแปŸ:", "openaiCompatibleApiKeyLabel": "Khรณa API:", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index d4ce96e8e4..39c3b2ff74 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "้€‰ๆ‹ฉๆไพ›ๅ•†", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API ๅฏ†้’ฅ๏ผš", + "geminiApiKeyPlaceholder": "่พ“ๅ…ฅๆ‚จ็š„Gemini APIๅฏ†้’ฅ", "openaiCompatibleProvider": "OpenAI ๅ…ผๅฎน", "openaiCompatibleBaseUrlLabel": "ๅŸบ็ก€ URL๏ผš", "openaiCompatibleApiKeyLabel": "API ๅฏ†้’ฅ๏ผš", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index be6ad5d80c..d463d9c2cf 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -44,6 +44,9 @@ "selectProviderPlaceholder": "้ธๆ“‡ๆไพ›่€…", "openaiProvider": "OpenAI", "ollamaProvider": "Ollama", + "geminiProvider": "Gemini", + "geminiApiKeyLabel": "API ้‡‘้‘ฐ๏ผš", + "geminiApiKeyPlaceholder": "่ผธๅ…ฅๆ‚จ็š„Gemini API้‡‘้‘ฐ", "openaiCompatibleProvider": "OpenAI ็›ธๅฎน", "openaiCompatibleBaseUrlLabel": "ๅŸบ็คŽ URL๏ผš", "openaiCompatibleApiKeyLabel": "API ้‡‘้‘ฐ๏ผš", From 37619d78507724a7f9ad43efac4a9207bbe723d5 Mon Sep 17 00:00:00 2001 From: SannidhyaSah Date: Thu, 3 Jul 2025 09:28:35 +0530 Subject: [PATCH 67/70] fix: support full endpoint URLs in OpenAI Compatible provider (#5212) (#5214) Co-authored-by: Matt Rubens --- .../__tests__/openai-compatible.spec.ts | 268 ++++++++++++++++++ .../code-index/embedders/openai-compatible.ts | 115 +++++++- 2 files changed, 368 insertions(+), 15 deletions(-) diff --git a/src/services/code-index/embedders/__tests__/openai-compatible.spec.ts b/src/services/code-index/embedders/__tests__/openai-compatible.spec.ts index 271d68cc20..107f3af24d 100644 --- a/src/services/code-index/embedders/__tests__/openai-compatible.spec.ts +++ b/src/services/code-index/embedders/__tests__/openai-compatible.spec.ts @@ -6,6 +6,9 @@ import { MAX_ITEM_TOKENS, INITIAL_RETRY_DELAY_MS } from "../../constants" // Mock the OpenAI SDK vitest.mock("openai") +// Mock global fetch +global.fetch = vitest.fn() + // Mock i18n vitest.mock("../../../../i18n", () => ({ t: (key: string, params?: Record) => { @@ -613,5 +616,270 @@ describe("OpenAICompatibleEmbedder", () => { expect(returnedArray).toEqual([0.25, 0.5, 0.75, 1.0]) }) }) + + /** + * Test Azure OpenAI compatibility with helper functions for conciseness + */ + describe("Azure OpenAI compatibility", () => { + const azureUrl = + "https://myresource.openai.azure.com/openai/deployments/mymodel/embeddings?api-version=2024-02-01" + const baseUrl = "https://api.openai.com/v1" + + // Helper to create mock fetch response + const createMockResponse = (data: any, status = 200, ok = true) => ({ + ok, + status, + json: vitest.fn().mockResolvedValue(data), + text: vitest.fn().mockResolvedValue(status === 200 ? "" : "Error message"), + }) + + // Helper to create base64 embedding + const createBase64Embedding = (values: number[]) => { + const embedding = new Float32Array(values) + return Buffer.from(embedding.buffer).toString("base64") + } + + // Helper to verify embedding values with floating-point tolerance + const expectEmbeddingValues = (actual: number[], expected: number[]) => { + expect(actual).toHaveLength(expected.length) + expected.forEach((val, i) => expect(actual[i]).toBeCloseTo(val, 5)) + } + + beforeEach(() => { + vitest.clearAllMocks() + ;(global.fetch as MockedFunction).mockReset() + }) + + describe("URL detection", () => { + it.each([ + [ + "https://myresource.openai.azure.com/openai/deployments/mymodel/embeddings?api-version=2024-02-01", + true, + ], + ["https://myresource.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings", true], + ["https://api.openai.com/v1", false], + ["https://api.example.com", false], + ["http://localhost:8080", false], + ])("should detect URL type correctly: %s -> %s", (url, expected) => { + const embedder = new OpenAICompatibleEmbedder(url, testApiKey, testModelId) + const isFullUrl = (embedder as any).isFullEndpointUrl(url) + expect(isFullUrl).toBe(expected) + }) + + // Edge cases where 'embeddings' or 'deployments' appear in non-endpoint contexts + it("should return false for URLs with 'embeddings' in non-endpoint contexts", () => { + const testUrls = [ + "https://api.example.com/embeddings-service/v1", + "https://embeddings.example.com/api", + "https://api.example.com/v1/embeddings-api", + "https://my-embeddings-provider.com/v1", + ] + + testUrls.forEach((url) => { + const embedder = new OpenAICompatibleEmbedder(url, testApiKey, testModelId) + const isFullUrl = (embedder as any).isFullEndpointUrl(url) + expect(isFullUrl).toBe(false) + }) + }) + + it("should return false for URLs with 'deployments' in non-endpoint contexts", () => { + const testUrls = [ + "https://deployments.example.com/api", + "https://api.deployments.com/v1", + "https://my-deployments-service.com/api/v1", + "https://deployments-manager.example.com", + ] + + testUrls.forEach((url) => { + const embedder = new OpenAICompatibleEmbedder(url, testApiKey, testModelId) + const isFullUrl = (embedder as any).isFullEndpointUrl(url) + expect(isFullUrl).toBe(false) + }) + }) + + it("should correctly identify actual endpoint URLs", () => { + const endpointUrls = [ + "https://api.example.com/v1/embeddings", + "https://api.example.com/v1/embeddings?api-version=2024", + "https://myresource.openai.azure.com/openai/deployments/mymodel/embeddings", + "https://api.example.com/embed", + "https://api.example.com/embed?version=1", + ] + + endpointUrls.forEach((url) => { + const embedder = new OpenAICompatibleEmbedder(url, testApiKey, testModelId) + const isFullUrl = (embedder as any).isFullEndpointUrl(url) + expect(isFullUrl).toBe(true) + }) + }) + }) + + describe("direct HTTP requests", () => { + it("should use direct fetch for Azure URLs and SDK for base URLs", async () => { + const testTexts = ["Test text"] + const base64String = createBase64Embedding([0.1, 0.2, 0.3]) + + // Test Azure URL (direct fetch) + const azureEmbedder = new OpenAICompatibleEmbedder(azureUrl, testApiKey, testModelId) + const mockFetchResponse = createMockResponse({ + data: [{ embedding: base64String }], + usage: { prompt_tokens: 10, total_tokens: 15 }, + }) + ;(global.fetch as MockedFunction).mockResolvedValue(mockFetchResponse as any) + + const azureResult = await azureEmbedder.createEmbeddings(testTexts) + expect(global.fetch).toHaveBeenCalledWith( + azureUrl, + expect.objectContaining({ + method: "POST", + headers: expect.objectContaining({ + "api-key": testApiKey, + Authorization: `Bearer ${testApiKey}`, + }), + }), + ) + expect(mockEmbeddingsCreate).not.toHaveBeenCalled() + expectEmbeddingValues(azureResult.embeddings[0], [0.1, 0.2, 0.3]) + + // Reset and test base URL (SDK) + vitest.clearAllMocks() + const baseEmbedder = new OpenAICompatibleEmbedder(baseUrl, testApiKey, testModelId) + mockEmbeddingsCreate.mockResolvedValue({ + data: [{ embedding: [0.4, 0.5, 0.6] }], + usage: { prompt_tokens: 10, total_tokens: 15 }, + }) + + const baseResult = await baseEmbedder.createEmbeddings(testTexts) + expect(mockEmbeddingsCreate).toHaveBeenCalled() + expect(global.fetch).not.toHaveBeenCalled() + expect(baseResult.embeddings[0]).toEqual([0.4, 0.5, 0.6]) + }) + + it.each([ + [401, "Authentication failed. Please check your API key."], + [500, "Failed to create embeddings after 3 attempts"], + ])("should handle HTTP errors: %d", async (status, expectedMessage) => { + const embedder = new OpenAICompatibleEmbedder(azureUrl, testApiKey, testModelId) + const mockResponse = createMockResponse({}, status, false) + ;(global.fetch as MockedFunction).mockResolvedValue(mockResponse as any) + + await expect(embedder.createEmbeddings(["test"])).rejects.toThrow(expectedMessage) + }) + + it("should handle rate limiting with retries", async () => { + vitest.useFakeTimers() + const embedder = new OpenAICompatibleEmbedder(azureUrl, testApiKey, testModelId) + const base64String = createBase64Embedding([0.1, 0.2, 0.3]) + + ;(global.fetch as MockedFunction) + .mockResolvedValueOnce(createMockResponse({}, 429, false) as any) + .mockResolvedValueOnce(createMockResponse({}, 429, false) as any) + .mockResolvedValueOnce( + createMockResponse({ + data: [{ embedding: base64String }], + usage: { prompt_tokens: 10, total_tokens: 15 }, + }) as any, + ) + + const resultPromise = embedder.createEmbeddings(["test"]) + await vitest.advanceTimersByTimeAsync(INITIAL_RETRY_DELAY_MS * 3) + const result = await resultPromise + + expect(global.fetch).toHaveBeenCalledTimes(3) + expect(console.warn).toHaveBeenCalledWith(expect.stringContaining("Rate limit hit")) + expectEmbeddingValues(result.embeddings[0], [0.1, 0.2, 0.3]) + vitest.useRealTimers() + }) + + it("should handle multiple embeddings and network errors", async () => { + const embedder = new OpenAICompatibleEmbedder(azureUrl, testApiKey, testModelId) + + // Test multiple embeddings + const base64_1 = createBase64Embedding([0.25, 0.5]) + const base64_2 = createBase64Embedding([0.75, 1.0]) + const mockResponse = createMockResponse({ + data: [{ embedding: base64_1 }, { embedding: base64_2 }], + usage: { prompt_tokens: 20, total_tokens: 30 }, + }) + ;(global.fetch as MockedFunction).mockResolvedValue(mockResponse as any) + + const result = await embedder.createEmbeddings(["test1", "test2"]) + expect(result.embeddings).toHaveLength(2) + expectEmbeddingValues(result.embeddings[0], [0.25, 0.5]) + expectEmbeddingValues(result.embeddings[1], [0.75, 1.0]) + + // Test network error + const networkError = new Error("Network failed") + ;(global.fetch as MockedFunction).mockRejectedValue(networkError) + await expect(embedder.createEmbeddings(["test"])).rejects.toThrow( + "Failed to create embeddings after 3 attempts", + ) + }) + }) + }) + }) + + describe("URL detection", () => { + it("should detect Azure deployment URLs as full endpoints", async () => { + const embedder = new OpenAICompatibleEmbedder( + "https://myinstance.openai.azure.com/openai/deployments/my-deployment/embeddings?api-version=2023-05-15", + "test-key", + ) + + // The private method is tested indirectly through the createEmbeddings behavior + // If it's detected as a full URL, it will make a direct HTTP request + const mockFetch = vitest.fn().mockResolvedValue({ + ok: true, + json: async () => ({ + data: [{ embedding: [0.1, 0.2] }], + usage: { prompt_tokens: 10, total_tokens: 15 }, + }), + }) + global.fetch = mockFetch + + await embedder.createEmbeddings(["test"]) + + // Should make direct HTTP request to the full URL + expect(mockFetch).toHaveBeenCalledWith( + "https://myinstance.openai.azure.com/openai/deployments/my-deployment/embeddings?api-version=2023-05-15", + expect.any(Object), + ) + }) + + it("should detect /embed endpoints as full URLs", async () => { + const embedder = new OpenAICompatibleEmbedder("https://api.example.com/v1/embed", "test-key") + + const mockFetch = vitest.fn().mockResolvedValue({ + ok: true, + json: async () => ({ + data: [{ embedding: [0.1, 0.2] }], + usage: { prompt_tokens: 10, total_tokens: 15 }, + }), + }) + global.fetch = mockFetch + + await embedder.createEmbeddings(["test"]) + + // Should make direct HTTP request to the full URL + expect(mockFetch).toHaveBeenCalledWith("https://api.example.com/v1/embed", expect.any(Object)) + }) + + it("should treat base URLs without endpoint patterns as SDK URLs", async () => { + const embedder = new OpenAICompatibleEmbedder("https://api.openai.com/v1", "test-key") + + // Mock the OpenAI SDK's embeddings.create method + const mockCreate = vitest.fn().mockResolvedValue({ + data: [{ embedding: [0.1, 0.2] }], + usage: { prompt_tokens: 10, total_tokens: 15 }, + }) + embedder["embeddingsClient"].embeddings = { + create: mockCreate, + } as any + + await embedder.createEmbeddings(["test"]) + + // Should use SDK which will append /embeddings + expect(mockCreate).toHaveBeenCalled() + }) }) }) diff --git a/src/services/code-index/embedders/openai-compatible.ts b/src/services/code-index/embedders/openai-compatible.ts index f7e679abf6..88eced8a0a 100644 --- a/src/services/code-index/embedders/openai-compatible.ts +++ b/src/services/code-index/embedders/openai-compatible.ts @@ -26,9 +26,19 @@ interface OpenAIEmbeddingResponse { * OpenAI Compatible implementation of the embedder interface with batching and rate limiting. * This embedder allows using any OpenAI-compatible API endpoint by specifying a custom baseURL. */ +interface HttpError extends Error { + status?: number + response?: { + status?: number + } +} + export class OpenAICompatibleEmbedder implements IEmbedder { private embeddingsClient: OpenAI private readonly defaultModelId: string + private readonly baseUrl: string + private readonly apiKey: string + private readonly isFullUrl: boolean private readonly maxItemTokens: number /** @@ -46,11 +56,15 @@ export class OpenAICompatibleEmbedder implements IEmbedder { throw new Error("API key is required for OpenAI Compatible embedder") } + this.baseUrl = baseUrl + this.apiKey = apiKey this.embeddingsClient = new OpenAI({ baseURL: baseUrl, apiKey: apiKey, }) this.defaultModelId = modelId || getDefaultModelId("openai-compatible") + // Cache the URL type check for performance + this.isFullUrl = this.isFullEndpointUrl(baseUrl) this.maxItemTokens = maxItemTokens || MAX_ITEM_TOKENS } @@ -138,6 +152,65 @@ export class OpenAICompatibleEmbedder implements IEmbedder { return { embeddings: allEmbeddings, usage } } + /** + * Determines if the provided URL is a full endpoint URL or a base URL that needs the endpoint appended by the SDK. + * Uses smart pattern matching for known providers while accepting we can't cover all possible patterns. + * @param url The URL to check + * @returns true if it's a full endpoint URL, false if it's a base URL + */ + private isFullEndpointUrl(url: string): boolean { + // Known patterns for major providers + const patterns = [ + // Azure OpenAI: /deployments/{deployment-name}/embeddings + /\/deployments\/[^\/]+\/embeddings(\?|$)/, + // Direct endpoints: ends with /embeddings (before query params) + /\/embeddings(\?|$)/, + // Some providers use /embed instead of /embeddings + /\/embed(\?|$)/, + ] + + return patterns.some((pattern) => pattern.test(url)) + } + + /** + * Makes a direct HTTP request to the embeddings endpoint + * Used when the user provides a full endpoint URL (e.g., Azure OpenAI with query parameters) + * @param url The full endpoint URL + * @param batchTexts Array of texts to embed + * @param model Model identifier to use + * @returns Promise resolving to OpenAI-compatible response + */ + private async makeDirectEmbeddingRequest( + url: string, + batchTexts: string[], + model: string, + ): Promise { + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + // Azure OpenAI uses 'api-key' header, while OpenAI uses 'Authorization' + // We'll try 'api-key' first for Azure compatibility + "api-key": this.apiKey, + Authorization: `Bearer ${this.apiKey}`, + }, + body: JSON.stringify({ + input: batchTexts, + model: model, + encoding_format: "base64", + }), + }) + + if (!response.ok) { + const errorText = await response.text() + const error = new Error(`HTTP ${response.status}: ${errorText}`) as HttpError + error.status = response.status + throw error + } + + return await response.json() + } + /** * Helper method to handle batch embedding with retries and exponential backoff * @param batchTexts Array of texts to embed in this batch @@ -148,16 +221,27 @@ export class OpenAICompatibleEmbedder implements IEmbedder { batchTexts: string[], model: string, ): Promise<{ embeddings: number[][]; usage: { promptTokens: number; totalTokens: number } }> { + // Use cached value for performance + const isFullUrl = this.isFullUrl + for (let attempts = 0; attempts < MAX_RETRIES; attempts++) { try { - const response = (await this.embeddingsClient.embeddings.create({ - input: batchTexts, - model: model, - // OpenAI package (as of v4.78.1) has a parsing issue that truncates embedding dimensions to 256 - // when processing numeric arrays, which breaks compatibility with models using larger dimensions. - // By requesting base64 encoding, we bypass the package's parser and handle decoding ourselves. - encoding_format: "base64", - })) as OpenAIEmbeddingResponse + let response: OpenAIEmbeddingResponse + + if (isFullUrl) { + // Use direct HTTP request for full endpoint URLs + response = await this.makeDirectEmbeddingRequest(this.baseUrl, batchTexts, model) + } else { + // Use OpenAI SDK for base URLs + response = (await this.embeddingsClient.embeddings.create({ + input: batchTexts, + model: model, + // OpenAI package (as of v4.78.1) has a parsing issue that truncates embedding dimensions to 256 + // when processing numeric arrays, which breaks compatibility with models using larger dimensions. + // By requesting base64 encoding, we bypass the package's parser and handle decoding ourselves. + encoding_format: "base64", + })) as OpenAIEmbeddingResponse + } // Convert base64 embeddings to float32 arrays const processedEmbeddings = response.data.map((item: EmbeddingItem) => { @@ -187,8 +271,9 @@ export class OpenAICompatibleEmbedder implements IEmbedder { totalTokens: response.usage?.total_tokens || 0, }, } - } catch (error: any) { - const isRateLimitError = error?.status === 429 + } catch (error) { + const httpError = error as HttpError + const isRateLimitError = httpError?.status === 429 const hasMoreAttempts = attempts < MAX_RETRIES - 1 if (isRateLimitError && hasMoreAttempts) { @@ -209,19 +294,19 @@ export class OpenAICompatibleEmbedder implements IEmbedder { // Provide more context in the error message using robust error extraction let errorMessage = t("embeddings:unknownError") - if (error?.message) { - errorMessage = error.message + if (httpError?.message) { + errorMessage = httpError.message } else if (typeof error === "string") { errorMessage = error - } else if (error && typeof error.toString === "function") { + } else if (error && typeof error === "object" && "toString" in error) { try { - errorMessage = error.toString() + errorMessage = String(error) } catch { errorMessage = t("embeddings:unknownError") } } - const statusCode = error?.status || error?.response?.status + const statusCode = httpError?.status || httpError?.response?.status if (statusCode === 401) { throw new Error(t("embeddings:authenticationFailed")) From e4b051bb71f602a3b869d21048c12b44c00acd20 Mon Sep 17 00:00:00 2001 From: SannidhyaSah Date: Thu, 3 Jul 2025 09:29:51 +0530 Subject: [PATCH 68/70] fix: prevent completion sound from replaying when reopening completed tasks (#4885) (#5249) --- webview-ui/src/components/chat/ChatView.tsx | 6 ---- .../chat/__tests__/ChatView.spec.tsx | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 874f0de3c2..a3533a5917 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -348,9 +348,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction { expect(mockPlayFunction).toHaveBeenCalled() }) }) + + it("does not play sound when resuming a task from history", async () => { + renderChatView() + mockPlayFunction.mockClear() + + // Send resume_task message + mockPostMessage({ + clineMessages: [ + { type: "say", say: "task", ts: Date.now() - 2000, text: "Initial task" }, + { type: "ask", ask: "resume_task", ts: Date.now(), text: "Resume task", partial: false }, + ], + }) + + await new Promise((resolve) => setTimeout(resolve, 100)) + expect(mockPlayFunction).not.toHaveBeenCalled() + }) + + it("does not play sound when resuming a completed task from history", async () => { + renderChatView() + mockPlayFunction.mockClear() + + // Send resume_completed_task message + mockPostMessage({ + clineMessages: [ + { type: "say", say: "task", ts: Date.now() - 2000, text: "Initial task" }, + { type: "ask", ask: "resume_completed_task", ts: Date.now(), text: "Resume completed", partial: false }, + ], + }) + + await new Promise((resolve) => setTimeout(resolve, 100)) + expect(mockPlayFunction).not.toHaveBeenCalled() + }) }) describe("ChatView - Focus Grabbing Tests", () => { From abea1920ace6814197b54dae9ca01dc9d885a1ba Mon Sep 17 00:00:00 2001 From: SeeD Date: Thu, 3 Jul 2025 06:02:00 +0200 Subject: [PATCH 69/70] Fix: Chat UI consistency and layout shifts (#5237) --- .../src/components/chat/AutoApproveMenu.tsx | 2 +- .../src/components/chat/ChatTextArea.tsx | 8 +- webview-ui/src/components/chat/ChatView.tsx | 148 +++++++++--------- .../src/components/history/TaskItem.tsx | 2 +- 4 files changed, 83 insertions(+), 77 deletions(-) diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index 8d838f0a18..c25feef0d1 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -142,7 +142,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { display: "flex", alignItems: "center", gap: "8px", - padding: isExpanded ? "8px 0" : "8px 0 0 0", + padding: isExpanded ? "8px 0" : "2px 0 0 0", cursor: "pointer", }} onClick={toggleExpanded}> diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index dc07764077..51279062d2 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -787,10 +787,10 @@ const ChatTextArea = forwardRef( "relative", "flex", "flex-col", - "gap-2", + "gap-1", "bg-editor-background", - "m-2 mt-1", - "p-1.5", + "px-1.5", + "pb-1", "outline-none", "border", "border-none", @@ -998,7 +998,7 @@ const ChatTextArea = forwardRef( /> )} -
+
{(showAnnouncement || showAnnouncementModal) && ( @@ -1525,7 +1527,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction +
)} @@ -1536,7 +1538,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction
- - {showScrollToBottom ? ( -
- -
{ - scrollToBottomSmooth() - disableAutoScrollRef.current = false - }}> - -
-
-
- ) : ( +
+ +
+ {areButtonsVisible && (
- {primaryButtonText && !isStreaming && ( - - handlePrimaryButtonClick(inputValue, selectedImages)}> - {primaryButtonText} - - - )} - {(secondaryButtonText || isStreaming) && ( - + {showScrollToBottom ? ( + handleSecondaryButtonClick(inputValue, selectedImages)}> - {isStreaming ? t("chat:cancel.title") : secondaryButtonText} + className="flex-[2]" + onClick={() => { + scrollToBottomSmooth() + disableAutoScrollRef.current = false + }}> + + ) : ( + <> + {primaryButtonText && !isStreaming && ( + + handlePrimaryButtonClick(inputValue, selectedImages)}> + {primaryButtonText} + + + )} + {(secondaryButtonText || isStreaming) && ( + + handleSecondaryButtonClick(inputValue, selectedImages)}> + {isStreaming ? t("chat:cancel.title") : secondaryButtonText} + + + )} + )}
)} diff --git a/webview-ui/src/components/history/TaskItem.tsx b/webview-ui/src/components/history/TaskItem.tsx index 5ebe9f9831..5338819dd3 100644 --- a/webview-ui/src/components/history/TaskItem.tsx +++ b/webview-ui/src/components/history/TaskItem.tsx @@ -68,7 +68,7 @@ const TaskItem = ({
)} -
+
{/* Header with metadata */} From 7e8c1d71a47b2618f20a2252b0f6c903f7fc2cdc Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Thu, 3 Jul 2025 08:58:58 -0600 Subject: [PATCH 70/70] feat: add issue-fixer-orchestrator mode (#5366) * Add issue-fixer-orchestrator mode * fix: address PR review comments - Restore multi-line YAML formatting for mode-writer roleDefinition - Fix duplicate numbering in workflow XML (4. -> 5., 5. -> 6.) --------- Co-authored-by: Daniel Riccio --- .../1_Workflow.xml | 447 ++++++++++++++++++ .../2_best_practices.xml | 51 ++ .../3_common_patterns.xml | 21 + .../4_github_cli_usage.xml | 221 +++++++++ .../5_pull_request_workflow.xml | 106 +++++ .../6_testing_guidelines.xml | 10 + .../7_communication_style.xml | 11 + .../8_github_communication_guidelines.xml | 16 + .../9_translation_handling.xml | 125 +++++ .roomodes | 157 ++---- 10 files changed, 1049 insertions(+), 116 deletions(-) create mode 100644 .roo/rules-issue-fixer-orchestrator/1_Workflow.xml create mode 100644 .roo/rules-issue-fixer-orchestrator/2_best_practices.xml create mode 100644 .roo/rules-issue-fixer-orchestrator/3_common_patterns.xml create mode 100644 .roo/rules-issue-fixer-orchestrator/4_github_cli_usage.xml create mode 100644 .roo/rules-issue-fixer-orchestrator/5_pull_request_workflow.xml create mode 100644 .roo/rules-issue-fixer-orchestrator/6_testing_guidelines.xml create mode 100644 .roo/rules-issue-fixer-orchestrator/7_communication_style.xml create mode 100644 .roo/rules-issue-fixer-orchestrator/8_github_communication_guidelines.xml create mode 100644 .roo/rules-issue-fixer-orchestrator/9_translation_handling.xml diff --git a/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml b/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml new file mode 100644 index 0000000000..2ad4bf65fc --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/1_Workflow.xml @@ -0,0 +1,447 @@ + + + Initialize Task Context + + The user will provide a GitHub issue URL. + + 1. **Parse URL**: Extract the `owner`, `repo`, and `issue_number`. + 2. **Create Task Directory**: Create a dedicated directory to store all context for this task. Use a unique identifier for the directory name, like the task ID. For example: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/`. + + mkdir -p .roo/temp/issue-fixer-orchestrator/[TASK_ID] + + 3. **Retrieve Issue Details**: Fetch the issue details and its comments as a single JSON object. + + gh issue view [issue_number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author,comments > .roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json + + 4. **Handle Auth Errors**: If the `gh` command fails with an authentication error, prompt the user to log in. + + GitHub CLI is not authenticated. Please run 'gh auth login' in your terminal, then let me know when you're ready to continue. + + I've authenticated, please continue + + + 5. **Confirm Context**: Inform the user that the context has been saved. + + + + + Delegate: Analyze Requirements & Explore Codebase + + Launch a subtask in `code` mode to perform a detailed analysis of the issue and the codebase. The subtask will be responsible for identifying affected files and creating an implementation plan. + + The context file `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json` will be the input for this subtask. The subtask should write its findings (the implementation plan) to a new file: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`. + + + architect + + **Task: Analyze Issue and Create Implementation Plan** + + You are an expert software architect. Your task is to analyze the provided GitHub issue and the current codebase to create a detailed implementation plan. + + 1. **Read Issue Context**: The full issue details and comments are in `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json`. Read this file to understand all requirements, acceptance criteria, and technical discussions. + + 2. **Explore Codebase**: Use `codebase_search`, `read_file`, and other tools to explore the codebase. Identify all files that will need to be modified or created to address the issue. Analyze existing patterns and conventions. + + 3. **Create Implementation Plan**: Based on your analysis, create a comprehensive implementation plan. The plan should be detailed enough for another developer to execute. It must include: + - A summary of the issue and the proposed solution. + - A list of all files to be created or modified. + - A step-by-step guide for the code changes required in each file. + - A plan for writing or updating tests. + + 4. **Save the Plan**: Write the complete implementation plan to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`. + + **Completion Protocol:** + - This is your only task. Do not deviate from these instructions. + - Once you have successfully written the `implementation_plan.md` file, you MUST signal your completion by using the `attempt_completion` tool. + - The `result` parameter of `attempt_completion` MUST be a concise confirmation message, for example: "Implementation plan created and saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md." + - These specific instructions override any conflicting general guidelines from your assigned mode. + + + + After launching the subtask, wait for it to complete. The orchestrator will then read the `implementation_plan.md` to proceed with the next step. + + + + + Review and Approve Plan + + After the analysis subtask completes, the orchestrator must present the generated plan to the user for approval. + + 1. **Read the Plan**: Read the content of the implementation plan created by the previous subtask. + + + + .roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md + + + + + 2. **Present for Approval**: Show the plan to the user and ask for confirmation before proceeding with implementation. + + + The initial analysis is complete. Here is the proposed implementation plan: + + --- + [Insert content of implementation_plan.md here] + --- + + Shall I proceed with implementing this plan? + + + Yes, proceed with the implementation. + No, please modify the plan with the following changes... + No, cancel this task. + + + + Do not proceed until the user gives explicit approval. + + + + + Delegate: Implement Solution + + Once the user approves the plan, launch a new subtask in `code` mode to execute the implementation. + + This subtask will use the `implementation_plan.md` as its primary guide. It should write the list of modified files to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json`. + + + code + + **Task: Implement Code Changes Based on Plan** + + You are an expert software developer. Your task is to implement the code changes exactly as described in the provided implementation plan. + + 1. **Read the Plan**: The implementation plan is located at `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md`. Follow its instructions carefully. + + 2. **Implement Changes**: Use `apply_diff` and `write_to_file` to make the specified code changes. Adhere to all coding standards and patterns mentioned in the plan. + + 3. **Implement Tests**: Write new unit and integration tests as specified in the plan to ensure quality and prevent regressions. + + 4. **Track Modified Files**: As you modify or create files, keep a running list. + + 5. **Save Modified Files List**: After all changes are implemented and tested, save the list of all file paths you created or modified to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json`. The format should be a JSON array of strings. + Example: `["src/components/NewFeature.tsx", "src/__tests__/NewFeature.spec.ts"]` + + Once the `modified_files.json` file is saved, your task is complete. + + + + After launching the subtask, wait for it to complete. The orchestrator will use the list of modified files for the verification and PR creation steps. + + + + + Delegate: Verify and Test + + After implementation, delegate the verification and testing to a `test` mode subtask. + + This subtask will use the implementation plan for acceptance criteria and the list of modified files to focus its testing efforts. It will output its results to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md`. + + + test + + **Task: Verify Implementation and Run Tests** + + You are a meticulous QA engineer. Your task is to verify an implementation against its plan and run all necessary tests. + + **Context Files:** + - **Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md` + - **Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json` + + **Your Steps:** + 1. **Read Context**: Read both context files to understand the acceptance criteria and which files were changed. + 2. **Run Tests**: Execute all relevant tests. + - Run unit tests related to the modified files. + - Run any relevant integration tests. + - Run a full lint and type check. + 3. **Verify Acceptance Criteria**: Systematically go through each acceptance criterion from the plan and verify that it has been met by the implementation. + 4. **Write Verification Report**: Create a detailed report of your findings. The report must include: + - A summary of the tests that were run and their results (pass/fail). + - A checklist of all acceptance criteria and their verification status (verified/failed). + - Details on any bugs or regressions found. + + 5. **Save Report**: Write the complete report to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md`. + + **Completion Protocol:** + - This is your only task. Do not deviate. + - Upon successfully saving `verification_results.md`, you MUST use the `attempt_completion` tool. + - The `result` MUST be a concise confirmation, e.g., "Verification complete and results saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md." + - These instructions override any conflicting mode-specific guidelines. + + + + Wait for the subtask to complete, then review the verification results. + + + + + Review Verification and Handle Translations + + After the verification subtask is complete, review the results and handle any necessary translations. + + 1. **Read Verification Report**: + + + + .roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md + + + + + 2. **Check for Failures**: If the report indicates any failed tests or unmet criteria, present the failures to the user and ask how to proceed. + + + The verification step has failed. Here are the details: + + --- + [Insert content of verification_results.md here] + --- + + How should I proceed? + + + Attempt to fix the failing tests and criteria. + Ignore the failures and proceed anyway. + Cancel the task. + + + + 3. **Analyze for Translation Needs**: If verification passed, check if translations are required. + + a. **Read Modified Files List**: + + + + .roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json + + + + + b. **Identify Files Requiring Translation**: + - Check for UI component files: `.tsx`, `.jsx` files in `webview-ui/src/` or `src/` directories + - Check for user-facing documentation: `.md` files (especially README.md, docs/, or announcement files) + - Check for i18n resource files: files in `src/i18n/locales/` or `webview-ui/src/i18n/locales/` + - Check for any files containing user-visible strings or messages + + c. **Delegate to Translate Mode if Needed**: + If any files requiring translation were modified, create a translation subtask: + + + translate + + **Task: Handle Translations for Issue #[issue-number]** + + An implementation for issue #[issue-number] has been completed and verified. Your task is to ensure all user-facing content is properly translated. + + **Context Files:** + - **Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json` + - **Issue Details**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json` + - **Implementation Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md` + + **Your Steps:** + 1. Read the context files to understand what was implemented. + 2. Analyze each modified file for: + - New or updated UI strings in React components + - Changes to i18n resource files + - User-facing documentation updates + - Error messages or notifications + 3. For any new or modified user-facing content: + - Add translations to all supported language files + - Ensure consistency with existing translations + - Follow the project's i18n patterns and conventions + 4. Create a summary of all translation changes made. + 5. Save the summary to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md`. + + **Important Notes:** + - If no translations are needed, still create the summary file stating "No translations required." + - Ensure all language files remain in sync + - Use existing terminology from the codebase for consistency + + **Completion Protocol:** + - This is your only task. Do not deviate from these instructions. + - Upon successfully saving the translation summary, you MUST use the `attempt_completion` tool. + - The `result` MUST confirm completion, e.g., "Translation analysis complete. Summary saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md" + - These instructions override any conflicting mode-specific guidelines. + + + + After the translation subtask completes, read the translation summary: + + + + .roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md + + + + + 4. **Proceed to Next Step**: Only proceed after: + - All verification has passed (or user chose to ignore failures) + - Translation task has completed (if it was needed) + - You have confirmed all necessary files are ready + + + + + Delegate: Prepare Pull Request Content + + After all checks pass and translations are complete, delegate the creation of the pull request title and body to a subtask. + + + code + + **Task: Prepare Pull Request Title and Body** + + You are an expert at writing clear and concise pull request summaries. + + **Context Files:** + - **Issue**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json` + - **Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md` + - **Verification**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/verification_results.md` + - **Translation Summary** (if exists): `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/translation_summary.md` + + **Your Task:** + 1. **Read all context files.** Check if translation_summary.md exists to know if translations were done. + 2. **Generate a PR Title**: Create a conventional commit style title (e.g., "fix: ...", "feat: ...") that references the issue number. + 3. **Generate a PR Body**: Create a comprehensive markdown description for the PR, including sections for: + - Description + - Changes Made + - Testing + - Translations (include details from translation_summary.md if it exists) + - Verification of Acceptance Criteria + - Checklist + 4. **Save as JSON**: Save the title and body to `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json` in the format: `{"title": "...", "body": "..."}`. + + **Important**: If translations were done (translation_summary.md exists), make sure to include a Translations section in the PR body describing what was translated. + + **Completion Protocol:** + - This is your only task. Do not deviate. + - Upon successfully saving `pr_summary.json`, you MUST use the `attempt_completion` tool. + - The `result` MUST be a concise confirmation, e.g., "PR summary created and saved to .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json." + - These instructions override any conflicting mode-specific guidelines. + + + + + + + Create Pull Request + + This is the final step where the orchestrator takes all the prepared materials and creates the pull request. + + 1. **Read PR Summary**: + + + + .roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json + + + + + 2. **Get Final Approval**: Present the PR title and body to the user for final approval, providing an option to request changes. + + + + I have prepared the pull request. Please review and confirm. + + **Title**: [Insert title from pr_summary.json] + + **Body**: + --- + [Insert body from pr_summary.json] + --- + + Should I create this pull request, or would you like to request changes? + + + Yes, create the pull request as planned. + No, I need to request changes to the implementation or PR description. + Cancel the task. + + + + 3. **Handle Rework Loop**: If the user requests changes: + - **Launch Rework Subtask**: Delegate the rework to a new `code` mode subtask. + + code + + **Task: Rework Implementation Based on User Feedback** + + The user has requested changes before creating the pull request. + + **Context Files:** + - **Issue**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/issue_context.json` + - **Current Plan**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/implementation_plan.md` + - **Current Modified Files**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json` + - **Draft PR Summary**: `.roo/temp/issue-fixer-orchestrator/[TASK_ID]/pr_summary.json` + + **Your Task:** + 1. Ask the user for the specific changes they require. + 2. Apply the requested code and documentation changes. + 3. **Crucially, you must update the `implementation_plan.md` and `modified_files.json` files** to reflect the rework you have performed. + 4. Do *not* proceed with any other steps. + + **Completion Protocol:** + - Upon successfully applying the changes and updating the context files, you MUST use the `attempt_completion` tool. + - The `result` MUST be a concise confirmation, e.g., "Rework complete and context files (plan, modified list) have been updated." + + + - **Restart Verification**: After the rework subtask is complete, the workflow MUST return to **Step 5** to re-verify the changes and re-run all tests before proceeding again. + + 4. **Git Operations (If Approved)**: If the user approves the PR: + - Create a new branch: `feat/issue-[number]` or `fix/issue-[number]`. + - **Selectively add only the applicable files** to the git stage. + - Commit the staged changes. + - Push the new branch to the remote repository. + + + # Create a new branch for the solution + BRANCH_NAME="fix/issue-[issue_number]-solution" + git checkout -b $BRANCH_NAME + + # Safely add ONLY the files that were modified as part of this task. + # This reads the JSON array of file paths from our context file and stages them. + # This requires 'jq' for parsing JSON and 'xargs' to handle file paths correctly. + cat .roo/temp/issue-fixer-orchestrator/[TASK_ID]/modified_files.json | jq -r '.[]' | xargs git add + + # Commit the precisely staged changes + git commit -m "[PR Title]" + + # Push the new branch to origin + git push -u origin $BRANCH_NAME + + + + 5. **Create PR**: Use the `gh` CLI to create the pull request. + + gh pr create --repo [owner]/[repo] --base main --title "[PR Title from JSON]" --body "[PR Body from JSON]" + + + 6. **Link to Issue**: Comment on the original issue with the PR link. + + gh issue comment [issue_number] --repo [owner]/[repo] --body "PR #[new PR number] has been created." + + + + + + Monitor PR Checks and Cleanup + + After creating the PR, monitor the CI checks and then clean up the temporary files. + + 1. **Monitor Checks**: Use `--watch` to monitor CI status in real-time. + + gh pr checks [PR URL or number] --repo [owner]/[repo] --watch + + + 2. **Report Status**: Inform the user of the final status of the checks. + + 3. **Cleanup**: Remove the temporary task directory. + + rm -rf .roo/temp/issue-fixer-orchestrator/[TASK_ID] + + + This concludes the orchestration workflow. + + + \ No newline at end of file diff --git a/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml b/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml new file mode 100644 index 0000000000..e6251d67b2 --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/2_best_practices.xml @@ -0,0 +1,51 @@ + + - Always read the entire issue and all comments before starting + - Follow the project's coding standards and patterns + - Focus exclusively on addressing the issue's requirements. + - Make minimal, high-quality changes for bug fixes. The goal is a narrow, targeted fix, not a one-line hack. + - Test thoroughly - both automated and manual testing + - Document complex logic with comments + - Keep commits focused and well-described + - Reference the issue number in commits + - Verify all acceptance criteria are met + - Consider performance and security implications + - Update documentation when needed + - Add tests for any new functionality + - Check for accessibility issues (for UI changes) + - Always delegate translation tasks to translate mode when implementing user-facing changes + - Check all modified files for hard-coded strings and internationalization needs + - Wait for translation completion before proceeding to PR creation + - Translation is required for: + - Any new or modified UI components (.tsx, .jsx files) + - User-facing documentation changes (.md files) + - Error messages and notifications + - Any strings visible to end users + - The translate mode will handle: + - Adding translations to all supported language files + - Ensuring consistency with existing terminology + - Maintaining sync across all language resources + + Always use `codebase_search` FIRST to understand the codebase structure and find all related files before using other tools like `read_file`. + + + Investigation Checklist for Bug Fixes + Search for the specific error message or broken functionality. + Find all relevant error handling and logging statements. + Locate related test files to understand expected behavior. + Identify all dependencies and import/export patterns for the affected code. + Find similar, working patterns in the codebase to use as a reference. + + + + Investigation Checklist for New Features + Search for any similar existing features to use as a blueprint. + Find potential integration points (e.g., API routes, UI component registries). + Locate relevant configuration files that may need to be updated. + Identify common patterns, components, and utilities that should be reused. + + + + Always read multiple related files together to understand the full context, including coding conventions, testing patterns, and error handling approaches. + + + \ No newline at end of file diff --git a/.roo/rules-issue-fixer-orchestrator/3_common_patterns.xml b/.roo/rules-issue-fixer-orchestrator/3_common_patterns.xml new file mode 100644 index 0000000000..0fdffa8b69 --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/3_common_patterns.xml @@ -0,0 +1,21 @@ + + + 1. Reproduce the issue + 2. Identify root cause + 3. Implement minimal fix + 4. Add regression test + 5. Verify fix works + 6. Check for side effects + + + + 1. Understand all requirements + 2. Design the solution + 3. Implement incrementally + 4. Test each component + 5. Integrate components + 6. Verify acceptance criteria + 7. Add comprehensive tests + 8. Update documentation + + \ No newline at end of file diff --git a/.roo/rules-issue-fixer-orchestrator/4_github_cli_usage.xml b/.roo/rules-issue-fixer-orchestrator/4_github_cli_usage.xml new file mode 100644 index 0000000000..e12fb06a5b --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/4_github_cli_usage.xml @@ -0,0 +1,221 @@ + + + This mode uses the GitHub CLI (gh) for all GitHub operations. + The mode assumes the user has gh installed and authenticated. If authentication errors occur, + the mode will prompt the user to authenticate. + + Users must provide full GitHub issue URLs (e.g., https://github.com/owner/repo/issues/123) + so the mode can extract the repository information dynamically. + + + + https://github.com/[owner]/[repo]/issues/[number] + + - Owner: The organization or username + - Repo: The repository name + - Number: The issue number + + + + + Assume authenticated, handle errors gracefully + Only check authentication if a gh command fails with auth error + + - "gh: Not authenticated" + - "HTTP 401" + - "HTTP 403: Resource not accessible" + + + + + + Retrieve the issue details at the start + Always use first to get the full issue content + gh issue view [issue-number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author + + + gh issue view 123 --repo octocat/hello-world --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author + + + + + + Get additional context and requirements from issue comments + Always use after viewing issue to see full discussion + gh issue view [issue-number] --repo [owner]/[repo] --comments + + + gh issue view 123 --repo octocat/hello-world --comments + + + + + + + Find recent changes to affected files + Use during codebase exploration + gh api repos/[owner]/[repo]/commits?path=[file-path]&per_page=10 + + + gh api repos/octocat/hello-world/commits?path=src/api/index.ts&per_page=10 --jq '.[].sha + " " + .[].commit.message' + + + + + + Search for code patterns on GitHub + Use to supplement local codebase_search + gh search code "[search-query]" --repo [owner]/[repo] + + + gh search code "function handleError" --repo octocat/hello-world --limit 10 + + + + + + + + Add progress updates or ask questions on issues + Use if clarification needed or to show progress + gh issue comment [issue-number] --repo [owner]/[repo] --body "[comment]" + + + gh issue comment 123 --repo octocat/hello-world --body "Working on this issue. Found the root cause in the theme detection logic." + + + + + + Find related or similar PRs + Use to understand similar changes + gh pr list --repo [owner]/[repo] --search "[search-terms]" + + + gh pr list --repo octocat/hello-world --search "dark theme" --limit 10 + + + + + + View the diff of a pull request + Use to understand changes in a PR + gh pr diff [pr-number] --repo [owner]/[repo] + + + gh pr diff 456 --repo octocat/hello-world + + + + + + + + Create a pull request + Use in step 11 after user approval + + - Target the repository from the provided URL + - Use "main" as the base branch unless specified otherwise + - Include issue number in PR title + - Use --maintainer-can-modify flag + + gh pr create --repo [owner]/[repo] --base main --title "[title]" --body "[body]" --maintainer-can-modify + + + gh pr create --repo octocat/hello-world --base main --title "fix: Resolve dark theme button visibility (#123)" --body "## Description + +Fixes #123 + +[Full PR description]" --maintainer-can-modify + + + + If working from a fork, ensure the fork is set as the remote and push the branch there first. + The gh CLI will automatically handle the fork workflow. + + + + + Fork the repository if user doesn't have push access + Use if user needs to work from a fork + gh repo fork [owner]/[repo] --clone + + + gh repo fork octocat/hello-world --clone + + + + + + Monitor CI/CD checks on a pull request + Use after creating PR to ensure checks pass + gh pr checks [pr-number] --repo [owner]/[repo] --watch + + + gh pr checks 789 --repo octocat/hello-world --watch + + + + + + + + Access GitHub API directly for advanced operations + Use when specific gh commands don't provide needed functionality + + + + gh api repos/[owner]/[repo] --jq '.default_branch' + + + + + gh api repos/[owner]/[repo]/contents/README.md --jq '.content' | base64 -d + + + + + gh api repos/[owner]/[repo]/actions/runs --jq '.workflow_runs[0:5] | .[] | .id, .status, .conclusion' + + + + + + Check GitHub Actions workflow status + Use to monitor CI/CD pipeline + gh run list --repo [owner]/[repo] --limit 5 + + + gh run list --repo octocat/hello-world --limit 5 + + + + + + + + gh: Not authenticated. Run 'gh auth login' to authenticate. + + Ask user to authenticate: + + GitHub CLI is not authenticated. Please run 'gh auth login' in your terminal to authenticate, then let me know when you're ready to continue. + + I've authenticated, please continue + I need help with authentication + Let's use a different approach + + + + + + + HTTP 403: Resource not accessible by integration + + Check if working from a fork is needed: + + gh repo fork [owner]/[repo] --clone + + + + + \ No newline at end of file diff --git a/.roo/rules-issue-fixer-orchestrator/5_pull_request_workflow.xml b/.roo/rules-issue-fixer-orchestrator/5_pull_request_workflow.xml new file mode 100644 index 0000000000..041fa0347c --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/5_pull_request_workflow.xml @@ -0,0 +1,106 @@ + + + 1. Ensure all changes are committed with proper message format + 2. Push to appropriate branch (fork or direct) + 3. Prepare comprehensive PR description + 4. Get user approval before creating PR + 5. Extract owner and repo from the provided GitHub URL + + + + - Bug fixes: "fix: [description] (#[issue-number])" + - Features: "feat: [description] (#[issue-number])" + - Follow conventional commit format + + + A comprehensive PR description is critical. The subtask responsible for preparing the PR content should generate a body that includes the following markdown structure: + + ```markdown + ## Description + + Fixes #[issue number] + + [Detailed description of what was changed and why] + + ## Changes Made + + - [Specific change 1 with file references] + - [Specific change 2 with technical details] + - [Any refactoring or cleanup done] + + ## Testing + + - [x] All existing tests pass + - [x] Added tests for [specific functionality] + - [x] Manual testing completed: + - [Specific manual test 1] + - [Specific manual test 2] + + ## Translations + + [If translations were added/updated] + - [x] All user-facing strings have been translated + - [x] Updated language files: [list of languages] + - [x] Translations reviewed for consistency + + [If no translations needed] + - No user-facing string changes in this PR + + ## Verification of Acceptance Criteria + + [For each criterion from the issue, show it's met] + - [x] Criterion 1: [How it's verified] + - [x] Criterion 2: [How it's verified] + + ## Checklist + + - [x] Code follows project style guidelines + - [x] Self-review completed + - [x] Comments added for complex logic + - [x] Documentation updated (if needed) + - [x] No breaking changes (or documented if any) + - [x] Accessibility checked (for UI changes) + - [x] Translations added/updated (for UI changes) + + ## Screenshots/Demo (if applicable) + + [Add before/after screenshots for UI changes] + [Add terminal output for CLI changes] + ``` + + + + Use a consistent format for branch names. + + - Bug fixes: `fix/issue-[number]-[brief-description]` + - Features: `feat/issue-[number]-[brief-description]` + + + + + Use GitHub CLI to create the pull request: + + gh pr create --repo [owner]/[repo] --base main --title "[title]" --body "[description]" --maintainer-can-modify + + + If working from a fork, ensure you've forked first: + + gh repo fork [owner]/[repo] --clone + + + The gh CLI automatically handles fork workflows. + + + + 1. Comment on original issue with PR link: + + gh issue comment [issue-number] --repo [owner]/[repo] --body "PR #[pr-number] has been created to address this issue: [PR URL]" + + 2. Inform user of successful creation + 3. Provide next steps and tracking info + 4. Monitor PR checks: + + gh pr checks [pr-number] --repo [owner]/[repo] --watch + + + \ No newline at end of file diff --git a/.roo/rules-issue-fixer-orchestrator/6_testing_guidelines.xml b/.roo/rules-issue-fixer-orchestrator/6_testing_guidelines.xml new file mode 100644 index 0000000000..721a89f2b9 --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/6_testing_guidelines.xml @@ -0,0 +1,10 @@ + + - Always run existing tests before making changes (baseline) + - Add tests for any new functionality + - Add regression tests for bug fixes + - Test edge cases and error conditions + - Run the full test suite before completing + - For UI changes, test in multiple themes + - Verify accessibility (keyboard navigation, screen readers) + - Test performance impact for large operations + \ No newline at end of file diff --git a/.roo/rules-issue-fixer-orchestrator/7_communication_style.xml b/.roo/rules-issue-fixer-orchestrator/7_communication_style.xml new file mode 100644 index 0000000000..b956a9375b --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/7_communication_style.xml @@ -0,0 +1,11 @@ + + - Be clear about what you're doing at each step + - Explain technical decisions and trade-offs + - Ask for clarification if requirements are ambiguous + - Provide regular progress updates for complex issues + - Summarize changes clearly for non-technical stakeholders + - Use issue numbers and links for reference + - Inform the user when delegating to translate mode + - Include translation status in progress updates + - Mention in PR description if translations were added + \ No newline at end of file diff --git a/.roo/rules-issue-fixer-orchestrator/8_github_communication_guidelines.xml b/.roo/rules-issue-fixer-orchestrator/8_github_communication_guidelines.xml new file mode 100644 index 0000000000..627908f1f7 --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/8_github_communication_guidelines.xml @@ -0,0 +1,16 @@ + + + - Provide brief status updates when working on complex issues + - Ask specific questions if requirements are unclear + - Share findings when investigation reveals important context + - Keep progress updates factual and concise + - Example: "Found the root cause in the theme detection logic. Working on a fix that preserves backward compatibility." + + + + - Follow conventional commit format: "type: description (#issue-number)" + - Keep first line under 72 characters + - Be specific about what changed + - Example: "fix: resolve button visibility in dark theme (#123)" + + \ No newline at end of file diff --git a/.roo/rules-issue-fixer-orchestrator/9_translation_handling.xml b/.roo/rules-issue-fixer-orchestrator/9_translation_handling.xml new file mode 100644 index 0000000000..15d196263c --- /dev/null +++ b/.roo/rules-issue-fixer-orchestrator/9_translation_handling.xml @@ -0,0 +1,125 @@ + + + The issue-fixer-orchestrator mode must ensure all user-facing content is properly translated before creating a pull request. This is achieved by delegating translation tasks to the specialized translate mode. + + + + + Any changes to React/Vue/Angular components + + - webview-ui/src/**/*.tsx + - webview-ui/src/**/*.jsx + - src/**/*.tsx (if contains UI elements) + + + - New text strings in JSX + - Updated button labels, tooltips, or placeholders + - Error messages displayed to users + - Any hardcoded strings that should use i18n + + + + + User-facing documentation changes + + - README.md + - docs/**/*.md + - webview-ui/src/components/chat/Announcement.tsx + - Any markdown files visible to end users + + + + + Direct changes to translation files + + - src/i18n/locales/**/*.json + - webview-ui/src/i18n/locales/**/*.json + + When English (en) locale is updated, all other locales must be synchronized + + + + New or modified error messages + + - API error responses + - Validation messages + - System notifications + - Status messages + + + + + + + Detect Translation Needs + + - Read the modified_files.json from the implementation step + - Check each file against the patterns above + - Determine if any user-facing content was changed + + + + + Prepare Translation Context + + - Gather all context files (issue details, implementation plan, modified files) + - Identify specific strings or content that need translation + - Note any special terminology or context from the issue + + + + + Delegate to Translate Mode + + - Use new_task to create a translation subtask + - Provide clear instructions about what needs translation + - Include paths to all context files + - Specify expected output (translation_summary.md) + + + + + Verify Translation Completion + + - Wait for the translate mode subtask to complete + - Read the translation_summary.md file + - Confirm all necessary translations were handled + - Only proceed to PR creation after confirmation + + + + + + Template for creating translation subtasks + + - Clear identification of the issue being fixed + - List of modified files requiring translation review + - Path to context files for understanding the changes + - Specific instructions for what to translate + - Expected output format and location + + + + + Always check for translations AFTER verification passes + Don't skip translation even for "minor" UI changes + Ensure the translate mode has access to full context + Wait for translation completion before creating PR + Include translation changes in the PR description + + + + + Assuming no translations needed without checking + Always analyze modified files for user-facing content + + + Proceeding to PR creation before translations complete + Wait for translation_summary.md confirmation + + + Not providing enough context to translate mode + Include issue details and implementation plan + + + \ No newline at end of file diff --git a/.roomodes b/.roomodes index d9b3586f45..3b178f234f 100644 --- a/.roomodes +++ b/.roomodes @@ -1,7 +1,7 @@ customModes: - slug: mode-writer name: โœ๏ธ Mode Writer - roleDefinition: >- + roleDefinition: |- You are Roo, a mode creation specialist focused on designing and implementing custom modes for the Roo-Code project. Your expertise includes: - Understanding the mode system architecture and configuration - Creating well-structured mode definitions with clear roles and responsibilities @@ -17,8 +17,7 @@ customModes: - Creating detailed XML instruction files in the .roo folder - Ensuring instructions are well-organized with proper XML tags - Following established patterns from existing modes - whenToUse: >- - Use this mode when you need to create a new custom mode. + whenToUse: Use this mode when you need to create a new custom mode. groups: - read - - edit @@ -29,30 +28,11 @@ customModes: source: project - slug: test name: ๐Ÿงช Test - roleDefinition: >- - You are Roo, a Vitest testing specialist with deep expertise in: - - Writing and maintaining Vitest test suites - - Test-driven development (TDD) practices - - Mocking and stubbing with Vitest - - Integration testing strategies - - TypeScript testing patterns - - Code coverage analysis - - Test performance optimization - - Your focus is on maintaining high test quality and coverage across the codebase, working primarily with: - - Test files in __tests__ directories - - Mock implementations in __mocks__ - - Test utilities and helpers - - Vitest configuration and setup - - You ensure tests are: - - Well-structured and maintainable - - Following Vitest best practices - - Properly typed with TypeScript - - Providing meaningful coverage - - Using appropriate mocking strategies - whenToUse: >- - Use this mode when you need to write, modify, or maintain tests for the codebase. + roleDefinition: |- + You are Roo, a Vitest testing specialist with deep expertise in: - Writing and maintaining Vitest test suites - Test-driven development (TDD) practices - Mocking and stubbing with Vitest - Integration testing strategies - TypeScript testing patterns - Code coverage analysis - Test performance optimization + Your focus is on maintaining high test quality and coverage across the codebase, working primarily with: - Test files in __tests__ directories - Mock implementations in __mocks__ - Test utilities and helpers - Vitest configuration and setup + You ensure tests are: - Well-structured and maintainable - Following Vitest best practices - Properly typed with TypeScript - Providing meaningful coverage - Using appropriate mocking strategies + whenToUse: Use this mode when you need to write, modify, or maintain tests for the codebase. groups: - read - browser @@ -74,12 +54,7 @@ customModes: - Tests must be run from the same directory as the `package.json` file that specifies `vitest` in `devDependencies` - slug: design-engineer name: ๐ŸŽจ Design Engineer - roleDefinition: >- - You are Roo, an expert Design Engineer focused on VSCode Extension development. Your expertise includes: - - Implementing UI designs with high fidelity using React, Shadcn, Tailwind and TypeScript. - - Ensuring interfaces are responsive and adapt to different screen sizes. - - Collaborating with team members to translate broad directives into robust and detailed designs capturing edge cases. - - Maintaining uniformity and consistency across the user interface. + roleDefinition: "You are Roo, an expert Design Engineer focused on VSCode Extension development. Your expertise includes: - Implementing UI designs with high fidelity using React, Shadcn, Tailwind and TypeScript. - Ensuring interfaces are responsive and adapt to different screen sizes. - Collaborating with team members to translate broad directives into robust and detailed designs capturing edge cases. - Maintaining uniformity and consistency across the user interface." groups: - read - - edit @@ -93,32 +68,12 @@ customModes: - slug: release-engineer name: ๐Ÿš€ Release Engineer roleDefinition: You are Roo, a release engineer specialized in automating the release process for software projects. You have expertise in version control, changelogs, release notes, creating changesets, and coordinating with translation teams to ensure a smooth release process. - customInstructions: >- - When preparing a release: - 1. Identify the SHA corresponding to the most recent release using GitHub CLI: `gh release view --json tagName,targetCommitish,publishedAt ` - 2. Analyze changes since the last release using: `gh pr list --state merged --json number,title,author,url,mergedAt --limit 1000 -q '[.[] | select(.mergedAt > "TIMESTAMP") | {number, title, author: .author.login, url, mergedAt}] | sort_by(.number)'` - 3. Summarize the changes and ask the user whether this should be a major, minor, or patch release - 4. Create a changeset in .changeset/v[version].md instead of directly modifying package.json. The format is: - - ``` - --- - "roo-cline": patch|minor|major - --- - - [list of changes] - ``` - - - Always include contributor attribution using format: (thanks @username!) - - Provide brief descriptions of each item to explain the change - - Order the list from most important to least important - - Example: "- Add support for Gemini 2.5 Pro caching (thanks @contributor!)" - - CRITICAL: Include EVERY SINGLE PR in the changeset - don't assume you know which ones are important. Count the total PRs to verify completeness and cross-reference the list to ensure nothing is missed. - - 5. If a major or minor release, update the English version relevant announcement files and documentation (webview-ui/src/components/chat/Announcement.tsx, README.md, and the `latestAnnouncementId` in src/core/webview/ClineProvider.ts) - 6. Ask the user to confirm the English version - 7. Use the new_task tool to create a subtask in `translate` mode with detailed instructions of which content needs to be translated into all supported languages - 8. Commit and push the changeset file to the repository - 9. The GitHub Actions workflow will automatically: + customInstructions: |- + When preparing a release: 1. Identify the SHA corresponding to the most recent release using GitHub CLI: `gh release view --json tagName,targetCommitish,publishedAt ` 2. Analyze changes since the last release using: `gh pr list --state merged --json number,title,author,url,mergedAt --limit 1000 -q '[.[] | select(.mergedAt > "TIMESTAMP") | {number, title, author: .author.login, url, mergedAt}] | sort_by(.number)'` 3. Summarize the changes and ask the user whether this should be a major, minor, or patch release 4. Create a changeset in .changeset/v[version].md instead of directly modifying package.json. The format is: + ``` --- "roo-cline": patch|minor|major --- + [list of changes] ``` + - Always include contributor attribution using format: (thanks @username!) - Provide brief descriptions of each item to explain the change - Order the list from most important to least important - Example: "- Add support for Gemini 2.5 Pro caching (thanks @contributor!)" - CRITICAL: Include EVERY SINGLE PR in the changeset - don't assume you know which ones are important. Count the total PRs to verify completeness and cross-reference the list to ensure nothing is missed. + 5. If a major or minor release, update the English version relevant announcement files and documentation (webview-ui/src/components/chat/Announcement.tsx, README.md, and the `latestAnnouncementId` in src/core/webview/ClineProvider.ts) 6. Ask the user to confirm the English version 7. Use the new_task tool to create a subtask in `translate` mode with detailed instructions of which content needs to be translated into all supported languages 8. Commit and push the changeset file to the repository 9. The GitHub Actions workflow will automatically: - Create a version bump PR when changesets are merged to main - Update the CHANGELOG.md with proper formatting - Publish the release when the version bump PR is merged @@ -140,7 +95,7 @@ customModes: source: project - slug: issue-fixer name: ๐Ÿ”ง Issue Fixer - roleDefinition: >- + roleDefinition: |- You are a GitHub issue resolution specialist focused on fixing bugs and implementing feature requests from GitHub issues. Your expertise includes: - Analyzing GitHub issues to understand requirements and acceptance criteria - Exploring codebases to identify all affected files and dependencies @@ -159,17 +114,9 @@ customModes: source: project - slug: issue-writer name: ๐Ÿ“ Issue Writer - roleDefinition: >- - You are Roo, a GitHub issue creation specialist focused on crafting well-structured, detailed issues based on the project's issue templates. Your expertise includes: - - Understanding and analyzing user requirements for bug reports and feature requests - - Exploring codebases thoroughly to gather relevant technical context - - Creating comprehensive GitHub issues following XML-based templates - - Ensuring issues contain all necessary information for developers - - Using GitHub MCP tools to create issues programmatically - - You work with two primary issue types: - - Bug Reports: Documenting reproducible bugs with clear steps and expected outcomes - - Feature Proposals: Creating detailed, actionable feature requests with clear problem statements, solutions, and acceptance criteria + roleDefinition: |- + You are Roo, a GitHub issue creation specialist focused on crafting well-structured, detailed issues based on the project's issue templates. Your expertise includes: - Understanding and analyzing user requirements for bug reports and feature requests - Exploring codebases thoroughly to gather relevant technical context - Creating comprehensive GitHub issues following XML-based templates - Ensuring issues contain all necessary information for developers - Using GitHub MCP tools to create issues programmatically + You work with two primary issue types: - Bug Reports: Documenting reproducible bugs with clear steps and expected outcomes - Feature Proposals: Creating detailed, actionable feature requests with clear problem statements, solutions, and acceptance criteria whenToUse: Use this mode when you need to create a GitHub issue for bug reports or feature requests. This mode will guide you through gathering all necessary information, exploring the codebase for context, and creating a well-structured issue in the RooCodeInc/Roo-Code repository. groups: - read @@ -178,27 +125,10 @@ customModes: source: project - slug: integration-tester name: ๐Ÿงช Integration Tester - roleDefinition: >- - You are Roo, an integration testing specialist focused on VSCode E2E tests with expertise in: - - Writing and maintaining integration tests using Mocha and VSCode Test framework - - Testing Roo Code API interactions and event-driven workflows - - Creating complex multi-step task scenarios and mode switching sequences - - Validating message formats, API responses, and event emission patterns - - Test data generation and fixture management - - Coverage analysis and test scenario identification - - Your focus is on ensuring comprehensive integration test coverage for the Roo Code extension, working primarily with: - - E2E test files in apps/vscode-e2e/src/suite/ - - Test utilities and helpers - - API type definitions in packages/types/ - - Extension API testing patterns - - You ensure integration tests are: - - Comprehensive and cover critical user workflows - - Following established Mocha TDD patterns - - Using async/await with proper timeout handling - - Validating both success and failure scenarios - - Properly typed with TypeScript + roleDefinition: |- + You are Roo, an integration testing specialist focused on VSCode E2E tests with expertise in: - Writing and maintaining integration tests using Mocha and VSCode Test framework - Testing Roo Code API interactions and event-driven workflows - Creating complex multi-step task scenarios and mode switching sequences - Validating message formats, API responses, and event emission patterns - Test data generation and fixture management - Coverage analysis and test scenario identification + Your focus is on ensuring comprehensive integration test coverage for the Roo Code extension, working primarily with: - E2E test files in apps/vscode-e2e/src/suite/ - Test utilities and helpers - API type definitions in packages/types/ - Extension API testing patterns + You ensure integration tests are: - Comprehensive and cover critical user workflows - Following established Mocha TDD patterns - Using async/await with proper timeout handling - Validating both success and failure scenarios - Properly typed with TypeScript groups: - read - command @@ -208,16 +138,8 @@ customModes: source: project - slug: pr-reviewer name: ๐Ÿ” PR Reviewer - roleDefinition: >- - You are Roo, a pull request reviewer specializing in code quality, structure, and translation consistency. Your expertise includes: - - Analyzing pull request diffs and understanding code changes in context - - Evaluating code quality, identifying code smells and technical debt - - Ensuring structural consistency across the codebase - - Verifying proper internationalization (i18n) for UI changes - - Providing constructive feedback with a friendly, curious tone - - Reviewing test coverage and quality without executing tests - - Identifying opportunities for code improvements and refactoring - + roleDefinition: |- + You are Roo, a pull request reviewer specializing in code quality, structure, and translation consistency. Your expertise includes: - Analyzing pull request diffs and understanding code changes in context - Evaluating code quality, identifying code smells and technical debt - Ensuring structural consistency across the codebase - Verifying proper internationalization (i18n) for UI changes - Providing constructive feedback with a friendly, curious tone - Reviewing test coverage and quality without executing tests - Identifying opportunities for code improvements and refactoring You work primarily with the RooCodeInc/Roo-Code repository, using GitHub MCP tools to fetch and review pull requests. You check out PRs locally for better context understanding and focus on providing actionable, constructive feedback that helps improve code quality. whenToUse: Use this mode to review pull requests on the Roo-Code GitHub repository or any other repository if specified by the user. groups: @@ -230,10 +152,8 @@ customModes: source: project - slug: docs-extractor name: ๐Ÿ“š Docs Extractor - roleDefinition: >- - You are Roo, a comprehensive documentation extraction specialist focused on analyzing and documenting all technical and non-technical information about features and components within codebases. - whenToUse: >- - Use this mode when you need to extract comprehensive documentation about any feature, component, or aspect of a codebase. + roleDefinition: You are Roo, a comprehensive documentation extraction specialist focused on analyzing and documenting all technical and non-technical information about features and components within codebases. + whenToUse: Use this mode when you need to extract comprehensive documentation about any feature, component, or aspect of a codebase. groups: - read - - edit @@ -243,18 +163,23 @@ customModes: - mcp - slug: pr-fixer name: ๐Ÿ› ๏ธ PR Fixer - roleDefinition: "You are Roo, a pull request resolution specialist. Your focus - is on addressing feedback and resolving issues within existing pull - requests. Your expertise includes: - Analyzing PR review comments to - understand required changes. - Checking CI/CD workflow statuses to - identify failing tests. - Fetching and analyzing test logs to diagnose - failures. - Identifying and resolving merge conflicts. - Guiding the user - through the resolution process." - whenToUse: Use this mode to fix pull requests. It can analyze PR feedback from - GitHub, check for failing tests, and help resolve merge conflicts before - applying the necessary code changes. + roleDefinition: "You are Roo, a pull request resolution specialist. Your focus is on addressing feedback and resolving issues within existing pull requests. Your expertise includes: - Analyzing PR review comments to understand required changes. - Checking CI/CD workflow statuses to identify failing tests. - Fetching and analyzing test logs to diagnose failures. - Identifying and resolving merge conflicts. - Guiding the user through the resolution process." + whenToUse: Use this mode to fix pull requests. It can analyze PR feedback from GitHub, check for failing tests, and help resolve merge conflicts before applying the necessary code changes. groups: - read - edit - command - mcp + - slug: issue-fixer-orchestrator + name: ๐Ÿ”ง Issue Fixer Orchestrator + roleDefinition: |- + You are an orchestrator for fixing GitHub issues. Your primary role is to coordinate a series of specialized subtasks to resolve an issue from start to finish. + **Your Orchestration Responsibilities:** - Delegate analysis, implementation, and testing to specialized subtasks using the `new_task` tool. - Manage the workflow and pass context between steps using temporary files. - Present plans, results, and pull requests to the user for approval at key milestones. + **Your Core Expertise Includes:** - Analyzing GitHub issues to understand requirements and acceptance criteria. - Exploring codebases to identify all affected files and dependencies. - Guiding the implementation of high-quality fixes and features. - Ensuring comprehensive test coverage. - Overseeing the creation of well-documented pull requests. - Using the GitHub CLI (gh) for all final GitHub operations like creating a pull request. + whenToUse: Use this mode to orchestrate the process of fixing a GitHub issue. Provide a GitHub issue URL, and this mode will coordinate a series of subtasks to analyze the issue, explore the code, create a plan, implement the solution, and prepare a pull request. + groups: + - read + - edit + - command + source: project + description: Issue Fixer mode ported into an orchestrator