feat(canvas): agent calls from browser clients and CodeRabbit round one
Merged
GN
2d ago+1512+1512+0123456789012345678901234567890123456789-684-684-012345678901234567890123456789
Summary
- Browser clients must serve agents like desktop windows, and review findings need fixes.
- Part 9 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
- Agent calls reach a browser lease holder and wait through a short reconnect; a canvas document must sit inside its own project.
- Fixes from the first CodeRabbit review: token in the bundle path instead of a third-party cookie, close by
mountSeq,.figcraft-only mounts, request size limits, queued unmount questions.
Scope
- E3-3 plus review fixes.
How It Was Tested
-
bun run typecheckon this branch - Each part is a checkpoint that was built and tested when it was made (
cargo testfor canvas and host_mcp, vitest, real runs in headless Edge). The bottom and top of the stack were rebuilt and re-tested on currentdev.
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
Browser clients now serve agents the same way desktop windows do, with the first round of CodeRabbit review fixes on top.
New Features
- Agent canvas calls reach a browser lease holder through the shared relay: calls wait through a reconnecting renderer inside the lease grace and resolve
CANVAS_CLOSEDwhen the grace expires. Covered on both the browser socket and desktopChannelcarriers.
Bug Fixes
- The canvas token is a path segment now, not a cookie; macOS and Linux webviews drop third-party cookies, so the bundle's sub-resources were failing to load.
- The document path must lie in the opening project's own root on both transports; desktop opens only canonicalized the path, so any file on disk could be opened.
- Close targets the renderer's
mountSeq, so a late close can't unmount a newer mount, and the bundle token is revoked only when the project has no mount. - Only
.figcraftdocuments mount; the extension check existed only at write time. - An oversize agent request answers
ENGINE_ERRORnaming the limit instead of a misreadCANVAS_CLOSED;/wsaccepts frames up to the bridge's reply cap. - Unmount questions queue instead of answering each other, and canvas iframes stay mounted behind the mid-session web token screen so a fresh iframe can't autosave an empty editor over the document.