fix(webview): invalidate live sibling view state on reset and settings import (vps2 F4) - #1562
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 ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
Review statusThanks for contributing. This comment tracks the review sequence and the next action. Current step: Fix the failing required CI checks; awaiting-maintainer requires CI and automated review completion. Review-state labels are managed by this workflow; do not edit them manually. |
…States Each ClineProvider instance now owns a unique viewId (renderContext plus a monotonic counter) and registers a stable viewStateId for durable persistence. - Per-view state buffer (viewLocalState) holds mode / currentApiConfigName / apiConfiguration overrides in memory; saveViewState persists the non-secret subset durably under the active view id, rekeyed to the stable id on registration. - viewStates is stored as a map pruned to the newest 50 entries; writes go through a serialized queue so concurrent provider instances merge without lost updates. - setViewStateId sanitizes ids and rejects "__proto__" so a per-view entry can never be keyed through the Object.prototype setter. - postMessageToWebview no longer awaits the webview ack: a remounted or disposed page never acknowledges, and awaiting would wedge task-critical callers. - History restore falls back to the default mode view-locally instead of writing the shared global mode. - GlobalState gains the "viewStates" key and GLOBAL_STATE_KEYS tracks it. Adds F1a coverage in ClineProvider.spec.ts (viewId uniqueness, saveViewState persistence semantics, loadViewState fallback and failure, pruning, the __proto__ guard) and adapts the two history-restore tests in ClineProvider.sticky-mode.spec.ts to the view-local restore. getState() merging of hydrated per-view values and the remaining view-state suites land in the follow-up (F1b).
…overrides Fold ClineProvider viewLocalState on top of ContextProxy values in getState() (mode, apiConfiguration, and all per-view fields) so each webview reports its own selections while falling back to shared global state for everything else. Ports the getState-merging and local-state-isolation spec coverage from the superseded vps2 source. Also pins the full default surface of the merged read path, including the apiConfiguration provider fill-in when provider settings sanitize the raw value away (mutation-diff gate).
… state WMH webviewDidLaunch persists the webview view-state id via provider.setViewStateId and re-pins the view-local currentApiConfigName through provider.saveViewState when the view-local profile is missing but the shared global selection is still valid. updateSettings is routed through provider.setValue so view-local buffer and pin sync stay consistent with the other mutation paths. The webview VSCodeAPIWrapper gains a stable getViewStateId persisted via setState (with an in-memory fallback) and the launch effect posts the id with the webviewDidLaunch message.
…d dispose retention
Port vps2 F3 (mode/profile writes) from upstream 978, hunk-by-hunk against the F1c..CS residual: - ClineProvider: add repointPersistedViewStates() to re-point currentApiConfigName across per-view entries when a profile is renamed or replaced, and prune orphaned entries; validate handleModeSwitch slugs against the custom-modes manager and no-op with a log on unknown modes; drop the as-any cast in delegateParentAndOpenChild. - Task: route mode switches through provider.handleModeSwitch(task) and keep the submitted message on failure instead of setMode(). - SwitchModeTool and specs: durable per-view mode writes. - webviewMessageHandler: no change vs base - the kimi-code OAuth hunk in the residual is CS-only divergence (not-ported register item 1), not part of Zoo-Code-Org#978/Zoo-Code-Org#979. - webviewMessageHandler.spec: ported only Zoo-Code-Org#979's 4 mock fields + defaultModeSlug import; the stack-side legacy-repair test, Key-aware getValue mock and em-dash comment are retained (register item 4). Zoo-Code-Org#979's mode-routing WMH.spec describe ("routes mode messages through handleModeSwitch instead of writing ContextProxy directly") exists in neither CS nor the stack and is ported by no unit (open question, logged). - Tests: H3/H4 durable handleModeSwitch writes in ClineProvider.spec.ts; profile-mutation, profile-activation and handleModeSwitch-integration describes (incl. A4 non-focused-target regression and new mutation-killing tests) in ClineProvider.parallelMode.spec.ts; sticky-mode and webviewMessageHandler spec updates; retain the setViewStateId __proto__ guard + spec test - shipped F1a hardening; the residual's guard removal is lineage divergence, not F3 content. - eslint-suppressions.json: no-explicit-any counts decrease for core/webview/ClineProvider.ts (12 -> 11) and core/webview/__tests__/ClineProvider.sticky-mode.spec.ts (36 -> 33). Upstream: Zoo-Code-Org#978 (vps2 F3) - issue Zoo-Code-Org#978; content ported hunk-by-hunk from the F1c..CS residual, cross-checked against upstream PR
…s import
- ClineProvider: new broadcastResetToAllInstances() clears each live instance's
view-local cache and issues the single global contextProxy setValue("viewStates", undefined)
write (single write-queue clear; no secrets involved, no prune-cap regression).
- resetState: awaits broadcastResetToAllInstances() before the final postStateToWebview
so parallel tabs do not keep stale durable/in-memory per-view state.
- importExport: ImportWithProviderOptions.provider gains optional
broadcastResetToAllInstances?(); importSettingsWithFeedback calls it in a guarded
try/catch (log-only) after a successful import, so a failing broadcast never fails the import.
- importExport spec: 3 new tests (broadcast called when available / skipped when missing /
import result preserved when broadcast throws, console.warn asserted; the skip test also
asserts the broadcast-failure warn is NOT reached). Provider identifiers use
providerIdentifiers.* per the zoo/no-raw-provider-identifiers rule (lint-required
adaptation from Zoo-Code-Org#981's raw-string casts; no semantic change).
- parallelMode spec: appends the CS source-of-record describes (multi-instance isolation,
_clearViewLocalState) — 5 new tests.
- ClineProvider spec: forward fix of the F3 resetState sentinel (F4's global viewStates
clear removes the key; the F3-era toEqual({}) expectation is replaced by toBeUndefined())
plus a new cross-instance resetState test pinning the multi-instance broadcast path
(sibling view-local cache cleared; sibling and caller each post state exactly once).
- webviewMessageHandler.ts was NOT edited: the importSettings case already passes the full
ClineProvider, which structurally satisfies the extended provider type and reaches the real
broadcast method — Zoo-Code-Org#981's structural wrapper hunk is redundant in this stack.
Upstream: Zoo-Code-Org#980 / PR Zoo-Code-Org#981 (vps2 F4)
80c147f to
da97f98
Compare
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…/180s under runner load, 13 failing / 72 passing)
…ures, 0-line diff)
Draft PR — vps2 unit F4 (cross-instance reset + import invalidation).
Tracking: easonLiangWorldedtech#41 (vps2 series ledger). Upstream issue: #1561 (this series' gap record; the original upstream bug is #980). Port source: upstream PR #981 (fix(webview): invalidate per-view state after reset and import) — closed draft, superseded by the vps2 series; the #41 ledger names #981 as the F4 port source.
Scope
5 files, 342 insertions, 1 deletion (measured vs stack base 8da5c6e):
Budget
Port fidelity (coordinator-verified)
Structural note on the parallelMode spec (coordinator-verified)
The CS parallelMode.spec.ts is 1790 lines: a shared preamble (L1-672), an F1-series test section (L673-1363: viewId uniqueness, local state isolation, saveViewState, stale temporary-id load), the F3 describes (L1364-1673), a blank separator (L1674), the F4 multi-instance describes (L1675-L1789), and the file's final top-level close (L1790). In this series the F1-series section lives in ClineProvider.spec.ts (shipped by F1a/F1b/F1c — the deliberate F1-series describe restructure), and the F2 unit shipped the persisted-pruning and #1065 retention tests inside the parallelMode file (absent from the CS parallelMode file). Both placements are behaviorally covered; the divergence is structural, not a coverage gap.
Series mechanics