mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
177 lines
5.3 KiB
TypeScript
177 lines
5.3 KiB
TypeScript
import { ZodError } from "zod"
|
|
|
|
import { logger } from "../../utils/logging"
|
|
import { PostHogClient, ClineProviderInterface } from "./PostHogClient"
|
|
|
|
/**
|
|
* TelemetryService wrapper class that defers PostHogClient initialization
|
|
* This ensures that we only create the PostHogClient after environment variables are loaded
|
|
*/
|
|
class TelemetryService {
|
|
private client: PostHogClient | null = null
|
|
private initialized = false
|
|
|
|
/**
|
|
* Initialize the telemetry service with the PostHog client
|
|
* This should be called after environment variables are loaded
|
|
*/
|
|
public initialize(): void {
|
|
if (this.initialized) {
|
|
return
|
|
}
|
|
|
|
try {
|
|
this.client = PostHogClient.getInstance()
|
|
this.initialized = true
|
|
} catch (error) {
|
|
console.warn("Failed to initialize telemetry service:", error)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the ClineProvider reference to use for global properties
|
|
* @param provider A ClineProvider instance to use
|
|
*/
|
|
public setProvider(provider: ClineProviderInterface): void {
|
|
// If client is initialized, pass the provider reference
|
|
if (this.isReady) {
|
|
this.client!.setProvider(provider)
|
|
}
|
|
|
|
logger.debug("TelemetryService: ClineProvider reference set")
|
|
}
|
|
|
|
/**
|
|
* Base method for all telemetry operations
|
|
* Checks if the service is initialized before performing any operation
|
|
* @returns Whether the service is ready to use
|
|
*/
|
|
private get isReady(): boolean {
|
|
return this.initialized && this.client !== null
|
|
}
|
|
|
|
/**
|
|
* Updates the telemetry state based on user preferences and VSCode settings
|
|
* @param didUserOptIn Whether the user has explicitly opted into telemetry
|
|
*/
|
|
public updateTelemetryState(didUserOptIn: boolean): void {
|
|
if (!this.isReady) {
|
|
return
|
|
}
|
|
|
|
this.client!.updateTelemetryState(didUserOptIn)
|
|
}
|
|
|
|
/**
|
|
* Captures a telemetry event if telemetry is enabled
|
|
* @param event The event to capture with its properties
|
|
*/
|
|
public capture(event: { event: string; properties?: any }): void {
|
|
if (!this.isReady) {
|
|
return
|
|
}
|
|
|
|
this.client!.capture(event)
|
|
}
|
|
|
|
/**
|
|
* Generic method to capture any type of event with specified properties
|
|
* @param eventName The event name to capture
|
|
* @param properties The event properties
|
|
*/
|
|
public captureEvent(eventName: string, properties?: any): void {
|
|
this.capture({ event: eventName, properties })
|
|
}
|
|
|
|
// Task events convenience methods
|
|
public captureTaskCreated(taskId: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.CREATED, { taskId })
|
|
}
|
|
|
|
public captureTaskRestarted(taskId: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.RESTARTED, { taskId })
|
|
}
|
|
|
|
public captureTaskCompleted(taskId: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.COMPLETED, { taskId })
|
|
}
|
|
|
|
public captureConversationMessage(taskId: string, source: "user" | "assistant"): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.CONVERSATION_MESSAGE, { taskId, source })
|
|
}
|
|
|
|
public captureModeSwitch(taskId: string, newMode: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.MODE_SWITCH, { taskId, newMode })
|
|
}
|
|
|
|
public captureToolUsage(taskId: string, tool: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.TOOL_USED, { taskId, tool })
|
|
}
|
|
|
|
public captureCheckpointCreated(taskId: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.CHECKPOINT_CREATED, { taskId })
|
|
}
|
|
|
|
public captureCheckpointDiffed(taskId: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.CHECKPOINT_DIFFED, { taskId })
|
|
}
|
|
|
|
public captureCheckpointRestored(taskId: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.CHECKPOINT_RESTORED, { taskId })
|
|
}
|
|
|
|
public captureCodeActionUsed(actionType: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.CODE_ACTION_USED, { actionType })
|
|
}
|
|
|
|
public capturePromptEnhanced(taskId?: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.TASK.PROMPT_ENHANCED, { ...(taskId && { taskId }) })
|
|
}
|
|
|
|
public captureSchemaValidationError({ schemaName, error }: { schemaName: string; error: ZodError }): void {
|
|
// https://zod.dev/ERROR_HANDLING?id=formatting-errors
|
|
this.captureEvent(PostHogClient.EVENTS.ERRORS.SCHEMA_VALIDATION_ERROR, { schemaName, error: error.format() })
|
|
}
|
|
|
|
public captureDiffApplicationError(taskId: string, consecutiveMistakeCount: number): void {
|
|
this.captureEvent(PostHogClient.EVENTS.ERRORS.DIFF_APPLICATION_ERROR, { taskId, consecutiveMistakeCount })
|
|
}
|
|
|
|
public captureShellIntegrationError(taskId: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.ERRORS.SHELL_INTEGRATION_ERROR, { taskId })
|
|
}
|
|
|
|
public captureConsecutiveMistakeError(taskId: string): void {
|
|
this.captureEvent(PostHogClient.EVENTS.ERRORS.CONSECUTIVE_MISTAKE_ERROR, { taskId })
|
|
}
|
|
|
|
/**
|
|
* Captures a title button click event
|
|
* @param button The button that was clicked
|
|
*/
|
|
public captureTitleButtonClicked(button: string): void {
|
|
this.captureEvent("Title Button Clicked", { button })
|
|
}
|
|
|
|
/**
|
|
* Checks if telemetry is currently enabled
|
|
* @returns Whether telemetry is enabled
|
|
*/
|
|
public isTelemetryEnabled(): boolean {
|
|
return this.isReady && this.client!.isTelemetryEnabled()
|
|
}
|
|
|
|
/**
|
|
* Shuts down the PostHog client
|
|
*/
|
|
public async shutdown(): Promise<void> {
|
|
if (!this.isReady) {
|
|
return
|
|
}
|
|
|
|
await this.client!.shutdown()
|
|
}
|
|
}
|
|
|
|
// Export a singleton instance of the telemetry service wrapper
|
|
export const telemetryService = new TelemetryService()
|