Skip to content

fix(telemetry): reduce PostHog event volume, fix consent dark pattern#835

Open
edelauna wants to merge 14 commits into
mainfrom
issue/830
Open

fix(telemetry): reduce PostHog event volume, fix consent dark pattern#835
edelauna wants to merge 14 commits into
mainfrom
issue/830

Conversation

@edelauna

@edelauna edelauna commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Related GitHub Issue

Closes: #830

Description

PostHog's Product Analytics quota was 2.7x over its free-tier limit (2.7M/1M events in the June 6 - July 6 cycle), driven mainly by a CODE_INDEX_ERROR retry-storm bug (309 people generating 254,786 events) and per-turn Conversation Message/Tool Used events. Separately, a telemetry gap analysis found the consent banner treated dismissal (and the default "unset" state) as opt-in rather than a real choice, and that the underlying default itself was undisclosed.

Volume reduction:

  • Circuit-breaker for CODE_INDEX_ERROR: sliding 10-minute window, trips after 50 occurrences, independent of any other telemetry the same install sends (so unrelated events can't mask or reset a burst).
  • Conversation Message/Tool Used are no longer emitted per-turn/per-tool-call. Instead, Task.messageCounts and Task.toolUsage are summarized into toolsUsed/messageCount on the Task Completed event. Tool usage is now recorded exactly once per attempt at a single central point (presentAssistantMessage), removing a double-count where several tool handlers also recorded success locally.
  • Task Completed now fires once per model-initiated attempt_completion call (tagged completionReason: "attempt_completion") rather than only when the user clicks Accept — a task the user declines, gives feedback on, or never explicitly accepts previously reported nothing at all. It also fires on a 30-minute idle timeout and on task/extension shutdown (completionReason: "idle"/"shutdown") so long-running or abandoned tasks aren't invisible either. Each installment reports only the delta since the previous one for that task (tracked separately from task.toolUsage/messageCounts, which stay full running totals for the public TaskCompleted API event and the UI), so summing a task's installments reconstructs its full counts without double-counting. Skips emission for stale replays of an already-completed subtask (revisiting it from history).
  • Model Cache Empty Response throttled to once per distinct provider+endpoint (matching the same compound cache-key identity the model cache itself uses) until a non-empty response is seen — including for auth-scoped providers (e.g. zoo-gateway), where the throttle now correctly re-arms after a later non-empty response even though those providers skip caching.

Consent / privacy:

  • Telemetry is opt-out by disclosed default: isTelemetryOptedIn() (packages/types) returns true unless the setting is explicitly "disabled". A fresh install ("unset") and an explicit "enabled" both capture telemetry; only an explicit Decline opts out. This replaces the previous ad hoc telemetrySetting !== "disabled" checks that were scattered across 5 call sites with a single source of truth, and keeps the default itself honestly disclosed in PRIVACY.md and the banner copy rather than silently opting users in via an ambiguous dismiss gesture.
  • Telemetry banner: the "×" is a neutral dismiss — it sends no message and leaves the setting "unset" (so the disclosed default stays in effect), and does not itself record a choice either way. Explicit Accept/Decline buttons let a user affirmatively opt in or out. Localized across all 18 supported locales.
  • Extension now reacts live to vscode.env.onDidChangeTelemetryEnabled, ANDing the current vscode.env.isTelemetryEnabled value into the gate so a live OS/editor-level telemetry-disable actually takes effect immediately, rather than only being caught on the next read of the deprecated telemetry.telemetryLevel setting.
  • TelemetryService.shutdown() is now properly awaited on deactivation, tracks in-flight capture()/captureException() promises and drains them before flushing/closing clients, and is wrapped so a shutdown failure can't skip terminal cleanup.
  • PRIVACY.md clarified: telemetry is enabled by default (opt-out, changeable in settings), and the "does not collect code or prompts" bullet now notes this applies to the PostHog path only — the separate Cloud task-sync pipeline does transmit task messages when enabled.
  • Tool usage is now recorded for analytics only after the tool name passes validation (or is bucketed under a static invalid_tool_call key for unrecognized/malformed calls), so a model-supplied name can never reach PostHog as an arbitrary toolsUsed property key.
  • webview-ui's PostHog client now explicitly disables autocapture, capture_pageview, and capture_pageleave on init, so the webview doesn't passively collect DOM interactions/navigation beyond the explicit events this PR already sends. (The src-side client uses posthog-node, the server SDK, which has no browser autocapture/session-recording/heatmap surface to begin with.)

Explicitly out of scope for this PR:

  • Hashing vscode.env.machineId — assessed and dropped; it's already a random per-install UUID, not a hostname/username-derived identifier, so hashing it would pseudonymize an already-non-identifying value while losing existing PostHog person continuity.
  • Error-tracking-specific fixes (redacting captureException payloads, potentially moving CODE_INDEX_ERROR from Product Analytics to Error Tracking) — Error Tracking was only 6% over quota vs. Product Analytics' 2.7x, so it wasn't the priority; flagged for a follow-up.

Test Procedure

  • pnpm check-types and pnpm lint clean across all packages.
  • Full test suite: 6753 tests in src, 1456 in webview-ui, 43 in @roo-code/telemetry, 238 in @roo-code/types — all passing. New/updated coverage includes:
    • the circuit breaker's sliding window and independence from unrelated events
    • tool usage recorded exactly once per attempt (no double-counting across handlers)
    • unrecognized/invalid tool calls bucketed under a static invalid_tool_call analytics key rather than the raw model-supplied name
    • per-endpoint empty-model throttling, including re-arming for auth-scoped providers after a non-empty response
    • the banner's Accept/Decline/neutral-dismiss behavior
    • isTelemetryOptedIn() opt-out-by-default semantics ("unset"/"enabled" both opted in, only "disabled" opts out) and the resulting opt-in/opt-out transition events
    • the live onDidChangeTelemetryEnabled listener honoring vscode.env.isTelemetryEnabled
    • shutdown draining/error-handling
    • Task Completed installment delta-tracking: first flush, second flush reporting only the new delta, no-op when nothing changed, idle-timer flush, shutdown flush, and skipping emission for a stale history replay of an already-completed subtask
  • Manual verification recommended: fresh profile shows the Accept/Decline banner with telemetry already active by default; "×" dismisses without recording a choice; Decline actually stops capture; a task whose model calls attempt_completion emits a Task Completed installment immediately regardless of whether the user accepts/declines/gives feedback, with correct (non-duplicated) toolsUsed/messageCount deltas and zero Conversation Message/Tool Used events.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Documentation Updates

  • No documentation updates are required.
  • Yes, documentation updates are required. PRIVACY.md updated to state telemetry is enabled by default (opt-out) and to clarify the Cloud task-sync pipeline's scope relative to PostHog telemetry.

Summary by CodeRabbit

  • New Features
    • Added explicit Accept/Decline actions to the telemetry banner (closing it no longer submits a choice).
    • Telemetry consent now reacts live to VS Code’s telemetry enable/disable toggle.
    • Task completion analytics now includes completion reason plus summarized tool usage and user/assistant message counts.
  • Bug Fixes
    • Reduced telemetry noise during error bursts with a per-event circuit breaker and safer shutdown draining.
    • Improved model-cache empty-response throttling and concurrent fetch coordination.
    • Hardened telemetry so invalid or model-supplied tool names are safely bucketed.
  • Documentation
    • Updated privacy and in-product telemetry text to clarify what is collected and what is not (and added a cloud task sync disclosure).

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

Telemetry is aggregated into task-completion installments with circuit breaking, pending-capture draining, and model-cache throttling. Consent handling now combines stored preferences with VS Code’s live telemetry state, while tool analytics use validated names and explicit invalid-tool bucketing.

Telemetry and task analytics

Layer / File(s) Summary
Telemetry delivery and contracts
packages/telemetry/src/*, packages/types/src/*
Adds event exclusions, circuit breaking, awaited shutdown, richer completion payloads, shared consent semantics, schema fields, and invalid_tool_call.
Task installments and validated tools
src/core/task/*, src/core/assistant-message/*, src/core/tools/*
Tracks message and tool deltas, flushes installments on lifecycle boundaries, prevents duplicate completion reports, and sanitizes model-controlled tool names.

Consent, model cache, and retry validation

Layer / File(s) Summary
Consent runtime and UI
src/extension.ts, src/core/webview/*, webview-ui/src/**/*
Combines stored consent with VS Code telemetry state, serializes setting updates, adds explicit banner actions, and updates localized copy.
Model-cache and Bedrock retry flows
src/api/providers/fetchers/*, apps/vscode-e2e/src/*
Deduplicates empty-response telemetry by scoped cache identity and validates preservation of the original prompt during retries.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Task
  participant TelemetryService
  participant TelemetryClient
  Task->>Task: accumulate message and tool deltas
  Task->>TelemetryService: flush TASK_COMPLETED installment
  TelemetryService->>TelemetryClient: capture task-completion properties
  Task->>TelemetryService: flush shutdown installment
  TelemetryService->>TelemetryClient: drain captures and shut down
Loading

Possibly related PRs

Suggested labels: awaiting-review

Suggested reviewers: taltas, navedmerchant, hannesrudolph

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Most objectives are met, but the requested machine-ID hashing is explicitly left out, so the PR does not fully satisfy #830. Implement salted hashing or a separate installation UUID for vscode.env.machineId, or update the issue scope if that work is deferred.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title succinctly captures the main telemetry work: reducing event volume and fixing consent behavior.
Description check ✅ Passed The PR includes the required issue link, summary, test procedure, checklist, and documentation updates sections.
Out of Scope Changes check ✅ Passed The changes align with the telemetry, consent, privacy, and aggregation goals and do not show clear unrelated additions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue/830

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown


expect(mockTask.diffViewProvider.saveChanges).toHaveBeenCalled()
expect(mockTask.didEditFile).toBe(true)
expect(mockTask.recordToolUsage).toHaveBeenCalledWith("edit_file")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed since we're no longer emitting per message, but rather as a summary once the task completes

@edelauna edelauna marked this pull request as ready for review July 12, 2026 12:56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
src/__tests__/extension.spec.ts (1)

324-328: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Clear onDidChangeTelemetryEnabled mock between tests to avoid stale handler references.

vi.resetModules() resets the module cache but does not clear vi.fn() call history. Since onDidChangeTelemetryEnabled is created once in the hoisted vi.mock("vscode", …) factory, its call history accumulates across tests. Tests at lines 357, 378, and 404 all retrieve mock.calls[0][0], which is always the handler registered by the first test — not the current test's own activate call. The tests pass today because the handler logic is identical and mock instances are shared, but this is fragile: removing or reordering the first test would silently break the others.

♻️ Proposed fix
 beforeEach(async () => {
 	vi.resetModules()
 	const vscode = await import("vscode")
 	;(vscode.env as any).isTelemetryEnabled = true
+	vi.mocked(vscode.env.onDidChangeTelemetryEnabled).mockClear()
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/extension.spec.ts` around lines 324 - 328, Update the
beforeEach setup in the extension tests to clear the shared
onDidChangeTelemetryEnabled mock, including its call history, after resetting
modules and before each test runs. Ensure tests retrieving mock.calls[0][0]
observe the handler registered by the current activate call rather than a prior
test.
src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts (1)

219-241: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Extend malicious-name coverage to the "mcp_" prefix case.

The chosen maliciousName doesn't start with "mcp_", so it doesn't exercise the isValidToolName prefix-heuristic bypass (see the corresponding comment in presentAssistantMessage.ts Lines 604-620). Consider adding a case where name is something like "mcp_'; DROP TABLE users; --" to lock in the expected fix once addressed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts`
around lines 219 - 241, Extend the test in “does not record raw model-supplied
tool names in tool usage analytics” to use a malicious tool name beginning with
“mcp_”, such as the existing injection payload with that prefix. Keep the
assertions covering both recordToolUsage and recordToolError so the
isValidToolName prefix-bypass path is exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/telemetry/src/TelemetryService.ts`:
- Around line 373-377: Update the pending-call drain in TelemetryService
shutdown to repeatedly await pendingClientCalls until the set is empty, ensuring
calls added during an in-flight drain are also completed before invoking
client.shutdown(). Keep the existing client shutdown flow unchanged after the
drain stabilizes.

In `@src/core/task/Task.ts`:
- Around line 2627-2636: The retry flow around shouldAddUserMessageToHistory and
the yesButtonClicked branch must keep user history and counts symmetric. When
removing the temporary user turn, decrement messageCounts.user, mark
userMessageWasRemoved true for the retry item, and ensure the retried request
restores the user message; add a regression test covering manual retry after an
empty-assistant response.

In `@src/core/webview/webviewMessageHandler.ts`:
- Around line 632-636: Update the telemetry state handling in webviewDidLaunch
and the telemetrySetting handler to also require vscode.env.isTelemetryEnabled,
matching the logic in extension.ts. Ensure either path cannot re-enable
telemetry when VS Code’s global telemetry toggle is disabled, while preserving
the existing telemetrySetting preference behavior.

In `@webview-ui/src/i18n/locales/hi/welcome.json`:
- Line 15: Update the helpImproveMessage translation in the Hindi welcome locale
to replace the incorrect term “दूरसंचार कोड” with “टेलीमेट्री” or “टेलीमेट्री
डेटा,” while preserving the surrounding meaning and settingsLink markup.

---

Nitpick comments:
In `@src/__tests__/extension.spec.ts`:
- Around line 324-328: Update the beforeEach setup in the extension tests to
clear the shared onDidChangeTelemetryEnabled mock, including its call history,
after resetting modules and before each test runs. Ensure tests retrieving
mock.calls[0][0] observe the handler registered by the current activate call
rather than a prior test.

In
`@src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts`:
- Around line 219-241: Extend the test in “does not record raw model-supplied
tool names in tool usage analytics” to use a malicious tool name beginning with
“mcp_”, such as the existing injection payload with that prefix. Keep the
assertions covering both recordToolUsage and recordToolError so the
isValidToolName prefix-bypass path is exercised.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fe02bd8b-7937-4172-aa49-30937b9de55a

📥 Commits

Reviewing files that changed from the base of the PR and between a441e02 and d430a18.

📒 Files selected for processing (62)
  • PRIVACY.md
  • packages/telemetry/src/PostHogTelemetryClient.ts
  • packages/telemetry/src/TelemetryService.ts
  • packages/telemetry/src/__tests__/PostHogTelemetryClient.test.ts
  • packages/telemetry/src/__tests__/TelemetryService.circuit-breaker.test.ts
  • packages/telemetry/src/__tests__/TelemetryService.shutdown.test.ts
  • packages/telemetry/src/__tests__/TelemetryService.task-completed.test.ts
  • packages/types/src/__tests__/telemetry.isTelemetryOptedIn.test.ts
  • packages/types/src/__tests__/telemetry.taskProperties.test.ts
  • packages/types/src/telemetry.ts
  • packages/types/src/tool.ts
  • src/__tests__/extension.spec.ts
  • src/__tests__/nested-delegation-resume.spec.ts
  • src/api/providers/fetchers/__tests__/modelCache.spec.ts
  • src/api/providers/fetchers/modelCache.ts
  • src/core/assistant-message/__tests__/presentAssistantMessage-custom-tool.spec.ts
  • src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts
  • src/core/assistant-message/presentAssistantMessage.ts
  • src/core/task/Task.ts
  • src/core/task/__tests__/Task.persistence.spec.ts
  • src/core/task/__tests__/Task.spec.ts
  • src/core/task/__tests__/messageCounting.spec.ts
  • src/core/task/messageCounting.ts
  • src/core/tools/ApplyPatchTool.ts
  • src/core/tools/AttemptCompletionTool.ts
  • src/core/tools/EditFileTool.ts
  • src/core/tools/EditTool.ts
  • src/core/tools/GenerateImageTool.ts
  • src/core/tools/SearchReplaceTool.ts
  • src/core/tools/__tests__/attemptCompletionTool.spec.ts
  • src/core/tools/__tests__/editFileTool.spec.ts
  • src/core/tools/__tests__/editTool.spec.ts
  • src/core/tools/__tests__/searchReplaceTool.spec.ts
  • src/core/webview/__tests__/telemetrySettingsTracking.spec.ts
  • src/core/webview/webviewMessageHandler.ts
  • src/extension.ts
  • src/shared/tools.ts
  • webview-ui/src/__tests__/TelemetryClient.spec.ts
  • webview-ui/src/components/chat/__tests__/ChatView.scroll-debug-repro.spec.tsx
  • webview-ui/src/components/common/TelemetryBanner.tsx
  • webview-ui/src/components/common/__tests__/TelemetryBanner.spec.tsx
  • webview-ui/src/components/settings/About.tsx
  • webview-ui/src/components/settings/__tests__/About.spec.tsx
  • webview-ui/src/i18n/locales/ca/welcome.json
  • webview-ui/src/i18n/locales/de/welcome.json
  • webview-ui/src/i18n/locales/en/welcome.json
  • webview-ui/src/i18n/locales/es/welcome.json
  • webview-ui/src/i18n/locales/fr/welcome.json
  • webview-ui/src/i18n/locales/hi/welcome.json
  • webview-ui/src/i18n/locales/id/welcome.json
  • webview-ui/src/i18n/locales/it/welcome.json
  • webview-ui/src/i18n/locales/ja/welcome.json
  • webview-ui/src/i18n/locales/ko/welcome.json
  • webview-ui/src/i18n/locales/nl/welcome.json
  • webview-ui/src/i18n/locales/pl/welcome.json
  • webview-ui/src/i18n/locales/pt-BR/welcome.json
  • webview-ui/src/i18n/locales/ru/welcome.json
  • webview-ui/src/i18n/locales/tr/welcome.json
  • webview-ui/src/i18n/locales/vi/welcome.json
  • webview-ui/src/i18n/locales/zh-CN/welcome.json
  • webview-ui/src/i18n/locales/zh-TW/welcome.json
  • webview-ui/src/utils/TelemetryClient.ts
💤 Files with no reviewable changes (6)
  • src/core/tools/tests/editTool.spec.ts
  • src/core/tools/tests/searchReplaceTool.spec.ts
  • src/core/tools/ApplyPatchTool.ts
  • src/core/tools/tests/editFileTool.spec.ts
  • src/core/tools/GenerateImageTool.ts
  • src/core/assistant-message/tests/presentAssistantMessage-custom-tool.spec.ts

Comment thread packages/telemetry/src/TelemetryService.ts
Comment thread src/core/task/Task.ts
Comment on lines +2627 to +2636
// See shouldAddUserMessageToHistory for the full add/skip rules (retry/empty/removed).
const isEmptyUserContent = currentUserContent.length === 0
const shouldAddUserMessage =
((currentItem.retryAttempt ?? 0) === 0 && !isEmptyUserContent) || currentItem.userMessageWasRemoved
const shouldAddUserMessage = shouldAddUserMessageToHistory({
retryAttempt: currentItem.retryAttempt,
isEmptyUserContent,
userMessageWasRemoved: currentItem.userMessageWasRemoved,
})
if (shouldAddUserMessage) {
await this.addToApiConversationHistory({ role: "user", content: finalUserContent })
TelemetryService.instance.captureConversationMessage(this.taskId, "user")
this.messageCounts.user++

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate relevant files and line ranges
printf '\n== Task.ts line map ==\n'
nl -ba src/core/task/Task.ts | sed -n '2608,2655p'
printf '\n== Task.ts retry handling around 3640-3715 ==\n'
nl -ba src/core/task/Task.ts | sed -n '3640,3715p'

printf '\n== Search for shouldAddUserMessageToHistory and userMessageWasRemoved ==\n'
rg -n "shouldAddUserMessageToHistory|userMessageWasRemoved|messageCounts\.user" src/core/task/Task.ts src -g '!**/dist/**' -g '!**/build/**'

printf '\n== Test files ==\n'
rg -n "messageCounting\.spec\.ts|Task\.spec\.ts|apiConversationHistory|messageCounts" src test . -g '*spec.ts' -g '*test.ts' -g '!**/dist/**' -g '!**/build/**'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 223


🏁 Script executed:

#!/bin/bash
set -euo pipefail

nl -ba src/core/task/Task.ts | sed -n '2608,2655p'
printf '\n---\n'
nl -ba src/core/task/Task.ts | sed -n '3640,3715p'
printf '\n---\n'
rg -n "shouldAddUserMessageToHistory|userMessageWasRemoved|messageCounts\\.user" src/core/task/Task.ts src -g '!**/dist/**' -g '!**/build/**'
printf '\n---\n'
rg -n "messageCounting\\.spec\\.ts|Task\\.spec\\.ts|apiConversationHistory|messageCounts" . -g '*spec.ts' -g '*test.ts' -g '!**/dist/**' -g '!**/build/**'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 199


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Print only the exact surrounding regions and the helper definition if present.
grep -n "function shouldAddUserMessageToHistory\|const shouldAddUserMessageToHistory\|userMessageWasRemoved" -n src/core/task/Task.ts || true
nl -ba src/core/task/Task.ts | sed -n '2588,2645p'
echo '---'
nl -ba src/core/task/Task.ts | sed -n '3638,3712p'
echo '---'
find . -name 'messageCounting.spec.ts' -o -name 'Task.spec.ts'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 406


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== helper and nearby logic =='
sed -n '2478,2510p' src/core/task/Task.ts

echo '== message add/pop/counter region =='
sed -n '2624,2642p' src/core/task/Task.ts

echo '== no-assistant-response pop region =='
sed -n '3648,3664p' src/core/task/Task.ts

echo '== retry pushes region =='
sed -n '3680,3712p' src/core/task/Task.ts

echo '== search for counter decrements =='
grep -n 'messageCounts\.user' src/core/task/Task.ts

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 4624


🏁 Script executed:

#!/bin/bash
set -euo pipefail

grep -n "function shouldAddUserMessageToHistory\|const shouldAddUserMessageToHistory\|shouldAddUserMessageToHistory =" -n src/core/task/Task.ts || true
sed -n '2510,2565p' src/core/task/Task.ts
echo '---'
sed -n '4690,4710p' src/core/task/Task.ts
echo '---'
grep -n "telemetryMessageCountsBaseline\|messageCounts =" -n src/core/task/Task.ts

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 3423


🏁 Script executed:

#!/bin/bash
set -euo pipefail

find . \( -name 'messageCounting.spec.ts' -o -name 'Task.spec.ts' \) -print
echo '---'
grep -R -n "no assistant messages\|api_req_failed\|userMessageWasRemoved\|messageCounts.user" . --include='*spec.ts' --include='*test.ts' | head -200

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 1397


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Narrow search for the helper definition if it is below the current section.
awk '
  /shouldAddUserMessageToHistory/ {print NR ":" $0}
' src/core/task/Task.ts

echo '--- helper vicinity ---'
sed -n '2565,2605p' src/core/task/Task.ts

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 1774


🏁 Script executed:

#!/bin/bash
set -euo pipefail

grep -R -n "shouldAddUserMessageToHistory" . --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 1877


🏁 Script executed:

#!/bin/bash
set -euo pipefail

grep -n "shouldAddUserMessageToHistory\|userMessageWasRemoved\|telemetryMessageCountsBaseline\|messageCounts.user" src/core/task/Task.ts
echo '--- helper vicinity ---'
sed -n '2518,2598p' src/core/task/Task.ts
echo '--- telemetry vicinity ---'
sed -n '4688,4710p' src/core/task/Task.ts

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 4787


🏁 Script executed:

#!/bin/bash
set -euo pipefail

find . \( -name 'messageCounting.spec.ts' -o -name 'Task.spec.ts' \) -print
echo '--- tests mentioning the retry flow ---'
grep -R -n "api_req_failed\|api_req_retried\|userMessageWasRemoved\|messageCounts.user\|no assistant messages" . --include='*spec.ts' --include='*test.ts' | head -200

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 1433


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== src/core/task/messageCounting.ts =='
sed -n '1,200p' src/core/task/messageCounting.ts

echo '== src/core/task/__tests__/messageCounting.spec.ts =='
sed -n '1,220p' src/core/task/__tests__/messageCounting.spec.ts

echo '== src/core/task/__tests__/Task.spec.ts (retry-related snippets) =='
grep -n "api_req_failed\|api_req_retried\|userMessageWasRemoved\|messageCounts.user\|shouldAddUserMessageToHistory" src/core/task/__tests__/Task.spec.ts

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 3154


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the Task.spec.ts sections around any retry/history tests.
grep -n "api_req_failed\|api_req_retried\|userMessageWasRemoved\|messageCounts.user\|shouldAddUserMessageToHistory" src/core/task/__tests__/Task.spec.ts | cut -d: -f1 | sort -n | uniq | while read -r line; do
  start=$((line-12))
  end=$((line+20))
  if [ "$start" -lt 1 ]; then start=1; fi
  sed -n "${start},${end}p" src/core/task/__tests__/Task.spec.ts
  echo '---'
done

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' src/core/task/messageCounting.ts
printf '\n---\n'
sed -n '1,220p' src/core/task/__tests__/messageCounting.spec.ts
printf '\n---\n'
grep -n "api_req_failed\|api_req_retried\|userMessageWasRemoved\|messageCounts.user\|shouldAddUserMessageToHistory" src/core/task/__tests__/Task.spec.ts

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 3003


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Focus only on the helper and the nearby Task tests if they exist.
sed -n '1,220p' src/core/task/messageCounting.ts
echo '---'
sed -n '1,220p' src/core/task/__tests__/messageCounting.spec.ts
echo '---'
grep -n "api_req_failed\|api_req_retried\|userMessageWasRemoved\|messageCounts.user\|shouldAddUserMessageToHistory" src/core/task/__tests__/Task.spec.ts || true

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 3001


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' src/core/task/messageCounting.ts
printf '\n---\n'
sed -n '1,220p' src/core/task/__tests__/messageCounting.spec.ts
printf '\n---\n'
grep -n "api_req_failed\|api_req_retried\|userMessageWasRemoved\|messageCounts.user\|shouldAddUserMessageToHistory" src/core/task/__tests__/Task.spec.ts || true

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 3003


Keep the empty-assistant retry path symmetric

  • Decrement messageCounts.user when the temporary user turn is popped, and set userMessageWasRemoved: true in the yesButtonClicked retry branch; otherwise the retried request skips restoring the user message and the counter drifts on each failed cycle.
  • Add a regression test for the manual retry path.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/task/Task.ts` around lines 2627 - 2636, The retry flow around
shouldAddUserMessageToHistory and the yesButtonClicked branch must keep user
history and counts symmetric. When removing the temporary user turn, decrement
messageCounts.user, mark userMessageWasRemoved true for the retry item, and
ensure the retried request restores the user message; add a regression test
covering manual retry after an empty-assistant response.

Comment thread src/core/webview/webviewMessageHandler.ts Outdated
Comment thread webview-ui/src/i18n/locales/hi/welcome.json Outdated
@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 12, 2026
@github-actions github-actions Bot added awaiting-review PR changes are ready and waiting for maintainer re-review and removed awaiting-review PR changes are ready and waiting for maintainer re-review labels Jul 12, 2026
@github-actions github-actions Bot added awaiting-review PR changes are ready and waiting for maintainer re-review and removed awaiting-review PR changes are ready and waiting for maintainer re-review labels Jul 12, 2026
@github-actions github-actions Bot removed the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/core/webview/webviewMessageHandler.ts (1)

641-651: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

webviewDidLaunch's telemetry update isn't serialized with telemetrySettingQueue, reopening the race the queue was built to fix.

This block reads telemetrySetting from an async getStateToPostToWebview() snapshot and applies it via TelemetryService.instance.updateTelemetryState(...) outside telemetrySettingQueue. If a concurrent "telemetrySetting" message is processed while this .then() is pending, this fire-and-forget continuation can resolve afterward with a stale value and clobber the queued (correct) update — the same interleaving class of bug the queue was added to prevent, just for webviewDidLaunch vs. telemetrySetting instead of telemetrySetting vs. telemetrySetting.

It's also redundant: provider.postStateToWebview() already computed full state at line 575; recomputing it here just to read one field is unnecessary when getGlobalState("telemetrySetting") (already used the same way in the telemetrySetting handler below) is synchronous.

🔒 Suggested fix: read state synchronously, removing the async gap
-			provider.getStateToPostToWebview().then((state) => {
-				const { telemetrySetting } = state
-				TelemetryService.instance.updateTelemetryState(
-					isTelemetryOptedIn(telemetrySetting) && vscode.env.isTelemetryEnabled,
-				)
-			})
+			const telemetrySetting = getGlobalState("telemetrySetting") || "unset"
+			TelemetryService.instance.updateTelemetryState(
+				isTelemetryOptedIn(telemetrySetting) && vscode.env.isTelemetryEnabled,
+			)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/webview/webviewMessageHandler.ts` around lines 641 - 651, Update the
webviewDidLaunch telemetry initialization to read telemetrySetting synchronously
via the existing getGlobalState path instead of awaiting
provider.getStateToPostToWebview(). Apply the value through the existing
telemetrySettingQueue so launch initialization is serialized with
telemetrySetting message handling, and remove the stale asynchronous
continuation while preserving the VS Code global telemetry check.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@webview-ui/src/i18n/locales/fr/settings.json`:
- Around line 966-967: Update the description value for the telemetry setting in
the French locale so its informal possessives use the formal forms “votre” and
“vos”, while preserving the existing formal wording and meaning.

In `@webview-ui/src/i18n/locales/hi/settings.json`:
- Line 967: Update the Hindi telemetry description string in the settings locale
to include the disclosure that telemetry can be disabled at any time, while
preserving the existing translation and privacy-policy link content.

In `@webview-ui/src/i18n/locales/it/settings.json`:
- Line 967: Update the Italian telemetry description in the settings locale to
state that telemetry can be disabled at any time, preserving the existing
privacy-link text and matching the equivalent disclosure used by other locales.

In `@webview-ui/src/i18n/locales/ja/settings.json`:
- Line 967: Update the Japanese telemetry description in the settings locale to
state that telemetry can be disabled at any time, while preserving the existing
explanation and privacyLink markup.

In `@webview-ui/src/i18n/locales/ko/settings.json`:
- Line 967: Update the Korean telemetry description value in the settings locale
to include that telemetry can be disabled at any time, while preserving the
existing installation-identifier, data-collection, code/prompt exclusion, and
privacy-link text.

In `@webview-ui/src/i18n/locales/tr/settings.json`:
- Line 966: Update the Turkish “label” value in the settings locale to use
grammatically correct telemetry wording, preferably “Hata ve kullanım
raporlamasına izin ver” or the equivalent approved alternative.

In `@webview-ui/src/i18n/locales/vi/settings.json`:
- Line 966: Update the Vietnamese telemetry label value near the settings
localization entry to clearly refer to both error reports and usage data, using
wording equivalent to “Cho phép báo cáo lỗi và dữ liệu sử dụng.”

In `@webview-ui/src/i18n/locales/zh-CN/settings.json`:
- Line 966: Update the Chinese settings label in the relevant permission entry
from “允许错误和使用情况报告” to “允许发送错误和使用情况报告”, preserving the existing key and
surrounding translations.

In `@webview-ui/src/i18n/locales/zh-TW/settings.json`:
- Line 994: Update the Traditional Chinese telemetry description in the settings
locale to include the equivalent disclosure that telemetry can be disabled at
any time, while preserving the existing translation and privacy-policy link.

---

Outside diff comments:
In `@src/core/webview/webviewMessageHandler.ts`:
- Around line 641-651: Update the webviewDidLaunch telemetry initialization to
read telemetrySetting synchronously via the existing getGlobalState path instead
of awaiting provider.getStateToPostToWebview(). Apply the value through the
existing telemetrySettingQueue so launch initialization is serialized with
telemetrySetting message handling, and remove the stale asynchronous
continuation while preserving the VS Code global telemetry check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 23f8bdfe-2bef-4513-837b-ce97a8f573a1

📥 Commits

Reviewing files that changed from the base of the PR and between cdaf9ae and ded1b6d.

📒 Files selected for processing (58)
  • PRIVACY.md
  • packages/telemetry/src/TelemetryService.ts
  • packages/telemetry/src/__tests__/TelemetryService.shutdown.test.ts
  • packages/types/src/vscode-extension-host.ts
  • src/__tests__/extension.spec.ts
  • src/api/providers/fetchers/__tests__/modelCache.spec.ts
  • src/api/providers/fetchers/modelCache.ts
  • src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts
  • src/core/assistant-message/__tests__/presentAssistantMessage-validation-error.spec.ts
  • src/core/assistant-message/__tests__/toTelemetryToolName.spec.ts
  • src/core/assistant-message/presentAssistantMessage.ts
  • src/core/task/Task.ts
  • src/core/task/__tests__/messageCounting.retrySymmetry.spec.ts
  • src/core/tools/AttemptCompletionTool.ts
  • src/core/tools/__tests__/attemptCompletionTool.spec.ts
  • src/core/webview/ClineProvider.ts
  • src/core/webview/__tests__/webviewMessageHandler.spec.ts
  • src/core/webview/webviewMessageHandler.ts
  • src/extension.ts
  • webview-ui/src/App.tsx
  • webview-ui/src/__tests__/TelemetryClient.spec.ts
  • webview-ui/src/i18n/locales/ca/settings.json
  • webview-ui/src/i18n/locales/ca/welcome.json
  • webview-ui/src/i18n/locales/de/settings.json
  • webview-ui/src/i18n/locales/de/welcome.json
  • webview-ui/src/i18n/locales/en/settings.json
  • webview-ui/src/i18n/locales/en/welcome.json
  • webview-ui/src/i18n/locales/es/settings.json
  • webview-ui/src/i18n/locales/es/welcome.json
  • webview-ui/src/i18n/locales/fr/settings.json
  • webview-ui/src/i18n/locales/fr/welcome.json
  • webview-ui/src/i18n/locales/hi/settings.json
  • webview-ui/src/i18n/locales/hi/welcome.json
  • webview-ui/src/i18n/locales/id/settings.json
  • webview-ui/src/i18n/locales/id/welcome.json
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/it/welcome.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/ja/welcome.json
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/i18n/locales/ko/welcome.json
  • webview-ui/src/i18n/locales/nl/settings.json
  • webview-ui/src/i18n/locales/nl/welcome.json
  • webview-ui/src/i18n/locales/pl/settings.json
  • webview-ui/src/i18n/locales/pl/welcome.json
  • webview-ui/src/i18n/locales/pt-BR/settings.json
  • webview-ui/src/i18n/locales/pt-BR/welcome.json
  • webview-ui/src/i18n/locales/ru/settings.json
  • webview-ui/src/i18n/locales/ru/welcome.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/tr/welcome.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/vi/welcome.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/zh-CN/welcome.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
  • webview-ui/src/i18n/locales/zh-TW/welcome.json
  • webview-ui/src/utils/TelemetryClient.ts
🚧 Files skipped from review as they are similar to previous changes (24)
  • webview-ui/src/i18n/locales/ca/welcome.json
  • webview-ui/src/i18n/locales/en/welcome.json
  • webview-ui/src/i18n/locales/ru/welcome.json
  • webview-ui/src/i18n/locales/id/welcome.json
  • webview-ui/src/i18n/locales/zh-CN/welcome.json
  • webview-ui/src/i18n/locales/zh-TW/welcome.json
  • webview-ui/src/i18n/locales/vi/welcome.json
  • webview-ui/src/i18n/locales/pt-BR/welcome.json
  • webview-ui/src/i18n/locales/nl/welcome.json
  • src/core/assistant-message/tests/presentAssistantMessage-unknown-tool.spec.ts
  • webview-ui/src/i18n/locales/tr/welcome.json
  • webview-ui/src/i18n/locales/fr/welcome.json
  • webview-ui/src/i18n/locales/pl/welcome.json
  • src/core/task/tests/messageCounting.retrySymmetry.spec.ts
  • src/extension.ts
  • webview-ui/src/i18n/locales/es/welcome.json
  • src/core/tools/AttemptCompletionTool.ts
  • webview-ui/src/i18n/locales/ko/welcome.json
  • src/tests/extension.spec.ts
  • webview-ui/src/i18n/locales/hi/welcome.json
  • packages/telemetry/src/TelemetryService.ts
  • src/core/assistant-message/presentAssistantMessage.ts
  • src/core/tools/tests/attemptCompletionTool.spec.ts
  • src/core/task/Task.ts

Comment thread webview-ui/src/i18n/locales/fr/settings.json Outdated
"label": "गुमनाम त्रुटि और उपयोग रिपोर्टिंग की अनुमति दें",
"description": "गुमनाम उपयोग डेटा और त्रुटि रिपोर्ट भेजकर Zoo Code को बेहतर बनाने में मदद करें। यह टेलीमेट्री कोड, प्रॉम्प्ट या व्यक्तिगत जानकारी एकत्र नहीं करती। अधिक विवरण के लिए हमारी <privacyLink>गोपनीयता नीति</privacyLink> देखें। आप इसे कभी भी बंद कर सकते हैं।"
"label": "त्रुटि और उपयोग रिपोर्टिंग की अनुमति दें",
"description": "आपके नाम या खाते के बजाय एक इंस्टॉल-लिंक्ड पहचानकर्ता से जुड़े उपयोग डेटा और त्रुटि रिपोर्ट भेजकर Zoo Code को बेहतर बनाने में मदद करें। यह टेलीमेट्री आपका कोड या प्रॉम्प्ट एकत्र नहीं करती। अधिक विवरण के लिए हमारी <privacyLink>गोपनीयता नीति</privacyLink> देखें। आप इसे कभी भी बंद कर सकते हैं।"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Restore the opt-out disclosure.

This Hindi description omits that telemetry can be disabled at any time, unlike the settings behavior and peer locale strings. Add the equivalent sentence to keep consent messaging complete.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/i18n/locales/hi/settings.json` at line 967, Update the Hindi
telemetry description string in the settings locale to include the disclosure
that telemetry can be disabled at any time, while preserving the existing
translation and privacy-policy link content.

Comment thread webview-ui/src/i18n/locales/it/settings.json Outdated
Comment thread webview-ui/src/i18n/locales/ja/settings.json Outdated
Comment thread webview-ui/src/i18n/locales/ko/settings.json Outdated
Comment thread webview-ui/src/i18n/locales/tr/settings.json Outdated
Comment thread webview-ui/src/i18n/locales/vi/settings.json Outdated
Comment thread webview-ui/src/i18n/locales/zh-CN/settings.json Outdated
Comment thread webview-ui/src/i18n/locales/zh-TW/settings.json Outdated
@github-actions github-actions Bot added awaiting-review PR changes are ready and waiting for maintainer re-review and removed awaiting-review PR changes are ready and waiting for maintainer re-review labels Jul 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/core/webview/__tests__/webviewMessageHandler.spec.ts (1)

1546-1599: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Solid regression coverage for the queue-ordering race; real-timer approach noted.

Good targeted reproduction of the pre-fix race (stale async state read clobbering a queued update) and a clear assertion on the final updateTelemetryState call. Relying on real setTimeout delays (2ms/10ms/50ms) to enforce ordering is a pragmatic but inherently timing-sensitive choice for CI; consider fake timers or an explicit deferred-promise handshake if this ever becomes flaky. As per coding guidelines, **/*.{test,spec}.{ts,tsx,js} should "Use package-local unit tests for pure logic, parsing, state transitions, validation, serialization, request construction, retry decisions, and error handling," which this test satisfies for the state-transition concern being covered.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/webview/__tests__/webviewMessageHandler.spec.ts` around lines 1546 -
1599, Make the regression test deterministic by replacing the real setTimeout
delays in the webviewDidLaunch/telemetrySetting race with fake timers or
explicit deferred-promise handshakes. Preserve the ordering where launch
snapshots state, telemetrySetting disables telemetry, and the queued launch
continuation completes afterward before asserting the final updateTelemetryState
call.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/core/webview/__tests__/webviewMessageHandler.spec.ts`:
- Around line 1546-1599: Make the regression test deterministic by replacing the
real setTimeout delays in the webviewDidLaunch/telemetrySetting race with fake
timers or explicit deferred-promise handshakes. Preserve the ordering where
launch snapshots state, telemetrySetting disables telemetry, and the queued
launch continuation completes afterward before asserting the final
updateTelemetryState call.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b619b5d1-3fa4-4cb1-bff4-d2a7af968de5

📥 Commits

Reviewing files that changed from the base of the PR and between ded1b6d and 11811ec.

📒 Files selected for processing (10)
  • src/core/webview/__tests__/webviewMessageHandler.spec.ts
  • src/core/webview/webviewMessageHandler.ts
  • webview-ui/src/i18n/locales/fr/settings.json
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
🚧 Files skipped from review as they are similar to previous changes (8)
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
  • webview-ui/src/i18n/locales/fr/settings.json
  • src/core/webview/webviewMessageHandler.ts

@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 13, 2026
@zoomote

zoomote Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

3 issues outstanding.

  • packages/telemetry/src/TelemetryService.ts:153 The circuit breaker records every CODE_INDEX_ERROR before it knows whether any client will send it. A user who is opted out while an index error loops will trip the breaker; enabling telemetry during the following 10 minutes then suppresses the first real errors. Only advance breaker state when telemetry is currently enabled, or reset it when telemetry is enabled.
  • src/api/providers/fetchers/modelCache.ts:58 reportedEmptyModelResponse is updated before captureEvent can determine that telemetry is disabled. If an endpoint is empty while the user is opted out, the throttle is consumed even though nothing was sent, and opting in later will not report that still-empty endpoint until it returns a non-empty result. Mark it reported only after a capture can actually be emitted, or clear this state when telemetry is enabled.
  • src/extension.ts:177 The new telemetry listener only updates client state after VS Code emits a change event. PostHogTelemetryClient starts disabled, so on a normal startup every extension-host event before the first webview launch is dropped, including code-index and model-cache events. Initialize TelemetryService from the stored preference and vscode.env.isTelemetryEnabled immediately after ContextProxy is available, then register the listener.

Reviewed 8eedfac

@github-actions github-actions Bot added has-conflicts PR has merge conflicts with the base branch awaiting-review PR changes are ready and waiting for maintainer re-review and removed awaiting-review PR changes are ready and waiting for maintainer re-review has-conflicts PR has merge conflicts with the base branch labels Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

has-conflicts PR has merge conflicts with the base branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reduce PostHog event volume and fix telemetry consent/privacy gaps

1 participant