Skip to content

Commit f489b0b

Browse files
author
Bruno Bergher
committed
Adds telemetry for modes: mode created, mode modified, mode settings opened
1 parent 19ef6f2 commit f489b0b

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

packages/telemetry/src/TelemetryService.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,30 @@ export class TelemetryService {
152152
this.captureEvent(TelemetryEventName.CONSECUTIVE_MISTAKE_ERROR, { taskId })
153153
}
154154

155+
/**
156+
* Captures when the ModesView settings UI is shown
157+
*/
158+
public captureModesViewShown(): void {
159+
this.captureEvent(TelemetryEventName.MODE_SETTINGS_SHOWN)
160+
}
161+
162+
/**
163+
* Captures when a setting is changed in ModesView
164+
* @param settingName The name of the setting that was changed
165+
*/
166+
public captureModeSettingChanged(settingName: string): void {
167+
this.captureEvent(TelemetryEventName.MODE_SETTINGS_CHANGED, { settingName })
168+
}
169+
170+
/**
171+
* Captures when a user creates a new custom mode
172+
* @param modeSlug The slug of the custom mode
173+
* @param modeName The name of the custom mode
174+
*/
175+
public captureCustomModeCreated(modeSlug: string, modeName: string): void {
176+
this.captureEvent(TelemetryEventName.CUSTOM_MODE_CREATED, { modeSlug, modeName })
177+
}
178+
155179
/**
156180
* Captures a marketplace item installation event
157181
* @param itemId The unique identifier of the marketplace item

packages/types/src/telemetry.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ export enum TelemetryEventName {
3131
CHECKPOINT_RESTORED = "Checkpoint Restored",
3232
CHECKPOINT_DIFFED = "Checkpoint Diffed",
3333

34+
MODE_SETTINGS_SHOWN = "Mode Settings Shown",
35+
MODE_SETTINGS_CHANGED = "Mode Setting Changed",
36+
CUSTOM_MODE_CREATED = "Custom Mode Created",
37+
3438
CONTEXT_CONDENSED = "Context Condensed",
3539
SLIDING_WINDOW_TRUNCATION = "Sliding Window Truncation",
3640

@@ -119,6 +123,9 @@ export const rooCodeTelemetryEventSchema = z.discriminatedUnion("type", [
119123
TelemetryEventName.CONSECUTIVE_MISTAKE_ERROR,
120124
TelemetryEventName.CONTEXT_CONDENSED,
121125
TelemetryEventName.SLIDING_WINDOW_TRUNCATION,
126+
TelemetryEventName.MODE_SETTINGS_SHOWN,
127+
TelemetryEventName.MODE_SETTINGS_CHANGED,
128+
TelemetryEventName.CUSTOM_MODE_CREATED,
122129
]),
123130
properties: telemetryPropertiesSchema,
124131
}),

src/core/webview/webviewMessageHandler.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,21 @@ export const webviewMessageHandler = async (
862862
hasOpenedModeSelector: currentState.hasOpenedModeSelector ?? false,
863863
}
864864
provider.postMessageToWebview({ type: "state", state: stateWithPrompts })
865+
866+
if (TelemetryService.hasInstance()) {
867+
// Determine which setting was changed by comparing objects
868+
const oldPrompt = existingPrompts[message.promptMode] || {}
869+
const newPrompt = message.customPrompt
870+
const changedSettings = Object.keys(newPrompt).filter(
871+
(key) =>
872+
JSON.stringify((oldPrompt as Record<string, unknown>)[key]) !==
873+
JSON.stringify((newPrompt as Record<string, unknown>)[key]),
874+
)
875+
876+
if (changedSettings.length > 0) {
877+
TelemetryService.instance.captureModeSettingChanged(changedSettings[0])
878+
}
879+
}
865880
}
866881
break
867882
case "deleteMessage": {
@@ -1326,12 +1341,41 @@ export const webviewMessageHandler = async (
13261341
break
13271342
case "updateCustomMode":
13281343
if (message.modeConfig) {
1344+
// Check if this is a new mode or an update to an existing mode
1345+
const existingModes = await provider.customModesManager.getCustomModes()
1346+
const isNewMode = !existingModes.some((mode) => mode.slug === message.modeConfig?.slug)
1347+
13291348
await provider.customModesManager.updateCustomMode(message.modeConfig.slug, message.modeConfig)
13301349
// Update state after saving the mode
13311350
const customModes = await provider.customModesManager.getCustomModes()
13321351
await updateGlobalState("customModes", customModes)
13331352
await updateGlobalState("mode", message.modeConfig.slug)
13341353
await provider.postStateToWebview()
1354+
1355+
// Track telemetry for custom mode creation or update
1356+
if (TelemetryService.hasInstance()) {
1357+
if (isNewMode) {
1358+
// This is a new custom mode
1359+
TelemetryService.instance.captureCustomModeCreated(
1360+
message.modeConfig.slug,
1361+
message.modeConfig.name,
1362+
)
1363+
} else {
1364+
// Determine which setting was changed by comparing objects
1365+
const existingMode = existingModes.find((mode) => mode.slug === message.modeConfig?.slug)
1366+
const changedSettings = existingMode
1367+
? Object.keys(message.modeConfig).filter(
1368+
(key) =>
1369+
JSON.stringify((existingMode as Record<string, unknown>)[key]) !==
1370+
JSON.stringify((message.modeConfig as Record<string, unknown>)[key]),
1371+
)
1372+
: []
1373+
1374+
if (changedSettings.length > 0) {
1375+
TelemetryService.instance.captureModeSettingChanged(changedSettings[0])
1376+
}
1377+
}
1378+
}
13351379
}
13361380
break
13371381
case "deleteCustomMode":
@@ -1510,6 +1554,7 @@ export const webviewMessageHandler = async (
15101554
)
15111555
await provider.postStateToWebview()
15121556
console.log(`Marketplace item installed and config file opened: ${configFilePath}`)
1557+
15131558
// Send success message to webview
15141559
provider.postMessageToWebview({
15151560
type: "marketplaceInstallResult",
@@ -1562,7 +1607,11 @@ export const webviewMessageHandler = async (
15621607

15631608
case "switchTab": {
15641609
if (message.tab) {
1565-
// Send a message to the webview to switch to the specified tab
1610+
// This could be more generic, but keeping it specific for now
1611+
if (message.tab === "modes" && TelemetryService.hasInstance()) {
1612+
TelemetryService.instance.captureModesViewShown()
1613+
}
1614+
15661615
await provider.postMessageToWebview({ type: "action", action: "switchTab", tab: message.tab })
15671616
}
15681617
break

webview-ui/src/components/modes/ModesView.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ const ModesView = ({ onDone }: ModesViewProps) => {
125125

126126
const updateCustomMode = useCallback((slug: string, modeConfig: ModeConfig) => {
127127
const source = modeConfig.source || "global"
128+
128129
vscode.postMessage({
129130
type: "updateCustomMode",
130131
slug,
@@ -269,6 +270,7 @@ const ModesView = ({ onDone }: ModesViewProps) => {
269270
const newMode: ModeConfig = {
270271
slug: newModeSlug,
271272
name: newModeName,
273+
description: newModeDescription.trim() || undefined,
272274
roleDefinition: newModeRoleDefinition.trim(),
273275
whenToUse: newModeWhenToUse.trim() || undefined,
274276
customInstructions: newModeCustomInstructions.trim() || undefined,
@@ -314,6 +316,7 @@ const ModesView = ({ onDone }: ModesViewProps) => {
314316
}, [
315317
newModeName,
316318
newModeSlug,
319+
newModeDescription,
317320
newModeRoleDefinition,
318321
newModeWhenToUse, // Add whenToUse dependency
319322
newModeCustomInstructions,
@@ -361,6 +364,7 @@ const ModesView = ({ onDone }: ModesViewProps) => {
361364
}
362365
if (customMode) {
363366
const source = customMode.source || "global"
367+
364368
updateCustomMode(customMode.slug, {
365369
...customMode,
366370
groups: newGroups,

0 commit comments

Comments
 (0)