diff --git a/.roo/rules-merge-resolver/1_workflow.xml b/.roo/rules-merge-resolver/1_workflow.xml index 2f0d1162f6..a63809db70 100644 --- a/.roo/rules-merge-resolver/1_workflow.xml +++ b/.roo/rules-merge-resolver/1_workflow.xml @@ -30,13 +30,12 @@ gh pr checkout [PR_NUMBER] --force git fetch origin main - GIT_EDITOR=true git rebase origin/main + git rebase origin/main
Force checkout the PR branch to ensure clean state Fetch the latest main branch Attempt to rebase onto main to reveal conflicts - Use GIT_EDITOR=true to ensure non-interactive rebase
@@ -109,8 +108,8 @@ - GIT_EDITOR=true git rebase origin/main - Rebase current branch onto main to reveal conflicts (non-interactive) + git rebase origin/main + Rebase current branch onto main to reveal conflicts @@ -134,20 +133,6 @@ - - GIT_EDITOR=true git rebase --continue - Continue rebase after resolving conflicts (non-interactive) - - - - - - true - Set to 'true' (a no-op command) to prevent interactive prompts during rebase operations - Prefix git rebase commands with GIT_EDITOR=true to ensure non-interactive execution - - - All merge conflicts have been resolved Resolved files have been staged diff --git a/.roo/rules-merge-resolver/3_tool_usage.xml b/.roo/rules-merge-resolver/3_tool_usage.xml index 30e7495574..35f3b5da75 100644 --- a/.roo/rules-merge-resolver/3_tool_usage.xml +++ b/.roo/rules-merge-resolver/3_tool_usage.xml @@ -26,8 +26,6 @@ Chain git commands with && for efficiency Use --format options for structured output Capture command output for parsing - Use GIT_EDITOR=true for non-interactive git rebase operations - Set environment variables inline to avoid prompts during automation @@ -48,7 +46,7 @@ Rebase onto main to reveal conflicts - GIT_EDITOR=true git rebase origin/main + git rebase origin/main @@ -73,7 +71,7 @@ Continue rebase after resolution - GIT_EDITOR=true git rebase --continue + git rebase --continue @@ -154,7 +152,7 @@ const config = { execute_command - Get PR info with gh CLI execute_command - Checkout PR with gh pr checkout --force execute_command - Fetch origin main - execute_command - Rebase onto origin/main with GIT_EDITOR=true + execute_command - Rebase onto origin/main execute_command - Check for conflicts with git status @@ -180,22 +178,13 @@ const config = { execute_command - Check all conflicts resolved - execute_command - Continue rebase with GIT_EDITOR=true git rebase --continue + execute_command - Continue rebase with git rebase --continue execute_command - Verify clean status - - Git commands waiting for interactive input - - Use GIT_EDITOR=true to bypass editor prompts - Set GIT_SEQUENCE_EDITOR=true for sequence editing - Consider --no-edit flag for commit operations - - - Rebase completes without conflicts @@ -236,42 +225,4 @@ const config = { - - - - Ensuring git operations run without requiring user interaction is critical - for automated conflict resolution. The mode uses environment variables to - bypass interactive prompts. - - - - - Set to 'true' (a no-op command) to skip editor prompts - GIT_EDITOR=true git rebase --continue - During rebase operations that would normally open an editor - - - - Skip interactive rebase todo editing - GIT_SEQUENCE_EDITOR=true git rebase -i HEAD~3 - When interactive rebase is triggered but no editing needed - - - - Use flags to avoid interactive prompts - - git commit --no-edit (use existing message) - git merge --no-edit (skip merge message editing) - git cherry-pick --no-edit (keep original message) - - - - - - Always test commands locally first to identify potential prompts - Combine environment variables when multiple editors might be invoked - Document why non-interactive mode is used in comments - Have fallback strategies if automation fails - - \ No newline at end of file diff --git a/.roo/rules-merge-resolver/4_complete_example.xml b/.roo/rules-merge-resolver/4_complete_example.xml index 32b2bf344b..dae8587997 100644 --- a/.roo/rules-merge-resolver/4_complete_example.xml +++ b/.roo/rules-merge-resolver/4_complete_example.xml @@ -54,7 +54,7 @@ From github.com:user/repo -GIT_EDITOR=true git rebase origin/main +git rebase origin/main ]]> -GIT_EDITOR=true git rebase --continue +git rebase --continue ]]> Use git blame and commit messages to understand the history Combine non-conflicting improvements when possible Prioritize bugfixes while accommodating refactors - Use GIT_EDITOR=true to ensure non-interactive rebase operations - Complete the rebase process with GIT_EDITOR=true git rebase --continue + Complete the rebase process with git rebase --continue Validate that both sets of changes work together \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0af79a7454..e8e06ecd4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,40 +1,5 @@ # Roo Code Changelog -## [3.28.1] - 2025-09-11 - -![3.28.1 Release - Kangaroo riding rocket to the clouds](/releases/3.28.1-release.png) - -- Announce Roo Code Cloud! -- Add cloud task button for opening tasks in Roo Code Cloud (thanks @app/roomote!) -- Make Posthog telemetry the default (thanks @mrubens!) -- Show notification when the checkpoint initialization fails (thanks @app/roomote!) -- Bust cache in generated image preview (thanks @mrubens!) -- Fix: Center active mode in selector dropdown on open (#7882 by @hannesrudolph, PR by @app/roomote) -- Fix: Preserve first message during conversation condensing (thanks @daniel-lxs!) - -## [3.28.0] - 2025-09-10 - -![3.28.0 Release - Continue tasks in Roo Code Cloud](/releases/3.28.0-release.png) - -- feat: Continue tasks in Roo Code Cloud (thanks @brunobergher!) -- feat: Support connecting to Cloud without redirect handling (thanks @mrubens!) -- feat: Add toggle to control task syncing to Cloud (thanks @jr!) -- feat: Add click-to-edit, ESC-to-cancel, and fix padding consistency for chat messages (#7788 by @hannesrudolph, PR by @app/roomote) -- feat: Make reasoning more visible (thanks @app/roomote!) -- fix: Fix Groq context window display (thanks @mrubens!) -- fix: Add GIT_EDITOR env var to merge-resolver mode for non-interactive rebase (thanks @daniel-lxs!) -- fix: Resolve chat message edit/delete duplication issues (thanks @daniel-lxs!) -- fix: Reduce CodeBlock button z-index to prevent overlap with popovers (#7703 by @A0nameless0man, PR by @daniel-lxs) -- fix: Revert PR #7188 - Restore temperature parameter to fix TabbyApi/ExLlamaV2 crashes (#7581 by @drknyt, PR by @daniel-lxs) -- fix: Make ollama models info transport work like lmstudio (#7674 by @ItsOnlyBinary, PR by @ItsOnlyBinary) -- fix: Update DeepSeek pricing to new unified rates effective Sept 5, 2025 (#7685 by @NaccOll, PR by @app/roomote) -- feat: Update Vertex AI models and regions (#7725 by @ssweens, PR by @ssweens) -- chore: Update dependency eslint-plugin-turbo to v2.5.6 (thanks @app/renovate!) -- chore: Update dependency @changesets/cli to v2.29.6 (thanks @app/renovate!) -- chore: Update dependency nock to v14.0.10 (thanks @app/renovate!) -- chore: Update dependency eslint-config-prettier to v10.1.8 (thanks @app/renovate!) -- chore: Update dependency esbuild to v0.25.9 (thanks @app/renovate!) - ## [3.27.0] - 2025-09-05 ![3.27.0 Release - Bug Fixes and Improvements](/releases/3.27.0-release.png) diff --git a/PRIVACY.md b/PRIVACY.md index 02e8e15103..2385fc27b9 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -1,6 +1,6 @@ # Roo Code Privacy Policy -**Last Updated: September 11th, 2025** +**Last Updated: August 20th, 2025** Roo Code respects your privacy and is committed to transparency about how we handle your data. Below is a simple breakdown of where key pieces of data go—and, importantly, where they don’t. @@ -10,19 +10,19 @@ Roo Code respects your privacy and is committed to transparency about how we han - **Commands**: Any commands executed through Roo Code happen on your local environment. However, when you use AI-powered features, the relevant code and context from your commands may be transmitted to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not have access to or store this data, but AI providers may process it per their privacy policies. - **Prompts & AI Requests**: When you use AI-powered features, your prompts and relevant project context are sent to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not store or process this data. These AI providers have their own privacy policies and may store data per their terms of service. If you choose Roo Code Cloud as the provider (proxy mode), prompts may transit Roo Code servers only to forward them to the upstream model and are not stored. - **API Keys & Credentials**: If you enter an API key (e.g., to connect an AI model), it is stored locally on your device and never sent to us or any third party, except the provider you have chosen. -- **Telemetry (Usage Data)**: We collect anonymous feature usage and error data to help us improve Roo Code. This telemetry is powered by PostHog and includes your VS Code machine ID, feature usage patterns, and exception reports. This telemetry does **not** collect personally identifiable information, your code, or AI prompts. You can opt out of this telemetry at any time through the settings. -- **Marketplace Requests**: When you browse or search the Marketplace for Model Configuration Profiles (MCPs) or Custom Modes, Roo Code makes a secure API call to Roo Code's backend servers to retrieve listing information. These requests send only the query parameters (e.g., extension version, search term) necessary to fulfill the request and do not include your code, prompts, or personally identifiable information. +- **Telemetry (Usage Data)**: We only collect feature usage and error data if you explicitly opt-in. This telemetry is powered by PostHog and helps us understand feature usage to improve Roo Code. This includes your VS Code machine ID and feature usage patterns and exception reports. We do **not** collect personally identifiable information, your code, or AI prompts. +- **Marketplace Requests**: When you browse or search the Marketplace for Model Configuration Profiles (MCPs) or Custom Modes, Roo Code makes a secure API call to Roo Code’s backend servers to retrieve listing information. These requests send only the query parameters (e.g., extension version, search term) necessary to fulfill the request and do not include your code, prompts, or personally identifiable information. ### **How We Use Your Data (If Collected)** -- We use telemetry to understand feature usage and improve Roo Code. +- If you opt-in to telemetry, we use it to understand feature usage and improve Roo Code. - We do **not** sell or share your data. - We do **not** train any models on your data. ### **Your Choices & Control** - You can run models locally to prevent data being sent to third-parties. -- Telemetry collection is enabled by default to help us improve Roo Code, but you can opt out at any time through the settings. +- By default, telemetry collection is off and if you turn it on, you can opt out of telemetry at any time. - You can delete Roo Code to stop all data collection. ### **Security & Updates** diff --git a/README.md b/README.md index a8235cb13b..fa61085306 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,16 @@ Check out the [CHANGELOG](CHANGELOG.md) for detailed updates and fixes. --- +## 🎉 Roo Code 3.25 Released + +Roo Code 3.25 brings powerful new features and significant improvements to enhance your development workflow! + +- **Message Queueing** - Queue multiple messages while Roo is working, allowing you to continue planning your workflow without interruption. +- **Custom Slash Commands** - Create personalized slash commands for quick access to frequently used prompts and workflows, with full UI management. +- **Enhanced Gemini Tools** - New URL context and Google Search grounding capabilities provide Gemini models with real-time web information and enhanced research abilities. + +--- + ## What Can Roo Code Do? - 🚀 **Generate Code** from natural language descriptions diff --git a/apps/web-roo-code/next.config.ts b/apps/web-roo-code/next.config.ts index ec82764607..b50bd93994 100644 --- a/apps/web-roo-code/next.config.ts +++ b/apps/web-roo-code/next.config.ts @@ -21,7 +21,7 @@ const nextConfig: NextConfig = { destination: "https://roocode.com/:path*", permanent: true, }, - // Redirect cloud waitlist to Notion page (kept for extension compatibility) + // Redirect cloud waitlist to Notion page { source: "/cloud-waitlist", destination: "https://roo-code.notion.site/238fd1401b0a8087b858e1ad431507cf?pvs=105", diff --git a/apps/web-roo-code/src/app/evals/evals.tsx b/apps/web-roo-code/src/app/evals/evals.tsx index 294d702f84..6b619de2b8 100644 --- a/apps/web-roo-code/src/app/evals/evals.tsx +++ b/apps/web-roo-code/src/app/evals/evals.tsx @@ -1,35 +1,61 @@ "use client" import { useMemo } from "react" +import { ScatterChart, Scatter, XAxis, YAxis, Label, Customized, Cross } from "recharts" + +import type { TaskMetrics, Run } from "@roo-code/evals" import { formatTokens, formatCurrency, formatDuration, formatScore } from "@/lib" import { useOpenRouterModels } from "@/lib/hooks" -import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui" +import { + ChartContainer, + ChartTooltip, + ChartTooltipContent, + ChartConfig, + ChartLegend, + ChartLegendContent, + Table, + TableBody, + TableCaption, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui" -import type { EvalRun } from "./types" -import { Plot } from "./plot" - -export function Evals({ runs }: { runs: EvalRun[] }) { +export function Evals({ + runs, +}: { + runs: (Run & { + label: string + score: number + languageScores?: Record<"go" | "java" | "javascript" | "python" | "rust", number> + taskMetrics: TaskMetrics + modelId?: string + })[] +}) { const { data: openRouterModels } = useOpenRouterModels() - const tableData: (EvalRun & { label: string; cost: number })[] = useMemo( + const tableData = useMemo( () => - runs.map((run) => { - const openRouterModelInfo = openRouterModels?.[run.modelId ?? ""]?.modelInfo - - return { - ...run, - label: run.name || run.description || run.model, - cost: run.taskMetrics.cost, - description: run.description ?? openRouterModelInfo?.description ?? null, - contextWindow: run.contextWindow ?? openRouterModelInfo?.contextWindow ?? null, - inputPrice: run.inputPrice ?? openRouterModelInfo?.inputPrice ?? null, - outputPrice: run.outputPrice ?? openRouterModelInfo?.outputPrice ?? null, - } - }), + runs.map((run) => ({ + ...run, + label: run.description || run.model, + score: run.score, + cost: run.taskMetrics.cost, + model: openRouterModels?.[run.modelId ?? ""], + modelInfo: openRouterModels?.[run.modelId ?? ""]?.modelInfo, + })), [runs, openRouterModels], ) + const chartData = useMemo(() => tableData.filter(({ cost }) => cost < 100), [tableData]) + + const chartConfig = useMemo( + () => chartData.reduce((acc, run) => ({ ...acc, [run.label]: run }), {} as ChartConfig), + [chartData], + ) + return (
@@ -101,15 +127,17 @@ export function Evals({ runs }: { runs: EvalRun[] }) { {tableData.map((run) => ( - +
{run.label}
-
{formatTokens(run.contextWindow)}
+
+ {formatTokens(run.modelInfo?.contextWindow ?? 0)} +
-
{formatCurrency(run.inputPrice)}
+
{formatCurrency(run.modelInfo?.inputPrice ?? 0)}
/
-
{formatCurrency(run.outputPrice)}
+
{formatCurrency(run.modelInfo?.outputPrice ?? 0)}
{formatDuration(run.taskMetrics.duration)} @@ -141,9 +169,58 @@ export function Evals({ runs }: { runs: EvalRun[] }) { ))}
- +
Cost Versus Score
+ + + Math.round((dataMin - 5) / 5) * 5, + (dataMax: number) => Math.round((dataMax + 5) / 5) * 5, + ]} + tickFormatter={(value) => formatCurrency(value)}> + + Math.max(0, Math.round((dataMin - 5) / 5) * 5), + (dataMax: number) => Math.min(100, Math.round((dataMax + 5) / 5) * 5), + ]} + tickFormatter={(value) => `${value}%`}> + + } /> + + {chartData.map((d, i) => ( + + ))} + } /> + + +
+ (Note: Very expensive models are excluded from the scatter plot.) +
) } + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const renderQuadrant = (props: any) => ( + +) diff --git a/apps/web-roo-code/src/app/evals/plot.tsx b/apps/web-roo-code/src/app/evals/plot.tsx deleted file mode 100644 index f68007cd12..0000000000 --- a/apps/web-roo-code/src/app/evals/plot.tsx +++ /dev/null @@ -1,336 +0,0 @@ -"use client" - -import { useMemo } from "react" -import { ScatterChart, Scatter, XAxis, YAxis, Customized, Cross, LabelList } from "recharts" - -import { formatCurrency } from "@/lib" -import { ChartContainer, ChartTooltip, ChartConfig } from "@/components/ui" - -import type { EvalRun } from "./types" - -type PlotProps = { - tableData: (EvalRun & { label: string; cost: number })[] -} - -type LabelPosition = "top" | "bottom" | "left" | "right" - -export const Plot = ({ tableData }: PlotProps) => { - const chartData = useMemo(() => tableData.filter(({ cost }) => cost < 50), [tableData]) - - const chartConfig = useMemo( - () => chartData.reduce((acc, run) => ({ ...acc, [run.label]: run }), {} as ChartConfig), - [chartData], - ) - - // Calculate label positions to avoid overlaps. - const labelPositions = useMemo(() => { - const positions: Record = {} - - // Track placed labels with their approximate bounds. - const placedLabels: Array<{ - cost: number - score: number - label: string - position: LabelPosition - }> = [] - - // Helper function to check if two labels would overlap. - const wouldLabelsOverlap = ( - p1: { cost: number; score: number; position: LabelPosition }, - p2: { cost: number; score: number; position: LabelPosition }, - ): boolean => { - // Approximate thresholds for overlap detection. - const horizontalThreshold = 4 // Cost units. - const verticalThreshold = 5 // Score units. - - const costDiff = Math.abs(p1.cost - p2.cost) - const scoreDiff = Math.abs(p1.score - p2.score) - - // If points are far apart, no overlap. - if (costDiff > horizontalThreshold * 2 || scoreDiff > verticalThreshold * 2) { - return false - } - - // Check specific position combinations for overlap. - // Same position for nearby points definitely overlaps. - if (p1.position === p2.position && costDiff < horizontalThreshold && scoreDiff < verticalThreshold) { - return true - } - - // Check adjacent position overlaps. - const p1IsTop = p1.position === "top" - const p1IsBottom = p1.position === "bottom" - const p2IsTop = p2.position === "top" - const p2IsBottom = p2.position === "bottom" - - // If both labels are on the same vertical side and points are close - // horizontally. - if ((p1IsTop && p2IsTop) || (p1IsBottom && p2IsBottom)) { - if (costDiff < horizontalThreshold && scoreDiff < verticalThreshold / 2) { - return true - } - } - - return false - } - - // Helper function to check if position would overlap with a data point. - const wouldOverlapPoint = (point: (typeof chartData)[0], position: LabelPosition): boolean => { - for (const other of chartData) { - if (other.label === point.label) { - continue - } - - const costDiff = Math.abs(point.cost - other.cost) - const scoreDiff = Math.abs(point.score - other.score) - - // Check if label would be placed on top of another point. - switch (position) { - case "top": - // Label is above, check if there's a point above. - if (costDiff < 3 && other.score > point.score && other.score - point.score < 6) { - return true - } - break - case "bottom": - // Label is below, check if there's a point below. - if (costDiff < 3 && other.score < point.score && point.score - other.score < 6) { - return true - } - break - case "left": - // Label is to the left, check if there's a point to the left. - if (scoreDiff < 3 && other.cost < point.cost && point.cost - other.cost < 4) { - return true - } - break - case "right": - // Label is to the right, check if there's a point to the right. - if (scoreDiff < 3 && other.cost > point.cost && other.cost - point.cost < 4) { - return true - } - break - } - } - return false - } - - // Sort points to process them in a consistent order. - // Process from top-left to bottom-right. - const sortedData = [...chartData].sort((a, b) => { - // First by score (higher first). - const scoreDiff = b.score - a.score - if (Math.abs(scoreDiff) > 1) return scoreDiff - // Then by cost (lower first). - return a.cost - b.cost - }) - - // Process each point and find the best position. - sortedData.forEach((point) => { - // Try positions in order of preference. - const positionPreferences: LabelPosition[] = ["top", "bottom", "right", "left"] - - let bestPosition: LabelPosition = "top" - - for (const position of positionPreferences) { - // Check if this position would overlap with any placed labels. - let hasLabelOverlap = false - - for (const placed of placedLabels) { - if ( - wouldLabelsOverlap( - { cost: point.cost, score: point.score, position }, - { cost: placed.cost, score: placed.score, position: placed.position }, - ) - ) { - hasLabelOverlap = true - break - } - } - - // Check if this position would overlap with any data points. - const hasPointOverlap = wouldOverlapPoint(point, position) - - // If no overlaps, use this position. - if (!hasLabelOverlap && !hasPointOverlap) { - bestPosition = position - break - } - } - - // Use the best position found - positions[point.label] = bestPosition - placedLabels.push({ - cost: point.cost, - score: point.score, - label: point.label, - position: bestPosition, - }) - }) - - return positions - }, [chartData]) - - return ( - <> -
Cost x Score
- - - Math.max(0, Math.round((dataMin - 5) / 5) * 5), - (dataMax: number) => Math.round((dataMax + 5) / 5) * 5, - ]} - tickFormatter={(value) => formatCurrency(value)} - /> - Math.max(0, Math.round((dataMin - 5) / 5) * 5), - (dataMax: number) => Math.min(100, Math.round((dataMax + 5) / 5) * 5), - ]} - tickFormatter={(value) => `${value}%`} - /> - { - if (!active || !payload || !payload.length || !payload[0]) { - return null - } - - const { label, cost, score } = payload[0].payload - - return ( -
-
{label}
-
-
- Score: {Math.round(score)}% -
-
- Cost: {formatCurrency(cost)} -
-
-
- ) - }} - /> - - {chartData.map((d, index) => ( - - renderCustomLabel(props, labelPositions[d.label] || "top")} - /> - - ))} -
-
-
- (Note: Models with a cost of $50 or more are excluded from the scatter plot.) -
- - ) -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const renderQuadrant = (props: any) => ( - -) - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const renderCustomLabel = (props: any, position: LabelPosition) => { - const { x, y, value } = props - const maxWidth = 80 // Maximum width in pixels - adjust as needed. - - const truncateText = (text: string, maxChars: number = 20) => { - if (text.length <= maxChars) { - return text - } - - return text.substring(0, maxChars - 1) + "…" - } - - // Calculate position offsets based on label position. - let xOffset = 0 - let yOffset = 0 - let textAnchor: "middle" | "start" | "end" = "middle" - let dominantBaseline: "auto" | "hanging" | "middle" = "auto" - - switch (position) { - case "top": - yOffset = -8 - textAnchor = "middle" - dominantBaseline = "auto" - break - case "bottom": - yOffset = 15 - textAnchor = "middle" - dominantBaseline = "hanging" - break - case "left": - xOffset = -8 - yOffset = 5 - textAnchor = "end" - dominantBaseline = "middle" - break - case "right": - xOffset = 15 - yOffset = 5 - textAnchor = "start" - dominantBaseline = "middle" - break - } - - return ( - - {truncateText(value)} - - ) -} - -const generateSpectrumColor = (index: number, total: number): string => { - // Distribute hues evenly across the color wheel (0-360 degrees). - // Start at 0 (red) and distribute evenly. - const hue = (index * 360) / total - - // Use high saturation for vibrant colors. - const saturation = 70 - - // Use medium lightness for good visibility on both light and dark backgrounds. - const lightness = 50 - - return `hsl(${Math.round(hue)}, ${saturation}%, ${lightness}%)` -} diff --git a/apps/web-roo-code/src/app/evals/types.ts b/apps/web-roo-code/src/app/evals/types.ts deleted file mode 100644 index c28049661d..0000000000 --- a/apps/web-roo-code/src/app/evals/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { TaskMetrics, Run } from "@roo-code/evals" - -export type EvalRun = Run & { - label: string - score: number - languageScores?: Record<"go" | "java" | "javascript" | "python" | "rust", number> - taskMetrics: TaskMetrics - modelId?: string -} diff --git a/apps/web-roo-code/src/components/chromes/nav-bar.tsx b/apps/web-roo-code/src/components/chromes/nav-bar.tsx index 00fe9d2727..ca6a4d4b4f 100644 --- a/apps/web-roo-code/src/components/chromes/nav-bar.tsx +++ b/apps/web-roo-code/src/components/chromes/nav-bar.tsx @@ -69,13 +69,19 @@ export function NavBar({ stars, downloads }: NavBarProps) { className="text-muted-foreground transition-transform duration-200 hover:scale-105 hover:text-foreground"> Community - - Cloud - +
+
+ + Roo Code Cloud is coming + + + Sign up + +
+
@@ -115,6 +121,19 @@ export function NavBar({ stars, downloads }: NavBarProps) {
{ - e.preventDefault() - window.postMessage( - { - type: "action", - action: "openExternal", - data: { - url: "https://docs.roocode.com/update-notes/v3.28.0#task-sync--roomote-control", - }, - }, - "*", - ) + bold: , + code: , + }} + /> +
+ +
+ {!cloudIsAuthenticated ? ( +
+
+ , + settingsLink: ( + { + e.preventDefault() + setOpen(false) + hideAnnouncement() + window.postMessage( + { + type: "action", + action: "settingsButtonClicked", + values: { section: "provider" }, + }, + "*", + ) + }} + /> + ), }} /> - ), - }} - /> -
- -
- -
- -
- , - discordLink: , - redditLink: , - }} - /> +
+ +
+ ) : ( +
+ , + settingsLink: ( + { + e.preventDefault() + setOpen(false) + hideAnnouncement() + window.postMessage( + { + type: "action", + action: "settingsButtonClicked", + values: { section: "provider" }, + }, + "*", + ) + }} + /> + ), + }} + /> +
+ )}
@@ -127,43 +136,4 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => { ) } -const XLink = () => ( - { - e.preventDefault() - window.postMessage({ type: "action", action: "openExternal", data: { url: "https://x.com/roo_code" } }, "*") - }}> - X - -) - -const DiscordLink = () => ( - { - e.preventDefault() - window.postMessage( - { type: "action", action: "openExternal", data: { url: "https://discord.gg/rCQcvT7Fnt" } }, - "*", - ) - }}> - Discord - -) - -const RedditLink = () => ( - { - e.preventDefault() - window.postMessage( - { type: "action", action: "openExternal", data: { url: "https://www.reddit.com/r/RooCode/" } }, - "*", - ) - }}> - r/RooCode - -) - export default memo(Announcement) diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index 25b936eb74..8961fc7f5d 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -9,9 +9,6 @@ import { AutoApproveToggle, AutoApproveSetting, autoApproveSettingsConfig } from import { StandardTooltip } from "@src/components/ui" import { useAutoApprovalState } from "@src/hooks/useAutoApprovalState" import { useAutoApprovalToggles } from "@src/hooks/useAutoApprovalToggles" -import DismissibleUpsell from "@src/components/common/DismissibleUpsell" -import { useCloudUpsell } from "@src/hooks/useCloudUpsell" -import { CloudUpsellDialog } from "@src/components/cloud/CloudUpsellDialog" interface AutoApproveMenuProps { style?: React.CSSProperties @@ -38,12 +35,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { const { t } = useAppTranslation() - const { isOpen, openUpsell, closeUpsell, handleConnect } = useCloudUpsell({ - autoOpenOnAuth: false, - }) - const baseToggles = useAutoApprovalToggles() - const enabledCount = useMemo(() => Object.values(baseToggles).filter(Boolean).length, [baseToggles]) // AutoApproveMenu needs alwaysApproveResubmit in addition to the base toggles const toggles = useMemo( @@ -181,23 +173,6 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
- - {enabledCount > 7 && ( - <> - openUpsell()} - dismissOnClick={false} - variant="banner"> - , - }} - /> - - - )} )} @@ -265,7 +240,6 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { /> - ) } diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 23ec50af37..bd84861b53 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -17,7 +17,8 @@ import { findMatchingResourceOrTemplate } from "@src/utils/mcp" import { vscode } from "@src/utils/vscode" import { removeLeadingNonAlphanumeric } from "@src/utils/removeLeadingNonAlphanumeric" import { getLanguageFromPath } from "@src/utils/getLanguageFromPath" -import { Button } from "@src/components/ui" +import { formatTokenStats } from "@src/utils/formatTokens" +import { Button, StandardTooltip } from "@src/components/ui" import { ToolUseBlock, ToolUseBlockHeader } from "../common/ToolUseBlock" import UpdateTodoListToolBlock from "./UpdateTodoListToolBlock" @@ -118,6 +119,7 @@ export const ChatRowContent = ({ const { mcpServers, alwaysAllowMcp, currentCheckpoint, mode, apiConfiguration } = useExtensionState() const { info: model } = useSelectedModel(apiConfiguration) + const [reasoningCollapsed, setReasoningCollapsed] = useState(true) const [isDiffErrorExpanded, setIsDiffErrorExpanded] = useState(false) const [showCopySuccess, setShowCopySuccess] = useState(false) const [isEditing, setIsEditing] = useState(false) @@ -179,13 +181,20 @@ export const ChatRowContent = ({ vscode.postMessage({ type: "selectImages", context: "edit", messageTs: message.ts }) }, [message.ts]) - const [cost, apiReqCancelReason, apiReqStreamingFailedMessage] = useMemo(() => { + const [cost, apiReqCancelReason, apiReqStreamingFailedMessage, tokensIn, tokensOut, cacheReads] = useMemo(() => { if (message.text !== null && message.text !== undefined && message.say === "api_req_started") { const info = safeJsonParse(message.text) - return [info?.cost, info?.cancelReason, info?.streamingFailedMessage] + return [ + info?.cost, + info?.cancelReason, + info?.streamingFailedMessage, + info?.tokensIn, + info?.tokensOut, + info?.cacheReads, + ] } - return [undefined, undefined, undefined] + return [undefined, undefined, undefined, undefined, undefined, undefined] }, [message.text, message.say]) // When resuming task, last wont be api_req_failed but a resume_task @@ -1086,13 +1095,15 @@ export const ChatRowContent = ({ return ( setReasoningCollapsed(!reasoningCollapsed)} /> ) case "api_req_started": + const tokenStats = formatTokenStats(tokensIn, tokensOut, cacheReads) + const hasTokenData = tokensIn !== undefined || tokensOut !== undefined + return ( <>
-
+
{icon} - {title} - 0 ? 1 : 0 }}> - ${Number(cost || 0)?.toFixed(4)} - + {hasTokenData ? ( + +
+ ↑ {t("chat:apiRequest.input")}: + {tokenStats.input} +
+
+ ↓ {t("chat:apiRequest.output")}: + {tokenStats.output} +
+
+ } + side="top"> + + {title} + + + ) : ( + + {title} + + )} +
+ {hasTokenData && cost !== null && cost !== undefined && cost > 0 ? ( + +
+ ↑ {t("chat:apiRequest.input")}: + {tokenStats.input} +
+
+ ↓ {t("chat:apiRequest.output")}: + {tokenStats.output} +
+
+ } + side="top"> + + ${Number(cost || 0)?.toFixed(4)} + + + ) : ( + 0 ? 1 : 0, + flexShrink: 0, + }}> + ${Number(cost || 0)?.toFixed(4)} + + )} +
@@ -1172,10 +1267,9 @@ export const ChatRowContent = ({ ) case "user_feedback": return ( -
+
{isEditing ? ( -
+
) : (
-
{ - e.stopPropagation() - if (!isStreaming) { - handleEditClick() - } - }} - title={t("chat:queuedMessages.clickToEdit")}> +
diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index e7a9f67b8b..c917797283 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -903,8 +903,20 @@ export const ChatTextArea = forwardRef( return (
( : isDraggingOver ? "border-2 border-dashed border-vscode-focusBorder" : "border border-transparent", - "pl-2", - "py-2", - isEditMode ? "pr-20" : "pr-9", + "px-[8px]", + "py-1.5", + "pr-9", "z-10", "forced-color-adjust-none", - "rounded", )} style={{ color: "transparent", @@ -1019,15 +1030,7 @@ export const ChatTextArea = forwardRef( updateHighlights() }} onFocus={() => setIsFocused(true)} - onKeyDown={(e) => { - // Handle ESC to cancel in edit mode - if (isEditMode && e.key === "Escape" && !e.nativeEvent?.isComposing) { - e.preventDefault() - onCancel?.() - return - } - handleKeyDown(e) - }} + onKeyDown={handleKeyDown} onKeyUp={handleKeyUp} onBlur={handleBlur} onPaste={handlePaste} @@ -1051,7 +1054,7 @@ export const ChatTextArea = forwardRef( "text-vscode-editor-font-size", "leading-vscode-editor-line-height", "cursor-text", - "py-2 pl-2", + "py-1.5 px-2", isFocused ? "border border-vscode-focusBorder outline outline-vscode-focusBorder" : isDraggingOver @@ -1068,7 +1071,7 @@ export const ChatTextArea = forwardRef( "resize-none", "overflow-x-hidden", "overflow-y-auto", - isEditMode ? "pr-20" : "pr-9", + "pr-9", "flex-none flex-grow", "z-[2]", "scrollbar-none", @@ -1077,7 +1080,7 @@ export const ChatTextArea = forwardRef( onScroll={() => updateHighlights()} /> -
+
-
+
{isEditMode && ( - - - - - - {t("chat:task.openInCloud")} - - -
-

{t("chat:task.openInCloudIntro")}

-
-
vscode.postMessage({ type: "openExternal", url: cloudTaskUrl })} - title={t("chat:task.openInCloud")}> - -
-
- -
- - -
-
-
-
- - ) -} diff --git a/webview-ui/src/components/chat/ModeSelector.tsx b/webview-ui/src/components/chat/ModeSelector.tsx index 331660143b..2ae9279fa8 100644 --- a/webview-ui/src/components/chat/ModeSelector.tsx +++ b/webview-ui/src/components/chat/ModeSelector.tsx @@ -44,8 +44,6 @@ export const ModeSelector = ({ const [open, setOpen] = React.useState(false) const [searchValue, setSearchValue] = React.useState("") const searchInputRef = React.useRef(null) - const selectedItemRef = React.useRef(null) - const scrollContainerRef = React.useRef(null) const portalContainer = useRooPortal("roo-portal") const { hasOpenedModeSelector, setHasOpenedModeSelector } = useExtensionState() const { t } = useAppTranslation() @@ -151,37 +149,10 @@ export const ModeSelector = ({ [trackModeSelectorOpened], ) - // Auto-focus search input and scroll to selected item when popover opens. + // Auto-focus search input when popover opens. React.useEffect(() => { - if (open) { - // Focus search input - if (searchInputRef.current) { - searchInputRef.current.focus() - } - - requestAnimationFrame(() => { - if (selectedItemRef.current && scrollContainerRef.current) { - const container = scrollContainerRef.current - const item = selectedItemRef.current - - // Calculate positions - const containerHeight = container.clientHeight - const itemTop = item.offsetTop - const itemHeight = item.offsetHeight - - // Center the item in the container - const scrollPosition = itemTop - containerHeight / 2 + itemHeight / 2 - - // Ensure we don't scroll past boundaries - const maxScroll = container.scrollHeight - containerHeight - const finalScrollPosition = Math.min(Math.max(0, scrollPosition), maxScroll) - - container.scrollTo({ - top: finalScrollPosition, - behavior: "instant", - }) - } - }) + if (open && searchInputRef.current) { + searchInputRef.current.focus() } }, [open]) @@ -252,40 +223,36 @@ export const ModeSelector = ({ )} {/* Mode List */} -
+
{filteredModes.length === 0 && searchValue ? (
{t("chat:modeSelector.noResults")}
) : (
- {filteredModes.map((mode) => { - const isSelected = mode.slug === value - return ( -
handleSelect(mode.slug)} - className={cn( - "px-3 py-1.5 text-sm cursor-pointer flex items-center", - "hover:bg-vscode-list-hoverBackground", - isSelected - ? "bg-vscode-list-activeSelectionBackground text-vscode-list-activeSelectionForeground" - : "", + {filteredModes.map((mode) => ( +
handleSelect(mode.slug)} + className={cn( + "px-3 py-1.5 text-sm cursor-pointer flex items-center", + "hover:bg-vscode-list-hoverBackground", + mode.slug === value + ? "bg-vscode-list-activeSelectionBackground text-vscode-list-activeSelectionForeground" + : "", + )} + data-testid="mode-selector-item"> +
+
{mode.name}
+ {mode.description && ( +
+ {mode.description} +
)} - data-testid="mode-selector-item"> -
-
{mode.name}
- {mode.description && ( -
- {mode.description} -
- )} -
- {isSelected && }
- ) - })} + {mode.slug === value && } +
+ ))}
)}
diff --git a/webview-ui/src/components/chat/ReasoningBlock.tsx b/webview-ui/src/components/chat/ReasoningBlock.tsx index 3c981126ef..baa93485f9 100644 --- a/webview-ui/src/components/chat/ReasoningBlock.tsx +++ b/webview-ui/src/components/chat/ReasoningBlock.tsx @@ -1,57 +1,96 @@ -import React, { useEffect, useRef, useState } from "react" +import { useCallback, useEffect, useRef, useState } from "react" +import { CaretDownIcon, CaretUpIcon, CounterClockwiseClockIcon } from "@radix-ui/react-icons" import { useTranslation } from "react-i18next" import MarkdownBlock from "../common/MarkdownBlock" -import { Clock, Lightbulb } from "lucide-react" +import { useMount } from "react-use" interface ReasoningBlockProps { content: string - ts: number - isStreaming: boolean - isLast: boolean - metadata?: any + elapsed?: number + isCollapsed?: boolean + onToggleCollapse?: () => void } -/** - * Render reasoning with a heading and a simple timer. - * - Heading uses i18n key chat:reasoning.thinking - * - Timer runs while reasoning is active (no persistence) - */ -export const ReasoningBlock = ({ content, isStreaming, isLast }: ReasoningBlockProps) => { - const { t } = useTranslation() +export const ReasoningBlock = ({ content, elapsed, isCollapsed = false, onToggleCollapse }: ReasoningBlockProps) => { + const contentRef = useRef(null) + const elapsedRef = useRef(0) + const { t } = useTranslation("chat") + const [thought, setThought] = useState() + const [prevThought, setPrevThought] = useState(t("chat:reasoning.thinking")) + const [isTransitioning, setIsTransitioning] = useState(false) + const cursorRef = useRef(0) + const queueRef = useRef([]) - const startTimeRef = useRef(Date.now()) - const [elapsed, setElapsed] = useState(0) - - // Simple timer that runs while streaming useEffect(() => { - if (isLast && isStreaming) { - const tick = () => setElapsed(Date.now() - startTimeRef.current) - tick() - const id = setInterval(tick, 1000) - return () => clearInterval(id) + if (contentRef.current && !isCollapsed) { + contentRef.current.scrollTop = contentRef.current.scrollHeight } - }, [isLast, isStreaming]) + }, [content, isCollapsed]) - const seconds = Math.floor(elapsed / 1000) - const secondsLabel = t("chat:reasoning.seconds", { count: seconds }) + useEffect(() => { + if (elapsed) { + elapsedRef.current = elapsed + } + }, [elapsed]) + + // Process the transition queue. + const processNextTransition = useCallback(() => { + const nextThought = queueRef.current.pop() + queueRef.current = [] + + if (nextThought) { + setIsTransitioning(true) + } + + setTimeout(() => { + if (nextThought) { + setPrevThought(nextThought) + setIsTransitioning(false) + } + + setTimeout(() => processNextTransition(), 500) + }, 200) + }, []) + + useMount(() => { + processNextTransition() + }) + + useEffect(() => { + if (content.length - cursorRef.current > 160) { + setThought("... " + content.slice(cursorRef.current)) + cursorRef.current = content.length + } + }, [content]) + + useEffect(() => { + if (thought && thought !== prevThought) { + queueRef.current.push(thought) + } + }, [thought, prevThought]) return ( -
-
-
- - {t("chat:reasoning.thinking")} +
+
+
+ {prevThought} +
+
+ {elapsedRef.current > 1000 && ( + <> + +
{t("reasoning.seconds", { count: Math.round(elapsedRef.current / 1000) })}
+ + )} + {isCollapsed ? : }
- {elapsed > 0 && ( - - - {secondsLabel} - - )}
- {(content?.trim()?.length ?? 0) > 0 && ( -
+ {!isCollapsed && ( +
)} diff --git a/webview-ui/src/components/chat/ShareButton.tsx b/webview-ui/src/components/chat/ShareButton.tsx index 74bb25a21e..4bcabb3a1c 100644 --- a/webview-ui/src/components/chat/ShareButton.tsx +++ b/webview-ui/src/components/chat/ShareButton.tsx @@ -1,14 +1,12 @@ -import { useState, useEffect } from "react" +import { useState, useEffect, useRef } from "react" import { useTranslation } from "react-i18next" -import { Share2 } from "lucide-react" +import { SquareArrowOutUpRightIcon } from "lucide-react" import { type HistoryItem, type ShareVisibility, TelemetryEventName } from "@roo-code/types" import { vscode } from "@/utils/vscode" import { telemetryClient } from "@/utils/TelemetryClient" import { useExtensionState } from "@/context/ExtensionStateContext" -import { useCloudUpsell } from "@/hooks/useCloudUpsell" -import { CloudUpsellDialog } from "@/components/cloud/CloudUpsellDialog" import { Button, Popover, @@ -18,6 +16,10 @@ import { CommandList, CommandItem, CommandGroup, + Dialog, + DialogContent, + DialogHeader, + DialogTitle, StandardTooltip, } from "@/components/ui" @@ -29,34 +31,29 @@ interface ShareButtonProps { export const ShareButton = ({ item, disabled = false, showLabel = false }: ShareButtonProps) => { const [shareDropdownOpen, setShareDropdownOpen] = useState(false) + const [connectModalOpen, setConnectModalOpen] = useState(false) const [shareSuccess, setShareSuccess] = useState<{ visibility: ShareVisibility; url: string } | null>(null) - const [wasConnectInitiatedFromShare, setWasConnectInitiatedFromShare] = useState(false) const { t } = useTranslation() - const { cloudUserInfo } = useExtensionState() + const { sharingEnabled, cloudIsAuthenticated, cloudUserInfo } = useExtensionState() + const wasUnauthenticatedRef = useRef(false) + const initiatedAuthFromThisButtonRef = useRef(false) - // Use enhanced cloud upsell hook with auto-open on auth success - const { - isOpen: connectModalOpen, - openUpsell, - closeUpsell, - handleConnect, - isAuthenticated: cloudIsAuthenticated, - sharingEnabled, - } = useCloudUpsell({ - onAuthSuccess: () => { - // Auto-open share dropdown after successful authentication - setShareDropdownOpen(true) - setWasConnectInitiatedFromShare(false) - }, - }) - - // Auto-open popover when user becomes authenticated after clicking Connect from share button + // Track authentication state changes to auto-open popover after login useEffect(() => { - if (wasConnectInitiatedFromShare && cloudIsAuthenticated) { - setShareDropdownOpen(true) - setWasConnectInitiatedFromShare(false) + if (!cloudIsAuthenticated || !sharingEnabled) { + wasUnauthenticatedRef.current = true + } else if (wasUnauthenticatedRef.current && cloudIsAuthenticated && sharingEnabled) { + // Only open dropdown if auth was initiated from this button + if (initiatedAuthFromThisButtonRef.current) { + // User just authenticated from this share button, send telemetry, close modal, and open the popover + telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_SUCCESS) + setConnectModalOpen(false) + setShareDropdownOpen(true) + initiatedAuthFromThisButtonRef.current = false // Reset the flag + } + wasUnauthenticatedRef.current = false } - }, [wasConnectInitiatedFromShare, cloudIsAuthenticated]) + }, [cloudIsAuthenticated, sharingEnabled]) // Listen for share success messages from the extension useEffect(() => { @@ -98,9 +95,14 @@ export const ShareButton = ({ item, disabled = false, showLabel = false }: Share } const handleConnectToCloud = () => { - setWasConnectInitiatedFromShare(true) - handleConnect() + // Send telemetry for connect to cloud action + telemetryClient.capture(TelemetryEventName.SHARE_CONNECT_TO_CLOUD_CLICKED) + + // Mark that authentication was initiated from this button + initiatedAuthFromThisButtonRef.current = true + vscode.postMessage({ type: "rooCloudSignIn" }) setShareDropdownOpen(false) + setConnectModalOpen(false) } const handleShareButtonClick = () => { @@ -109,8 +111,7 @@ export const ShareButton = ({ item, disabled = false, showLabel = false }: Share if (!cloudIsAuthenticated) { // Show modal for unauthenticated users - openUpsell() - telemetryClient.capture(TelemetryEventName.SHARE_CONNECT_TO_CLOUD_CLICKED) + setConnectModalOpen(true) } else { // Show popover for authenticated users setShareDropdownOpen(true) @@ -164,7 +165,7 @@ export const ShareButton = ({ item, disabled = false, showLabel = false }: Share } onClick={handleShareButtonClick} data-testid="share-button"> - + {showLabel && {t("chat:task.share")}} @@ -233,14 +234,50 @@ export const ShareButton = ({ item, disabled = false, showLabel = false }: Share } onClick={handleShareButtonClick} data-testid="share-button"> - + {showLabel && {t("chat:task.share")}} )} {/* Connect to Cloud Modal */} - + + + + + {t("cloud:cloudBenefitsTitle")} + + + +
+
+

+ {t("cloud:cloudBenefitsSubtitle")} +

+
    +
  • + + {t("cloud:cloudBenefitSharing")} +
  • +
  • + + {t("cloud:cloudBenefitHistory")} +
  • +
  • + + {t("cloud:cloudBenefitMetrics")} +
  • +
+
+ +
+ +
+
+
+
) } diff --git a/webview-ui/src/components/chat/TaskActions.tsx b/webview-ui/src/components/chat/TaskActions.tsx index a6954c5ef3..1b192219ad 100644 --- a/webview-ui/src/components/chat/TaskActions.tsx +++ b/webview-ui/src/components/chat/TaskActions.tsx @@ -9,7 +9,6 @@ import { useCopyToClipboard } from "@/utils/clipboard" import { DeleteTaskDialog } from "../history/DeleteTaskDialog" import { IconButton } from "./IconButton" import { ShareButton } from "./ShareButton" -import { CloudTaskButton } from "./CloudTaskButton" interface TaskActionsProps { item?: HistoryItem @@ -63,7 +62,6 @@ export const TaskActions = ({ item, buttonsDisabled }: TaskActionsProps) => { )} -
) } diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 6164294722..8fd06b168f 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -1,15 +1,11 @@ -import { memo, useEffect, useRef, useState } from "react" +import { memo, useRef, useState } from "react" import { useTranslation } from "react-i18next" -import { useCloudUpsell } from "@src/hooks/useCloudUpsell" -import { CloudUpsellDialog } from "@src/components/cloud/CloudUpsellDialog" -import DismissibleUpsell from "@src/components/common/DismissibleUpsell" import { FoldVertical, ChevronUp, ChevronDown } from "lucide-react" import prettyBytes from "pretty-bytes" import type { ClineMessage } from "@roo-code/types" import { getModelMaxOutputTokens } from "@roo/api" -import { findLastIndex } from "@roo/array" import { formatLargeNumber } from "@src/utils/format" import { cn } from "@src/lib/utils" @@ -50,37 +46,9 @@ const TaskHeader = ({ todos, }: TaskHeaderProps) => { const { t } = useTranslation() - const { apiConfiguration, currentTaskItem, clineMessages } = useExtensionState() + const { apiConfiguration, currentTaskItem } = useExtensionState() const { id: modelId, info: model } = useSelectedModel(apiConfiguration) const [isTaskExpanded, setIsTaskExpanded] = useState(false) - const [showLongRunningTaskMessage, setShowLongRunningTaskMessage] = useState(false) - const { isOpen, openUpsell, closeUpsell, handleConnect } = useCloudUpsell({ - autoOpenOnAuth: false, - }) - - // Check if the task is complete by looking at the last relevant message (skipping resume messages) - const isTaskComplete = - clineMessages && clineMessages.length > 0 - ? (() => { - const lastRelevantIndex = findLastIndex( - clineMessages, - (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"), - ) - return lastRelevantIndex !== -1 - ? clineMessages[lastRelevantIndex]?.ask === "completion_result" - : false - })() - : false - - useEffect(() => { - const timer = setTimeout(() => { - if (currentTaskItem && !isTaskComplete) { - setShowLongRunningTaskMessage(true) - } - }, 120_000) // Show upsell after 2 minutes - - return () => clearTimeout(timer) - }, [currentTaskItem, isTaskComplete]) const textContainerRef = useRef(null) const textRef = useRef(null) @@ -101,15 +69,6 @@ const TaskHeader = ({ return (
- {showLongRunningTaskMessage && !isTaskComplete && ( - openUpsell()} - dismissOnClick={false} - variant="banner"> - {t("cloud:upsell.longRunningTask")} - - )}
-
) } diff --git a/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx new file mode 100644 index 0000000000..2e95e027a1 --- /dev/null +++ b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx @@ -0,0 +1,102 @@ +import { render, screen } from "@/utils/test-utils" + +import { Package } from "@roo/package" + +import Announcement from "../Announcement" + +// Mock the components from @src/components/ui +vi.mock("@src/components/ui", () => ({ + Dialog: ({ children }: { children: React.ReactNode }) =>
{children}
, + DialogContent: ({ children }: { children: React.ReactNode }) =>
{children}
, + DialogDescription: ({ children }: { children: React.ReactNode }) =>
{children}
, + DialogHeader: ({ children }: { children: React.ReactNode }) =>
{children}
, + DialogTitle: ({ children }: { children: React.ReactNode }) =>
{children}
, + DialogFooter: ({ children }: { children: React.ReactNode }) =>
{children}
, + Button: ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => ( + + ), +})) + +// Mock the useAppTranslation hook and Trans component +vi.mock("@src/i18n/TranslationContext", () => ({ + useAppTranslation: () => ({ + t: (key: string, options?: { version: string }) => { + if (key === "chat:announcement.title") { + return `🎉 Roo Code ${options?.version} Released` + } + if (key === "chat:announcement.stealthModel.feature") { + return "The Sonic stealth model is now Grok Code Fast!" + } + if (key === "chat:announcement.stealthModel.note") { + return "As a thank you for all the helpful feedback about Sonic, you'll also continue to have free access to the grok-code-fast-1 model for another week through the Roo Code Cloud provider." + } + if (key === "chat:announcement.stealthModel.connectButton") { + return "Connect to Roo Code Cloud" + } + // Return key for other translations not relevant to this test + return key + }, + }), +})) + +// Mock react-i18next Trans component +vi.mock("react-i18next", () => ({ + Trans: ({ i18nKey, children }: { i18nKey?: string; children: React.ReactNode }) => { + if (i18nKey === "chat:announcement.stealthModel.feature") { + return ( + <> + The Sonic stealth model is now Grok Code Fast! The fast reasoning model is now available as + grok-code-fast-1 under the “xAI (Grok)” provider. + + ) + } + if (i18nKey === "chat:announcement.stealthModel.selectModel") { + return <>Visit Settings to get started + } + if (i18nKey === "chat:announcement.stealthModel.note") { + return ( + <> + As a thank you for all the helpful feedback about Sonic, you’ll also continue to have free + access to the grok-code-fast-1 model for another week through the Roo Code Cloud provider. + + ) + } + return <>{children} + }, +})) + +// Mock VSCodeLink +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ + VSCodeLink: ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => ( + {children} + ), +})) + +// Mock the useExtensionState hook +vi.mock("@src/context/ExtensionStateContext", () => ({ + useExtensionState: () => ({ + apiConfiguration: null, + cloudIsAuthenticated: false, + }), +})) + +describe("Announcement", () => { + const mockHideAnnouncement = vi.fn() + const expectedVersion = Package.version + + it("renders the announcement with the version number from package.json", () => { + render() + + // Check if the mocked version number is present in the title + expect(screen.getByText(`🎉 Roo Code ${expectedVersion} Released`)).toBeInTheDocument() + + // Check if the Grok Code Fast feature is displayed + expect(screen.getByText(/The Sonic stealth model is now Grok Code Fast!/)).toBeInTheDocument() + + // Check if the note is displayed + expect(screen.getByText(/As a thank you for all the helpful feedback about Sonic/)).toBeInTheDocument() + + // Check if the connect button is displayed (since cloudIsAuthenticated is false in the mock) + expect(screen.getByText("Connect to Roo Code Cloud")).toBeInTheDocument() + }) +}) diff --git a/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx b/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx index f7ba2732fd..09d46083d4 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx @@ -82,10 +82,16 @@ vi.mock("../Announcement", () => ({ }, })) -// Mock DismissibleUpsell component -vi.mock("@/components/common/DismissibleUpsell", () => ({ - default: function MockDismissibleUpsell({ children }: { children: React.ReactNode }) { - return
{children}
+// Mock RooCloudCTA component +vi.mock("@src/components/welcome/RooCloudCTA", () => ({ + default: function MockRooCloudCTA() { + return ( +
+
rooCloudCTA.title
+
rooCloudCTA.description
+
rooCloudCTA.joinWaitlist
+
+ ) }, })) @@ -1268,10 +1274,10 @@ describe("ChatView - Version Indicator Tests", () => { }) }) -describe("ChatView - DismissibleUpsell Display Tests", () => { +describe("ChatView - RooCloudCTA Display Tests", () => { beforeEach(() => vi.clearAllMocks()) - it("does not show DismissibleUpsell when user is authenticated to Cloud", () => { + it("does not show RooCloudCTA when user is authenticated to Cloud", () => { const { queryByTestId } = renderChatView() // Hydrate state with user authenticated to cloud @@ -1286,11 +1292,11 @@ describe("ChatView - DismissibleUpsell Display Tests", () => { clineMessages: [], // No active task }) - // Should not show DismissibleUpsell when authenticated - expect(queryByTestId("dismissible-upsell")).not.toBeInTheDocument() + // Should not show RooCloudCTA when authenticated + expect(queryByTestId("roo-cloud-cta")).not.toBeInTheDocument() }) - it("does not show DismissibleUpsell when user has only run 3 tasks in their history", () => { + it("does not show RooCloudCTA when user has only run 3 tasks in their history", () => { const { queryByTestId } = renderChatView() // Hydrate state with user not authenticated but only 3 tasks @@ -1304,11 +1310,11 @@ describe("ChatView - DismissibleUpsell Display Tests", () => { clineMessages: [], // No active task }) - // Should not show DismissibleUpsell with less than 4 tasks - expect(queryByTestId("dismissible-upsell")).not.toBeInTheDocument() + // Should not show RooCloudCTA with less than 4 tasks + expect(queryByTestId("roo-cloud-cta")).not.toBeInTheDocument() }) - it("shows DismissibleUpsell when user is not authenticated and has run 4 or more tasks", async () => { + it("shows RooCloudCTA when user is not authenticated and has run 4 or more tasks", async () => { const { getByTestId } = renderChatView() // Hydrate state with user not authenticated and 4 tasks @@ -1323,13 +1329,13 @@ describe("ChatView - DismissibleUpsell Display Tests", () => { clineMessages: [], // No active task }) - // Wait for component to render and show DismissibleUpsell + // Wait for component to render and show RooCloudCTA await waitFor(() => { - expect(getByTestId("dismissible-upsell")).toBeInTheDocument() + expect(getByTestId("roo-cloud-cta")).toBeInTheDocument() }) }) - it("shows DismissibleUpsell when user is not authenticated and has run 5 tasks", async () => { + it("shows RooCloudCTA when user is not authenticated and has run 5 tasks", async () => { const { getByTestId } = renderChatView() // Hydrate state with user not authenticated and 5 tasks @@ -1345,13 +1351,13 @@ describe("ChatView - DismissibleUpsell Display Tests", () => { clineMessages: [], // No active task }) - // Wait for component to render and show DismissibleUpsell + // Wait for component to render and show RooCloudCTA await waitFor(() => { - expect(getByTestId("dismissible-upsell")).toBeInTheDocument() + expect(getByTestId("roo-cloud-cta")).toBeInTheDocument() }) }) - it("does not show DismissibleUpsell when there is an active task (regardless of auth status)", async () => { + it("does not show RooCloudCTA when there is an active task (regardless of auth status)", async () => { const { queryByTestId } = renderChatView() // Hydrate state with active task @@ -1375,8 +1381,8 @@ describe("ChatView - DismissibleUpsell Display Tests", () => { // Wait for component to render with active task await waitFor(() => { - // Should not show DismissibleUpsell during active task - expect(queryByTestId("dismissible-upsell")).not.toBeInTheDocument() + // Should not show RooCloudCTA during active task + expect(queryByTestId("roo-cloud-cta")).not.toBeInTheDocument() // Should not show RooTips either since the entire welcome screen is hidden during active tasks expect(queryByTestId("roo-tips")).not.toBeInTheDocument() // Should not show RooHero either since the entire welcome screen is hidden during active tasks @@ -1384,7 +1390,7 @@ describe("ChatView - DismissibleUpsell Display Tests", () => { }) }) - it("shows RooTips when user is authenticated (instead of DismissibleUpsell)", () => { + it("shows RooTips when user is authenticated (instead of RooCloudCTA)", () => { const { queryByTestId, getByTestId } = renderChatView() // Hydrate state with user authenticated to cloud @@ -1399,12 +1405,12 @@ describe("ChatView - DismissibleUpsell Display Tests", () => { clineMessages: [], // No active task }) - // Should not show DismissibleUpsell but should show RooTips - expect(queryByTestId("dismissible-upsell")).not.toBeInTheDocument() + // Should not show RooCloudCTA but should show RooTips + expect(queryByTestId("roo-cloud-cta")).not.toBeInTheDocument() expect(getByTestId("roo-tips")).toBeInTheDocument() }) - it("shows RooTips when user has fewer than 4 tasks (instead of DismissibleUpsell)", () => { + it("shows RooTips when user has fewer than 4 tasks (instead of RooCloudCTA)", () => { const { queryByTestId, getByTestId } = renderChatView() // Hydrate state with user not authenticated but fewer than 4 tasks @@ -1418,8 +1424,8 @@ describe("ChatView - DismissibleUpsell Display Tests", () => { clineMessages: [], // No active task }) - // Should not show DismissibleUpsell but should show RooTips - expect(queryByTestId("dismissible-upsell")).not.toBeInTheDocument() + // Should not show RooCloudCTA but should show RooTips + expect(queryByTestId("roo-cloud-cta")).not.toBeInTheDocument() expect(getByTestId("roo-tips")).toBeInTheDocument() }) }) diff --git a/webview-ui/src/components/chat/__tests__/CloudTaskButton.spec.tsx b/webview-ui/src/components/chat/__tests__/CloudTaskButton.spec.tsx deleted file mode 100644 index fc2b9f025e..0000000000 --- a/webview-ui/src/components/chat/__tests__/CloudTaskButton.spec.tsx +++ /dev/null @@ -1,234 +0,0 @@ -import { useTranslation } from "react-i18next" - -import { render, screen, fireEvent, waitFor } from "@/utils/test-utils" - -import { CloudTaskButton } from "../CloudTaskButton" - -// Mock the qrcode library -vi.mock("qrcode", () => ({ - default: { - toCanvas: vi.fn((_canvas, _text, _options, callback) => { - // Simulate successful QR code generation - if (callback) { - callback(null) - } - }), - }, -})) - -// Mock react-i18next -vi.mock("react-i18next") - -// Mock the cloud config -vi.mock("@roo-code/cloud/src/config", () => ({ - getRooCodeApiUrl: vi.fn(() => "https://app.roocode.com"), -})) - -// Mock the extension state context -vi.mock("@/context/ExtensionStateContext", () => ({ - ExtensionStateContextProvider: ({ children }: { children: React.ReactNode }) => children, - useExtensionState: vi.fn(), -})) - -// Mock clipboard utility -vi.mock("@/utils/clipboard", () => ({ - useCopyToClipboard: () => ({ - copyWithFeedback: vi.fn(), - showCopyFeedback: false, - }), -})) - -const mockUseTranslation = vi.mocked(useTranslation) -const { useExtensionState } = await import("@/context/ExtensionStateContext") -const mockUseExtensionState = vi.mocked(useExtensionState) - -describe("CloudTaskButton", () => { - const mockT = vi.fn((key: string) => key) - const mockItem = { - id: "test-task-id", - number: 1, - ts: Date.now(), - task: "Test Task", - tokensIn: 100, - tokensOut: 50, - totalCost: 0.01, - } - - beforeEach(() => { - vi.clearAllMocks() - - mockUseTranslation.mockReturnValue({ - t: mockT, - i18n: {} as any, - ready: true, - } as any) - - // Default extension state with bridge enabled - mockUseExtensionState.mockReturnValue({ - cloudUserInfo: { - id: "test-user", - email: "test@example.com", - extensionBridgeEnabled: true, - }, - cloudApiUrl: "https://app.roocode.com", - } as any) - }) - - test("renders cloud task button when extension bridge is enabled", () => { - render() - - const button = screen.getByTestId("cloud-task-button") - expect(button).toBeInTheDocument() - expect(button).toHaveAttribute("aria-label", "chat:task.openInCloud") - }) - - test("does not render when extension bridge is disabled", () => { - mockUseExtensionState.mockReturnValue({ - cloudUserInfo: { - id: "test-user", - email: "test@example.com", - extensionBridgeEnabled: false, - }, - cloudApiUrl: "https://app.roocode.com", - } as any) - - render() - - expect(screen.queryByTestId("cloud-task-button")).not.toBeInTheDocument() - }) - - test("does not render when cloudUserInfo is null", () => { - mockUseExtensionState.mockReturnValue({ - cloudUserInfo: null, - cloudApiUrl: "https://app.roocode.com", - } as any) - - render() - - expect(screen.queryByTestId("cloud-task-button")).not.toBeInTheDocument() - }) - - test("does not render when item has no id", () => { - const itemWithoutId = { ...mockItem, id: undefined } - render() - - expect(screen.queryByTestId("cloud-task-button")).not.toBeInTheDocument() - }) - - test("opens dialog when button is clicked", async () => { - render() - - const button = screen.getByTestId("cloud-task-button") - fireEvent.click(button) - - await waitFor(() => { - expect(screen.getByText("chat:task.openInCloud")).toBeInTheDocument() - }) - }) - - test("displays correct cloud URL in dialog", async () => { - render() - - const button = screen.getByTestId("cloud-task-button") - fireEvent.click(button) - - await waitFor(() => { - const input = screen.getByDisplayValue("https://app.roocode.com/task/test-task-id") - expect(input).toBeInTheDocument() - expect(input).toBeDisabled() - }) - }) - - test("displays intro text in dialog", async () => { - render() - - const button = screen.getByTestId("cloud-task-button") - fireEvent.click(button) - - await waitFor(() => { - expect(screen.getByText("chat:task.openInCloudIntro")).toBeInTheDocument() - }) - }) - - // Note: QR code generation is tested implicitly through the canvas rendering test below - - test("QR code canvas is rendered", async () => { - render() - - const button = screen.getByTestId("cloud-task-button") - fireEvent.click(button) - - await waitFor(() => { - // Canvas element doesn't have a specific aria label, find it directly - const canvas = document.querySelector("canvas") - expect(canvas).toBeInTheDocument() - expect(canvas?.tagName).toBe("CANVAS") - }) - }) - - // Note: Error handling for QR code generation is non-critical as per PR feedback - - test("button is disabled when disabled prop is true", () => { - render() - - const button = screen.getByTestId("cloud-task-button") - expect(button).toBeDisabled() - }) - - test("button is enabled when disabled prop is false", () => { - render() - - const button = screen.getByTestId("cloud-task-button") - expect(button).not.toBeDisabled() - }) - - test("dialog can be closed", async () => { - render() - - // Open dialog - const button = screen.getByTestId("cloud-task-button") - fireEvent.click(button) - - await waitFor(() => { - expect(screen.getByText("chat:task.openInCloud")).toBeInTheDocument() - }) - - // Close dialog by clicking the X button (assuming it exists in Dialog component) - const closeButton = screen.getByRole("button", { name: /close/i }) - fireEvent.click(closeButton) - - await waitFor(() => { - expect(screen.queryByText("chat:task.openInCloud")).not.toBeInTheDocument() - }) - }) - - test("copy button exists in dialog", async () => { - render() - - const button = screen.getByTestId("cloud-task-button") - fireEvent.click(button) - - await waitFor(() => { - // Look for the copy button (it should have a Copy icon) - const copyButtons = screen.getAllByRole("button") - const copyButton = copyButtons.find( - (btn) => btn.querySelector('[class*="lucide"]') || btn.textContent?.includes("Copy"), - ) - expect(copyButton).toBeInTheDocument() - }) - }) - - test("uses correct URL from getRooCodeApiUrl", async () => { - // Mock getRooCodeApiUrl to return a custom URL - vi.doMock("@roo-code/cloud/src/config", () => ({ - getRooCodeApiUrl: vi.fn(() => "https://custom.roocode.com"), - })) - - // Clear module cache and re-import to get the mocked version - vi.resetModules() - - // Since we can't easily test the dynamic import, let's skip this specific test - // The functionality is already covered by the main component using getRooCodeApiUrl - expect(true).toBe(true) - }) -}) diff --git a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx index e7b1c85434..c5f9c2055d 100644 --- a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx @@ -43,11 +43,11 @@ vi.mock("react-i18next", () => ({ "chat:task.connectToCloudDescription": "Sign in to Roo Code Cloud to share tasks", "chat:task.sharingDisabledByOrganization": "Sharing disabled by organization", "cloud:cloudBenefitsTitle": "Connect to Roo Code Cloud", + "cloud:cloudBenefitsSubtitle": "Sign in to Roo Code Cloud to share tasks", "cloud:cloudBenefitHistory": "Access your task history from anywhere", "cloud:cloudBenefitSharing": "Share tasks with your team", "cloud:cloudBenefitMetrics": "Track usage and costs", "cloud:connect": "Connect", - "history:copyPrompt": "Copy", } return translations[key] || key }, @@ -197,6 +197,7 @@ describe("TaskActions", () => { 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() expect(screen.getByText("Connect")).toBeInTheDocument() }) @@ -350,13 +351,30 @@ describe("TaskActions", () => { }) describe("Button States", () => { + it("keeps share, export, and copy buttons enabled but disables delete button when buttonsDisabled is true", () => { + render() + + // Find buttons by their labels/test IDs + const shareButton = screen.getByTestId("share-button") + const exportButton = screen.getByLabelText("Export task history") + const copyButton = screen.getByLabelText("history:copyPrompt") + const deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)") + + // Share, export, and copy buttons should be enabled regardless of buttonsDisabled + expect(shareButton).not.toBeDisabled() + expect(exportButton).not.toBeDisabled() + expect(copyButton).not.toBeDisabled() + // Delete button should respect buttonsDisabled + expect(deleteButton).toBeDisabled() + }) + it("share, export, and copy buttons are always enabled while delete button respects buttonsDisabled state", () => { // Test with buttonsDisabled = false const { rerender } = render() let shareButton = screen.getByTestId("share-button") let exportButton = screen.getByLabelText("Export task history") - let copyButton = screen.getByLabelText("Copy") + let copyButton = screen.getByLabelText("history:copyPrompt") let deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)") expect(shareButton).not.toBeDisabled() @@ -369,7 +387,7 @@ describe("TaskActions", () => { shareButton = screen.getByTestId("share-button") exportButton = screen.getByLabelText("Export task history") - copyButton = screen.getByLabelText("Copy") + copyButton = screen.getByLabelText("history:copyPrompt") deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)") // Share, export, and copy remain enabled diff --git a/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx index 6cdbeaf0c6..d89305348e 100644 --- a/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx @@ -32,62 +32,18 @@ vi.mock("@vscode/webview-ui-toolkit/react", () => ({ VSCodeBadge: ({ children }: { children: React.ReactNode }) =>
{children}
, })) -// Create a variable to hold the mock state -let mockExtensionState: { - apiConfiguration: ProviderSettings - currentTaskItem: { id: string } | null - clineMessages: any[] -} = { - apiConfiguration: { - apiProvider: "anthropic", - apiKey: "test-api-key", - apiModelId: "claude-3-opus-20240229", - } as ProviderSettings, - currentTaskItem: { id: "test-task-id" }, - clineMessages: [], -} - // Mock the ExtensionStateContext vi.mock("@src/context/ExtensionStateContext", () => ({ - useExtensionState: () => mockExtensionState, -})) - -// Mock the useCloudUpsell hook -vi.mock("@src/hooks/useCloudUpsell", () => ({ - useCloudUpsell: () => ({ - isOpen: false, - openUpsell: vi.fn(), - closeUpsell: vi.fn(), - handleConnect: vi.fn(), + useExtensionState: () => ({ + apiConfiguration: { + apiProvider: "anthropic", + apiKey: "test-api-key", // Add relevant fields + apiModelId: "claude-3-opus-20240229", // Add relevant fields + } as ProviderSettings, // Optional: Add type assertion if ProviderSettings is imported + currentTaskItem: { id: "test-task-id" }, }), })) -// Mock DismissibleUpsell component -vi.mock("@src/components/common/DismissibleUpsell", () => ({ - default: ({ children, ...props }: any) => ( -
- {children} -
- ), -})) - -// Mock CloudUpsellDialog component -vi.mock("@src/components/cloud/CloudUpsellDialog", () => ({ - CloudUpsellDialog: () => null, -})) - -// Mock findLastIndex from @roo/array -vi.mock("@roo/array", () => ({ - findLastIndex: (array: any[], predicate: (item: any) => boolean) => { - for (let i = array.length - 1; i >= 0; i--) { - if (predicate(array[i])) { - return i - } - } - return -1 - }, -})) - describe("TaskHeader", () => { const defaultProps: TaskHeaderProps = { task: { type: "say", ts: Date.now(), text: "Test task", images: [] }, @@ -179,182 +135,4 @@ describe("TaskHeader", () => { fireEvent.click(condenseButton!) expect(handleCondenseContext).not.toHaveBeenCalled() }) - - describe("DismissibleUpsell behavior", () => { - beforeEach(() => { - vi.useFakeTimers() - // Reset the mock state before each test - mockExtensionState = { - apiConfiguration: { - apiProvider: "anthropic", - apiKey: "test-api-key", - apiModelId: "claude-3-opus-20240229", - } as ProviderSettings, - currentTaskItem: { id: "test-task-id" }, - clineMessages: [], - } - }) - - afterEach(() => { - vi.useRealTimers() - }) - - it("should show DismissibleUpsell after 2 minutes when task is not complete", async () => { - renderTaskHeader() - - // Initially, the upsell should not be visible - expect(screen.queryByTestId("dismissible-upsell")).not.toBeInTheDocument() - - // Fast-forward time by 2 minutes to match component timeout - await vi.advanceTimersByTimeAsync(120_000) - - // The upsell should now be visible - expect(screen.getByTestId("dismissible-upsell")).toBeInTheDocument() - expect(screen.getByText("cloud:upsell.longRunningTask")).toBeInTheDocument() - }) - - it("should not show DismissibleUpsell when task is complete", async () => { - // Set up mock state with a completion_result message - mockExtensionState = { - ...mockExtensionState, - clineMessages: [ - { - type: "ask", - ask: "completion_result", - ts: Date.now(), - text: "Task completed!", - }, - ], - } - - renderTaskHeader() - - // Fast-forward time by more than 2 minutes - await vi.advanceTimersByTimeAsync(130_000) - - // The upsell should not appear - expect(screen.queryByTestId("dismissible-upsell")).not.toBeInTheDocument() - }) - - it("should not show DismissibleUpsell when currentTaskItem is null", async () => { - // Update the mock state to have null currentTaskItem - mockExtensionState = { - ...mockExtensionState, - currentTaskItem: null, - } - - renderTaskHeader() - - // Fast-forward time by more than 2 minutes - await vi.advanceTimersByTimeAsync(130_000) - - // The upsell should not appear - expect(screen.queryByTestId("dismissible-upsell")).not.toBeInTheDocument() - }) - - it("should not show DismissibleUpsell when task has completion_result in clineMessages", async () => { - // Set up mock state with a completion_result message from the start - mockExtensionState = { - ...mockExtensionState, - clineMessages: [ - { - type: "say", - say: "text", - ts: Date.now() - 1000, - text: "Working on task...", - }, - { - type: "ask", - ask: "completion_result", - ts: Date.now(), - text: "Task completed!", - }, - ], - } - - renderTaskHeader() - - // Fast-forward time by more than 2 minutes - await vi.advanceTimersByTimeAsync(130_000) - - // The upsell should not appear because the task is complete - expect(screen.queryByTestId("dismissible-upsell")).not.toBeInTheDocument() - }) - - it("should not show DismissibleUpsell when task has completion_result followed by resume messages", async () => { - // Set up mock state with a completion_result message followed by resume messages - mockExtensionState = { - ...mockExtensionState, - clineMessages: [ - { - type: "say", - say: "text", - ts: Date.now() - 3000, - text: "Working on task...", - }, - { - type: "ask", - ask: "completion_result", - ts: Date.now() - 2000, - text: "Task completed!", - }, - { - type: "ask", - ask: "resume_completed_task", - ts: Date.now() - 1000, - text: "Resume completed task?", - }, - { - type: "ask", - ask: "resume_task", - ts: Date.now(), - text: "Resume task?", - }, - ], - } - - renderTaskHeader() - - // Fast-forward time by more than 2 minutes - await vi.advanceTimersByTimeAsync(130_000) - - // The upsell should not appear because the last relevant message (skipping resume messages) is completion_result - expect(screen.queryByTestId("dismissible-upsell")).not.toBeInTheDocument() - }) - - it("should show DismissibleUpsell when task has non-completion message followed by resume messages", async () => { - // Set up mock state with a non-completion message followed by resume messages - mockExtensionState = { - ...mockExtensionState, - clineMessages: [ - { - type: "say", - say: "text", - ts: Date.now() - 3000, - text: "Working on task...", - }, - { - type: "ask", - ask: "tool", - ts: Date.now() - 2000, - text: "Need permission to use tool", - }, - { - type: "ask", - ask: "resume_task", - ts: Date.now() - 1000, - text: "Resume task?", - }, - ], - } - - renderTaskHeader() - - // Fast-forward time by 2 minutes to trigger the upsell - await vi.advanceTimersByTimeAsync(120_000) - - // The upsell should appear because the last relevant message (skipping resume messages) is not completion_result - expect(screen.getByTestId("dismissible-upsell")).toBeInTheDocument() - }) - }) }) diff --git a/webview-ui/src/components/cloud/CloudUpsellDialog.tsx b/webview-ui/src/components/cloud/CloudUpsellDialog.tsx deleted file mode 100644 index 6f1d8e7481..0000000000 --- a/webview-ui/src/components/cloud/CloudUpsellDialog.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { useTranslation } from "react-i18next" -import { Dialog, DialogContent, DialogHeader, Button } from "@/components/ui" -import RooHero from "../welcome/RooHero" -import { CircleDollarSign, FileStack, Router, Share } from "lucide-react" -import { DialogTitle } from "@radix-ui/react-dialog" - -interface CloudUpsellDialogProps { - open: boolean - onOpenChange: (open: boolean) => void - onConnect: () => void -} - -// Reusable method to render cloud benefits content -export const renderCloudBenefitsContent = (t: any) => { - return ( -
-
- -
-

{t("cloud:cloudBenefitsTitle")}

-
-
    -
  • - - {t("cloud:cloudBenefitWalkaway")} -
  • -
  • - - {t("cloud:cloudBenefitSharing")} -
  • -
  • - - {t("cloud:cloudBenefitMetrics")} -
  • -
  • - - {t("cloud:cloudBenefitHistory")} -
  • -
-
-
- ) -} - -export const CloudUpsellDialog = ({ open, onOpenChange, onConnect }: CloudUpsellDialogProps) => { - const { t } = useTranslation() - - return ( - - - - {/* Intentionally empty */} - - -
- {renderCloudBenefitsContent(t)} - -
- -
-
-
-
- ) -} diff --git a/webview-ui/src/components/cloud/CloudView.tsx b/webview-ui/src/components/cloud/CloudView.tsx index a89d3ee0d3..63733ef7d2 100644 --- a/webview-ui/src/components/cloud/CloudView.tsx +++ b/webview-ui/src/components/cloud/CloudView.tsx @@ -1,5 +1,5 @@ -import { useEffect, useRef, useState } from "react" -import { VSCodeButton, VSCodeProgressRing, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" +import { useEffect, useRef } from "react" +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" import { type CloudUserInfo, TelemetryEventName } from "@roo-code/types" @@ -8,9 +8,8 @@ import { useExtensionState } from "@src/context/ExtensionStateContext" import { vscode } from "@src/utils/vscode" import { telemetryClient } from "@src/utils/TelemetryClient" import { ToggleSwitch } from "@/components/ui/toggle-switch" -import { renderCloudBenefitsContent } from "./CloudUpsellDialog" -import { TriangleAlert } from "lucide-react" -import { cn } from "@/lib/utils" + +import { History, PiggyBank, SquareArrowOutUpRightIcon } from "lucide-react" // Define the production URL constant locally to avoid importing from cloud package in tests const PRODUCTION_ROO_CODE_API_URL = "https://app.roocode.com" @@ -24,32 +23,15 @@ type CloudViewProps = { export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: CloudViewProps) => { const { t } = useAppTranslation() - const { - remoteControlEnabled, - setRemoteControlEnabled, - taskSyncEnabled, - setTaskSyncEnabled, - featureRoomoteControlEnabled, - } = useExtensionState() + const { remoteControlEnabled, setRemoteControlEnabled } = useExtensionState() const wasAuthenticatedRef = useRef(false) - const timeoutRef = useRef(null) - const manualUrlInputRef = useRef(null) - // Manual URL entry state - const [authInProgress, setAuthInProgress] = useState(false) - const [showManualEntry, setShowManualEntry] = useState(false) - const [manualUrl, setManualUrl] = useState("") + + const rooLogoUri = (window as any).IMAGES_BASE_URI + "/roo-logo.svg" // Track authentication state changes to detect successful logout useEffect(() => { if (isAuthenticated) { wasAuthenticatedRef.current = true - // Clear auth in progress state when authentication succeeds - setAuthInProgress(false) - setShowManualEntry(false) - if (timeoutRef.current) { - clearTimeout(timeoutRef.current) - timeoutRef.current = null - } } else if (wasAuthenticatedRef.current && !isAuthenticated) { // User just logged out successfully // NOTE: Telemetry events use ACCOUNT_* naming for continuity with existing analytics @@ -59,64 +41,11 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl } }, [isAuthenticated]) - // Focus the manual URL input when it becomes visible - useEffect(() => { - if (showManualEntry && manualUrlInputRef.current) { - // Small delay to ensure the DOM is ready - setTimeout(() => { - manualUrlInputRef.current?.focus() - }, 50) - } - }, [showManualEntry]) - - // Cleanup timeout on unmount - useEffect(() => { - return () => { - if (timeoutRef.current) { - clearTimeout(timeoutRef.current) - } - } - }, []) - const handleConnectClick = () => { // Send telemetry for cloud connect action // NOTE: Using ACCOUNT_* telemetry events for backward compatibility with analytics telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_CLICKED) vscode.postMessage({ type: "rooCloudSignIn" }) - - // Start auth in progress state - show "Having trouble?" immediately for debugging - setAuthInProgress(true) - } - - const handleManualUrlChange = (e: any) => { - const url = e.target.value - setManualUrl(url) - - // Auto-trigger authentication when a complete URL is pasted (with slight delay to ensure full paste is processed) - setTimeout(() => { - if (url.trim() && url.includes("://") && url.includes("/auth/clerk/callback")) { - vscode.postMessage({ type: "rooCloudManualUrl", text: url.trim() }) - } - }, 100) - } - - const handleKeyDown = (e: any) => { - if (e.key === "Enter") { - const url = manualUrl.trim() - if (url && url.includes("://") && url.includes("/auth/clerk/callback")) { - vscode.postMessage({ type: "rooCloudManualUrl", text: url }) - } - } - } - - const handleShowManualEntry = () => { - setShowManualEntry(true) - } - - const handleReset = () => { - setAuthInProgress(false) - setShowManualEntry(false) - setManualUrl("") } const handleLogoutClick = () => { @@ -146,16 +75,10 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl vscode.postMessage({ type: "remoteControlEnabled", bool: newValue }) } - const handleTaskSyncToggle = () => { - const newValue = !taskSyncEnabled - setTaskSyncEnabled(newValue) - vscode.postMessage({ type: "taskSyncEnabled", bool: newValue }) - } - return (
-

{isAuthenticated && t("cloud:title")}

+

{t("cloud:title")}

{t("settings:common.done")} @@ -198,62 +121,24 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl
)} - {/* Task Sync Toggle - Always shown when authenticated */} -
-
- - {t("cloud:taskSync")} -
-
- {t("cloud:taskSyncDescription")} -
- {userInfo?.organizationId && ( -
- {t("cloud:taskSyncManagedByOrganization")} + {userInfo?.extensionBridgeEnabled && ( +
+
+ + {t("cloud:remoteControl")}
- )} - - {/* Remote Control Toggle - Only shown when both extensionBridgeEnabled and featureRoomoteControlEnabled are true */} - {userInfo?.extensionBridgeEnabled && featureRoomoteControlEnabled && ( - <> -
- - - {t("cloud:remoteControl")} - -
-
- {t("cloud:remoteControlDescription")} - {!taskSyncEnabled && ( -
- {t("cloud:remoteControlRequiresTaskSync")} -
- )} -
- - )} - - {/* Info text about usage metrics */} -
- {t("cloud:usageMetricsAlwaysReported")} +
+ {t("cloud:remoteControlDescription")} +
+
- -
-
+ )}
@@ -266,64 +151,53 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl ) : ( <> -
-
{renderCloudBenefitsContent(t)}
- - {!authInProgress && ( - - {t("cloud:connect")} - - )} - - {/* Manual entry section */} - {authInProgress && !showManualEntry && ( - // Timeout message with "Having trouble?" link -
-
- - {t("cloud:authWaiting")} -
- {!showManualEntry && ( - - )} +
+
+
+ Roo logo
- )} +
+
- {showManualEntry && ( - // Manual URL entry form -
-

- {t("cloud:pasteCallbackUrl")} -

- -

- or{" "} - -

-
- )} +
+

+ {t("cloud:cloudBenefitsTitle")} +

+
    +
  • + + {t("cloud:cloudBenefitSharing")} +
  • +
  • + + {t("cloud:cloudBenefitHistory")} +
  • +
  • + + {t("cloud:cloudBenefitMetrics")} +
  • +
+
+ +
+ + {t("cloud:connect")} +
)} {cloudApiUrl && cloudApiUrl !== PRODUCTION_ROO_CODE_API_URL && ( -
-
- +
+
{t("cloud:cloudUrlPillLabel")}: -
- ) - }, -) - -DismissibleUpsell.displayName = "DismissibleUpsell" - -export default DismissibleUpsell diff --git a/webview-ui/src/components/common/TelemetryBanner.tsx b/webview-ui/src/components/common/TelemetryBanner.tsx index 3d39b17115..4fcd7fa170 100644 --- a/webview-ui/src/components/common/TelemetryBanner.tsx +++ b/webview-ui/src/components/common/TelemetryBanner.tsx @@ -1,53 +1,85 @@ import { memo, useState } from "react" +import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react" +import styled from "styled-components" import { Trans } from "react-i18next" -import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" import type { TelemetrySetting } from "@roo-code/types" import { vscode } from "@src/utils/vscode" import { useAppTranslation } from "@src/i18n/TranslationContext" +const BannerContainer = styled.div` + background-color: var(--vscode-banner-background); + padding: 12px 20px; + display: flex; + flex-direction: column; + gap: 10px; + flex-shrink: 0; + margin-bottom: 6px; +` + +const ButtonContainer = styled.div` + display: flex; + gap: 8px; + width: 100%; + & > vscode-button { + flex: 1; + } +` + const TelemetryBanner = () => { const { t } = useAppTranslation() - const [isDismissed, setIsDismissed] = useState(false) + const [hasChosen, setHasChosen] = useState(false) - const handleClose = () => { - setIsDismissed(true) + const handleAllow = () => { + setHasChosen(true) vscode.postMessage({ type: "telemetrySetting", text: "enabled" satisfies TelemetrySetting }) } + const handleDeny = () => { + setHasChosen(true) + vscode.postMessage({ type: "telemetrySetting", text: "disabled" satisfies TelemetrySetting }) + } + const handleOpenSettings = () => { window.postMessage({ type: "action", action: "settingsButtonClicked", - values: { section: "about" }, + values: { section: "about" }, // Link directly to about settings with telemetry controls }) } - if (isDismissed) { - return null - } - return ( -
- {/* Close button (X) */} - - -
{t("welcome:telemetry.helpImprove")}
+
- , - }} - /> + {t("welcome:telemetry.title")} +
+ , + }} + /> +
+ , + }} + /> + . +
+
-
+ + + {t("welcome:telemetry.allow")} + + + {t("welcome:telemetry.deny")} + + + ) } diff --git a/webview-ui/src/components/common/__tests__/DismissibleUpsell.spec.tsx b/webview-ui/src/components/common/__tests__/DismissibleUpsell.spec.tsx deleted file mode 100644 index 3af66dfdf1..0000000000 --- a/webview-ui/src/components/common/__tests__/DismissibleUpsell.spec.tsx +++ /dev/null @@ -1,557 +0,0 @@ -import { render, screen, fireEvent, waitFor, act } from "@testing-library/react" -import { describe, it, expect, vi, beforeEach, afterEach } from "vitest" -import DismissibleUpsell from "../DismissibleUpsell" - -// Mock the vscode API -const mockPostMessage = vi.fn() -vi.mock("@src/utils/vscode", () => ({ - vscode: { - postMessage: (message: any) => mockPostMessage(message), - }, -})) - -// Mock the translation hook -vi.mock("@src/i18n/TranslationContext", () => ({ - useAppTranslation: () => ({ - t: (key: string) => { - const translations: Record = { - "common:dismiss": "Dismiss", - "common:dismissAndDontShowAgain": "Dismiss and don't show again", - } - return translations[key] || key - }, - }), -})) - -describe("DismissibleUpsell", () => { - beforeEach(() => { - mockPostMessage.mockClear() - vi.clearAllTimers() - }) - - afterEach(() => { - vi.clearAllTimers() - }) - - // Helper function to make the component visible - const makeUpsellVisible = () => { - const messageEvent = new MessageEvent("message", { - data: { - type: "dismissedUpsells", - list: [], // Empty list means no upsells are dismissed - }, - }) - window.dispatchEvent(messageEvent) - } - - it("renders children content", async () => { - render( - -
Test content
-
, - ) - - // Component starts hidden, make it visible - makeUpsellVisible() - - // Wait for component to become visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - }) - - it("requests dismissed upsells list on mount", () => { - render( - -
Test content
-
, - ) - - expect(mockPostMessage).toHaveBeenCalledWith({ - type: "getDismissedUpsells", - }) - }) - - it("hides the upsell when dismiss button is clicked", async () => { - const onDismiss = vi.fn() - const { container } = render( - -
Test content
-
, - ) - - // Make component visible first - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - // Find and click the dismiss button - const dismissButton = screen.getByRole("button", { name: /dismiss/i }) - fireEvent.click(dismissButton) - - // Check that the dismiss message was sent BEFORE hiding - expect(mockPostMessage).toHaveBeenCalledWith({ - type: "dismissUpsell", - upsellId: "test-upsell", - }) - - // Check that the component is no longer visible - await waitFor(() => { - expect(container.firstChild).toBeNull() - }) - - // Check that the callback was called - expect(onDismiss).toHaveBeenCalled() - }) - - it("hides the upsell if it's in the dismissed list", async () => { - const { container } = render( - -
Test content
-
, - ) - - // Component starts hidden by default - expect(container.firstChild).toBeNull() - - // Simulate receiving a message that this upsell is dismissed - const messageEvent = new MessageEvent("message", { - data: { - type: "dismissedUpsells", - list: ["test-upsell", "other-upsell"], - }, - }) - window.dispatchEvent(messageEvent) - - // Check that the component remains hidden - await waitFor(() => { - expect(container.firstChild).toBeNull() - }) - }) - - it("remains visible if not in the dismissed list", async () => { - render( - -
Test content
-
, - ) - - // Simulate receiving a message that doesn't include this upsell - const messageEvent = new MessageEvent("message", { - data: { - type: "dismissedUpsells", - list: ["other-upsell"], - }, - }) - window.dispatchEvent(messageEvent) - - // Check that the component is still visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - }) - - it("applies the className prop to the container", async () => { - const { container } = render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(container.firstChild).not.toBeNull() - }) - - expect(container.firstChild).toHaveClass("custom-class") - }) - - it("dismiss button has proper accessibility attributes", async () => { - render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - const dismissButton = screen.getByRole("button", { name: /dismiss/i }) - expect(dismissButton).toHaveAttribute("aria-label", "Dismiss") - expect(dismissButton).toHaveAttribute("title", "Dismiss and don't show again") - }) - - // New edge case tests - it("handles multiple rapid dismissals of the same component", async () => { - const onDismiss = vi.fn() - render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - const dismissButton = screen.getByRole("button", { name: /dismiss/i }) - - // Click multiple times rapidly - fireEvent.click(dismissButton) - fireEvent.click(dismissButton) - fireEvent.click(dismissButton) - - // Should only send one message - expect(mockPostMessage).toHaveBeenCalledTimes(2) // 1 for getDismissedUpsells, 1 for dismissUpsell - expect(mockPostMessage).toHaveBeenCalledWith({ - type: "dismissUpsell", - upsellId: "test-upsell", - }) - - // Callback should only be called once - expect(onDismiss).toHaveBeenCalledTimes(1) - }) - - it("does not update state after component unmounts", async () => { - const { unmount } = render( - -
Test content
-
, - ) - - // Unmount the component - unmount() - - // Simulate receiving a message after unmount - const messageEvent = new MessageEvent("message", { - data: { - type: "dismissedUpsells", - list: ["test-upsell"], - }, - }) - - // This should not cause any errors - act(() => { - window.dispatchEvent(messageEvent) - }) - - // No errors should be thrown - expect(true).toBe(true) - }) - - it("handles invalid/malformed messages gracefully", async () => { - render( - -
Test content
-
, - ) - - // First make it visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - // Send various malformed messages - const malformedMessages = [ - { type: "dismissedUpsells", list: null }, - { type: "dismissedUpsells", list: "not-an-array" }, - { type: "dismissedUpsells" }, // missing list - { type: "wrongType", list: ["test-upsell"] }, - null, - undefined, - "string-message", - ] - - malformedMessages.forEach((data) => { - const messageEvent = new MessageEvent("message", { data }) - window.dispatchEvent(messageEvent) - }) - - // Component should still be visible - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - it("ensures message is sent before component unmounts on dismiss", async () => { - const { unmount } = render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - const dismissButton = screen.getByRole("button", { name: /dismiss/i }) - fireEvent.click(dismissButton) - - // Message should be sent immediately - expect(mockPostMessage).toHaveBeenCalledWith({ - type: "dismissUpsell", - upsellId: "test-upsell", - }) - - // Unmount immediately after clicking - unmount() - - // Message was already sent before unmount - expect(mockPostMessage).toHaveBeenCalledWith({ - type: "dismissUpsell", - upsellId: "test-upsell", - }) - }) - - it("uses separate id and className props correctly", async () => { - const { container } = render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(container.firstChild).not.toBeNull() - }) - - // className should be applied to the container - expect(container.firstChild).toHaveClass("styling-class") - - // When dismissed, should use the id, not className - const dismissButton = screen.getByRole("button", { name: /dismiss/i }) - fireEvent.click(dismissButton) - - expect(mockPostMessage).toHaveBeenCalledWith({ - type: "dismissUpsell", - upsellId: "unique-id", - }) - }) - - it("calls onClick when the container is clicked", async () => { - const onClick = vi.fn() - render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - // Click on the container (not the dismiss button) - const container = screen.getByText("Test content").parentElement as HTMLElement - fireEvent.click(container) - - expect(onClick).toHaveBeenCalledTimes(1) - }) - - it("does not call onClick when dismiss button is clicked", async () => { - const onClick = vi.fn() - const onDismiss = vi.fn() - render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - // Click the dismiss button - const dismissButton = screen.getByRole("button", { name: /dismiss/i }) - fireEvent.click(dismissButton) - - // onClick should not be called, but onDismiss should - expect(onClick).not.toHaveBeenCalled() - expect(onDismiss).toHaveBeenCalledTimes(1) - }) - - it("adds cursor-pointer class when onClick is provided", async () => { - const { container, rerender } = render( - {}}> -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(container.firstChild).not.toBeNull() - }) - - // Should have cursor-pointer when onClick is provided - expect(container.firstChild).toHaveClass("cursor-pointer") - - // Re-render without onClick - rerender( - -
Test content
-
, - ) - - // Should not have cursor-pointer when onClick is not provided - expect(container.firstChild).not.toHaveClass("cursor-pointer") - }) - - it("handles both onClick and onDismiss independently", async () => { - const onClick = vi.fn() - const onDismiss = vi.fn() - const { container } = render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - // Click on the container - const containerDiv = screen.getByText("Test content").parentElement as HTMLElement - fireEvent.click(containerDiv) - expect(onClick).toHaveBeenCalledTimes(1) - expect(onDismiss).not.toHaveBeenCalled() - - // Reset mocks - onClick.mockClear() - onDismiss.mockClear() - - // Click the dismiss button - const dismissButton = screen.getByRole("button", { name: /dismiss/i }) - fireEvent.click(dismissButton) - - // Only onDismiss should be called - expect(onClick).not.toHaveBeenCalled() - expect(onDismiss).toHaveBeenCalledTimes(1) - - // Component should be hidden after dismiss - await waitFor(() => { - expect(container.firstChild).toBeNull() - }) - }) - - it("dismisses when clicked if dismissOnClick is true", async () => { - const onClick = vi.fn() - const onDismiss = vi.fn() - const { container } = render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - const containerDiv = screen.getByText("Test content").parentElement as HTMLElement - fireEvent.click(containerDiv) - - expect(onClick).toHaveBeenCalledTimes(1) - expect(onDismiss).toHaveBeenCalledTimes(1) - - expect(mockPostMessage).toHaveBeenCalledWith({ - type: "dismissUpsell", - upsellId: "test-upsell", - }) - - await waitFor(() => { - expect(container.firstChild).toBeNull() - }) - }) - - it("does not dismiss when clicked if dismissOnClick is false", async () => { - const onClick = vi.fn() - const onDismiss = vi.fn() - render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - const containerDiv = screen.getByText("Test content").parentElement as HTMLElement - fireEvent.click(containerDiv) - - expect(onClick).toHaveBeenCalledTimes(1) - expect(onDismiss).not.toHaveBeenCalled() - - expect(mockPostMessage).not.toHaveBeenCalledWith(expect.objectContaining({ type: "dismissUpsell" })) - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - it("does not dismiss when clicked if dismissOnClick is not provided (defaults to false)", async () => { - const onClick = vi.fn() - const onDismiss = vi.fn() - render( - -
Test content
-
, - ) - - // Make component visible - makeUpsellVisible() - - // Wait for component to be visible - await waitFor(() => { - expect(screen.getByText("Test content")).toBeInTheDocument() - }) - - const containerDiv = screen.getByText("Test content").parentElement as HTMLElement - fireEvent.click(containerDiv) - - expect(onClick).toHaveBeenCalledTimes(1) - expect(onDismiss).not.toHaveBeenCalled() - expect(screen.getByText("Test content")).toBeInTheDocument() - }) -}) diff --git a/webview-ui/src/components/settings/About.tsx b/webview-ui/src/components/settings/About.tsx index 9afee12d72..c25a1aebe3 100644 --- a/webview-ui/src/components/settings/About.tsx +++ b/webview-ui/src/components/settings/About.tsx @@ -40,7 +40,7 @@ export const About = ({ telemetrySetting, setTelemetrySetting, className, ...pro
{ const checked = e.target.checked === true setTelemetrySetting(checked ? "enabled" : "disabled") diff --git a/webview-ui/src/components/settings/providers/Ollama.tsx b/webview-ui/src/components/settings/providers/Ollama.tsx index b3ff00ccdd..b09ecad5d6 100644 --- a/webview-ui/src/components/settings/providers/Ollama.tsx +++ b/webview-ui/src/components/settings/providers/Ollama.tsx @@ -11,7 +11,6 @@ import { useRouterModels } from "@src/components/ui/hooks/useRouterModels" import { vscode } from "@src/utils/vscode" import { inputEventTransform } from "../transforms" -import { ModelRecord } from "@roo/api" type OllamaProps = { apiConfiguration: ProviderSettings @@ -21,7 +20,7 @@ type OllamaProps = { export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaProps) => { const { t } = useAppTranslation() - const [ollamaModels, setOllamaModels] = useState({}) + const [ollamaModels, setOllamaModels] = useState([]) const routerModels = useRouterModels() const handleInputChange = useCallback( @@ -41,7 +40,7 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro switch (message.type) { case "ollamaModels": { - const newModels = message.ollamaModels ?? {} + const newModels = message.ollamaModels ?? [] setOllamaModels(newModels) } break @@ -62,7 +61,7 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro if (!selectedModel) return false // Check if model exists in local ollama models - if (Object.keys(ollamaModels).length > 0 && selectedModel in ollamaModels) { + if (ollamaModels.length > 0 && ollamaModels.includes(selectedModel)) { return false // Model is available locally } @@ -117,13 +116,15 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro
)} - {Object.keys(ollamaModels).length > 0 && ( + {ollamaModels.length > 0 && ( - {Object.keys(ollamaModels).map((model) => ( + {ollamaModels.map((model) => ( {model} diff --git a/webview-ui/src/components/settings/providers/__tests__/Vertex.spec.tsx b/webview-ui/src/components/settings/providers/__tests__/Vertex.spec.tsx index c9765429cd..4abe1e8847 100644 --- a/webview-ui/src/components/settings/providers/__tests__/Vertex.spec.tsx +++ b/webview-ui/src/components/settings/providers/__tests__/Vertex.spec.tsx @@ -74,7 +74,6 @@ describe("Vertex", () => { { value: "us-east1", label: "us-east1" }, { value: "us-east4", label: "us-east4" }, { value: "us-east5", label: "us-east5" }, - { value: "us-south1", label: "us-south1" }, { value: "us-west1", label: "us-west1" }, { value: "us-west2", label: "us-west2" }, { value: "us-west3", label: "us-west3" }, diff --git a/webview-ui/src/components/ui/hooks/useOllamaModels.ts b/webview-ui/src/components/ui/hooks/useOllamaModels.ts deleted file mode 100644 index 67a172b0d8..0000000000 --- a/webview-ui/src/components/ui/hooks/useOllamaModels.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { useQuery } from "@tanstack/react-query" - -import { ModelRecord } from "@roo/api" -import { ExtensionMessage } from "@roo/ExtensionMessage" - -import { vscode } from "@src/utils/vscode" - -const getOllamaModels = async () => - new Promise((resolve, reject) => { - const cleanup = () => { - window.removeEventListener("message", handler) - } - - const timeout = setTimeout(() => { - cleanup() - reject(new Error("Ollama models request timed out")) - }, 10000) - - const handler = (event: MessageEvent) => { - const message: ExtensionMessage = event.data - - if (message.type === "ollamaModels") { - clearTimeout(timeout) - cleanup() - - if (message.ollamaModels) { - resolve(message.ollamaModels) - } else { - reject(new Error("No Ollama models in response")) - } - } - } - - window.addEventListener("message", handler) - vscode.postMessage({ type: "requestOllamaModels" }) - }) - -export const useOllamaModels = (modelId?: string) => - useQuery({ queryKey: ["ollamaModels"], queryFn: () => (modelId ? getOllamaModels() : {}) }) diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index f8a005e86a..b7fe4ff03d 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -64,23 +64,19 @@ import type { ModelRecord, RouterModels } from "@roo/api" import { useRouterModels } from "./useRouterModels" import { useOpenRouterModelProviders } from "./useOpenRouterModelProviders" import { useLmStudioModels } from "./useLmStudioModels" -import { useOllamaModels } from "./useOllamaModels" export const useSelectedModel = (apiConfiguration?: ProviderSettings) => { const provider = apiConfiguration?.apiProvider || "anthropic" const openRouterModelId = provider === "openrouter" ? apiConfiguration?.openRouterModelId : undefined const lmStudioModelId = provider === "lmstudio" ? apiConfiguration?.lmStudioModelId : undefined - const ollamaModelId = provider === "ollama" ? apiConfiguration?.ollamaModelId : undefined const routerModels = useRouterModels() const openRouterModelProviders = useOpenRouterModelProviders(openRouterModelId) const lmStudioModels = useLmStudioModels(lmStudioModelId) - const ollamaModels = useOllamaModels(ollamaModelId) const { id, info } = apiConfiguration && (typeof lmStudioModelId === "undefined" || typeof lmStudioModels.data !== "undefined") && - (typeof ollamaModelId === "undefined" || typeof ollamaModels.data !== "undefined") && typeof routerModels.data !== "undefined" && typeof openRouterModelProviders.data !== "undefined" ? getSelectedModel({ @@ -89,7 +85,6 @@ export const useSelectedModel = (apiConfiguration?: ProviderSettings) => { routerModels: routerModels.data, openRouterModelProviders: openRouterModelProviders.data, lmStudioModels: lmStudioModels.data, - ollamaModels: ollamaModels.data, }) : { id: anthropicDefaultModelId, info: undefined } @@ -114,14 +109,12 @@ function getSelectedModel({ routerModels, openRouterModelProviders, lmStudioModels, - ollamaModels, }: { provider: ProviderName apiConfiguration: ProviderSettings routerModels: RouterModels openRouterModelProviders: Record lmStudioModels: ModelRecord | undefined - ollamaModels: ModelRecord | undefined }): { id: string; info: ModelInfo | undefined } { // the `undefined` case are used to show the invalid selection to prevent // users from seeing the default model if their selection is invalid @@ -262,7 +255,7 @@ function getSelectedModel({ } case "ollama": { const id = apiConfiguration.ollamaModelId ?? "" - const info = ollamaModels && ollamaModels[apiConfiguration.ollamaModelId!] + const info = routerModels.ollama && routerModels.ollama[id] return { id, info: info || undefined, diff --git a/webview-ui/src/components/welcome/RooCloudCTA.tsx b/webview-ui/src/components/welcome/RooCloudCTA.tsx new file mode 100644 index 0000000000..c116cdbc3c --- /dev/null +++ b/webview-ui/src/components/welcome/RooCloudCTA.tsx @@ -0,0 +1,23 @@ +import { useTranslation } from "react-i18next" + +export function RooCloudCTA() { + const { t } = useTranslation("chat") + + return ( +
+ +
+

+ {t("rooCloudCTA.title")} +
+ {t("rooCloudCTA.description")} +

+

+ {t("rooCloudCTA.joinWaitlist")} +

+
+
+ ) +} + +export default RooCloudCTA diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 5534686db6..2f4af84f58 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -101,10 +101,6 @@ export interface ExtensionStateContextType extends ExtensionState { setEnableMcpServerCreation: (value: boolean) => void remoteControlEnabled: boolean setRemoteControlEnabled: (value: boolean) => void - taskSyncEnabled: boolean - setTaskSyncEnabled: (value: boolean) => void - featureRoomoteControlEnabled: boolean - setFeatureRoomoteControlEnabled: (value: boolean) => void alwaysApproveResubmit?: boolean setAlwaysApproveResubmit: (value: boolean) => void requestDelaySeconds: number @@ -205,8 +201,6 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode mcpEnabled: true, enableMcpServerCreation: false, remoteControlEnabled: false, - taskSyncEnabled: false, - featureRoomoteControlEnabled: false, alwaysApproveResubmit: false, requestDelaySeconds: 5, currentApiConfigName: "default", @@ -423,8 +417,6 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode alwaysAllowFollowupQuestions, followupAutoApproveTimeoutMs, remoteControlEnabled: state.remoteControlEnabled ?? false, - taskSyncEnabled: state.taskSyncEnabled, - featureRoomoteControlEnabled: state.featureRoomoteControlEnabled ?? false, setExperimentEnabled: (id, enabled) => setState((prevState) => ({ ...prevState, experiments: { ...prevState.experiments, [id]: enabled } })), setApiConfiguration, @@ -472,9 +464,6 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode setEnableMcpServerCreation: (value) => setState((prevState) => ({ ...prevState, enableMcpServerCreation: value })), setRemoteControlEnabled: (value) => setState((prevState) => ({ ...prevState, remoteControlEnabled: value })), - setTaskSyncEnabled: (value) => setState((prevState) => ({ ...prevState, taskSyncEnabled: value }) as any), - setFeatureRoomoteControlEnabled: (value) => - setState((prevState) => ({ ...prevState, featureRoomoteControlEnabled: value })), setAlwaysApproveResubmit: (value) => setState((prevState) => ({ ...prevState, alwaysApproveResubmit: value })), setRequestDelaySeconds: (value) => setState((prevState) => ({ ...prevState, requestDelaySeconds: value })), setCurrentApiConfigName: (value) => setState((prevState) => ({ ...prevState, currentApiConfigName: value })), diff --git a/webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx b/webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx index 33d7dc0ec7..c45b997622 100644 --- a/webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx +++ b/webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx @@ -211,9 +211,6 @@ describe("mergeExtensionState", () => { hasOpenedModeSelector: false, // Add the new required property maxImageFileSize: 5, maxTotalImageSize: 20, - remoteControlEnabled: false, - taskSyncEnabled: false, - featureRoomoteControlEnabled: false, } const prevState: ExtensionState = { diff --git a/webview-ui/src/hooks/useCloudUpsell.ts b/webview-ui/src/hooks/useCloudUpsell.ts deleted file mode 100644 index 1476a5a83e..0000000000 --- a/webview-ui/src/hooks/useCloudUpsell.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { useState, useCallback, useRef, useEffect } from "react" -import { TelemetryEventName } from "@roo-code/types" -import { vscode } from "@/utils/vscode" -import { telemetryClient } from "@/utils/TelemetryClient" -import { useExtensionState } from "@/context/ExtensionStateContext" - -interface UseCloudUpsellOptions { - onAuthSuccess?: () => void - autoOpenOnAuth?: boolean -} - -export const useCloudUpsell = (options: UseCloudUpsellOptions = {}) => { - const { onAuthSuccess, autoOpenOnAuth = false } = options - const [isOpen, setIsOpen] = useState(false) - const [shouldOpenOnAuth, setShouldOpenOnAuth] = useState(false) - const { cloudIsAuthenticated, sharingEnabled } = useExtensionState() - const wasUnauthenticatedRef = useRef(false) - const initiatedAuthRef = useRef(false) - - // Track authentication state changes - useEffect(() => { - if (!cloudIsAuthenticated || !sharingEnabled) { - wasUnauthenticatedRef.current = true - } else if (wasUnauthenticatedRef.current && cloudIsAuthenticated && sharingEnabled) { - // User just authenticated - if (initiatedAuthRef.current) { - // Auth was initiated from this hook - telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_SUCCESS) - setIsOpen(false) // Close the upsell dialog - - if (autoOpenOnAuth && shouldOpenOnAuth) { - onAuthSuccess?.() - setShouldOpenOnAuth(false) - } - - initiatedAuthRef.current = false // Reset the flag - } - wasUnauthenticatedRef.current = false - } - }, [cloudIsAuthenticated, sharingEnabled, onAuthSuccess, autoOpenOnAuth, shouldOpenOnAuth]) - - const openUpsell = useCallback(() => { - setIsOpen(true) - }, []) - - const closeUpsell = useCallback(() => { - setIsOpen(false) - setShouldOpenOnAuth(false) - }, []) - - const handleConnect = useCallback(() => { - // Mark that authentication was initiated from this hook - initiatedAuthRef.current = true - setShouldOpenOnAuth(true) - - // Send message to VS Code to initiate sign in - vscode.postMessage({ type: "rooCloudSignIn" }) - - // Close the upsell dialog - closeUpsell() - }, [closeUpsell]) - - return { - isOpen, - openUpsell, - closeUpsell, - handleConnect, - isAuthenticated: cloudIsAuthenticated, - sharingEnabled, - } -} diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index d0d2bbc1f5..1d20be0c40 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Inicia sessió a Roo Code Cloud per compartir tasques", "sharingDisabledByOrganization": "Compartició deshabilitada per l'organització", "shareSuccessOrganization": "Enllaç d'organització copiat al porta-retalls", - "shareSuccessPublic": "Enllaç públic copiat al porta-retalls", - "openInCloud": "Obrir tasca a Roo Code Cloud", - "openInCloudIntro": "Continua monitoritzant o interactuant amb Roo des de qualsevol lloc. Escaneja, fes clic o copia per obrir." + "shareSuccessPublic": "Enllaç públic copiat al porta-retalls" }, "unpin": "Desfixar", "pin": "Fixar", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} Llançat", - "description": "Presentem Roo Code Cloud: Portant el poder de Roo més enllà de l'IDE", - "feature1": "Segueix el progrés de les tasques des de qualsevol lloc (Gratuït): Obté actualitzacions en temps real de tasques de llarga durada sense quedar-te atrapat a la teva IDE", - "feature2": "Controla l'Extensió Roo remotament (Pro): Inicia, atura i interactua amb tasques des d'una interfície de navegador basada en xat.", - "learnMore": "Llest per prendre el control? Aprèn més aquí.", - "visitCloudButton": "Visita Roo Code Cloud", - "socialLinks": "Uneix-te a nosaltres a X, Discord, o r/RooCode" + "stealthModel": { + "feature": "El model stealth Sonic ara és Grok Code Fast! Aquest model de raonament d'alt rendiment està disponible com a grok-code-fast-1 sota el proveïdor xAI (Grok).", + "note": "Com a agraïment per tots els comentaris útils sobre Sonic, xAI està ampliant l'accés gratuït a grok-code-fast-1 durant una setmana més a través del proveïdor Roo Code Cloud.", + "connectButton": "Connectar amb Roo Code Cloud", + "selectModel": "Visita la Configuració per actualitzar la configuració del proveïdor." + }, + "description": "Roo Code {{version}} porta noves funcions potents i millores significatives per millorar el vostre flux de treball de desenvolupament.", + "whatsNew": "Novetats", + "feature1": "Cua de Missatges: Posa en cua múltiples missatges mentre Roo està treballant, permetent-te continuar planificant el teu flux de treball sense interrupcions.", + "feature2": "Comandaments de Barra Personalitzats: Crea comandaments de barra personalitzats per a accés ràpid a prompts i fluxos de treball utilitzats freqüentment, amb gestió completa de la interfície d'usuari.", + "feature3": "Eines Gemini Millorades: Noves capacitats de context d'URL i fonamentació de cerca de Google proporcionen als models Gemini informació web en temps real i capacitats de recerca millorades.", + "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/ca/cloud.json b/webview-ui/src/i18n/locales/ca/cloud.json index ec2a989ae7..02714c7c4b 100644 --- a/webview-ui/src/i18n/locales/ca/cloud.json +++ b/webview-ui/src/i18n/locales/ca/cloud.json @@ -6,26 +6,13 @@ "signIn": "Connecta't a Roo Code Cloud", "connect": "Connecta", "cloudBenefitsTitle": "Connecta't a Roo Code Cloud", + "cloudBenefitsSubtitle": "Sincronitza els teus prompts i telemetria per habilitar:", + "cloudBenefitHistory": "Historial de tasques en línia", + "cloudBenefitSharing": "Funcions de compartició i col·laboració", + "cloudBenefitMetrics": "Mètriques d'ús basades en tasques, tokens i costos", "cloudBenefitWalkaway": "Segueix i controla tasques des de qualsevol lloc amb Roomote Control", - "cloudBenefitSharing": "Comparteix tasques amb altres", - "cloudBenefitHistory": "Accedeix al teu historial de tasques", - "cloudBenefitMetrics": "Obtén una visió holística del teu consum de tokens", - "visitCloudWebsite": "Visita Roo Code Cloud", - "taskSync": "Sincronització de tasques", - "taskSyncDescription": "Sincronitza les teves tasques per veure-les i compartir-les a Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Permet controlar tasques des de Roo Code Cloud", - "remoteControlRequiresTaskSync": "La sincronització de tasques ha d'estar habilitada per utilitzar Roomote Control", - "taskSyncManagedByOrganization": "La sincronització de tasques la gestiona la teva organització", - "usageMetricsAlwaysReported": "La informació d'ús del model sempre es reporta quan s'ha iniciat sessió", - "cloudUrlPillLabel": "URL de Roo Code Cloud", - "authWaiting": "Esperant que es completi l'autenticació...", - "havingTrouble": "Tens problemes?", - "pasteCallbackUrl": "Copia l'URL de redirect del teu navegador i enganxa-la aquí:", - "startOver": "Torna a començar", - "upsell": { - "autoApprovePowerUser": "Donant-li una mica d'independència a Roo? Controla'l des de qualsevol lloc amb Roo Code Cloud. Més informació.", - "longRunningTask": "Això pot trigar una estona. Continua des de qualsevol lloc amb Cloud.", - "taskList": "Roo Code Cloud ja és aquí: segueix i controla les teves tasques des de qualsevol lloc. Més informació." - } + "remoteControlDescription": "Permet seguir i interactuar amb tasques en aquest espai de treball amb Roo Code Cloud", + "visitCloudWebsite": "Visita Roo Code Cloud", + "cloudUrlPillLabel": "URL de Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index 53103cd5fe..d785ed5fe0 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -792,7 +792,7 @@ "feedback": "Si teniu qualsevol pregunta o comentari, no dubteu a obrir un issue a github.com/RooCodeInc/Roo-Code o unir-vos a reddit.com/r/RooCode o discord.gg/roocode", "telemetry": { "label": "Permetre informes anònims d'errors i ús", - "description": "Ajuda a millorar Roo Code enviant dades d'ús anònimes i informes d'error. Aquesta telemetria no recull codi, prompts o informació personal. Consulta la nostra política de privacitat per a més detalls. Pots desactivar-ho en qualsevol moment." + "description": "Ajudeu a millorar Roo Code enviant dades d'ús anònimes i informes d'errors. Mai s'envia codi, prompts o informació personal. Vegeu la nostra política de privacitat per a més detalls." }, "settings": { "import": "Importar", diff --git a/webview-ui/src/i18n/locales/ca/welcome.json b/webview-ui/src/i18n/locales/ca/welcome.json index 4b3e75a3e1..8ef62ea205 100644 --- a/webview-ui/src/i18n/locales/ca/welcome.json +++ b/webview-ui/src/i18n/locales/ca/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Recomanem utilitzar un router LLM:", "startCustom": "O pots utilitzar la teva pròpia clau API:", "telemetry": { - "helpImprove": "Ajuda a millorar Roo Code", - "helpImproveMessage": "Roo Code recopila dades d'errors i d'ús per ajudar-nos a corregir errors i millorar l'extensió. Aquesta telemetria no recopila codi, prompts o informació personal. Pots desactivar això a la configuració." + "title": "Ajuda a millorar Roo Code", + "anonymousTelemetry": "Envia dades d'ús i errors anònims per ajudar-nos a corregir errors i millorar l'extensió. No s'envia mai cap codi, text o informació personal.", + "changeSettings": "Sempre pots canviar això a la part inferior de la configuració", + "settings": "configuració", + "allow": "Permetre", + "deny": "Denegar" }, "importSettings": "Importar configuració" } diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index 6c69647644..82f1c77fbf 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Melde dich bei Roo Code Cloud an, um Aufgaben zu teilen", "sharingDisabledByOrganization": "Freigabe von der Organisation deaktiviert", "shareSuccessOrganization": "Organisationslink in die Zwischenablage kopiert", - "shareSuccessPublic": "Öffentlicher Link in die Zwischenablage kopiert", - "openInCloud": "Aufgabe in Roo Code Cloud öffnen", - "openInCloudIntro": "Überwache oder interagiere mit Roo von überall aus. Scanne, klicke oder kopiere zum Öffnen." + "shareSuccessPublic": "Öffentlicher Link in die Zwischenablage kopiert" }, "unpin": "Lösen von oben", "pin": "Anheften", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} veröffentlicht", - "description": "Wir stellen vor: Roo Code Cloud: Die Macht von Roo über die IDE hinaus bringen", - "feature1": "Aufgabenfortschritt von überall verfolgen (Kostenlos): Erhalte Echtzeit-Updates zu lang laufenden Aufgaben, ohne in deiner IDE festzustecken", - "feature2": "Die Roo-Erweiterung fernsteuern (Pro): Starte, stoppe und interagiere mit Aufgaben über eine chat-basierte Browser-Oberfläche.", - "learnMore": "Bereit, die Kontrolle zu übernehmen? Erfahre mehr hier.", - "visitCloudButton": "Roo Code Cloud besuchen", - "socialLinks": "Folge uns auf X, Discord oder r/RooCode" + "stealthModel": { + "feature": "Das Sonic Stealth-Modell heißt jetzt Grok Code Fast! Dieses hochleistungsfähige Reasoning-Modell ist als grok-code-fast-1 unter dem xAI (Grok) Provider verfügbar.", + "note": "Als Dankeschön für all das hilfreiche Feedback zu Sonic erweitert xAI den kostenlosen Zugang zu grok-code-fast-1 für eine weitere Woche über den Roo Code Cloud-Anbieter.", + "connectButton": "Mit Roo Code Cloud verbinden", + "selectModel": "Besuche die Einstellungen, um deine Provider-Konfiguration zu aktualisieren." + }, + "description": "Roo Code {{version}} bringt mächtige neue Funktionen und bedeutende Verbesserungen, um deinen Entwicklungsworkflow zu verbessern.", + "whatsNew": "Was ist neu", + "feature1": "Nachrichten-Warteschlange: Stelle mehrere Nachrichten in die Warteschlange, während Roo arbeitet, damit du deinen Workflow ohne Unterbrechung weiter planen kannst.", + "feature2": "Benutzerdefinierte Slash-Befehle: Erstelle personalisierte Slash-Befehle für schnellen Zugriff auf häufig verwendete Prompts und Workflows mit vollständiger UI-Verwaltung.", + "feature3": "Erweiterte Gemini-Tools: Neue URL-Kontext- und Google-Such-Grundlagen-Funktionen bieten Gemini-Modellen Echtzeit-Web-Informationen und erweiterte Recherche-Fähigkeiten.", + "hideButton": "Ankündigung ausblenden", + "detailsDiscussLinks": "Erhalte mehr Details und diskutiere auf Discord und Reddit 🚀" }, "browser": { "rooWantsToUse": "Roo möchte den Browser verwenden:", diff --git a/webview-ui/src/i18n/locales/de/cloud.json b/webview-ui/src/i18n/locales/de/cloud.json index 1f83e70bad..cbba345399 100644 --- a/webview-ui/src/i18n/locales/de/cloud.json +++ b/webview-ui/src/i18n/locales/de/cloud.json @@ -4,28 +4,15 @@ "logOut": "Abmelden", "testApiAuthentication": "API-Authentifizierung testen", "signIn": "Mit Roo Code Cloud verbinden", - "connect": "Jetzt verbinden", + "connect": "Verbinden", "cloudBenefitsTitle": "Mit Roo Code Cloud verbinden", + "cloudBenefitsSubtitle": "Synchronisiere deine Prompts und Telemetrie, um folgendes zu aktivieren:", + "cloudBenefitHistory": "Online-Aufgabenverlauf", + "cloudBenefitSharing": "Freigabe- und Kollaborationsfunktionen", + "cloudBenefitMetrics": "Aufgaben-, Token- und kostenbasierte Nutzungsmetriken", "cloudBenefitWalkaway": "Verfolge und steuere Aufgaben von überall mit Roomote Control", - "cloudBenefitSharing": "Aufgaben mit anderen teilen", - "cloudBenefitHistory": "Auf deinen Aufgabenverlauf zugreifen", - "cloudBenefitMetrics": "Erhalte einen ganzheitlichen Überblick über deinen Token-Verbrauch", - "visitCloudWebsite": "Roo Code Cloud besuchen", - "taskSync": "Aufgabensynchronisierung", - "taskSyncDescription": "Synchronisiere deine Aufgaben zum Anzeigen und Teilen in Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Ermöglicht die Steuerung von Aufgaben über Roo Code Cloud", - "remoteControlRequiresTaskSync": "Die Aufgabensynchronisierung muss aktiviert sein, um Roomote Control zu verwenden", - "taskSyncManagedByOrganization": "Die Aufgabensynchronisierung wird von deiner Organisation verwaltet", - "usageMetricsAlwaysReported": "Modellnutzungsinformationen werden bei Anmeldung immer gemeldet", - "authWaiting": "Warte auf Abschluss der Authentifizierung...", - "havingTrouble": "Probleme?", - "pasteCallbackUrl": "Kopiere die Redirect-URL aus deinem Browser und füge sie hier ein:", - "startOver": "Von vorne beginnen", - "cloudUrlPillLabel": "Roo Code Cloud URL", - "upsell": { - "autoApprovePowerUser": "Roo etwas Unabhängigkeit geben? Kontrolliere es von überall mit Roo Code Cloud. Mehr erfahren.", - "longRunningTask": "Das könnte eine Weile dauern. Mit Cloud von überall weitermachen.", - "taskList": "Roo Code Cloud ist hier: Verfolge und kontrolliere deine Aufgaben von überall. Mehr erfahren." - } + "remoteControlDescription": "Ermöglicht das Verfolgen und Interagieren mit Aufgaben in diesem Arbeitsbereich mit Roo Code Cloud", + "visitCloudWebsite": "Roo Code Cloud besuchen", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index ac56ae82be..6648b6e670 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -792,7 +792,7 @@ "feedback": "Wenn du Fragen oder Feedback hast, kannst du gerne ein Issue auf github.com/RooCodeInc/Roo-Code eröffnen oder reddit.com/r/RooCode oder discord.gg/roocode beitreten", "telemetry": { "label": "Anonyme Fehler- und Nutzungsberichte zulassen", - "description": "Hilf mit, Roo Code zu verbessern, indem du anonyme Nutzungsdaten und Fehlerberichte sendest. Diese Telemetrie sammelt keine Code-, Prompt- oder persönliche Informationen. Weitere Einzelheiten findest du in unserer Datenschutzrichtlinie." + "description": "Hilf mit, Roo Code zu verbessern, indem du anonyme Nutzungsdaten und Fehlerberichte sendest. Es werden niemals Code, Prompts oder persönliche Informationen gesendet (es sei denn, du verbindest dich mit Roo Code Cloud). Weitere Einzelheiten findest du in unserer Datenschutzrichtlinie." }, "settings": { "import": "Importieren", diff --git a/webview-ui/src/i18n/locales/de/welcome.json b/webview-ui/src/i18n/locales/de/welcome.json index 13cf9f8687..8b322380df 100644 --- a/webview-ui/src/i18n/locales/de/welcome.json +++ b/webview-ui/src/i18n/locales/de/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Wir empfehlen die Verwendung eines LLM-Routers:", "startCustom": "Oder du kannst deinen eigenen API-Schlüssel verwenden:", "telemetry": { - "helpImprove": "Hilf, Roo Code zu verbessern", - "helpImproveMessage": "Roo Code sammelt Fehler- und Nutzungsdaten, um uns dabei zu helfen, Fehler zu beheben und die Erweiterung zu verbessern. Diese Telemetrie sammelt keine Code-, Prompt- oder persönliche Informationen. Du kannst diese in den Einstellungen deaktivieren." + "title": "Hilf, Roo Code zu verbessern", + "anonymousTelemetry": "Sende anonyme Fehler- und Nutzungsdaten, um uns bei der Fehlerbehebung und Verbesserung der Erweiterung zu helfen. Es werden niemals Code, Texte oder persönliche Informationen gesendet.", + "changeSettings": "Du kannst dies jederzeit unten in den Einstellungen ändern", + "settings": "Einstellungen", + "allow": "Erlauben", + "deny": "Ablehnen" }, "importSettings": "Einstellungen importieren" } diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 38448ffee0..11935456a3 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Sign in to Roo Code Cloud to share tasks", "sharingDisabledByOrganization": "Sharing disabled by organization", "shareSuccessOrganization": "Organization link copied to clipboard", - "shareSuccessPublic": "Public link copied to clipboard", - "openInCloud": "Open task in Roo Code Cloud", - "openInCloudIntro": "Keep monitoring or interacting with Roo from anywhere. Scan, click or copy to open." + "shareSuccessPublic": "Public link copied to clipboard" }, "unpin": "Unpin", "pin": "Pin", @@ -147,7 +145,9 @@ "failed": "API Request Failed", "streaming": "API Request...", "cancelled": "API Request Cancelled", - "streamingFailed": "API Streaming Failed" + "streamingFailed": "API Streaming Failed", + "input": "Input", + "output": "Output" }, "checkpoint": { "regular": "Checkpoint", @@ -280,12 +280,12 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} Released", - "description": "Introducing Roo Code Cloud: Bringing the power of Roo beyond the IDE", - "feature1": "Track task progress from anywhere (Free): Get real-time updates on long-running tasks without being stuck in your IDE", - "feature2": "Control the Roo Extension remotely (Pro): Start, stop, and interact with tasks from a chat-based browser interface.", - "learnMore": "Ready to take control? Learn more here.", - "visitCloudButton": "Visit Roo Code Cloud", - "socialLinks": "Join us on X, Discord, or r/RooCode" + "stealthModel": { + "feature": "The Sonic stealth model is now Grok Code Fast! This high-performance reasoning model is available as grok-code-fast-1 under the xAI (Grok) provider.", + "note": "As a thank you for all the helpful feedback on Sonic, xAI is extending free access to grok-code-fast-1 for another week through the Roo Code Cloud provider.", + "connectButton": "Connect to Roo Code Cloud", + "selectModel": "Visit Settings to update your provider configuration." + } }, "reasoning": { "thinking": "Thinking", @@ -356,6 +356,11 @@ "versionIndicator": { "ariaLabel": "Version {{version}} - Click to view release notes" }, + "rooCloudCTA": { + "title": "Roo Code Cloud is evolving!", + "description": "Run Roomote agents in the cloud, access your tasks from anywhere, collaborate with others, and more.", + "joinWaitlist": "Sign up to get the latest updates." + }, "command": { "triggerDescription": "Trigger the {{name}} command" }, diff --git a/webview-ui/src/i18n/locales/en/cloud.json b/webview-ui/src/i18n/locales/en/cloud.json index b8afcc4db4..88948c9153 100644 --- a/webview-ui/src/i18n/locales/en/cloud.json +++ b/webview-ui/src/i18n/locales/en/cloud.json @@ -4,28 +4,14 @@ "logOut": "Log out", "testApiAuthentication": "Test API Authentication", "signIn": "Connect to Roo Code Cloud", - "connect": "Get started", - "cloudBenefitsTitle": "Try Roo Code Cloud", - "cloudBenefitWalkaway": "Follow and control tasks from anywhere (including your phone)", + "connect": "Connect Now", + "cloudBenefitsTitle": "Connect to Roo Code Cloud", + "cloudBenefitWalkaway": "Follow and control tasks from anywhere with Roomote Control", "cloudBenefitSharing": "Share tasks with others", - "cloudBenefitHistory": "Access your task history from anywhere", + "cloudBenefitHistory": "Access your task history", "cloudBenefitMetrics": "Get a holistic view of your token consumption", "visitCloudWebsite": "Visit Roo Code Cloud", - "taskSync": "Task sync", - "taskSyncDescription": "Sync your tasks for viewing and sharing on Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Allow controlling tasks from Roo Code Cloud", - "remoteControlRequiresTaskSync": "Task sync must be enabled to use Roomote Control", - "taskSyncManagedByOrganization": "Task sync is managed by your organization", - "usageMetricsAlwaysReported": "Model usage info is always reported when logged in", - "cloudUrlPillLabel": "Roo Code Cloud URL", - "authWaiting": "Waiting for browser authentication...", - "havingTrouble": "Having trouble?", - "pasteCallbackUrl": "Copy the redirect URL from your browser and paste it here:", - "startOver": "Start over", - "upsell": { - "autoApprovePowerUser": "Giving Roo some independence? Control it from anywhere with Roo Code Cloud. Learn more.", - "longRunningTask": "This might take a while. Continue from anywhere with Cloud.", - "taskList": "Roo Code Cloud is here: follow and control your tasks from anywhere. Learn more." - } + "remoteControlDescription": "Enable following and interacting with tasks in this workspace with Roo Code Cloud", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 3c71e237b1..1cb4b144f7 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -791,7 +791,7 @@ "feedback": "If you have any questions or feedback, feel free to open an issue at github.com/RooCodeInc/Roo-Code or join reddit.com/r/RooCode or discord.gg/roocode", "telemetry": { "label": "Allow anonymous error and usage reporting", - "description": "Help improve Roo Code by sending anonymous usage data and error reports. This telemetry does not collect code, prompts or personal information. See our privacy policy for more details." + "description": "Help improve Roo Code by sending anonymous usage data and error reports. No code, prompts, or personal information is ever sent (unless you connect to Roo Code Cloud). See our privacy policy for more details." }, "settings": { "import": "Import", diff --git a/webview-ui/src/i18n/locales/en/welcome.json b/webview-ui/src/i18n/locales/en/welcome.json index b19245fa8e..2202f6fd61 100644 --- a/webview-ui/src/i18n/locales/en/welcome.json +++ b/webview-ui/src/i18n/locales/en/welcome.json @@ -16,8 +16,12 @@ "startRouter": "We recommend using an LLM Router:", "startCustom": "Or you can bring your provider API key:", "telemetry": { - "helpImprove": "Help Improve Roo Code", - "helpImproveMessage": "Roo Code collects error and usage data to help us fix bugs and improve the extension. This telemetry does not collect code, prompts or personal information. You can turn this off in settings." + "title": "Help Improve Roo Code", + "anonymousTelemetry": "Send anonymous error and usage data to help us fix bugs and improve the extension. No code, prompts, or personal information is ever sent (unless you connect to Roo Code Cloud). See our privacy policy for more details.", + "changeSettings": "You can always change this at the bottom of the settings", + "settings": "settings", + "allow": "Allow", + "deny": "Deny" }, "importSettings": "Import Settings" } diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index 64476b075a..e63731b095 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Inicia sesión en Roo Code Cloud para compartir tareas", "sharingDisabledByOrganization": "Compartir deshabilitado por la organización", "shareSuccessOrganization": "Enlace de organización copiado al portapapeles", - "shareSuccessPublic": "Enlace público copiado al portapapeles", - "openInCloud": "Abrir tarea en Roo Code Cloud", - "openInCloudIntro": "Continúa monitoreando o interactuando con Roo desde cualquier lugar. Escanea, haz clic o copia para abrir." + "shareSuccessPublic": "Enlace público copiado al portapapeles" }, "unpin": "Desfijar", "pin": "Fijar", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} publicado", - "description": "Presentamos Roo Code Cloud: Llevando el poder de Roo más allá del IDE", - "feature1": "Seguir el progreso de las tareas desde cualquier lugar (Gratis): Obtén actualizaciones en tiempo real de tareas de larga duración sin estar atrapado en tu IDE", - "feature2": "Controlar la extensión Roo remotamente (Pro): Inicia, detén e interactúa con tareas desde una interfaz de navegador basada en chat.", - "learnMore": "¿Listo para tomar el control? Aprende más aquí.", - "visitCloudButton": "Visitar Roo Code Cloud", - "socialLinks": "Únete a nosotros en X, Discord, o r/RooCode" + "stealthModel": { + "feature": "¡El modelo stealth Sonic ahora es Grok Code Fast! Este modelo de razonamiento de alto rendimiento está disponible como grok-code-fast-1 bajo el proveedor xAI (Grok).", + "note": "Como agradecimiento por todos los comentarios útiles sobre Sonic, xAI está extendiendo el acceso gratuito a grok-code-fast-1 por una semana más a través del proveedor Roo Code Cloud.", + "connectButton": "Conectar con Roo Code Cloud", + "selectModel": "Visita Configuración para actualizar tu configuración de proveedor." + }, + "description": "Roo Code {{version}} trae poderosas nuevas funcionalidades y mejoras significativas para mejorar tu flujo de trabajo de desarrollo.", + "whatsNew": "Novedades", + "feature1": "Cola de Mensajes: Pon en cola múltiples mensajes mientras Roo está trabajando, permitiéndote continuar planificando tu flujo de trabajo sin interrupciones.", + "feature2": "Comandos de Barra Personalizados: Crea comandos de barra personalizados para acceso rápido a prompts y flujos de trabajo utilizados frecuentemente, con gestión completa de la interfaz de usuario.", + "feature3": "Herramientas Gemini Mejoradas: Nuevas capacidades de contexto de URL y fundamentación de búsqueda de Google proporcionan a los modelos Gemini información web en tiempo real y capacidades de investigación mejoradas.", + "hideButton": "Ocultar anuncio", + "detailsDiscussLinks": "Obtén más detalles y participa en Discord y Reddit 🚀" }, "browser": { "rooWantsToUse": "Roo quiere usar el navegador:", diff --git a/webview-ui/src/i18n/locales/es/cloud.json b/webview-ui/src/i18n/locales/es/cloud.json index 80d0dc4705..2497edf7bf 100644 --- a/webview-ui/src/i18n/locales/es/cloud.json +++ b/webview-ui/src/i18n/locales/es/cloud.json @@ -4,28 +4,15 @@ "logOut": "Cerrar sesión", "testApiAuthentication": "Probar autenticación de API", "signIn": "Conectar a Roo Code Cloud", - "connect": "Conectar ahora", + "connect": "Conectar", "cloudBenefitsTitle": "Conectar a Roo Code Cloud", + "cloudBenefitsSubtitle": "Sincroniza tus prompts y telemetría para habilitar:", + "cloudBenefitHistory": "Historial de tareas en línea", + "cloudBenefitSharing": "Funciones de compartir y colaboración", + "cloudBenefitMetrics": "Métricas de uso basadas en tareas, tokens y costos", "cloudBenefitWalkaway": "Sigue y controla tareas desde cualquier lugar con Roomote Control", - "cloudBenefitSharing": "Comparte tareas con otros", - "cloudBenefitHistory": "Accede a tu historial de tareas", - "cloudBenefitMetrics": "Obtén una visión holística de tu consumo de tokens", - "visitCloudWebsite": "Visitar Roo Code Cloud", - "taskSync": "Sincronización de tareas", - "taskSyncDescription": "Sincroniza tus tareas para verlas y compartirlas en Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Permite controlar tareas desde Roo Code Cloud", - "remoteControlRequiresTaskSync": "La sincronización de tareas debe estar habilitada para usar Roomote Control", - "taskSyncManagedByOrganization": "La sincronización de tareas es gestionada por tu organización", - "usageMetricsAlwaysReported": "La información de uso del modelo siempre se reporta cuando se ha iniciado sesión", - "authWaiting": "Esperando que se complete la autenticación...", - "havingTrouble": "¿Tienes problemas?", - "pasteCallbackUrl": "Copia la URL de redirect desde tu navegador y pégala aquí:", - "startOver": "Empezar de nuevo", - "cloudUrlPillLabel": "URL de Roo Code Cloud", - "upsell": { - "autoApprovePowerUser": "¿Dándole a Roo un poco de independencia? Contrólalo desde cualquier lugar con Roo Code Cloud. Saber más.", - "longRunningTask": "Esto podría tardar un poco. Continúa desde cualquier lugar con la Nube.", - "taskList": "Roo Code Cloud ya está aquí: sigue y controla tus tareas desde cualquier lugar. Saber más." - } + "remoteControlDescription": "Permite seguir e interactuar con tareas en este espacio de trabajo con Roo Code Cloud", + "visitCloudWebsite": "Visitar Roo Code Cloud", + "cloudUrlPillLabel": "URL de Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 88a8312faf..c1174cbf0f 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -792,7 +792,7 @@ "feedback": "Si tiene alguna pregunta o comentario, no dude en abrir un issue en github.com/RooCodeInc/Roo-Code o unirse a reddit.com/r/RooCode o discord.gg/roocode", "telemetry": { "label": "Permitir informes anónimos de errores y uso", - "description": "Ayuda a mejorar Roo Code enviando datos de uso anónimos e informes de errores. Esta telemetría no recopila código, prompts o información personal. Consulta nuestra política de privacidad para más detalles." + "description": "Ayude a mejorar Roo Code enviando datos de uso anónimos e informes de errores. Nunca se envía código, prompts o información personal. Consulte nuestra política de privacidad para más detalles." }, "settings": { "import": "Importar", diff --git a/webview-ui/src/i18n/locales/es/welcome.json b/webview-ui/src/i18n/locales/es/welcome.json index 2a3a80751a..d4f3a20e08 100644 --- a/webview-ui/src/i18n/locales/es/welcome.json +++ b/webview-ui/src/i18n/locales/es/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Recomendamos usar un router LLM:", "startCustom": "O puedes traer tu propia clave API:", "telemetry": { - "helpImprove": "Ayuda a mejorar Roo Code", - "helpImproveMessage": "Roo Code recopila datos de errores y uso para ayudarnos a corregir errores y mejorar la extensión. Esta telemetría no recopila código, prompts o información personal. Puedes desactivar esto en la configuración." + "title": "Ayuda a mejorar Roo Code", + "anonymousTelemetry": "Envía datos de uso y errores anónimos para ayudarnos a corregir errores y mejorar la extensión. Nunca se envía código, texto o información personal.", + "changeSettings": "Siempre puedes cambiar esto en la parte inferior de la configuración", + "settings": "configuración", + "allow": "Permitir", + "deny": "Denegar" }, "importSettings": "Importar configuración" } diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 717c3ee236..2575489787 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Connecte-toi à Roo Code Cloud pour partager des tâches", "sharingDisabledByOrganization": "Partage désactivé par l'organisation", "shareSuccessOrganization": "Lien d'organisation copié dans le presse-papiers", - "shareSuccessPublic": "Lien public copié dans le presse-papiers", - "openInCloud": "Ouvrir la tâche dans Roo Code Cloud", - "openInCloudIntro": "Continue à surveiller ou interagir avec Roo depuis n'importe où. Scanne, clique ou copie pour ouvrir." + "shareSuccessPublic": "Lien public copié dans le presse-papiers" }, "unpin": "Désépingler", "pin": "Épingler", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} est sortie", - "description": "Présentation de Roo Code Cloud : Apporter la puissance de Roo au-delà de l'IDE", - "feature1": "Suivre le progrès des tâches depuis n'importe où (Gratuit) : Obtenir des mises à jour en temps réel sur les tâches de longue durée sans être bloqué dans ton IDE", - "feature2": "Contrôler l'extension Roo à distance (Pro) : Démarre, arrête et interagis avec les tâches depuis une interface de navigateur basée sur le chat.", - "learnMore": "Prêt à prendre le contrôle ? En savoir plus ici.", - "visitCloudButton": "Visiter Roo Code Cloud", - "socialLinks": "Rejoins-nous sur X, Discord, ou r/RooCode" + "stealthModel": { + "feature": "Le modèle stealth Sonic devient Grok Code Fast ! Ce modèle de raisonnement haute performance est disponible sous grok-code-fast-1 chez le fournisseur xAI (Grok).", + "note": "En remerciement de tous vos commentaires utiles sur Sonic, xAI étend l'accès gratuit à grok-code-fast-1 pendant une semaine supplémentaire via le fournisseur Roo Code Cloud.", + "connectButton": "Se connecter à Roo Code Cloud", + "selectModel": "Visitez les Paramètres pour mettre à jour votre configuration de fournisseur." + }, + "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": "File d'Attente de Messages : Mettez en file d'attente plusieurs messages pendant que Roo travaille, vous permettant de continuer à planifier votre flux de travail sans interruption.", + "feature2": "Commandes Slash Personnalisées : Créez des commandes slash personnalisées pour un accès rapide aux prompts et flux de travail fréquemment utilisés, avec une gestion complète de l'interface utilisateur.", + "feature3": "Outils Gemini Améliorés : De nouvelles capacités de contexte d'URL et de fondation de recherche Google fournissent aux modèles Gemini des informations web en temps réel et des capacités de recherche améliorées.", + "hideButton": "Masquer l'annonce", + "detailsDiscussLinks": "Obtenez plus de détails et participez aux discussions sur Discord et Reddit 🚀" }, "browser": { "rooWantsToUse": "Roo veut utiliser le navigateur :", diff --git a/webview-ui/src/i18n/locales/fr/cloud.json b/webview-ui/src/i18n/locales/fr/cloud.json index 8f32a2628d..76db922933 100644 --- a/webview-ui/src/i18n/locales/fr/cloud.json +++ b/webview-ui/src/i18n/locales/fr/cloud.json @@ -4,28 +4,15 @@ "logOut": "Déconnexion", "testApiAuthentication": "Tester l'authentification API", "signIn": "Se connecter à Roo Code Cloud", - "connect": "Se connecter maintenant", + "connect": "Se connecter", "cloudBenefitsTitle": "Se connecter à Roo Code Cloud", + "cloudBenefitsSubtitle": "Synchronise tes prompts et télémétrie pour activer :", + "cloudBenefitHistory": "Historique des tâches en ligne", + "cloudBenefitSharing": "Fonctionnalités de partage et collaboration", + "cloudBenefitMetrics": "Métriques d'utilisation basées sur les tâches, tokens et coûts", "cloudBenefitWalkaway": "Suivez et contrôlez les tâches depuis n'importe où avec Roomote Control", - "cloudBenefitSharing": "Partagez des tâches avec d'autres", - "cloudBenefitHistory": "Accédez à votre historique de tâches", - "cloudBenefitMetrics": "Obtenez une vue holistique de votre consommation de tokens", - "visitCloudWebsite": "Visiter Roo Code Cloud", - "taskSync": "Synchronisation des tâches", - "taskSyncDescription": "Synchronisez vos tâches pour les visualiser et les partager sur Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Permet de contrôler les tâches depuis Roo Code Cloud", - "remoteControlRequiresTaskSync": "La synchronisation des tâches doit être activée pour utiliser Roomote Control", - "taskSyncManagedByOrganization": "La synchronisation des tâches est gérée par votre organisation", - "usageMetricsAlwaysReported": "Les informations d'utilisation du modèle sont toujours signalées lors de la connexion", - "authWaiting": "En attente de la fin de l'authentification...", - "havingTrouble": "Des difficultés ?", - "pasteCallbackUrl": "Copie l'URL de redirect depuis ton navigateur et colle-la ici :", - "startOver": "Recommencer", - "cloudUrlPillLabel": "URL de Roo Code Cloud", - "upsell": { - "autoApprovePowerUser": "Donner à Roo un peu d'indépendance ? Contrôlez-le de n'importe où avec Roo Code Cloud. En savoir plus.", - "longRunningTask": "Cela peut prendre un certain temps. Continuez de n'importe où avec le Cloud.", - "taskList": "Roo Code Cloud est là : suivez et contrôlez vos tâches de n'importe où. En savoir plus." - } + "remoteControlDescription": "Permet de suivre et d'interagir avec les tâches dans cet espace de travail avec Roo Code Cloud", + "visitCloudWebsite": "Visiter Roo Code Cloud", + "cloudUrlPillLabel": "URL de Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index d23dd433f5..5cfd4d005f 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -792,7 +792,7 @@ "feedback": "Si vous avez des questions ou des commentaires, n'hésitez pas à ouvrir un problème sur github.com/RooCodeInc/Roo-Code ou à rejoindre reddit.com/r/RooCode ou discord.gg/roocode", "telemetry": { "label": "Autoriser les rapports anonymes d'erreurs et d'utilisation", - "description": "Aidez à améliorer Roo Code en envoyant des données d'utilisation anonymes et des rapports d'erreurs. Cette télémétrie ne collecte pas de code, de prompts ou d'informations personnelles. Consultez notre politique de confidentialité pour plus de détails." + "description": "Aidez à améliorer Roo Code en envoyant des données d'utilisation anonymes et des rapports d'erreurs. Aucun code, prompt ou information personnelle n'est jamais envoyé. Consultez notre politique de confidentialité pour plus de détails." }, "settings": { "import": "Importer", diff --git a/webview-ui/src/i18n/locales/fr/welcome.json b/webview-ui/src/i18n/locales/fr/welcome.json index 7c3ce18d65..2e1ead38cb 100644 --- a/webview-ui/src/i18n/locales/fr/welcome.json +++ b/webview-ui/src/i18n/locales/fr/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Nous recommandons d'utiliser un routeur LLM :", "startCustom": "Ou tu peux apporter ta propre clé API :", "telemetry": { - "helpImprove": "Aide à améliorer Roo Code", - "helpImproveMessage": "Roo Code collecte des données d'erreurs et d'utilisation pour nous aider à corriger les bugs et améliorer l'extension. Cette télémétrie ne collecte pas de code, de prompts ou d'informations personnelles. Tu peux désactiver ceci dans les paramètres." + "title": "Aide à améliorer Roo Code", + "anonymousTelemetry": "Envoie des données d'utilisation et d'erreurs anonymes pour nous aider à corriger les bugs et améliorer l'extension. Aucun code, texte ou information personnelle n'est jamais envoyé.", + "changeSettings": "Tu peux toujours modifier cela en bas des paramètres", + "settings": "paramètres", + "allow": "Autoriser", + "deny": "Refuser" }, "importSettings": "Importer les paramètres" } diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index 0cd6f89a4e..28fc26fcaf 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "कार्य साझा करने के लिए Roo Code Cloud में साइन इन करें", "sharingDisabledByOrganization": "संगठन द्वारा साझाकरण अक्षम किया गया", "shareSuccessOrganization": "संगठन लिंक क्लिपबोर्ड में कॉपी किया गया", - "shareSuccessPublic": "सार्वजनिक लिंक क्लिपबोर्ड में कॉपी किया गया", - "openInCloud": "Roo Code Cloud में कार्य खोलें", - "openInCloudIntro": "कहीं से भी Roo की निगरानी या इंटरैक्ट करना जारी रखें। खोलने के लिए स्कैन करें, क्लिक करें या कॉपी करें।" + "shareSuccessPublic": "सार्वजनिक लिंक क्लिपबोर्ड में कॉपी किया गया" }, "unpin": "पिन करें", "pin": "अवपिन करें", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} रिलीज़ हुआ", - "description": "Roo Code Cloud का परिचय: Roo की शक्ति को IDE से आगे ले जाना", - "feature1": "कहीं से भी कार्य प्रगति ट्रैक करें (निःशुल्क): लंबे समय तक चलने वाले कार्यों के लिए रीयल-टाइम अपडेट प्राप्त करें बिना अपने IDE में फंसे", - "feature2": "Roo एक्सटेंशन को दूर से नियंत्रित करें (Pro): चैट-आधारित ब्राउज़र इंटरफ़ेस से कार्य शुरू करें, रोकें और बातचीत करें।", - "learnMore": "नियंत्रण लेने के लिए तैयार हैं? यहां और जानें।", - "visitCloudButton": "Roo Code Cloud पर जाएं", - "socialLinks": "X, Discord, या r/RooCode पर हमसे जुड़ें" + "stealthModel": { + "feature": "Sonic स्टेल्थ मॉडल अब Grok Code Fast है! यह उच्च-प्रदर्शन रीज़निंग मॉडल xAI (Grok) प्रोवाइडर के तहत grok-code-fast-1 के रूप में उपलब्ध है।", + "note": "Sonic के बारे में सभी सहायक फीडबैक के लिए धन्यवाद के रूप में, xAI Roo Code Cloud प्रदाता के माध्यम से एक और सप्ताह के लिए grok-code-fast-1 तक मुफ्त पहुंच बढ़ा रहा है।", + "connectButton": "Roo Code Cloud से कनेक्ट करें", + "selectModel": "अपने प्रोवाइडर कॉन्फ़िगरेशन को अपडेट करने के लिए सेटिंग्स देखें।" + }, + "description": "Roo Code {{version}} आपके विकास वर्कफ़्लो को बेहतर बनाने के लिए शक्तिशाली नई सुविधाएं और महत्वपूर्ण सुधार लेकर आया है।", + "whatsNew": "नया क्या है", + "feature1": "संदेश कतार: Roo के काम करते समय कई संदेशों को कतार में रखें, जिससे आप बिना रुकावट के अपने वर्कफ़्लो की योजना बना सकते हैं।", + "feature2": "कस्टम स्लैश कमांड: अक्सर उपयोग किए जाने वाले प्रॉम्प्ट और वर्कफ़्लो तक त्वरित पहुंच के लिए व्यक्तिगत स्लैश कमांड बनाएं, पूर्ण UI प्रबंधन के साथ।", + "feature3": "उन्नत Gemini उपकरण: नए URL संदर्भ और Google खोज आधार क्षमताएं Gemini मॉडल को वास्तविक समय वेब जानकारी और बेहतर अनुसंधान क्षमताएं प्रदान करती हैं।", + "hideButton": "घोषणा छुपाएं", + "detailsDiscussLinks": "Discord और Reddit पर अधिक विवरण प्राप्त करें और चर्चाओं में शामिल हों 🚀" }, "browser": { "rooWantsToUse": "Roo ब्राउज़र का उपयोग करना चाहता है:", diff --git a/webview-ui/src/i18n/locales/hi/cloud.json b/webview-ui/src/i18n/locales/hi/cloud.json index 2d896575bb..60d7103c25 100644 --- a/webview-ui/src/i18n/locales/hi/cloud.json +++ b/webview-ui/src/i18n/locales/hi/cloud.json @@ -4,28 +4,15 @@ "logOut": "लॉग आउट", "testApiAuthentication": "API प्रमाणीकरण का परीक्षण करें", "signIn": "Roo Code Cloud से कनेक्ट करें", - "connect": "अभी कनेक्ट करें", + "connect": "कनेक्ट करें", "cloudBenefitsTitle": "Roo Code Cloud से कनेक्ट करें", + "cloudBenefitsSubtitle": "निम्नलिखित को सक्षम करने के लिए अपने prompts और telemetry को sync करें:", + "cloudBenefitHistory": "ऑनलाइन कार्य इतिहास", + "cloudBenefitSharing": "साझाकरण और सहयोग सुविधाएं", + "cloudBenefitMetrics": "कार्य, token और लागत आधारित उपयोग मेट्रिक्स", "cloudBenefitWalkaway": "Roomote Control के साथ कहीं से भी कार्यों को फॉलो और नियंत्रित करें", - "cloudBenefitSharing": "दूसरों के साथ कार्य साझा करें", - "cloudBenefitHistory": "अपने कार्य इतिहास तक पहुंचें", - "cloudBenefitMetrics": "अपने टोकन उपभोग का समग्र दृश्य प्राप्त करें", - "visitCloudWebsite": "Roo Code Cloud पर जाएं", - "taskSync": "कार्य सिंक", - "taskSyncDescription": "Roo Code Cloud पर देखने और साझा करने के लिए अपने कार्यों को सिंक करें", "remoteControl": "Roomote Control", - "remoteControlDescription": "Roo Code Cloud से कार्यों को नियंत्रित करने की अनुमति दें", - "remoteControlRequiresTaskSync": "Roomote Control का उपयोग करने के लिए कार्य सिंक सक्षम होना चाहिए", - "taskSyncManagedByOrganization": "कार्य सिंक आपके संगठन द्वारा प्रबंधित किया जाता है", - "usageMetricsAlwaysReported": "लॉग इन होने पर मॉडल उपयोग जानकारी हमेशा रिपोर्ट की जाती है", - "authWaiting": "प्रमाणीकरण पूरा होने की प्रतीक्षा कर रहे हैं...", - "havingTrouble": "समस्या हो रही है?", - "pasteCallbackUrl": "अपने ब्राउज़र से redirect URL कॉपी करें और यहाँ पेस्ट करें:", - "startOver": "फिर से शुरू करें", - "cloudUrlPillLabel": "Roo Code Cloud URL", - "upsell": { - "autoApprovePowerUser": "रू को थोड़ी स्वतंत्रता दे रहे हैं? रू कोड क्लाउड के साथ इसे कहीं से भी नियंत्रित करें। और जानें।", - "longRunningTask": "इसमें थोड़ा समय लग सकता है। क्लाउड के साथ कहीं से भी जारी रखें।", - "taskList": "रू कोड क्लाउड यहाँ है: कहीं से भी अपने कार्यों का पालन और नियंत्रण करें। और जानें।" - } + "remoteControlDescription": "Roo Code Cloud के साथ इस वर्कस्पेस में कार्यों को फॉलो और इंटरैक्ट करने की सुविधा दें", + "visitCloudWebsite": "Roo Code Cloud पर जाएं", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index bdadba0d6d..bb5cf6f6c4 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -793,7 +793,7 @@ "feedback": "यदि आपके कोई प्रश्न या प्रतिक्रिया है, तो github.com/RooCodeInc/Roo-Code पर एक मुद्दा खोलने या reddit.com/r/RooCode या discord.gg/roocode में शामिल होने में संकोच न करें", "telemetry": { "label": "गुमनाम त्रुटि और उपयोग रिपोर्टिंग की अनुमति दें", - "description": "गुमनाम उपयोग डेटा और त्रुटि रिपोर्ट भेजकर Roo Code को बेहतर बनाने में मदद करें। यह टेलीमेट्री कोड, प्रॉम्प्ट या व्यक्तिगत जानकारी एकत्र नहीं करती। अधिक विवरण के लिए हमारी गोपनीयता नीति देखें। आप इसे कभी भी बंद कर सकते हैं।" + "description": "गुमनाम उपयोग डेटा और त्रुटि रिपोर्ट भेजकर Roo Code को बेहतर बनाने में मदद करें। कोड, प्रॉम्प्ट, या व्यक्तिगत जानकारी कभी भी नहीं भेजी जाती है। अधिक विवरण के लिए हमारी गोपनीयता नीति देखें।" }, "settings": { "import": "इम्पोर्ट", diff --git a/webview-ui/src/i18n/locales/hi/welcome.json b/webview-ui/src/i18n/locales/hi/welcome.json index 03dffc9052..e8ef257f48 100644 --- a/webview-ui/src/i18n/locales/hi/welcome.json +++ b/webview-ui/src/i18n/locales/hi/welcome.json @@ -16,8 +16,12 @@ "startRouter": "हम एक LLM राउटर का उपयोग करने की सलाह देते हैं:", "startCustom": "या आप अपनी खुद की API कुंजी ला सकते हैं:", "telemetry": { - "helpImprove": "Roo Code को बेहतर बनाने में मदद करें", - "helpImproveMessage": "Roo Code बग्स को ठीक करने और एक्सटेंशन को बेहतर बनाने में हमारी मदद करने के लिए त्रुटि और उपयोग डेटा एकत्र करता है। यह टेलीमेट्री कोड, प्रॉम्प्ट या व्यक्तिगत जानकारी एकत्र नहीं करती। आप इसे सेटिंग्स में बंद कर सकते हैं।" + "title": "Roo Code को बेहतर बनाने में मदद करें", + "anonymousTelemetry": "बग ठीक करने और एक्सटेंशन को बेहतर बनाने में हमारी मदद करने के लिए गुमनाम त्रुटि और उपयोग डेटा भेजें। कोड, संकेत या व्यक्तिगत जानकारी कभी नहीं भेजी जाती है।", + "changeSettings": "आप इसे हमेशा सेटिंग्स के निचले भाग में बदल सकते हैं", + "settings": "सेटिंग्स", + "allow": "अनुमति दें", + "deny": "अस्वीकार करें" }, "importSettings": "सेटिंग्स आयात करें" } diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index b893516a59..0425a02b8f 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Masuk ke Roo Code Cloud untuk berbagi tugas", "sharingDisabledByOrganization": "Berbagi dinonaktifkan oleh organisasi", "shareSuccessOrganization": "Tautan organisasi disalin ke clipboard", - "shareSuccessPublic": "Tautan publik disalin ke clipboard", - "openInCloud": "Buka tugas di Roo Code Cloud", - "openInCloudIntro": "Terus pantau atau berinteraksi dengan Roo dari mana saja. Pindai, klik atau salin untuk membuka." + "shareSuccessPublic": "Tautan publik disalin ke clipboard" }, "history": { "title": "Riwayat" @@ -283,12 +281,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} Dirilis", - "description": "Memperkenalkan Roo Code Cloud: Membawa kekuatan Roo melampaui IDE", - "feature1": "Lacak kemajuan tugas dari mana saja (Gratis): Dapatkan pembaruan real-time tentang tugas yang berjalan lama tanpa terjebak di IDE Anda", - "feature2": "Kontrol Ekstensi Roo dari jarak jauh (Pro): Mulai, hentikan, dan berinteraksi dengan tugas dari antarmuka browser berbasis chat.", - "learnMore": "Siap mengambil kontrol? Pelajari lebih lanjut di sini.", - "visitCloudButton": "Kunjungi Roo Code Cloud", - "socialLinks": "Bergabunglah dengan kami di X, Discord, atau r/RooCode" + "stealthModel": { + "feature": "Model stealth Sonic kini adalah Grok Code Fast! Model penalaran berperforma tinggi ini tersedia sebagai grok-code-fast-1 di bawah penyedia xAI (Grok).", + "note": "Sebagai ucapan terima kasih atas semua masukan berguna tentang Sonic, xAI memperpanjang akses gratis ke grok-code-fast-1 selama satu minggu lagi melalui penyedia Roo Code Cloud.", + "connectButton": "Hubungkan ke Roo Code Cloud", + "selectModel": "Kunjungi Pengaturan untuk memperbarui konfigurasi penyedia." + }, + "description": "Roo Code {{version}} menghadirkan fitur-fitur baru yang kuat dan peningkatan signifikan untuk meningkatkan alur kerja pengembangan Anda.", + "whatsNew": "Yang Baru", + "feature1": "Antrian Pesan: Antrikan beberapa pesan saat Roo sedang bekerja, memungkinkan Anda melanjutkan perencanaan alur kerja tanpa gangguan.", + "feature2": "Perintah Slash Kustom: Buat perintah slash yang dipersonalisasi untuk akses cepat ke prompt dan alur kerja yang sering digunakan, dengan manajemen UI lengkap.", + "feature3": "Alat Gemini yang Ditingkatkan: Kemampuan konteks URL baru dan dasar pencarian Google memberikan model Gemini informasi web real-time dan kemampuan penelitian yang ditingkatkan.", + "hideButton": "Sembunyikan pengumuman", + "detailsDiscussLinks": "Dapatkan detail lebih lanjut dan bergabung dalam diskusi di Discord dan Reddit 🚀" }, "reasoning": { "thinking": "Berpikir", diff --git a/webview-ui/src/i18n/locales/id/cloud.json b/webview-ui/src/i18n/locales/id/cloud.json index 8af9b197ed..e48bb16fe8 100644 --- a/webview-ui/src/i18n/locales/id/cloud.json +++ b/webview-ui/src/i18n/locales/id/cloud.json @@ -4,28 +4,15 @@ "logOut": "Keluar", "testApiAuthentication": "Uji Autentikasi API", "signIn": "Hubungkan ke Roo Code Cloud", - "connect": "Hubungkan Sekarang", + "connect": "Hubungkan", "cloudBenefitsTitle": "Hubungkan ke Roo Code Cloud", + "cloudBenefitsSubtitle": "Sinkronkan prompt dan telemetri kamu untuk mengaktifkan:", + "cloudBenefitHistory": "Riwayat tugas online", + "cloudBenefitSharing": "Fitur berbagi dan kolaborasi", + "cloudBenefitMetrics": "Metrik penggunaan berdasarkan tugas, token, dan biaya", "cloudBenefitWalkaway": "Ikuti dan kontrol tugas dari mana saja dengan Roomote Control", - "cloudBenefitSharing": "Bagikan tugas dengan orang lain", - "cloudBenefitHistory": "Akses riwayat tugas Anda", - "cloudBenefitMetrics": "Dapatkan tampilan holistik konsumsi token Anda", - "visitCloudWebsite": "Kunjungi Roo Code Cloud", - "taskSync": "Sinkronisasi tugas", - "taskSyncDescription": "Sinkronkan tugas Anda untuk melihat dan berbagi di Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Izinkan mengontrol tugas dari Roo Code Cloud", - "remoteControlRequiresTaskSync": "Sinkronisasi tugas harus diaktifkan untuk menggunakan Roomote Control", - "taskSyncManagedByOrganization": "Sinkronisasi tugas dikelola oleh organisasi Anda", - "usageMetricsAlwaysReported": "Informasi penggunaan model selalu dilaporkan saat masuk", - "authWaiting": "Menunggu autentikasi selesai...", - "havingTrouble": "Ada masalah?", - "pasteCallbackUrl": "Salin URL redirect dari browser dan tempel di sini:", - "startOver": "Mulai dari awal", - "cloudUrlPillLabel": "URL Roo Code Cloud", - "upsell": { - "autoApprovePowerUser": "Memberi Roo sedikit kebebasan? Kendalikan dari mana saja dengan Roo Code Cloud. Pelajari lebih lanjut.", - "longRunningTask": "Ini mungkin akan memakan waktu cukup lama. Lanjutkan dari mana saja dengan Cloud.", - "taskList": "Roo Code Cloud ada di sini: ikuti dan kendalikan tugas Anda dari mana saja. Pelajari lebih lanjut." - } + "remoteControlDescription": "Memungkinkan mengikuti dan berinteraksi dengan tugas di workspace ini dengan Roo Code Cloud", + "visitCloudWebsite": "Kunjungi Roo Code Cloud", + "cloudUrlPillLabel": "URL Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 4457b3fb2f..93225bab1e 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -822,7 +822,7 @@ "feedback": "Jika kamu punya pertanyaan atau feedback, jangan ragu untuk membuka issue di github.com/RooCodeInc/Roo-Code atau bergabung reddit.com/r/RooCode atau discord.gg/roocode", "telemetry": { "label": "Izinkan pelaporan error dan penggunaan anonim", - "description": "Bantu tingkatkan Roo Code dengan mengirimkan data penggunaan anonim dan laporan error. Telemetri ini tidak mengumpulkan kode, prompt, atau informasi pribadi. Lihat kebijakan privasi kami untuk detail lebih lanjut. Anda dapat menonaktifkannya kapan saja." + "description": "Bantu tingkatkan Roo Code dengan mengirim data penggunaan anonim dan laporan error. Tidak ada kode, prompt, atau informasi pribadi yang pernah dikirim. Lihat kebijakan privasi kami untuk detail lebih lanjut." }, "settings": { "import": "Impor", diff --git a/webview-ui/src/i18n/locales/id/welcome.json b/webview-ui/src/i18n/locales/id/welcome.json index 49efa819e2..b1d6d71c80 100644 --- a/webview-ui/src/i18n/locales/id/welcome.json +++ b/webview-ui/src/i18n/locales/id/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Kami merekomendasikan menggunakan Router LLM:", "startCustom": "Atau Anda dapat menggunakan API key Anda sendiri:", "telemetry": { - "helpImprove": "Bantu Tingkatkan Roo Code", - "helpImproveMessage": "Roo Code mengumpulkan data kesalahan dan penggunaan untuk membantu kami memperbaiki bug dan meningkatkan ekstensi. Telemetri ini tidak mengumpulkan kode, prompt, atau informasi pribadi. Anda dapat menonaktifkan ini di pengaturan." + "title": "Bantu Tingkatkan Roo Code", + "anonymousTelemetry": "Kirim data error dan penggunaan anonim untuk membantu kami memperbaiki bug dan meningkatkan ekstensi. Tidak ada kode, prompt, atau informasi pribadi yang pernah dikirim.", + "changeSettings": "Anda selalu dapat mengubah ini di bagian bawah pengaturan", + "settings": "pengaturan", + "allow": "Izinkan", + "deny": "Tolak" }, "importSettings": "Impor Pengaturan" } diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index ea231f4d61..4dd1270e34 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Accedi a Roo Code Cloud per condividere attività", "sharingDisabledByOrganization": "Condivisione disabilitata dall'organizzazione", "shareSuccessOrganization": "Link organizzazione copiato negli appunti", - "shareSuccessPublic": "Link pubblico copiato negli appunti", - "openInCloud": "Apri attività in Roo Code Cloud", - "openInCloudIntro": "Continua a monitorare o interagire con Roo da qualsiasi luogo. Scansiona, clicca o copia per aprire." + "shareSuccessPublic": "Link pubblico copiato negli appunti" }, "unpin": "Rilascia", "pin": "Fissa", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Rilasciato Roo Code {{version}}", - "description": "Presentazione di Roo Code Cloud: Portare la potenza di Roo oltre l'IDE", - "feature1": "Traccia il progresso delle attività ovunque (Gratuito): Ricevi aggiornamenti in tempo reale su attività di lunga durata senza rimanere bloccato nel tuo IDE", - "feature2": "Controlla l'estensione Roo da remoto (Pro): Avvia, ferma e interagisci con le attività da un'interfaccia browser basata su chat.", - "learnMore": "Pronto a prendere il controllo? Scopri di più qui.", - "visitCloudButton": "Visita Roo Code Cloud", - "socialLinks": "Unisciti a noi su X, Discord, o r/RooCode" + "stealthModel": { + "feature": "Il modello stealth Sonic ora è Grok Code Fast! Questo modello di ragionamento ad alte prestazioni è disponibile come grok-code-fast-1 sotto il provider xAI (Grok).", + "note": "Come ringraziamento per tutti i feedback utili su Sonic, xAI sta estendendo l'accesso gratuito a grok-code-fast-1 per un'altra settimana tramite il provider Roo Code Cloud.", + "connectButton": "Connetti a Roo Code Cloud", + "selectModel": "Visita le Impostazioni per aggiornare la configurazione del provider." + }, + "description": "Roo Code {{version}} porta nuove potenti funzionalità e miglioramenti significativi per potenziare il tuo flusso di lavoro di sviluppo.", + "whatsNew": "Novità", + "feature1": "Coda Messaggi: Metti in coda più messaggi mentre Roo sta lavorando, permettendoti di continuare a pianificare il tuo flusso di lavoro senza interruzioni.", + "feature2": "Comandi Slash Personalizzati: Crea comandi slash personalizzati per accesso rapido a prompt e flussi di lavoro utilizzati frequentemente, con gestione completa dell'interfaccia utente.", + "feature3": "Strumenti Gemini Migliorati: Nuove capacità di contesto URL e fondamenta di ricerca Google forniscono ai modelli Gemini informazioni web in tempo reale e capacità di ricerca migliorate.", + "hideButton": "Nascondi annuncio", + "detailsDiscussLinks": "Ottieni maggiori dettagli e partecipa alle discussioni su Discord e Reddit 🚀" }, "browser": { "rooWantsToUse": "Roo vuole utilizzare il browser:", diff --git a/webview-ui/src/i18n/locales/it/cloud.json b/webview-ui/src/i18n/locales/it/cloud.json index 422a1a688b..0678fcd721 100644 --- a/webview-ui/src/i18n/locales/it/cloud.json +++ b/webview-ui/src/i18n/locales/it/cloud.json @@ -4,28 +4,15 @@ "logOut": "Disconnetti", "testApiAuthentication": "Verifica autenticazione API", "signIn": "Connetti a Roo Code Cloud", - "connect": "Connetti ora", + "connect": "Connetti", "cloudBenefitsTitle": "Connetti a Roo Code Cloud", + "cloudBenefitsSubtitle": "Sincronizza i tuoi prompt e telemetria per abilitare:", + "cloudBenefitHistory": "Cronologia attività online", + "cloudBenefitSharing": "Funzionalità di condivisione e collaborazione", + "cloudBenefitMetrics": "Metriche di utilizzo basate su attività, token e costi", "cloudBenefitWalkaway": "Segui e controlla le attività da qualsiasi luogo con Roomote Control", - "cloudBenefitSharing": "Condividi attività con altri", - "cloudBenefitHistory": "Accedi alla cronologia delle tue attività", - "cloudBenefitMetrics": "Ottieni una visione olistica del tuo consumo di token", - "visitCloudWebsite": "Visita Roo Code Cloud", - "taskSync": "Sincronizzazione attività", - "taskSyncDescription": "Sincronizza le tue attività per visualizzarle e condividerle su Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Consenti il controllo delle attività da Roo Code Cloud", - "remoteControlRequiresTaskSync": "La sincronizzazione delle attività deve essere abilitata per utilizzare Roomote Control", - "taskSyncManagedByOrganization": "La sincronizzazione delle attività è gestita dalla tua organizzazione", - "usageMetricsAlwaysReported": "Le informazioni sull'utilizzo del modello vengono sempre segnalate quando si è connessi", - "authWaiting": "In attesa del completamento dell'autenticazione...", - "havingTrouble": "Hai problemi?", - "pasteCallbackUrl": "Copia l'URL di redirect dal tuo browser e incollalo qui:", - "startOver": "Ricomincia", - "cloudUrlPillLabel": "URL di Roo Code Cloud", - "upsell": { - "autoApprovePowerUser": "Vuoi dare un po' di indipendenza a Roo? Controllalo da qualsiasi luogo con Roo Code Cloud. Scopri di più.", - "longRunningTask": "Potrebbe volerci un po' di tempo. Continua da qualsiasi luogo con il Cloud.", - "taskList": "Roo Code Cloud è qui: segui e controlla le tue attività da qualsiasi luogo. Scopri di più." - } + "remoteControlDescription": "Abilita il monitoraggio e l'interazione con le attività in questo workspace con Roo Code Cloud", + "visitCloudWebsite": "Visita Roo Code Cloud", + "cloudUrlPillLabel": "URL di Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index c3d360b56a..b8487b01dd 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -793,7 +793,7 @@ "feedback": "Se hai domande o feedback, sentiti libero di aprire un issue su github.com/RooCodeInc/Roo-Code o unirti a reddit.com/r/RooCode o discord.gg/roocode", "telemetry": { "label": "Consenti segnalazioni anonime di errori e utilizzo", - "description": "Aiuta a migliorare Roo Code inviando dati di utilizzo anonimi e segnalazioni di errori. Questa telemetria non raccoglie codice, prompt o informazioni personali. Consulta la nostra informativa sulla privacy per maggiori dettagli." + "description": "Aiuta a migliorare Roo Code inviando dati di utilizzo anonimi e segnalazioni di errori. Non vengono mai inviati codice, prompt o informazioni personali. Consulta la nostra politica sulla privacy per maggiori dettagli." }, "settings": { "import": "Importa", diff --git a/webview-ui/src/i18n/locales/it/welcome.json b/webview-ui/src/i18n/locales/it/welcome.json index 5bc96b045f..caa5f3e1d1 100644 --- a/webview-ui/src/i18n/locales/it/welcome.json +++ b/webview-ui/src/i18n/locales/it/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Consigliamo di utilizzare un router LLM:", "startCustom": "Oppure puoi utilizzare la tua chiave API:", "telemetry": { - "helpImprove": "Aiuta a migliorare Roo Code", - "helpImproveMessage": "Roo Code raccoglie dati di errori e utilizzo per aiutarci a correggere bug e migliorare l'estensione. Questa telemetria non raccoglie codice, prompt o informazioni personali. Puoi disabilitare questo nelle impostazioni." + "title": "Aiuta a migliorare Roo Code", + "anonymousTelemetry": "Invia dati di utilizzo ed errori anonimi per aiutarci a correggere bug e migliorare l'estensione. Non viene mai inviato codice, testo o informazioni personali.", + "changeSettings": "Puoi sempre cambiare questo in fondo alle impostazioni", + "settings": "impostazioni", + "allow": "Consenti", + "deny": "Nega" }, "importSettings": "Importa impostazioni" } diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index c8cc7af301..9a5d47fec8 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "タスクを共有するためにRoo Code Cloudにサインイン", "sharingDisabledByOrganization": "組織により共有が無効化されています", "shareSuccessOrganization": "組織リンクをクリップボードにコピーしました", - "shareSuccessPublic": "公開リンクをクリップボードにコピーしました", - "openInCloud": "Roo Code Cloudでタスクを開く", - "openInCloudIntro": "どこからでもRooの監視や操作を続けられます。スキャン、クリック、またはコピーして開いてください。" + "shareSuccessPublic": "公開リンクをクリップボードにコピーしました" }, "unpin": "ピン留めを解除", "pin": "ピン留め", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} リリース", - "description": "Roo Code Cloudのご紹介:RooのパワーをIDEを超えて", - "feature1": "どこからでもタスクの進行状況を追跡(無料):IDEに縛られることなく、長時間実行タスクのリアルタイム更新を取得", - "feature2": "Roo拡張機能をリモート制御(Pro):チャットベースのブラウザインターフェースからタスクを開始、停止、操作。", - "learnMore": "制御を取る準備はできましたか?詳細はこちら。", - "visitCloudButton": "Roo Code Cloudを訪問", - "socialLinks": "XDiscord、またはr/RooCodeでフォローしてください" + "stealthModel": { + "feature": "Sonicステルスモデルが今、Grok Code Fastに!この高性能推論モデルがxAI (Grok)プロバイダーの下でgrok-code-fast-1として利用できるようになりました。", + "note": "Sonicに関するすべての有用なフィードバックに感謝して、xAIはRoo Code Cloudプロバイダーを通じてgrok-code-fast-1への無料アクセスをもう1週間延長しています。", + "connectButton": "Roo Code Cloudに接続", + "selectModel": "プロバイダー設定を更新するために設定にアクセスしてください。" + }, + "description": "Roo Code {{version}}は、開発ワークフローを向上させる強力な新機能と重要な改善をもたらします。", + "whatsNew": "新機能", + "feature1": "メッセージキュー: Rooが作業中に複数のメッセージをキューに入れ、ワークフローの計画を中断することなく続行できます。", + "feature2": "カスタムスラッシュコマンド: よく使用するプロンプトやワークフローへの迅速なアクセスのために、パーソナライズされたスラッシュコマンドを作成し、完全なUI管理を提供します。", + "feature3": "強化されたGeminiツール: 新しいURLコンテキストとGoogle検索グラウンディング機能により、Geminiモデルにリアルタイムのウェブ情報と強化された研究能力を提供します。", + "hideButton": "通知を非表示", + "detailsDiscussLinks": "詳細はDiscordRedditでご確認・ディスカッションください 🚀" }, "browser": { "rooWantsToUse": "Rooはブラウザを使用したい:", diff --git a/webview-ui/src/i18n/locales/ja/cloud.json b/webview-ui/src/i18n/locales/ja/cloud.json index 6bdf6f886e..4b409af9e0 100644 --- a/webview-ui/src/i18n/locales/ja/cloud.json +++ b/webview-ui/src/i18n/locales/ja/cloud.json @@ -4,28 +4,15 @@ "logOut": "ログアウト", "testApiAuthentication": "API認証をテスト", "signIn": "Roo Code Cloud に接続", - "connect": "今すぐ接続", + "connect": "接続", "cloudBenefitsTitle": "Roo Code Cloudに接続", + "cloudBenefitsSubtitle": "プロンプトとテレメトリを同期して以下を有効にする:", + "cloudBenefitHistory": "オンラインタスク履歴", + "cloudBenefitSharing": "共有とコラボレーション機能", + "cloudBenefitMetrics": "タスク、Token、コストベースの使用メトリクス", "cloudBenefitWalkaway": "Roomote Controlでどこからでもタスクをフォローし制御", - "cloudBenefitSharing": "他の人とタスクを共有", - "cloudBenefitHistory": "タスク履歴にアクセス", - "cloudBenefitMetrics": "トークン消費の全体像を把握", - "visitCloudWebsite": "Roo Code Cloudを訪問", - "taskSync": "タスク同期", - "taskSyncDescription": "Roo Code Cloudでタスクを表示・共有するために同期", "remoteControl": "Roomote Control", - "remoteControlDescription": "Roo Code Cloudからタスクを制御できるようにする", - "remoteControlRequiresTaskSync": "Roomote Controlを使用するにはタ스크同期を有効にする必要があります", - "taskSyncManagedByOrganization": "タスク同期は組織によって管理されます", - "usageMetricsAlwaysReported": "ログイン時にはモデル使用情報が常に報告されます", - "authWaiting": "認証完了をお待ちください...", - "havingTrouble": "問題が発生していますか?", - "pasteCallbackUrl": "ブラウザからリダイレクトURLをコピーし、ここに貼り付けてください:", - "startOver": "最初からやり直す", - "cloudUrlPillLabel": "Roo Code Cloud URL", - "upsell": { - "autoApprovePowerUser": "Rooに少し独立性を与えませんか?Roo Code Cloudでどこからでもコントロールできます。詳細。", - "longRunningTask": "これには時間がかかるかもしれません。Cloudを使えばどこからでも続けられます。", - "taskList": "Roo Code Cloudが登場しました:どこからでもタスクを追跡し、コントロールできます。詳細。" - } + "remoteControlDescription": "Roo Code Cloudでこのワークスペースのタスクをフォローし操作することを有効にする", + "visitCloudWebsite": "Roo Code Cloudを訪問", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index 5abf228418..d8b9d6482f 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -793,7 +793,7 @@ "feedback": "質問やフィードバックがある場合は、github.com/RooCodeInc/Roo-Codeで問題を開くか、reddit.com/r/RooCodediscord.gg/roocodeに参加してください", "telemetry": { "label": "匿名のエラーと使用状況レポートを許可", - "description": "匿名の使用データとエラーレポートを送信してRoo Codeの改善にご協力ください。このテレメトリはコード、プロンプト、個人情報を収集しません。詳細についてはプライバシーポリシーをご覧ください。" + "description": "匿名の使用データとエラーレポートを送信してRoo Codeの改善にご協力ください。コード、プロンプト、個人情報が送信されることはありません。詳細については、プライバシーポリシーをご覧ください。" }, "settings": { "import": "インポート", diff --git a/webview-ui/src/i18n/locales/ja/welcome.json b/webview-ui/src/i18n/locales/ja/welcome.json index a1a13015b8..bc4bad4918 100644 --- a/webview-ui/src/i18n/locales/ja/welcome.json +++ b/webview-ui/src/i18n/locales/ja/welcome.json @@ -16,8 +16,12 @@ "startRouter": "LLMルーターの使用をお勧めします:", "startCustom": "または、あなた自身のAPIキーを使用できます:", "telemetry": { - "helpImprove": "Roo Codeの改善にご協力ください", - "helpImproveMessage": "Roo Codeは、バグの修正と拡張機能の改善のためにエラーと使用データを収集します。このテレメトリはコード、プロンプト、または個人情報を収集しません。これは設定で無効にできます。" + "title": "Roo Codeの改善にご協力ください", + "anonymousTelemetry": "バグの修正と拡張機能の改善のため、匿名のエラーと使用データを送信してください。コード、プロンプト、個人情報は一切送信されません。", + "changeSettings": "設定の下部でいつでも変更できます", + "settings": "設定", + "allow": "許可", + "deny": "拒否" }, "importSettings": "設定をインポート" } diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 8e1a76f566..aaf29243b7 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "작업을 공유하려면 Roo Code Cloud에 로그인하세요", "sharingDisabledByOrganization": "조직에서 공유가 비활성화됨", "shareSuccessOrganization": "조직 링크가 클립보드에 복사되었습니다", - "shareSuccessPublic": "공개 링크가 클립보드에 복사되었습니다", - "openInCloud": "Roo Code Cloud에서 작업 열기", - "openInCloudIntro": "어디서나 Roo를 계속 모니터링하거나 상호작용할 수 있습니다. 스캔, 클릭 또는 복사하여 열기." + "shareSuccessPublic": "공개 링크가 클립보드에 복사되었습니다" }, "unpin": "고정 해제하기", "pin": "고정하기", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} 출시", - "description": "Roo Code Cloud 소개: IDE를 넘어 Roo의 힘을 확장", - "feature1": "어디서나 작업 진행상황 추적 (무료): IDE에 갇히지 않고 장시간 실행 작업의 실시간 업데이트를 받아보세요", - "feature2": "원격으로 Roo 확장기능 제어 (Pro): 채팅 기반 브라우저 인터페이스에서 작업을 시작, 중지, 상호작용하세요.", - "learnMore": "제어권을 잡을 준비가 되셨나요? 여기서 자세히 알아보세요.", - "visitCloudButton": "Roo Code Cloud 방문", - "socialLinks": "X, Discord, 또는 r/RooCode에서 만나요" + "stealthModel": { + "feature": "Sonic 스텔스 모델이 이제 Grok Code Fast입니다! 이 고성능 추론 모델은 xAI (Grok) 제공업체 하에서 grok-code-fast-1로 이용 가능합니다.", + "note": "Sonic에 대한 모든 유용한 피드백에 대한 감사의 표시로, xAI는 Roo Code Cloud 제공업체를 통해 grok-code-fast-1에 대한 무료 액세스를 한 주 더 연장합니다.", + "connectButton": "Roo Code Cloud에 연결", + "selectModel": "제공업체 설정을 업데이트하려면 설정을 방문하세요." + }, + "description": "Roo Code {{version}}은 개발 워크플로우를 향상시키는 강력한 새 기능과 중요한 개선사항을 제공합니다.", + "whatsNew": "새로운 기능", + "feature1": "메시지 대기열: Roo가 작업하는 동안 여러 메시지를 대기열에 넣어 워크플로우 계획을 중단 없이 계속할 수 있습니다.", + "feature2": "사용자 정의 슬래시 명령: 자주 사용하는 프롬프트와 워크플로우에 빠르게 액세스할 수 있는 개인화된 슬래시 명령을 생성하고, 완전한 UI 관리를 제공합니다.", + "feature3": "향상된 Gemini 도구: 새로운 URL 컨텍스트 및 Google 검색 기반 기능으로 Gemini 모델에 실시간 웹 정보와 향상된 연구 기능을 제공합니다.", + "hideButton": "공지 숨기기", + "detailsDiscussLinks": "DiscordReddit에서 자세한 내용을 확인하고 토론에 참여하세요 🚀" }, "browser": { "rooWantsToUse": "Roo가 브라우저를 사용하고 싶어합니다:", diff --git a/webview-ui/src/i18n/locales/ko/cloud.json b/webview-ui/src/i18n/locales/ko/cloud.json index 763947da3e..4272a94acf 100644 --- a/webview-ui/src/i18n/locales/ko/cloud.json +++ b/webview-ui/src/i18n/locales/ko/cloud.json @@ -4,28 +4,15 @@ "logOut": "로그아웃", "testApiAuthentication": "API 인증 테스트", "signIn": "Roo Code Cloud에 연결", - "connect": "지금 연결", + "connect": "연결", "cloudBenefitsTitle": "Roo Code Cloud에 연결", + "cloudBenefitsSubtitle": "프롬프트와 텔레메트리를 동기화하여 다음을 활성화:", + "cloudBenefitHistory": "온라인 작업 기록", + "cloudBenefitSharing": "공유 및 협업 기능", + "cloudBenefitMetrics": "작업, 토큰, 비용 기반 사용 메트릭", "cloudBenefitWalkaway": "Roomote Control로 어디서나 작업을 팔로우하고 제어하세요", - "cloudBenefitSharing": "다른 사람과 작업 공유", - "cloudBenefitHistory": "작업 기록에 액세스", - "cloudBenefitMetrics": "토큰 소비에 대한 전체적인 보기 얻기", - "visitCloudWebsite": "Roo Code Cloud 방문", - "taskSync": "작업 동기화", - "taskSyncDescription": "Roo Code Cloud에서 보고 공유할 수 있도록 작업을 동기화", "remoteControl": "Roomote Control", - "remoteControlDescription": "Roo Code Cloud에서 작업을 제어할 수 있도록 허용", - "remoteControlRequiresTaskSync": "Roomote Control을 사용하려면 작업 동기화가 활성화되어야 합니다", - "taskSyncManagedByOrganization": "작업 동기화는 조직에서 관리합니다", - "usageMetricsAlwaysReported": "로그인 시 모델 사용 정보가 항상 보고됩니다", - "authWaiting": "인증 완료를 기다리는 중...", - "havingTrouble": "문제가 있나요?", - "pasteCallbackUrl": "브라우저에서 리다이렉트 URL을 복사하여 여기에 붙여넣으세요:", - "startOver": "다시 시작", - "cloudUrlPillLabel": "Roo Code Cloud URL", - "upsell": { - "autoApprovePowerUser": "Roo에게 약간의 독립성을 부여하시겠습니까? Roo Code Cloud로 어디서든 제어하세요. 더 알아보기.", - "longRunningTask": "시간이 좀 걸릴 수 있습니다. Cloud로 어디서든 계속하세요.", - "taskList": "Roo Code Cloud가 여기 있습니다: 어디서든 작업을 추적하고 제어하세요. 더 알아보기." - } + "remoteControlDescription": "Roo Code Cloud로 이 워크스페이스의 작업을 팔로우하고 상호작용할 수 있게 합니다", + "visitCloudWebsite": "Roo Code Cloud 방문", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 8a967bc6ef..6b8cd0d2c9 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -793,7 +793,7 @@ "feedback": "질문이나 피드백이 있으시면 github.com/RooCodeInc/Roo-Code에서 이슈를 열거나 reddit.com/r/RooCode 또는 discord.gg/roocode에 가입하세요", "telemetry": { "label": "익명 오류 및 사용 보고 허용", - "description": "익명 사용 데이터 및 오류 보고서를 전송하여 Roo Code 개선에 도움을 주세요. 이 텔레메트리는 코드, 프롬프트 또는 개인 정보를 수집하지 않습니다. 자세한 내용은 개인정보 보호정책을 참조하세요." + "description": "익명 사용 데이터 및 오류 보고서를 보내 Roo Code 개선에 도움을 주세요. 코드, 프롬프트 또는 개인 정보는 절대 전송되지 않습니다. 자세한 내용은 개인정보 보호정책을 참조하세요." }, "settings": { "import": "가져오기", diff --git a/webview-ui/src/i18n/locales/ko/welcome.json b/webview-ui/src/i18n/locales/ko/welcome.json index bd00d8a2aa..7637cf3d42 100644 --- a/webview-ui/src/i18n/locales/ko/welcome.json +++ b/webview-ui/src/i18n/locales/ko/welcome.json @@ -16,8 +16,12 @@ "startRouter": "LLM 라우터 사용을 권장합니다:", "startCustom": "또는 직접 API 키를 가져올 수 있습니다:", "telemetry": { - "helpImprove": "Roo Code 개선에 도움 주세요", - "helpImproveMessage": "Roo Code는 버그 수정과 확장 프로그램 개선을 위해 오류 및 사용 데이터를 수집합니다. 이 텔레메트리는 코드, 프롬프트 또는 개인 정보를 수집하지 않습니다. 설정에서 이를 비활성화할 수 있습니다." + "title": "Roo Code 개선에 도움 주세요", + "anonymousTelemetry": "버그 수정 및 확장 기능 개선을 위해 익명의 오류 및 사용 데이터를 보내주세요. 코드, 프롬프트 또는 개인 정보는 절대 전송되지 않습니다.", + "changeSettings": "설정 하단에서 언제든지 변경할 수 있습니다", + "settings": "설정", + "allow": "허용", + "deny": "거부" }, "importSettings": "설정 가져오기" } diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index d662a3598a..c6d52fa92e 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Meld je aan bij Roo Code Cloud om taken te delen", "sharingDisabledByOrganization": "Delen uitgeschakeld door organisatie", "shareSuccessOrganization": "Organisatielink gekopieerd naar klembord", - "shareSuccessPublic": "Openbare link gekopieerd naar klembord", - "openInCloud": "Taak openen in Roo Code Cloud", - "openInCloudIntro": "Blijf Roo vanaf elke locatie monitoren of ermee interacteren. Scan, klik of kopieer om te openen." + "shareSuccessPublic": "Openbare link gekopieerd naar klembord" }, "unpin": "Losmaken", "pin": "Vastmaken", @@ -256,12 +254,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} uitgebracht", - "description": "Introductie van Roo Code Cloud: De kracht van Roo brengen voorbij de IDE", - "feature1": "Volg taakvoortgang overal (Gratis): Krijg realtime updates van langlopende taken zonder vast te zitten in je IDE", - "feature2": "Bestuur de Roo Extensie op afstand (Pro): Start, stop en interacteer met taken vanuit een chat-gebaseerde browserinterface.", - "learnMore": "Klaar om de controle te nemen? Leer meer hier.", - "visitCloudButton": "Bezoek Roo Code Cloud", - "socialLinks": "Sluit je bij ons aan op X, Discord, of r/RooCode" + "stealthModel": { + "feature": "Het Sonic stealth model is nu Grok Code Fast! Dit hoogperformante redeneermodel is beschikbaar als grok-code-fast-1 onder de xAI (Grok) provider.", + "note": "Als dank voor alle nuttige feedback over Sonic, breidt xAI de gratis toegang tot grok-code-fast-1 uit voor nog een week via de Roo Code Cloud-provider.", + "connectButton": "Verbinden met Roo Code Cloud", + "selectModel": "Ga naar Instellingen om je provider configuratie bij te werken." + }, + "description": "Roo Code {{version}} brengt krachtige nieuwe functies en significante verbeteringen om je ontwikkelingsworkflow te verbeteren.", + "whatsNew": "Wat is er nieuw", + "feature1": "Berichtenwachtrij: Zet meerdere berichten in de wachtrij terwijl Roo werkt, zodat je je workflow kunt blijven plannen zonder onderbreking.", + "feature2": "Aangepaste Slash Commando's: Maak gepersonaliseerde slash commando's voor snelle toegang tot veelgebruikte prompts en workflows, met volledige UI-beheer.", + "feature3": "Verbeterde Gemini Tools: Nieuwe URL-context en Google Search grounding mogelijkheden bieden Gemini modellen realtime webinformatie en verbeterde onderzoeksmogelijkheden.", + "hideButton": "Aankondiging verbergen", + "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/nl/cloud.json b/webview-ui/src/i18n/locales/nl/cloud.json index 533237c88c..f77a37fbf0 100644 --- a/webview-ui/src/i18n/locales/nl/cloud.json +++ b/webview-ui/src/i18n/locales/nl/cloud.json @@ -4,28 +4,15 @@ "logOut": "Uitloggen", "testApiAuthentication": "API-authenticatie testen", "signIn": "Verbind met Roo Code Cloud", - "connect": "Nu verbinden", + "connect": "Verbinden", "cloudBenefitsTitle": "Verbind met Roo Code Cloud", + "cloudBenefitsSubtitle": "Synchroniseer je prompts en telemetrie om het volgende in te schakelen:", + "cloudBenefitHistory": "Online taakgeschiedenis", + "cloudBenefitSharing": "Deel- en samenwerkingsfuncties", + "cloudBenefitMetrics": "Taak-, token- en kostengebaseerde gebruiksstatistieken", "cloudBenefitWalkaway": "Volg en beheer taken van overal met Roomote Control", - "cloudBenefitSharing": "Deel taken met anderen", - "cloudBenefitHistory": "Toegang tot je taakgeschiedenis", - "cloudBenefitMetrics": "Krijg een holistisch overzicht van je tokenverbruik", - "visitCloudWebsite": "Bezoek Roo Code Cloud", - "taskSync": "Taaksynchronisatie", - "taskSyncDescription": "Synchroniseer je taken om ze te bekijken en delen op Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Sta toe taken te besturen vanuit Roo Code Cloud", - "remoteControlRequiresTaskSync": "Taaksynchronisatie moet ingeschakeld zijn om Roomote Control te gebruiken", - "taskSyncManagedByOrganization": "Taaksynchronisatie wordt beheerd door uw organisatie", - "usageMetricsAlwaysReported": "Modelgebruiksinformatie wordt altijd gerapporteerd wanneer ingelogd", - "authWaiting": "Wachten tot authenticatie voltooid is...", - "havingTrouble": "Problemen?", - "pasteCallbackUrl": "Kopieer de redirect-URL uit je browser en plak hem hier:", - "startOver": "Opnieuw beginnen", - "cloudUrlPillLabel": "Roo Code Cloud URL", - "upsell": { - "autoApprovePowerUser": "Roo wat onafhankelijkheid geven? Bedien het overal met Roo Code Cloud. Meer informatie.", - "longRunningTask": "Dit kan even duren. Ga overal verder met de Cloud.", - "taskList": "Roo Code Cloud is hier: volg en beheer je taken overal. Meer informatie." - } + "remoteControlDescription": "Schakel het volgen en interacteren met taken in deze workspace in met Roo Code Cloud", + "visitCloudWebsite": "Bezoek Roo Code Cloud", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 39baabb9d5..7e9da9b11a 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -793,7 +793,7 @@ "feedback": "Heb je vragen of feedback? Open gerust een issue op github.com/RooCodeInc/Roo-Code of sluit je aan bij reddit.com/r/RooCode of discord.gg/roocode", "telemetry": { "label": "Anonieme fout- en gebruiksrapportage toestaan", - "description": "Help Roo Code te verbeteren door anonieme gebruiksgegevens en foutmeldingen te versturen. Deze telemetrie verzamelt geen code, prompts of persoonlijke informatie. Zie ons privacybeleid voor meer details." + "description": "Help Roo Code te verbeteren door anonieme gebruiksgegevens en foutmeldingen te verzenden. Er worden nooit code, prompts of persoonlijke gegevens verzonden. Zie ons privacybeleid voor meer informatie." }, "settings": { "import": "Importeren", diff --git a/webview-ui/src/i18n/locales/nl/welcome.json b/webview-ui/src/i18n/locales/nl/welcome.json index 625122816d..c07d9c5ace 100644 --- a/webview-ui/src/i18n/locales/nl/welcome.json +++ b/webview-ui/src/i18n/locales/nl/welcome.json @@ -16,8 +16,12 @@ "startRouter": "We raden aan om een LLM-router te gebruiken:", "startCustom": "Of je kunt je eigen API-sleutel gebruiken:", "telemetry": { - "helpImprove": "Help Roo Code verbeteren", - "helpImproveMessage": "Roo Code verzamelt fout- en gebruiksgegevens om ons te helpen bugs op te lossen en de extensie te verbeteren. Deze telemetrie verzamelt geen code, prompts of persoonlijke informatie. Je kunt dit uitschakelen in de instellingen." + "title": "Help Roo Code verbeteren", + "anonymousTelemetry": "Stuur anonieme fout- en gebruiksgegevens om ons te helpen bugs op te lossen en de extensie te verbeteren. Er worden nooit code, prompts of persoonlijke gegevens verzonden.", + "changeSettings": "Je kunt dit altijd wijzigen onderaan de instellingen", + "settings": "instellingen", + "allow": "Toestaan", + "deny": "Weigeren" }, "importSettings": "Instellingen importeren" } diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index bfcf5e5a26..2028cb705b 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Zaloguj się do Roo Code Cloud, aby udostępniać zadania", "sharingDisabledByOrganization": "Udostępnianie wyłączone przez organizację", "shareSuccessOrganization": "Link organizacji skopiowany do schowka", - "shareSuccessPublic": "Link publiczny skopiowany do schowka", - "openInCloud": "Otwórz zadanie w Roo Code Cloud", - "openInCloudIntro": "Kontynuuj monitorowanie lub interakcję z Roo z dowolnego miejsca. Zeskanuj, kliknij lub skopiuj, aby otworzyć." + "shareSuccessPublic": "Link publiczny skopiowany do schowka" }, "unpin": "Odepnij", "pin": "Przypnij", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} wydany", - "description": "Przedstawiamy Roo Code Cloud: Przenosimy moc Roo poza IDE", - "feature1": "Śledź postęp zadań z dowolnego miejsca (Bezpłatnie): Otrzymuj aktualizacje w czasie rzeczywistym długotrwałych zadań bez utknięcia w IDE", - "feature2": "Kontroluj rozszerzenie Roo zdalnie (Pro): Uruchamiaj, zatrzymuj i wchodź w interakcje z zadaniami z interfejsu przeglądarki opartego na czacie.", - "learnMore": "Gotowy przejąć kontrolę? Dowiedz się więcej tutaj.", - "visitCloudButton": "Odwiedź Roo Code Cloud", - "socialLinks": "Dołącz do nas na X, Discord, lub r/RooCode" + "stealthModel": { + "feature": "Model stealth Sonic to teraz Grok Code Fast! Ten wysokowydajny model rozumowania jest dostępny jako grok-code-fast-1 u dostawcy xAI (Grok).", + "note": "W podzięce za wszystkie pomocne opinie o Sonic, xAI rozszerza bezpłatny dostęp do grok-code-fast-1 na kolejny tydzień za pośrednictwem dostawcy Roo Code Cloud.", + "connectButton": "Połącz z Roo Code Cloud", + "selectModel": "Odwiedź Ustawienia, aby zaktualizować konfigurację dostawcy." + }, + "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": "Kolejka Wiadomości: Umieszczaj wiele wiadomości w kolejce podczas pracy Roo, pozwalając na kontynuowanie planowania przepływu pracy bez przerw.", + "feature2": "Niestandardowe Polecenia Slash: Twórz spersonalizowane polecenia slash dla szybkiego dostępu do często używanych promptów i przepływów pracy, z pełnym zarządzaniem interfejsu użytkownika.", + "feature3": "Ulepszone Narzędzia Gemini: Nowe możliwości kontekstu URL i ugruntowania wyszukiwania Google zapewniają modelom Gemini informacje internetowe w czasie rzeczywistym i ulepszone możliwości badawcze.", + "hideButton": "Ukryj ogłoszenie", + "detailsDiscussLinks": "Uzyskaj więcej szczegółów i dołącz do dyskusji na Discord i Reddit 🚀" }, "browser": { "rooWantsToUse": "Roo chce użyć przeglądarki:", diff --git a/webview-ui/src/i18n/locales/pl/cloud.json b/webview-ui/src/i18n/locales/pl/cloud.json index be940d3710..4f98bf0b98 100644 --- a/webview-ui/src/i18n/locales/pl/cloud.json +++ b/webview-ui/src/i18n/locales/pl/cloud.json @@ -4,28 +4,15 @@ "logOut": "Wyloguj", "testApiAuthentication": "Testuj uwierzytelnianie API", "signIn": "Połącz z Roo Code Cloud", - "connect": "Połącz teraz", + "connect": "Połącz", "cloudBenefitsTitle": "Połącz z Roo Code Cloud", + "cloudBenefitsSubtitle": "Synchronizuj swoje prompty i telemetrię, aby włączyć:", + "cloudBenefitHistory": "Historia zadań online", + "cloudBenefitSharing": "Funkcje udostępniania i współpracy", + "cloudBenefitMetrics": "Metryki użycia oparte na zadaniach, tokenach i kosztach", "cloudBenefitWalkaway": "Śledź i kontroluj zadania z dowolnego miejsca za pomocą Roomote Control", - "cloudBenefitSharing": "Udostępniaj zadania innym", - "cloudBenefitHistory": "Uzyskaj dostęp do historii zadań", - "cloudBenefitMetrics": "Uzyskaj całościowy widok zużycia tokenów", - "visitCloudWebsite": "Odwiedź Roo Code Cloud", - "taskSync": "Synchronizacja zadań", - "taskSyncDescription": "Synchronizuj swoje zadania, aby przeglądać i udostępniać je w Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Pozwól kontrolować zadania z Roo Code Cloud", - "remoteControlRequiresTaskSync": "Synchronizacja zadań musi być włączona, aby używać Roomote Control", - "taskSyncManagedByOrganization": "Synchronizacja zadań jest zarządzana przez Twoją organizację", - "usageMetricsAlwaysReported": "Informacje o użyciu modelu są zawsze raportowane po zalogowaniu", - "authWaiting": "Oczekiwanie na zakończenie uwierzytelniania...", - "havingTrouble": "Masz problemy?", - "pasteCallbackUrl": "Skopiuj URL redirect z przeglądarki i wklej tutaj:", - "startOver": "Zacznij od nowa", - "cloudUrlPillLabel": "URL Roo Code Cloud", - "upsell": { - "autoApprovePowerUser": "Dać Roo trochę niezależności? Kontroluj go z dowolnego miejsca dzięki Roo Code Cloud. Dowiedz się więcej.", - "longRunningTask": "To może chwilę potrwać. Kontynuuj z dowolnego miejsca dzięki Chmurze.", - "taskList": "Roo Code Cloud jest tutaj: śledź i kontroluj swoje zadania z dowolnego miejsca. Dowiedz się więcej." - } + "remoteControlDescription": "Umożliwia śledzenie i interakcję z zadaniami w tym obszarze roboczym za pomocą Roo Code Cloud", + "visitCloudWebsite": "Odwiedź Roo Code Cloud", + "cloudUrlPillLabel": "URL Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index 2fc353a8e9..c9aa603d2f 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -793,7 +793,7 @@ "feedback": "Jeśli masz jakiekolwiek pytania lub opinie, śmiało otwórz zgłoszenie na github.com/RooCodeInc/Roo-Code lub dołącz do reddit.com/r/RooCode lub discord.gg/roocode", "telemetry": { "label": "Zezwól na anonimowe raportowanie błędów i użycia", - "description": "Pomóż ulepszyć Roo Code, wysyłając anonimowe dane użytkowania i raporty błędów. Ta telemetria nie zbiera kodu, promptów ani danych osobowych. Zobacz naszą politykę prywatności, aby uzyskać więcej szczegółów. Możesz to wyłączyć w dowolnym momencie." + "description": "Pomóż ulepszyć Roo Code, wysyłając anonimowe dane o użytkowaniu i raporty o błędach. Nigdy nie są wysyłane kod, podpowiedzi ani informacje osobiste. Zobacz naszą politykę prywatności, aby uzyskać więcej szczegółów." }, "settings": { "import": "Importuj", diff --git a/webview-ui/src/i18n/locales/pl/welcome.json b/webview-ui/src/i18n/locales/pl/welcome.json index 7bddbac4cb..5794dced84 100644 --- a/webview-ui/src/i18n/locales/pl/welcome.json +++ b/webview-ui/src/i18n/locales/pl/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Zalecamy korzystanie z routera LLM:", "startCustom": "Lub możesz użyć własnego klucza API:", "telemetry": { - "helpImprove": "Pomóż ulepszyć Roo Code", - "helpImproveMessage": "Roo Code zbiera dane o błędach i użytkowaniu, aby pomóc nam naprawiać błędy i ulepszać rozszerzenie. Ta telemetria nie zbiera kodu, promptów ani danych osobowych. Możesz wyłączyć to w ustawieniach." + "title": "Pomóż ulepszyć Roo Code", + "anonymousTelemetry": "Wyślij anonimowe dane o błędach i użyciu, aby pomóc nam w naprawianiu błędów i ulepszaniu rozszerzenia. Nigdy nie są wysyłane żadne kody, teksty ani informacje osobiste.", + "changeSettings": "Zawsze możesz to zmienić na dole ustawień", + "settings": "ustawienia", + "allow": "Zezwól", + "deny": "Odmów" }, "importSettings": "Importuj ustawienia" } diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index 5d8f9f53e2..6ee23ca627 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Entre no Roo Code Cloud para compartilhar tarefas", "sharingDisabledByOrganization": "Compartilhamento desabilitado pela organização", "shareSuccessOrganization": "Link da organização copiado para a área de transferência", - "shareSuccessPublic": "Link público copiado para a área de transferência", - "openInCloud": "Abrir tarefa no Roo Code Cloud", - "openInCloudIntro": "Continue monitorando ou interagindo com Roo de qualquer lugar. Escaneie, clique ou copie para abrir." + "shareSuccessPublic": "Link público copiado para a área de transferência" }, "unpin": "Desfixar", "pin": "Fixar", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} Lançado", - "description": "Apresentando Roo Code Cloud: Levando o poder do Roo além da IDE", - "feature1": "Acompanhe o progresso das tarefas de qualquer lugar (Grátis): Receba atualizações em tempo real de tarefas de longa duração sem ficar preso na sua IDE", - "feature2": "Controle a Extensão Roo remotamente (Pro): Inicie, pare e interaja com tarefas de uma interface de navegador baseada em chat.", - "learnMore": "Pronto para assumir o controle? Saiba mais aqui.", - "visitCloudButton": "Visite Roo Code Cloud", - "socialLinks": "Junte-se a nós no X, Discord, ou r/RooCode" + "stealthModel": { + "feature": "O modelo stealth Sonic agora é Grok Code Fast! Este modelo de raciocínio de alta performance está disponível como grok-code-fast-1 no provedor xAI (Grok).", + "note": "Como agradecimento por todo o feedback útil sobre o Sonic, a xAI está estendendo o acesso gratuito ao grok-code-fast-1 por mais uma semana através do provedor Roo Code Cloud.", + "connectButton": "Conectar ao Roo Code Cloud", + "selectModel": "Visite as Configurações para atualizar sua configuração de provedor." + }, + "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": "Fila de Mensagens: Coloque várias mensagens na fila enquanto o Roo está trabalhando, permitindo que você continue planejando seu fluxo de trabalho sem interrupção.", + "feature2": "Comandos de Barra Personalizados: Crie comandos de barra personalizados para acesso rápido a prompts e fluxos de trabalho usados frequentemente, com gerenciamento completo da interface do usuário.", + "feature3": "Ferramentas Gemini Aprimoradas: Novas capacidades de contexto de URL e fundamentação de pesquisa do Google fornecem aos modelos Gemini informações web em tempo real e capacidades de pesquisa aprimoradas.", + "hideButton": "Ocultar anúncio", + "detailsDiscussLinks": "Obtenha mais detalhes e participe da discussão no Discord e Reddit 🚀" }, "browser": { "rooWantsToUse": "Roo quer usar o navegador:", diff --git a/webview-ui/src/i18n/locales/pt-BR/cloud.json b/webview-ui/src/i18n/locales/pt-BR/cloud.json index 8511982769..749395edae 100644 --- a/webview-ui/src/i18n/locales/pt-BR/cloud.json +++ b/webview-ui/src/i18n/locales/pt-BR/cloud.json @@ -4,28 +4,15 @@ "logOut": "Sair", "testApiAuthentication": "Testar Autenticação de API", "signIn": "Conectar ao Roo Code Cloud", - "connect": "Conectar Agora", + "connect": "Conectar", "cloudBenefitsTitle": "Conectar ao Roo Code Cloud", + "cloudBenefitsSubtitle": "Sincronize seus prompts e telemetria para habilitar:", + "cloudBenefitHistory": "Histórico de tarefas online", + "cloudBenefitSharing": "Recursos de compartilhamento e colaboração", + "cloudBenefitMetrics": "Métricas de uso baseadas em tarefas, tokens e custos", "cloudBenefitWalkaway": "Acompanhe e controle tarefas de qualquer lugar com Roomote Control", - "cloudBenefitSharing": "Compartilhe tarefas com outros", - "cloudBenefitHistory": "Acesse seu histórico de tarefas", - "cloudBenefitMetrics": "Obtenha uma visão holística do seu consumo de tokens", - "visitCloudWebsite": "Visitar Roo Code Cloud", - "taskSync": "Sincronização de tarefas", - "taskSyncDescription": "Sincronize suas tarefas para visualizar e compartilhar no Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Permite controlar tarefas a partir do Roo Code Cloud", - "remoteControlRequiresTaskSync": "A sincronização de tarefas deve estar habilitada para usar o Roomote Control", - "taskSyncManagedByOrganization": "A sincronização de tarefas é gerenciada pela sua organização", - "usageMetricsAlwaysReported": "As informações de uso do modelo são sempre reportadas quando conectado", - "authWaiting": "Aguardando conclusão da autenticação...", - "havingTrouble": "Tendo problemas?", - "pasteCallbackUrl": "Copie a URL de redirect do seu navegador e cole aqui:", - "startOver": "Recomeçar", - "cloudUrlPillLabel": "URL do Roo Code Cloud ", - "upsell": { - "autoApprovePowerUser": "Dando um pouco de independência ao Roo? Controle-o de qualquer lugar com o Roo Code Cloud. Saiba mais.", - "longRunningTask": "Isso pode levar um tempo. Continue de qualquer lugar com a Nuvem.", - "taskList": "O Roo Code Cloud está aqui: acompanhe e controle suas tarefas de qualquer lugar. Saiba mais." - } + "remoteControlDescription": "Permite acompanhar e interagir com tarefas neste workspace com Roo Code Cloud", + "visitCloudWebsite": "Visitar Roo Code Cloud", + "cloudUrlPillLabel": "URL do Roo Code Cloud " } diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 024506cc43..0fbb47d348 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -793,7 +793,7 @@ "feedback": "Se tiver alguma dúvida ou feedback, sinta-se à vontade para abrir um problema em github.com/RooCodeInc/Roo-Code ou juntar-se a reddit.com/r/RooCode ou discord.gg/roocode", "telemetry": { "label": "Permitir relatórios anônimos de erros e uso", - "description": "Ajude a melhorar o Roo Code enviando dados de uso anônimos e relatórios de erros. Esta telemetria não coleta código, prompts ou informações pessoais. Consulte nossa política de privacidade para mais detalhes." + "description": "Ajude a melhorar o Roo Code enviando dados de uso anônimos e relatórios de erros. Nunca são enviados código, prompts ou informações pessoais. Consulte nossa política de privacidade para mais detalhes." }, "settings": { "import": "Importar", diff --git a/webview-ui/src/i18n/locales/pt-BR/welcome.json b/webview-ui/src/i18n/locales/pt-BR/welcome.json index fced51060f..1c0dec8ca0 100644 --- a/webview-ui/src/i18n/locales/pt-BR/welcome.json +++ b/webview-ui/src/i18n/locales/pt-BR/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Recomendamos usar um roteador LLM:", "startCustom": "Ou você pode trazer sua própria chave API:", "telemetry": { - "helpImprove": "Ajude a melhorar o Roo Code", - "helpImproveMessage": "O Roo Code coleta dados de erro e uso para nos ajudar a corrigir bugs e melhorar a extensão. Esta telemetria não coleta código, prompts ou informações pessoais. Você pode desativar isso nas configurações." + "title": "Ajude a melhorar o Roo Code", + "anonymousTelemetry": "Envie dados de uso e erros anônimos para nos ajudar a corrigir bugs e melhorar a extensão. Nenhum código, texto ou informação pessoal é enviado.", + "changeSettings": "Você sempre pode mudar isso na parte inferior das configurações", + "settings": "configurações", + "allow": "Permitir", + "deny": "Negar" }, "importSettings": "Importar configurações" } diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index 8f5083c97c..6cafe6bac9 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Войди в Roo Code Cloud, чтобы делиться задачами", "sharingDisabledByOrganization": "Обмен отключен организацией", "shareSuccessOrganization": "Ссылка организации скопирована в буфер обмена", - "shareSuccessPublic": "Публичная ссылка скопирована в буфер обмена", - "openInCloud": "Открыть задачу в Roo Code Cloud", - "openInCloudIntro": "Продолжай отслеживать или взаимодействовать с Roo откуда угодно. Отсканируй, нажми или скопируй для открытия." + "shareSuccessPublic": "Публичная ссылка скопирована в буфер обмена" }, "unpin": "Открепить", "pin": "Закрепить", @@ -256,12 +254,19 @@ }, "announcement": { "title": "🎉 Выпущен Roo Code {{version}}", - "description": "Представляем Roo Code Cloud: Расширяя возможности Roo за пределы IDE", - "feature1": "Отслеживайте прогресс задач из любого места (Бесплатно): Получайте обновления в реальном времени о долгосрочных задачах, не привязываясь к IDE", - "feature2": "Управляйте расширением Roo удаленно (Pro): Запускайте, останавливайте и взаимодействуйте с задачами через браузерный интерфейс на основе чата.", - "learnMore": "Готовы взять контроль в свои руки? Узнайте больше здесь.", - "visitCloudButton": "Посетить Roo Code Cloud", - "socialLinks": "Присоединяйтесь к нам в X, Discord, или r/RooCode" + "stealthModel": { + "feature": "Скрытая модель Sonic теперь называется Grok Code Fast! Эта высокопроизводительная модель рассуждения доступна как grok-code-fast-1 у провайдера xAI (Grok).", + "note": "В благодарность за все полезные отзывы о Sonic, xAI продлевает бесплатный доступ к grok-code-fast-1 ещё на одну неделю через провайдера Roo Code Cloud.", + "connectButton": "Подключиться к Roo Code Cloud", + "selectModel": "Перейдите в Настройки для обновления конфигурации провайдера." + }, + "description": "Roo Code {{version}} приносит мощные новые функции и значительные улучшения для совершенствования вашего рабочего процесса разработки.", + "whatsNew": "Что нового", + "feature1": "Очередь сообщений: Ставьте несколько сообщений в очередь, пока Roo работает, позволяя вам продолжать планировать рабочий процесс без прерывания.", + "feature2": "Пользовательские слэш-команды: Создавайте персонализированные слэш-команды для быстрого доступа к часто используемым промптам и рабочим процессам с полным управлением пользовательского интерфейса.", + "feature3": "Улучшенные инструменты Gemini: Новые возможности контекста URL и основы поиска Google предоставляют моделям Gemini информацию в реальном времени и расширенные возможности исследования.", + "hideButton": "Скрыть объявление", + "detailsDiscussLinks": "Подробнее и обсуждение в Discord и Reddit 🚀" }, "reasoning": { "thinking": "Обдумывание", diff --git a/webview-ui/src/i18n/locales/ru/cloud.json b/webview-ui/src/i18n/locales/ru/cloud.json index b2a1aa85fe..5fd6dc372b 100644 --- a/webview-ui/src/i18n/locales/ru/cloud.json +++ b/webview-ui/src/i18n/locales/ru/cloud.json @@ -4,28 +4,15 @@ "logOut": "Выход", "testApiAuthentication": "Проверить аутентификацию API", "signIn": "Подключиться к Roo Code Cloud", - "connect": "Подключиться сейчас", + "connect": "Подключиться", "cloudBenefitsTitle": "Подключиться к Roo Code Cloud", + "cloudBenefitsSubtitle": "Синхронизируй свои промпты и телеметрию, чтобы включить:", + "cloudBenefitHistory": "Онлайн-история задач", + "cloudBenefitSharing": "Функции обмена и совместной работы", + "cloudBenefitMetrics": "Метрики использования на основе задач, токенов и затрат", "cloudBenefitWalkaway": "Отслеживайте и управляйте задачами откуда угодно с Roomote Control", - "cloudBenefitSharing": "Делитесь задачами с другими", - "cloudBenefitHistory": "Получите доступ к истории задач", - "cloudBenefitMetrics": "Получите целостное представление о потреблении токенов", - "visitCloudWebsite": "Посетить Roo Code Cloud", - "taskSync": "Синхронизация задач", - "taskSyncDescription": "Синхронизируйте свои задачи для просмотра и обмена в Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Разрешить управление задачами из Roo Code Cloud", - "remoteControlRequiresTaskSync": "Для использования Roomote Control должна быть включена синхронизация задач", - "taskSyncManagedByOrganization": "Синхронизация задач управляется вашей организацией", - "usageMetricsAlwaysReported": "Информация об использовании модели всегда сообщается при входе в систему", - "authWaiting": "Ожидание завершения аутентификации...", - "havingTrouble": "Проблемы?", - "pasteCallbackUrl": "Скопируй URL перенаправления из браузера и вставь его сюда:", - "startOver": "Начать заново", - "cloudUrlPillLabel": "URL Roo Code Cloud", - "upsell": { - "autoApprovePowerUser": "Предоставить Roo немного независимости? Управляйте им из любого места с помощью Roo Code Cloud. Узнать больше.", - "longRunningTask": "Это может занять некоторое время. Продолжайте из любого места с помощью Облака.", - "taskList": "Roo Code Cloud уже здесь: отслеживайте и управляйте своими задачами из любого места. Узнать больше." - } + "remoteControlDescription": "Позволяет отслеживать и взаимодействовать с задачами в этом рабочем пространстве с Roo Code Cloud", + "visitCloudWebsite": "Посетить Roo Code Cloud", + "cloudUrlPillLabel": "URL Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index b2afae6c6a..24b09ab6c1 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -793,7 +793,7 @@ "feedback": "Если у вас есть вопросы или предложения, откройте issue на github.com/RooCodeInc/Roo-Code или присоединяйтесь к reddit.com/r/RooCode или discord.gg/roocode", "telemetry": { "label": "Разрешить анонимную отправку ошибок и статистики использования", - "description": "Помогите улучшить Roo Code, отправляя анонимные данные об использовании и отчеты об ошибках. Эта телеметрия не собирает код, промпты или личную информацию. Смотрите нашу политику конфиденциальности для получения подробной информации." + "description": "Помогите улучшить Roo Code, отправляя анонимные данные об ошибках и использовании. Код, подсказки и личная информация не отправляются. Подробнее — в политике конфиденциальности." }, "settings": { "import": "Импорт", diff --git a/webview-ui/src/i18n/locales/ru/welcome.json b/webview-ui/src/i18n/locales/ru/welcome.json index b8400444a0..cae5b790e7 100644 --- a/webview-ui/src/i18n/locales/ru/welcome.json +++ b/webview-ui/src/i18n/locales/ru/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Мы рекомендуем использовать маршрутизатор LLM:", "startCustom": "Или вы можете использовать свой собственный API-ключ:", "telemetry": { - "helpImprove": "Помогите улучшить Roo Code", - "helpImproveMessage": "Roo Code собирает данные об ошибках и использовании, чтобы помочь нам исправлять баги и улучшать расширение. Эта телеметрия не собирает код, промпты или личную информацию. Вы можете отключить это в настройках." + "title": "Помогите улучшить Roo Code", + "anonymousTelemetry": "Отправлять анонимные данные об ошибках и использовании, чтобы помочь нам исправлять баги и совершенствовать расширение. Код, промпты и личная информация никогда не отправляются.", + "changeSettings": "Вы всегда можете изменить это внизу страницы настроек", + "settings": "настройки", + "allow": "Разрешить", + "deny": "Запретить" }, "importSettings": "Импорт настроек" } diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 5fbf909500..867acfbc9f 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Görevleri paylaşmak için Roo Code Cloud'a giriş yap", "sharingDisabledByOrganization": "Paylaşım kuruluş tarafından devre dışı bırakıldı", "shareSuccessOrganization": "Organizasyon bağlantısı panoya kopyalandı", - "shareSuccessPublic": "Genel bağlantı panoya kopyalandı", - "openInCloud": "Görevi Roo Code Cloud'da aç", - "openInCloudIntro": "Roo'yu her yerden izlemeye veya etkileşime devam et. Açmak için tara, tıkla veya kopyala." + "shareSuccessPublic": "Genel bağlantı panoya kopyalandı" }, "unpin": "Sabitlemeyi iptal et", "pin": "Sabitle", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} Yayınlandı", - "description": "Roo Code Cloud Tanıtımı: Roo'nun gücünü IDE'nin ötesine taşıyoruz", - "feature1": "Görev ilerlemesini her yerden takip edin (Ücretsiz): IDE'nizde sıkışıp kalmadan uzun süren görevlerin gerçek zamanlı güncellemelerini alın", - "feature2": "Roo Uzantısını uzaktan kontrol edin (Pro): Sohbet tabanlı tarayıcı arayüzünden görevleri başlatın, durdurun ve etkileşime geçin.", - "learnMore": "Kontrolü ele almaya hazır mısınız? Daha fazlasını buradan öğrenin.", - "visitCloudButton": "Roo Code Cloud'u Ziyaret Et", - "socialLinks": "Bize X, Discord, veya r/RooCode'da katılın" + "stealthModel": { + "feature": "Sonic gizli model artık Grok Code Fast! Bu yüksek performanslı akıl yürütme modeli xAI (Grok) sağlayıcısı altında grok-code-fast-1 olarak mevcut.", + "note": "Sonic hakkındaki tüm yararlı geri bildirimler için teşekkür olarak, xAI grok-code-fast-1'e ücretsiz erişimi Roo Code Cloud sağlayıcısı üzerinden bir hafta daha uzatıyor.", + "connectButton": "Roo Code Cloud'a bağlan", + "selectModel": "Sağlayıcı yapılandırmanızı güncellemek için Ayarlar'ı ziyaret edin." + }, + "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": "Mesaj Kuyruğu: Roo çalışırken birden fazla mesajı kuyruğa alın, iş akışınızı kesintisiz olarak planlamaya devam etmenizi sağlar.", + "feature2": "Özel Slash Komutları: Sık kullanılan promptlara ve iş akışlarına hızlı erişim için kişiselleştirilmiş slash komutları oluşturun, tam UI yönetimi ile.", + "feature3": "Gelişmiş Gemini Araçları: Yeni URL bağlamı ve Google Arama temellendirilmesi yetenekleri, Gemini modellerine gerçek zamanlı web bilgileri ve gelişmiş araştırma yetenekleri sağlar.", + "hideButton": "Duyuruyu gizle", + "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/tr/cloud.json b/webview-ui/src/i18n/locales/tr/cloud.json index e8630c2d9e..822e837a9f 100644 --- a/webview-ui/src/i18n/locales/tr/cloud.json +++ b/webview-ui/src/i18n/locales/tr/cloud.json @@ -4,28 +4,15 @@ "logOut": "Çıkış yap", "testApiAuthentication": "API Kimlik Doğrulamayı Test Et", "signIn": "Roo Code Cloud'a bağlan", - "connect": "Şimdi Bağlan", + "connect": "Bağlan", "cloudBenefitsTitle": "Roo Code Cloud'a bağlan", + "cloudBenefitsSubtitle": "Aşağıdakileri etkinleştirmek için promptlarını ve telemetriyi senkronize et:", + "cloudBenefitHistory": "Çevrimiçi görev geçmişi", + "cloudBenefitSharing": "Paylaşım ve işbirliği özellikleri", + "cloudBenefitMetrics": "Görev, token ve maliyet tabanlı kullanım metrikleri", "cloudBenefitWalkaway": "Roomote Control ile görevleri her yerden takip et ve kontrol et", - "cloudBenefitSharing": "Görevleri başkalarıyla paylaş", - "cloudBenefitHistory": "Görev geçmişine eriş", - "cloudBenefitMetrics": "Token tüketiminizin bütünsel görünümünü elde edin", - "visitCloudWebsite": "Roo Code Cloud'u ziyaret et", - "taskSync": "Görev senkronizasyonu", - "taskSyncDescription": "Görevlerinizi Roo Code Cloud'da görüntülemek ve paylaşmak için senkronize edin", "remoteControl": "Roomote Control", - "remoteControlDescription": "Roo Code Cloud'dan görevleri kontrol etmeye izin ver", - "remoteControlRequiresTaskSync": "Roomote Control'ü kullanmak için görev senkronizasyonu etkinleştirilmelidir", - "taskSyncManagedByOrganization": "Görev senkronizasyonu kuruluşunuz tarafından yönetilir", - "usageMetricsAlwaysReported": "Oturum açıldığında model kullanım bilgileri her zaman raporlanır", - "authWaiting": "Kimlik doğrulama tamamlanması bekleniyor...", - "havingTrouble": "Sorun yaşıyor musun?", - "pasteCallbackUrl": "Tarayıcından redirect URL'sini kopyala ve buraya yapıştır:", - "startOver": "Baştan başla", - "cloudUrlPillLabel": "Roo Code Cloud URL'si", - "upsell": { - "autoApprovePowerUser": "Roo'ya biraz bağımsızlık mı veriyorsunuz? Roo Code Cloud ile onu her yerden kontrol edin. Daha fazla bilgi edinin.", - "longRunningTask": "Bu biraz zaman alabilir. Bulut ile her yerden devam edin.", - "taskList": "Roo Code Cloud burada: görevlerinizi her yerden takip edin ve kontrol edin. Daha fazla bilgi edinin." - } + "remoteControlDescription": "Bu çalışma alanındaki görevleri Roo Code Cloud ile takip etme ve etkileşim kurma imkanı sağlar", + "visitCloudWebsite": "Roo Code Cloud'u ziyaret et", + "cloudUrlPillLabel": "Roo Code Cloud URL'si" } diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 0be0860693..91e5b3e9d0 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -793,7 +793,7 @@ "feedback": "Herhangi bir sorunuz veya geri bildiriminiz varsa, github.com/RooCodeInc/Roo-Code adresinde bir konu açmaktan veya reddit.com/r/RooCode ya da discord.gg/roocode'a katılmaktan çekinmeyin", "telemetry": { "label": "Anonim hata ve kullanım raporlamaya izin ver", - "description": "Anonim kullanım verileri ve hata raporları göndererek Roo Code'u geliştirmeye yardım edin. Bu telemetri kod, prompt veya kişisel bilgi toplamaz. Daha fazla ayrıntı için gizlilik politikamıza bakın. Bunu istediğiniz zaman kapatabilirsiniz." + "description": "Anonim kullanım verileri ve hata raporları göndererek Roo Code'u geliştirmeye yardımcı olun. Hiçbir kod, istem veya kişisel bilgi asla gönderilmez. Daha fazla ayrıntı için gizlilik politikamıza bakın." }, "settings": { "import": "İçe Aktar", diff --git a/webview-ui/src/i18n/locales/tr/welcome.json b/webview-ui/src/i18n/locales/tr/welcome.json index 7551676c6c..5f989fa75d 100644 --- a/webview-ui/src/i18n/locales/tr/welcome.json +++ b/webview-ui/src/i18n/locales/tr/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Bir LLM yönlendiricisi kullanmanı öneririz:", "startCustom": "Veya kendi API anahtarını kullanabilirsin:", "telemetry": { - "helpImprove": "Roo Code'u Geliştirmeye Yardım Et", - "helpImproveMessage": "Roo Code, hataları düzeltmemize ve uzantıyı geliştirmemize yardımcı olmak için hata ve kullanım verilerini toplar. Bu telemetri kod, prompt veya kişisel bilgi toplamaz. Bunu ayarlardan kapatabilirsin." + "title": "Roo Code'u Geliştirmeye Yardım Et", + "anonymousTelemetry": "Hataları düzeltmemize ve eklentiyi geliştirmemize yardımcı olmak için anonim hata ve kullanım verileri gönder. Hiçbir zaman kod, metin veya kişisel bilgi gönderilmez.", + "changeSettings": "Bunu her zaman ayarların altından değiştirebilirsin", + "settings": "ayarlar", + "allow": "İzin Ver", + "deny": "Reddet" }, "importSettings": "Ayarları İçe Aktar" } diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index 7684714045..ef8e951aac 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "Đăng nhập vào Roo Code Cloud để chia sẻ tác vụ", "sharingDisabledByOrganization": "Chia sẻ bị tổ chức vô hiệu hóa", "shareSuccessOrganization": "Liên kết tổ chức đã được sao chép vào clipboard", - "shareSuccessPublic": "Liên kết công khai đã được sao chép vào clipboard", - "openInCloud": "Mở tác vụ trong Roo Code Cloud", - "openInCloudIntro": "Tiếp tục theo dõi hoặc tương tác với Roo từ bất cứ đâu. Quét, nhấp hoặc sao chép để mở." + "shareSuccessPublic": "Liên kết công khai đã được sao chép vào clipboard" }, "unpin": "Bỏ ghim khỏi đầu", "pin": "Ghim lên đầu", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} Đã phát hành", - "description": "Giới thiệu Roo Code Cloud: Mang sức mạnh của Roo vượt ra ngoài IDE", - "feature1": "Theo dõi tiến trình tác vụ từ bất kỳ đâu (Miễn phí): Nhận cập nhật thời gian thực về các tác vụ chạy dài mà không bị mắc kẹt trong IDE của bạn", - "feature2": "Điều khiển Tiện ích Roo từ xa (Pro): Bắt đầu, dừng và tương tác với các tác vụ từ giao diện trình duyệt dựa trên chat.", - "learnMore": "Sẵn sàng nắm quyền kiểm soát? Tìm hiểu thêm tại đây.", - "visitCloudButton": "Truy cập Roo Code Cloud", - "socialLinks": "Tham gia với chúng tôi trên X, Discord, hoặc r/RooCode" + "stealthModel": { + "feature": "Mô hình stealth Sonic giờ là Grok Code Fast! Mô hình lý luận hiệu năng cao này có sẵn dưới dạng grok-code-fast-1 trong nhà cung cấp xAI (Grok).", + "note": "Để cảm ơn tất cả các phản hồi hữu ích về Sonic, xAI đang mở rộng quyền truy cập miễn phí vào grok-code-fast-1 thêm một tuần nữa thông qua nhà cung cấp Roo Code Cloud.", + "connectButton": "Kết nối với Roo Code Cloud", + "selectModel": "Truy cập Cài đặt để cập nhật cấu hình nhà cung cấp 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": "Hàng đợi Tin nhắn: Xếp hàng nhiều tin nhắn trong khi Roo đang làm việc, cho phép bạn tiếp tục lập kế hoạch quy trình làm việc mà không bị gián đoạn.", + "feature2": "Lệnh Slash Tùy chỉnh: Tạo các lệnh slash được cá nhân hóa để truy cập nhanh vào các prompt và quy trình làm việc thường dùng, với quản lý UI đầy đủ.", + "feature3": "Công cụ Gemini Nâng cao: Khả năng ngữ cảnh URL mới và nền tảng tìm kiếm Google cung cấp cho các mô hình Gemini thông tin web thời gian thực và khả năng nghiên cứu nâng cao.", + "hideButton": "Ẩn thông báo", + "detailsDiscussLinks": "Nhận thêm chi tiết và thảo luận tại DiscordReddit 🚀" }, "browser": { "rooWantsToUse": "Roo muốn sử dụng trình duyệt:", diff --git a/webview-ui/src/i18n/locales/vi/cloud.json b/webview-ui/src/i18n/locales/vi/cloud.json index 069c57e87b..ef444e70bd 100644 --- a/webview-ui/src/i18n/locales/vi/cloud.json +++ b/webview-ui/src/i18n/locales/vi/cloud.json @@ -4,28 +4,15 @@ "logOut": "Đăng xuất", "testApiAuthentication": "Kiểm tra xác thực API", "signIn": "Kết nối với Roo Code Cloud", - "connect": "Kết nối ngay", + "connect": "Kết nối", "cloudBenefitsTitle": "Kết nối với Roo Code Cloud", + "cloudBenefitsSubtitle": "Đồng bộ prompts và telemetry của bạn để kích hoạt:", + "cloudBenefitHistory": "Lịch sử tác vụ trực tuyến", + "cloudBenefitSharing": "Tính năng chia sẻ và cộng tác", + "cloudBenefitMetrics": "Số liệu sử dụng dựa trên tác vụ, token và chi phí", "cloudBenefitWalkaway": "Theo dõi và điều khiển tác vụ từ bất kỳ đâu với Roomote Control", - "cloudBenefitSharing": "Chia sẻ tác vụ với người khác", - "cloudBenefitHistory": "Truy cập lịch sử tác vụ của bạn", - "cloudBenefitMetrics": "Có cái nhìn toàn diện về mức tiêu thụ token của bạn", - "visitCloudWebsite": "Truy cập Roo Code Cloud", - "taskSync": "Đồng bộ tác vụ", - "taskSyncDescription": "Đồng bộ tác vụ của bạn để xem và chia sẻ trên Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Cho phép điều khiển tác vụ từ Roo Code Cloud", - "remoteControlRequiresTaskSync": "Đồng bộ tác vụ phải được bật để sử dụng Roomote Control", - "taskSyncManagedByOrganization": "Việc đồng bộ hóa công việc được quản lý bởi tổ chức của bạn", - "usageMetricsAlwaysReported": "Thông tin sử dụng mô hình luôn được báo cáo khi đăng nhập", - "authWaiting": "Đang chờ hoàn tất xác thực...", - "havingTrouble": "Gặp vấn đề?", - "pasteCallbackUrl": "Sao chép URL redirect từ trình duyệt và dán vào đây:", - "startOver": "Bắt đầu lại", - "cloudUrlPillLabel": "URL Roo Code Cloud", - "upsell": { - "autoApprovePowerUser": "Trao cho Roo một chút độc lập? Kiểm soát nó từ mọi nơi với Roo Code Cloud. Tìm hiểu thêm.", - "longRunningTask": "Việc này có thể mất một lúc. Tiếp tục từ mọi nơi với Cloud.", - "taskList": "Roo Code Cloud đã có mặt: theo dõi và kiểm soát các tác vụ của bạn từ mọi nơi. Tìm hiểu thêm." - } + "remoteControlDescription": "Cho phép theo dõi và tương tác với các tác vụ trong workspace này với Roo Code Cloud", + "visitCloudWebsite": "Truy cập Roo Code Cloud", + "cloudUrlPillLabel": "URL Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 48d5375628..c6fdea7841 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -793,7 +793,7 @@ "feedback": "Nếu bạn có bất kỳ câu hỏi hoặc phản hồi nào, vui lòng mở một vấn đề tại github.com/RooCodeInc/Roo-Code hoặc tham gia reddit.com/r/RooCode hoặc discord.gg/roocode", "telemetry": { "label": "Cho phép báo cáo lỗi và sử dụng ẩn danh", - "description": "Giúp cải thiện Roo Code bằng cách gửi dữ liệu sử dụng ẩn danh và báo cáo lỗi. Telemetry này không thu thập mã, prompt hoặc thông tin cá nhân. Xem chính sách bảo mật của chúng tôi để biết thêm chi tiết. Bạn có thể tắt tính năng này bất cứ lúc nào." + "description": "Giúp cải thiện Roo Code bằng cách gửi dữ liệu sử dụng ẩn danh và báo cáo lỗi. Không bao giờ gửi mã, lời nhắc hoặc thông tin cá nhân. Xem chính sách bảo mật của chúng tôi để biết thêm chi tiết." }, "settings": { "import": "Nhập", diff --git a/webview-ui/src/i18n/locales/vi/welcome.json b/webview-ui/src/i18n/locales/vi/welcome.json index 275bc5039d..6eb484eb89 100644 --- a/webview-ui/src/i18n/locales/vi/welcome.json +++ b/webview-ui/src/i18n/locales/vi/welcome.json @@ -16,8 +16,12 @@ "startRouter": "Chúng tôi khuyên bạn nên sử dụng bộ định tuyến LLM:", "startCustom": "Hoặc bạn có thể sử dụng khóa API của riêng mình:", "telemetry": { - "helpImprove": "Giúp cải thiện Roo Code", - "helpImproveMessage": "Roo Code thu thập dữ liệu lỗi và sử dụng để giúp chúng tôi sửa lỗi và cải thiện tiện ích mở rộng. Telemetry này không thu thập mã, prompt hoặc thông tin cá nhân. Bạn có thể tắt điều này trong cài đặt." + "title": "Giúp cải thiện Roo Code", + "anonymousTelemetry": "Gửi dữ liệu lỗi và sử dụng ẩn danh để giúp chúng tôi sửa lỗi và cải thiện tiện ích mở rộng. Không bao giờ gửi mã, lời nhắc hoặc thông tin cá nhân.", + "changeSettings": "Bạn luôn có thể thay đổi điều này ở cuối phần cài đặt", + "settings": "cài đặt", + "allow": "Cho phép", + "deny": "Từ chối" }, "importSettings": "Nhập cài đặt" } diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index 861eeb3ac5..1e430200a1 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "登录 Roo Code Cloud 以分享任务", "sharingDisabledByOrganization": "组织已禁用分享功能", "shareSuccessOrganization": "组织链接已复制到剪贴板", - "shareSuccessPublic": "公开链接已复制到剪贴板", - "openInCloud": "在 Roo Code Cloud 中打开任务", - "openInCloudIntro": "从任何地方继续监控或与 Roo 交互。扫描、点击或复制以打开。" + "shareSuccessPublic": "公开链接已复制到剪贴板" }, "unpin": "取消置顶", "pin": "置顶", @@ -271,12 +269,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} 已发布", - "description": "介绍 Roo Code Cloud:将 Roo 的强大功能扩展到 IDE 之外", - "feature1": "随时随地跟踪任务进度(免费):获取长时间运行任务的实时更新,无需困在 IDE 中", - "feature2": "远程控制 Roo 扩展(Pro):通过基于聊天的浏览器界面启动、停止和与任务交互。", - "learnMore": "准备掌控一切?在这里了解更多。", - "visitCloudButton": "访问 Roo Code Cloud", - "socialLinks": "在 XDiscordr/RooCode 上关注我们" + "stealthModel": { + "feature": "Sonic 隐形模型现在是 Grok Code Fast!这个高性能推理模型可在 xAI (Grok) 提供商下作为 grok-code-fast-1 使用。", + "note": "作为对所有关于 Sonic 有用反馈的感谢,xAI 将通过 Roo Code Cloud 提供商延长对 grok-code-fast-1 的免费访问权限再一周。", + "connectButton": "连接到 Roo Code Cloud", + "selectModel": "访问设置更新你的提供商配置。" + }, + "description": "Roo Code {{version}} 带来强大的新功能和重大改进,提升您的开发工作流程。", + "whatsNew": "新特性", + "feature1": "消息队列: 在 Roo 工作时将多个消息排队,让你可以不间断地继续规划工作流程。", + "feature2": "自定义斜杠命令: 创建个性化斜杠命令,快速访问常用提示词和工作流程,具备完整的 UI 管理功能。", + "feature3": "增强的 Gemini 工具: 新的 URL 上下文和 Google 搜索基础功能为 Gemini 模型提供实时网络信息和增强的研究能力。", + "hideButton": "隐藏公告", + "detailsDiscussLinks": "在 DiscordReddit 获取更多详情并参与讨论 🚀" }, "browser": { "rooWantsToUse": "Roo想使用浏览器:", diff --git a/webview-ui/src/i18n/locales/zh-CN/cloud.json b/webview-ui/src/i18n/locales/zh-CN/cloud.json index 47006c9227..5a90cb8ccd 100644 --- a/webview-ui/src/i18n/locales/zh-CN/cloud.json +++ b/webview-ui/src/i18n/locales/zh-CN/cloud.json @@ -4,28 +4,15 @@ "logOut": "退出登录", "testApiAuthentication": "测试 API 认证", "signIn": "连接到 Roo Code Cloud", - "connect": "立即连接", + "connect": "连接", "cloudBenefitsTitle": "连接到 Roo Code Cloud", + "cloudBenefitsSubtitle": "同步你的提示词和遥测数据以启用:", + "cloudBenefitHistory": "在线任务历史", + "cloudBenefitSharing": "共享和协作功能", + "cloudBenefitMetrics": "基于任务、Token 和成本的使用指标", "cloudBenefitWalkaway": "使用 Roomote Control 随时随地跟踪和控制任务", - "cloudBenefitSharing": "与他人共享任务", - "cloudBenefitHistory": "访问您的任务历史", - "cloudBenefitMetrics": "获取您的令牌消耗的整体视图", - "visitCloudWebsite": "访问 Roo Code Cloud", - "taskSync": "任务同步", - "taskSyncDescription": "同步您的任务以在 Roo Code Cloud 上查看和共享", "remoteControl": "Roomote Control", - "remoteControlDescription": "允许从 Roo Code Cloud 控制任务", - "remoteControlRequiresTaskSync": "必须启用任务同步才能使用 Roomote Control", - "taskSyncManagedByOrganization": "任务同步由您的组织管理", - "usageMetricsAlwaysReported": "登录时始终报告模型使用信息", - "authWaiting": "等待身份验证完成...", - "havingTrouble": "遇到问题?", - "pasteCallbackUrl": "从浏览器复制重定向 URL 并粘贴到这里:", - "startOver": "重新开始", - "cloudUrlPillLabel": "Roo Code Cloud URL", - "upsell": { - "autoApprovePowerUser": "给 Roo 一些独立性?使用 Roo Code Cloud 从任何地方控制它。 了解更多。", - "longRunningTask": "这可能需要一段时间。使用 Cloud 从任何地方继续。", - "taskList": "Roo Code Cloud 在这里:从任何地方关注和控制您的任务。 了解更多。" - } + "remoteControlDescription": "允许通过 Roo Code Cloud 跟踪和操作此工作区中的任务", + "visitCloudWebsite": "访问 Roo Code Cloud", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index e217bdbbca..c8ca284c04 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -793,7 +793,7 @@ "feedback": "如果您有任何问题或反馈,请随时在 github.com/RooCodeInc/Roo-Code 上提出问题或加入 reddit.com/r/RooCodediscord.gg/roocode", "telemetry": { "label": "允许匿名数据收集", - "description": "通过发送匿名使用数据和错误报告来帮助改进 Roo Code。此遥测不会收集代码、提示 或个人信息。详细信息请参阅我们的隐私政策。您可以随时关闭此功能。" + "description": "匿名收集错误报告和使用数据(不含代码/提示/个人信息),详情见隐私政策" }, "settings": { "import": "导入", diff --git a/webview-ui/src/i18n/locales/zh-CN/welcome.json b/webview-ui/src/i18n/locales/zh-CN/welcome.json index a53adf08cd..690a6aa199 100644 --- a/webview-ui/src/i18n/locales/zh-CN/welcome.json +++ b/webview-ui/src/i18n/locales/zh-CN/welcome.json @@ -16,8 +16,12 @@ "startRouter": "我们推荐使用 LLM 路由器:", "startCustom": "或者你可以使用自己的 API 密钥:", "telemetry": { - "helpImprove": "Help Improve Roo Code", - "helpImproveMessage": "Roo Code 收集错误和使用数据来帮助我们修复 bug 并改进扩展。此遥测不会收集代码、提示词或个人信息。您可以在设置中关闭此设置。" + "title": "帮助改进 Roo Code", + "anonymousTelemetry": "发送匿名的错误和使用数据,以帮助我们修复错误并改进扩展程序。不会涉及代码、提示词或个人隐私信息。", + "changeSettings": "可以随时在设置页面底部更改此设置", + "settings": "设置", + "allow": "允许", + "deny": "拒绝" }, "importSettings": "导入设置" } diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 1d6c824ced..f5183d65a9 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -24,9 +24,7 @@ "connectToCloudDescription": "登入 Roo Code Cloud 以分享工作", "sharingDisabledByOrganization": "組織已停用分享功能", "shareSuccessOrganization": "組織連結已複製到剪貼簿", - "shareSuccessPublic": "公開連結已複製到剪貼簿", - "openInCloud": "在 Roo Code Cloud 中開啟工作", - "openInCloudIntro": "從任何地方繼續監控或與 Roo 互動。掃描、點擊或複製以開啟。" + "shareSuccessPublic": "公開連結已複製到剪貼簿" }, "unpin": "取消釘選", "pin": "釘選", @@ -280,12 +278,19 @@ }, "announcement": { "title": "🎉 Roo Code {{version}} 已發布", - "description": "介紹 Roo Code Cloud:將 Roo 的強大功能延伸到 IDE 之外", - "feature1": "隨時隨地追蹤任務進度(免費):取得長時間執行任務的即時更新,無需被困在 IDE 中", - "feature2": "遠端控制 Roo 擴充功能(Pro):透過基於聊天的瀏覽器介面啟動、停止並與任務互動。", - "learnMore": "準備好掌控一切了嗎?在這裡了解更多。", - "visitCloudButton": "造訪 Roo Code Cloud", - "socialLinks": "在 XDiscordr/RooCode 上關注我們" + "stealthModel": { + "feature": "Sonic 隱形模型現在是 Grok Code Fast!這個高效能推理模型現已作為 grok-code-fast-1xAI (Grok) 提供商下提供。", + "note": "作為對 Sonic 所有寶貴回饋的感謝,xAI 將透過 Roo Code Cloud 提供商延長 grok-code-fast-1 的免費存取一週。", + "connectButton": "連接到 Roo Code Cloud", + "selectModel": "造訪設定更新你的提供商設定。" + }, + "description": "Roo Code {{version}} 帶來強大的新功能和重大改進,提升您的開發工作流程。", + "whatsNew": "新功能", + "feature1": "訊息佇列:在 Roo 工作時將多個訊息排入佇列,讓您可以不間斷地繼續規劃工作流程。", + "feature2": "自訂斜線命令:建立個人化斜線命令,快速存取常用提示詞和工作流程,具備完整的 UI 管理功能。", + "feature3": "增強的 Gemini 工具:新的 URL 內容和 Google 搜尋基礎功能為 Gemini 模型提供即時網路資訊和增強的研究能力。", + "hideButton": "隱藏公告", + "detailsDiscussLinks": "在 DiscordReddit 取得更多詳細資訊並參與討論 🚀" }, "reasoning": { "thinking": "思考中", diff --git a/webview-ui/src/i18n/locales/zh-TW/cloud.json b/webview-ui/src/i18n/locales/zh-TW/cloud.json index 053dd23024..034c15e204 100644 --- a/webview-ui/src/i18n/locales/zh-TW/cloud.json +++ b/webview-ui/src/i18n/locales/zh-TW/cloud.json @@ -3,29 +3,16 @@ "profilePicture": "個人圖片", "logOut": "登出", "testApiAuthentication": "測試 API 認證", - "signIn": "連線至 Roo Code Cloud", - "connect": "立即連線", + "signIn": "登入 Roo Code Cloud", + "connect": "連線", "cloudBenefitsTitle": "連線至 Roo Code Cloud", - "cloudBenefitWalkaway": "使用 Roomote Control 隨時隨地追蹤和控制任務", - "cloudBenefitSharing": "與他人分享任務", - "cloudBenefitHistory": "存取您的任務歷史", - "cloudBenefitMetrics": "獲得您的代幣消耗的整體視圖", - "visitCloudWebsite": "造訪 Roo Code Cloud", - "taskSync": "任務同步", - "taskSyncDescription": "同步您的任務以在 Roo Code Cloud 上檢視和分享", + "cloudBenefitsSubtitle": "同步您的提示詞和遙測資料以啟用:", + "cloudBenefitHistory": "線上工作歷史紀錄", + "cloudBenefitSharing": "分享和協作功能", + "cloudBenefitMetrics": "基於工作任務、Token 和成本的用量指標", + "cloudBenefitWalkaway": "使用 Roomote Control 隨時隨地追蹤和控制工作", "remoteControl": "Roomote Control", - "remoteControlDescription": "允許從 Roo Code Cloud 控制任務", - "remoteControlRequiresTaskSync": "必須啟用任務同步才能使用 Roomote Control", - "taskSyncManagedByOrganization": "工作同步由您的組織管理", - "usageMetricsAlwaysReported": "登入時始終報告模型使用資訊", - "authWaiting": "等待身份驗證完成...", - "havingTrouble": "遇到問題?", - "pasteCallbackUrl": "從瀏覽器複製重新導向 URL 並貼上到這裡:", - "startOver": "重新開始", - "cloudUrlPillLabel": "Roo Code Cloud URL", - "upsell": { - "autoApprovePowerUser": "給 Roo 一點獨立性?使用 Roo Code Cloud 隨時隨地控制它。了解更多。", - "longRunningTask": "這可能需要一些時間。使用雲端隨時隨地繼續。", - "taskList": "Roo Code Cloud 在此:隨時隨地追蹤和控制您的任務。了解更多。" - } + "remoteControlDescription": "允許透過 Roo Code Cloud 追蹤和操作此工作區中的工作", + "visitCloudWebsite": "造訪 Roo Code Cloud", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 69bd4be8c6..8163cce20f 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -793,7 +793,7 @@ "feedback": "若您有任何問題或建議,歡迎至 github.com/RooCodeInc/Roo-Code 提出 issue,或加入 reddit.com/r/RooCodediscord.gg/roocode 討論。", "telemetry": { "label": "允許匿名錯誤與使用情況回報", - "description": "透過發送匿名使用資料和錯誤回報來協助改善 Roo Code。此遙測不會收集程式碼、Prompt 或個人資訊。查看我們的隱私政策以了解更多詳情。您可以隨時關閉此功能。" + "description": "透過傳送匿名的使用資料與錯誤回報,協助改善 Roo Code。我們絕不會傳送您的程式碼、提示或個人資訊。詳細資訊請參閱我們的隱私權政策。" }, "settings": { "import": "匯入", diff --git a/webview-ui/src/i18n/locales/zh-TW/welcome.json b/webview-ui/src/i18n/locales/zh-TW/welcome.json index de1beb9ffe..2384d4f3e9 100644 --- a/webview-ui/src/i18n/locales/zh-TW/welcome.json +++ b/webview-ui/src/i18n/locales/zh-TW/welcome.json @@ -16,8 +16,12 @@ "startRouter": "我們建議使用 LLM 路由器:", "startCustom": "或者您可以使用自己的 API 金鑰:", "telemetry": { - "helpImprove": "協助改進 Roo Code", - "helpImproveMessage": "Roo Code 會收集錯誤和使用資料,協助我們修復錯誤並改善擴充功能。此遙測不會收集程式碼、提示或個人資訊。您可以在設定中關閉此設定。" + "title": "協助改進 Roo Code", + "anonymousTelemetry": "傳送匿名錯誤和使用資料,以協助我們修復錯誤並改善擴充功能。我們絕不會傳送任何程式碼、命令提示詞、或個人資訊 (除非您使用了 Roo Code Cloud)。詳細資訊請參閱我們的隱私權政策。", + "changeSettings": "您隨時可以到設定頁面底部變更此選項", + "settings": "設定", + "allow": "允許", + "deny": "拒絕" }, "importSettings": "匯入設定" } diff --git a/webview-ui/src/index.css b/webview-ui/src/index.css index 6f23892ced..073b815845 100644 --- a/webview-ui/src/index.css +++ b/webview-ui/src/index.css @@ -140,9 +140,6 @@ --color-vscode-editorHoverWidget-foreground: var(--vscode-editorHoverWidget-foreground); --color-vscode-editorHoverWidget-background: var(--vscode-editorHoverWidget-background); --color-vscode-editorHoverWidget-border: var(--vscode-editorHoverWidget-border); - - --color-vscode-banner-background: var(--vscode-banner-background); - --color-vscode-banner-foreground: var(--vscode-banner-foreground); } @layer base { @@ -489,4 +486,24 @@ input[cmdk-input]:focus { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; + + /* Hide API Request text when container is too narrow */ + @media (max-width: 400px) { + .api-request-text { + display: none !important; + } + } + + /* Alternative: Use container query for more precise control */ + @supports (container-type: inline-size) { + .api-request-container { + container-type: inline-size; + } + + @container (max-width: 350px) { + .api-request-text { + display: none !important; + } + } + } } diff --git a/webview-ui/src/utils/TelemetryClient.ts b/webview-ui/src/utils/TelemetryClient.ts index 7eec16d75d..dd587f51ed 100644 --- a/webview-ui/src/utils/TelemetryClient.ts +++ b/webview-ui/src/utils/TelemetryClient.ts @@ -9,7 +9,7 @@ class TelemetryClient { public updateTelemetryState(telemetrySetting: TelemetrySetting, apiKey?: string, distinctId?: string) { posthog.reset() - if (telemetrySetting !== "disabled" && apiKey && distinctId) { + if (telemetrySetting === "enabled" && apiKey && distinctId) { TelemetryClient.telemetryEnabled = true posthog.init(apiKey, { diff --git a/webview-ui/src/utils/formatTokens.ts b/webview-ui/src/utils/formatTokens.ts new file mode 100644 index 0000000000..2e11f16af8 --- /dev/null +++ b/webview-ui/src/utils/formatTokens.ts @@ -0,0 +1,52 @@ +/** + * Format token count for display + * @param count - The token count to format + * @returns Formatted string (e.g., "1.2k" for 1200) + */ +export function formatTokenCount(count: number | undefined): string { + if (count === undefined || count === 0) { + return "0" + } + + if (count < 1000) { + return count.toString() + } + + // Format as k (thousands) with one decimal place + const thousands = count / 1000 + if (thousands < 10) { + // For values less than 10k, show one decimal place + return `${thousands.toFixed(1)}k` + } else { + // For values 10k and above, show no decimal places + return `${Math.round(thousands)}k` + } +} + +/** + * Format token statistics for display + * @param tokensIn - Input tokens + * @param tokensOut - Output tokens + * @param cacheReads - Cache read tokens (optional) + * @returns Formatted string for display + */ +export function formatTokenStats( + tokensIn?: number, + tokensOut?: number, + cacheReads?: number, +): { input: string; output: string } { + let inputDisplay = formatTokenCount(tokensIn) + + // Add cache reads in parentheses if they exist + if (cacheReads && cacheReads > 0) { + const cacheDisplay = formatTokenCount(cacheReads) + inputDisplay = `${inputDisplay} (${cacheDisplay} cache)` + } + + const outputDisplay = formatTokenCount(tokensOut) + + return { + input: inputDisplay, + output: outputDisplay, + } +}