From 0bcac6519e0775385637e8a5251f56a673174ef3 Mon Sep 17 00:00:00 2001 From: hannesrudolph Date: Fri, 18 Apr 2025 17:12:42 -0600 Subject: [PATCH 01/15] isotrUpdate welcome screen UI components and fix unused variable --- .../src/components/chat/Announcement.tsx | 59 ++++---- webview-ui/src/components/chat/ChatView.tsx | 135 +++++++----------- .../src/components/chat/ContextMenu.tsx | 4 +- .../src/components/history/HistoryPreview.tsx | 48 +++---- webview-ui/src/components/welcome/RooHero.tsx | 9 +- webview-ui/src/components/welcome/RooTips.tsx | 93 ++++++++++++ .../welcome/__tests__/RooTips.test.tsx | 74 ++++++++++ webview-ui/src/i18n/locales/en/chat.json | 19 ++- 8 files changed, 290 insertions(+), 151 deletions(-) create mode 100644 webview-ui/src/components/welcome/RooTips.tsx create mode 100644 webview-ui/src/components/welcome/__tests__/RooTips.test.tsx diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 26ccd6e55b1..9bbee7b5846 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -42,25 +42,26 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { ) return ( -
- - - -

{t("chat:announcement.title")}

+
+
+ + + +

{t("chat:announcement.title")}

-

{t("chat:announcement.description")}

+

{t("chat:announcement.description")}

{t("chat:announcement.whatsNew")}

    @@ -70,7 +71,6 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { i18nKey="chat:announcement.feature1" components={{ bold: , - code: , }} /> @@ -80,7 +80,6 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { i18nKey="chat:announcement.feature2" components={{ bold: , - code: , }} /> @@ -90,21 +89,21 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { i18nKey="chat:announcement.feature3" components={{ bold: , - code: , }} />
-

- -

+

+ +

+
) } diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 419537b361a..28cb97d2c31 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -3,7 +3,6 @@ import debounce from "debounce" import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react" import { useDeepCompareEffect, useEvent, useMount } from "react-use" import { Virtuoso, type VirtuosoHandle } from "react-virtuoso" -import styled from "styled-components" import removeMd from "remove-markdown" import { Trans } from "react-i18next" @@ -30,8 +29,8 @@ import { useAppTranslation } from "@src/i18n/TranslationContext" import TelemetryBanner from "../common/TelemetryBanner" import HistoryPreview from "../history/HistoryPreview" -import RooHero from "../welcome/RooHero" - +import RooHero from "@src/components/welcome/RooHero" +import RooTips from "@src/components/welcome/RooTips" import Announcement from "./Announcement" import BrowserSessionRow from "./BrowserSessionRow" import ChatRow from "./ChatRow" @@ -40,6 +39,7 @@ import TaskHeader from "./TaskHeader" import AutoApproveMenu from "./AutoApproveMenu" import SystemPromptWarning from "./SystemPromptWarning" +import { useTaskSearch } from "@/components/history/useTaskSearch" interface ChatViewProps { isHidden: boolean showAnnouncement: boolean @@ -86,6 +86,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined const task = useMemo(() => messages.at(0), [messages]) // leaving this less safe version here since if the first message is not a task, then the extension is in a bad state and needs to be debugged (see Cline.abort) const modifiedMessages = useMemo(() => combineApiRequests(combineCommandSequences(messages.slice(1))), [messages]) @@ -1199,17 +1201,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction +
{task ? ( <> ) : ( -
+
{telemetrySetting === "unset" && } {showAnnouncement && } + {/* Always show the hero. */} + {/* If the user has no task history, we can show the onboarding message */} + {!taskHistory.length && ( +

+ + the docs + + ), + }} + /> +

+ )} + + {/* Show the task history if there are any for this workspace. */} {taskHistory.length > 0 && } + {/* Finally, if there less than 3 tasks, we can show the tips */} + {tasks.length < 3 && 0)} />}
)} @@ -1272,28 +1279,20 @@ const ChatViewComponent: React.ForwardRefRenderFunction +
+ +
)} {task && ( <> -
+
, // Add empty padding at the bottom + Footer: () =>
, // Add empty padding at the bottom }} // increasing top by 3_000 to prevent jumping around when user collapses a row increaseViewportBy={{ top: 3_000, bottom: Number.MAX_SAFE_INTEGER }} // hack to make sure the last message is always rendered to get truly perfect scroll to bottom animation when new messages are added (Number.MAX_SAFE_INTEGER is safe for arithmetic operations, which is all virtuoso uses this value for in src/sizeRangeSystem.ts) @@ -1312,40 +1311,33 @@ const ChatViewComponent: React.ForwardRefRenderFunction {showScrollToBottom ? ( -
- +
{ scrollToBottomSmooth() disableAutoScrollRef.current = false }} title={t("chat:scrollToBottom")}> - - + +
) : (
+ className={`flex ${ + primaryButtonText || secondaryButtonText || isStreaming ? "px-[15px] pt-[10px]" : "p-0" + } ${ + primaryButtonText || secondaryButtonText || isStreaming + ? enableButtons || (isStreaming && !didClickCancel) + ? "opacity-100" + : "opacity-50" + : "opacity-0" + }`}> {primaryButtonText && !isStreaming && ( = ({ diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 3d3a5f0a13a..82bfcb909c3 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -9,6 +9,7 @@ import { CopyButton } from "./CopyButton" import { useTaskSearch } from "./useTaskSearch" import { Trans } from "react-i18next" +import { Coins } from "lucide-react" type HistoryPreviewProps = { showHistoryView: () => void @@ -20,20 +21,21 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { return ( <>
- {!!tasks.length && ( -
+ {tasks.length !== 0 && ( +
{t("history:recentTasks")}
)} + {tasks.length === 0 && ( <> -

+

{ />

- )} + {tasks.slice(0, 3).map((item) => (
vscode.postMessage({ type: "showTaskWithId", text: item.id })}>
@@ -67,39 +71,23 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => {
{item.task}
-
- - {t("history:tokens", { - in: formatLargeNumber(item.tokensIn || 0), - out: formatLargeNumber(item.tokensOut || 0), - })} - - {!!item.cacheWrites && ( - <> - {" • "} - - {t("history:cache", { - writes: formatLargeNumber(item.cacheWrites || 0), - reads: formatLargeNumber(item.cacheReads || 0), - })} - - - )} +
+ ↑ {formatLargeNumber(item.tokensIn || 0)} + ↓ {formatLargeNumber(item.tokensOut || 0)} {!!item.totalCost && ( - <> - {" • "} - {t("history:apiCost", { cost: item.totalCost?.toFixed(4) })} - + + {"$" + item.totalCost?.toFixed(2)} + )}
{showAllWorkspaces && item.workspace && ( diff --git a/webview-ui/src/components/welcome/RooHero.tsx b/webview-ui/src/components/welcome/RooHero.tsx index f4be0b6c070..bc99dbd004d 100644 --- a/webview-ui/src/components/welcome/RooHero.tsx +++ b/webview-ui/src/components/welcome/RooHero.tsx @@ -1,7 +1,7 @@ import { useState } from "react" -import { useAppTranslation } from "@src/i18n/TranslationContext" +import { useAppTranslation } from "../../i18n/TranslationContext" -const WelcomeView = () => { +const RooHero = () => { const { t } = useAppTranslation() const [imagesBaseUri] = useState(() => { @@ -10,7 +10,7 @@ const WelcomeView = () => { }) return ( -
+
{ className="mx-auto"> Roo logo
+

{t("chat:greeting")}

) } -export default WelcomeView +export default RooHero diff --git a/webview-ui/src/components/welcome/RooTips.tsx b/webview-ui/src/components/welcome/RooTips.tsx new file mode 100644 index 00000000000..597449bb4a0 --- /dev/null +++ b/webview-ui/src/components/welcome/RooTips.tsx @@ -0,0 +1,93 @@ +import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" +import { useTranslation } from "react-i18next" +import { useState, useEffect } from "react" +import clsx from "clsx" + +const tips = [ + { + icon: "codicon-list-tree", + href: "https://docs.roocode.com/features/boomerang-tasks", + titleKey: "rooTips.boomerangTasks.title", + descriptionKey: "rooTips.boomerangTasks.description", + }, + { + icon: "codicon-pinned", + href: "https://docs.roocode.com/basic-usage/using-modes", + titleKey: "rooTips.stickyModels.title", + descriptionKey: "rooTips.stickyModels.description", + }, + { + icon: "codicon-tools", + href: "https://docs.roocode.com/basic-usage/how-tools-work", + titleKey: "rooTips.tools.title", + descriptionKey: "rooTips.tools.description", + }, +] + +interface RooTipsProps { + cycle?: boolean +} + +const RooTips = ({ cycle = true }: RooTipsProps) => { + const { t } = useTranslation("chat") + const [currentTipIndex, setCurrentTipIndex] = useState(Math.floor(Math.random() * tips.length)) + const [isFading, setIsFading] = useState(false) + + useEffect(() => { + if (!cycle) return + + const intervalId = setInterval(() => { + setIsFading(true) // Start fade out + setTimeout(() => { + setCurrentTipIndex((prevIndex) => (prevIndex + 1) % tips.length) + setIsFading(false) // Start fade in + }, 1000) // Fade duration + }, 11000) // 10s display + 1s fade + + return () => clearInterval(intervalId) // Cleanup on unmount + }, [cycle]) + + const currentTip = tips[currentTipIndex] + const topTwoTips = tips.slice(0, 2) + + return ( +
+ {/* If we need real estate, we show a compressed version of the tips. Otherwise, we expand it. */} + {cycle ? ( + <> +
Did you know about...
+
+ {" "} + {/* Corrected backtick to parenthesis */} + + + {t(currentTip.titleKey)}:{" "} + {t(currentTip.descriptionKey)} + +
+ + ) : ( + topTwoTips.map((tip) => ( +
+ + + {t(tip.titleKey)}: {t(tip.descriptionKey)} + +
+ )) + )} +
+ ) +} + +export default RooTips diff --git a/webview-ui/src/components/welcome/__tests__/RooTips.test.tsx b/webview-ui/src/components/welcome/__tests__/RooTips.test.tsx new file mode 100644 index 00000000000..fdd49db4eb1 --- /dev/null +++ b/webview-ui/src/components/welcome/__tests__/RooTips.test.tsx @@ -0,0 +1,74 @@ +import { render, screen, act } from "@testing-library/react" +import RooTips from "../RooTips" +import React from "react" // Import React for JSX types + +// Mock the translation hook +jest.mock("react-i18next", () => ({ + useTranslation: () => ({ + t: (key: string) => key, // Simple mock that returns the key + }), + Trans: ({ children }: { children: React.ReactNode }) => children, +})) + +// Mock VSCodeLink +jest.mock("@vscode/webview-ui-toolkit/react", () => ({ + VSCodeLink: ({ href, children }: { href: string; children: React.ReactNode }) => {children}, +})) + +describe("RooTips Component", () => { + beforeEach(() => { + jest.useFakeTimers() + }) + + afterEach(() => { + jest.runOnlyPendingTimers() + jest.useRealTimers() + }) + + test("renders and cycles through tips by default (cycle=true)", () => { + render() + + // Initial render (random tip) - check if one tip is rendered + // We check for the link text pattern as the description is included + expect(screen.getByRole("link", { name: /rooTips\..*\.title/i })).toBeInTheDocument() + expect(screen.getAllByRole("link")).toHaveLength(1) + + // Fast-forward time to trigger the interval + fade timeout + act(() => { + jest.advanceTimersByTime(11000 + 1000) // interval + fade duration + }) + + // After interval, a different tip should be potentially rendered (still one tip) + // Note: Due to random start, we can't guarantee a *different* tip if there are only 2, + // but the core logic is that it attempts to cycle. We re-check the structure. + expect(screen.getByRole("link", { name: /rooTips\..*\.title/i })).toBeInTheDocument() + expect(screen.getAllByRole("link")).toHaveLength(1) + }) + + test("renders only the top two tips when cycle is false", () => { + render() + + // Check if the first two tips are rendered + expect(screen.getByRole("link", { name: "rooTips.boomerangTasks.title" })).toBeInTheDocument() + expect(screen.getByText("rooTips.boomerangTasks.description")).toBeInTheDocument() + expect(screen.getByRole("link", { name: "rooTips.stickyModels.title" })).toBeInTheDocument() + expect(screen.getByText("rooTips.stickyModels.description")).toBeInTheDocument() + + // Ensure only two tips are present + expect(screen.getAllByRole("link")).toHaveLength(2) + + // Check that the third tip is not rendered + expect(screen.queryByRole("link", { name: "rooTips.tools.title" })).not.toBeInTheDocument() + + // Fast-forward time - nothing should change + act(() => { + jest.advanceTimersByTime(12000) + }) + + // Verify the state remains the same (still top two tips) + expect(screen.getByRole("link", { name: "rooTips.boomerangTasks.title" })).toBeInTheDocument() + expect(screen.getByRole("link", { name: "rooTips.stickyModels.title" })).toBeInTheDocument() + expect(screen.getAllByRole("link")).toHaveLength(2) + expect(screen.queryByRole("link", { name: "rooTips.tools.title" })).not.toBeInTheDocument() + }) +}) diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index c40a5507583..75ea986d541 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -65,7 +65,8 @@ "tooltip": "Cancel the current operation" }, "scrollToBottom": "Scroll to bottom of chat", - "onboarding": "Your task list in this workspace is empty. Start by typing in a task below. Not sure how to begin? Read more about what Roo can do for you in the docs.", + "about": "Generate, refactor, and debug code with AI assistance.
Check out our documentation to learn more.", + "onboarding": "Your task list in this workspace is empty.", "selectMode": "Select mode for interaction", "selectApiConfig": "Select API configuration", "enhancePrompt": "Enhance prompt with additional context", @@ -217,5 +218,19 @@ "close": "Close browser" } }, - "systemPromptWarning": "WARNING: Custom system prompt override active. This can severely break functionality and cause unpredictable behavior." + "systemPromptWarning": "WARNING: Custom system prompt override active. This can severely break functionality and cause unpredictable behavior.", + "rooTips": { + "boomerangTasks": { + "title": "Boomerang Tasks", + "description": "Orchestrate complex workflows with subtasks" + }, + "stickyModels": { + "title": "Sticky Models", + "description": "Each mode remembers your last used model" + }, + "tools": { + "title": "Tools", + "description": "Allow the AI to solve problems by browsing the web, running commands, and more." + } + } } From ba9a4767641614fb507fe887541c7a52e1f10bf0 Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 10:30:26 -0400 Subject: [PATCH 02/15] Save collapsibility. --- src/core/webview/ClineProvider.ts | 3 + src/core/webview/webviewMessageHandler.ts | 4 + src/exports/roo-code.d.ts | 1 + src/exports/types.ts | 1 + src/schemas/index.ts | 4 + src/shared/ExtensionMessage.ts | 2 + src/shared/WebviewMessage.ts | 2 + .../src/components/history/HistoryPreview.tsx | 107 +++++++++++------- .../src/context/ExtensionStateContext.tsx | 5 + 9 files changed, 88 insertions(+), 41 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index bf5901b8171..81958c8564f 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1244,6 +1244,7 @@ export class ClineProvider extends EventEmitter implements language, maxReadFileLine, terminalCompressProgressBar, + historyPreviewCollapsed } = await this.getState() const telemetryKey = process.env.POSTHOG_API_KEY @@ -1329,6 +1330,7 @@ export class ClineProvider extends EventEmitter implements settingsImportedAt: this.settingsImportedAt, terminalCompressProgressBar: terminalCompressProgressBar ?? true, hasSystemPromptOverride, + historyPreviewCollapsed: historyPreviewCollapsed ?? false, } } @@ -1417,6 +1419,7 @@ export class ClineProvider extends EventEmitter implements telemetrySetting: stateValues.telemetrySetting || "unset", showRooIgnoredFiles: stateValues.showRooIgnoredFiles ?? true, maxReadFileLine: stateValues.maxReadFileLine ?? 500, + historyPreviewCollapsed: stateValues.historyPreviewCollapsed ?? false, } } diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index a62c1d94104..a8faaa55bfb 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -952,6 +952,10 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We await updateGlobalState("maxReadFileLine", message.value) await provider.postStateToWebview() break + case "setHistoryPreviewCollapsed": // Add the new case handler + await updateGlobalState("historyPreviewCollapsed", message.bool ?? false) + // No need to call postStateToWebview here as the UI already updated optimistically + break case "toggleApiConfigPin": if (message.text) { const currentPinned = getGlobalState("pinnedApiConfigs") ?? {} diff --git a/src/exports/roo-code.d.ts b/src/exports/roo-code.d.ts index 894b776985c..e909b4ae8d6 100644 --- a/src/exports/roo-code.d.ts +++ b/src/exports/roo-code.d.ts @@ -407,6 +407,7 @@ type GlobalSettings = { } | undefined enhancementApiConfigId?: string | undefined + historyPreviewCollapsed?: boolean | undefined } type ClineMessage = { diff --git a/src/exports/types.ts b/src/exports/types.ts index 4f394c29741..3a6ea228cdf 100644 --- a/src/exports/types.ts +++ b/src/exports/types.ts @@ -410,6 +410,7 @@ type GlobalSettings = { } | undefined enhancementApiConfigId?: string | undefined + historyPreviewCollapsed?: boolean | undefined } export type { GlobalSettings } diff --git a/src/schemas/index.ts b/src/schemas/index.ts index 2dc4d3f6a1e..c5ed17643e0 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -581,6 +581,8 @@ export const globalSettingsSchema = z.object({ customModePrompts: customModePromptsSchema.optional(), customSupportPrompts: customSupportPromptsSchema.optional(), enhancementApiConfigId: z.string().optional(), + + historyPreviewCollapsed: z.boolean().optional() }) export type GlobalSettings = z.infer @@ -658,6 +660,8 @@ const globalSettingsRecord: GlobalSettingsRecord = { customSupportPrompts: undefined, enhancementApiConfigId: undefined, cachedChromeHostUrl: undefined, + + historyPreviewCollapsed: undefined } export const GLOBAL_SETTINGS_KEYS = Object.keys(globalSettingsRecord) as Keys[] diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index b942188345f..e55a26341dd 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -69,6 +69,7 @@ export interface ExtensionMessage { | "fileSearchResults" | "toggleApiConfigPin" | "acceptInput" + | "setHistoryPreviewCollapsed" // Add the new message type text?: string action?: | "chatButtonClicked" @@ -207,6 +208,7 @@ export type ExtensionState = Pick< renderContext: "sidebar" | "editor" settingsImportedAt?: number + historyPreviewCollapsed?: boolean // Add the new state property } export type { ClineMessage, ClineAsk, ClineSay } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 6b5c111f7a6..15ac5ca9c07 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -126,6 +126,7 @@ export interface WebviewMessage { | "maxReadFileLine" | "searchFiles" | "toggleApiConfigPin" + | "setHistoryPreviewCollapsed" text?: string disabled?: boolean askResponse?: ClineAskResponse @@ -152,6 +153,7 @@ export interface WebviewMessage { requestId?: string ids?: string[] hasSystemPromptOverride?: boolean + historyPreviewCollapsed?: boolean } export const checkoutDiffPayloadSchema = z.object({ diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 82bfcb909c3..21a1f0bbd72 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -1,10 +1,11 @@ -import { memo } from "react" +import { memo, useState, useCallback } from "react" import { vscode } from "@/utils/vscode" import { formatLargeNumber, formatDate } from "@/utils/format" import { Button } from "@/components/ui" import { useAppTranslation } from "@src/i18n/TranslationContext" +import { useExtensionState } from "@src/context/ExtensionStateContext" import { CopyButton } from "./CopyButton" import { useTaskSearch } from "./useTaskSearch" @@ -16,17 +17,30 @@ type HistoryPreviewProps = { } const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { const { tasks, showAllWorkspaces } = useTaskSearch() + const { historyPreviewCollapsed } = useExtensionState() // Will add this state later const { t } = useAppTranslation() + // Initialize expanded state based on the persisted setting (default to expanded if undefined) + const [isExpanded, setIsExpanded] = useState( + historyPreviewCollapsed === undefined ? true : !historyPreviewCollapsed, + ) + + const toggleExpanded = useCallback(() => { + const newState = !isExpanded + setIsExpanded(newState) + // Send message to extension to persist the new collapsed state + vscode.postMessage({ type: "setHistoryPreviewCollapsed", bool: !newState }) + }, [isExpanded]) return ( <>
{tasks.length !== 0 && (
-
- +
+ {t("history:recentTasks")}
+ {/* Keep the history button, but maybe it should just show the full view? Or remove it if header is clicked? Let's keep it for now. */} @@ -58,47 +72,58 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { )} - {tasks.slice(0, 3).map((item) => ( -
vscode.postMessage({ type: "showTaskWithId", text: item.id })}> -
-
- - {formatDate(item.ts)} - - -
+ {tasks.length !== 0 && isExpanded && ( + <> + {tasks.slice(0, 3).map((item) => (
- {item.task} -
-
- ↑ {formatLargeNumber(item.tokensIn || 0)} - ↓ {formatLargeNumber(item.tokensOut || 0)} - {!!item.totalCost && ( - - {"$" + item.totalCost?.toFixed(2)} - - )} -
- {showAllWorkspaces && item.workspace && ( -
- - {item.workspace} + key={item.id} + className="bg-vscode-editor-background rounded relative overflow-hidden cursor-pointer border border-vscode-toolbar-hoverBackground/30 hover:border-vscode-toolbar-hoverBackground/60" + onClick={() => vscode.postMessage({ type: "showTaskWithId", text: item.id })}> +
+
+ + {formatDate(item.ts)} + + +
+
+ {item.task} +
+
+ ↑ {formatLargeNumber(item.tokensIn || 0)} + ↓ {formatLargeNumber(item.tokensOut || 0)} + {!!item.totalCost && ( + + {" "} + {"$" + item.totalCost?.toFixed(2)} + + )} +
+ {showAllWorkspaces && item.workspace && ( +
+ + {item.workspace} +
+ )}
- )} +
+ ))} + {/* Add a "View All" link below the preview list when expanded */} +
showHistoryView()}> + {t("history:viewAll")} ({tasks.length})
-
- ))} + + )}
) diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 5c5ef57c194..a7292928fd5 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -13,6 +13,7 @@ import { experimentDefault, ExperimentId } from "@roo/shared/experiments" import { TelemetrySetting } from "@roo/shared/TelemetrySetting" export interface ExtensionStateContextType extends ExtensionState { + historyPreviewCollapsed?: boolean // Add the new state property didHydrateState: boolean showWelcome: boolean theme: any @@ -89,6 +90,7 @@ export interface ExtensionStateContextType extends ExtensionState { togglePinnedApiConfig: (configName: string) => void terminalCompressProgressBar?: boolean setTerminalCompressProgressBar: (value: boolean) => void + setHistoryPreviewCollapsed: (value: boolean) => void } export const ExtensionStateContext = createContext(undefined) @@ -166,6 +168,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode terminalZshP10k: false, // Default Powerlevel10k integration setting terminalZdotdir: false, // Default ZDOTDIR handling setting terminalCompressProgressBar: true, // Default to compress progress bar output + historyPreviewCollapsed: false, // Initialize the new state (default to expanded) }) const [didHydrateState, setDidHydrateState] = useState(false) @@ -336,6 +339,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode return { ...prevState, pinnedApiConfigs: newPinned } }), + setHistoryPreviewCollapsed: (value) => + setState((prevState) => ({ ...prevState, historyPreviewCollapsed: value })), // Implement the setter } return {children} From a588dc957b0d0fb2e372c0c4dc988cd40f40aa34 Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 11:04:02 -0400 Subject: [PATCH 03/15] Add persistence, locales. --- src/core/config/ContextProxy.ts | 14 ++++++++++++++ src/core/webview/ClineProvider.ts | 2 ++ src/schemas/index.ts | 6 ++---- webview-ui/src/i18n/locales/ca/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/de/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/en/chat.json | 14 ++++++++++++++ webview-ui/src/i18n/locales/es/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/fr/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/hi/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/it/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/ja/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/ko/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/pl/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/pt-BR/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/tr/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/vi/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/zh-CN/chat.json | 16 +++++++++++++++- webview-ui/src/i18n/locales/zh-TW/chat.json | 16 +++++++++++++++- 18 files changed, 242 insertions(+), 18 deletions(-) diff --git a/src/core/config/ContextProxy.ts b/src/core/config/ContextProxy.ts index aa40477ad81..6148dbf91d5 100644 --- a/src/core/config/ContextProxy.ts +++ b/src/core/config/ContextProxy.ts @@ -53,12 +53,26 @@ export class ContextProxy { public async initialize() { for (const key of GLOBAL_STATE_KEYS) { try { + // Revert to original assignment this.stateCache[key] = this.originalContext.globalState.get(key) } catch (error) { logger.error(`Error loading global ${key}: ${error instanceof Error ? error.message : String(error)}`) } } + // Explicitly load historyPreviewCollapsed after the main loop + try { + const historyCollapsedValue = this.originalContext.globalState.get("historyPreviewCollapsed") + if (typeof historyCollapsedValue === "boolean") { + this.stateCache.historyPreviewCollapsed = historyCollapsedValue + } + // No logging needed here anymore + } catch (error) { + logger.error( + `Error loading global historyPreviewCollapsed: ${error instanceof Error ? error.message : String(error)}`, + ) + } + const promises = SECRET_STATE_KEYS.map(async (key) => { try { this.secretCache[key] = await this.originalContext.secrets.get(key) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 81958c8564f..fcc499b1821 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1247,6 +1247,8 @@ export class ClineProvider extends EventEmitter implements historyPreviewCollapsed } = await this.getState() + this.log(`[Debug] getState historyPreviewCollapsed: ${historyPreviewCollapsed}`) // Add logging here + const telemetryKey = process.env.POSTHOG_API_KEY const machineId = vscode.env.machineId const allowedCommands = vscode.workspace.getConfiguration("roo-cline").get("allowedCommands") || [] diff --git a/src/schemas/index.ts b/src/schemas/index.ts index c5ed17643e0..b0946aca0f3 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -581,8 +581,7 @@ export const globalSettingsSchema = z.object({ customModePrompts: customModePromptsSchema.optional(), customSupportPrompts: customSupportPromptsSchema.optional(), enhancementApiConfigId: z.string().optional(), - - historyPreviewCollapsed: z.boolean().optional() + historyPreviewCollapsed: z.boolean().optional(), }) export type GlobalSettings = z.infer @@ -660,8 +659,7 @@ const globalSettingsRecord: GlobalSettingsRecord = { customSupportPrompts: undefined, enhancementApiConfigId: undefined, cachedChromeHostUrl: undefined, - - historyPreviewCollapsed: undefined + historyPreviewCollapsed: undefined, } export const GLOBAL_SETTINGS_KEYS = Object.keys(globalSettingsRecord) as Keys[] diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 40c4d4ca418..8b0ed2f1ee1 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -65,9 +65,23 @@ "tooltip": "Cancel·la l'operació actual" }, "scrollToBottom": "Desplaça't al final del xat", + "about": "Genera, refactoritza i depura codi amb l'ajuda de la IA.
Consulta la nostra documentació per obtenir més informació.", "onboarding": " La vostra llista de tasques en aquest espai de treball està buida. Comença escrivint una tasca a continuació. \nNo esteu segur per on començar? \nMés informació sobre què pot fer Roo als documents.", + "rooTips": { + "boomerangTasks": { + "title": "Tasques Boomerang", + "description": "Divideix les tasques en parts més petites i manejables." + }, + "stickyModels": { + "title": "Models persistents", + "description": "Cada mode recorda el teu últim model utilitzat" + }, + "tools": { + "title": "Eines", + "description": "Permet que la IA resolgui problemes navegant per la web, executant ordres i molt més." + } + }, "selectMode": "Selecciona el mode d'interacció", - "selectApiConfig": "Selecciona la configuració de l'API", "enhancePrompt": "Millora la sol·licitud amb context addicional", "addImages": "Afegeix imatges al missatge", "sendMessage": "Envia el missatge", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index dccc2bab1ed..74b78689c0b 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -65,9 +65,23 @@ "tooltip": "Aktuelle Operation abbrechen" }, "scrollToBottom": "Zum Chat-Ende scrollen", + "about": "Generiere, überarbeite und debugge Code mit KI-Unterstützung.
Weitere Informationen findest du in unserer Dokumentation.", "onboarding": "Deine Aufgabenliste in diesem Arbeitsbereich ist leer. Beginne mit der Eingabe einer Aufgabe unten. Du bist dir nicht sicher, wie du anfangen sollst? Lies mehr darüber, was Roo für dich tun kann, in den Dokumenten.", + "rooTips": { + "boomerangTasks": { + "title": "Bumerang-Aufgaben", + "description": "Teile Aufgaben in kleinere, überschaubare Teile auf." + }, + "stickyModels": { + "title": "Sticky Models", + "description": "Jeder Modus merkt sich dein zuletzt verwendetes Modell" + }, + "tools": { + "title": "Tools", + "description": "Erlaube der KI, Probleme durch Surfen im Web, Ausführen von Befehlen und mehr zu lösen." + } + }, "selectMode": "Interaktionsmodus auswählen", - "selectApiConfig": "API-Konfiguration auswählen", "enhancePrompt": "Prompt mit zusätzlichem Kontext verbessern", "addImages": "Bilder zur Nachricht hinzufügen", "sendMessage": "Nachricht senden", diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 75ea986d541..499e8a77c6b 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -67,6 +67,20 @@ "scrollToBottom": "Scroll to bottom of chat", "about": "Generate, refactor, and debug code with AI assistance.
Check out our documentation to learn more.", "onboarding": "Your task list in this workspace is empty.", + "rooTips": { + "boomerangTasks": { + "title": "Boomerang Tasks", + "description": "Split tasks into smaller, manageable parts." + }, + "stickyModels": { + "title": "Sticky Models", + "description": "Each mode remembers your last used model" + }, + "tools": { + "title": "Tools", + "description": "Allow the AI to solve problems by browsing the web, running commands, and more." + } + }, "selectMode": "Select mode for interaction", "selectApiConfig": "Select API configuration", "enhancePrompt": "Enhance prompt with additional context", diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index e89587493e6..5b7f0ff44f9 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -65,9 +65,23 @@ "tooltip": "Cancelar la operación actual" }, "scrollToBottom": "Desplazarse al final del chat", + "about": "Genera, refactoriza y depura código con asistencia de IA.
Consulta nuestra documentación para obtener más información.", "onboarding": "Tu lista de tareas en este espacio de trabajo está vacía. Comienza escribiendo una tarea abajo. ¿No estás seguro cómo empezar? Lee más sobre lo que Roo puede hacer por ti en la documentación.", + "rooTips": { + "boomerangTasks": { + "title": "Tareas Boomerang", + "description": "Divide las tareas en partes más pequeñas y manejables." + }, + "stickyModels": { + "title": "Modelos persistentes", + "description": "Cada modo recuerda tu último modelo utilizado" + }, + "tools": { + "title": "Herramientas", + "description": "Permite que la IA resuelva problemas navegando por la web, ejecutando comandos y mucho más." + } + }, "selectMode": "Seleccionar modo de interacción", - "selectApiConfig": "Seleccionar configuración de API", "enhancePrompt": "Mejorar el mensaje con contexto adicional", "addImages": "Agregar imágenes al mensaje", "sendMessage": "Enviar mensaje", diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 51375d11504..cc51bc0cdfc 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -65,9 +65,23 @@ "tooltip": "Annuler l'opération actuelle" }, "scrollToBottom": "Défiler jusqu'au bas du chat", + "about": "Générer, refactoriser et déboguer du code avec l'assistance de l'IA.
Consultez notre documentation pour en savoir plus.", "onboarding": "Grâce aux dernières avancées en matière de capacités de codage agent, je peux gérer des tâches complexes de développement logiciel étape par étape. Avec des outils qui me permettent de créer et d'éditer des fichiers, d'explorer des projets complexes, d'utiliser le navigateur et d'exécuter des commandes de terminal (après votre autorisation), je peux vous aider de manières qui vont au-delà de la complétion de code ou du support technique. Je peux même utiliser MCP pour créer de nouveaux outils et étendre mes propres capacités.", + "rooTips": { + "boomerangTasks": { + "title": "Tâches Boomerang", + "description": "Divisez les tâches en parties plus petites et gérables." + }, + "stickyModels": { + "title": "Modèles persistants", + "description": "Chaque mode se souvient de votre dernier modèle utilisé" + }, + "tools": { + "title": "Outils", + "description": "Permettez à l'IA de résoudre des problèmes en naviguant sur le Web, en exécutant des commandes, et plus encore." + } + }, "selectMode": "Sélectionner le mode d'interaction", - "selectApiConfig": "Sélectionner la configuration API", "enhancePrompt": "Améliorer la requête avec un contexte supplémentaire", "addImages": "Ajouter des images au message", "sendMessage": "Envoyer le message", diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index e92eba0162b..d6f5b225876 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -65,9 +65,23 @@ "tooltip": "वर्तमान ऑपरेशन रद्द करें" }, "scrollToBottom": "चैट के निचले हिस्से तक स्क्रॉल करें", + "about": "एआई सहायता से कोड जेनरेट करें, रिफैक्टर करें और डिबग करें। अधिक जानने के लिए हमारे दस्तावेज़ देखें।", "onboarding": "एजेंटिक कोडिंग क्षमताओं में नवीनतम प्रगति के कारण, मैं जटिल सॉफ्टवेयर विकास कार्यों को चरण-दर-चरण संभाल सकता हूं। ऐसे उपकरणों के साथ जो मुझे फ़ाइलें बनाने और संपादित करने, जटिल प्रोजेक्ट का अन्वेषण करने, ब्राउज़र का उपयोग करने और टर्मिनल कमांड (आपकी अनुमति के बाद) निष्पादित करने की अनुमति देते हैं, मैं आपकी मदद कोड पूर्णता या तकनीकी समर्थन से परे तरीकों से कर सकता हूं। मैं अपनी क्षमताओं का विस्तार करने और नए उपकरण बनाने के लिए MCP का भी उपयोग कर सकता हूं।", + "rooTips": { + "boomerangTasks": { + "title": "बूमरैंग कार्य", + "description": "कार्यों को छोटे, प्रबंधनीय भागों में विभाजित करें।" + }, + "stickyModels": { + "title": "चिपचिपे मॉडल", + "description": "प्रत्येक मोड आपके अंतिम उपयोग किए गए मॉडल को याद रखता है" + }, + "tools": { + "title": "उपकरण", + "description": "एआई को वेब ब्राउज़ करके, कमांड चलाकर और अधिक समस्याओं को हल करने की अनुमति दें।" + } + }, "selectMode": "इंटरैक्शन मोड चुनें", - "selectApiConfig": "API कॉन्फ़िगरेशन चुनें", "enhancePrompt": "अतिरिक्त संदर्भ के साथ प्रॉम्प्ट बढ़ाएँ", "addImages": "संदेश में चित्र जोड़ें", "sendMessage": "संदेश भेजें", diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index d613d0e01b8..eed9bc9883c 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -65,9 +65,23 @@ "tooltip": "Annulla l'operazione corrente" }, "scrollToBottom": "Scorri fino alla fine della chat", + "about": "Genera, refactor e debug del codice con l'assistenza dell'IA.
Consulta la nostra documentazione per saperne di più.", "onboarding": "Grazie alle più recenti innovazioni nelle capacità di codifica agentica, posso gestire complesse attività di sviluppo software passo dopo passo. Con strumenti che mi permettono di creare e modificare file, esplorare progetti complessi, utilizzare il browser ed eseguire comandi da terminale (dopo la tua autorizzazione), posso aiutarti in modi che vanno oltre il completamento del codice o il supporto tecnico. Posso persino usare MCP per creare nuovi strumenti ed estendere le mie capacità.", + "rooTips": { + "boomerangTasks": { + "title": "Attività Boomerang", + "description": "Dividi le attività in parti più piccole e gestibili." + }, + "stickyModels": { + "title": "Modelli persistenti", + "description": "Ogni modalità ricorda il tuo ultimo modello utilizzato" + }, + "tools": { + "title": "Strumenti", + "description": "Consenti all'IA di risolvere i problemi navigando sul Web, eseguendo comandi e altro ancora." + } + }, "selectMode": "Seleziona modalità di interazione", - "selectApiConfig": "Seleziona configurazione API", "enhancePrompt": "Migliora prompt con contesto aggiuntivo", "addImages": "Aggiungi immagini al messaggio", "sendMessage": "Invia messaggio", diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index a3fefb79b69..32822c4c99b 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -65,9 +65,23 @@ "tooltip": "現在の操作をキャンセル" }, "scrollToBottom": "チャットの最下部にスクロール", + "about": "AI支援でコードを生成、リファクタリング、デバッグします。詳細については、ドキュメントをご覧ください。", "onboarding": "最新のエージェント型コーディング能力の進歩により、複雑なソフトウェア開発タスクをステップバイステップで処理できます。ファイルの作成や編集、複雑なプロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(許可後)を可能にするツールにより、コード補完や技術サポート以上の方法であなたをサポートできます。MCPを使用して新しいツールを作成し、自分の能力を拡張することもできます。", + "rooTips": { + "boomerangTasks": { + "title": "ブーメランタスク", + "description": "タスクをより小さく、管理しやすい部分に分割します。" + }, + "stickyModels": { + "title": "スティッキーモデル", + "description": "各モードは、最後に使用したモデルを記憶します" + }, + "tools": { + "title": "ツール", + "description": "AIがWebの閲覧、コマンドの実行などによって問題を解決できるようにします。" + } + }, "selectMode": "対話モードを選択", - "selectApiConfig": "API設定を選択", "enhancePrompt": "追加コンテキストでプロンプトを強化", "addImages": "メッセージに画像を追加", "sendMessage": "メッセージを送信", diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index c2a3db6f666..3c819b02235 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -65,9 +65,23 @@ "tooltip": "현재 작업 취소" }, "scrollToBottom": "채팅 하단으로 스크롤", + "about": "AI 지원으로 코드를 생성, 리팩터링 및 디버깅합니다. 자세한 내용은 문서를 확인하세요.", "onboarding": "이 작업 공간의 작업 목록이 비어 있습니다. 아래에 작업을 입력하여 시작하세요. 어떻게 시작해야 할지 모르겠나요? Roo가 무엇을 할 수 있는지 문서에서 자세히 알아보세요.", + "rooTips": { + "boomerangTasks": { + "title": "부메랑 작업", + "description": "작업을 더 작고 관리하기 쉬운 부분으로 나눕니다." + }, + "stickyModels": { + "title": "고정 모델", + "description": "각 모드는 마지막으로 사용한 모델을 기억합니다." + }, + "tools": { + "title": "도구", + "description": "AI가 웹 탐색, 명령 실행 등으로 문제를 해결하도록 허용합니다." + } + }, "selectMode": "상호작용 모드 선택", - "selectApiConfig": "API 구성 선택", "enhancePrompt": "추가 컨텍스트로 프롬프트 향상", "addImages": "메시지에 이미지 추가", "sendMessage": "메시지 보내기", diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index 4008195a4f1..f9911686b37 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -65,9 +65,23 @@ "tooltip": "Anuluj bieżącą operację" }, "scrollToBottom": "Przewiń do dołu czatu", + "about": "Generuj, refaktoryzuj i debuguj kod z pomocą sztucznej inteligencji.
Sprawdź naszą dokumentację, aby dowiedzieć się więcej.", "onboarding": "Twoja lista zadań w tym obszarze roboczym jest pusta. Zacznij od wpisania zadania poniżej. Nie wiesz, jak zacząć? Przeczytaj więcej o tym, co Roo może dla Ciebie zrobić w dokumentacji.", + "rooTips": { + "boomerangTasks": { + "title": "Zadania bumerangowe", + "description": "Podziel zadania na mniejsze, łatwiejsze do zarządzania części." + }, + "stickyModels": { + "title": "Modele przyklejone", + "description": "Każdy tryb zapamiętuje ostatnio używany model" + }, + "tools": { + "title": "Narzędzia", + "description": "Pozwól sztucznej inteligencji rozwiązywać problemy, przeglądając sieć, uruchamiając polecenia i nie tylko." + } + }, "selectMode": "Wybierz tryb interakcji", - "selectApiConfig": "Wybierz konfigurację API", "enhancePrompt": "Ulepsz podpowiedź dodatkowym kontekstem", "addImages": "Dodaj obrazy do wiadomości", "sendMessage": "Wyślij wiadomość", diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index fbfa3852983..56ef986ce3a 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -65,9 +65,23 @@ "tooltip": "Cancelar a operação atual" }, "scrollToBottom": "Rolar para o final do chat", + "about": "Gere, refatore e depure código com assistência de IA.
Confira nossa documentação para saber mais.", "onboarding": "Sua lista de tarefas neste espaço de trabalho está vazia. Comece digitando uma tarefa abaixo. Não sabe como começar? Leia mais sobre o que o Roo pode fazer por você nos documentos.", + "rooTips": { + "boomerangTasks": { + "title": "Tarefas Bumerangue", + "description": "Divida as tarefas em partes menores e gerenciáveis." + }, + "stickyModels": { + "title": "Modelos Persistentes", + "description": "Cada modo lembra seu último modelo usado" + }, + "tools": { + "title": "Ferramentas", + "description": "Permita que a IA resolva problemas navegando na web, executando comandos e muito mais." + } + }, "selectMode": "Selecionar modo de interação", - "selectApiConfig": "Selecionar configuração de API", "enhancePrompt": "Aprimorar prompt com contexto adicional", "addImages": "Adicionar imagens à mensagem", "sendMessage": "Enviar mensagem", diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 7fa48ccb736..6bd8ce50aef 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -65,9 +65,23 @@ "tooltip": "Mevcut işlemi iptal et" }, "scrollToBottom": "Sohbetin altına kaydır", + "about": "AI yardımıyla kod oluşturun, yeniden düzenleyin ve hatalarını ayıklayın.
Daha fazla bilgi edinmek için belgelerimize göz atın.", "onboarding": "Bu çalışma alanındaki görev listeniz boş. Aşağıya bir görev yazarak başlayın. Nasıl başlayacağınızdan emin değil misiniz? Roo'nun sizin için neler yapabileceği hakkında daha fazla bilgiyi belgelerde okuyun.", + "rooTips": { + "boomerangTasks": { + "title": "Bumerang Görevleri", + "description": "Görevleri daha küçük, yönetilebilir parçalara ayırın." + }, + "stickyModels": { + "title": "Yapışkan Modeller", + "description": "Her mod en son kullandığınız modeli hatırlar" + }, + "tools": { + "title": "Araçlar", + "description": "AI'nın web'e göz atarak, komutlar çalıştırarak ve daha fazlasını yaparak sorunları çözmesine izin verin." + } + }, "selectMode": "Etkileşim modunu seçin", - "selectApiConfig": "API yapılandırmasını seçin", "enhancePrompt": "Ek bağlamla istemi geliştir", "addImages": "Mesaja resim ekle", "sendMessage": "Mesaj gönder", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index f2cd321820c..e6fb683d529 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -65,9 +65,23 @@ "tooltip": "Hủy thao tác hiện tại" }, "scrollToBottom": "Cuộn xuống cuối cuộc trò chuyện", + "about": "Tạo, tái cấu trúc và gỡ lỗi mã bằng sự hỗ trợ của AI.
Kiểm tra tài liệu của chúng tôi để tìm hiểu thêm.", "onboarding": "Danh sách nhiệm vụ của bạn trong không gian làm việc này trống. Bắt đầu bằng cách nhập nhiệm vụ bên dưới. Bạn không chắc chắn nên bắt đầu như thế nào? Đọc thêm về những gì Roo có thể làm cho bạn trong tài liệu.", + "rooTips": { + "boomerangTasks": { + "title": "Nhiệm vụ Boomerang", + "description": "Chia nhỏ các nhiệm vụ thành các phần nhỏ hơn, dễ quản lý hơn." + }, + "stickyModels": { + "title": "Mô hình dính", + "description": "Mỗi chế độ ghi nhớ mô hình bạn đã sử dụng gần đây nhất" + }, + "tools": { + "title": "Công cụ", + "description": "Cho phép AI giải quyết vấn đề bằng cách duyệt web, chạy lệnh, v.v." + } + }, "selectMode": "Chọn chế độ tương tác", - "selectApiConfig": "Chọn cấu hình API", "enhancePrompt": "Nâng cao yêu cầu với ngữ cảnh bổ sung", "addImages": "Thêm hình ảnh vào tin nhắn", "sendMessage": "Gửi tin nhắn", diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index 4fa48d6999d..1c6e1a3e8c2 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -65,9 +65,23 @@ "tooltip": "取消当前操作" }, "scrollToBottom": "滚动到聊天底部", + "about": "通过 AI 辅助生成、重构和调试代码。
查看我们的 文档 了解更多信息。", "onboarding": "此工作区中的任务列表为空。 请在下方输入任务开始。 不确定如何开始? 在 文档 中阅读更多关于 Roo 可以为您做什么的信息。", + "rooTips": { + "boomerangTasks": { + "title": "任务拆分", + "description": "将任务拆分为更小、更易于管理的部分。" + }, + "stickyModels": { + "title": "增强导向模式", + "description": "每个模式都会记住您上次使用的模型" + }, + "tools": { + "title": "工具", + "description": "允许 AI 通过浏览网络、运行命令等方式解决问题。" + } + }, "selectMode": "选择交互模式", - "selectApiConfig": "选择API配置", "enhancePrompt": "增强提示词", "addImages": "添加图片到消息", "sendMessage": "发送消息", diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 177fa893d70..47c264a5f62 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -65,9 +65,23 @@ "tooltip": "取消目前操作" }, "scrollToBottom": "捲動至對話框底部", + "about": "透過 AI 輔助產生、重構和偵錯程式碼。
查看我們的 說明文件 以瞭解更多資訊。", "onboarding": "您在此工作區中的工作清單是空的。 請在下方輸入工作以開始。 不確定如何開始? 在 說明文件 中閱讀更多關於 Roo 能為您做什麼的資訊。", + "rooTips": { + "boomerangTasks": { + "title": "任務拆分", + "description": "將任務拆分為更小、更易於管理的部分。" + }, + "stickyModels": { + "title": "增強導向模式", + "description": "每個模式都會記住您上次使用的模型" + }, + "tools": { + "title": "工具", + "description": "允許 AI 透過瀏覽網路、執行命令等方式解決問題。" + } + }, "selectMode": "選擇互動模式", - "selectApiConfig": "選擇 API 設定", "enhancePrompt": "使用額外內容增強提示", "addImages": "新增圖片到訊息中", "sendMessage": "傳送訊息", From b029ff68e432793c7189ec4c29f73eb1919df6ce Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 11:29:29 -0400 Subject: [PATCH 04/15] Top layout, expanded tips. --- webview-ui/src/components/chat/ChatView.tsx | 65 +++++++++---------- .../src/components/history/HistoryPreview.tsx | 13 ++-- webview-ui/src/components/welcome/RooHero.tsx | 7 +- .../src/components/welcome/WelcomeView.tsx | 1 + 4 files changed, 41 insertions(+), 45 deletions(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 28cb97d2c31..ec0d83ccdc2 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -38,8 +38,6 @@ import ChatTextArea from "./ChatTextArea" import TaskHeader from "./TaskHeader" import AutoApproveMenu from "./AutoApproveMenu" import SystemPromptWarning from "./SystemPromptWarning" - -import { useTaskSearch } from "@/components/history/useTaskSearch" interface ChatViewProps { isHidden: boolean showAnnouncement: boolean @@ -86,8 +84,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined const task = useMemo(() => messages.at(0), [messages]) // leaving this less safe version here since if the first message is not a task, then the extension is in a bad state and needs to be debugged (see Cline.abort) const modifiedMessages = useMemo(() => combineApiRequests(combineCommandSequences(messages.slice(1))), [messages]) @@ -1231,36 +1227,39 @@ const ChatViewComponent: React.ForwardRefRenderFunction ) : ( -
- {telemetrySetting === "unset" && } - {showAnnouncement && } - - {/* Always show the hero. */} - - {/* If the user has no task history, we can show the onboarding message */} - {!taskHistory.length && ( -

- - the docs - - ), - }} - /> -

- )} - - {/* Show the task history if there are any for this workspace. */} + <> {taskHistory.length > 0 && } - {/* Finally, if there less than 3 tasks, we can show the tips */} - {tasks.length < 3 && 0)} />} -
+
+ {/* Show the task history if there are any for this workspace. */} + + {telemetrySetting === "unset" && } + {showAnnouncement && } + + {/* Always show the hero. */} + + {/* If the user has little task history, we can show the onboarding message */} + {taskHistory.length < 10 && ( +

+ + the docs + + ), + }} + /> +

+ )} + + {/* Finally, always show the tips */} + +
+ )} {/* diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 21a1f0bbd72..56f41a17668 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -36,14 +36,15 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => {
{tasks.length !== 0 && (
+ {/* Keep the history button, but maybe it should just show the full view? Or remove it if header is clicked? Let's keep it for now. */} +
{t("chat:greeting")}
+
- - {t("history:recentTasks")} + + + {isExpanded ? "" : t("history:recentTasks")} +
- {/* Keep the history button, but maybe it should just show the full view? Or remove it if header is clicked? Let's keep it for now. */} -
)} diff --git a/webview-ui/src/components/welcome/RooHero.tsx b/webview-ui/src/components/welcome/RooHero.tsx index bc99dbd004d..8a2e01cec45 100644 --- a/webview-ui/src/components/welcome/RooHero.tsx +++ b/webview-ui/src/components/welcome/RooHero.tsx @@ -1,16 +1,13 @@ import { useState } from "react" -import { useAppTranslation } from "../../i18n/TranslationContext" const RooHero = () => { - const { t } = useAppTranslation() - const [imagesBaseUri] = useState(() => { const w = window as any return w.IMAGES_BASE_URI || "" }) return ( -
+
{ className="mx-auto"> Roo logo
- -

{t("chat:greeting")}

) } diff --git a/webview-ui/src/components/welcome/WelcomeView.tsx b/webview-ui/src/components/welcome/WelcomeView.tsx index 07871496a43..e919f5bf4b5 100644 --- a/webview-ui/src/components/welcome/WelcomeView.tsx +++ b/webview-ui/src/components/welcome/WelcomeView.tsx @@ -38,6 +38,7 @@ const WelcomeView = () => { +

{t("chat:greeting")}

From 06f8497086bca035da210f5ecb2ca64ae49ebe80 Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 11:37:14 -0400 Subject: [PATCH 05/15] Minimal 'tasks' language. --- webview-ui/src/components/history/HistoryPreview.tsx | 4 ++-- webview-ui/src/i18n/locales/ca/history.json | 2 +- webview-ui/src/i18n/locales/de/history.json | 2 +- webview-ui/src/i18n/locales/en/history.json | 2 +- webview-ui/src/i18n/locales/es/history.json | 2 +- webview-ui/src/i18n/locales/fr/history.json | 2 +- webview-ui/src/i18n/locales/hi/history.json | 2 +- webview-ui/src/i18n/locales/it/history.json | 2 +- webview-ui/src/i18n/locales/ko/history.json | 2 +- webview-ui/src/i18n/locales/pl/history.json | 2 +- webview-ui/src/i18n/locales/pt-BR/history.json | 2 +- webview-ui/src/i18n/locales/tr/history.json | 2 +- webview-ui/src/i18n/locales/vi/history.json | 2 +- webview-ui/src/i18n/locales/zh-CN/history.json | 2 +- webview-ui/src/i18n/locales/zh-TW/history.json | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 56f41a17668..9c4a0e5e9b4 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -35,15 +35,15 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { <>
{tasks.length !== 0 && ( -
+
{/* Keep the history button, but maybe it should just show the full view? Or remove it if header is clicked? Let's keep it for now. */}
{t("chat:greeting")}
- {isExpanded ? "" : t("history:recentTasks")} +
)} diff --git a/webview-ui/src/i18n/locales/ca/history.json b/webview-ui/src/i18n/locales/ca/history.json index 6bf40b3d838..9efa263823d 100644 --- a/webview-ui/src/i18n/locales/ca/history.json +++ b/webview-ui/src/i18n/locales/ca/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Tasques recents", + "recentTasks": "Tasques", "viewAll": "Veure tot", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Cau: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/de/history.json b/webview-ui/src/i18n/locales/de/history.json index f85243c886f..247d09a8924 100644 --- a/webview-ui/src/i18n/locales/de/history.json +++ b/webview-ui/src/i18n/locales/de/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Jüngste Aufgaben", + "recentTasks": "Aufgaben", "viewAll": "Alle anzeigen", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Cache: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/en/history.json b/webview-ui/src/i18n/locales/en/history.json index 5e785fd5444..19d481fe4b7 100644 --- a/webview-ui/src/i18n/locales/en/history.json +++ b/webview-ui/src/i18n/locales/en/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Recent Tasks", + "recentTasks": "Tasks", "viewAll": "View All Tasks", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Cache: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/es/history.json b/webview-ui/src/i18n/locales/es/history.json index 7a0d93ce8d9..d7c65ef6b15 100644 --- a/webview-ui/src/i18n/locales/es/history.json +++ b/webview-ui/src/i18n/locales/es/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Tareas recientes", + "recentTasks": "Tareas", "viewAll": "Ver todas", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Caché: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/fr/history.json b/webview-ui/src/i18n/locales/fr/history.json index 76b1f8cc3fb..4e33048753a 100644 --- a/webview-ui/src/i18n/locales/fr/history.json +++ b/webview-ui/src/i18n/locales/fr/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Tâches récentes", + "recentTasks": "Tâches", "viewAll": "Voir tout", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Cache: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/hi/history.json b/webview-ui/src/i18n/locales/hi/history.json index dcadfbe5e4c..58373f95261 100644 --- a/webview-ui/src/i18n/locales/hi/history.json +++ b/webview-ui/src/i18n/locales/hi/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "हाल के कार्य", + "recentTasks": "कार्य", "viewAll": "सभी देखें", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "कैश: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/it/history.json b/webview-ui/src/i18n/locales/it/history.json index 9f0dc2ce757..c56f8492d3d 100644 --- a/webview-ui/src/i18n/locales/it/history.json +++ b/webview-ui/src/i18n/locales/it/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Compiti recenti", + "recentTasks": "Compiti", "viewAll": "Vedi tutto", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Cache: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/ko/history.json b/webview-ui/src/i18n/locales/ko/history.json index dd5042540ad..a35cc9b1f13 100644 --- a/webview-ui/src/i18n/locales/ko/history.json +++ b/webview-ui/src/i18n/locales/ko/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "최근 작업", + "recentTasks": "작업", "viewAll": "모두 보기", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "캐시: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/pl/history.json b/webview-ui/src/i18n/locales/pl/history.json index d66c4b349ab..f775b04de35 100644 --- a/webview-ui/src/i18n/locales/pl/history.json +++ b/webview-ui/src/i18n/locales/pl/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Ostatnie zadania", + "recentTasks": "Zadania", "viewAll": "Zobacz wszystkie", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Pamięć podręczna: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/pt-BR/history.json b/webview-ui/src/i18n/locales/pt-BR/history.json index 2c25fe6e59d..58fdb7e6ed9 100644 --- a/webview-ui/src/i18n/locales/pt-BR/history.json +++ b/webview-ui/src/i18n/locales/pt-BR/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Tarefas recentes", + "recentTasks": "Tarefas", "viewAll": "Ver todas", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Cache: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/tr/history.json b/webview-ui/src/i18n/locales/tr/history.json index a29107ef76d..672659b90d2 100644 --- a/webview-ui/src/i18n/locales/tr/history.json +++ b/webview-ui/src/i18n/locales/tr/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Son Görevler", + "recentTasks": "Görevler", "viewAll": "Tümünü Gör", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "Önbellek: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/vi/history.json b/webview-ui/src/i18n/locales/vi/history.json index 3d3565c2e88..00154d47c3a 100644 --- a/webview-ui/src/i18n/locales/vi/history.json +++ b/webview-ui/src/i18n/locales/vi/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "Nhiệm vụ gần đây", + "recentTasks": "Nhiệm vụ", "viewAll": "Xem tất cả", "tokens": "Token: ↑{{in}} ↓{{out}}", "cache": "Bộ nhớ đệm: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/zh-CN/history.json b/webview-ui/src/i18n/locales/zh-CN/history.json index 68cffd73892..43c362aaa14 100644 --- a/webview-ui/src/i18n/locales/zh-CN/history.json +++ b/webview-ui/src/i18n/locales/zh-CN/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "最近任务", + "recentTasks": "任务", "viewAll": "查看全部", "tokens": "Token用量: ↑{{in}} ↓{{out}}", "cache": "缓存操作: +{{writes}} → {{reads}}", diff --git a/webview-ui/src/i18n/locales/zh-TW/history.json b/webview-ui/src/i18n/locales/zh-TW/history.json index f3a009022c8..d234ef6b3dd 100644 --- a/webview-ui/src/i18n/locales/zh-TW/history.json +++ b/webview-ui/src/i18n/locales/zh-TW/history.json @@ -1,5 +1,5 @@ { - "recentTasks": "最近的工作", + "recentTasks": "工作", "viewAll": "檢視全部", "tokens": "Tokens: ↑{{in}} ↓{{out}}", "cache": "快取:+{{writes}} → {{reads}}", From 5070acff47618b9b3fe711636c147a6790a4c296 Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 15:17:37 -0400 Subject: [PATCH 06/15] Adjust announcement positioning/dimensions. --- .../src/components/chat/Announcement.tsx | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 9bbee7b5846..27ceec92997 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -42,7 +42,7 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { ) return ( -
+
{

{t("chat:announcement.description")}

-

{t("chat:announcement.whatsNew")}

-
    -
  • - •{" "} - , - }} - /> -
  • -
  • - •{" "} - , - }} - /> -
  • -
  • - •{" "} - , - }} - /> -
  • -
+

{t("chat:announcement.whatsNew")}

+
    +
  • + •{" "} + , + }} + /> +
  • +
  • + •{" "} + , + }} + /> +
  • +
  • + •{" "} + , + }} + /> +
  • +

Date: Fri, 25 Apr 2025 15:58:15 -0400 Subject: [PATCH 07/15] Fix tests, defaults. --- src/core/config/ContextProxy.ts | 13 ---- src/shared/ExtensionMessage.ts | 4 +- webview-ui/src/components/welcome/RooTips.tsx | 2 +- .../welcome/__tests__/RooTips.test.tsx | 61 +++++-------------- 4 files changed, 19 insertions(+), 61 deletions(-) diff --git a/src/core/config/ContextProxy.ts b/src/core/config/ContextProxy.ts index 6148dbf91d5..a16d48d717c 100644 --- a/src/core/config/ContextProxy.ts +++ b/src/core/config/ContextProxy.ts @@ -60,19 +60,6 @@ export class ContextProxy { } } - // Explicitly load historyPreviewCollapsed after the main loop - try { - const historyCollapsedValue = this.originalContext.globalState.get("historyPreviewCollapsed") - if (typeof historyCollapsedValue === "boolean") { - this.stateCache.historyPreviewCollapsed = historyCollapsedValue - } - // No logging needed here anymore - } catch (error) { - logger.error( - `Error loading global historyPreviewCollapsed: ${error instanceof Error ? error.message : String(error)}`, - ) - } - const promises = SECRET_STATE_KEYS.map(async (key) => { try { this.secretCache[key] = await this.originalContext.secrets.get(key) diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index e55a26341dd..a4659e2f98f 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -69,7 +69,7 @@ export interface ExtensionMessage { | "fileSearchResults" | "toggleApiConfigPin" | "acceptInput" - | "setHistoryPreviewCollapsed" // Add the new message type + | "setHistoryPreviewCollapsed" text?: string action?: | "chatButtonClicked" @@ -208,7 +208,7 @@ export type ExtensionState = Pick< renderContext: "sidebar" | "editor" settingsImportedAt?: number - historyPreviewCollapsed?: boolean // Add the new state property + historyPreviewCollapsed?: boolean } export type { ClineMessage, ClineAsk, ClineSay } diff --git a/webview-ui/src/components/welcome/RooTips.tsx b/webview-ui/src/components/welcome/RooTips.tsx index 597449bb4a0..db56d57b0c5 100644 --- a/webview-ui/src/components/welcome/RooTips.tsx +++ b/webview-ui/src/components/welcome/RooTips.tsx @@ -28,7 +28,7 @@ interface RooTipsProps { cycle?: boolean } -const RooTips = ({ cycle = true }: RooTipsProps) => { +const RooTips = ({ cycle = false }: RooTipsProps) => { const { t } = useTranslation("chat") const [currentTipIndex, setCurrentTipIndex] = useState(Math.floor(Math.random() * tips.length)) const [isFading, setIsFading] = useState(false) diff --git a/webview-ui/src/components/welcome/__tests__/RooTips.test.tsx b/webview-ui/src/components/welcome/__tests__/RooTips.test.tsx index fdd49db4eb1..ef648803165 100644 --- a/webview-ui/src/components/welcome/__tests__/RooTips.test.tsx +++ b/webview-ui/src/components/welcome/__tests__/RooTips.test.tsx @@ -1,13 +1,13 @@ -import { render, screen, act } from "@testing-library/react" +import React from "react" +import { render, screen } from "@testing-library/react" import RooTips from "../RooTips" -import React from "react" // Import React for JSX types // Mock the translation hook jest.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key: string) => key, // Simple mock that returns the key }), - Trans: ({ children }: { children: React.ReactNode }) => children, + // Mock Trans component if it were used directly, but it's not here })) // Mock VSCodeLink @@ -15,60 +15,31 @@ jest.mock("@vscode/webview-ui-toolkit/react", () => ({ VSCodeLink: ({ href, children }: { href: string; children: React.ReactNode }) => {children}, })) +// Mock clsx if complex class logic needs specific testing (optional) +// jest.mock('clsx'); + describe("RooTips Component", () => { beforeEach(() => { jest.useFakeTimers() + // Reset Math.random mock for consistent starting points if needed + // jest.spyOn(global.Math, 'random').mockReturnValue(0); // Example: always start with the first tip }) afterEach(() => { jest.runOnlyPendingTimers() jest.useRealTimers() + // Restore Math.random if mocked + // jest.spyOn(global.Math, 'random').mockRestore(); }) - test("renders and cycles through tips by default (cycle=true)", () => { - render() - - // Initial render (random tip) - check if one tip is rendered - // We check for the link text pattern as the description is included - expect(screen.getByRole("link", { name: /rooTips\..*\.title/i })).toBeInTheDocument() - expect(screen.getAllByRole("link")).toHaveLength(1) - - // Fast-forward time to trigger the interval + fade timeout - act(() => { - jest.advanceTimersByTime(11000 + 1000) // interval + fade duration + describe("when cycle is false (default)", () => { + beforeEach(() => { + render() }) - // After interval, a different tip should be potentially rendered (still one tip) - // Note: Due to random start, we can't guarantee a *different* tip if there are only 2, - // but the core logic is that it attempts to cycle. We re-check the structure. - expect(screen.getByRole("link", { name: /rooTips\..*\.title/i })).toBeInTheDocument() - expect(screen.getAllByRole("link")).toHaveLength(1) - }) - - test("renders only the top two tips when cycle is false", () => { - render() - - // Check if the first two tips are rendered - expect(screen.getByRole("link", { name: "rooTips.boomerangTasks.title" })).toBeInTheDocument() - expect(screen.getByText("rooTips.boomerangTasks.description")).toBeInTheDocument() - expect(screen.getByRole("link", { name: "rooTips.stickyModels.title" })).toBeInTheDocument() - expect(screen.getByText("rooTips.stickyModels.description")).toBeInTheDocument() - - // Ensure only two tips are present - expect(screen.getAllByRole("link")).toHaveLength(2) - - // Check that the third tip is not rendered - expect(screen.queryByRole("link", { name: "rooTips.tools.title" })).not.toBeInTheDocument() - - // Fast-forward time - nothing should change - act(() => { - jest.advanceTimersByTime(12000) + test("renders only the top two tips", () => { + // Ensure only two tips are present (check by link role) + expect(screen.getAllByRole("link")).toHaveLength(2) }) - - // Verify the state remains the same (still top two tips) - expect(screen.getByRole("link", { name: "rooTips.boomerangTasks.title" })).toBeInTheDocument() - expect(screen.getByRole("link", { name: "rooTips.stickyModels.title" })).toBeInTheDocument() - expect(screen.getAllByRole("link")).toHaveLength(2) - expect(screen.queryByRole("link", { name: "rooTips.tools.title" })).not.toBeInTheDocument() }) }) From 2eeae64e65e1e804e649491920532815310ce33f Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 16:09:54 -0400 Subject: [PATCH 08/15] Fix translations. --- webview-ui/src/i18n/locales/ca/chat.json | 3 ++- webview-ui/src/i18n/locales/de/chat.json | 3 ++- webview-ui/src/i18n/locales/es/chat.json | 3 ++- webview-ui/src/i18n/locales/fr/chat.json | 3 ++- webview-ui/src/i18n/locales/hi/chat.json | 3 ++- webview-ui/src/i18n/locales/it/chat.json | 3 ++- webview-ui/src/i18n/locales/ja/chat.json | 3 ++- webview-ui/src/i18n/locales/ko/chat.json | 3 ++- webview-ui/src/i18n/locales/pl/chat.json | 3 ++- webview-ui/src/i18n/locales/pt-BR/chat.json | 3 ++- webview-ui/src/i18n/locales/ru/chat.json | 15 +++++++++++++++ webview-ui/src/i18n/locales/tr/chat.json | 3 ++- webview-ui/src/i18n/locales/vi/chat.json | 3 ++- webview-ui/src/i18n/locales/zh-CN/chat.json | 3 ++- webview-ui/src/i18n/locales/zh-TW/chat.json | 3 ++- 15 files changed, 43 insertions(+), 14 deletions(-) diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 8b0ed2f1ee1..03608c288e6 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -231,5 +231,6 @@ "close": "Tancar navegador" } }, - "systemPromptWarning": "ADVERTÈNCIA: S'ha activat una substitució personalitzada d'instruccions del sistema. Això pot trencar greument la funcionalitat i causar un comportament impredictible." + "systemPromptWarning": "ADVERTÈNCIA: S'ha activat una substitució personalitzada d'instruccions del sistema. Això pot trencar greument la funcionalitat i causar un comportament impredictible.", + "selectApiConfig": "Seleccioneu la configuració de l'API" } diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index 74b78689c0b..78e8d9a460e 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -231,5 +231,6 @@ "close": "Browser schließen" } }, - "systemPromptWarning": "WARNUNG: Benutzerdefinierte Systemaufforderung aktiv. Dies kann die Funktionalität erheblich beeinträchtigen und zu unvorhersehbarem Verhalten führen." + "systemPromptWarning": "WARNUNG: Benutzerdefinierte Systemaufforderung aktiv. Dies kann die Funktionalität erheblich beeinträchtigen und zu unvorhersehbarem Verhalten führen.", + "selectApiConfig": "API-Konfiguration auswählen" } diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index 5b7f0ff44f9..650bcc6cba6 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -231,5 +231,6 @@ "close": "Cerrar navegador" } }, - "systemPromptWarning": "ADVERTENCIA: Anulación de instrucciones del sistema personalizada activa. Esto puede romper gravemente la funcionalidad y causar un comportamiento impredecible." + "systemPromptWarning": "ADVERTENCIA: Anulación de instrucciones del sistema personalizada activa. Esto puede romper gravemente la funcionalidad y causar un comportamiento impredecible.", + "selectApiConfig": "Seleccionar configuración de API" } diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index cc51bc0cdfc..3dc0e519dbd 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -231,5 +231,6 @@ "close": "Fermer le navigateur" } }, - "systemPromptWarning": "AVERTISSEMENT : Remplacement d'instructions système personnalisées actif. Cela peut gravement perturber la fonctionnalité et provoquer un comportement imprévisible." + "systemPromptWarning": "AVERTISSEMENT : Remplacement d'instructions système personnalisées actif. Cela peut gravement perturber la fonctionnalité et provoquer un comportement imprévisible.", + "selectApiConfig": "Sélectionner la configuration de l’API" } diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index d6f5b225876..9e5d00da7e2 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -231,5 +231,6 @@ "close": "ब्राउज़र बंद करें" } }, - "systemPromptWarning": "चेतावनी: कस्टम सिस्टम प्रॉम्प्ट ओवरराइड सक्रिय है। यह कार्यक्षमता को गंभीर रूप से बाधित कर सकता है और अनियमित व्यवहार का कारण बन सकता है।" + "systemPromptWarning": "चेतावनी: कस्टम सिस्टम प्रॉम्प्ट ओवरराइड सक्रिय है। यह कार्यक्षमता को गंभीर रूप से बाधित कर सकता है और अनियमित व्यवहार का कारण बन सकता है.", + "selectApiConfig": "एपीआई कॉन्फ़िगरेशन का चयन करें" } diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index eed9bc9883c..092c8a84a09 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -231,5 +231,6 @@ "close": "Chiudi browser" } }, - "systemPromptWarning": "ATTENZIONE: Sovrascrittura personalizzata delle istruzioni di sistema attiva. Questo può compromettere gravemente le funzionalità e causare comportamenti imprevedibili." + "systemPromptWarning": "ATTENZIONE: Sovrascrittura personalizzata delle istruzioni di sistema attiva. Questo può compromettere gravemente le funzionalità e causare comportamenti imprevedibili.", + "selectApiConfig": "Seleziona la configurazione API" } diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index 32822c4c99b..aa42cc85f74 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -231,5 +231,6 @@ "close": "ブラウザを閉じる" } }, - "systemPromptWarning": "警告:カスタムシステムプロンプトの上書きが有効です。これにより機能が深刻に損なわれ、予測不可能な動作が発生する可能性があります。" + "systemPromptWarning": "警告:カスタムシステムプロンプトの上書きが有効です。これにより機能が深刻に損なわれ、予測不可能な動作が発生する可能性があります。", + "selectApiConfig": "API構成を選択" } diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 3c819b02235..e0b3a6d05a7 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -231,5 +231,6 @@ "close": "브라우저 닫기" } }, - "systemPromptWarning": "경고: 사용자 정의 시스템 프롬프트 재정의가 활성화되었습니다. 이로 인해 기능이 심각하게 손상되고 예측할 수 없는 동작이 발생할 수 있습니다." + "systemPromptWarning": "경고: 사용자 정의 시스템 프롬프트 재정의가 활성화되었습니다. 이로 인해 기능이 심각하게 손상되고 예측할 수 없는 동작이 발생할 수 있습니다.", + "selectApiConfig": "API 구성 선택" } diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index f9911686b37..796f9af1b7f 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -231,5 +231,6 @@ "close": "Zamknij przeglądarkę" } }, - "systemPromptWarning": "OSTRZEŻENIE: Aktywne niestandardowe zastąpienie instrukcji systemowych. Może to poważnie zakłócić funkcjonalność i powodować nieprzewidywalne zachowanie." + "systemPromptWarning": "OSTRZEŻENIE: Aktywne niestandardowe zastąpienie instrukcji systemowych. Może to poważnie zakłócić funkcjonalność i powodować nieprzewidywalne zachowanie.", + "selectApiConfig": "Wybierz konfigurację API" } diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index 56ef986ce3a..a74e8a6c9d4 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -231,5 +231,6 @@ "close": "Fechar navegador" } }, - "systemPromptWarning": "AVISO: Substituição personalizada de instrução do sistema ativa. Isso pode comprometer gravemente a funcionalidade e causar comportamento imprevisível." + "systemPromptWarning": "AVISO: Substituição personalizada de instrução do sistema ativa. Isso pode comprometer gravemente a funcionalidade e causar comportamento imprevisível.", + "selectApiConfig": "Selecionar configuração da API" } diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index 0eb6882ca63..5f8730573a8 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -65,6 +65,21 @@ "tooltip": "Отменить текущую операцию" }, "scrollToBottom": "Прокрутить чат вниз", + "about": "Создавайте, рефакторите и отлаживайте код с помощью ИИ.
Подробнее см. в нашей документации.", + "rooTips": { + "boomerangTasks": { + "title": "Boomerang Tasks", + "description": "Orchestrate complex workflows with subtasks" + }, + "stickyModels": { + "title": "Липучие модели", + "description": "Каждый режим запоминает вашу последнюю использованную модель" + }, + "tools": { + "title": "Инструменты", + "description": "Разрешите ИИ решать проблемы, просматривая веб-страницы, выполняя команды и т. д." + } + }, "onboarding": "Ваш список задач в этом рабочем пространстве пуст. Начните с ввода задачи ниже. Не знаете, с чего начать? Подробнее о возможностях Roo читайте в документации.", "selectMode": "Выберите режим взаимодействия", "selectApiConfig": "Выберите конфигурацию API", diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 6bd8ce50aef..efa608d6db9 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -231,5 +231,6 @@ "close": "Tarayıcıyı kapat" } }, - "systemPromptWarning": "UYARI: Özel sistem komut geçersiz kılma aktif. Bu işlevselliği ciddi şekilde bozabilir ve öngörülemeyen davranışlara neden olabilir." + "systemPromptWarning": "UYARI: Özel sistem komut geçersiz kılma aktif. Bu işlevselliği ciddi şekilde bozabilir ve öngörülemeyen davranışlara neden olabilir.", + "selectApiConfig": "API yapılandırmasını seçin" } diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index e6fb683d529..03b465f0b0b 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -231,5 +231,6 @@ "close": "Đóng trình duyệt" } }, - "systemPromptWarning": "CẢNH BÁO: Đã kích hoạt ghi đè lệnh nhắc hệ thống tùy chỉnh. Điều này có thể phá vỡ nghiêm trọng chức năng và gây ra hành vi không thể dự đoán." + "systemPromptWarning": "CẢNH BÁO: Đã kích hoạt ghi đè lệnh nhắc hệ thống tùy chỉnh. Điều này có thể phá vỡ nghiêm trọng chức năng và gây ra hành vi không thể dự đoán.", + "selectApiConfig": "Chọn cấu hình API" } diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index 1c6e1a3e8c2..488c4a60d72 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -231,5 +231,6 @@ "close": "关闭浏览器" } }, - "systemPromptWarning": "警告:自定义系统提示词覆盖已激活。这可能严重破坏功能并导致不可预测的行为。" + "systemPromptWarning": "警告:自定义系统提示词覆盖已激活。这可能严重破坏功能并导致不可预测的行为。", + "selectApiConfig": "选择 API 配置" } diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 47c264a5f62..0e34fdf8910 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -231,5 +231,6 @@ "close": "關閉瀏覽器" } }, - "systemPromptWarning": "警告:自訂系統提示詞覆蓋已啟用。這可能嚴重破壞功能並導致不可預測的行為。" + "systemPromptWarning": "警告:自訂系統提示詞覆蓋已啟用。這可能嚴重破壞功能並導致不可預測的行為。", + "selectApiConfig": "選取 API 設定" } From b9821976a416b31d0820f6a560465f95c7f8f3c3 Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 12:16:58 -0400 Subject: [PATCH 09/15] Compromise-compromise. --- webview-ui/src/components/chat/ChatView.tsx | 54 ++++++++++++++----- .../src/components/history/HistoryPreview.tsx | 51 ++++++------------ 2 files changed, 56 insertions(+), 49 deletions(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index ec0d83ccdc2..b1630acc51b 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -38,6 +38,7 @@ import ChatTextArea from "./ChatTextArea" import TaskHeader from "./TaskHeader" import AutoApproveMenu from "./AutoApproveMenu" import SystemPromptWarning from "./SystemPromptWarning" +import { useTaskSearch } from "../history/useTaskSearch" interface ChatViewProps { isHidden: boolean showAnnouncement: boolean @@ -82,8 +83,23 @@ const ChatViewComponent: React.ForwardRefRenderFunction { + const newState = !isExpanded + setIsExpanded(newState) + // Send message to extension to persist the new collapsed state + vscode.postMessage({ type: "setHistoryPreviewCollapsed", bool: !newState }) + }, [isExpanded]) + //const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined const task = useMemo(() => messages.at(0), [messages]) // leaving this less safe version here since if the first message is not a task, then the extension is in a bad state and needs to be debugged (see Cline.abort) const modifiedMessages = useMemo(() => combineApiRequests(combineCommandSequences(messages.slice(1))), [messages]) @@ -1227,18 +1243,31 @@ const ChatViewComponent: React.ForwardRefRenderFunction ) : ( - <> - {taskHistory.length > 0 && } -

- {/* Show the task history if there are any for this workspace. */} - - {telemetrySetting === "unset" && } +
+ {/* Moved Task Bar Header Here */} + {tasks.length !== 0 && ( +
+
+ {tasks.length < 10 && ( + {t("history:recentTasks")} + )} + +
+
+ )} +
{showAnnouncement && } - {/* Always show the hero. */} - {/* If the user has little task history, we can show the onboarding message */} - {taskHistory.length < 10 && ( + {/* Always show the hero. */} + + {telemetrySetting === "unset" && } + {/* Show the task history preview if expanded and tasks exist */} + {taskHistory.length > 0 && isExpanded && } + {/* If the user has no task history, we can show the onboarding message */} + {taskHistory.length > -1 && (

)} - - {/* Finally, always show the tips */} - + {/* Finally, if there less than 3 tasks, we can show the tips */} + {tasks.length > -1 && }
- +
)} {/* diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 9c4a0e5e9b4..3a01ce534c9 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -1,53 +1,23 @@ -import { memo, useState, useCallback } from "react" +import { memo } from "react" import { vscode } from "@/utils/vscode" import { formatLargeNumber, formatDate } from "@/utils/format" import { Button } from "@/components/ui" import { useAppTranslation } from "@src/i18n/TranslationContext" -import { useExtensionState } from "@src/context/ExtensionStateContext" import { CopyButton } from "./CopyButton" import { useTaskSearch } from "./useTaskSearch" import { Trans } from "react-i18next" import { Coins } from "lucide-react" -type HistoryPreviewProps = { - showHistoryView: () => void -} -const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { +const HistoryPreview = () => { const { tasks, showAllWorkspaces } = useTaskSearch() - const { historyPreviewCollapsed } = useExtensionState() // Will add this state later const { t } = useAppTranslation() - // Initialize expanded state based on the persisted setting (default to expanded if undefined) - const [isExpanded, setIsExpanded] = useState( - historyPreviewCollapsed === undefined ? true : !historyPreviewCollapsed, - ) - - const toggleExpanded = useCallback(() => { - const newState = !isExpanded - setIsExpanded(newState) - // Send message to extension to persist the new collapsed state - vscode.postMessage({ type: "setHistoryPreviewCollapsed", bool: !newState }) - }, [isExpanded]) return ( <>
- {tasks.length !== 0 && ( -
- {/* Keep the history button, but maybe it should just show the full view? Or remove it if header is clicked? Let's keep it for now. */} -
{t("chat:greeting")}
- -
- - {isExpanded ? "" : t("history:recentTasks")} - - -
-
- )} - {tasks.length === 0 && ( <>

@@ -66,14 +36,21 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { />

- )} - {tasks.length !== 0 && isExpanded && ( + {tasks.length !== 0 && ( <> {tasks.slice(0, 3).map((item) => (
{
))} - {/* Add a "View All" link below the preview list when expanded */} + {/* The link to show history view will be moved to ChatView */}
showHistoryView()}> + onClick={() => { + /* TODO: Implement or remove */ + }}> {t("history:viewAll")} ({tasks.length})
From 45a021c34148b622dfb025473cc3824935d7f54e Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 18:13:41 -0400 Subject: [PATCH 10/15] Final tweaks. --- webview-ui/src/components/chat/ChatView.tsx | 2 +- .../src/components/history/HistoryPreview.tsx | 23 ------------------- webview-ui/src/i18n/locales/de/chat.json | 2 +- webview-ui/src/i18n/locales/en/chat.json | 18 ++------------- 4 files changed, 4 insertions(+), 41 deletions(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index b1630acc51b..ff971e455dc 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -1257,7 +1257,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction
)} -
+
{showAnnouncement && } diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 3a01ce534c9..d0a210713c2 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -2,9 +2,7 @@ import { memo } from "react" import { vscode } from "@/utils/vscode" import { formatLargeNumber, formatDate } from "@/utils/format" -import { Button } from "@/components/ui" -import { useAppTranslation } from "@src/i18n/TranslationContext" import { CopyButton } from "./CopyButton" import { useTaskSearch } from "./useTaskSearch" @@ -13,7 +11,6 @@ import { Coins } from "lucide-react" const HistoryPreview = () => { const { tasks, showAllWorkspaces } = useTaskSearch() - const { t } = useAppTranslation() return ( <> @@ -35,18 +32,6 @@ const HistoryPreview = () => { }} />

- - {/* The button to show history view will be moved to ChatView */} - )} @@ -94,14 +79,6 @@ const HistoryPreview = () => {
))} - {/* The link to show history view will be moved to ChatView */} -
{ - /* TODO: Implement or remove */ - }}> - {t("history:viewAll")} ({tasks.length}) -
)}
diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index 78e8d9a460e..a6aef03ec83 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -73,7 +73,7 @@ "description": "Teile Aufgaben in kleinere, überschaubare Teile auf." }, "stickyModels": { - "title": "Sticky Models", + "title": "Sticky Modes", "description": "Jeder Modus merkt sich dein zuletzt verwendetes Modell" }, "tools": { diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 499e8a77c6b..ffa4e456092 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -73,7 +73,7 @@ "description": "Split tasks into smaller, manageable parts." }, "stickyModels": { - "title": "Sticky Models", + "title": "Sticky Modes", "description": "Each mode remembers your last used model" }, "tools": { @@ -232,19 +232,5 @@ "close": "Close browser" } }, - "systemPromptWarning": "WARNING: Custom system prompt override active. This can severely break functionality and cause unpredictable behavior.", - "rooTips": { - "boomerangTasks": { - "title": "Boomerang Tasks", - "description": "Orchestrate complex workflows with subtasks" - }, - "stickyModels": { - "title": "Sticky Models", - "description": "Each mode remembers your last used model" - }, - "tools": { - "title": "Tools", - "description": "Allow the AI to solve problems by browsing the web, running commands, and more." - } - } + "systemPromptWarning": "WARNING: Custom system prompt override active. This can severely break functionality and cause unpredictable behavior." } From daee1e2716afef7dd844c3704174675c89411451 Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 18:20:21 -0400 Subject: [PATCH 11/15] More tweaks. --- webview-ui/src/components/history/HistoryPreview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index d0a210713c2..fce65886bdb 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -14,7 +14,7 @@ const HistoryPreview = () => { return ( <> -
+
{tasks.length === 0 && ( <>

From 103e2aed9a071dbf72a1c570913e883c0941b60c Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 20:48:38 -0400 Subject: [PATCH 12/15] More tweaks. --- webview-ui/src/App.tsx | 1 - .../src/components/chat/Announcement.tsx | 6 ++- webview-ui/src/components/chat/ChatView.tsx | 50 ++++++++----------- .../__tests__/ChatView.auto-approve.test.tsx | 1 - .../chat/__tests__/ChatView.test.tsx | 1 - .../src/components/history/HistoryPreview.tsx | 23 +-------- webview-ui/src/components/welcome/RooTips.tsx | 3 +- 7 files changed, 27 insertions(+), 58 deletions(-) diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index 2b9d15d19ee..8ca72ecf718 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -123,7 +123,6 @@ const App = () => { isHidden={tab !== "chat"} showAnnouncement={showAnnouncement} hideAnnouncement={() => setShowAnnouncement(false)} - showHistoryView={() => switchTab("history")} /> void } /* You must update the latestAnnouncementId in ClineProvider for new announcements to show to users. This new id will be compared with whats in state for the 'last announcement shown', and if it's different then the announcement will render. As soon as an announcement is shown, the id will be updated in state. This ensures that announcements are not shown more than once, even if the user doesn't close it themselves. */ -const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { +const Announcement = ({ hideAnnouncement }: AnnouncementProps) => { const { t } = useAppTranslation() const discordLink = ( @@ -71,6 +70,7 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { i18nKey="chat:announcement.feature1" components={{ bold: , + code: , }} /> @@ -80,6 +80,7 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { i18nKey="chat:announcement.feature2" components={{ bold: , + code: , }} /> @@ -89,6 +90,7 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { i18nKey="chat:announcement.feature3" components={{ bold: , + code: , }} /> diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index b7b1d8f72b8..927e6810474 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -44,7 +44,6 @@ export interface ChatViewProps { isHidden: boolean showAnnouncement: boolean hideAnnouncement: () => void - showHistoryView: () => void } export interface ChatViewRef { @@ -56,13 +55,12 @@ export const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0 const ChatViewComponent: React.ForwardRefRenderFunction = ( - { isHidden, showAnnouncement, hideAnnouncement, showHistoryView }, + { isHidden, showAnnouncement, hideAnnouncement }, ref, ) => { const { t } = useAppTranslation() const modeShortcutText = `${isMac ? "⌘" : "Ctrl"} + . ${t("chat:forNextMode")}` const { - version, clineMessages: messages, taskHistory, apiConfiguration, @@ -1213,6 +1211,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction + {showAnnouncement && } {task ? ( <> {/* Moved Task Bar Header Here */} {tasks.length !== 0 && ( -

+
{tasks.length < 10 && ( {t("history:recentTasks")} @@ -1256,35 +1255,28 @@ const ChatViewComponent: React.ForwardRefRenderFunction
)} -
- {showAnnouncement && } - +
0 ? "mt-0" : ""} p-10 pt-5"`}> - {/* Always show the hero. */} - {telemetrySetting === "unset" && } {/* Show the task history preview if expanded and tasks exist */} {taskHistory.length > 0 && isExpanded && } - {/* If the user has no task history, we can show the onboarding message */} - {taskHistory.length > -1 && ( -

- - the docs - - ), - }} - /> -

- )} - {/* Finally, if there less than 3 tasks, we can show the tips */} - {tasks.length > -1 && } +

+ + the docs + + ), + }} + /> +

+
)} diff --git a/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.test.tsx b/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.test.tsx index 704c705d394..56d7eb3f41f 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.test.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.test.tsx @@ -95,7 +95,6 @@ const defaultProps: ChatViewProps = { isHidden: false, showAnnouncement: false, hideAnnouncement: () => {}, - showHistoryView: () => {}, } const renderChatView = (props: Partial = {}) => { diff --git a/webview-ui/src/components/chat/__tests__/ChatView.test.tsx b/webview-ui/src/components/chat/__tests__/ChatView.test.tsx index 13d9433f8de..05540f35d36 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.test.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.test.tsx @@ -153,7 +153,6 @@ const defaultProps: ChatViewProps = { isHidden: false, showAnnouncement: false, hideAnnouncement: () => {}, - showHistoryView: () => {}, } const queryClient = new QueryClient() diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index fce65886bdb..080cbff3e20 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -6,7 +6,6 @@ import { formatLargeNumber, formatDate } from "@/utils/format" import { CopyButton } from "./CopyButton" import { useTaskSearch } from "./useTaskSearch" -import { Trans } from "react-i18next" import { Coins } from "lucide-react" const HistoryPreview = () => { @@ -14,27 +13,7 @@ const HistoryPreview = () => { return ( <> -
- {tasks.length === 0 && ( - <> -

- - the docs - - ), - }} - /> -

- - )} - +
{tasks.length !== 0 && ( <> {tasks.slice(0, 3).map((item) => ( diff --git a/webview-ui/src/components/welcome/RooTips.tsx b/webview-ui/src/components/welcome/RooTips.tsx index db56d57b0c5..2a1dc4a1bd8 100644 --- a/webview-ui/src/components/welcome/RooTips.tsx +++ b/webview-ui/src/components/welcome/RooTips.tsx @@ -54,7 +54,7 @@ const RooTips = ({ cycle = false }: RooTipsProps) => {
{/* If we need real estate, we show a compressed version of the tips. Otherwise, we expand it. */} {cycle ? ( @@ -66,7 +66,6 @@ const RooTips = ({ cycle = false }: RooTipsProps) => { isFading ? "opacity-0" : "opacity-70", )}> {" "} - {/* Corrected backtick to parenthesis */} {t(currentTip.titleKey)}:{" "} From d00e120849b167daaf24b07146a1db0a4169f73c Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 20:54:34 -0400 Subject: [PATCH 13/15] Issues fix. --- webview-ui/src/components/chat/ChatView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 927e6810474..a2eeeebf090 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -1256,7 +1256,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction )}
0 ? "mt-0" : ""} p-10 pt-5"`}> + className={` w-full flex flex-col gap-4 m-auto ${isExpanded && tasks.length > 0 ? "mt-0" : ""} p-10 pt-5`}> {telemetrySetting === "unset" && } {/* Show the task history preview if expanded and tasks exist */} @@ -1331,7 +1331,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction
{ scrollToBottomSmooth() disableAutoScrollRef.current = false From 9e14548f4138ca6657c7c25aab577e0864582d9b Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 21:05:00 -0400 Subject: [PATCH 14/15] Update translations, remove debug. --- src/core/webview/ClineProvider.ts | 6 ++---- webview-ui/src/i18n/locales/ca/chat.json | 4 ++-- webview-ui/src/i18n/locales/de/chat.json | 2 +- webview-ui/src/i18n/locales/es/chat.json | 2 +- webview-ui/src/i18n/locales/fr/chat.json | 2 +- webview-ui/src/i18n/locales/hi/chat.json | 2 +- webview-ui/src/i18n/locales/it/chat.json | 2 +- webview-ui/src/i18n/locales/ja/chat.json | 4 ++-- webview-ui/src/i18n/locales/ko/chat.json | 2 +- webview-ui/src/i18n/locales/pl/chat.json | 2 +- webview-ui/src/i18n/locales/pt-BR/chat.json | 4 ++-- webview-ui/src/i18n/locales/ru/chat.json | 2 +- webview-ui/src/i18n/locales/tr/chat.json | 4 ++-- webview-ui/src/i18n/locales/vi/chat.json | 4 ++-- webview-ui/src/i18n/locales/zh-CN/chat.json | 4 ++-- webview-ui/src/i18n/locales/zh-TW/chat.json | 2 +- 16 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index edf0a64990e..431f061db74 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1213,11 +1213,9 @@ export class ClineProvider extends EventEmitter implements language, maxReadFileLine, terminalCompressProgressBar, - historyPreviewCollapsed + historyPreviewCollapsed, } = await this.getState() - this.log(`[Debug] getState historyPreviewCollapsed: ${historyPreviewCollapsed}`) // Add logging here - const telemetryKey = process.env.POSTHOG_API_KEY const machineId = vscode.env.machineId const allowedCommands = vscode.workspace.getConfiguration("roo-cline").get("allowedCommands") || [] @@ -1390,7 +1388,7 @@ export class ClineProvider extends EventEmitter implements telemetrySetting: stateValues.telemetrySetting || "unset", showRooIgnoredFiles: stateValues.showRooIgnoredFiles ?? true, maxReadFileLine: stateValues.maxReadFileLine ?? 500, - historyPreviewCollapsed: stateValues.historyPreviewCollapsed ?? false, + historyPreviewCollapsed: stateValues.historyPreviewCollapsed ?? false, } } diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 03608c288e6..b5eeb292dda 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -73,8 +73,8 @@ "description": "Divideix les tasques en parts més petites i manejables." }, "stickyModels": { - "title": "Models persistents", - "description": "Cada mode recorda el teu últim model utilitzat" + "title": "Modes persistents", + "description": "Cada mode recorda el vostre darrer model utilitzat" }, "tools": { "title": "Eines", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index a6aef03ec83..46d64c0236a 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -73,7 +73,7 @@ "description": "Teile Aufgaben in kleinere, überschaubare Teile auf." }, "stickyModels": { - "title": "Sticky Modes", + "title": "Sticky Modi", "description": "Jeder Modus merkt sich dein zuletzt verwendetes Modell" }, "tools": { diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index 650bcc6cba6..ba3d53c0ff3 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -73,7 +73,7 @@ "description": "Divide las tareas en partes más pequeñas y manejables." }, "stickyModels": { - "title": "Modelos persistentes", + "title": "Modos persistentes", "description": "Cada modo recuerda tu último modelo utilizado" }, "tools": { diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 3dc0e519dbd..f67850c126f 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -73,7 +73,7 @@ "description": "Divisez les tâches en parties plus petites et gérables." }, "stickyModels": { - "title": "Modèles persistants", + "title": "Modes persistants", "description": "Chaque mode se souvient de votre dernier modèle utilisé" }, "tools": { diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index 9e5d00da7e2..a8ddb342937 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -73,7 +73,7 @@ "description": "कार्यों को छोटे, प्रबंधनीय भागों में विभाजित करें।" }, "stickyModels": { - "title": "चिपचिपे मॉडल", + "title": "स्टिकी मोड", "description": "प्रत्येक मोड आपके अंतिम उपयोग किए गए मॉडल को याद रखता है" }, "tools": { diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index 092c8a84a09..4c2d30847d8 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -73,7 +73,7 @@ "description": "Dividi le attività in parti più piccole e gestibili." }, "stickyModels": { - "title": "Modelli persistenti", + "title": "Modalità persistenti", "description": "Ogni modalità ricorda il tuo ultimo modello utilizzato" }, "tools": { diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index aa42cc85f74..9ec1c7e3c3f 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -73,8 +73,8 @@ "description": "タスクをより小さく、管理しやすい部分に分割します。" }, "stickyModels": { - "title": "スティッキーモデル", - "description": "各モードは、最後に使用したモデルを記憶します" + "title": "スティッキーモード", + "description": "各モードは、最後に使用したモデルを記憶しています" }, "tools": { "title": "ツール", diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index e0b3a6d05a7..badba25d101 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -73,7 +73,7 @@ "description": "작업을 더 작고 관리하기 쉬운 부분으로 나눕니다." }, "stickyModels": { - "title": "고정 모델", + "title": "스티키 모드", "description": "각 모드는 마지막으로 사용한 모델을 기억합니다." }, "tools": { diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index 796f9af1b7f..e969b247377 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -73,7 +73,7 @@ "description": "Podziel zadania na mniejsze, łatwiejsze do zarządzania części." }, "stickyModels": { - "title": "Modele przyklejone", + "title": "Tryby trwałe", "description": "Każdy tryb zapamiętuje ostatnio używany model" }, "tools": { diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index a74e8a6c9d4..f1924b13eb6 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -73,8 +73,8 @@ "description": "Divida as tarefas em partes menores e gerenciáveis." }, "stickyModels": { - "title": "Modelos Persistentes", - "description": "Cada modo lembra seu último modelo usado" + "title": "Modos Fixos", + "description": "Cada modo lembra o seu último modelo usado" }, "tools": { "title": "Ferramentas", diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index 5f8730573a8..cd0be1c2d96 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -72,7 +72,7 @@ "description": "Orchestrate complex workflows with subtasks" }, "stickyModels": { - "title": "Липучие модели", + "title": "Липкие режимы", "description": "Каждый режим запоминает вашу последнюю использованную модель" }, "tools": { diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index efa608d6db9..9e010ca5851 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -73,8 +73,8 @@ "description": "Görevleri daha küçük, yönetilebilir parçalara ayırın." }, "stickyModels": { - "title": "Yapışkan Modeller", - "description": "Her mod en son kullandığınız modeli hatırlar" + "title": "Yapışkan Modlar", + "description": "Her mod, en son kullandığınız modeli hatırlar" }, "tools": { "title": "Araçlar", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index 03b465f0b0b..7f6ad3aaba9 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -73,8 +73,8 @@ "description": "Chia nhỏ các nhiệm vụ thành các phần nhỏ hơn, dễ quản lý hơn." }, "stickyModels": { - "title": "Mô hình dính", - "description": "Mỗi chế độ ghi nhớ mô hình bạn đã sử dụng gần đây nhất" + "title": "Chế độ dính", + "description": "Mỗi chế độ ghi nhớ mô hình đã sử dụng cuối cùng của bạn" }, "tools": { "title": "Công cụ", diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index 488c4a60d72..be9073fbf58 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -73,8 +73,8 @@ "description": "将任务拆分为更小、更易于管理的部分。" }, "stickyModels": { - "title": "增强导向模式", - "description": "每个模式都会记住您上次使用的模型" + "title": "粘性模式", + "description": "每个模式 都会记住 您上次使用的模型" }, "tools": { "title": "工具", diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 0e34fdf8910..bd9a7ae279a 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -73,7 +73,7 @@ "description": "將任務拆分為更小、更易於管理的部分。" }, "stickyModels": { - "title": "增強導向模式", + "title": "黏性模式", "description": "每個模式都會記住您上次使用的模型" }, "tools": { From 1ca3f960c8d0fcbbd141396b1672daf85362027e Mon Sep 17 00:00:00 2001 From: Sacha Sayan Date: Fri, 25 Apr 2025 21:52:54 -0400 Subject: [PATCH 15/15] Fix transparency issue. --- webview-ui/src/components/chat/Announcement.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index f1f72d04954..b3a79cde7c7 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -44,7 +44,7 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => {