docs(mcp): add 10-agent research on scene-save workflow
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>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
bdb47a6e5d
commit
42bd05db9c
@@ -0,0 +1,49 @@
|
||||
# R1 — Persistence layer
|
||||
|
||||
## TL;DR
|
||||
- **Scene data:** single-key localStorage, `pascal-editor-scene`, shape `{ nodes, rootNodeIds }`. Written by the autosave hook with 1 s debounce; flushed on `beforeunload`.
|
||||
- **UI preferences, viewer prefs, audio:** three separate Zustand-persist stores, each with its own localStorage key.
|
||||
- **Asset binaries (textures):** IndexedDB via `idb-keyval`, keys `asset_data:<uuid>`.
|
||||
- **Backend persistence:** NONE in this repo. No Supabase calls, no API routes for scenes, no database integration.
|
||||
- **Scene identity / listing:** NONE. One scene per origin per browser.
|
||||
|
||||
## Write pathways
|
||||
|
||||
| When | What | Where |
|
||||
|---|---|---|
|
||||
| 1 s after any scene mutation | `{ nodes, rootNodeIds }` → `onSave` callback (if provided) else `localStorage['pascal-editor-scene']` | `packages/editor/src/hooks/use-auto-save.ts:104–135` |
|
||||
| Every UI state mutation | `pascal-editor-ui-preferences` | Zustand persist in `use-editor.tsx:372–607` |
|
||||
| Every viewer state mutation | `viewer-preferences` | Zustand persist in `use-viewer.ts:81–220` |
|
||||
| Every audio state mutation | `pascal-audio-settings` | `use-audio.tsx:22–43` |
|
||||
| On `beforeunload` | Final scene snapshot | `use-auto-save.ts:137–147` |
|
||||
|
||||
## Read pathways
|
||||
|
||||
1. **Editor mount** (`editor/index.tsx:765–796`):
|
||||
- If host supplied `onLoad` → `await onLoad()`
|
||||
- Else → `loadSceneFromLocalStorage()`
|
||||
- Apply via `useScene.setScene(nodes, rootNodeIds)`
|
||||
2. **Selection hydration** — `syncEditorSelectionFromCurrentScene()` (`lib/scene.ts:251–332`)
|
||||
3. **Zustand persist** hydrates UI/viewer/audio stores automatically on first subscriber
|
||||
|
||||
## What's NOT persisted
|
||||
- Undo/redo history (`useScene.temporal` — in-memory only)
|
||||
- Active tool state (`movingNode`, `editingHole`, `curvingWall`)
|
||||
- Camera position/rotation
|
||||
- Collections (stored in nodes array but not in the persist partialize)
|
||||
- Three.js mesh/material cache
|
||||
|
||||
## Multi-scene support
|
||||
- Single global key `pascal-editor-scene`. No scene id, name, thumbnail, version.
|
||||
- `projectId` prop scopes UI **selection** (building/level/zone) but NOT scene data.
|
||||
- No listing, no metadata, no per-project isolation of the scene itself.
|
||||
|
||||
## Gap to "MCP writes → user opens saved scene"
|
||||
Needs:
|
||||
1. Scene entity layer: id, name, projectId, created_at, thumbnail_url.
|
||||
2. Backend table (or filesystem for local dev).
|
||||
3. MCP tools for scene lifecycle (`save_scene`, `list_scenes`, `load_scene`, `delete_scene`).
|
||||
4. Editor route `/scene/[id]` that reads scene by id on mount.
|
||||
5. Host-app `onLoad(() => fetchScene(sceneId))`.
|
||||
|
||||
Foundation is solid — `SceneGraph` type + `applySceneGraphToEditor` are production-ready; only the entity layer is missing.
|
||||
Reference in New Issue
Block a user