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

feat(webview): change cards UI and rollback buttons (B3b v2-13, epic #1375)#56
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.

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