feat(canvas): converge web and desktop CanvasViews on a shared core (0277) - #403
Merged
crs48 merged 11 commits intoJul 7, 2026
Merged
Conversation
…gence decisions Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Web hand-rolled frame properties while desktop used createCanvasFrameVariantProperties — two wire shapes for the same synced node type (0277 M2). Both sides now write the factory shape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The desktop canvas ignored the connectors map entirely: edge changes did not bump the scene revision and a selected connector had no HUD (0277 W9). Mirrors the web view's edge handling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two sync-parity gaps closed (0277 Phase 0): media nodes dropped on the web rendered as bare text cards on desktop (no image preview, no PDF page viewer, no storage-policy badge), and dashboard widget nodes fell through to the engine default on desktop. - CanvasMediaCard moves to @xnetjs/editor with a mediaGate slot; the web passes its ModeratedMedia veil (M1) so every canvas media preview is moderation-gated. Desktop has no moderation stack yet and renders ungated until one exists. - CanvasWidgetNodeCard + the canvas/dashboard schema registry move to @xnetjs/views (canvas-view area); DashboardView re-exports the shared registry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s in Settles the 0277 Phase 1 location question the same way 0276 settled DataWorkspaceCore: shared app-view cores live under packages/views. The desktop-only canvas-shell resolution helpers (display type, source id, preview model) move here unchanged with their tests; both apps now import them from @xnetjs/views. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The verbatim middle of the two CanvasView forks moves into useCanvasViewController (@xnetjs/views): scene observation, selection resolution, alias/comment editing, ingestion, primitive creation, and presence intent. Cards unify behind renderCanvasNodeCard (@xnetjs/editor); alias/comment/shortcut-help panels render from one implementation. Web adopts the desktop page/note preview cards (0277 E9) and the pinned source-record card (E2). M3: canvas test attributes unify on data-canvas-* (web loses the data-web-canvas-* namespace); e2e selectors updated. Web: 1,843 → ~900 lines. Desktop: 3,195 → ~2,050 lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… platforms Phase 2 of the 0277 convergence: - Query frames (E1/E2): the saved-view executor moves to @xnetjs/views with the schema registry as a parameter; both platforms execute against the shared canvas/dashboard registry, and the web now runs + refreshes query frames synced from desktop. - Source references (E3): useCanvasSourceReferences and the merged current-canvas scan move to the shared package; the web gains the "Copies" panel and reveal-in-canvas. - Undo (E5/W8): the desktop's four-domain undo ladder is the shared model. The web's registry-claimed Mod+Z now dispatches into it, so undo inside a focused canvas can target an inline-edited source document — a deliberate behavior change from the old scene-only undo. - Selection HUD (E6/W6/W9): one shared HUD on both platforms — web gains lock/align/distribute/tidy/connect/layering, Open, query-frame Refresh, and Copies; frame Present/Export moves into the controller and appears on desktop for the first time. - W5: the desktop canvas header becomes an editable title with presence avatars, matching the web. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase 3 of the 0277 convergence: - E4: CanvasInlinePageSurface and CanvasDatabasePreviewSurface move to @xnetjs/editor with a shared useCanvasPeek hook + CanvasPeekOverlay. The web canvas gains Peek (modal source preview) and zoom-gated inline editing of pages, notes, and databases — previously the web could only navigate away. - E10: useCanvasCommands registers every canvas action once in the shared workspace command registry from the core. The desktop palette keeps its metadata table as presentation over the same actions via the (now transitional) imperative handle; full handle deletion waits on registry palette metadata, tracked in the doc's Risks. - W1 verified: the shared core has no Desk branches — the Desk (0273) composes via config override, empty-state slot, overlay slot, and the pin-ingestion queue. - The view-drift tripwire already covers the pair on main; both sides changed together throughout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ards Live validation of the converged web canvas caught a latent desktop bug the audit had missed: CanvasHandle.undo() delegates straight back to onUndoRedoShortcut, so the ladder's scene rung called itself instead of undoing — scene undo on the desktop canvas could never complete. The shared ladder now owns the scene Y.UndoManager (the web's 0179 manager) directly, which fixes scene undo on desktop and restores it on web. Verified in the running web app: toolbar create → Mod+Z removes the object, Mod+Y restores it; shared HUD, comment panel, and the peek overlay (inline page editor) all render and operate. Also adds canvas-view-convergence.test.ts: source-level guards that both apps render through the shared dispatcher/cards/controller, plus the M2 frame wire-shape golden assertion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ergence decisions Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
crs48
deleted the
claude/0277-canvasview-feature-parity-audit-and-convergence
branch
July 7, 2026 02:57
Contributor
|
Preview removed for PR #403. |
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.
Implements exploration 0277 — the CanvasView feature-parity audit (the gate 0230 Phase 5 / 0276 Theme 3 was waiting for) and the full convergence it green-lights, in one pass.
The audit
docs/explorations/0277_[x]_CANVASVIEW_FEATURE_PARITY_AUDIT_AND_CONVERGENCE_DECISIONS.mddecides all 22 single-sided features: 13 port, 8 platform-specific, 1 deprecate. Two 0276 premises corrected along the way (ModeratedMedia was never in the web canvas; the "electron-only" selection ops were one-line engine delegations).The convergence
Shared core (
packages/views/src/canvas-view/+ canvas cards/surfaces inpackages/editor):useCanvasViewController(selection, alias/comment, ingestion, creation, presence),useCanvasUndoLadder,useCanvasQueryFrames+ executors,useCanvasSourceReferences,useCanvasCommands(registry registration),CanvasSelectionHud, shared panels,renderCanvasNodeCard+ card set,useCanvasPeek+CanvasPeekOverlay,CanvasInlinePageSurface/CanvasDatabasePreviewSurface.Web gains (previously desktop-only): peek + zoom-gated inline editing of pages/notes/databases, query-frame execution + refresh, linked-copies ("Copies") panel, the full selection HUD (lock/align/distribute/tidy/connect/layering), frame present/export on desktop too, multi-domain undo, desktop's richer page-preview and pinned-record cards.
Desktop gains (previously web-only): dashboard widget cards, the rich media/PDF card, edge selection, editable canvas title + presence avatars.
Sync-parity fixes: widget and media nodes synced across platforms previously rendered degraded or not at all on desktop; frame nodes were written with two different wire shapes (M2). Both fixed — every node type now renders through the same components on both sides.
Bug found during live validation:
CanvasHandle.undo()delegates back toonUndoRedoShortcut, so the desktop undo ladder's scene rung recursed instead of undoing. The shared ladder now owns the sceneY.UndoManagerdirectly — fixing desktop scene undo and preserving web's.Moderation (M1): the shared media card routes previews through a
mediaGateslot; web passesModeratedMedia. Desktop has no moderation stack yet and renders ungated until one exists.Behavior change (release-noted): inside a focused canvas, Mod+Z now walks the multi-domain ladder — it can undo an inline-edited source document when that was the latest change, instead of only scene moves.
E10 residual (in doc Risks): all canvas commands register once in the shared registry; the desktop palette keeps its metadata table over the same actions via a now-transitional
CanvasViewHandle(the registry schema can't carry icons/groups/keywords yet, and the shell needs the two viewport methods for open/close animations).Numbers
canvas-view-convergence.test.ts(shared-component assertions + M2 wire-shape golden + line-count ceiling) plus the 0276 drift tripwire.Validation
pnpm typecheckgreen; electron renderer additionally checked withtsc -b apps/electron/tsconfig.json(the desktop app has no typecheck script — pre-existing gap).🤖 Generated with Claude Code