@volter/editor-core 0.5.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (719) hide show
  1. package/BUNDLED_NOTICES +1527 -0
  2. package/LICENSE +686 -0
  3. package/LICENSE-APACHE +202 -0
  4. package/NOTICE +18 -0
  5. package/README.md +24 -0
  6. package/dist/build/chunk-JS4D4XZ3.js +175 -0
  7. package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
  8. package/dist/build/vite-plugin-product-contributions.js +100 -0
  9. package/dist/build/vite-plugin-product-contributions.js.map +7 -0
  10. package/dist/build/vite-plugin-shared-react.js +25 -0
  11. package/dist/build/vite-plugin-shared-react.js.map +7 -0
  12. package/dist/build/vite-plugin-shared-three.js +86 -0
  13. package/dist/build/vite-plugin-shared-three.js.map +7 -0
  14. package/dist/server/chunk-KMJC7AGO.js +98 -0
  15. package/dist/server/chunk-KMJC7AGO.js.map +7 -0
  16. package/dist/server/chunk-PSILUMGS.js +46 -0
  17. package/dist/server/chunk-PSILUMGS.js.map +7 -0
  18. package/dist/server/frame-proxy.js +255 -0
  19. package/dist/server/frame-proxy.js.map +7 -0
  20. package/dist/server/open-browser.js +53 -0
  21. package/dist/server/open-browser.js.map +7 -0
  22. package/dist/server/process-shutdown.js +127 -0
  23. package/dist/server/process-shutdown.js.map +7 -0
  24. package/dist/server/session-registry.js +141 -0
  25. package/dist/server/session-registry.js.map +7 -0
  26. package/dist/server/spawn-opener.js +11 -0
  27. package/dist/server/spawn-opener.js.map +7 -0
  28. package/dist/server/worktree-identity.js +11 -0
  29. package/dist/server/worktree-identity.js.map +7 -0
  30. package/dist-server/packaged.mjs +88816 -0
  31. package/package.json +118 -0
  32. package/scripts/build-plugins.mjs +14 -0
  33. package/scripts/build-server.mjs +26 -0
  34. package/scripts/build-session.mjs +9 -0
  35. package/server/account-credentials.ts +60 -0
  36. package/server/account-service.ts +1434 -0
  37. package/server/adapter-region-includes.ts +47 -0
  38. package/server/asset-catalog-v2.ts +175 -0
  39. package/server/asset-history-snapshots.ts +196 -0
  40. package/server/asset-ledger-store.ts +195 -0
  41. package/server/asset-library-routes.ts +1595 -0
  42. package/server/blender-wasm-artifact.ts +430 -0
  43. package/server/boot-timings.ts +106 -0
  44. package/server/canonical-path.ts +50 -0
  45. package/server/checkout-workspace-preflight.ts +349 -0
  46. package/server/cloud-asset-catalog.ts +158 -0
  47. package/server/coding-inference-launch.ts +237 -0
  48. package/server/collaboration-account-client.ts +202 -0
  49. package/server/collaboration-attribution.ts +122 -0
  50. package/server/collaboration-session.ts +934 -0
  51. package/server/comfyui-bridge.ts +248 -0
  52. package/server/console-ledger.ts +499 -0
  53. package/server/creation-site-transform.ts +304 -0
  54. package/server/creation-site-write.ts +648 -0
  55. package/server/data-file-serialize.ts +158 -0
  56. package/server/editor-brand-html.ts +72 -0
  57. package/server/editor-control-socket.ts +366 -0
  58. package/server/editor-server-options.ts +190 -0
  59. package/server/editor-server.ts +1483 -0
  60. package/server/editor-sse.ts +352 -0
  61. package/server/engine-provenance.ts +169 -0
  62. package/server/engine-source-restart.ts +117 -0
  63. package/server/frame-bridge.ts +115 -0
  64. package/server/frame-proxy.ts +490 -0
  65. package/server/frame-workbench.ts +259 -0
  66. package/server/frontend-handoff.ts +229 -0
  67. package/server/game-globals-shadow.ts +113 -0
  68. package/server/gameplay-session-retention.ts +149 -0
  69. package/server/gameplay-sessions.ts +123 -0
  70. package/server/generation-jobs.ts +201 -0
  71. package/server/generation-reconciler.ts +137 -0
  72. package/server/generative-execution-context.ts +59 -0
  73. package/server/git-workflow.ts +612 -0
  74. package/server/harness-chat-caller.ts +36 -0
  75. package/server/harness-chat-service.ts +1681 -0
  76. package/server/idle-shutdown.ts +170 -0
  77. package/server/js-profiling-policy.ts +52 -0
  78. package/server/launcher-settings.ts +84 -0
  79. package/server/local-asset-catalog.ts +410 -0
  80. package/server/managed-account-defaults.ts +22 -0
  81. package/server/mock-control-plane.ts +540 -0
  82. package/server/model-import-conversion.ts +345 -0
  83. package/server/native-credential-store.ts +162 -0
  84. package/server/open-browser.ts +118 -0
  85. package/server/packaged.ts +1192 -0
  86. package/server/play-stall.ts +126 -0
  87. package/server/process-shutdown.ts +218 -0
  88. package/server/product-presets.ts +55 -0
  89. package/server/project-build-artifact.ts +95 -0
  90. package/server/project-components.ts +100 -0
  91. package/server/project-dependency-invalidation.ts +114 -0
  92. package/server/project-file-scan.ts +235 -0
  93. package/server/project-hmr-files.ts +215 -0
  94. package/server/project-install-roots.ts +210 -0
  95. package/server/project-kinds.ts +71 -0
  96. package/server/project-mcp-servers.ts +82 -0
  97. package/server/project-module-freshness.ts +109 -0
  98. package/server/project-module-instance.ts +375 -0
  99. package/server/project-optimize-deps-entries.ts +827 -0
  100. package/server/project-output-writer.ts +679 -0
  101. package/server/project-package-origin.ts +63 -0
  102. package/server/project-root-surface.ts +831 -0
  103. package/server/project-scratch-path.ts +47 -0
  104. package/server/project-script-hmr.ts +619 -0
  105. package/server/project-serving-plugins.ts +236 -0
  106. package/server/project-tools.ts +653 -0
  107. package/server/project-validation.ts +250 -0
  108. package/server/project-verbs.ts +127 -0
  109. package/server/project-view.ts +52 -0
  110. package/server/project-watch.ts +1134 -0
  111. package/server/project-work-coordinator.ts +288 -0
  112. package/server/provider-credentials.ts +331 -0
  113. package/server/recent-projects-store.ts +98 -0
  114. package/server/redact-secrets.ts +71 -0
  115. package/server/repository-presence.ts +267 -0
  116. package/server/routes/account.ts +357 -0
  117. package/server/routes/agents.ts +60 -0
  118. package/server/routes/assets.ts +154 -0
  119. package/server/routes/build.ts +13 -0
  120. package/server/routes/collaboration.ts +595 -0
  121. package/server/routes/configurations.ts +419 -0
  122. package/server/routes/context.ts +264 -0
  123. package/server/routes/control-plane.ts +1811 -0
  124. package/server/routes/logs.ts +272 -0
  125. package/server/routes/project-identity.ts +302 -0
  126. package/server/routes/project-open.ts +429 -0
  127. package/server/routes/project-source.ts +686 -0
  128. package/server/routes/project-state.ts +383 -0
  129. package/server/routes/relay.ts +1029 -0
  130. package/server/routes/route-helpers.ts +29 -0
  131. package/server/routes/served-modules.ts +138 -0
  132. package/server/routes/session-tabs.ts +196 -0
  133. package/server/routes/settings.ts +121 -0
  134. package/server/routes/share-control.ts +486 -0
  135. package/server/routes/themes.ts +116 -0
  136. package/server/routes/tools.ts +230 -0
  137. package/server/routes/worktrees.ts +595 -0
  138. package/server/scoped-game-css.ts +461 -0
  139. package/server/server-utils.ts +1194 -0
  140. package/server/session-product.ts +112 -0
  141. package/server/session-registry.ts +230 -0
  142. package/server/share-claims.ts +138 -0
  143. package/server/share-host.ts +526 -0
  144. package/server/share-session-gateway.ts +1362 -0
  145. package/server/share-tunnel.ts +123 -0
  146. package/server/spawn-opener.ts +74 -0
  147. package/server/support/play/log-format.ts +76 -0
  148. package/server/support/play/session-record.ts +199 -0
  149. package/server/support/project/build-discipline.ts +718 -0
  150. package/server/support/project/inspection-node.ts +119 -0
  151. package/server/support/project/log-naming.ts +54 -0
  152. package/server/support/project/provenance.ts +290 -0
  153. package/server/support/project/run-name.ts +18 -0
  154. package/server/support/project/session-journal.ts +830 -0
  155. package/server/support/project/shared.ts +327 -0
  156. package/server/tab-bootstrap.ts +62 -0
  157. package/server/tab-heartbeat.ts +477 -0
  158. package/server/tab-lifecycle.ts +550 -0
  159. package/server/tab-presence.ts +1508 -0
  160. package/server/team-agent-mirror.ts +95 -0
  161. package/server/twin-auth.ts +138 -0
  162. package/server/vendored-lock-recorder.ts +968 -0
  163. package/server/worktree-identity.ts +121 -0
  164. package/server/worktree-management.ts +398 -0
  165. package/server/worktree-retention.d.mts +13 -0
  166. package/server/worktree-retention.mjs +205 -0
  167. package/src/EditorContext.tsx +169 -0
  168. package/src/account.ts +333 -0
  169. package/src/action-registry.ts +532 -0
  170. package/src/active-product.ts +74 -0
  171. package/src/active-project.ts +155 -0
  172. package/src/adapter-editor-config.ts +25 -0
  173. package/src/adapter-observation.ts +49 -0
  174. package/src/animation/stage-transport.ts +379 -0
  175. package/src/animation/three-clips-subject.ts +172 -0
  176. package/src/api/asset-library-wire.ts +45 -0
  177. package/src/api/assets.ts +365 -0
  178. package/src/api/base.ts +10 -0
  179. package/src/api/build.ts +99 -0
  180. package/src/api/git-wire.ts +56 -0
  181. package/src/api/logs.ts +92 -0
  182. package/src/api/project-identity.ts +74 -0
  183. package/src/api/project-open.ts +355 -0
  184. package/src/api/project-source.ts +162 -0
  185. package/src/api/project-state.ts +107 -0
  186. package/src/api/relay.ts +268 -0
  187. package/src/api/settings.ts +36 -0
  188. package/src/api/themes.ts +45 -0
  189. package/src/api/worktrees.ts +257 -0
  190. package/src/asset-compare-core.ts +171 -0
  191. package/src/asset-compare.ts +294 -0
  192. package/src/asset-editor-context.tsx +100 -0
  193. package/src/asset-events.ts +97 -0
  194. package/src/asset-inspector-actions.ts +87 -0
  195. package/src/asset-preview-framing.ts +357 -0
  196. package/src/asset-preview.ts +2802 -0
  197. package/src/asset-selection-viewer-registry.ts +113 -0
  198. package/src/asset-selection.ts +133 -0
  199. package/src/asset-workflow/asset-capabilities.ts +344 -0
  200. package/src/asset-workflow/asset-import-jobs.ts +106 -0
  201. package/src/asset-workflow/asset-ledger-backend.ts +126 -0
  202. package/src/asset-workflow/asset-ledger.ts +156 -0
  203. package/src/asset-workflow/asset-materialization-report.ts +140 -0
  204. package/src/asset-workflow/asset-pack-manifest.ts +320 -0
  205. package/src/asset-workflow/asset-types.ts +142 -0
  206. package/src/asset-workflow/asset-workflow-quality.ts +61 -0
  207. package/src/asset-workflow/audio-preview-player.ts +193 -0
  208. package/src/asset-workflow/audio-waveform.ts +22 -0
  209. package/src/asset-workflow/cloud-asset-client.ts +263 -0
  210. package/src/asset-workflow/folder-preview.ts +345 -0
  211. package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
  212. package/src/asset-workflow/image-view-scale.ts +32 -0
  213. package/src/asset-workflow/import-contract.ts +124 -0
  214. package/src/asset-workflow/ledger-write-lock.ts +244 -0
  215. package/src/asset-workflow/model-inspection.ts +818 -0
  216. package/src/asset-workflow/pixi-spritesheet.ts +197 -0
  217. package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
  218. package/src/asset-workflow/project-asset-commands.ts +23 -0
  219. package/src/asset-workflow/project-asset-health.ts +139 -0
  220. package/src/asset-workflow/project-asset-operations.ts +154 -0
  221. package/src/asset-workflow/project-asset-roots.ts +68 -0
  222. package/src/asset-workflow/project-content.ts +288 -0
  223. package/src/asset-workflow/project-source-index.ts +550 -0
  224. package/src/asset-workflow/thumbnail-system.ts +256 -0
  225. package/src/authoring/active-adapter.ts +199 -0
  226. package/src/authoring/active-systems.ts +422 -0
  227. package/src/authoring/adapter-key.ts +18 -0
  228. package/src/authoring/authoring-asset-url.ts +27 -0
  229. package/src/authoring/bootstrap-state.ts +49 -0
  230. package/src/authoring/boundary-authoring-adapter.ts +184 -0
  231. package/src/authoring/breakpoint-state.ts +43 -0
  232. package/src/authoring/canvas-scene-guides.ts +76 -0
  233. package/src/authoring/component-instance-root.ts +171 -0
  234. package/src/authoring/composite-authoring-adapter.ts +2110 -0
  235. package/src/authoring/consumer-actions.ts +520 -0
  236. package/src/authoring/css-numeric-style.ts +97 -0
  237. package/src/authoring/design-time-layers.ts +849 -0
  238. package/src/authoring/design-time-mount-registry.ts +235 -0
  239. package/src/authoring/design-time-settle.ts +343 -0
  240. package/src/authoring/edit-mode-authoring.ts +619 -0
  241. package/src/authoring/eyedropper-session.ts +60 -0
  242. package/src/authoring/instance-source-menu-register.ts +13 -0
  243. package/src/authoring/instance-source-menu.ts +135 -0
  244. package/src/authoring/layered-pick.ts +183 -0
  245. package/src/authoring/live-gesture-lock.ts +50 -0
  246. package/src/authoring/live-object-transform.ts +62 -0
  247. package/src/authoring/mount-failure-report.ts +154 -0
  248. package/src/authoring/mounted-root-subjects.ts +144 -0
  249. package/src/authoring/no-authoring-adapter.ts +55 -0
  250. package/src/authoring/null-inspection-subjects.tsx +75 -0
  251. package/src/authoring/object3d-document-persistence.ts +106 -0
  252. package/src/authoring/object3d-document-session-registry.ts +120 -0
  253. package/src/authoring/object3d-document-session.ts +1326 -0
  254. package/src/authoring/object3d-gesture-controller.ts +113 -0
  255. package/src/authoring/panel-authoring.ts +121 -0
  256. package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
  257. package/src/authoring/prefab-instance-section-model.ts +55 -0
  258. package/src/authoring/project-authoring-session.ts +105 -0
  259. package/src/authoring/provenance.ts +99 -0
  260. package/src/authoring/quarks-particle-systems.ts +19 -0
  261. package/src/authoring/react-canvas-navigation.ts +255 -0
  262. package/src/authoring/react-design-canvas-style.ts +20 -0
  263. package/src/authoring/react-story-board.ts +937 -0
  264. package/src/authoring/selection-scope.ts +195 -0
  265. package/src/authoring/shell-document-ops.ts +169 -0
  266. package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
  267. package/src/authoring/shell-viewport-policy.ts +48 -0
  268. package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
  269. package/src/authoring/stories-scope.ts +35 -0
  270. package/src/authoring/story-board-chrome-fit.ts +107 -0
  271. package/src/authoring/story-board-presentation.ts +111 -0
  272. package/src/authoring/three-projection-core.ts +226 -0
  273. package/src/authoring/viewport-pick-context.ts +40 -0
  274. package/src/authoring/viewport-raycast.ts +240 -0
  275. package/src/authoring/viewport-tool-context.ts +73 -0
  276. package/src/authoring/world-canvas-viewport-state.ts +35 -0
  277. package/src/authoring/world-hidden-viewport.ts +152 -0
  278. package/src/authoring/world-pan-state.ts +198 -0
  279. package/src/authoring/world-session-state.ts +101 -0
  280. package/src/authoring/write-pipe.ts +173 -0
  281. package/src/availability-tick.ts +66 -0
  282. package/src/bitmap-label.ts +120 -0
  283. package/src/blender-tab-metrics.ts +161 -0
  284. package/src/board-open-actions.ts +20 -0
  285. package/src/boot-routing.ts +391 -0
  286. package/src/build-identity.ts +15 -0
  287. package/src/bytes-codec.ts +62 -0
  288. package/src/camera-authoring.ts +175 -0
  289. package/src/cancellation-reason.ts +58 -0
  290. package/src/canvas-preview-frames.ts +482 -0
  291. package/src/capture-camera-pose.ts +77 -0
  292. package/src/chrome-registry.ts +159 -0
  293. package/src/chrome-slot-registry.ts +91 -0
  294. package/src/collaboration-client.ts +264 -0
  295. package/src/collaboration-presence.ts +41 -0
  296. package/src/command-dispatch.ts +19 -0
  297. package/src/command-listener.ts +2743 -0
  298. package/src/command-registry.ts +70 -0
  299. package/src/component-board-registry.ts +205 -0
  300. package/src/component-states-registry.ts +200 -0
  301. package/src/components/AgentPresentationNotice.tsx +75 -0
  302. package/src/components/AlignToolbar.tsx +204 -0
  303. package/src/components/AppRoot.tsx +394 -0
  304. package/src/components/ApplicationMenus.tsx +415 -0
  305. package/src/components/AssetBrowser.tsx +2843 -0
  306. package/src/components/AssetEditorShell.tsx +216 -0
  307. package/src/components/AssetInspectorToolSection.tsx +124 -0
  308. package/src/components/BoardRulers.tsx +354 -0
  309. package/src/components/CameraInfo.tsx +81 -0
  310. package/src/components/CanvasSceneViewport.tsx +556 -0
  311. package/src/components/CapabilityCoverageSection.tsx +185 -0
  312. package/src/components/CenterDocuments.tsx +22 -0
  313. package/src/components/ChromeSlot.tsx +20 -0
  314. package/src/components/CodeView.tsx +470 -0
  315. package/src/components/CollaborationHeaderControl.css +74 -0
  316. package/src/components/CompactInspectorCard.tsx +190 -0
  317. package/src/components/CompactInspectorShell.tsx +39 -0
  318. package/src/components/ConsolePanel.css +55 -0
  319. package/src/components/ConsolePanel.tsx +270 -0
  320. package/src/components/DefaultEditorLayout.tsx +106 -0
  321. package/src/components/DocumentHeaderStrip.tsx +96 -0
  322. package/src/components/DocumentShelfRail.tsx +45 -0
  323. package/src/components/DocumentThumbnail.tsx +345 -0
  324. package/src/components/EditorLeaseGuard.tsx +372 -0
  325. package/src/components/ErrorBanner.tsx +123 -0
  326. package/src/components/FolderPreviewTile.tsx +159 -0
  327. package/src/components/GameHierarchy.tsx +3842 -0
  328. package/src/components/GameplaySessionTimeline.tsx +295 -0
  329. package/src/components/InspectionProjection.tsx +968 -0
  330. package/src/components/Inspector.tsx +233 -0
  331. package/src/components/InspectorCanvasPreview.tsx +35 -0
  332. package/src/components/InspectorFieldsSection.tsx +290 -0
  333. package/src/components/InspectorObjectPreview.tsx +57 -0
  334. package/src/components/InspectorStoriesSection.tsx +92 -0
  335. package/src/components/InspectorToolSection.tsx +96 -0
  336. package/src/components/InspectorTransformSection.tsx +245 -0
  337. package/src/components/LightExplorerPanel.tsx +433 -0
  338. package/src/components/MediaProperties.tsx +145 -0
  339. package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
  340. package/src/components/Object3DDocumentToolbar.css +100 -0
  341. package/src/components/Object3DDocumentToolbar.tsx +454 -0
  342. package/src/components/Object3DDocumentViewport.tsx +58 -0
  343. package/src/components/ProjectHeader.css +617 -0
  344. package/src/components/ProjectHeader.tsx +328 -0
  345. package/src/components/ProjectLayout.tsx +249 -0
  346. package/src/components/ReactCanvasControls.tsx +284 -0
  347. package/src/components/RootSelectionOverlay.tsx +3162 -0
  348. package/src/components/RootTextEditor.tsx +79 -0
  349. package/src/components/SaveStatus.tsx +70 -0
  350. package/src/components/StageHost.tsx +1954 -0
  351. package/src/components/StageOverlays.tsx +21 -0
  352. package/src/components/StartupErrorScreen.tsx +76 -0
  353. package/src/components/StartupLoadingScreen.tsx +65 -0
  354. package/src/components/StatsOverlay.tsx +78 -0
  355. package/src/components/SurfaceStateOverlay.tsx +24 -0
  356. package/src/components/ToolContributionSurfaces.tsx +65 -0
  357. package/src/components/ToolHost.tsx +370 -0
  358. package/src/components/ToolObject3DPreview.tsx +39 -0
  359. package/src/components/Toolbar.tsx +595 -0
  360. package/src/components/TransientHint.tsx +44 -0
  361. package/src/components/TransportStrip.tsx +174 -0
  362. package/src/components/VersionControlSection.tsx +470 -0
  363. package/src/components/VgaiLogo.css +83 -0
  364. package/src/components/VgaiLogo.tsx +35 -0
  365. package/src/components/ViewportControlsHint.tsx +60 -0
  366. package/src/components/ViewportFurniture.tsx +401 -0
  367. package/src/components/ViewportOverlay.tsx +145 -0
  368. package/src/components/ViewportOverlaysMenu.tsx +153 -0
  369. package/src/components/ViewportShadingMenu.tsx +300 -0
  370. package/src/components/ViewportViewMenu.tsx +101 -0
  371. package/src/components/WorkspaceDocumentSurface.tsx +204 -0
  372. package/src/components/WorkspaceUtilitySurface.tsx +22 -0
  373. package/src/components/WorktreeSwitcher.css +239 -0
  374. package/src/components/WorktreeSwitcher.tsx +890 -0
  375. package/src/components/account-documents.tsx +1162 -0
  376. package/src/components/asset-documents.tsx +812 -0
  377. package/src/components/asset-editor-persistence.ts +216 -0
  378. package/src/components/asset-selection-section.tsx +535 -0
  379. package/src/components/asset-thumbnails.tsx +312 -0
  380. package/src/components/asset-viewers/AudioViewer.tsx +201 -0
  381. package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
  382. package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
  383. package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
  384. package/src/components/asset-viewers/ImageViewer.tsx +300 -0
  385. package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
  386. package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
  387. package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
  388. package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
  389. package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
  390. package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
  391. package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
  392. package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
  393. package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
  394. package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
  395. package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
  396. package/src/components/asset-viewers/VideoViewer.tsx +101 -0
  397. package/src/components/asset-viewers/shader-source.ts +144 -0
  398. package/src/components/asset-workflow.css +731 -0
  399. package/src/components/board-guides.ts +150 -0
  400. package/src/components/compact-inspector.css +539 -0
  401. package/src/components/core-utilities.tsx +90 -0
  402. package/src/components/editor-notifications.css +40 -0
  403. package/src/components/engine-workspace.css +274 -0
  404. package/src/components/inspector-preview-section.tsx +238 -0
  405. package/src/components/inspector-property-grouping.ts +64 -0
  406. package/src/components/inspector-revert-label.ts +20 -0
  407. package/src/components/inspector-selection.ts +42 -0
  408. package/src/components/inspector-stories-gating.ts +171 -0
  409. package/src/components/inspector-transform-subject.ts +11 -0
  410. package/src/components/inspector-transform.ts +75 -0
  411. package/src/components/kind-documents.tsx +500 -0
  412. package/src/components/palette-action-publisher.tsx +140 -0
  413. package/src/components/primitives/DraftColorInput.tsx +74 -0
  414. package/src/components/product-shell.css +1829 -0
  415. package/src/components/project-tool-documents.tsx +410 -0
  416. package/src/components/scene-documents.tsx +223 -0
  417. package/src/components/stage-keyboard.tsx +37 -0
  418. package/src/components/stage-overlay-set.tsx +107 -0
  419. package/src/components/stage-presence-markers.ts +478 -0
  420. package/src/components/standard-viewport-dressing.ts +417 -0
  421. package/src/components/status-contributions.tsx +403 -0
  422. package/src/components/tool-documents.tsx +309 -0
  423. package/src/components/tool-schema-form.tsx +262 -0
  424. package/src/components/use-after-paint.ts +41 -0
  425. package/src/components/use-project-image-assets.ts +86 -0
  426. package/src/components/viewport-header-controls.css +90 -0
  427. package/src/components/viewport-surface-status.tsx +55 -0
  428. package/src/components/workspace-history.ts +32 -0
  429. package/src/components/workspace-static-panel-registry.tsx +152 -0
  430. package/src/components/workspace-surfaces.css +621 -0
  431. package/src/components/world-documents.tsx +586 -0
  432. package/src/components/world-overlay-gestures.ts +1694 -0
  433. package/src/composite-screenshot.ts +1641 -0
  434. package/src/console-sync.ts +131 -0
  435. package/src/constraint-helper.ts +338 -0
  436. package/src/content-entry-source-registry.ts +184 -0
  437. package/src/coverage/authoring-seam-evidence.ts +300 -0
  438. package/src/coverage/canvas-reveal.ts +192 -0
  439. package/src/coverage/design-time-surfaces.ts +101 -0
  440. package/src/coverage/live-seam-evidence.ts +11 -0
  441. package/src/coverage/ontology-invariants.ts +466 -0
  442. package/src/coverage/session-vitals.ts +501 -0
  443. package/src/coverage/system-seam-evidence.ts +72 -0
  444. package/src/crash-null-boundary.ts +36 -0
  445. package/src/creation-site-edit.ts +1479 -0
  446. package/src/creation-site-registry.ts +160 -0
  447. package/src/delegate-harness-registry.ts +143 -0
  448. package/src/document-context-registry.ts +177 -0
  449. package/src/document-open-registry.ts +200 -0
  450. package/src/document-preview-source.ts +20 -0
  451. package/src/document-renderer-session.ts +138 -0
  452. package/src/editor-api.ts +46 -0
  453. package/src/editor-chrome-capture.ts +139 -0
  454. package/src/editor-commands.ts +164 -0
  455. package/src/editor-console.ts +563 -0
  456. package/src/editor-current-view.ts +82 -0
  457. package/src/editor-document-probe.ts +881 -0
  458. package/src/editor-git-client.ts +115 -0
  459. package/src/editor-host-door.ts +462 -0
  460. package/src/editor-hotkeys.ts +842 -0
  461. package/src/editor-lease-view.ts +39 -0
  462. package/src/editor-lease.ts +415 -0
  463. package/src/editor-mode.ts +19 -0
  464. package/src/editor-notifications.ts +140 -0
  465. package/src/editor-presence.ts +563 -0
  466. package/src/editor-presentation-activity.ts +50 -0
  467. package/src/editor-presentation-notice.ts +42 -0
  468. package/src/editor-runtime.tsx +145 -0
  469. package/src/editor-server-response.ts +86 -0
  470. package/src/editor-session-attribution.ts +75 -0
  471. package/src/editor-session-mode.ts +54 -0
  472. package/src/editor-shell-store.ts +1304 -0
  473. package/src/editor-state-facets.ts +74 -0
  474. package/src/editor-styles.css +33 -0
  475. package/src/editor-view-presentation.ts +810 -0
  476. package/src/editor-viewport.ts +5302 -0
  477. package/src/entity-lod.ts +31 -0
  478. package/src/entity-object.ts +91 -0
  479. package/src/files/file-provider.ts +62 -0
  480. package/src/files/project-files.ts +264 -0
  481. package/src/finders/index.ts +136 -0
  482. package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
  483. package/src/frame/bridge.tsx +1408 -0
  484. package/src/frame/product.ts +77 -0
  485. package/src/gameplay-dom-recording.ts +319 -0
  486. package/src/gameplay-export-state.ts +14 -0
  487. package/src/gameplay-replay.ts +417 -0
  488. package/src/gameplay-session-time.ts +9 -0
  489. package/src/gameplay-sessions.ts +204 -0
  490. package/src/harness-chat-types.ts +253 -0
  491. package/src/hierarchy-component-marks.ts +298 -0
  492. package/src/hierarchy-drop.ts +91 -0
  493. package/src/hierarchy-expansion-state.ts +80 -0
  494. package/src/hierarchy-header-slot.ts +52 -0
  495. package/src/hierarchy-internals.ts +197 -0
  496. package/src/hierarchy-kind-icon.ts +217 -0
  497. package/src/hierarchy-mark-reader.ts +73 -0
  498. package/src/hierarchy-menu-registry.ts +67 -0
  499. package/src/hierarchy-node-rows.ts +307 -0
  500. package/src/hierarchy-panel-view.ts +280 -0
  501. package/src/hierarchy-projection.ts +76 -0
  502. package/src/hierarchy-row-cache.ts +243 -0
  503. package/src/hierarchy-row-model.ts +308 -0
  504. package/src/hierarchy-rows.ts +11 -0
  505. package/src/hierarchy-walk.ts +86 -0
  506. package/src/history/editor-session.ts +25 -0
  507. package/src/history/history-commands.ts +147 -0
  508. package/src/history/history-delegate.ts +163 -0
  509. package/src/history/history-limit-notices.ts +43 -0
  510. package/src/history/history-service.ts +1173 -0
  511. package/src/history/persistence-coordinator.ts +35 -0
  512. package/src/history/project-file-history.ts +386 -0
  513. package/src/history/project-root-history-backends.ts +139 -0
  514. package/src/history/resource-registry.ts +209 -0
  515. package/src/history/snapshot-store.ts +103 -0
  516. package/src/history/source-history-backend.ts +546 -0
  517. package/src/history/types.ts +124 -0
  518. package/src/hmr-registration-group.ts +67 -0
  519. package/src/hmr-stable-react-context.ts +23 -0
  520. package/src/hotkeys.ts +188 -0
  521. package/src/inference-diagnostics.ts +69 -0
  522. package/src/initial-project.ts +80 -0
  523. package/src/inspection/active-subject.ts +578 -0
  524. package/src/inspection/active-surface.ts +142 -0
  525. package/src/inspection/compose.ts +1064 -0
  526. package/src/inspection/display.ts +170 -0
  527. package/src/inspection/document-subject.ts +109 -0
  528. package/src/inspection/game-subject.ts +85 -0
  529. package/src/inspection/model.ts +542 -0
  530. package/src/inspection/null-subject.ts +115 -0
  531. package/src/inspection/serialize.ts +357 -0
  532. package/src/inspection/use-active-inspection.ts +180 -0
  533. package/src/inspector-presentation.ts +201 -0
  534. package/src/inspector-section-registry.ts +221 -0
  535. package/src/instance-source-actions.ts +163 -0
  536. package/src/instanced-presentation.ts +164 -0
  537. package/src/js-heap.ts +71 -0
  538. package/src/key-actions.ts +91 -0
  539. package/src/keymap-presets.ts +401 -0
  540. package/src/layout-policy.ts +31 -0
  541. package/src/learn-links.ts +73 -0
  542. package/src/light-explorer-model.ts +134 -0
  543. package/src/live-canvas-frame.ts +55 -0
  544. package/src/live-document.ts +279 -0
  545. package/src/live-module-source.ts +230 -0
  546. package/src/live-session-registry.ts +220 -0
  547. package/src/live-transition.ts +633 -0
  548. package/src/manifest-project.ts +107 -0
  549. package/src/model-thumbnail.ts +523 -0
  550. package/src/native-selection-style.ts +202 -0
  551. package/src/object3d-document-write-policy.ts +137 -0
  552. package/src/packaged-runtime.ts +108 -0
  553. package/src/palettes/maya.palette.json +57 -0
  554. package/src/palettes/substance.palette.json +57 -0
  555. package/src/pasteboard-module.ts +81 -0
  556. package/src/performance-profiler.ts +367 -0
  557. package/src/performance-sources.ts +69 -0
  558. package/src/play-boot-phase.ts +145 -0
  559. package/src/presentation-surface.ts +248 -0
  560. package/src/project-adapter.ts +1143 -0
  561. package/src/project-asset-refresh.ts +26 -0
  562. package/src/project-declaration-refresh.ts +31 -0
  563. package/src/project-local-state.ts +118 -0
  564. package/src/project-manager.ts +243 -0
  565. package/src/project-module-changes.ts +163 -0
  566. package/src/project-module-split.ts +266 -0
  567. package/src/project-provenance.ts +115 -0
  568. package/src/project-ready.ts +42 -0
  569. package/src/project-session-reset.ts +67 -0
  570. package/src/project-shape.ts +68 -0
  571. package/src/project-tool-discovery.ts +66 -0
  572. package/src/project-tools.ts +107 -0
  573. package/src/project-work-types.ts +149 -0
  574. package/src/projection/three.ts +898 -0
  575. package/src/projection/types.ts +44 -0
  576. package/src/readiness.ts +113 -0
  577. package/src/reflection-probe-helper.ts +142 -0
  578. package/src/reported-play-state.ts +90 -0
  579. package/src/resolve-relative-specifier.ts +33 -0
  580. package/src/scene-document-plan.ts +315 -0
  581. package/src/scene-framing.ts +315 -0
  582. package/src/scene-live-open.ts +210 -0
  583. package/src/scene-view-fog.ts +89 -0
  584. package/src/scoped-game-css.ts +152 -0
  585. package/src/session-orphan-record.ts +193 -0
  586. package/src/session-tombstone.ts +126 -0
  587. package/src/settings/settings-provider.ts +82 -0
  588. package/src/settings-store.ts +345 -0
  589. package/src/shared-view-restore.ts +42 -0
  590. package/src/shell-store-door.ts +45 -0
  591. package/src/source-conflict.ts +122 -0
  592. package/src/spatial-handle-visuals.ts +332 -0
  593. package/src/stage-context.ts +341 -0
  594. package/src/stage-store-registry.ts +63 -0
  595. package/src/stale-chunk-recovery.ts +34 -0
  596. package/src/state-report-deferral.ts +73 -0
  597. package/src/storage/host-files-storage.ts +97 -0
  598. package/src/storage/http-storage.ts +174 -0
  599. package/src/storage/index.ts +75 -0
  600. package/src/storage/mem-storage.ts +149 -0
  601. package/src/storage/path-lock.ts +44 -0
  602. package/src/storage/paths.ts +26 -0
  603. package/src/storage/types.ts +116 -0
  604. package/src/stories/StoryComponentThumbnail.tsx +184 -0
  605. package/src/stories/StoryPreviewMount.tsx +306 -0
  606. package/src/stories/component-content-source.tsx +106 -0
  607. package/src/stories/component-states-source.ts +78 -0
  608. package/src/stories/compose-project-stories.ts +255 -0
  609. package/src/stories/pixi-story-model.ts +30 -0
  610. package/src/stories/prefabs-finder.ts +54 -0
  611. package/src/stories/prefabs-from-stories.ts +182 -0
  612. package/src/stories/project-story-discovery.ts +78 -0
  613. package/src/stories/project-story-regions.ts +24 -0
  614. package/src/stories/story-actions.ts +54 -0
  615. package/src/stories/story-capture-command.ts +124 -0
  616. package/src/stories/story-capture.ts +584 -0
  617. package/src/stories/story-declared-medium.ts +126 -0
  618. package/src/stories/story-discovery.ts +176 -0
  619. package/src/stories/story-document-openers.ts +36 -0
  620. package/src/stories/story-dom-runtime.ts +78 -0
  621. package/src/stories/story-grouping.ts +111 -0
  622. package/src/stories/story-lane.ts +88 -0
  623. package/src/stories/story-mount-turn.ts +27 -0
  624. package/src/stories/story-opener.ts +260 -0
  625. package/src/stories/story-pixi-preview.ts +408 -0
  626. package/src/stories/story-presentation.ts +215 -0
  627. package/src/stories/story-registry.ts +517 -0
  628. package/src/stories/story-three-preview.ts +807 -0
  629. package/src/stories/three-story-model.ts +96 -0
  630. package/src/story-three-preview-runtime.ts +56 -0
  631. package/src/surface-keyboard.ts +112 -0
  632. package/src/surface-state.ts +124 -0
  633. package/src/tab-bootstrap.js +628 -0
  634. package/src/tab-census.ts +198 -0
  635. package/src/tab-lifecycle-client.ts +196 -0
  636. package/src/theme-library.ts +844 -0
  637. package/src/theme-preference.ts +378 -0
  638. package/src/theme.css +3437 -0
  639. package/src/three-viewport/bone-selection-highlight.ts +119 -0
  640. package/src/three-viewport/camera-fit.ts +41 -0
  641. package/src/three-viewport/interactive-renderer.ts +132 -0
  642. package/src/three-viewport/selection-brackets.ts +310 -0
  643. package/src/three-viewport/selection-outline.ts +183 -0
  644. package/src/three-viewport/skeleton-helper.ts +61 -0
  645. package/src/three-viewport/source-color.ts +167 -0
  646. package/src/three-viewport/studio-environment.ts +96 -0
  647. package/src/three-viewport-presentation.ts +23 -0
  648. package/src/tool-contribution-play.ts +74 -0
  649. package/src/tool-loader.ts +1798 -0
  650. package/src/transform-mode-request.ts +57 -0
  651. package/src/transient-hint.ts +78 -0
  652. package/src/trigger-volume-helper.ts +116 -0
  653. package/src/ui-source/adapter-region-includes.ts +241 -0
  654. package/src/ui-source/ensure-import.ts +132 -0
  655. package/src/ui-source/file-region-resolver.ts +302 -0
  656. package/src/ui-source/inspect.ts +775 -0
  657. package/src/ui-source/oid-transform.ts +1845 -0
  658. package/src/ui-source/plan-csf-story.ts +196 -0
  659. package/src/ui-source/plan-extract-component.ts +421 -0
  660. package/src/ui-source/plan-fork-component.ts +621 -0
  661. package/src/ui-source/plan-named-style.ts +95 -0
  662. package/src/ui-source/plan-source-edit.ts +353 -0
  663. package/src/ui-source/r3f-contract-resolver.ts +327 -0
  664. package/src/ui-source/r3f-diagnostic-index.ts +165 -0
  665. package/src/ui-source/r3f-environment-binding.ts +133 -0
  666. package/src/ui-source/r3f-joint-binding.ts +251 -0
  667. package/src/ui-source/r3f-lod-binding.ts +91 -0
  668. package/src/ui-source/r3f-particle-binding.ts +235 -0
  669. package/src/ui-source/r3f-physics-binding.ts +483 -0
  670. package/src/ui-source/r3f-project-contracts.ts +444 -0
  671. package/src/ui-source/relative-import-specifier.ts +34 -0
  672. package/src/ui-source/reparent-guard.ts +544 -0
  673. package/src/ui-source/source-edit-request.ts +97 -0
  674. package/src/ui-source/source-write-backend.ts +618 -0
  675. package/src/ui-source/syntactic-prop-specs.ts +296 -0
  676. package/src/ui-source/tier-source-write-backend.ts +279 -0
  677. package/src/ui-source/ts-ast.ts +171 -0
  678. package/src/ui-source/utility-class-support.ts +169 -0
  679. package/src/ui-source/write-component-default.ts +133 -0
  680. package/src/ui-source/writer.ts +1989 -0
  681. package/src/viewport-activation-timings.ts +840 -0
  682. package/src/viewport-authoring-policy.ts +186 -0
  683. package/src/viewport-controls-hint.ts +57 -0
  684. package/src/viewport-door.ts +237 -0
  685. package/src/viewport-shading-boundary.ts +12 -0
  686. package/src/vite-error-surface.ts +141 -0
  687. package/src/wait-until.ts +37 -0
  688. package/src/workspace-areas.ts +156 -0
  689. package/src/workspace-aux-commands.ts +11 -0
  690. package/src/workspace-available-documents.ts +127 -0
  691. package/src/workspace-core-utilities.ts +31 -0
  692. package/src/workspace-document-ids.ts +59 -0
  693. package/src/workspace-document-registry.ts +612 -0
  694. package/src/workspace-document-restore.ts +145 -0
  695. package/src/workspace-host-commands.ts +141 -0
  696. package/src/workspace-persistence-gate.ts +40 -0
  697. package/src/workspace-play-utilities.ts +44 -0
  698. package/src/workspace-presets.ts +425 -0
  699. package/src/workspace-regions.ts +294 -0
  700. package/src/workspace-state-persistence.ts +536 -0
  701. package/src/workspace-static-panels.ts +73 -0
  702. package/src/workspace-status-registry.ts +121 -0
  703. package/src/workspace-style.ts +239 -0
  704. package/src/workspace-utility-commands.ts +74 -0
  705. package/src/workspace-utility-registry.ts +263 -0
  706. package/src/workspace-viewport-rect.ts +97 -0
  707. package/src/world-adoption.ts +115 -0
  708. package/src/world-document-routing.ts +104 -0
  709. package/vite-plugin-creation-site-write.ts +184 -0
  710. package/vite-plugin-creation-site.ts +80 -0
  711. package/vite-plugin-game-static.ts +303 -0
  712. package/vite-plugin-module-doorways.ts +336 -0
  713. package/vite-plugin-product-contributions.ts +197 -0
  714. package/vite-plugin-project-game-static.ts +125 -0
  715. package/vite-plugin-project-jsx-js.ts +65 -0
  716. package/vite-plugin-project-root-absolute-assets.ts +359 -0
  717. package/vite-plugin-shared-react.ts +420 -0
  718. package/vite-plugin-shared-three.ts +203 -0
  719. package/vite-plugin-ui-oid.ts +2106 -0
@@ -0,0 +1,26 @@
1
+ /** Parsed asset caches outlive R3F mounts. Invalidate before asking a document
2
+ * to reload, so replacing a GLB updates every placement without editing JSX.
3
+ */
4
+ export async function evictLoaderCaches(paths: readonly string[]): Promise<void> {
5
+ if (!paths.length) return;
6
+ const { useGLTF, useTexture } = await import('@react-three/drei');
7
+ for (const path of paths) {
8
+ useGLTF.clear(path);
9
+ useTexture.clear(path);
10
+ }
11
+ }
12
+
13
+ export function announceAssetReload(paths: readonly string[]): void {
14
+ if (
15
+ typeof window === 'undefined' ||
16
+ !paths.some((path) => /\.(glb|gltf|png|jpe?g|webp|avif)$/i.test(path))
17
+ )
18
+ return;
19
+ window.dispatchEvent(new CustomEvent('editor:asset-loaders-changed'));
20
+ }
21
+
22
+ export function onAssetReload(listener: () => void): () => void {
23
+ if (typeof window === 'undefined') return () => {};
24
+ window.addEventListener('editor:asset-loaders-changed', listener);
25
+ return () => window.removeEventListener('editor:asset-loaders-changed', listener);
26
+ }
@@ -0,0 +1,31 @@
1
+ import { assignActiveProject, getCurrentProject, type ProjectConfig } from './active-project';
2
+ import { connectProjectDeclarationEvents } from './asset-events';
3
+ import { probeCurrentServerProject } from './editor-api';
4
+
5
+ /** Refresh declarations in the current session without reopening its project. */
6
+ export function startProjectDeclarationRefresh(): () => void {
7
+ let revision = 0;
8
+ const refresh = async (): Promise<void> => {
9
+ const request = ++revision;
10
+ const project = getCurrentProject();
11
+ if (!project) return;
12
+ try {
13
+ const probe = await probeCurrentServerProject();
14
+ // Invalid intermediate saves retain the last valid configuration;
15
+ // validate-on-save owns their diagnostics.
16
+ if (probe.status !== 'project' || probe.project.path !== project.rootPath) return;
17
+ const config: ProjectConfig = probe.project.config as ProjectConfig;
18
+ if (request !== revision || getCurrentProject() !== project) return;
19
+ assignActiveProject({ ...project, config });
20
+ } catch (error) {
21
+ if (request === revision && getCurrentProject() === project) {
22
+ console.error('[project] Could not refresh project declarations:', error);
23
+ }
24
+ }
25
+ };
26
+ const stop = connectProjectDeclarationEvents(() => void refresh());
27
+ return () => {
28
+ revision++;
29
+ stop();
30
+ };
31
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * THE PROJECT-LOCAL SETTINGS LAYER — one in-memory document mirroring
3
+ * `.vgai/editor-state.json`, the git-ignored file the scaffold already
4
+ * reserves for "editor autosaved UI state" (ARCHITECTURE-CORE §Editor chrome,
5
+ * "Settings have four layers with named homes").
6
+ *
7
+ * Every piece of per-user, per-checkout state — the workspace layouts, the
8
+ * active workspace, the open documents, the view state the shell store
9
+ * autosaves — is a SECTION of this one document, loaded ONCE when a project
10
+ * becomes active and written back debounced through `saveEditorState`, the
11
+ * editor server's own route. One document, one writer, so two sections can
12
+ * never clobber each other through the whole-file route.
13
+ *
14
+ * Keyed by the folder itself: a rename, another browser or another checkout
15
+ * of the same folder finds the same file. Browser storage keyed by an
16
+ * absolute path was the previous home, and it lost a layout to exactly those
17
+ * three moves (measured 2026-09-04).
18
+ */
19
+
20
+ import { activeProjectKey, getCurrentProject, onProjectChange } from './active-project';
21
+ import { loadEditorState, saveEditorState } from './editor-api';
22
+ import { preloadSettings } from './settings-store';
23
+
24
+ type Sections = Record<string, unknown>;
25
+
26
+ const WRITE_DEBOUNCE_MS = 400;
27
+
28
+ let loadedFor: string | null = null;
29
+ let loading: Promise<void> | null = null;
30
+ let doc: Sections = {};
31
+ let dirty = false;
32
+ let timer: ReturnType<typeof setTimeout> | null = null;
33
+
34
+ function projectKey(): string {
35
+ return activeProjectKey();
36
+ }
37
+
38
+ /**
39
+ * Load the active project's local document, once per project. Idempotent and
40
+ * memoized: the second caller for the same project joins the first load, and
41
+ * a different project starts over. Callers that read synchronously through
42
+ * {@link projectLocalSection} await this first.
43
+ */
44
+ export function preloadProjectLocalState(): Promise<void> {
45
+ const key = projectKey();
46
+ if (loadedFor === key) return Promise.resolve();
47
+ // A load in flight for ANOTHER project (the boot's unscoped one, or a
48
+ // project switched away from mid-load) settles for that project; this
49
+ // caller's project loads after it, never joins it.
50
+ if (loading) return loading.then(() => preloadProjectLocalState());
51
+ loading = Promise.all([loadEditorState(), preloadSettings()])
52
+ .then(([state]) => {
53
+ doc = state && typeof state === 'object' ? { ...state } : {};
54
+ loadedFor = key;
55
+ })
56
+ .catch(() => {
57
+ doc = {};
58
+ loadedFor = key;
59
+ })
60
+ .finally(() => {
61
+ loading = null;
62
+ });
63
+ return loading;
64
+ }
65
+
66
+ /** True once the active project's document has loaded. */
67
+ export function projectLocalStateReady(): boolean {
68
+ return loadedFor === projectKey();
69
+ }
70
+
71
+ /** One section of the loaded document, or `undefined` before load or when
72
+ * the project has never written it. Synchronous by design: the boot awaits
73
+ * {@link preloadProjectLocalState} before anything reads. */
74
+ export function projectLocalSection<T>(name: string): T | undefined {
75
+ if (!projectLocalStateReady()) return undefined;
76
+ return doc[name] as T | undefined;
77
+ }
78
+
79
+ function flush(): void {
80
+ if (timer !== null) {
81
+ clearTimeout(timer);
82
+ timer = null;
83
+ }
84
+ if (!dirty) return;
85
+ dirty = false;
86
+ void saveEditorState(doc);
87
+ }
88
+
89
+ /** Replace one section and schedule the write. A write before the load has
90
+ * settled is applied on top of what loads, so a fast first edit is kept. */
91
+ export function writeProjectLocalSection(name: string, value: unknown): void {
92
+ const apply = () => {
93
+ doc = { ...doc, [name]: value };
94
+ dirty = true;
95
+ if (timer !== null) clearTimeout(timer);
96
+ timer = setTimeout(flush, WRITE_DEBOUNCE_MS);
97
+ };
98
+ if (projectLocalStateReady()) apply();
99
+ else void preloadProjectLocalState().then(apply);
100
+ }
101
+
102
+ /** Write what is pending NOW — the page is leaving. */
103
+ export function flushProjectLocalState(): void {
104
+ flush();
105
+ }
106
+
107
+ // The layer loads the moment a project becomes active, so the dock that
108
+ // mounts next reads its layout from the folder, not defaults. This module is
109
+ // imported by the shell's boot (`EditorContext`), which is what makes the
110
+ // subscription exist before the first project activates; `active-project.ts`
111
+ // imports nothing of it, so a bounded host's closure stays as it was.
112
+ onProjectChange(() => {
113
+ if (getCurrentProject()) void preloadProjectLocalState();
114
+ });
115
+
116
+ if (typeof window !== 'undefined') {
117
+ window.addEventListener('pagehide', flushProjectLocalState);
118
+ }
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Project manager — manages the active game project.
3
+ *
4
+ * How the editor learns which project is open depends on the surface, and the
5
+ * split is the whole point:
6
+ *
7
+ * - LOCAL (server-backed) — it ASKS the server. The editor server holds
8
+ * "which project is open" as session state, re-rooted live by
9
+ * `POST /__editor/open-project` (the project browser, `vgai edit <path>`).
10
+ * The URL carries no project identity at all, so a
11
+ * refresh or a tab-heal navigation back to the bare origin lands in the
12
+ * same project — a VS Code window, not a deep link. A `?project=` on a
13
+ * local URL is a loud boot error (`assertNoRemovedBootParams`).
14
+ *
15
+ * Sibling deep-link param (the §6 contract):
16
+ * `?create-from=<templateOrExampleId>` — handled at AppRoot's routing layer,
17
+ * NOT here. When no explicit project target wins, it opens the
18
+ * hub's New Project wizard with that template/example preselected and the name
19
+ * field focused (invalid ids degrade to the default selection plus a
20
+ * non-blocking notice). An explicit project target always takes precedence.
21
+ *
22
+ * Boot precedence (§5/FT-7, unit G5) is decided by `boot-routing.ts`'s pure
23
+ * `resolveBootTarget` and merely EXECUTED here: explicit target → opted-in
24
+ * reopen-last → hub. `?hub=1` forces the hub, and a reopen-last project that
25
+ * fails to open falls back to the hub rather than trapping the user.
26
+ */
27
+
28
+ import { assertProjectCompatibility } from '@volter/editor-sdk/session/editor-compatibility';
29
+ import { hasRootOnSurface } from '@volter/editor-project/adapter/manifest-interpreter';
30
+ import { loadGameManifest } from '@volter/editor-project/manifest/load';
31
+ import { type ActiveProject, assignActiveProject, type ProjectConfig } from './active-project';
32
+ import {
33
+ assertNoRemovedBootParams,
34
+ decideServerProjectBoot,
35
+ describeServerProjectFailure,
36
+ hubRequestedFromSearch,
37
+ resolveBootTarget,
38
+ ServerProjectDetectionError,
39
+ } from './boot-routing';
40
+ import {
41
+ getLauncherSettings,
42
+ listRecentProjects,
43
+ probeCurrentServerProject,
44
+ requireEditorCompatibility,
45
+ } from './editor-api';
46
+ import { parseHierarchyProjection } from './hierarchy-projection';
47
+
48
+ function describeManifestError(error: unknown): string {
49
+ const issues =
50
+ error && typeof error === 'object' && Array.isArray((error as { issues?: unknown }).issues)
51
+ ? (error as { issues: unknown[] }).issues
52
+ : null;
53
+ if (!issues) return error instanceof Error ? error.message : String(error);
54
+
55
+ return issues
56
+ .map((issue) => {
57
+ if (!issue || typeof issue !== 'object') return String(issue);
58
+ const candidate = issue as { path?: unknown; message?: unknown };
59
+ const path = Array.isArray(candidate.path)
60
+ ? candidate.path.map(String).join('.') || '(root)'
61
+ : '(root)';
62
+ const message =
63
+ typeof candidate.message === 'string' ? candidate.message : 'Invalid manifest value';
64
+ return `${path}: ${message}`;
65
+ })
66
+ .join('\n');
67
+ }
68
+
69
+ /** Open a project by its root path. Fetches the sole v2 project manifest. */
70
+ export async function openProject(rootPath: string): Promise<ActiveProject> {
71
+ const compatibility = await requireEditorCompatibility();
72
+ const res = await fetch('/vgai.project.json');
73
+ if (!res.ok) {
74
+ throw new Error(
75
+ `Could not open project at ${rootPath}.\n` +
76
+ `Failed to load vgai.project.json: ${res.status} ${res.statusText}`,
77
+ );
78
+ }
79
+ let rawManifest: unknown;
80
+ try {
81
+ rawManifest = await res.json();
82
+ } catch (error) {
83
+ throw new Error(
84
+ `Could not open project at ${rootPath}.\n` +
85
+ `vgai.project.json is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
86
+ );
87
+ }
88
+ assertProjectCompatibility(
89
+ rawManifest && typeof rawManifest === 'object'
90
+ ? (rawManifest as {
91
+ manifestVersion?: unknown;
92
+ engine?: { version?: unknown };
93
+ roots?: unknown;
94
+ })
95
+ : {},
96
+ compatibility,
97
+ );
98
+ let manifest: ReturnType<typeof loadGameManifest>;
99
+ try {
100
+ manifest = loadGameManifest(rawManifest, { configurationKinds: 'defer' });
101
+ } catch (error) {
102
+ throw new Error(
103
+ `Could not open project at ${rootPath}.\n` +
104
+ `vgai.project.json does not match the current project format:\n${describeManifestError(error)}`,
105
+ );
106
+ }
107
+ const config: ProjectConfig = {
108
+ manifestVersion: manifest.manifestVersion,
109
+ name: manifest.name,
110
+ version: manifest.version,
111
+ engine: manifest.engine,
112
+ appId: manifest.appId,
113
+ resolution: manifest.resolution,
114
+ authoring: manifest.authoring
115
+ ? { hierarchy: parseHierarchyProjection(manifest.authoring.hierarchy) }
116
+ : undefined,
117
+ hasThreeRoot: hasRootOnSurface(manifest, 'three'),
118
+ rootCount: manifest.roots.length,
119
+ configurations: manifest.configurations,
120
+ };
121
+ return assignActiveProject({ rootPath, config });
122
+ }
123
+
124
+ /** How many times boot may re-ask a server that failed to answer at all, and
125
+ * how long it waits between tries. Both small: `detectProject` runs inside
126
+ * AppRoot's detection timeout, and a failing fetch fails fast. */
127
+ export const SERVER_PROJECT_PROBE_ATTEMPTS = 3;
128
+ export const SERVER_PROJECT_PROBE_RETRY_MS = 300;
129
+
130
+ /**
131
+ * Detect and open whatever project the server currently has active.
132
+ * Used in production where __VGAI_PROJECT_PATH__ isn't available at build time.
133
+ *
134
+ * Returns null ONLY when the server said it has no project open — that is the
135
+ * one answer the launcher is a truthful response to. A server that is serving
136
+ * a project it cannot describe, or that could not be asked at all, THROWS
137
+ * (after bounded retries for the transient shape), because rendering the
138
+ * launcher there tells the user their project does not exist when it does.
139
+ * The ladder itself is `boot-routing.ts`'s `decideServerProjectBoot`.
140
+ */
141
+ export async function detectServerProject(): Promise<ActiveProject | null> {
142
+ const compatibility = await requireEditorCompatibility();
143
+ for (let attempt = 1; ; attempt++) {
144
+ const probe = await probeCurrentServerProject();
145
+ const action = decideServerProjectBoot({
146
+ status: probe.status,
147
+ attempt,
148
+ maxAttempts: SERVER_PROJECT_PROBE_ATTEMPTS,
149
+ });
150
+ if (action === 'continue-ladder') return null;
151
+ if (action === 'open' && probe.status === 'project') {
152
+ const info = probe.project;
153
+ assertProjectCompatibility(info.config, compatibility);
154
+ return assignActiveProject({ rootPath: info.path, config: info.config as ProjectConfig });
155
+ }
156
+ if (action === 'retry') {
157
+ await new Promise((resolve) => setTimeout(resolve, SERVER_PROJECT_PROBE_RETRY_MS));
158
+ continue;
159
+ }
160
+ // 'fail' is only reachable from the two failure shapes, and the surface
161
+ // that renders this must name the served path and the server's own error
162
+ // separately — a launcher with a banner is what this fix exists to stop.
163
+ throw new ServerProjectDetectionError(
164
+ describeServerProjectFailure(
165
+ probe.status === 'unreadable'
166
+ ? { status: 'unreadable', path: probe.path, error: probe.error }
167
+ : {
168
+ status: 'unknown',
169
+ error: probe.status === 'unknown' ? probe.error : 'no answer from the server',
170
+ },
171
+ ),
172
+ );
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Detect which project is open, by ASKING the session. Returns the project if
178
+ * found, null if the project screen should be shown.
179
+ */
180
+ export async function detectProject(): Promise<ActiveProject | null> {
181
+ // One gate before anything is resolved: a removed boot
182
+ // param errors loudly naming its replacement rather than falling through
183
+ // (boot-routing.ts) — including `?project=` itself: project identity is
184
+ // session-held.
185
+ assertNoRemovedBootParams(window.location.search);
186
+
187
+ // 1. ASK THE SESSION. This is the one explicit target —
188
+ // `vgai edit <path>`, `VGAI_PROJECT`, and the project browser all reach
189
+ // the client the same way, because they all move the SERVER's project
190
+ // and the client reads it from there. There is no URL param and no
191
+ // boot-time Vite define snapshot in this path: the define is a
192
+ // build-time value, and `POST /__editor/open-project` moves the session
193
+ // live, so a snapshot could disagree with the server that serves the
194
+ // files.
195
+ const serverProject = await detectServerProject();
196
+ if (serverProject) return serverProject;
197
+
198
+ // 2. Reopen-last (G5). Only reached when the server said it has no project
199
+ // open: a live session project outranks the preference.
200
+ return reopenLastProjectIfEnabled();
201
+ }
202
+
203
+ /**
204
+ * The opted-in "Reopen last project on launch" rung of the §5 ladder.
205
+ *
206
+ * Returns the reopened project, or null to fall through to the hub — which is
207
+ * also what a FAILED reopen returns. That fallback is deliberate and is half
208
+ * the reason the escape hatch exists: a project that was deleted, moved, or
209
+ * broken since it was last opened must not be able to wedge the launcher in a
210
+ * boot loop the user cannot click their way out of. Unreal behaves the same
211
+ * way. The failure is reported to the console rather than thrown, because a
212
+ * thrown error here would render the startup-failure screen instead of the hub
213
+ * and hide the recents list the user needs in order to pick something else.
214
+ */
215
+ async function reopenLastProjectIfEnabled(): Promise<ActiveProject | null> {
216
+ const [settings, recents] = await Promise.all([getLauncherSettings(), listRecentProjects()]);
217
+ const target = resolveBootTarget({
218
+ explicitTarget: null,
219
+ hubRequested: hubRequestedFromSearch(window.location.search),
220
+ reopenLastEnabled: settings.reopenLastProject,
221
+ recents,
222
+ });
223
+ if (target.kind !== 'reopen-last') return null;
224
+ try {
225
+ return await openProject(target.path);
226
+ } catch (err) {
227
+ // biome-ignore lint/suspicious/noConsole: a failed auto-reopen must be visible; the editor console isn't mounted yet at boot.
228
+ console.warn(
229
+ `[vgai] "Reopen last project on launch" could not open ${target.path}; showing the project browser instead.`,
230
+ err,
231
+ );
232
+ return null;
233
+ }
234
+ }
235
+
236
+ export {
237
+ type ActiveProject,
238
+ getCurrentProject,
239
+ onProjectChange,
240
+ onProjectSessionEnd,
241
+ type ProjectConfig,
242
+ setActiveProject,
243
+ } from './active-project';
@@ -0,0 +1,163 @@
1
+ /**
2
+ * "This project module was saved" — the ONE subscription for editor surfaces
3
+ * that hold a live, re-executable copy of a project source module.
4
+ *
5
+ * WHICH SIGNAL, AND WHY IT IS THE HMR CHANNEL AND NOT SSE
6
+ * -------------------------------------------------------
7
+ * The editor has two file-change channels and they answer different
8
+ * questions. `asset-events.ts` (SSE) reports FILE-SET changes — a tool or
9
+ * story file appeared/vanished, a `public/` asset changed — and it carries no
10
+ * event for "an arbitrary `src/**` module's bytes changed". Vite's HMR
11
+ * channel does, and it carries something the SSE channel cannot: the dev
12
+ * server has already stamped the changed file HMR-invalid across the
13
+ * project's own subgraph before it sends (`server/project-script-hmr.ts`'s
14
+ * `stampHmrInvalidation`, bounded at editor chrome). That stamp is what makes
15
+ * a cache-busted re-import re-evaluate the module's DEPENDENCIES too; without
16
+ * it a fresh leaf url re-runs against the browser's cached copies of
17
+ * everything it imports, which is the exact stale-restart defect that module's
18
+ * header documents. So the freshness guarantee is the server's, and this
19
+ * subscription is how a document learns the stamp has landed.
20
+ *
21
+ * THE THREE EVENTS are the complete set the server sends for a project source
22
+ * file (`handleProjectScriptHotUpdate`); a live module document takes all
23
+ * three because its subject can be any of those classifications:
24
+ * - `vgai:restart-required` — a plain `.ts`, or a `.tsx` that is not a Fast
25
+ * Refresh boundary. THE COMMON CASE for a model module, whose export is a
26
+ * lowercase builder function.
27
+ * - `vgai:script-update` — the file is in the editor's lane (`src/contributions/`, `src/tools/`).
28
+ * - `vgai:r3f-entry-update` — the file is R3F-dialect.
29
+ * A `.tsx` that IS a Fast Refresh boundary rides stock Vite HMR instead and
30
+ * sends none of these, so `vite:afterUpdate` is taken as well: Vite stamped
31
+ * the graph itself on that path, and the accepted path names the file.
32
+ *
33
+ * Nothing here re-imports anything. The subscriber owns what "changed" means
34
+ * for its own surface.
35
+ */
36
+
37
+ /** Project-relative path of the module that changed, e.g. `src/prefabs/probe.ts`. */
38
+ export type ProjectModuleChangeListener = (relativePath: string) => void;
39
+
40
+ /**
41
+ * WHY THE TRANSFORM ERROR IS RECORDED SEPARATELY: a dynamic `import()` of a
42
+ * module the server could not transform rejects with the browser's own opaque
43
+ * `TypeError: Failed to fetch dynamically imported module: <url>` — the
44
+ * ACTUAL reason (`Unexpected ";"`, at line:col, with a source frame) never
45
+ * reaches the importer. Vite sends it on the HMR channel instead, as
46
+ * `vite:error`, and `editor-console.ts` already prints it. A document showing
47
+ * a build failure needs the same text: "failed to fetch" is not a modeling
48
+ * error message.
49
+ *
50
+ * Kept as a LAST-ERROR-PER-FILE map rather than a subscription because the
51
+ * consumer reads it at the moment its import rejects, which is after the
52
+ * event: the server sends `vite:error` while answering the very request that
53
+ * is about to reject.
54
+ */
55
+ interface ViteErrorPayload {
56
+ readonly err?: {
57
+ readonly message?: unknown;
58
+ readonly id?: unknown;
59
+ readonly frame?: unknown;
60
+ readonly loc?: { readonly file?: unknown; readonly line?: unknown; readonly column?: unknown };
61
+ };
62
+ }
63
+
64
+ /** Keyed by the normalized absolute file path Vite reports. */
65
+ const lastTransformError = new Map<string, string>();
66
+ let transformErrorsWired = false;
67
+
68
+ function wireTransformErrors(): void {
69
+ if (transformErrorsWired) return;
70
+ const hot = import.meta.hot;
71
+ if (!hot) return;
72
+ transformErrorsWired = true;
73
+ hot.on('vite:error', (payload: ViteErrorPayload) => {
74
+ const err = payload?.err;
75
+ if (!err || typeof err.message !== 'string') return;
76
+ const file =
77
+ typeof err.loc?.file === 'string' ? err.loc.file : typeof err.id === 'string' ? err.id : null;
78
+ if (file === null) return;
79
+ const frame = typeof err.frame === 'string' && err.frame !== '' ? `\n${err.frame}` : '';
80
+ // Vite ids carry the transform query; the record is keyed by the file.
81
+ lastTransformError.set(normalize(file.split('?')[0] ?? file), `${err.message}${frame}`);
82
+ });
83
+ }
84
+
85
+ /**
86
+ * The server's own reason the module at `relativePath` did not transform, if
87
+ * it reported one — see {@link ViteErrorPayload}. `null` when the failure was
88
+ * something else (a throwing top level, a missing dependency at runtime),
89
+ * which is the caller's cue to report what its own `import()` said.
90
+ */
91
+ export function projectModuleTransformError(relativePath: string): string | null {
92
+ for (const [file, message] of lastTransformError) {
93
+ if (projectModuleChangeMatches(file, relativePath)) return message;
94
+ }
95
+ return null;
96
+ }
97
+
98
+ /** Drop the recorded transform error for a module that has now built. */
99
+ export function clearProjectModuleTransformError(relativePath: string): void {
100
+ for (const file of [...lastTransformError.keys()]) {
101
+ if (projectModuleChangeMatches(file, relativePath)) lastTransformError.delete(file);
102
+ }
103
+ }
104
+
105
+ /** Server-sent event payloads all carry `{ file }` as an ABSOLUTE path. */
106
+ interface HotFilePayload {
107
+ readonly file?: unknown;
108
+ }
109
+
110
+ /** Vite's own `vite:afterUpdate` payload, narrowed to what is read here. */
111
+ interface ViteUpdatePayload {
112
+ readonly updates?: ReadonlyArray<{ readonly acceptedPath?: unknown; readonly path?: unknown }>;
113
+ }
114
+
115
+ function normalize(path: string): string {
116
+ return path.replaceAll('\\', '/');
117
+ }
118
+
119
+ /**
120
+ * Does `changedPath` (absolute, or already project-relative) name
121
+ * `relativePath` of the open project? Compared by SUFFIX because the two
122
+ * halves spell the same file differently: the dev server reports the absolute
123
+ * path it watched, and a document knows only its project-relative one. The
124
+ * leading separator makes the suffix a whole path segment, so
125
+ * `src/prefabs/probe.ts` never matches `.../not-src/prefabs/probe.ts`.
126
+ */
127
+ export function projectModuleChangeMatches(changedPath: string, relativePath: string): boolean {
128
+ const changed = normalize(changedPath);
129
+ const relative = normalize(relativePath).replace(/^\.?\//, '');
130
+ return changed === relative || changed.endsWith(`/${relative}`);
131
+ }
132
+
133
+ /**
134
+ * Call `listener` whenever the dev server reports that a project source module
135
+ * was saved. Returns the unsubscribe. A no-op (and an immediately-returned
136
+ * unsubscribe) outside a Vite dev client — the packaged host has no HMR
137
+ * channel, and a surface that needs one says so itself.
138
+ */
139
+ export function subscribeProjectModuleChange(listener: ProjectModuleChangeListener): () => void {
140
+ const hot = import.meta.hot;
141
+ if (!hot) return () => {};
142
+ wireTransformErrors();
143
+ const onFileEvent = (payload: HotFilePayload): void => {
144
+ if (typeof payload?.file === 'string') listener(normalize(payload.file));
145
+ };
146
+ const onViteUpdate = (payload: ViteUpdatePayload): void => {
147
+ for (const update of payload?.updates ?? []) {
148
+ const path = update.acceptedPath ?? update.path;
149
+ // Vite's urls carry the transform query (`?t=…`); the path half is the file.
150
+ if (typeof path === 'string') listener(normalize(path.split('?')[0] ?? path));
151
+ }
152
+ };
153
+ hot.on('vgai:restart-required', onFileEvent);
154
+ hot.on('vgai:script-update', onFileEvent);
155
+ hot.on('vgai:r3f-entry-update', onFileEvent);
156
+ hot.on('vite:afterUpdate', onViteUpdate);
157
+ return () => {
158
+ hot.off('vgai:restart-required', onFileEvent);
159
+ hot.off('vgai:script-update', onFileEvent);
160
+ hot.off('vgai:r3f-entry-update', onFileEvent);
161
+ hot.off('vite:afterUpdate', onViteUpdate);
162
+ };
163
+ }