Skip to content

Commit 7b07ff9

Browse files
committed
Remove Telemetry everywhere
1 parent 2243036 commit 7b07ff9

File tree

20 files changed

+8
-866
lines changed

20 files changed

+8
-866
lines changed

PRIVACY.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,10 @@ Roo Code respects your privacy and is committed to transparency about how we han
1010
- **Commands**: Any commands executed through Roo Code happen on your local environment. However, when you use AI-powered features, the relevant code and context from your commands may be transmitted to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not have access to or store this data, but AI providers may process it per their privacy policies.
1111
- **Prompts & AI Requests**: When you use AI-powered features, your prompts and relevant project context are sent to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not store or process this data. These AI providers have their own privacy policies and may store data per their terms of service.
1212
- **API Keys & Credentials**: If you enter an API key (e.g., to connect an AI model), it is stored locally on your device and never sent to us or any third party, except the provider you have chosen.
13-
- **Telemetry (Usage Data)**: We only collect feature usage and error data if you explicitly opt-in. This telemetry is powered by PostHog and helps us understand feature usage to improve Roo Code. This includes your VS Code machine ID and feature usage patterns and exception reports. We do **not** collect personally identifiable information, your code, or AI prompts.
14-
15-
### **How We Use Your Data (If Collected)**
16-
17-
- If you opt-in to telemetry, we use it to understand feature usage and improve Roo Code.
18-
- We do **not** sell or share your data.
19-
- We do **not** train any models on your data.
2013

2114
### **Your Choices & Control**
2215

2316
- You can run models locally to prevent data being sent to third-parties.
24-
- By default, telemetry collection is off and if you turn it on, you can opt out of telemetry at any time.
25-
- You can delete Roo Code to stop all data collection.
2617

2718
### **Security & Updates**
2819

src/core/Cline.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ import { McpHub } from "../services/mcp/McpHub"
7171
import crypto from "crypto"
7272
import { insertGroups } from "./diff/insert-groups"
7373
import { OutputBuilder } from "../integrations/terminal/OutputBuilder"
74-
import { telemetryService } from "../services/telemetry/TelemetryService"
7574

7675
const cwd =
7776
vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution
@@ -191,12 +190,6 @@ export class Cline {
191190
this.enableCheckpoints = enableCheckpoints
192191
this.checkpointStorage = checkpointStorage
193192

194-
if (historyItem) {
195-
telemetryService.captureTaskRestarted(this.taskId)
196-
} else {
197-
telemetryService.captureTaskCreated(this.taskId)
198-
}
199-
200193
// Initialize diffStrategy based on current state
201194
this.updateDiffStrategy(
202195
Experiments.isEnabled(experiments ?? {}, EXPERIMENT_IDS.DIFF_STRATEGY),
@@ -1468,10 +1461,6 @@ export class Cline {
14681461
await this.browserSession.closeBrowser()
14691462
}
14701463

1471-
if (!block.partial) {
1472-
telemetryService.captureToolUsage(this.taskId, block.name)
1473-
}
1474-
14751464
// Validate tool use before execution
14761465
const { mode, customModes } = (await this.providerRef.deref()?.getState()) ?? {}
14771466
try {
@@ -2956,7 +2945,6 @@ export class Cline {
29562945
if (lastMessage && lastMessage.ask !== "command") {
29572946
// havent sent a command message yet so first send completion_result then command
29582947
await this.say("completion_result", result, undefined, false)
2959-
telemetryService.captureTaskCompleted(this.taskId)
29602948
}
29612949

29622950
// complete command message
@@ -2974,7 +2962,6 @@ export class Cline {
29742962
commandResult = execCommandResult
29752963
} else {
29762964
await this.say("completion_result", result, undefined, false)
2977-
telemetryService.captureTaskCompleted(this.taskId)
29782965
}
29792966

29802967
if (this.isSubTask) {
@@ -3144,7 +3131,6 @@ export class Cline {
31443131
userContent.push({ type: "text", text: environmentDetails })
31453132

31463133
await this.addToApiConversationHistory({ role: "user", content: userContent })
3147-
telemetryService.captureConversationMessage(this.taskId, "user")
31483134

31493135
// since we sent off a placeholder api_req_started message to update the webview while waiting to actually start the API request (to load potential details for example), we need to update the text of that message
31503136
const lastApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started")
@@ -3346,7 +3332,6 @@ export class Cline {
33463332
role: "assistant",
33473333
content: [{ type: "text", text: assistantMessage }],
33483334
})
3349-
telemetryService.captureConversationMessage(this.taskId, "assistant")
33503335

33513336
// NOTE: this comment is here for future reference - this was a workaround for userMessageContent not getting set to true. It was due to it not recursively calling for partial blocks when didRejectTool, so it would get stuck waiting for a partial block to complete before it could continue.
33523337
// in case the content blocks finished
@@ -3798,8 +3783,6 @@ export class Cline {
37983783
return
37993784
}
38003785

3801-
telemetryService.captureCheckpointDiffed(this.taskId)
3802-
38033786
if (!previousCommitHash && mode === "checkpoint") {
38043787
const previousCheckpoint = this.clineMessages
38053788
.filter(({ say }) => say === "checkpoint_saved")
@@ -3851,8 +3834,6 @@ export class Cline {
38513834
return
38523835
}
38533836

3854-
telemetryService.captureCheckpointCreated(this.taskId)
3855-
38563837
// Start the checkpoint process in the background.
38573838
service.saveCheckpoint(`Task: ${this.taskId}, Time: ${Date.now()}`).catch((err) => {
38583839
console.error("[Cline#checkpointSave] caught unexpected error, disabling checkpoints", err)
@@ -3884,8 +3865,6 @@ export class Cline {
38843865
try {
38853866
await service.restoreCheckpoint(commitHash)
38863867

3887-
telemetryService.captureCheckpointRestored(this.taskId)
3888-
38893868
await this.providerRef.deref()?.postMessageToWebview({ type: "currentCheckpointUpdated", text: commitHash })
38903869

38913870
if (mode === "restore") {

src/core/webview/ClineProvider.ts

Lines changed: 1 addition & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ import { Cline, ClineOptions } from "../Cline"
5353
import { openMention } from "../mentions"
5454
import { getNonce } from "./getNonce"
5555
import { getUri } from "./getUri"
56-
import { telemetryService } from "../../services/telemetry/TelemetryService"
57-
import { TelemetrySetting } from "../../shared/TelemetrySetting"
5856

5957
/**
6058
* https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts
@@ -85,9 +83,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
8583
this.contextProxy = new ContextProxy(context)
8684
ClineProvider.activeInstances.add(this)
8785

88-
// Register this provider with the telemetry service to enable it to add properties like mode and provider
89-
telemetryService.setProvider(this)
90-
9186
this.workspaceTracker = new WorkspaceTracker(this)
9287
this.configManager = new ConfigManager(this.context)
9388
this.customModesManager = new CustomModesManager(this.context, async () => {
@@ -931,13 +926,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
931926
),
932927
)
933928

934-
// If user already opted in to telemetry, enable telemetry service
935-
this.getStateToPostToWebview().then((state) => {
936-
const { telemetrySetting } = state
937-
const isOptedIn = telemetrySetting === "enabled"
938-
telemetryService.updateTelemetryState(isOptedIn)
939-
})
940-
941929
this.isViewLaunched = true
942930
break
943931
case "newTask":
@@ -1799,15 +1787,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
17991787
})
18001788
}
18011789
break
1802-
1803-
case "telemetrySetting": {
1804-
const telemetrySetting = message.text as TelemetrySetting
1805-
await this.updateGlobalState("telemetrySetting", telemetrySetting)
1806-
const isOptedIn = telemetrySetting === "enabled"
1807-
telemetryService.updateTelemetryState(isOptedIn)
1808-
await this.postStateToWebview()
1809-
break
1810-
}
18111790
}
18121791
},
18131792
null,
@@ -1867,12 +1846,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
18671846
* @param newMode The mode to switch to
18681847
*/
18691848
public async handleModeSwitch(newMode: Mode) {
1870-
// Capture mode switch telemetry event
1871-
const currentTaskId = this.getCurrentCline()?.taskId
1872-
if (currentTaskId) {
1873-
telemetryService.captureModeSwitch(currentTaskId, newMode)
1874-
}
1875-
18761849
await this.updateGlobalState("mode", newMode)
18771850

18781851
// Load the saved API config for the new mode if it exists
@@ -2211,10 +2184,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
22112184
experiments,
22122185
maxOpenTabsContext,
22132186
browserToolEnabled,
2214-
telemetrySetting,
22152187
showRooIgnoredFiles,
22162188
} = await this.getState()
2217-
const telemetryKey = process.env.POSTHOG_API_KEY
22182189
const machineId = vscode.env.machineId
22192190

22202191
const allowedCommands = vscode.workspace.getConfiguration("roo-cline").get<string[]>("allowedCommands") || []
@@ -2244,8 +2215,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
22442215
diffEnabled: diffEnabled ?? true,
22452216
enableCheckpoints: enableCheckpoints ?? true,
22462217
checkpointStorage: checkpointStorage ?? "task",
2247-
shouldShowAnnouncement:
2248-
telemetrySetting !== "unset" && lastShownAnnouncementId !== this.latestAnnouncementId,
2218+
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
22492219
allowedCommands,
22502220
soundVolume: soundVolume ?? 0.5,
22512221
browserViewportSize: browserViewportSize ?? "900x600",
@@ -2272,8 +2242,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
22722242
maxOpenTabsContext: maxOpenTabsContext ?? 20,
22732243
cwd,
22742244
browserToolEnabled: browserToolEnabled ?? true,
2275-
telemetrySetting,
2276-
telemetryKey,
22772245
machineId,
22782246
showRooIgnoredFiles: showRooIgnoredFiles ?? true,
22792247
}
@@ -2455,7 +2423,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
24552423
maxOpenTabsContext: stateValues.maxOpenTabsContext ?? 20,
24562424
openRouterUseMiddleOutTransform: stateValues.openRouterUseMiddleOutTransform ?? true,
24572425
browserToolEnabled: stateValues.browserToolEnabled ?? true,
2458-
telemetrySetting: stateValues.telemetrySetting || "unset",
24592426
showRooIgnoredFiles: stateValues.showRooIgnoredFiles ?? true,
24602427
}
24612428
}
@@ -2535,47 +2502,4 @@ export class ClineProvider implements vscode.WebviewViewProvider {
25352502
public getMcpHub(): McpHub | undefined {
25362503
return this.mcpHub
25372504
}
2538-
2539-
/**
2540-
* Returns properties to be included in every telemetry event
2541-
* This method is called by the telemetry service to get context information
2542-
* like the current mode, API provider, etc.
2543-
*/
2544-
public async getTelemetryProperties(): Promise<Record<string, any>> {
2545-
const { mode, apiConfiguration } = await this.getState()
2546-
const appVersion = this.context.extension?.packageJSON?.version
2547-
const vscodeVersion = vscode.version
2548-
const platform = process.platform
2549-
2550-
const properties: Record<string, any> = {
2551-
vscodeVersion,
2552-
platform,
2553-
}
2554-
2555-
// Add extension version
2556-
if (appVersion) {
2557-
properties.appVersion = appVersion
2558-
}
2559-
2560-
// Add current mode
2561-
if (mode) {
2562-
properties.mode = mode
2563-
}
2564-
2565-
// Add API provider
2566-
if (apiConfiguration?.apiProvider) {
2567-
properties.apiProvider = apiConfiguration.apiProvider
2568-
}
2569-
2570-
// Add model ID if available
2571-
const currentCline = this.getCurrentCline()
2572-
if (currentCline?.api) {
2573-
const { id: modelId } = currentCline.api.getModel()
2574-
if (modelId) {
2575-
properties.modelId = modelId
2576-
}
2577-
}
2578-
2579-
return properties
2580-
}
25812505
}

src/core/webview/__tests__/ClineProvider.test.ts

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,6 @@ describe("ClineProvider", () => {
444444
experiments: experimentDefault,
445445
maxOpenTabsContext: 20,
446446
browserToolEnabled: true,
447-
telemetrySetting: "unset",
448447
showRooIgnoredFiles: true,
449448
}
450449

@@ -1652,62 +1651,3 @@ describe("ContextProxy integration", () => {
16521651
expect(mockContextProxy.setValues).toBeDefined()
16531652
})
16541653
})
1655-
1656-
describe("getTelemetryProperties", () => {
1657-
let provider: ClineProvider
1658-
let mockContext: vscode.ExtensionContext
1659-
let mockOutputChannel: vscode.OutputChannel
1660-
let mockCline: any
1661-
1662-
beforeEach(() => {
1663-
// Reset mocks
1664-
jest.clearAllMocks()
1665-
1666-
// Setup basic mocks
1667-
mockContext = {
1668-
globalState: {
1669-
get: jest.fn().mockImplementation((key: string) => {
1670-
if (key === "mode") return "code"
1671-
if (key === "apiProvider") return "anthropic"
1672-
return undefined
1673-
}),
1674-
update: jest.fn(),
1675-
keys: jest.fn().mockReturnValue([]),
1676-
},
1677-
secrets: { get: jest.fn(), store: jest.fn(), delete: jest.fn() },
1678-
extensionUri: {} as vscode.Uri,
1679-
globalStorageUri: { fsPath: "/test/path" },
1680-
extension: { packageJSON: { version: "1.0.0" } },
1681-
} as unknown as vscode.ExtensionContext
1682-
1683-
mockOutputChannel = { appendLine: jest.fn() } as unknown as vscode.OutputChannel
1684-
provider = new ClineProvider(mockContext, mockOutputChannel)
1685-
1686-
// Setup Cline instance with mocked getModel method
1687-
const { Cline } = require("../../Cline")
1688-
mockCline = new Cline()
1689-
mockCline.api = {
1690-
getModel: jest.fn().mockReturnValue({
1691-
id: "claude-3-7-sonnet-20250219",
1692-
info: { contextWindow: 200000 },
1693-
}),
1694-
}
1695-
})
1696-
1697-
test("includes basic properties in telemetry", async () => {
1698-
const properties = await provider.getTelemetryProperties()
1699-
1700-
expect(properties).toHaveProperty("vscodeVersion")
1701-
expect(properties).toHaveProperty("platform")
1702-
expect(properties).toHaveProperty("appVersion", "1.0.0")
1703-
})
1704-
1705-
test("includes model ID from current Cline instance if available", async () => {
1706-
// Add mock Cline to stack
1707-
await provider.addClineToStack(mockCline)
1708-
1709-
const properties = await provider.getTelemetryProperties()
1710-
1711-
expect(properties).toHaveProperty("modelId", "claude-3-7-sonnet-20250219")
1712-
})
1713-
})

src/extension.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { CodeActionProvider } from "./core/CodeActionProvider"
1818
import { DIFF_VIEW_URI_SCHEME } from "./integrations/editor/DiffViewProvider"
1919
import { handleUri, registerCommands, registerCodeActions } from "./activate"
2020
import { McpServerManager } from "./services/mcp/McpServerManager"
21-
import { telemetryService } from "./services/telemetry/TelemetryService"
2221

2322
/**
2423
* Built using https://github.com/microsoft/vscode-webview-ui-toolkit
@@ -51,9 +50,6 @@ export function activate(context: vscode.ExtensionContext) {
5150
context.subscriptions.push(outputChannel)
5251
outputChannel.appendLine("Roo-Code extension activated")
5352

54-
// Initialize telemetry service after environment variables are loaded
55-
telemetryService.initialize()
56-
5753
// Get default commands from configuration.
5854
const defaultCommands = vscode.workspace.getConfiguration("roo-cline").get<string[]>("allowedCommands") || []
5955

@@ -62,7 +58,6 @@ export function activate(context: vscode.ExtensionContext) {
6258
context.globalState.update("allowedCommands", defaultCommands)
6359
}
6460
const sidebarProvider = new ClineProvider(context, outputChannel)
65-
telemetryService.setProvider(sidebarProvider)
6661

6762
context.subscriptions.push(
6863
vscode.window.registerWebviewViewProvider(ClineProvider.sideBarId, sidebarProvider, {
@@ -151,5 +146,4 @@ export async function deactivate() {
151146
outputChannel.appendLine("Roo-Code extension deactivated")
152147
// Clean up MCP server manager
153148
await McpServerManager.cleanup(extensionContext)
154-
telemetryService.shutdown()
155149
}

0 commit comments

Comments
 (0)