feat(canvas): mount the figcraft editor and autosave from the host

Merged
GN
3d ago
+3912-3070

Summary

  • The canvas tab has to run the real editor and keep its document on disk without the editor touching the file system.
  • Part 2 of 10 in a stacked series. Review and merge bottom-up; each PR targets the one below it. Canvas mode v3 (figcraft engine). Spec: spec-openpencil-canvas-mode; architecture spine 2026-10-16 (AD-17 to AD-31).

Related Issue

No issue. Split from #1369 so each part stays under 50 files.

Type of Change

  • feat: new feature

What Changed

  • CanvasShell loads the kiosk editor in an iframe; canvas-bridge.ts speaks figcraft's control protocol with opaque JSON bodies, request ids per mount, mountSeq and an origin lock.
  • Rust owns the autosave debounce, savedVersion and the atomic write; the store holds a projection only. The Save button and Ctrl+S save.

Scope

  • E1-7, E2-1. Hidden mounts and the agent path come later in the stack.

How It Was Tested

  • bun run typecheck on this branch
  • Each part is a checkpoint that was built and tested when it was made (cargo test for canvas and host_mcp, vitest, real runs in headless Edge). The bottom and top of the stack were rebuilt and re-tested on current dev.

Checklist

  • PR title follows the conventional commit format
  • Explained why no issue exists
  • Added or updated tests
  • Read AGENTS.md
  • A human reviewed the complete diff before submission

🤖 Generated with Claude Code


Summary by cubic

The canvas tab now mounts the real figcraft editor in an iframe, with the host owning autosave, the saved version, and the atomic document write so the editor never touches the filesystem.

  • CanvasShell loads the kiosk editor; canvas-bridge.ts speaks figcraft's control protocol with opaque JSON bodies, per-mount request ids, mountSeq, and an origin lock.
  • Rust canvas::persistence owns one mount record per project: autosave debounce (default 1500 ms), phase gating, and the temp-and-rename write.
  • Desktop canvas_* commands and POST /canvas/* routes share one service, pinned by a parity test that drives one sequence through both.
  • The panel regains the Save button, unsaved dot, and save error display; Ctrl+S saves the active canvas while focus is in Termul's chrome.
  • Canvas documents are .figcraft files; a project without one opens design.figcraft, created on first save.