Skip to content

test(webview): add parallelMode spec with viewStates pruning edges and dispose retention - #1555

Draft
easonLiangWorldedtech wants to merge 4 commits into
Zoo-Code-Org:mainfrom
easonLiangWorldedtech:vps2/f2-durable-viewstates
Draft

test(webview): add parallelMode spec with viewStates pruning edges and dispose retention#1555
easonLiangWorldedtech wants to merge 4 commits into
Zoo-Code-Org:mainfrom
easonLiangWorldedtech:vps2/f2-durable-viewstates

Conversation

@easonLiangWorldedtech

Copy link
Copy Markdown
Contributor

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 this
mock-GitHub environment offers no draft-conversion API (no gh pr update
subcommand, no draft flag on gh pr edit, and the REST PATCH /pulls /
GraphQL updatePullRequest inputs both ignore or reject draft) — so the only
path for a wrongly-opened PR is close + re-create with --draft. This is that
re-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:

  • L1–675: the vps2 CS parallelMode spec preamble copied 100% verbatim
    (line-by-line verified, 0 mismatches): imports, the vi.mock blocks (modes
    with defaultModeSlug: "code", cloud, modelCache, zoo-code-auth,
    RateLimitClock, …), the beforeAll/afterAll console spies, the
    describe("ClineProvider - Parallel Mode Support") open, the
    globalState-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-vars off, so the verbatim list passes).
  • 3 F2 regression tests:
    1. should drop the entry without updatedAt first when the cap is exceeded
      — a legacy entry without updatedAt ranks ?? 0 and falls off the
      50-entry cap before every timestamped entry.
    2. should keep the earliest inserted entries when updatedAt values tie
      — equal updatedAt preserves insertion order (stable sort); the first 50
      registered views survive.
    3. 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's
      viewStates 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.ts is byte-identical to the F1c head.

Budget

  • a+d 733 vs the 400-soft / 1000-hard budget: soft exceeded by composition,
    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.
  • Stryker-diff gate: vacuous — the commit changes 0 executable lines
    (test-only); 0 executable changed lines, 0 raw mutants.
  • vitest: 3/3 pass in the new file (coordinator re-ran independently).
  • check-types, eslint (--prune-suppressions, 0 as any in 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+), where
ClineProvider.dispose() was rewritten to drain registry tasks. The #1065
dispose-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

  • Base of record: upstream/main @ 0d937c050; PR base is main; the branch is
    stacked on the F1c head 090d2c87e.
  • Draft PR per unit; merge order F1a → F1b → F1c → F2 → F3 → F4 → F5 → F6 → F7.
  • The CS parallelMode spec describes for the F1-series (L676–1363) are already
    shipped by F1a/F1b/F1c; the F3/F4 describes (L1364–1791) are pending units
    that append to this file.

…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.
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • coderabbit-review-active

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: 034d8ea3-89a8-4c06-8c79-2cc15a7fcc30

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Review status

Thanks 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

codecov Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/core/webview/ClineProvider.ts 94.59% 3 Missing and 7 partials ⚠️
webview-ui/src/utils/vscode.ts 86.36% 1 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants