diff --git a/apps/vscode/src/core/controller/ui/initializeWebview.ts b/apps/vscode/src/core/controller/ui/initializeWebview.ts index f095f29f90..7fd665f3f3 100644 --- a/apps/vscode/src/core/controller/ui/initializeWebview.ts +++ b/apps/vscode/src/core/controller/ui/initializeWebview.ts @@ -20,6 +20,11 @@ import { refreshOpenRouterModels } from "../models/refreshOpenRouterModels" */ export async function initializeWebview(controller: Controller, _request: EmptyRequest): Promise { try { + // The webview calls this once on mount, on every host. The VS Code-only + // "sidebar_resolved"/"sidebar_visible" sources never fire for JetBrains, so + // this is the only host-neutral signal that the Cline UI actually rendered. + telemetryService.capturePanelOpened("webview_initialized") + // Sync workflow toggles with the files on disk so the chat input's slash // command menu knows about workflows without requiring the user to open // the Workflows modal first (which is the only other place that refreshes diff --git a/apps/vscode/src/services/telemetry/TelemetryService.ts b/apps/vscode/src/services/telemetry/TelemetryService.ts index 21d51738df..222416a4f7 100644 --- a/apps/vscode/src/services/telemetry/TelemetryService.ts +++ b/apps/vscode/src/services/telemetry/TelemetryService.ts @@ -92,6 +92,13 @@ export enum TerminalHangStage { BUFFER_STUCK = "buffer_stuck", } +/** + * Which hook fired `ui.panel_opened`. "sidebar_resolved" / "sidebar_visible" come from + * VscodeWebviewProvider and are VS Code-only; "webview_initialized" comes from the webview's + * mount-time initializeWebview RPC and fires on every host. + */ +export type PanelOpenedSource = "sidebar_resolved" | "sidebar_visible" | "webview_initialized" + export type TelemetryMetadata = { /** * The extension or cline-core version. JetBrains and CLI have different @@ -328,7 +335,9 @@ export class TelemetryService { MODEL_FAVORITE_TOGGLED: "ui.model_favorite_toggled", // Tracks when a button is clicked BUTTON_CLICKED: "ui.button_clicked", - // Tracks when the Cline panel becomes visible + // Tracks when the Cline panel becomes visible; `source` (PanelOpenedSource) says + // which hook fired. On JetBrains "webview_initialized" also fires on every webview + // reload, e.g. after a core restart, so a crash-restart loop emits one per restart. PANEL_OPENED: "ui.panel_opened", // Tracks when the user explicitly starts a new task flow NEW_TASK_CLICKED: "ui.new_task_clicked", @@ -944,7 +953,7 @@ export class TelemetryService { }) } - public capturePanelOpened(source?: string) { + public capturePanelOpened(source: PanelOpenedSource) { this.capture({ event: TelemetryService.EVENTS.UI.PANEL_OPENED, properties: { source },