feat(ui): Version History block/word-level diff (Compare) (PVH-6)#176
Merged
Conversation
Pure, tested engine: LCS block alignment by stable id (added/removed/ unchanged/changed) plus an intra-block word-level LCS diff for changed text blocks. Non-text blocks (image/chart/table/embed) are reported opaquely at block granularity. No diff dependency added — the word-LCS is self-contained (same shape as textMerge.ts). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KFk2T9k3p7ghCjdzMfkA5w
Wire the reserved "Compare (coming soon)" placeholder into a working Preview/Compare toggle. Compare renders VersionDiff — added blocks tint green (+), removed red with strikethrough (−), changed text blocks show inline word-level <ins>/<del>, non-text changes show old→new opaquely, and long unchanged runs collapse. Markers + sr-only labels keep it accessible (not colour-only). Current row stays preview-only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KFk2T9k3p7ghCjdzMfkA5w
…/dead-code cleanup (review) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KFk2T9k3p7ghCjdzMfkA5w
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
The last Version History slice (PVH-6): a Compare mode in the history side pane that shows a real block/word-level diff of a captured version against the current document — not just two read-only previews.
unchanged/changed, an old-only block isremoved, a new-only block isadded.kept/added/removedruns) rendered with semantic<ins>/<del>(never colour-only), tinted emerald / destructive / amber."{Type} changed"badge rather than pretending to diff their internals.lib/blockDiff.ts,plain BlockJSONin / data out), unit-tested; no diff dependency added (the word-LCS is ~20 lines).Before / After
Before= basemain(the history pane's disabled Compare (coming soon) placeholder).After= this branch.read-only preview only; Compare disabled
quick→slowins/del · removed row struck through · Image changed chip · added row"No changes — this version matches the current document."
Review fixes applied (Quinn + Devon — batched)
decodeSnapshot→ensureNotEmptyinjects a lone empty paragraph with a fresh random id into each decoded-empty doc, so empty-vs-empty diffed as removed+added. The engine now drops a lone trailing bare default paragraph from each side before aligning → truly empty-vs-empty reads "No changes" (blockDiff.ts,stripTrailingBareParagraph).oldBlock(always truthy forchanged), so a text block with identical text but changed props/children rendered a blank row with a lone~. Now gated on the word runs actually containing an ins/del; all-keptruns render a "Formatting changed" hint (new i18n key) (VersionDiff.tsx)."{Type} changed"badge is the honest representation (module doc +VersionDiffcomments/copy).aria-label="Compare". The toggle wrapper now uses a dedicated "View mode" label; "Compare" is reserved for the button + diff content (HistoryPaneBody.tsx).history.diffShowUnchangedkey and the unreachable singularUnchangedRunbranch + its singulardiffUnchangedRunstring (the run only renders for count ≥3 → plural only).MAX_WORD_TOKENSwhole-block +/− fallback.(Devon #6 — the "Computing changes…" flash on every Preview↔Compare toggle — left as-is:
VersionDiffunmounts on toggle and refetches the live page, so a safe cache would risk staleness for marginal gain. Noted for follow-up.)By-design (reviewer product-confirm flags)
"{Type} changed"chip on the container, not a drill-down diff — intentional at this granularity.\p{L}\p{N}); it does not diff below the token.Verify
build:libs· uitypecheck· uibuild· uilint· uivitestall green (observed exit 0). Vitest: 1099 passed (incl. 14 inblockDiff.test.ts). Captures driven through the web e2e harness (seed a page whose captured version differs from current; Compare in light + dark).Gates: design (Devon) + code (Quinn) — both CLEAR WITH NITS; all nits applied in the fix commit on this branch.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KFk2T9k3p7ghCjdzMfkA5w