Skip to content

feat(webview): per-file restore-latest on change cards and corrected rollback confirm copy (B3b v2-15b, epic #1375) - #60

Open
easonLiangWorldedtech wants to merge 1 commit into
feat/fws-v2-15-restore-latest-apifrom
feat/fws-v2-15-restore-latest-ui
Open

feat(webview): per-file restore-latest on change cards and corrected rollback confirm copy (B3b v2-15b, epic #1375)#60
easonLiangWorldedtech wants to merge 1 commit into
feat/fws-v2-15-restore-latest-apifrom
feat/fws-v2-15-restore-latest-ui

Conversation

@easonLiangWorldedtech

@easonLiangWorldedtech easonLiangWorldedtech commented Sep 6, 2026

Copy link
Copy Markdown
Owner

What

B3b v2-15b (epic Zoo-Code-Org#1375): the restore-latest UI on change cards — a per-file "restore latest version" control (idle → confirm → pending → success/error) independent of the rollback control, plus the per-file rollback confirm warning copy. Stacked on feat/fws-v2-15-restore-latest-api (base 5ec15d56f); the UI half of the v2-15 split.

  • ChangeCard.tsx (+105/−10): fileRestoreLatestControls(path, index) — idle native button (History icon, tooltip + aria-label affordance), confirm span with the localized restoreLatestWarning copy, pending ring, success restored label, and an error state whose tooltip carries the failure detail with the restoreFailed fallback. The fileRestores state and the per-file result routing by kind: restore-latest results update the restore control; everything else (including results posted before kind existed) the rollback control. The file rollback confirm span gains the rollbackFileWarning copy (the corrected rollback confirm copy from v2-15).
  • ChangeCard.spec.tsx (+187/−4): the upstream v2-15 spec (5 restore-latest tests + 5 t-mock entries) + the local round-2 superset (StandardTooltip inline-content mock, the within import, the title assertion) + 4 new round-2 mutation tests added to make the Stryker gate green (below).
  • 18 locales (+5 each): rollbackFileWarning, restoreLatest, restoreLatestWarning, restored, restoreFailed — byte-identical to the upstream translations.

Base-parity decisions

Built from the v2-15 source commit (7a1d4e61b4c1, upstream PR Zoo-Code-Org#1412; its empty CI commits are skipped).

  • ChangeCard.tsx = upstream v2-15 + 15 lines only: 6 Stryker disable next-line directive lines + 9 justification comment lines (upstream carries 0 directives). The v2-13/v2-14 directives on lines upstream rewrote were dropped (they no longer apply); the surviving ones carry into the rewritten regions, and 1 new directive covers the cancel handler (see Stryker below).
  • ChangeCard.spec.tsx = upstream v2-15 spec + the local superset. Two local round-2 tooltip tests now match by content (getAllByTestId(...).some(...)): v2-15 adds a second per-row tooltip (restore-latest), so a bare getByTestId matches twice.
  • Locales: the 5 changeCard keys only — the upstream What's New marketing-text hunk is skipped as stale drift (same policy as v2-13).
  • changeCardDetail stays optional in packages/types (v2-9 documented divergence; untouched here).

Stryker (local diff gate, base 5ec15d56f)

Run 1 (head 6c4eee73d) was red with 7 blocking mutants (6 Survived + 1 NoCoverage), all in the new restore-latest region:

Mutant Cause Fix
ChangeCard.tsx:193 (StringLiteral, Survived) the new per-file rollback confirm warning copy is never asserted new round-2 test asserting the rollbackFileWarning text
ChangeCard.tsx:272 (ObjectLiteral, Survived) the cancel handler's { ...prev, [path]: IDLE } — resetting to IDLE is read-equivalent to dropping the key (fileRestores[path] ?? IDLE) Stryker disable next-line ObjectLiteral directive (justified in-line)
ChangeCard.tsx:274 (StringLiteral, Survived) the restore cancel button's localized label is clicked via testid, never asserted new round-2 test asserting Cancel
ChangeCard.tsx:295 (StringLiteral NoCoverage + LogicalOperator Survived) the state.error ?? t("…restoreFailed") right side is only evaluated when no error is given, and ?? vs `
ChangeCard.tsx:306, :310 (StringLiteral, Survived) the idle restore tooltip + aria-label affordance is never asserted new round-2 test asserting both

Final gate (head 45f810db9): 98 changed-code lines (webview lane) → 55 valid mutants: 55 Killed, 0 Survived, 0 NoCoverage, 0 timeout, 1 Ignored (= the new ObjectLiteral directive on the restore-cancel handler, run-1 line 272). 0 blocking.

Gates

  • pnpm check-types 11/11
  • node scripts/find-missing-translations.js — all green (backend 7 files, frontend 9 files, package.nls 50 keys)
  • ChangeCard.spec.tsx vitest: 39/39 (35 at the previous head + 4 new round-2 tests)
  • eslint 0 (webview-ui, --max-warnings=0), prettier clean, pre-commit turbo lint 11/11
  • diff budget: 20 files, +383/−14 (397 shortstat lines) < 400 soft cap — UI half of the v2-15 split; the 492-line source increment (7a1d4e61b4c1) exceeded the soft cap, hence the A/B split (A = 173 lines, B = 397 lines)

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

Review status

Thanks for contributing. This comment tracks the review sequence and the next action.

Current step: Required CI passed. Waiting for automated review of the latest commit.

If automated review does not start, a maintainer must restart it.

Review-state labels are managed by this workflow; do not edit them manually.

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

Labels

awaiting-coderabbit Waiting for CodeRabbit to approve the latest commit coderabbit-review-active Required CI passed; CodeRabbit review is active

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants