test(e2e): port view-state suite with reload and rehydration coverage (vps2 F6) - #1565
test(e2e): port view-state suite with reload and rehydration coverage (vps2 F6)#1565easonLiangWorldedtech wants to merge 13 commits into
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: Wait for 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)
Ports the vps2 CS API wiring onto the F4 head 80c147f: - startNewTask(newTab, preserveOpenTabs): skips editor revert/close-all when preserveOpenTabs is set - task ask registry: approveTaskAsk + selectTaskFollowupSuggestion (per-provider mode validation; a failed mode switch does not swallow the follow-up answer; a stale instance's teardown cannot evict its replacement) - setConfiguration routes through ClineProvider.setValues so the view-local subset stays in sync with the sidebar view's state - getConfiguration flattens the nested view-local apiConfiguration and strips secrets before returning - getGlobalState read surface (test-only) - docs: setConfiguration JSDoc now states writes target the extension-host (sidebar) view (parked A4 major, documented limitation); @PARAM note added for preserveOpenTabs - specs: api-task-control (12 tests), api-set-configuration (1), api-configuration getConfiguration flatten/strip-secrets (1) Upstream: Zoo-Code-Org#982 (vps2 F5)
Port source: CS e9a44b2 apps/vscode-e2e (A5 Zoo-Code-Org#929 re-review series) — 3 files byte-identical, 2 suite tests F6-authored: sidebar webview reload/rehydration test (A5 minor 2) — the durable per-view mode survives a sidebar hide/show cycle
f42c571 to
09876ae
Compare
…el CI load (no code change)
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
… (coordinated-mode test); 0-line diff
…ing the tracked one
The F0 single-tab reuse in openClineInNewTab made the 2nd/3rd
startNewTask({newTab:true}) return the first tab's provider, so its
evictCurrentTask() aborted the live task that tab was serving (TaskUnfocused
-> removeRegisteredTask, breaking follow-up suggestion delivery) and
re-registering listeners on the reused provider stacked duplicate task
handlers (Nth task events re-emitted N times).
Extract the creation body as createClineTabPanel (always creates a fresh
panel + provider), point API.startNewTask at it, keep the UI button path on
openClineInNewTab's reuse behavior, guard registerListeners with a
per-provider set, and only clear the tracked tab ref on dispose when it
still points at the disposed panel.
Restores the 3-panel follow-up coordination contract; the e2e 3-panel
coordinated-rounds test that failed 6/6 now passes locally.
Tracking: easonLiangWorldedtech#41 (vps2 series ledger). Upstream issue: #1564 (this series' gap record; the review lineage is #929, A5 re-review minor 2). Port source: the CS worktree apps/vscode-e2e (e9a44b2, the A5 re-review state) — 3 files byte-identical to CS; the reload test is F6-authored.
Scope
4 files, 543 insertions, 0 deletions (measured vs stack base 95a18b2); all under apps/vscode-e2e/ — no production code:
Gate evidence
Port fidelity
Series mechanics