feat(canvas): add snapshot sharing - #768
Draft
beruro wants to merge 4 commits into
Draft
Conversation
beruro
marked this pull request as draft
August 11, 2026 15:36
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.
Problem
Canvas has no dedicated way to publish one completed prototype. Reusing ORG2 Cloud session sharing applies the wrong eligibility and data scope, while embedding the whole compressed snapshot in the URL creates very long links. Link generation also lived at the mounted dialog boundary, so switching workstation tabs destroyed the result and generated/uploaded the same immutable Canvas again.
The missing invariant was a Canvas-only publication boundary with an explicit lifecycle: only the selected, stable Canvas may be serialized; session, conversation, repository, event, and account data must never cross it; completed links must remain reusable across Canvas tab remounts without creating unbounded retained state. The public URL also needs to be owned by ORG2 instead of depending on a personal GitHub Pages hostname.
Solution
CanvasShareEnvelopeV1containing onlymode,title,content, andurl; validate source size and public URL rules before encoding.https://canvas.org2.dev/for both hosted and self-contained links andhttps://canvas.org2.dev/api/canvas-sharesfor uploads. Regression coverage fixes that owned-origin contract for all three paths.closed -> preparing -> ready/error, with copy feedback, retry, operation generations, and stale-completion rejection.The owned viewer and same-origin Vercel proxy are introduced by ORGII-cloud-infra#20.
Potential risks
https://canvas.org2.dev/#/s/<id>and#/share/g1/<payload>both pass production checks.CompressionStreamAPI. Unsupported runtimes show a recoverable error instead of emitting an incompatible payload.https://beruro.github.io/canvas-share/links remain available only for backward compatibility. Rollback is to revert the desktop default origin and the infrastructure domain/project binding; already-issued legacy links are unaffected.State and edge coverage
Audit
Architecture audit covered domain vocabulary, discriminated state/types, click-to-network control flow, privacy data flow, configuration/limits, dead-code sweep, cache/runtime behavior, initialization defaults, wire validation, and viewer/API resolver symmetry. Rust/backend layers were intentionally skipped because this PR changes only the desktop frontend and its external HTTPS contract.
Frontend UI audit: 0 fixes recommended, 15 elements kept with documented reason, 0 abstraction candidates.
finallyPerformance verdict: pass. There is no idle resource, all active resources have a deadline or bounded owner, retained memory is capped, and applicable lifecycle invariants have focused regression coverage.
Effects: one lifecycle cleanup Effect in
useCanvasShareDialog; it invalidates the pending promise subscriber on unmount so a stale completion cannot write into the remounted UI. No timer, listener, or network resource is owned by that Effect. The owned-origin update adds or changes no Effects.Verification
pnpm verify:quick -- src/engines/Simulator/apps/canvas/CanvasApp.tsx src/engines/Simulator/apps/canvas/CanvasApp.share.test.ts src/features/CanvasShare/CanvasShareDialog.tsx src/features/CanvasShare/canvasShareCache.ts src/features/CanvasShare/canvasShareProtocol.ts src/features/CanvasShare/canvasShareProtocol.test.ts src/features/CanvasShare/index.ts src/features/CanvasShare/useCanvasShareDialog.ts src/features/CanvasShare/useCanvasShareDialog.test.ts— passed; 9 files linted and 24 focused tests passed.pnpm verify:final— executed a real full TypeScript check and passed after the test-only fixture correction.origin/develop, the current branch does not contain the repository's documentedverify:quick/verify:finalpackage scripts.pnpm verify:quick -- src/features/CanvasShare/canvasShareProtocol.ts src/features/CanvasShare/canvasShareProtocol.test.tswas attempted and returnedCommand "verify:quick" not found; no unsupported success claim is made for that wrapper.pnpm exec eslint src/features/CanvasShare/canvasShareProtocol.ts src/features/CanvasShare/canvasShareProtocol.test.ts— passed.pnpm exec vitest run src/features/CanvasShare/canvasShareProtocol.test.ts— passed, 1 file / 10 tests.pnpm typecheck— executed the branch's fulltsc --noEmit --pretty falsecheck and passed; no cache was used by this script.git diff --check— passed before commit.git rev-list --left-right --count origin/develop...HEADafter the final fetch —0 4; the branch contains the latestdevelopwith no base-only commits.canvas.org2.devsmoke testing was not run because infrastructure PR fix(Skill): Skills Menu & Import Skill bug #20 has not yet been deployed or bound to the domain.UI evidence
Manual UI screenshots were exercised in the originating desktop task (toolbar action, generated short/fallback viewer, and cross-tab repro). They are not attached here because the CLI PR update path does not provide an authenticated image-upload surface. The owned-origin update has no intentional desktop visual delta; production viewer evidence must be added after infrastructure PR #20 is deployed and before this PR is marked ready.