Repository navigation
[Improve] Dispose view listeners and ignore stale views when the webview is replaced - #2213
Conversation
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one): 1
Please check the settings in the CodeRabbit UI or the
|
|
No code issues found. See session The follow-up commits fix the outstanding item: the unused
Reviewed e35e95bf |
Review statusThis PR was opened by an automated account. A human maintainer must verify the change intent, provenance, and validation before merging. Current step: The required review sequence passed. Remaining merge requirements apply. Review-state labels are managed by this workflow; do not edit them manually. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
64c7d62 to
4eebab1
Compare
Related GitHub Issue
Closes: #2205
Description
ClineProvider.resolveWebviewViewnow keeps all subscriptions of the current view in one list,webviewDisposables. The list holds the message, focus tracker, view state, dispose, and configuration listeners. The dispose listener moved there from the extension-lifetimedisposableslist. A replaced view can no longer keep listeners alive.A resolve that starts for a different view now disposes that list at entry. The view dispose path also disposes it. Each listener ignores events from a view that is no longer the current view. This covers the message, visibility, view state, configuration, and dispose listeners. A stale dispose can no longer clear the listeners of the new view.
Two guards stop a resolve that finishes after disposal or replacement. One guard runs after the HTML load. A stale resolve does not assign HTML. The other guard runs after
await this.getState(). A stale resolve does not install listeners. The sidebar dispose handler clearsthis.viewbefore it clears the view resources.This PR does not add heartbeat or watchdog code. That work stays in PR #1715, which rebases on this change.
Six provider test files used a shared
onDidDisposemock that fired the callback at registration. Real VS Code never fires a dispose event at registration. The new sidebar dispose behavior would clearthis.viewduring every resolve with that mock. The mocks now record the registration and return a disposable only.Test Procedure
A new suite,
src/core/webview/__tests__/ClineProvider.stale-view.spec.ts, covers each behavior with eight tests:await this.getState(). Each guard has a replacement case and a provider-disposed case. No earlier test reached the guard aftergetState().this.viewand disposes the view subscriptions. The provider instance stays registered.Commands run from the repository root:
pnpm --dir src exec vitest run core/webview— 731 tests pass, including the new suite.pnpm --dir src run check-types— passes.pnpm --dir src exec eslint --prune-suppressions --max-warnings=0 <changed files>— passes. Suppression counts did not increase.pnpm test— all 14 tasks pass.Reviewers can repeat the focused run with
pnpm --dir src exec vitest run core/webview/__tests__/ClineProvider.stale-view.spec.ts.Pre-Submission Checklist
Visual Snapshots
None. This change handles extension-host view lifecycle only. It has no rendered UI state.
Videos (interaction / animation only)
None.
Documentation Updates
This change fixes internal listener lifecycle behavior. It adds no setting, command, or user-visible behavior. The Zoo-Code-Docs repository needs no paired change.
Additional Notes
as anywas added in the new tests. The twoas unknown ascasts in the new suite carry a comment, as AGENTS.md requires.src/__tests__/extension.spec.tsunder parallel load. That file mocksClineProvidercompletely. The tests pass on a solo run and on a full rerun, so they are unrelated flake.Get in Touch
Use the follow-up links in the note at the top of this PR.