Repository navigation
Continue in Claude: one-click web→MCP part handoff - #315
Merged
Merged
Conversation
… handoff The server side of the web app's "Continue in Claude" handoff. The browser mints a public share token for the part the user is looking at and hands it to the model in the seed prompt; continue_document resolves it server-side via the get_shared_document RPC and opens it as a live MCP session — the geometry never rides the URL, only the opaque token does. Web docs store canonical CRDT state, so the tool materializes content to IR via the kernel engine's WasmDocumentEngine.load() (the same engine render_view boots); raw-IR/legacy content passes through. The opened session is a fresh mcp:-keyed session seeded from the geometry, so it renders inline (UI_META) and persists to the user's account (SWITCH_DOC_WRITERS) like any MCP-authored doc. - resolveShareToken() in session-store.ts (service-role get_shared_document RPC) - continue-doc.ts tool + registration + dispatch case - unit tests: token parsing, uuid guard, unknown-token hint, IR passthrough Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pure builders for the "Continue in Claude" host matrix. Encodes each host's real, verified mechanism: claude:// prefill for Claude Desktop, copy-to-paste for claude.ai web (the ?q= prefill was removed Oct 2025), chatgpt.com/?q= for ChatGPT, and the one-click MCP install deep links for Cursor (base64 config) and VS Code (url-encoded JSON, name inline) plus a claude-mcp-add one-liner for Claude Code. The seed carries only the share token + the continue_document tool name — never the geometry. 9 unit tests pin every encoder. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the user-facing entry point for the handoff. A sign-in-gated "Continue in Claude…" item in the File menu opens ContinueDialog, which mints (or reuses) a share token for the current cloud doc — token only, no public /@user/slug publish, so there's no username picker — and presents the host matrix from continue-links: open Claude Desktop / ChatGPT with the part prefilled, install + copy-to-paste for Cursor / VS Code / claude.ai web, and a copyable command for Claude Code. Remembers the last-used host. The model resolves the token with continue_document and renders the user's exact part. Also folds in a noUncheckedIndexedAccess fix in the continue-links encoder. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ry hints - Anon escape hatch: continue_document now accepts an inline `doc` (gzip + base64url IR) in addition to a share token, and the dialog compresses the live geometry into the seed for users without an account — length-guarded (MAX_INLINE_BLOB), falling back to a sign-in nudge for parts too big to ride a host URL. The File-menu item is no longer sign-in-gated. - Telemetry: continue_handoff event (host + token/inline mode) via the app analytics pipeline; continue_document tool calls are already captured server-side. - Directory readiness: continue_document carries MCP tool annotations (title, readOnlyHint, openWorldHint). Tests: inline-doc round-trip (app encoder <-> mcp decoder), oversize guard, corrupt-blob hint, inline seed shape. app 12 + mcp continue-doc 9, full mcp 302. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ation) continue_document now keys a token handoff to a deterministic session id (cont_<token>) instead of a random one, and reuses an already-open or durably persisted session before re-materializing from the share snapshot. Effects: - Idempotent: re-clicking "Continue" (or a cold-instance re-open) reattaches to the SAME session — the Living Viewport accretes in place and in-progress edits survive, matching the shipped accret-on-document_id behavior. - Rendezvous key: because the id derives from the token the web app minted, the vcad.io tab knows the session's durable row (mcp:cont_<token>) in advance — the primitive a future live-reflection panel subscribes to. The token is an unguessable UUID, so the derived id stays capability-safe. - Success payload nudges the verify loop (render_view -> verify_part/build_receipt). Inline (accountless) handoffs keep a fresh random id (no stable key). Tests: warm-cache reuse (one fetch), durable cold-instance rehydrate. mcp 306 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The "alive in both surfaces" beat. After a signed-in token handoff, the dialog shows a "Live in Claude" pill that pulses as the model edits the part: the continued session persists to the user's own documents row (mcp:cont_<token>), and the tab subscribes to Realtime changes on exactly that row. - migration 031: publish `documents` to supabase_realtime (idempotent, guarded). Owner RLS already scopes rows to the user, and Realtime enforces RLS per subscriber, so a user only ever receives their OWN document changes. - continueSessionRowKey(token): the shared mcp:cont_<token> contract between the server's keying and the tab's subscription (unit-tested rendezvous). - useClaudeLiveStatus(token): subscribes/cleans up the channel, counts edits. - ContinueDialog: the live pill, shown once a token host is launched. VERIFY: end-to-end (a real Claude session morphing the pill) needs a manual pass with the migration applied — it can't be driven headless. Pure parts (rowkey) and types are covered; app tsc -b clean, 13 link tests pass, migration dry-run OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Continue in Claude
A signed-in user looking at their part on vcad.io clicks File → Continue in Claude… and lands in Claude (or ChatGPT, or their editor) with their exact geometry already loaded and being edited — no blank slate, no copy-paste. The install is plumbing; the part teleports.
The geometry never rides the URL: the link carries a short share token, and a new
continue_documentMCP tool resolves it server-side and materializes the geometry.What's in here (7 commits)
V1 — the core
continue_documentMCP tool: resolves a share token via theget_shared_documentRPC, materializes raw CRDT content through the kernel engine (WasmDocumentEngine.load().get_document_json()— the enginerender_viewalready boots), opens a live session that renders inline + persists to the user's account.continue-links.ts: the verified per-host deep-link matrix — Claude Desktopclaude://claude.ai/new?q=(prefill), ChatGPTchatgpt.com/?q=, Cursor/VS Code one-click MCP install, Claude Code one-liner. (claude.ai web?q=was removed Oct 2025, so it's open-and-copy.)ContinueDialog+ File-menu item: mints/reuses a share token (no public profile publish → no username picker), host picker, remembers last host.V2 — reach + readiness
encodeDocForSeed, length-guarded), falling back to a sign-in nudge for large parts.continue_handofftelemetry;continue_documentMCP tool annotations for Anthropic Directory readiness.V3 — alive in both surfaces
cont_<token>rendezvous key: re-clicks reattach to the same session (Living Viewport accretes in place, edits survive), and it's the durable row key the tab can watch.documentsto Realtime; the dialog shows a "Live in Claude" pill that pulses as the model edits (owner-RLS scopes it to the user's own row).Verification
continue_document11 tests + full suite 306 pass; typecheck clean.continue-linkstests; whole-apptsc -bclean; app boots with no errors.supabase db push --dry-runOK (not applied — see below).documentstable to Supabase Realtime — a deliberate prod fan-out decision. RLS still scopes every event to its owner. Apply withsupabase db pushwhen ready.claude://claude.ai/new?q=scheme.🤖 Generated with Claude Code