Skip to content

Commit e5d616b

Browse files
committed
add optional telemetry (RooCodeInc#1939)
* add optional telemetry * move capture * add changeset * implement suggestions
1 parent 5d8172a commit e5d616b

File tree

12 files changed

+122
-14
lines changed

12 files changed

+122
-14
lines changed

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@
294294
"os-name": "^6.0.0",
295295
"p-wait-for": "^5.0.2",
296296
"pdf-parse": "^1.1.1",
297-
"posthog-node": "^4.7.0",
297+
"posthog-node": "^4.8.1",
298298
"puppeteer-chromium-resolver": "^23.0.0",
299299
"puppeteer-core": "^23.4.0",
300300
"serialize-error": "^11.0.3",

src/core/Cline.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import { addUserInstructions, SYSTEM_PROMPT } from "./prompts/system"
6060
import { getNextTruncationRange, getTruncatedMessages } from "./sliding-window"
6161
import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider"
6262
import { DEFAULT_LANGUAGE_SETTINGS, getLanguageKey, LanguageDisplay, LanguageKey } from "../shared/Languages"
63+
import { telemetryService } from "../services/telemetry/TelemetryService"
6364

6465
const cwd = 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
6566

@@ -153,6 +154,16 @@ export class Cline {
153154
} else {
154155
throw new Error("Either historyItem or task/images must be provided")
155156
}
157+
// capture start of thread with the state at the beginning
158+
telemetryService.capture({
159+
event: "cline created",
160+
properties: {
161+
taskId: this.taskId,
162+
isHistory: !!historyItem,
163+
chatMode: this.chatSettings.mode,
164+
hasImages: !!images,
165+
},
166+
})
156167
}
157168

158169
updateBrowserSettings(browserSettings: BrowserSettings) {
@@ -3284,6 +3295,14 @@ export class Cline {
32843295
this.consecutiveMistakeCount++
32853296
}
32863297

3298+
telemetryService.capture({
3299+
event: "message sent",
3300+
properties: {
3301+
taskId: this.taskId,
3302+
chatMode: this.chatSettings.mode,
3303+
},
3304+
})
3305+
32873306
const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent)
32883307
didEndLoop = recDidEndLoop
32893308
} else {

src/core/webview/ClineProvider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
387387
<meta charset="utf-8">
388388
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
389389
<meta name="theme-color" content="#000000">
390-
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; font-src ${webview.cspSource}; style-src ${webview.cspSource} 'unsafe-inline'; img-src ${webview.cspSource} https: data:; script-src 'nonce-${nonce}';">
391390
<link rel="stylesheet" type="text/css" href="${stylesUri}">
392391
<link href="${codiconsUri}" rel="stylesheet" />
392+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; connect-src https://*.posthog.com; font-src ${webview.cspSource}; style-src ${webview.cspSource} 'unsafe-inline'; img-src ${webview.cspSource} https: data:; script-src 'nonce-${nonce}' https://*.posthog.com;">
393393
<title>Cline</title>
394394
</head>
395395
<body>
@@ -1745,6 +1745,7 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
17451745
userInfo,
17461746
mcpMarketplaceEnabled,
17471747
telemetrySetting,
1748+
vscMachineId: vscode.env.machineId,
17481749
}
17491750
}
17501751

src/services/telemetry/TelemetryService.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ class PostHogClient {
2626
this.telemetryEnabled = didUserOptIn
2727
}
2828

29-
// Update PostHog client state based on telemetry preference
29+
// Update PostHog client state based on telemetry preference and use machineId to tie it to the webview
3030
if (this.telemetryEnabled) {
3131
this.client.optIn()
32+
this.client.identify({ distinctId: this.distinctId })
3233
// console.log("Telemetry enabled")
3334
} else {
3435
this.client.optOut()

src/shared/ExtensionMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export interface ExtensionState {
9595
}
9696
mcpMarketplaceEnabled?: boolean
9797
telemetrySetting: TelemetrySetting
98+
vscMachineId: string
9899
}
99100

100101
export interface ClineMessage {

webview-ui/package-lock.json

Lines changed: 69 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"fuse.js": "^7.0.0",
2222
"fzf": "^0.5.2",
2323
"mermaid": "^11.4.1",
24+
"posthog-js": "^1.224.0",
2425
"pretty-bytes": "^6.1.1",
2526
"react": "^18.3.1",
2627
"react-dom": "^18.3.1",

webview-ui/src/App.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import AccountView from "./components/account/AccountView"
99
import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext"
1010
import { vscode } from "./utils/vscode"
1111
import McpView from "./components/mcp/McpView"
12+
import posthog from "posthog-js"
1213

1314
const AppContent = () => {
14-
const { didHydrateState, showWelcome, shouldShowAnnouncement } = useExtensionState()
15+
const { didHydrateState, showWelcome, shouldShowAnnouncement, telemetrySetting, vscMachineId } = useExtensionState()
1516
const [showSettings, setShowSettings] = useState(false)
1617
const [showHistory, setShowHistory] = useState(false)
1718
const [showMcp, setShowMcp] = useState(false)
@@ -60,6 +61,15 @@ const AppContent = () => {
6061

6162
useEvent("message", handleMessage)
6263

64+
useEffect(() => {
65+
if (telemetrySetting === "enabled") {
66+
posthog.identify(vscMachineId)
67+
posthog.opt_in_capturing()
68+
} else {
69+
posthog.opt_out_capturing()
70+
}
71+
}, [telemetrySetting, vscMachineId])
72+
6373
useEffect(() => {
6474
if (shouldShowAnnouncement) {
6575
setShowAnnouncement(true)

webview-ui/src/components/chat/ChatView.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
1+
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
22
import debounce from "debounce"
33
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
44
import { useDeepCompareEffect, useEvent, useMount } from "react-use"
@@ -793,6 +793,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
793793
{telemetrySetting === "unset" && <TelemetryBanner />}
794794

795795
{showAnnouncement && <Announcement version={version} hideAnnouncement={hideAnnouncement} />}
796+
796797
<div style={{ padding: "0 20px", flexShrink: 0 }}>
797798
<h2>What can I do for you?</h2>
798799
<p>

0 commit comments

Comments
 (0)