Skip to content

feat(webview): change cards UI and rollback buttons (B3b v2-13, epic #1375) - #56

Open
easonLiangWorldedtech wants to merge 1 commit into
feat/fws-v2-12-rollback-wiringfrom
feat/fws-v2-13-change-card-ui
Open

easonLiangWorldedtech wants to merge 1 commit into
feat/fws-v2-12-rollback-wiringfrom
feat/fws-v2-13-change-card-ui

Conversation

@easonLiangWorldedtech

Copy link
Copy Markdown
Owner

What

B3b change cards UI (v2-13, epic Zoo-Code-Org#1375): renders a per-step change card inside the chat for persisted changeCard messages — header with the file count, per-file rows with +/− diff badges, per-file and per-step rollback controls wired to the extension host through the checkpointRollbackFile / checkpointRollbackStep messages. Diffs come from the payload's per-file diff field: full cards expand by default, summary cards expand lazily, compact cards carry no diff.

Stacked on #55 (v2-12 rollback wiring). Locales land in a separate stacked PR (#57) to keep this PR under the hard line cap.

Provenance

  • ChangeCard.tsx = the B3c L2 line (0e021ef96) plus four documented Stryker directives (see below).
  • ChangeCard.spec.tsx = the B3c L2 spec (incl. the missing-task step-result tests) plus 13 round-2 mutation-coverage tests (the 13th — drops rollback payloads carried by messages of other types — closes the type-guard mutant found by the mutation gate: a foreign checkpointRollbackResult payload on a non-checkpointRollbackResult message must not be applied even when the card ts matches).
  • ChatRow.tsx = the ChangeCard wiring (2 lines) unchanged from v2-13 line 1.

Stryker directives

Four single-line Stryker disable next-line directives suppress genuinely equivalent mutants (no test can observe the variant). New pattern for this repo (no prior directive precedent):

  1. if (parsed === undefined) guard — safeParse below rejects undefined input identically; the early return is unobservable. (ConditionalExpression, BlockStatement)
  2. Initial expandedFiles set — expansion only affects diff-carrying files; diff-less rows render compact either way. (MethodExpression, ConditionalExpression)
  3. filePath !== undefined file branch — a no-file-path result would update the state record under the key "undefined", which matches no card file and never renders. (ConditionalExpression)
  4. Effect cleanup return — the effect re-adds the same listener when the card ts changes; a stale/missing cleanup cannot be observed from the DOM. (ArrowFunction, StringLiteral)

Stryker mutation-diff gate

Stryker diff gate (base = #55 head aef395e05, head 1ca004b95): 182 changed-code mutants across ChangeCard.tsx + ChatRow.tsx (298 changed lines), 168 Killed, 0 Survived, 0 NoCoverage, 0 timeout, 14 ignored (4 ignoreStatic + 10 directive-suppressed, see above); ChangeCard.spec.tsx (27 tests) ran as the test set.

Local gates

  • tsc --noEmit (via pnpm check-types): 11/11 tasks.
  • Vitest (webview-ui, ChangeCard.spec.tsx): 27 tests passed.
  • ESLint --max-warnings=0 on the touched webview-ui files + full pnpm lint via the pre-commit hook: clean; no suppression count changes (no src/ files touched).
  • Prettier: all 3 files content-clean under the repo config (tabs, width 120, no semis).

Line budget

997 lines (soft cap 400 exceeded, hard cap 1000 respected): ChangeCard.tsx 327 + ChangeCard.spec.tsx 667 + ChatRow.tsx 3. The mutation gate binds the spec and the component into one unit — killing the surviving mutants requires tests and component code in the same PR. Locales (216 lines, 18 files) split into #57.

@easonLiangWorldedtech easonLiangWorldedtech added coderabbit-review-active Required CI passed; CodeRabbit review is active awaiting-coderabbit Waiting for CodeRabbit to approve the latest commit labels Sep 6, 2026
@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. community-approved is managed the same way — do not add or remove it manually. It signals a fresh community code approval for the current head as an advisory priority only; maintainer review is still required.

This branch has not been deployed

No deployments
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