10 parallel research agents (R1-R10) investigated whether MCP can save scenes as saveable entities that the user later opens in the editor — rather than injecting via a dev-only window.__pascalScene hook. Key findings: - Editor is already backend-agnostic via onLoad/onSave callbacks (R2,R7) - Current persistence is localStorage-only, single key (R1) - Zero dynamic routes and no backend code yet — env declared (R4,R5) - File import exists as "Load Build" but lacks Zod validation (R6) - MCP-written scenes load cleanly into the editor today (R6, Casa del Sol test already proved this) - Best path: filesystem-handoff this week, Supabase in weeks 2-4, Supabase Realtime for live mode in Q2. Skip Yjs for now. (R8) - 4-5 weeks to private beta, 10-14 to GA (R9) - 10 high-value ideas ranked; "photo -> scene" is the unblocker (R10) SYNTHESIS.md pulls all 10 reports together with the recommended implementation plan. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.2 KiB
3.2 KiB
R7 — @pascal-app/editor public API
Exports (packages/editor/src/index.tsx)
Components: Editor (default), SettingsPanel, SitePanel, FloatingLevelSelector, SceneLoader, ViewerToolbarLeft, ViewerToolbarRight, Slider, SliderControl
Hooks/Stores: useEditor, useCommandRegistry, useSidebarStore, useUploadStore, useAudio, usePaletteViewRegistry, useCommandPalette
Utilities: applySceneGraphToEditor, SceneGraph (type), CATALOG_ITEMS, PresetsProvider, PresetsAdapter (type)
<Editor> host integration points
| Prop | Signature | Trigger | Host opportunity |
|---|---|---|---|
onLoad |
() => Promise<SceneGraph | null> |
Mount + onLoad identity change |
Fetch scene by id from backend |
onSave |
(scene) => Promise<void> |
1s debounce + beforeunload |
Persist to backend |
onDirty |
() => void |
First edit after save | Show "unsaved" badge |
onSaveStatusChange |
(status) => void |
idle/pending/saving/saved/paused/error |
Top-bar status indicator |
onThumbnailCapture |
(blob, cameraData) => void |
~10s idle after camera/scene stable, 1920×1080 SSGI | Upload to cloud, use in scene list |
appMenuButton, sidebarTop, navbarSlot, viewerToolbarLeft, viewerToolbarRight, sidebarOverlay, viewerBanner |
ReactNode |
Render slots | Drop in a "Scene picker" |
settingsPanelProps.onVisibilityChange |
(visible) => void |
User toggles project visibility | Project-level permissions |
sitePanelProps.onUploadAsset |
(projectId, levelId, file, type) |
Scan/guide image upload | S3/Supabase Storage |
sitePanelProps.onDeleteAsset |
(projectId, url) |
User deletes scan/guide | Clean up backend |
presetsAdapter |
PresetsAdapter |
Preset CRUD | Replace localStorage with backend-backed presets |
commandPaletteEmptyAction |
fn | No-match search | Route to AI / search |
extraSidebarPanels |
ExtraPanel[] |
Always visible | Add "Saved scenes" panel |
Sidebar slots suited for a scene switcher
- Layout v1:
appMenuButton(top-left) orsidebarTop(above tabs) - Layout v2:
navbarSlot(full-width top nav) - Both:
extraSidebarPanelsto add a dedicated "Scenes" tab
Command palette extension
useCommandRegistry().register([
{ id: 'editor.scene.open', label: 'Open scene…', group: 'Scene', execute: () => setShowSceneList(true) },
{ id: 'editor.scene.new', label: 'New scene', group: 'Scene', shortcut: ['Meta', 'N'], execute: createNewScene },
{ id: 'editor.scene.save-as', label: 'Save as…', group: 'Scene', execute: saveAs },
])
Effort to ship a minimal scene switcher inside this package
- Add
extraSidebarPanelsconsumer that takes ascenes: SceneMeta[]+onOpen(id)+onDelete(id)+onCreate()— ~150 lines. - Wire three palette commands — ~50 lines.
- Consume
onThumbnailCapturein the example host to populate list thumbnails — ~30 lines host-side. - Total ≈ 1–2 days for an in-editor scene browser, OR host-side if we keep the Editor scene-agnostic.
Verdict
The Editor's architecture is backend-agnostic by design. Every persistence decision is a host callback. Implementing the user's vision is 100% about wiring up what already exists — no Editor refactor needed.