test(webview): add parallelMode spec with viewStates pruning edges and dispose retention - #1555
Conversation
…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
|
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. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Draft PR — vps2 unit F2 (durable per-view state regression coverage).
Supersedes PR #1554 (closed). The first cut of this branch was built on the
wrong stack base and extended the existing spec file instead of adding the
mandated
ClineProvider.parallelMode.spec.ts. PR #1554 was closed because thismock-GitHub environment offers no draft-conversion API (no
gh pr updatesubcommand, no
draftflag ongh pr edit, and the RESTPATCH /pulls/GraphQL
updatePullRequestinputs both ignore or rejectdraft) — so the onlypath for a wrongly-opened PR is close + re-create with
--draft. This is thatre-created draft.
Tracking: easonLiangWorldedtech#41 (vps2 series ledger). Upstream issue:
#1553.
Scope
New file only:
src/core/webview/__tests__/ClineProvider.parallelMode.spec.ts(733 lines), created on the F1c head
090d2c87e:(line-by-line verified, 0 mismatches): imports, the
vi.mockblocks (modeswith
defaultModeSlug: "code", cloud, modelCache, zoo-code-auth,RateLimitClock, …), the
beforeAll/afterAllconsole spies, thedescribe("ClineProvider - Parallel Mode Support")open, theglobalState-backed ExtensionContext fixture, and
createMockWebviewView.This preamble is a shared series asset: F3 and F4 append their describe
blocks into this file, so it lands in the series ahead of both. No mock/shape
adaptations were needed — it compiles and passes at the F1c head as-is.
The CS import list is kept intact (specifiers only consumed by F3/F4's future
describes are kept on purpose; the repo eslint config has
@typescript-eslint/no-unused-varsoff, so the verbatim list passes).should drop the entry without updatedAt first when the cap is exceeded— a legacy entry without
updatedAtranks?? 0and falls off the50-entry cap before every timestamped entry.
should keep the earliest inserted entries when updatedAt values tie— equal
updatedAtpreserves insertion order (stable sort); the first 50registered views survive.
should preserve persisted viewStates entry when an editor provider is disposed during teardown(Preserve durable editor view state across provider disposal #1065) — a disposed editor provider'sviewStates entry survives teardown.
Standalone diff vs stack base
090d2c87e(F1c head): 1 file changed,733 insertions(+), 0 deletions(-) — a+d 733. The existing
ClineProvider.spec.tsis byte-identical to the F1c head.Budget
exactly as F1a's 999 — ~675 of the 733 lines are the verbatim CS preamble,
shared series infrastructure (F3/F4 append into this file; if F3 had carried
the preamble, F3 would have breached the 1000 hard cap). Under the hard cap.
(test-only); 0 executable changed lines, 0 raw mutants.
--prune-suppressions, 0as anyin the new file,suppression counts unchanged — the prune pass's re-indent was reverted),
prettier (
--end-of-line=auto): all green.Post-merge interaction flag
Upstream main has since advanced to
4c7474d42(v3.82.0+), whereClineProvider.dispose()was rewritten to drain registry tasks. The #1065dispose-retention test is green at this base of record; re-verify after the
lower units merge. This series keeps the base of record
(
0d937c050) and rebases after lower PRs merge.Series mechanics
0d937c050; PR base ismain; the branch isstacked on the F1c head
090d2c87e.shipped by F1a/F1b/F1c; the F3/F4 describes (L1364–1791) are pending units
that append to this file.