diff --git a/apps/web-roo-code/src/app/privacy/page.tsx b/apps/web-roo-code/src/app/privacy/page.tsx index bb132651f7..6b17c4ff8d 100644 --- a/apps/web-roo-code/src/app/privacy/page.tsx +++ b/apps/web-roo-code/src/app/privacy/page.tsx @@ -46,7 +46,7 @@ export default function Privacy() {

Roo Code Cloud Privacy Policy

-

Last Updated: August 20, 2025

+

Last Updated: September 19, 2025

This Privacy Policy explains how Roo Code, Inc. ("Roo Code," "we," @@ -86,8 +86,8 @@ export default function Privacy() { Your source code does not transit Roo Code servers unless you explicitly choose Roo Code as a model provider (proxy mode). {" "} - When Roo Code Cloud is your model provider, your code briefly transits Roo Code servers only to - forward it to the upstream model, is not stored, and is deleted immediately after + When Roo Code Cloud is your model provider, your code briefly transits Roo Code servers only + to forward it to the upstream model, is not stored, and is deleted immediately after forwarding. Otherwise, your code is sent directly—via client‑to‑provider TLS—to the model you select. Roo Code never stores, inspects, or trains on your code. @@ -184,6 +184,13 @@ export default function Privacy() {

  • Send product updates and roadmap communications (opt‑out available)
  • +
  • + Send onboarding, educational, and promotional communications. We may use + your account information (such as your name and email address) to send you onboarding + messages, product tutorials, feature announcements, newsletters, and other marketing + communications. You can opt out of non‑transactional emails at any time (see “Your Choices” + below). +
  • 3. Where Your Data Goes (And Doesn't)

    @@ -277,6 +284,12 @@ export default function Privacy() { Delete your Cloud account at any time from{" "} Security Settings inside Roo Code Cloud. +
  • + Marketing communications: You can unsubscribe from marketing and + promotional emails by clicking the unsubscribe link in those emails. Transactional or + service‑related emails (such as password resets, billing notices, or security alerts) will + continue even if you opt out. +
  • 6. Security Practices

    diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index accb66f6e9..facb0bb5cd 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -3035,5 +3035,10 @@ export const webviewMessageHandler = async ( }) break } + case "openSettings": { + // Jump the user to the Providers settings panel when they click the CODE SUPERNOVA upsell link + await vscode.commands.executeCommand(getCommand("settingsButtonClicked")) + break + } } } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 93d0b9bc45..8ee282dfb3 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -225,6 +225,7 @@ export interface WebviewMessage { | "editQueuedMessage" | "dismissUpsell" | "getDismissedUpsells" + | "openSettings" text?: string editedMessageContent?: string tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "cloud" diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index d358c68f1c..469ffe9ce9 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -57,7 +57,6 @@ import { CheckpointWarning } from "./CheckpointWarning" import { QueuedMessages } from "./QueuedMessages" import DismissibleUpsell from "../common/DismissibleUpsell" import { useCloudUpsell } from "@src/hooks/useCloudUpsell" -import { Cloud } from "lucide-react" export interface ChatViewProps { isHidden: boolean @@ -131,7 +130,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction 0 // Initialize expanded state based on the persisted setting (default to expanded if undefined) const [isExpanded, setIsExpanded] = useState( @@ -212,7 +212,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction {/* Moved Task Bar Header Here */} - {tasks.length !== 0 && ( + {hasTaskHistory && (
    - {tasks.length < 10 && ( + {recentTasks.length < 10 && ( {t("history:recentTasks")} )} } - onClick={() => openUpsell()} + upsellId="taskListSupernova" dismissOnClick={false} className="bg-vscode-editor-background p-4 !text-base"> - , - }} - /> +
    + , + providersLink: ( + vscode.postMessage({ type: "openSettings" })} + /> + ), + }} + /> +
    )}
    {/* Show the task history preview if expanded and tasks exist */} - {taskHistory.length > 0 && isExpanded && } + {hasTaskHistory && isExpanded && }
    )} diff --git a/webview-ui/src/components/chat/__tests__/CloudTaskButton.spec.tsx b/webview-ui/src/components/chat/__tests__/CloudTaskButton.spec.tsx index fc2b9f025e..ae4e7ebbe0 100644 --- a/webview-ui/src/components/chat/__tests__/CloudTaskButton.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/CloudTaskButton.spec.tsx @@ -19,11 +19,6 @@ vi.mock("qrcode", () => ({ // Mock react-i18next vi.mock("react-i18next") -// Mock the cloud config -vi.mock("@roo-code/cloud/src/config", () => ({ - getRooCodeApiUrl: vi.fn(() => "https://app.roocode.com"), -})) - // Mock the extension state context vi.mock("@/context/ExtensionStateContext", () => ({ ExtensionStateContextProvider: ({ children }: { children: React.ReactNode }) => children, diff --git a/webview-ui/src/components/cloud/CloudView.tsx b/webview-ui/src/components/cloud/CloudView.tsx index 78dfba7494..32dd534553 100644 --- a/webview-ui/src/components/cloud/CloudView.tsx +++ b/webview-ui/src/components/cloud/CloudView.tsx @@ -136,6 +136,10 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl vscode.postMessage({ type: "openExternal", url: cloudUrl }) } + const handleStartFreeTrial = () => { + vscode.postMessage({ type: "openExternal", url: "https://app.roocode.com/billing" }) + } + const handleOpenCloudUrl = () => { if (cloudApiUrl) { vscode.postMessage({ type: "openExternal", url: cloudApiUrl }) @@ -272,9 +276,20 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl
    {renderCloudBenefitsContent(t)}
    {!authInProgress && ( - - {t("cloud:connect")} - + <> + + {t("cloud:startFreeTrial")} + + + {t("cloud:connect")} + + )} {/* Manual entry section */} diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 753b4b84e7..dc973c69b2 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -7,18 +7,22 @@ import { useTaskSearch } from "./useTaskSearch" import TaskItem from "./TaskItem" const HistoryPreview = () => { - const { tasks } = useTaskSearch() + const { tasks, recentTasks } = useTaskSearch() const { t } = useAppTranslation() const handleViewAllHistory = () => { vscode.postMessage({ type: "switchTab", tab: "history" }) } + const previewSource = tasks.length > 0 ? tasks : recentTasks + const previewTasks = previewSource.slice(0, 3) + const hasAnyTasks = recentTasks.length > 0 + return (
    - {tasks.length !== 0 && ( + {hasAnyTasks && ( <> - {tasks.slice(0, 3).map((item) => ( + {previewTasks.map((item) => ( ))}